feat: add physical animal care delivery
This commit is contained in:
@@ -3,6 +3,7 @@ extends Node
|
||||
const SimulationEventLogScript := preload("res://simulation/events/SimulationEventLog.gd")
|
||||
const VillageEconomyScript := preload("res://simulation/economy/VillageEconomy.gd")
|
||||
const AnimalCareSystemScript := preload("res://simulation/animals/animal_care_system.gd")
|
||||
const NpcTickDebugLog := preload("res://simulation/debug/npc_tick_debug_log.gd")
|
||||
const RelationshipSystemScript := preload("res://simulation/relationships/RelationshipSystem.gd")
|
||||
const EventKnowledgeSystemScript := preload("res://simulation/knowledge/EventKnowledgeSystem.gd")
|
||||
|
||||
@@ -187,6 +188,13 @@ func _simulate_npc_tick(npc: SimNPC) -> bool:
|
||||
var was_complete := npc.task_complete
|
||||
var was_dead := npc.is_dead
|
||||
|
||||
if animal_care.requires_working_feed_recovery(npc):
|
||||
npc.task_state = SimNPC.TASK_STATE_TRAVELING
|
||||
npc.task_complete = false
|
||||
if not _continue_animal_feed_delivery(npc):
|
||||
_redirect_npc_to_wander(npc)
|
||||
return false
|
||||
|
||||
action_executor.advance_npc(npc, village)
|
||||
_population_view.refresh_npc(npc)
|
||||
_select_action_if_idle(npc, previous_state)
|
||||
@@ -205,7 +213,8 @@ func _simulate_npc_tick(npc: SimNPC) -> bool:
|
||||
_complete_current_action(npc)
|
||||
_population_view.refresh_npc(npc)
|
||||
|
||||
_debug_npc_tick(npc, previous_state)
|
||||
if debug_logs:
|
||||
NpcTickDebugLog.print_tick(npc, previous_state)
|
||||
return completed
|
||||
|
||||
|
||||
@@ -333,45 +342,6 @@ func _complete_resource_gather(npc: SimNPC, completed_task: StringName) -> void:
|
||||
release_npc_reservation(npc.id)
|
||||
|
||||
|
||||
func _debug_npc_tick(npc: SimNPC, previous_state: StringName) -> void:
|
||||
if not debug_logs:
|
||||
return
|
||||
print(
|
||||
npc.npc_name,
|
||||
" | ",
|
||||
npc.profession,
|
||||
" | task: ",
|
||||
npc.current_task,
|
||||
" | state: ",
|
||||
npc.task_state,
|
||||
" | progress: ",
|
||||
npc.task_progress,
|
||||
"/",
|
||||
npc.task_duration,
|
||||
" | complete: ",
|
||||
npc.task_complete,
|
||||
" | hunger: ",
|
||||
round(npc.hunger),
|
||||
" | energy: ",
|
||||
round(npc.energy),
|
||||
" | starving: ",
|
||||
npc.is_starving,
|
||||
" | starvation_ticks: ",
|
||||
npc.starvation_ticks,
|
||||
" | dead: ",
|
||||
npc.is_dead
|
||||
)
|
||||
if previous_state != npc.task_state:
|
||||
print(
|
||||
"[SimulationManager] State changed: ",
|
||||
npc.npc_name,
|
||||
" ",
|
||||
previous_state,
|
||||
" -> ",
|
||||
npc.task_state
|
||||
)
|
||||
|
||||
|
||||
func release_npc_reservation(npc_id: int) -> void:
|
||||
for npc in npcs:
|
||||
if npc.id == npc_id:
|
||||
@@ -406,13 +376,7 @@ func notify_npc_arrived(npc_id: int) -> void:
|
||||
or resource_state.get_reserved_by() != npc.id
|
||||
):
|
||||
if debug_logs:
|
||||
print(
|
||||
"[SimulationManager] ",
|
||||
npc.npc_name,
|
||||
" arrived but target ",
|
||||
npc.target_id,
|
||||
" is unavailable, replanning"
|
||||
)
|
||||
NpcTickDebugLog.print_unavailable_resource(npc)
|
||||
notify_npc_navigation_failed(npc.id)
|
||||
return
|
||||
if (
|
||||
@@ -422,18 +386,19 @@ func notify_npc_arrived(npc_id: int) -> void:
|
||||
):
|
||||
if not animal_care.can_complete_feed(npc.target_id, npc.id):
|
||||
if debug_logs:
|
||||
print(
|
||||
"[SimulationManager] ",
|
||||
npc.npc_name,
|
||||
" arrived but animal ",
|
||||
npc.target_id,
|
||||
" no longer needs feeding, replanning"
|
||||
)
|
||||
NpcTickDebugLog.print_unavailable_animal(npc)
|
||||
notify_npc_navigation_failed(npc.id)
|
||||
return
|
||||
if animal_care.requires_feed_pickup(npc):
|
||||
if _continue_animal_feed_delivery(npc):
|
||||
return
|
||||
_redirect_npc_to_wander(npc)
|
||||
return
|
||||
|
||||
npc.has_travel_target = false
|
||||
npc.start_working()
|
||||
npc.start_working(
|
||||
npc.current_task == SimulationIds.ACTION_FEED_ANIMAL and npc.task_progress > 0.0
|
||||
)
|
||||
|
||||
var working_speakers: Array[SimNPC] = []
|
||||
if npc.target_id != &"":
|
||||
@@ -455,15 +420,42 @@ func notify_npc_arrived(npc_id: int) -> void:
|
||||
break
|
||||
|
||||
if debug_logs:
|
||||
print(
|
||||
"[SimulationManager] ",
|
||||
npc.npc_name,
|
||||
" arrived and started working on: ",
|
||||
npc.current_task
|
||||
)
|
||||
NpcTickDebugLog.print_started_work(npc)
|
||||
return
|
||||
|
||||
|
||||
func _continue_animal_feed_delivery(npc: SimNPC) -> bool:
|
||||
var animal_target := target_resolver.resolve_claimed_animal(npc, self, active_world_adapter)
|
||||
var pantry_target := target_resolver.resolve_storage_target(
|
||||
SimulationIds.STORAGE_VILLAGE_PANTRY, active_world_adapter
|
||||
)
|
||||
if animal_target.is_empty() or pantry_target.is_empty():
|
||||
return false
|
||||
if not npc.travel_target_position.is_equal_approx(pantry_target["position"]):
|
||||
npc.travel_target_position = pantry_target["position"]
|
||||
npc.has_travel_target = true
|
||||
npc_travel_requested.emit(npc, npc.travel_target_position)
|
||||
return true
|
||||
var pickup_target := npc.travel_target_position
|
||||
npc.travel_target_position = animal_target["position"]
|
||||
npc.has_travel_target = true
|
||||
if not animal_care.collect_feed_supply(npc):
|
||||
npc.travel_target_position = pickup_target
|
||||
return false
|
||||
village_changed.emit(village)
|
||||
npc_travel_requested.emit(npc, npc.travel_target_position)
|
||||
return true
|
||||
|
||||
|
||||
func _redirect_npc_to_wander(npc: SimNPC) -> void:
|
||||
var failed_task := npc.current_task
|
||||
release_npc_reservation(npc.id)
|
||||
npc.last_task = failed_task
|
||||
npc.set_task(SimulationIds.ACTION_WANDER, 2.0)
|
||||
npc_task_changed.emit(npc, failed_task, npc.current_task)
|
||||
npc_target_requested.emit(npc)
|
||||
|
||||
|
||||
func notify_npc_navigation_failed(npc_id: int) -> void:
|
||||
for npc in npcs:
|
||||
if npc.id != npc_id:
|
||||
@@ -472,20 +464,10 @@ func notify_npc_navigation_failed(npc_id: int) -> void:
|
||||
return
|
||||
|
||||
var failed_task := npc.current_task
|
||||
release_npc_reservation(npc.id)
|
||||
npc.last_task = failed_task
|
||||
npc.set_task(SimulationIds.ACTION_WANDER, 2.0)
|
||||
npc_task_changed.emit(npc, failed_task, npc.current_task)
|
||||
npc_target_requested.emit(npc)
|
||||
_redirect_npc_to_wander(npc)
|
||||
|
||||
if debug_logs:
|
||||
print(
|
||||
"[SimulationManager] ",
|
||||
npc.npc_name,
|
||||
" could not navigate for ",
|
||||
failed_task,
|
||||
" and is trying a wander target"
|
||||
)
|
||||
NpcTickDebugLog.print_navigation_failure(npc, failed_task)
|
||||
return
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user