147 lines
3.8 KiB
GDScript
147 lines
3.8 KiB
GDScript
extends Node
|
|
|
|
const DEBUG_LOGS := true
|
|
|
|
@export var npc_visual_scene: PackedScene
|
|
@export var simulation_manager: Node
|
|
@export var active_npcs_parent: Node3D
|
|
|
|
@export var farm_zone: Marker3D
|
|
@export var forest_zone: Marker3D
|
|
@export var guard_zone: Marker3D
|
|
@export var study_zone: Marker3D
|
|
@export var rest_zone: Marker3D
|
|
@export var food_zone: Marker3D
|
|
|
|
var active_npc_visuals := {}
|
|
|
|
func debug_log(message: String) -> void:
|
|
if DEBUG_LOGS:
|
|
print("[WorldViewManager] ", message)
|
|
|
|
func _ready() -> void:
|
|
call_deferred("initialize_world_view")
|
|
|
|
func initialize_world_view() -> void:
|
|
await get_tree().physics_frame
|
|
spawn_initial_npcs()
|
|
|
|
if simulation_manager.has_signal("npc_task_changed"):
|
|
simulation_manager.npc_task_changed.connect(_on_npc_task_changed)
|
|
else:
|
|
push_error("WorldViewManager: SimulationManager has no npc_task_changed signal")
|
|
|
|
if simulation_manager.has_signal("npc_died"):
|
|
simulation_manager.npc_died.connect(_on_npc_died)
|
|
else:
|
|
push_error("WorldViewManager: SimulationManager has no npc_died signal")
|
|
|
|
update_npc_targets()
|
|
|
|
func spawn_initial_npcs() -> void:
|
|
if simulation_manager == null:
|
|
push_error("WorldViewManager: simulation_manager is missing")
|
|
return
|
|
|
|
if npc_visual_scene == null:
|
|
push_error("WorldViewManager: npc_visual_scene is missing")
|
|
return
|
|
|
|
if active_npcs_parent == null:
|
|
push_error("WorldViewManager: active_npcs_parent is missing")
|
|
return
|
|
|
|
debug_log("Spawning NPC visuals. Count: %s" % simulation_manager.npcs.size())
|
|
|
|
for npc in simulation_manager.npcs:
|
|
spawn_npc_visual(npc)
|
|
|
|
func spawn_npc_visual(npc: SimNPC) -> void:
|
|
if active_npc_visuals.has(npc.id):
|
|
return
|
|
|
|
var visual = npc_visual_scene.instantiate()
|
|
active_npcs_parent.add_child(visual)
|
|
|
|
visual.global_position = npc.position
|
|
visual.setup_from_sim(npc)
|
|
|
|
if visual.has_signal("arrived_at_target"):
|
|
visual.arrived_at_target.connect(_on_npc_visual_arrived)
|
|
else:
|
|
push_error("WorldViewManager: NPCVisual has no arrived_at_target signal")
|
|
|
|
active_npc_visuals[npc.id] = visual
|
|
debug_log("Spawned visual for %s at %s" % [npc.npc_name, npc.position])
|
|
|
|
func update_npc_targets() -> void:
|
|
if simulation_manager == null:
|
|
return
|
|
|
|
for npc in simulation_manager.npcs:
|
|
if not active_npc_visuals.has(npc.id):
|
|
continue
|
|
|
|
var visual = active_npc_visuals[npc.id]
|
|
var target := get_target_for_task(npc.current_task)
|
|
|
|
if target == null:
|
|
debug_log("No target for task: %s" % npc.current_task)
|
|
continue
|
|
|
|
visual.set_target_position(target.global_position)
|
|
|
|
func get_target_for_task(task: String) -> Marker3D:
|
|
match task:
|
|
"gather_food":
|
|
return farm_zone
|
|
"gather_wood":
|
|
return forest_zone
|
|
"patrol":
|
|
return guard_zone
|
|
"study":
|
|
return study_zone
|
|
"rest":
|
|
return rest_zone
|
|
"eat":
|
|
return food_zone
|
|
_:
|
|
return rest_zone
|
|
|
|
func _on_npc_task_changed(npc: SimNPC, old_task: String, new_task: String) -> void:
|
|
if DEBUG_LOGS:
|
|
debug_log("%s changed task: %s -> %s" % [npc.npc_name, old_task, new_task])
|
|
|
|
if not active_npc_visuals.has(npc.id):
|
|
return
|
|
|
|
var visual = active_npc_visuals[npc.id]
|
|
var target := get_target_for_task(new_task)
|
|
|
|
if target != null:
|
|
visual.set_target_position(target.global_position)
|
|
|
|
func _on_npc_visual_arrived(sim_id: int) -> void:
|
|
debug_log("NPC visual arrived. sim_id=%s" % sim_id)
|
|
|
|
if simulation_manager == null:
|
|
push_error("WorldViewManager: simulation_manager missing during arrival report")
|
|
return
|
|
|
|
if simulation_manager.has_method("notify_npc_arrived"):
|
|
simulation_manager.notify_npc_arrived(sim_id)
|
|
else:
|
|
push_error("WorldViewManager: SimulationManager has no notify_npc_arrived method")
|
|
|
|
|
|
func _on_npc_died(npc: SimNPC) -> void:
|
|
if not active_npc_visuals.has(npc.id):
|
|
return
|
|
|
|
var visual = active_npc_visuals[npc.id]
|
|
|
|
if visual.has_method("apply_dead_visual_state"):
|
|
visual.apply_dead_visual_state()
|
|
else:
|
|
push_error("WorldViewManager: NPCVisual has no apply_dead_visual_state method")
|