aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/bullet.gd6
-rw-r--r--scripts/debug.gd7
-rw-r--r--scripts/enemies.gd41
-rw-r--r--scripts/fx/fx_enemy_damage.gd5
-rw-r--r--scripts/gui.gd27
-rw-r--r--scripts/movement.gd398
-rw-r--r--scripts/path.gd9
-rw-r--r--scripts/turret.gd109
8 files changed, 229 insertions, 373 deletions
diff --git a/scripts/bullet.gd b/scripts/bullet.gd
index 9b4434d..994d3d1 100644
--- a/scripts/bullet.gd
+++ b/scripts/bullet.gd
@@ -3,6 +3,8 @@ extends Spatial
var _enemies_holder
var shooter
+var damage = 1
+
var timer = 0
var time_life = 3
var speed = 7
@@ -10,7 +12,7 @@ var hit_something = false
func _ready():
_enemies_holder = get_tree().root.get_child(0).find_node("enemies")
- $Area.connect("body_entered", self, "collided")
+ var _err = $Area.connect("body_entered", self, "collided")
func _physics_process(delta):
var forward_dir = -global_transform.basis.z.normalized()
@@ -27,7 +29,7 @@ func collided(body):
if hit_something == false:
var groups = parent.get_groups()
if "enemies" in groups:
- _enemies_holder.damage(parent.name)
+ _enemies_holder.damage(parent.name, damage)
hit_something = true
queue_free()
diff --git a/scripts/debug.gd b/scripts/debug.gd
index 339eec7..b65bd79 100644
--- a/scripts/debug.gd
+++ b/scripts/debug.gd
@@ -5,9 +5,9 @@ var _path
var _enemies
func _ready():
- _path = get_tree().root.get_child(0).find_node("path")
- _player = get_tree().root.get_child(0).find_node("player")
- _enemies = get_tree().root.get_child(0).find_node("enemies")
+ _path = get_tree().root.get_child(0).get_node("path")
+ _player = get_tree().root.get_child(0).get_node("player")
+ _enemies = get_tree().root.get_child(0).get_node("enemies")
func _process(delta):
pass
@@ -16,7 +16,6 @@ func _process(delta):
func _on_Button_button_down():
_enemies.spawn()
-
func _on_Button2_button_down():
var res = _path.load_nodes()
_path.hide()
diff --git a/scripts/enemies.gd b/scripts/enemies.gd
index 08cc389..2144bdf 100644
--- a/scripts/enemies.gd
+++ b/scripts/enemies.gd
@@ -1,8 +1,11 @@
extends Node
+var _resources : Node
+
var _path
var _enemy_blue
var _dissolve_mat : ShaderMaterial
+var _enemy_mat : Material
var _fx_holder
var _fx_enemy_damage
@@ -12,11 +15,27 @@ var _shapes = {}
var serial_enemy = 0
var enemies = {}
+var colors = [
+ Color.red,
+ Color.purple,
+ Color.blue,
+ Color.mediumseagreen,
+ Color.green,
+ Color.greenyellow,
+ Color.yellow,
+ Color.orange,
+ Color.violet,
+ Color.indigo,
+]
+
func _ready():
- _fx_holder = get_tree().root.get_child(0).find_node("fx")
- _path = get_tree().root.get_child(0).find_node("path")
+ var root = get_tree().root.get_child(0)
+ _fx_holder = root.get_node("fx")
+ _path = root.get_node("path")
+ _resources = root.get_node("player").get_node("resources")
_dissolve_mat = load("res://shaders/dissolve_mat.tres")
+ _enemy_mat = load("res://models/shapes/Enemy.material")
_enemy_blue = load("res://scenes/enemy.tscn")
_fx_enemy_damage = load("res://scenes/fx/enemy_damage.tscn")
@@ -42,10 +61,13 @@ func spawn():
instance.name = str(serial_enemy)
var instance_model = _shapes[_shapes.keys()[randi() % _shapes.size()]].instance()
instance.add_child(instance_model)
+ instance_model.get_child(0).set_surface_material(0, _enemy_mat.duplicate())
+
var axis : Vector3 = Quat(Vector3(0, randf()*TAU, 0)) * Vector3.RIGHT
enemies[serial_enemy] = {
"cur": 0, "hp": 10, "rel": 0, "ops": instance_model.name,
- "axis": [axis.x, axis.y, axis.z] }
+ "axis": [axis.x, axis.y, axis.z]
+ }
serial_enemy += 1
func node_from_id (id):
@@ -87,18 +109,23 @@ func _physics_process(delta):
var axis = Vector3(enemy.axis[0], enemy.axis[1], enemy.axis[2])
child.transform.basis = child.transform.basis.rotated(axis, delta)
+
+ var mesh : MeshInstance = child.get_node(enemy.ops).get_child(0)
+ mesh.get_active_material(0).albedo_color = colors[enemy.hp-1]
for id in delist:
get_node(str(id)).queue_free()
enemies.erase(id)
-func damage(name):
+func damage(name, amt):
var id = int(name)
var enemy = enemies[id]
- enemies[id].hp -= 1
- fx_damage(name)
+ if enemy.hp > 0:
+ enemy.hp -= amt
+ _resources.add({ enemy.ops[0]: amt })
+ fx_damage(name)
func fx_damage(name):
var id = int(name)
@@ -114,4 +141,4 @@ func fx_damage(name):
var instance_model = _shapes[enemy["ops"]].instance()
instance.add_child(instance_model)
- instance.refresh_shader(_dissolve_mat.duplicate())
+ instance.refresh_shader(_dissolve_mat.duplicate(), colors[enemy.hp-1])
diff --git a/scripts/fx/fx_enemy_damage.gd b/scripts/fx/fx_enemy_damage.gd
index 48f4629..2ec1d96 100644
--- a/scripts/fx/fx_enemy_damage.gd
+++ b/scripts/fx/fx_enemy_damage.gd
@@ -1,7 +1,7 @@
extends Spatial
var timer = 0
-var timer_life = 0.5
+var timer_life = 1
var anim_size = 1
@@ -9,9 +9,10 @@ var _mesh : MeshInstance
var base
-func refresh_shader(mat):
+func refresh_shader(mat, color : Color):
_mesh = get_child(0).get_child(0)
_mesh.set_surface_material(0, mat)
+ _mesh.get_active_material(0).set_shader_param("albedo", color)
func refresh_basis():
base = transform.basis
diff --git a/scripts/gui.gd b/scripts/gui.gd
index bae4ffc..03a2e04 100644
--- a/scripts/gui.gd
+++ b/scripts/gui.gd
@@ -1,12 +1,23 @@
-extends Panel
+extends Control
-var _player
-var _label
+var player : Node
+var _in_editor : bool
-func _ready():
- _player = self.get_parent().get_parent().find_node("player")
- _label = self.find_node("Label")
+var bottom_bar : Control
+var top_bar : Control
+
+func _fetch ():
+ var root = get_tree().root.get_child(0)
+ player = root.get_node("player")
+
+ if bottom_bar == null: bottom_bar = get_node("bottom_bar")
+ if top_bar == null: top_bar = get_node("top_bar")
-func _process(delta):
- _label.text = str(_player.sel_map[_player.sel])
+func _ready():
+ _fetch()
+ bottom_bar.build()
+func refresh (in_editor : bool):
+ _fetch()
+ bottom_bar.refresh(in_editor)
+ top_bar.refresh(in_editor)
diff --git a/scripts/movement.gd b/scripts/movement.gd
index 0b7726d..587b338 100644
--- a/scripts/movement.gd
+++ b/scripts/movement.gd
@@ -1,209 +1,132 @@
extends KinematicBody
+var in_editor : bool = false
+
var vel = Vector3()
-var _mouse = Vector2()
-var sensitivity_mouse = 0.1
+var camera = Camera
-var _camera : Camera
+var _mouse = Vector2()
+var sensitivity_mouse = 10
-var _normal = Vector3.ZERO
-var _colliding = false
-var _colliding_group = []
-var _colliding_node
-var _collision_point
+var placer : Spatial
var _pivot
var _pivot_dist
-var _pivot_rot
-var _pivot_look
+var _orbit_timer
-var _world
+var _world : VoxelMesh
-var _turret : PackedScene
-var _turret_holder
-var _turret_blues = []
+var _gui : Control
-var _attach_point
-var _attach_point_holder
+var _turret_holder : Node
+var _attach_point_holder : Node
+var path_holder : Node
+var load_turrets : Node
+var ptr : Node
-var _path_start
-var _path
-var _path_end
-var _path_holder
+var _enemies : Node
-var sel = 0;
-var sel_map = [
- "turrets", "path start", "path", "path end", "attach point"
-]
+var sel = {
+ "type": "",
+ "name": ""
+}
func _ready():
- _camera = $Camera
+ camera = $camera
+ placer = $placer
- _world = self.get_parent().find_node("world")
- _turret_holder = self.get_parent().find_node("turrets")
- _path_holder = self.get_parent().find_node("path")
- _attach_point_holder = self.get_parent().find_node("attach")
+ var root = get_tree().root.get_child(0)
- _turret = load("res://scenes/turret.tscn")
- _path_start = load("res://scenes/path_start.tscn")
- _path = load("res://scenes/path.tscn")
- _path_end = load("res://scenes/path_end.tscn")
- _attach_point = load("res://scenes/attach_point.tscn")
+ path_holder = root.get_node("path")
+ _gui = root.get_node("gui")
+ _enemies = root.get_node("enemies")
+ ptr = root.find_node("pointer");
- load_turrets()
+ var saveload = root.get_node("saveload")
+ load_turrets = saveload.get_node("load_turrets")
- #_save()
- _load()
-
-func load_turrets():
- _turret_blues = []
- var dir = Directory.new()
- dir.open("res://models/turrets")
- dir.list_dir_begin(true)
- var turr = dir.get_next()
- while turr != "":
- if (turr.ends_with(".glb")):
- _turret_blues.append(load("res://models/turrets/" + turr))
- turr = dir.get_next()
-
-func get_map_state ():
- var state = {}
+ _gui.refresh(in_editor)
- state["voxels"] = []
- for pos in _world.get_voxels():
- var vox = { "pos": [pos.x, pos.y, pos.z], "id":_world.get_voxel_id(pos) }
- state["voxels"] += [vox]
+ refresh_path()
- state["path"] = []
- for node in _path_holder.get_children():
- var pos = node.transform.origin;
- var rot = node.transform.basis.get_rotation_quat();
- var pobj = {
- "pos": [pos.x, pos.y, pos.z],
- "rot": [rot.x, rot.y, rot.z, rot.w],
- "id": node.name
- }
- state["path"] += [pobj]
+func refresh_gui():
+ _gui.refresh(in_editor)
- state["attach"] = []
- for node in _attach_point_holder.get_children():
- var pos = node.transform.origin;
- var rot = node.transform.basis.get_rotation_quat();
- var pobj = {
- "pos": [pos.x, pos.y, pos.z],
- "rot": [rot.x, rot.y, rot.z, rot.w],
- "id": node.name
- }
- state["attach"] += [pobj]
-
- return state
-
-func set_map_state (state):
- _world.erase_voxels()
- for vox in state["voxels"]:
- var vecpos = Vector3(vox.pos[0], vox.pos[1], vox.pos[2]);
- _world.set_voxel(vecpos, vox.id)
- _world.update_mesh()
+func gui_editor_toggle_event ():
+ in_editor = !in_editor
+ _gui.refresh(in_editor)
+ refresh_path()
- clear_children(_path_holder)
- for pobj in state["path"]:
- var blue = _path
- if "start" in pobj.id:
- blue = _path_start
- if "end" in pobj.id:
- blue = _path_end
- var instance = blue.instance()
- _path_holder.add_child(instance)
- var vecpos = Vector3(pobj.pos[0], pobj.pos[1], pobj.pos[2]);
- instance.transform.origin = vecpos;
- var quat = Quat(pobj.rot[0], pobj.rot[1], pobj.rot[2], pobj.rot[3]);
- instance.transform.basis = Basis(quat);
+func gui_start_wave_event ():
+ refresh_path()
+ _enemies.spawn()
+ _gui.refresh(in_editor)
- clear_children(_attach_point_holder)
- for pobj in state["attach"]:
- var blue = _attach_point
- var instance = blue.instance()
- _attach_point_holder.add_child(instance)
- var vecpos = Vector3(pobj.pos[0], pobj.pos[1], pobj.pos[2]);
- instance.transform.origin = vecpos;
- var quat = Quat(pobj.rot[0], pobj.rot[1], pobj.rot[2], pobj.rot[3]);
- instance.transform.basis = Basis(quat);
-
-
-func _save():
- var save_game = File.new()
- save_game.open("user://map0.json", File.WRITE)
- save_game.store_string(to_json(get_map_state()))
- save_game.close()
- print("saved")
-
-func _load():
- var save_game = File.new()
- save_game.open("user://map0.json", File.READ)
- var raw = save_game.get_as_text()
- save_game.close()
-
- var state = parse_json(raw)
- set_map_state(state)
- print("loaded")
-
-func _process(delta):
- if Input.is_action_just_released("save"):
- _save()
- if Input.is_action_just_released("load"):
- _load()
-
-func clear_children (node):
- for n in node.get_children():
- node.remove_child(n)
- n.queue_free()
-
-func look_free (delta, m):
+func refresh_path():
+ if in_editor:
+ path_holder.show()
+ else:
+ var _res = path_holder.load_nodes()
+ path_holder.hide()
+
+func selected_event (sel_name, sel_type):
+ sel.name = sel_name
+ sel.type = sel_type
+ _gui.refresh(in_editor)
+
+ if sel_type == "turrets":
+ var info = load_turrets.info[sel.name]
+ var model = load_turrets.models[info.model_name]
+ var instance_model = model.instance()
+ instance_model.name = "preview"
+ ptr.add_child(instance_model)
+ elif sel_type != "":
+ ptr.get_node("base").visible = true
+
+func look_free (m):
self.transform.basis = self.transform.basis.rotated(Vector3.UP, m.x)
var rrrot = self.transform.basis.get_rotation_quat()
self.transform.basis = self.transform.basis.rotated(rrrot*Vector3.RIGHT, m.y)
-func look_orbit(delta, m):
+func look_orbit(m):
var diff : Vector3 = self.transform.origin - _pivot
+ _pivot_dist = diff.length()
var orbit : Basis = Transform.looking_at(diff, Vector3.UP).basis
orbit = orbit.rotated(Vector3.UP, m.x)
orbit = orbit.rotated(orbit.get_rotation_quat()*Vector3.RIGHT, -m.y)
- self.transform.basis = self.transform.basis.rotated(Vector3.UP, m.x)
- var rrrot = self.transform.basis.get_rotation_quat()
- self.transform.basis = self.transform.basis.rotated(rrrot*Vector3.RIGHT, m.y)
- var normdiff = diff.normalized()
self.transform.origin = _pivot - orbit.z * _pivot_dist
+
+ diff = self.transform.origin - _pivot
+ self.transform.basis = self.transform.basis.slerp( \
+ Transform.looking_at(-diff, Vector3.UP).basis, _orbit_timer)
+
func _move_input(delta):
- var dir = Vector3()
-
var m = _mouse
+ m *= delta
_mouse = Vector2()
-
- var orbiting = false
if Input.is_action_just_pressed("orbit"):
- if _colliding:
- _pivot = _collision_point
+ if placer.colliding:
+ _pivot = placer.collision_point
var diff : Vector3 = self.transform.origin - _pivot
- _pivot_rot = Transform.looking_at(diff, Vector3.UP).basis.get_rotation_quat()
_pivot_dist = diff.length()
- _pivot_look = Transform(Basis(), _collision_point)
+ _orbit_timer = 0
else: _pivot = null
+ Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
+
if Input.is_action_pressed("orbit"):
+ Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
if _pivot != null:
- orbiting = true
- look_orbit(delta, m)
+ _orbit_timer = min(1, _orbit_timer+delta * 2)
+ look_orbit(m)
else:
- look_free(delta, m)
-
- Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
-
- if Input.is_action_pressed("look"):
- look_free(delta, m)
+ look_free(m)
+ elif Input.is_action_pressed("look"):
+ look_free(m)
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
var input_movement_vector = Vector3()
@@ -221,7 +144,7 @@ func _move_input(delta):
input_movement_vector.y -= 1
input_movement_vector = input_movement_vector.normalized()
- dir = self.transform.basis.get_rotation_quat() * input_movement_vector
+ var dir : Vector3 = self.transform.basis.get_rotation_quat() * input_movement_vector
vel += dir * delta;
vel *= 0.8
@@ -230,164 +153,7 @@ func _move_input(delta):
if collision: vel = Vector3(0, 0, 0)
func _physics_process(delta):
- if Input.is_action_just_released("cycle_forward"):
- sel += 1
- if sel >= len(sel_map):
- sel = len(sel_map)-1
- if Input.is_action_just_released("cycle_backward"):
- sel -= 1
- if sel < 0:
- sel = 0
-
_move_input(delta)
- _pointer()
-
-func check_overlap_pointer():
- var ptr = self.get_parent().find_node("pointer");
-
- var overlap = false
- var space = get_world().direct_space_state
-
- var center = ptr.transform.origin + _normal*0.25
-
- var shape: = BoxShape.new()
- shape.extents = Vector3(0.24, 0.24, 0.24)
-
- var params: = PhysicsShapeQueryParameters.new()
- params.set_shape(shape)
- params.collision_mask = 3
- params.transform = Transform.IDENTITY
- params.transform.origin = center
-
- var result = space.intersect_shape(params)
- for body in result:
- if !body.collider.get_parent().is_in_group("attach"):
- overlap = true
- break
-
- for pos in _world.get_voxels():
- var wpos = pos * 0.5
- wpos += Vector3.ONE * (0.5 / 2)
- var dist = (wpos - center).length_squared()
- if dist < 0.1:
- overlap = true
- break
-
- for node in _path_holder.get_children():
- var pos = node.transform.origin
- var dist = (pos - center).length_squared()
- if dist < 0.1:
- overlap = true
- break
-
- return overlap
-
-func _inst_turret (pos, rot):
- var instance = _turret.instance()
- _turret_holder.add_child(instance)
- instance.transform.origin = pos;
- instance.transform.basis = Basis(rot);
- instance.refresh_normal()
- var instance_model = _turret_blues[0].instance()
- instance_model.name = "model"
- instance.add_child(instance_model)
- instance.refresh_model()
-
-func _inst_path_start (pos, rot):
- var instance = _path_start.instance()
- _path_holder.add_child(instance)
- instance.transform.origin = pos + _normal * 0.25;
- instance.transform.basis = Basis(rot);
-
-func _inst_path (pos, rot):
- var instance = _path.instance()
- _path_holder.add_child(instance)
- instance.transform.origin = pos + _normal * 0.25;
- instance.transform.basis = Basis(rot);
- instance.set_name("path")
- _colliding_node.transform.basis = Basis(rot);
-
-func _inst_path_end (pos, rot):
- var instance = _path_end.instance()
- _path_holder.add_child(instance)
- instance.transform.origin = pos + _normal * 0.25
- instance.transform.basis = Basis(rot);
-
-func _inst_attach (pos, rot):
- var instance = _attach_point.instance()
- _attach_point_holder.add_child(instance)
- instance.transform.origin = pos;
- instance.transform.basis = Basis(rot);
-
-func place (group, inst : FuncRef):
- var ptr = self.get_parent().find_node("pointer");
- if Input.is_action_just_pressed("use"):
- if _colliding && group in _colliding_group:
- if !check_overlap_pointer():
- inst.call_func(ptr.transform.origin, ptr.transform.basis.get_rotation_quat())
-
-func delete (group):
- if Input.is_action_just_pressed("cancel"):
- if _colliding && group in _colliding_group:
- _colliding_node.queue_free()
-
-func _pointer ():
- var ptr = self.get_parent().find_node("pointer");
-
- var space: PhysicsDirectSpaceState = get_world().direct_space_state as PhysicsDirectSpaceState
- var mouse2d = get_viewport().get_mouse_position()
- var from = _camera.project_ray_origin(mouse2d)
- var to = (from + _camera.project_ray_normal(mouse2d) * 5)
-
- ptr.transform.origin = to
-
- var mask = 1
- if sel in [1, 2, 3]: mask = 3
- var result = space.intersect_ray(from, to, [], mask)
- if result.size() > 0:
- ptr.get_child(0).visible = true
-
- _colliding = true
- _normal = result.normal;
- _collision_point = result.position
-
- var node = result.collider.get_parent()
- _colliding_node = node
- _colliding_group = node.get_groups()
-
- if ("voxels" in _colliding_group or "path" in _colliding_group):
- var cpos = result.position - _normal * (0.5 / 2)
- var _cursor_position = (cpos / 0.5).floor() * 0.5
- _cursor_position += Vector3.ONE * (0.5 / 2) + _normal * (0.5 / 2)
- _collision_point = _cursor_position
-
- if ("attach" in _colliding_group):
- _collision_point = node.global_transform.origin;
- _normal = (node.global_transform.basis.get_rotation_quat() * Vector3.UP).normalized();
-
- ptr.transform.basis = Basis(Utils.quat_look(_normal, Vector3.UP))
- ptr.transform.origin = _collision_point
- else:
- _colliding = false
- _colliding_group = []
- ptr.get_child(0).visible = false
-
- match sel:
- 0:
- place("attach", funcref(self, "_inst_turret"))
- delete("turret")
- 1:
- place("voxels", funcref(self, "_inst_path_start"))
- delete("path")
- 2:
- place("path", funcref(self, "_inst_path"))
- delete("path")
- 3:
- place("path", funcref(self, "_inst_path_end"))
- delete("path")
- 4:
- place("voxels", funcref(self, "_inst_attach"))
- delete("attach")
func _input(event):
if event is InputEventMouseMotion:
diff --git a/scripts/path.gd b/scripts/path.gd
index bd3b40f..f8c0fb7 100644
--- a/scripts/path.gd
+++ b/scripts/path.gd
@@ -8,9 +8,6 @@ const dirs = [
var nodes = []
-
-func _ready():
- pass # Replace with function body.
func next_node (node, dir):
var pos : Vector3 = node.transform.origin
@@ -59,13 +56,13 @@ func load_nodes ():
func hide ():
for child in get_children():
- var mesh = child.find_node("MeshInstance")
+ var mesh = child.get_node("MeshInstance")
mesh.visible = false
func show ():
for child in get_children():
- var mesh = child.find_node("MeshInstance")
- mesh.visible = false
+ var mesh = child.get_node("MeshInstance")
+ mesh.visible = true
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
diff --git a/scripts/turret.gd b/scripts/turret.gd
index cc90dd4..9dce497 100644
--- a/scripts/turret.gd
+++ b/scripts/turret.gd
@@ -1,28 +1,30 @@
extends Spatial
-var _path
-var _enemies
-var _projectiles_holder
+var _path : Node
+var _enemies : Node
+var _projectiles_holder : Node
+var _enemies_holder : Node
-var _base
-var _gun
-var _shooting_point
-var _normal
+var _base : Spatial
+var _gun : Spatial
+var _shooting_point : Vector3
+var _normal : Vector3
var aim_mode = "first"
var _target = null
-var _range = 10
+var projectile : PackedScene
-var projectile
+var info : Dictionary
-var cooldown = 0.1
var cooldown_timer = 0
func _ready():
- _path = get_tree().root.get_child(0).find_node("path")
- _enemies = get_tree().root.get_child(0).find_node("enemies")
- _projectiles_holder = get_tree().root.get_child(0).find_node("projectiles")
+ var root = get_tree().root.get_child(0)
+ _path = root.get_node("path")
+ _enemies = root.get_node("enemies")
+ _projectiles_holder = root.get_node("projectiles")
+ _enemies_holder = root.find_node("enemies")
projectile = load("res://scenes/projectiles/bullet.tscn")
@@ -34,17 +36,20 @@ func refresh_model():
_base = get_node("model").find_node("pivot*").find_node("base*")
_gun = _base.find_node("gun*")
+func refresh_info(tinfo):
+ self.info = tinfo
+
func filter_in_range(set):
var filtered = []
for target in set:
var node = _enemies.node_from_id(target)
var dist = (node.transform.origin - _shooting_point).length_squared()
- if dist < _range*_range:
+ if dist < info.range*info.range:
filtered += [target]
return filtered
func filter_visible(set):
- var space: PhysicsDirectSpaceState = get_world().direct_space_state as PhysicsDirectSpaceState
+ var space: PhysicsDirectSpaceState = get_world().direct_space_state
var from = _shooting_point
var filtered = []
@@ -86,28 +91,76 @@ func _physics_process(delta):
var direction = (enemy.transform.origin - _shooting_point).normalized()
var proj_normal = direction - _normal.dot(direction) * _normal
- var base_rot = Transform().looking_at(proj_normal, _normal).basis.get_rotation_quat()
+ var base_rot : Quat = Transform().looking_at(proj_normal, _normal).basis.get_rotation_quat()
- var perp = proj_normal.cross(_normal).normalized()
+ var perp = -proj_normal.cross(_normal).normalized()
var proj_forward = direction - perp.dot(direction) * perp
- var gun_rot = Transform().looking_at(proj_forward, perp).basis.get_rotation_quat()
+ var gun_rot : Quat = Transform().looking_at(proj_forward, perp).basis.get_rotation_quat()
gun_rot = Quat(direction, PI/2) * gun_rot
+ gun_rot = gun_rot.normalized()
+ gun_rot = base_rot.inverse() * gun_rot
- _base.global_transform.basis = Basis(base_rot)
- _gun.global_transform.basis = Basis(gun_rot)
+ var base_basis = _base.global_transform.basis.get_rotation_quat()
+ var base_angle = base_basis.angle_to(base_rot)
+ if base_angle > 0.01:
+ var base_amt = (info.turn_speed * delta) / base_angle
+ base_amt = min(1, base_amt)
+ _base.global_transform.basis = Basis(base_basis.slerp(Basis(base_rot), base_amt))
+
+ var gun_basis = _gun.transform.basis.get_rotation_quat()
+ var gun_angle = gun_basis.angle_to(gun_rot)
+ if gun_angle > 0.01:
+ var gun_amt = (info.turn_speed * delta) / gun_angle
+ gun_amt = min(1, gun_amt)
+ _gun.transform.basis = Basis(gun_basis.slerp(Basis(gun_rot), gun_amt))
cooldown_timer += delta
- if cooldown_timer > cooldown:
- cooldown_timer -= cooldown
- shoot(direction)
+ if cooldown_timer > info.cooldown:
+ cooldown_timer -= info.cooldown
+ shoot()
+
+func spread (amt : int) -> Array:
+ var dirs = []
+ var width : int = ceil(sqrt(amt))
+ for i in amt:
+ var dir = _gun.global_transform.basis
+ var x = floor(i%width)-width/2+(width+1)%2*0.5
+ var y = floor(i/width)-floor(sqrt(amt)-1)/2
+ var spread = info.projectile.spread
+ dir = dir.rotated(_normal, deg2rad(x*spread))
+ dir = dir.rotated(_normal.cross(dir.z).normalized(), deg2rad(y*spread))
+ dirs.append(dir)
+ return dirs
-func shoot (dir):
- shoot_projectile(dir)
+func shoot ():
+ if info.projectile.amount > 1:
+ for dir in spread(info.projectile.amount):
+ match info.projectile.type:
+ "bullet": shoot_bullet(dir)
+ "ray": shoot_ray(dir)
+ else:
+ match info.projectile.type:
+ "bullet": shoot_bullet(_gun.global_transform.basis)
+ "ray": shoot_ray(_gun.global_transform.basis)
-func shoot_projectile (dir):
+func shoot_bullet (dir : Basis):
var instance = projectile.instance()
_projectiles_holder.add_child(instance)
- instance.transform = Transform().looking_at(dir, _normal)
- instance.transform.origin = _shooting_point + dir*0.3;
+ instance.transform.basis = dir
+ instance.transform.origin = _shooting_point - dir.z*0.3;
instance.shooter = self
+ instance.damage = info.damage
+ instance.speed = info.projectile.speed
+
+func shoot_ray (dir : Basis):
+ var space: PhysicsDirectSpaceState = get_world().direct_space_state
+ var from = _shooting_point
+ var to = _shooting_point - dir.z*info.range;
+
+ var result = space.intersect_ray(from, to, _path.nodes, 1)
+ if result.size() > 0:
+ var parent = result.collider.get_parent()
+ var groups = parent.get_groups()
+ if "enemies" in groups:
+ _enemies_holder.damage(parent.name, info.damage)