xanarch-td/scripts/gameplay/Creep.gd
2026-06-03 21:53:16 -04:00

90 lines
2.3 KiB
GDScript

## Creep.gd
## Enemy unit that follows the lane path and damages the Security System on exit.
## Call assign_path() immediately after adding to the scene tree.
class_name Creep
extends Node2D
var _max_hp: int = 100
var _hp: int = 100
var _speed: float = 100.0
var _armor_type: int = DamageCalc.ArmorType.LIGHT
var _bounty: int = 5
var _hp_damage: int = 1
# Baked path points in global space
var _path: PackedVector2Array = []
var _path_index: int = 0
var _dead: bool = false
func _ready() -> void:
add_to_group("creeps")
func setup(wave_data: Dictionary) -> void:
_max_hp = wave_data.get("creep_hp", 100)
_hp = _max_hp
_speed = wave_data.get("creep_speed", 100.0)
_bounty = wave_data.get("bounty", 5)
_hp_damage = wave_data.get("hp_damage", 1)
_armor_type = wave_data.get("creep_armor", DamageCalc.ArmorType.LIGHT)
## Assign the world-space baked path from the Lane's Path2D.
func assign_path(world_points: PackedVector2Array) -> void:
_path = world_points
_path_index = 0
if _path.size() > 0:
global_position = _path[0]
func get_armor_type() -> int:
return _armor_type
func get_hp_fraction() -> float:
return float(_hp) / float(_max_hp)
func take_damage(amount: int) -> void:
if _dead:
return
_hp -= amount
_update_health_bar()
if _hp <= 0:
_die()
func _process(delta: float) -> void:
if _dead or _path.size() == 0:
return
if _path_index >= _path.size():
return
var target: Vector2 = _path[_path_index]
var dir: Vector2 = (target - global_position).normalized()
global_position += dir * _speed * delta
# Advance to next waypoint when close enough
if global_position.distance_to(target) < 3.0:
_path_index += 1
if _path_index >= _path.size():
_reach_exit()
func _die() -> void:
if _dead:
return
_dead = true
remove_from_group("creeps")
EventBus.creep_died.emit(self, _bounty)
# Award bounty to all players
for pid in Economy._minerals.keys():
Economy._minerals[pid] += _bounty
EventBus.minerals_changed.emit(pid, Economy._minerals[pid])
queue_free()
func _reach_exit() -> void:
if _dead:
return
_dead = true
remove_from_group("creeps")
EventBus.creep_reached_exit.emit(self, _hp_damage)
queue_free()
func _update_health_bar() -> void:
var bar := get_node_or_null("HealthBar") as ProgressBar
if bar:
bar.value = get_hp_fraction() * 100.0