Various changes, idk
This commit is contained in:
parent
0e37458674
commit
6194de5a87
|
@ -0,0 +1 @@
|
|||
*.wasm filter=lfs diff=lfs merge=lfs -text
|
861
node_3d.tscn
861
node_3d.tscn
File diff suppressed because one or more lines are too long
|
@ -43,16 +43,16 @@ surface_0/tile_rotation_order = 2
|
|||
surface_0/distribution = 0
|
||||
surface_0/alignment = 0
|
||||
surface_0/warp_along_curve = true
|
||||
surface_0/sample_cubic = false
|
||||
surface_0/tilt = true
|
||||
surface_0/sample_cubic = true
|
||||
surface_0/tilt = false
|
||||
surface_0/offset = Vector2(0, 0)
|
||||
surface_1/tile_rotation = Vector3(0, 0, 0)
|
||||
surface_1/tile_rotation_order = 2
|
||||
surface_1/distribution = 0
|
||||
surface_1/alignment = 0
|
||||
surface_1/warp_along_curve = true
|
||||
surface_1/sample_cubic = false
|
||||
surface_1/tilt = true
|
||||
surface_1/sample_cubic = true
|
||||
surface_1/tilt = false
|
||||
surface_1/offset = Vector2(0, 0)
|
||||
visibility_range_end = 100.0
|
||||
|
||||
|
@ -66,7 +66,7 @@ surface_0/distribution = 0
|
|||
surface_0/alignment = 0
|
||||
surface_0/warp_along_curve = true
|
||||
surface_0/sample_cubic = false
|
||||
surface_0/tilt = true
|
||||
surface_0/tilt = false
|
||||
surface_0/offset = Vector2(0, 0)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0)
|
||||
visibility_range_begin = 100.0
|
||||
|
|
|
@ -60,5 +60,6 @@ metadata/_custom_type_script = "uid://bshiyw2k3op02"
|
|||
[node name="Detector" type="Node3D" parent="." index="7"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.31252, 0)
|
||||
script = ExtResource("5_vuktq")
|
||||
debug_draw = false
|
||||
|
||||
[connection signal="item_added" from="Consumer" to="." method="_on_consumer_item_added"]
|
||||
|
|
|
@ -60,4 +60,5 @@ skeleton = NodePath("../../..")
|
|||
script = ExtResource("6_pedvu")
|
||||
detection_range = 50.0
|
||||
scan_period = 0.5
|
||||
debug_draw = false
|
||||
metadata/_custom_type_script = "uid://b3jshlhs24s8d"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://1gcj3gixy6hs"]
|
||||
[gd_scene load_steps=8 format=3 uid="uid://1gcj3gixy6hs"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://f0j7u0so2ug5" path="res://scripts/units/unit.gd" id="1_dberb"]
|
||||
[ext_resource type="Texture2D" uid="uid://3javrn230ddq" path="res://assets/images/enemy.png" id="2_2pk7s"]
|
||||
[ext_resource type="Script" uid="uid://d2xsmjrclnawc" path="res://scripts/tower_navigation_agent.gd" id="3_rjs3g"]
|
||||
|
||||
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_a0tk4"]
|
||||
friction = 0.25
|
||||
|
@ -24,6 +25,8 @@ material = SubResource("StandardMaterial3D_jka67")
|
|||
axis_lock_angular_x = true
|
||||
axis_lock_angular_z = true
|
||||
physics_material_override = SubResource("PhysicsMaterial_a0tk4")
|
||||
contact_monitor = true
|
||||
max_contacts_reported = 6
|
||||
angular_damp = 20.0
|
||||
script = ExtResource("1_dberb")
|
||||
movement_force = 5.0
|
||||
|
@ -53,3 +56,6 @@ shape = SubResource("SphereShape3D_a202f")
|
|||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.668082, 0)
|
||||
billboard = 1
|
||||
text = "blablabla"
|
||||
|
||||
[node name="TowerNavigationAgent" type="Node3D" parent="."]
|
||||
script = ExtResource("3_rjs3g")
|
||||
|
|
|
@ -78,6 +78,7 @@ enabled=PackedStringArray("res://addons/GPUTrail/plugin.cfg", "res://addons/Path
|
|||
Enemies=""
|
||||
Citizens=""
|
||||
Buildings=""
|
||||
Spawners=""
|
||||
|
||||
[input]
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class_name Building
|
|||
@export var build_materials_needed: Dictionary[Item, int] = {}
|
||||
|
||||
@export_group("Defence")
|
||||
@export var max_hp: int = 100 ## Amount of damage this building can sustain before being destroyed.
|
||||
@export var max_hp: int = 1000 ## Amount of damage this building can sustain before being destroyed.
|
||||
|
||||
@export_group("Stacking")
|
||||
@export var can_stack: bool = true ## Whether this building can be stacked on top of other buildings.
|
||||
|
@ -191,3 +191,12 @@ func set_collision_enabled(enabled: bool) -> void:
|
|||
collision_shape.get_parent().collision_layer = 1 << 31
|
||||
else:
|
||||
collision_shape.get_parent().collision_layer = initial_collision_layer
|
||||
|
||||
func hurt(damage: float) -> void:
|
||||
hp -= damage
|
||||
if hp <= 0:
|
||||
destroy()
|
||||
|
||||
func destroy() -> void:
|
||||
build_state = BuildState.DESTROYED
|
||||
visible = false
|
||||
|
|
|
@ -15,7 +15,7 @@ func _input(event: InputEvent) -> void:
|
|||
if placing_building == null:
|
||||
return
|
||||
if event is InputEventMouseButton:
|
||||
if event.is_action("building_place"):
|
||||
if event.is_action("building_place") and event.pressed:
|
||||
placement_mouse_input((event as InputEventMouseButton).global_position, true)
|
||||
get_viewport().set_input_as_handled()
|
||||
elif event.is_action("building_cancel"):
|
||||
|
|
|
@ -79,8 +79,23 @@ func set_path_waypoint(global_pos: Vector3, add: bool) -> void:
|
|||
func update_path_from_waypoints() -> void:
|
||||
path.curve.clear_points()
|
||||
|
||||
for waypoint in waypoints:
|
||||
path.curve.add_point(waypoint)
|
||||
path.curve.add_point(waypoints[0])
|
||||
for i in range(1, waypoints.size()):
|
||||
var last_waypoint: Vector3 = waypoints[i-1]
|
||||
var waypoint: Vector3 = waypoints[i]
|
||||
var out: Vector3 = (waypoint - last_waypoint).normalized() * 0.5
|
||||
#if i >= 1 and i < waypoints.size() - 1:
|
||||
#out = (waypoints[i+1] - waypoints[i]).normalized().slerp((waypoints[i] - waypoints[i-1]).normalized(),0.5)
|
||||
#out *= 1.0
|
||||
#DebugDraw3D.draw_text(to_global(waypoint + Vector3(0,1,0)), "%d" % i, 32, Color.BLUE_VIOLET, 0.5)
|
||||
#DebugDraw3D.draw_sphere(to_global(waypoint), 0.25, Color.BLUE_VIOLET, 0.5)
|
||||
#DebugDraw3D.draw_line(to_global(waypoint), to_global(waypoint + out), Color.BLUE_VIOLET, 0.5)
|
||||
#print("Conveyor path %d: pos=%s out=%s" % [i, waypoints[i], out])
|
||||
var a: Vector3 = last_waypoint.move_toward(waypoint, 1.0)
|
||||
var b: Vector3 = waypoint.move_toward(last_waypoint, 1.0)
|
||||
path.curve.add_point(a,-out,out)
|
||||
path.curve.add_point(b,-out,out)
|
||||
path.curve.add_point(waypoints[-1])
|
||||
# find paths between the defined points
|
||||
#for i in range(1, waypoints.size()):
|
||||
#var a: Vector3 = to_global(waypoints[i-1])
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
extends Node3D
|
||||
|
||||
@export var waves: Array[WaveData] = []
|
||||
|
||||
signal wave_started()
|
||||
signal wave_completed()
|
||||
|
||||
var next_wave_id: int = 0
|
||||
var wave_timer: float = 0.0
|
||||
var wave_in_progress: bool = false
|
||||
var next_spawn_times: Dictionary[String, float] = {}
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if next_wave_id >= waves.size():
|
||||
next_wave_id = 0
|
||||
var wave: WaveData = waves[next_wave_id]
|
||||
wave_timer += delta
|
||||
if !wave_in_progress:
|
||||
if wave_timer >= wave.delay:
|
||||
wave_timer = 0
|
||||
next_spawn_times.clear()
|
||||
wave_in_progress = true
|
||||
wave_started.emit()
|
||||
else:
|
||||
if wave_timer >= wave.duration:
|
||||
wave_in_progress = false
|
||||
wave_timer = 0
|
||||
next_wave_id += 1
|
||||
else:
|
||||
for key in wave.enemies.keys():
|
||||
var next_spawn_time: float = next_spawn_times.get(key, 0)
|
||||
if wave_timer >= next_spawn_time:
|
||||
var enemy_delay: float = wave.duration / wave.enemies.get(key)
|
||||
next_spawn_time += enemy_delay
|
||||
next_spawn_times.set(key, next_spawn_time)
|
||||
spawn(key as String)
|
||||
|
||||
func spawn(key: String) -> void:
|
||||
var node: Node = get_tree().get_nodes_in_group("Spawners").pick_random()
|
||||
var spawner: Spawner = node as Spawner
|
||||
spawner.spawn()
|
|
@ -0,0 +1 @@
|
|||
uid://d1yjsbla7fld2
|
|
@ -1,5 +1,6 @@
|
|||
@tool
|
||||
extends Node3D
|
||||
class_name NavigationGrid
|
||||
|
||||
@export_tool_button("Generate", "Reload") var action: Callable = generate
|
||||
@export var nav_point_offset: float = 0.5
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
extends Label
|
||||
|
||||
@export var path: NodePath
|
||||
@export var property_name: StringName
|
||||
@export var format: String
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
var full_path: NodePath = NodePath( path.get_concatenated_names() + ":" + property_name)
|
||||
#var node = get_node(path)
|
||||
var arr: Array = get_node_and_resource(full_path)
|
||||
if arr[0] != null:
|
||||
var resource: Object = (arr[1] if arr[1] != null else arr[0])
|
||||
var property
|
||||
if arr[2] != null:
|
||||
property = resource.get_indexed(arr[2] as NodePath)
|
||||
else:
|
||||
property = resource
|
||||
text = format % property
|
|
@ -0,0 +1 @@
|
|||
uid://ye6pb2u3g83d
|
|
@ -1,16 +1,20 @@
|
|||
extends Node3D
|
||||
class_name Spawner
|
||||
|
||||
@export var spawn_scene: PackedScene = null
|
||||
@export var spawn_time: float = 5.0
|
||||
#@export var spawn_time: float = 5.0
|
||||
@export var enabled: bool = true
|
||||
|
||||
var spawn_timer: float = 0.0
|
||||
func spawn() -> void:
|
||||
var node: Node = spawn_scene.instantiate()
|
||||
add_child(node)
|
||||
if node is Node3D:
|
||||
(node as Node3D).global_position = global_position
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
spawn_timer += delta
|
||||
if spawn_timer >= spawn_time:
|
||||
spawn_timer -= spawn_time
|
||||
var node: Node = spawn_scene.instantiate()
|
||||
add_child(node)
|
||||
if node is Node3D:
|
||||
(node as Node3D).global_position = global_position
|
||||
#var spawn_timer: float = 0.0
|
||||
#
|
||||
#func _process(delta: float) -> void:
|
||||
#spawn_timer += delta
|
||||
#if spawn_timer >= spawn_time:
|
||||
#spawn_timer -= spawn_time
|
||||
#
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
extends Node3D
|
||||
class_name TowerNavigationAgent
|
||||
|
||||
# How close do we want to get to the target before finishing navigation
|
||||
@export var target_distance: float = 2.0
|
||||
# How close do we need to get to path points before advancing to the next one
|
||||
@export var next_position_distance: float = 2.0
|
||||
# How far can we get from the path before giving up and recalculating
|
||||
@export var recalculate_distance: float = 5.0
|
||||
|
||||
var navigation_grid: NavigationGrid
|
||||
var target_position: Vector3
|
||||
var last_target_position: Vector3
|
||||
|
||||
var path : PackedVector3Array = []
|
||||
var next_point_idx: int = 0
|
||||
var grid: NavigationGrid
|
||||
|
||||
func _ready() -> void:
|
||||
var node: Node = self
|
||||
while !node is NavigationGrid and node.get_parent() != null:
|
||||
node = node.get_parent()
|
||||
grid = node as NavigationGrid
|
||||
|
||||
func get_next_path_position() -> Vector3:
|
||||
if _ensure_path():
|
||||
if global_position.distance_to(path[next_point_idx]) <= next_position_distance:
|
||||
next_point_idx = min(next_point_idx+1, path.size()-1)
|
||||
return path[next_point_idx]
|
||||
else:
|
||||
return Vector3()
|
||||
|
||||
func get_movement_direction() -> Vector3:
|
||||
return get_next_path_position() - global_position
|
||||
|
||||
func is_target_reachable() -> bool:
|
||||
return _ensure_path()
|
||||
|
||||
func is_navigation_finished() -> bool:
|
||||
_ensure_path()
|
||||
return path.is_empty()
|
||||
|
||||
func _ensure_path() -> bool:
|
||||
if target_position.is_zero_approx():
|
||||
return false
|
||||
var recalculate_needed: bool = path.is_empty() \
|
||||
or target_position.distance_to(last_target_position) >= target_distance \
|
||||
or global_position.distance_to(path[next_point_idx]) >= recalculate_distance
|
||||
|
||||
if recalculate_needed:
|
||||
var start_pos: int = grid.grid.get_closest_point(global_position)
|
||||
var end_pos: int = grid.grid.get_closest_point(target_position)
|
||||
path = grid.grid.get_point_path(start_pos, end_pos)
|
||||
next_point_idx = 0
|
||||
return !path.is_empty()
|
||||
return true
|
|
@ -0,0 +1 @@
|
|||
uid://d2xsmjrclnawc
|
|
@ -8,7 +8,7 @@ func process(delta: float) -> Unit.TaskStatus:
|
|||
time_limit -= delta
|
||||
if time_limit <= 0:
|
||||
return Unit.TaskStatus.TIMED_OUT
|
||||
return Unit.TaskStatus.DONE
|
||||
return Unit.TaskStatus.IN_PROGRESS
|
||||
|
||||
class MoveAction extends UnitAction:
|
||||
var last_distance_to_target: float = 99999999.9
|
||||
|
@ -119,3 +119,42 @@ class RepairAction extends UnitAction:
|
|||
building.hp = building.max_hp
|
||||
return Unit.TaskStatus.DONE
|
||||
return Unit.TaskStatus.IN_PROGRESS
|
||||
|
||||
class AttackUnitAction extends UnitAction:
|
||||
var victim: Node3D
|
||||
|
||||
var attacking: bool = false
|
||||
|
||||
func _init() -> void:
|
||||
time_limit = 3.0
|
||||
|
||||
func process(delta: float) -> Unit.TaskStatus:
|
||||
var status: Unit.TaskStatus = super(delta)
|
||||
if status != Unit.TaskStatus.IN_PROGRESS:
|
||||
return status
|
||||
if victim == null or victim.is_queued_for_deletion():
|
||||
return Unit.TaskStatus.IMPOSSIBLE
|
||||
var distance: float = unit.global_position.distance_to(victim.global_position)
|
||||
var towards_victim: Vector3 = (unit.global_position - victim.global_position).normalized()
|
||||
if !attacking:
|
||||
unit.target_velocity = towards_victim * unit.max_speed
|
||||
if distance >= unit.attack_runup_distance:
|
||||
attacking = true
|
||||
unit.jump(victim.global_position)
|
||||
unit.target_velocity = Vector3()
|
||||
return Unit.TaskStatus.IN_PROGRESS
|
||||
else:
|
||||
var colliding: Array[Node3D] = unit.get_colliding_bodies()
|
||||
for collider in colliding:
|
||||
var hit_unit: Unit = collider as Unit
|
||||
if hit_unit != null:
|
||||
hit_unit.hurt(unit.attack_damage)
|
||||
return Unit.TaskStatus.DONE
|
||||
var hit_building: Building = collider as Building
|
||||
if hit_building != null:
|
||||
hit_building.hurt(unit.attack_damage)
|
||||
return Unit.TaskStatus.DONE
|
||||
#if unit.shapecast_3d.is_colliding():
|
||||
return Unit.TaskStatus.IN_PROGRESS
|
||||
|
||||
|
||||
|
|
|
@ -6,12 +6,34 @@ var sighted: bool = true:
|
|||
sighted = val
|
||||
visible = sighted
|
||||
|
||||
var target_citizen: Citizen = null
|
||||
|
||||
func _ready() -> void:
|
||||
sighted = false
|
||||
var target_citizen: Citizen = get_tree().get_nodes_in_group("Citizens").pick_random() as Citizen
|
||||
if target_citizen != null:
|
||||
var chase_action: UnitAction.ChaseAction = UnitAction.ChaseAction.new()
|
||||
chase_action.unit = self
|
||||
chase_action.target = target_citizen
|
||||
action = chase_action
|
||||
|
||||
#go_to_destination(Vector3(17,1,15))
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
super(delta)
|
||||
|
||||
if target_citizen == null:
|
||||
target_citizen = get_tree().get_nodes_in_group("Citizens").pick_random() as Citizen
|
||||
|
||||
if target_citizen != null:
|
||||
var chase_action: UnitAction.ChaseAction = UnitAction.ChaseAction.new()
|
||||
chase_action.unit = self
|
||||
chase_action.target = target_citizen
|
||||
action = chase_action
|
||||
|
||||
var status: Unit.TaskStatus = await wait_for_task_update()
|
||||
if status != TaskStatus.DONE:
|
||||
target_citizen = null
|
||||
return
|
||||
|
||||
var attack_action: UnitAction.AttackUnitAction = UnitAction.AttackUnitAction.new()
|
||||
attack_action.unit = self
|
||||
attack_action.victim = target_citizen
|
||||
action = attack_action
|
||||
|
||||
status = await wait_for_task_update()
|
||||
target_citizen = null
|
||||
|
|
|
@ -4,6 +4,12 @@ class_name Unit
|
|||
@export_group("Defence")
|
||||
@export var max_hp: float = 100
|
||||
|
||||
@export_group("Attack", "attack")
|
||||
@export var attack_damage: float = 15.0
|
||||
@export var attack_runup_distance: float = 4.0;
|
||||
@export var attack_lunge_impulse_forward: float = 20.0;
|
||||
@export var attack_lunge_impulse_upward: float = 5.0;
|
||||
|
||||
@export_group("Movement")
|
||||
@export var movement_force: float = 100
|
||||
@export var rotation_torque: float = 3
|
||||
|
@ -86,6 +92,11 @@ func hurt(damage: float) -> void:
|
|||
func die() -> void:
|
||||
interrupt()
|
||||
queue_free()
|
||||
|
||||
func jump(towards: Vector3) -> void:
|
||||
# TODO: use trajectory prediction to accurately aim at the target
|
||||
var direction: Vector3 = (towards - global_position).normalized()
|
||||
apply_central_impulse((direction * attack_lunge_impulse_forward) + Vector3.UP * attack_lunge_impulse_upward)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if shapecast_3d.is_colliding():
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
extends Resource
|
||||
class_name WaveData
|
||||
|
||||
@export var delay: float = 180.0
|
||||
@export var enemies: Dictionary[String, int] = {}
|
||||
@export var duration: float
|
||||
@export var bunching: int = 1
|
|
@ -0,0 +1 @@
|
|||
uid://clijm653tl81h
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -227,5 +227,4 @@ metadata/_editor_floor_ = Vector3(0, 1, 0)
|
|||
|
||||
[node name="Node3D" type="Node3D" parent="GridMap"]
|
||||
script = ExtResource("1_jwgur")
|
||||
nav_point_offset = Vector3(0, 0.5, 0)
|
||||
collider_shape = SubResource("SphereShape3D_jwgur")
|
||||
|
|
Loading…
Reference in New Issue