158 lines
4.9 KiB
GDScript
158 lines
4.9 KiB
GDScript
extends Node
|
|
|
|
const PLAYER_GROUP := "player"
|
|
const ENEMY_NAME_PATTERN := "%s%d"
|
|
@export var max_enemies: int = 3
|
|
@export var enemies_container: Node
|
|
@export var enemy_scenes: Array[PackedScene]
|
|
@export var enemies_ui_manager: Node
|
|
@export var spawn_points_container: Node
|
|
|
|
const ENEMY_SCENE_PATHS := [
|
|
"res://packed-scenes/skeleton_warrior.tscn"
|
|
# Weitere Enemy-Szenen hier hinzufügen
|
|
]
|
|
|
|
var player: Player
|
|
var current_enemies: Array[Enemy] = []
|
|
var _enemy_counter: int = 0
|
|
var _enemy_ui_ready: bool = false
|
|
var spawn_points: Array[SpawnPoint] = []
|
|
|
|
var enemy_ui_ready: bool:
|
|
get:
|
|
return _enemy_ui_ready
|
|
set(value):
|
|
_enemy_ui_ready = value
|
|
if value:
|
|
maintain_enemy_quota()
|
|
|
|
|
|
func _ready() -> void:
|
|
player = get_tree().get_first_node_in_group(PLAYER_GROUP)
|
|
if player == null:
|
|
print("Error: No player found!")
|
|
|
|
# Lade Enemy-Szenen automatisch, falls nicht zugewiesen
|
|
func load_default_enemy_scenes() -> void:
|
|
push_warning("No enemy scenes configured. Loading default enemy scenes...")
|
|
for path in ENEMY_SCENE_PATHS:
|
|
if ResourceLoader.exists(path):
|
|
var scene := load(path) as PackedScene
|
|
if scene != null:
|
|
enemy_scenes.append(scene)
|
|
print("Loaded enemy scene: %s" % path)
|
|
else:
|
|
push_warning("Enemy scene not found: %s" % path)
|
|
|
|
if enemy_scenes.is_empty():
|
|
push_error("Could not load any enemy scenes!")
|
|
|
|
# Sammelt SpawnPoints aus dem konfigurierten Container (falls vorhanden)
|
|
func collect_spawn_points_from_container() -> void:
|
|
if spawn_points_container == null:
|
|
push_warning("spawn_points_container is not assigned! Try to find on my own...")
|
|
spawn_points_container = get_tree().root.find_child("SpawnPointsContainer", true, false)
|
|
if spawn_points_container == null:
|
|
push_warning("spawn_points_container not found!!")
|
|
return
|
|
var collected: Array[SpawnPoint] = []
|
|
var children: Array = spawn_points_container.get_children()
|
|
for child in children:
|
|
if child is SpawnPoint:
|
|
collected.append(child)
|
|
spawn_points = collected
|
|
|
|
|
|
# Hält die Anzahl der aktiven Gegner auf dem gewünschten Soll
|
|
func maintain_enemy_quota() -> void:
|
|
var current := current_enemies.size()
|
|
print("Enemy quota: %d/%d" % [current, max_enemies])
|
|
if current >= max_enemies:
|
|
return
|
|
var empty_points := find_empty_spawn_points()
|
|
if empty_points.is_empty():
|
|
print("No free SpawnPoints found!")
|
|
return
|
|
var required_count: int = min(max_enemies - current, empty_points.size())
|
|
for i in required_count:
|
|
spawn_enemy(empty_points[i])
|
|
|
|
|
|
func spawn_enemy(spawn_point: SpawnPoint) -> void:
|
|
if enemy_scenes.is_empty():
|
|
load_default_enemy_scenes()
|
|
var scene: PackedScene = enemy_scenes.pick_random()
|
|
if scene == null:
|
|
push_warning("No enemy scene available to spawn.")
|
|
return
|
|
var new_enemy := scene.instantiate() as Enemy
|
|
if new_enemy == null:
|
|
push_warning("PackedScene did not instantiate as Enemy.")
|
|
return
|
|
configure_enemy(new_enemy, spawn_point)
|
|
register_enemy(new_enemy, spawn_point)
|
|
update_enemies_ui()
|
|
|
|
|
|
# Stellt Eigenschaften des Gegners vor dem Hinzufügen ein
|
|
func configure_enemy(new_enemy: Enemy, spawn_point: SpawnPoint) -> void:
|
|
new_enemy.player = player
|
|
_enemy_counter += 1
|
|
new_enemy.name = ENEMY_NAME_PATTERN % [new_enemy.name, _enemy_counter]
|
|
new_enemy.unit_name = new_enemy.name
|
|
print("Spawn %s at %s" % [new_enemy.unit_name, spawn_point.name])
|
|
new_enemy.position = spawn_point.position
|
|
new_enemy.unit_died.connect(_on_unit_died)
|
|
|
|
|
|
# Fügt Gegner zur Szene hinzu und markiert den SpawnPoint
|
|
func register_enemy(new_enemy: Enemy, spawn_point: SpawnPoint) -> void:
|
|
if enemies_container == null:
|
|
push_warning("enemies_container is not assigned! Try to find on my own...")
|
|
enemies_container = get_tree().root.find_child("Enemies", true, false)
|
|
if enemies_container == null:
|
|
push_warning("enemies_container not found!!")
|
|
return
|
|
enemies_container.add_child(new_enemy)
|
|
spawn_point.is_occupied = true
|
|
spawn_point.enemy = new_enemy
|
|
current_enemies.append(new_enemy)
|
|
|
|
|
|
func update_enemies_ui() -> void:
|
|
if enemies_ui_manager != null and enemy_ui_ready:
|
|
enemies_ui_manager.rebuild_enemy_ui(current_enemies)
|
|
|
|
|
|
func find_empty_spawn_points() -> Array[SpawnPoint]:
|
|
if spawn_points.size() == 0:
|
|
collect_spawn_points_from_container()
|
|
|
|
var empty_spawn_points: Array[SpawnPoint] = []
|
|
print("Count of spawn points: " + str(spawn_points.size()))
|
|
for sp in spawn_points:
|
|
if not sp.is_occupied:
|
|
empty_spawn_points.append(sp)
|
|
else:
|
|
print("Spawn point " + sp.name + " is full!")
|
|
return empty_spawn_points
|
|
|
|
|
|
func remove_enemy(enemy: Enemy) -> void:
|
|
var index := current_enemies.find(enemy)
|
|
if index != -1:
|
|
current_enemies.remove_at(index)
|
|
else:
|
|
print("Enemy is not in the list!")
|
|
|
|
|
|
func _on_unit_died(unit: Unit) -> void:
|
|
if unit is Enemy:
|
|
print("%s died -> Remove from current_enemies." % unit.unit_name)
|
|
remove_enemy(unit)
|
|
maintain_enemy_quota()
|
|
update_enemies_ui()
|
|
else:
|
|
print("Something died which is not an enemy!")
|