aboutsummaryrefslogtreecommitdiff
path: root/scripts/placer.gd
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/placer.gd')
-rw-r--r--scripts/placer.gd210
1 files changed, 210 insertions, 0 deletions
diff --git a/scripts/placer.gd b/scripts/placer.gd
new file mode 100644
index 0000000..f06944e
--- /dev/null
+++ b/scripts/placer.gd
@@ -0,0 +1,210 @@
+extends Spatial
+
+var player : Spatial
+var world : VoxelMesh
+var turret_holder : Node
+var path_holder : Node
+var attach_point_holder : Node
+var load_turrets : Node
+var saveload_map : Node
+var load_scenes : Node
+var ptr : Spatial
+var resources : Node
+
+var normal = Vector3.ZERO
+var colliding = false
+var colliding_group = []
+var colliding_node : Spatial
+var collision_point : Vector3
+
+func _ready ():
+ player = get_parent()
+ resources = get_parent().get_node("resources")
+
+ var root = get_tree().root.get_child(0)
+ world = root.get_node("world")
+ turret_holder = root.get_node("turrets")
+ attach_point_holder = root.get_node("attach")
+ path_holder = root.get_node("path")
+ ptr = root.find_node("pointer");
+
+ var saveload = root.get_node("saveload")
+ load_turrets = saveload.get_node("load_turrets")
+ saveload_map = saveload.get_node("saveload_map")
+ load_scenes = saveload.get_node("load_scenes")
+
+ if !load_turrets.loaded: yield(load_turrets, "done_loading")
+
+func _physics_process(_delta):
+ _pointer()
+
+func check_overlap_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 = load_scenes.turret.instance()
+ turret_holder.add_child(instance)
+ instance.transform.origin = pos;
+ instance.transform.basis = Basis(rot);
+ instance.refresh_normal()
+
+ var info = load_turrets.info[player.sel.name]
+ var model = load_turrets.models[info.model_name]
+ var instance_model = model.instance()
+ instance_model.name = "model"
+ instance.add_child(instance_model)
+ instance.refresh_model()
+
+ instance.refresh_info(info)
+
+func _inst_path_start (pos, rot):
+ var instance = load_scenes.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 = load_scenes.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 = load_scenes.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 = load_scenes.attach_point.instance()
+ attach_point_holder.add_child(instance)
+ instance.transform.origin = pos;
+ instance.transform.basis = Basis(rot);
+
+func place (group, inst : FuncRef):
+ 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())
+ return "ok"
+
+func delete (group):
+ if Input.is_action_just_pressed("cancel"):
+ if colliding && group in colliding_group:
+ colliding_node.queue_free()
+
+func select ():
+ pass
+
+func _pointer ():
+ if player.sel.name == "" or player.sel.type == "": ptr.visible = false
+ else: ptr.visible = true
+
+ var space: PhysicsDirectSpaceState = get_world().direct_space_state as PhysicsDirectSpaceState
+ var mouse2d = get_viewport().get_mouse_position()
+ var from = player.camera.project_ray_origin(mouse2d)
+ var to = (from + player.camera.project_ray_normal(mouse2d) * 100)
+
+ ptr.transform.origin = to
+
+ var mask = 1
+ if player.sel.name.find("path") != -1: mask = 3
+
+ var result = space.intersect_ray(from, to, [], mask)
+ if result.size() > 0:
+ ptr.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.visible = false
+
+ var placed = ""
+ match player.sel.type:
+ "map_tools":
+ match player.sel.name:
+ "start path":
+ place("path", funcref(self, "_inst_path_start"))
+ delete("path")
+ "path":
+ place("path", funcref(self, "_inst_path"))
+ delete("path")
+ "end path":
+ place("path", funcref(self, "_inst_path_end"))
+ delete("path")
+ "attach":
+ place("voxels", funcref(self, "_inst_attach"))
+ delete("attach")
+ "voxels":
+ pass
+ "turrets":
+ placed = place("attach", funcref(self, "_inst_turret"))
+ if placed == "ok" and !player.in_editor:
+ resources.sub(load_turrets.info[player.sel.name].cost)
+ delete("turret")
+
+ if placed == "ok":
+ player.sel.name = ""
+ player.sel.type = ""
+ if ptr.has_node("preview"):
+ ptr.get_node("preview").queue_free()
+ player.refresh_gui()
+ else:
+ select()