summaryrefslogtreecommitdiff
path: root/Mob.gd
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2024-08-25 23:47:22 +0200
committerDaniel Weipert <git@mail.dweipert.de>2024-08-25 23:47:22 +0200
commitcf4f54f8e43d1deb03e1b644f6a374530efa11e3 (patch)
tree7003af7af09775f09dda2164c4b16faa05a1290f /Mob.gd
parent8d4e709f7e2390e06c3e412c20662e8bc21f0d0c (diff)
next commit
Diffstat (limited to 'Mob.gd')
-rw-r--r--Mob.gd124
1 files changed, 91 insertions, 33 deletions
diff --git a/Mob.gd b/Mob.gd
index f582ccd..a83a119 100644
--- a/Mob.gd
+++ b/Mob.gd
@@ -2,12 +2,15 @@ class_name Mob
extends CharacterBody2D
+signal selected
+
static var selected_unit: Mob
var is_selected = false :
set(value):
if value:
Mob.selected_unit = self
+ selected.emit()
else:
if Mob.selected_unit == self:
Mob.selected_unit = null
@@ -19,12 +22,24 @@ var is_hovered = false :
is_hovered = value
queue_redraw()
-var target: Vector2
+var target: Node2D :
+ set(value):
+ target = value
+ reset_path()
var immediate_target: Vector2
-var path: PackedVector2Array
+var current_path: PackedVector2Array
var current_path_idx = 0
+var previous_path: PackedVector2Array
+var previous_path_idx = 0
+
+var previous_position: Vector2
+
+var recent_closest_paths: Array[PackedVector2Array]
+
+var roaming_mode = false
+
@export var speed: float = 100
@export var hp = 50
@@ -33,46 +48,39 @@ var current_path_idx = 0
# Called when the node enters the scene tree for the first time.
func _ready():
if not target:
- print("No target!")
- set_process(false)
- queue_free()
-
- path = Game.path_grid.get_point_path(Game.map.local_to_map(global_position), Game.map.local_to_map(target))
+ target = get_tree().current_scene.find_child("Goal")
+ reset_path()
Game.path_grid_changed.connect(func():
- path = Game.path_grid.get_point_path(Game.map.local_to_map(global_position), Game.map.local_to_map(target))
- current_path_idx = min(1, path.size() - 1)
+ reset_path()
+ current_path_idx = min(1, current_path.size() - 1)
)
- %HP.max_value = hp
+ %HPBar.init(hp)
set_hp(hp)
func _physics_process(delta):
- # TODO: if path is empty
- # TODO: change state to "AttackClosestTowerState"
- # TODO: get all towers, sort by distance to mob
- # TODO: walk to and attack/destroy closest tower
- # TODO: repeat, unless =>
- # TODO: check path every frame if still closed off (empty)
- # TODO: if path not empty anymore change state to walk next path
+ previous_position = global_position
- if not path.is_empty():
- if (global_position - path[current_path_idx]).is_zero_approx():
+ if not current_path.is_empty():
+ if (global_position - current_path[current_path_idx]).is_zero_approx():
current_path_idx += 1
- if current_path_idx >= path.size():
- path = Game.path_grid.get_point_path(Game.map.local_to_map(global_position), Game.map.local_to_map(target))
- current_path_idx = 0
+ if current_path_idx >= current_path.size():
+ reset_path()
+
+ walk_along_path(current_path, current_path_idx, delta)
- #var displacement := target - global_transform.origin
- immediate_target = path[current_path_idx]
- var displacement := (path[current_path_idx]) - global_position
- var direction := displacement.normalized()
- var distance := displacement.length()
-
- var max_speed: float = (distance / delta)
- velocity = direction * minf(speed, max_speed)
- move_and_slide()
+ if roaming_mode:
+ var collision = get_last_slide_collision()
+ if collision:
+ var tower = collision.get_collider() as Node2D
+ Game.destroy_tower(tower)
+
+ # if unit stuck in tower
+ if previous_position == global_position: # doesn't work with 0.05 fluctuating position
+ reset_path()
+ roaming_mode = true
func _draw():
@@ -100,15 +108,28 @@ func _draw():
func _on_navigation_base_area_entered(area: Area2D):
if area.is_in_group("goal"):
+ Game.score += 1
queue_free()
if area.is_in_group("path"):
var path_node = area.get_parent()
- target = path_node.next_node.global_position
+ if path_node == target:
+ target = path_node.next_node
+
+
+func walk_along_path(path: PackedVector2Array, index: int, delta: float):
+ immediate_target = path[index]
+ var displacement := (path[index]) - global_position
+ var direction := displacement.normalized()
+ var distance := displacement.length()
+
+ var max_speed: float = (distance / delta)
+ velocity = direction * minf(speed, max_speed)
+ move_and_slide()
func set_hp(value):
hp = value
- %HP.value = value
+ %HPBar.set_value(value)
if is_selected:
$Label.text = str(hp)
@@ -119,6 +140,43 @@ func set_hp(value):
queue_free()
+func reset_path():
+ roaming_mode = false
+ current_path = get_grid_path()
+
+ if current_path.is_empty():
+ current_path = get_grid_path(true)
+ recent_closest_paths.append(current_path)
+
+ # reached end of partial path
+ if current_path.size() == 1 and current_path[0] == global_position:
+ roaming_mode = true
+ current_path = PackedVector2Array([target.global_position])
+
+ # iterating between one or more closest paths
+ elif recent_closest_paths.count(current_path) >= 2:
+ roaming_mode = true
+ current_path = PackedVector2Array([target.global_position])
+ recent_closest_paths = []
+ else:
+ recent_closest_paths = []
+ roaming_mode = false
+
+ current_path_idx = 0
+
+func get_grid_path(partial = false):
+ #return Game.path_grid.get_point_path(
+ #Game.map.local_to_map(global_position) * 2,
+ #Game.map.local_to_map(target.global_position) * 2,
+ #partial
+ #)
+ return Game.path_grid.get_point_path(
+ Game.map.local_to_map(global_position),
+ Game.map.local_to_map(target.global_position),
+ partial
+ )
+
+
func _on_input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
if Game.mode == Game.Mode.DEFAULT:
if event.is_action_pressed("select"):