feat: add weak-villager and damaged-roof village needs

This commit is contained in:
Rijad Zuzo
2026-08-11 00:32:22 +02:00
parent 37f262fb84
commit 82e44a9f5d
10 changed files with 547 additions and 45 deletions
+2 -2
View File
@@ -95,13 +95,13 @@ static func from_dictionary(record_data: Dictionary) -> OpportunityStateRecord:
if opportunity_id < 0 or created_tick < 0 or trigger_event_id < 0 or interested_npc_id < 0:
return null
match opportunity_type:
SimulationIds.OPPORTUNITY_RESTOCK_EMPTY_PANTRY:
SimulationIds.OPPORTUNITY_RESTOCK_EMPTY_PANTRY, SimulationIds.OPPORTUNITY_FEED_WEAK_VILLAGER:
if (
target_id != SimulationIds.STORAGE_VILLAGE_PANTRY
or resource_id != SimulationIds.RESOURCE_FOOD
):
return null
SimulationIds.OPPORTUNITY_SUPPLY_MISSING_WOOD:
SimulationIds.OPPORTUNITY_SUPPLY_MISSING_WOOD, SimulationIds.OPPORTUNITY_REPAIR_HOME_ROOF:
if (
target_id != SimulationIds.STORAGE_VILLAGE_WOODPILE
or resource_id != SimulationIds.RESOURCE_WOOD
+61 -10
View File
@@ -573,6 +573,12 @@ static func _is_valid_opportunity(
SimulationIds.OPPORTUNITY_SUPPLY_MISSING_WOOD:
if not _is_valid_missing_wood_trigger(trigger_event, opportunity, npc_ids):
return false
SimulationIds.OPPORTUNITY_FEED_WEAK_VILLAGER:
if not _is_valid_weak_trigger(trigger_event, opportunity, npc_ids):
return false
SimulationIds.OPPORTUNITY_REPAIR_HOME_ROOF:
if not _is_valid_home_damaged_trigger(trigger_event, opportunity, npc_ids):
return false
_:
return false
var trigger_tick := int(trigger_event.data["tick"])
@@ -594,25 +600,41 @@ static func _is_valid_opportunity(
"%d:%d" % [opportunity.get_interested_npc_id(), opportunity.get_trigger_event_id()]
)
var evidence := knowledge_records_by_key.get(evidence_key) as KnownEventStateRecord
var is_weak_need := (
opportunity.get_opportunity_type() == SimulationIds.OPPORTUNITY_FEED_WEAK_VILLAGER
)
var interested_alive := (
interested_record != null and not bool(interested_record.data["is_dead"])
)
var storage_satisfied := (
is_weak_need
or (
target_storage != null
and (
target_storage.get_amount(opportunity.get_resource_id())
< opportunity.get_target_amount()
)
)
)
return (
resolution_event_id == OpportunityStateRecord.NO_EVENT_ID
and resolved_tick == -1
and interested_record != null
and (
opportunity.get_opportunity_type() != SimulationIds.OPPORTUNITY_SUPPLY_MISSING_WOOD
or not bool(interested_record.data["is_dead"])
)
and interested_alive
and target_storage != null
and (
target_storage.get_amount(opportunity.get_resource_id())
< opportunity.get_target_amount()
)
and storage_satisfied
and evidence != null
and evidence.get_acquired_tick() <= created_tick
)
if status == OpportunityStateRecord.STATUS_INVALIDATED:
if (
opportunity.get_opportunity_type() != SimulationIds.OPPORTUNITY_SUPPLY_MISSING_WOOD
(
opportunity.get_opportunity_type()
not in [
SimulationIds.OPPORTUNITY_SUPPLY_MISSING_WOOD,
SimulationIds.OPPORTUNITY_FEED_WEAK_VILLAGER,
SimulationIds.OPPORTUNITY_REPAIR_HOME_ROOF,
]
)
or resolution_event_id != OpportunityStateRecord.NO_EVENT_ID
or resolved_tick != -1
or opportunity.get_closed_tick() < created_tick
@@ -681,6 +703,26 @@ static func _is_valid_pantry_empty_trigger(event: EconomicEventRecord, npc_ids:
)
static func _is_valid_weak_trigger(
event: EconomicEventRecord, opportunity: OpportunityStateRecord, npc_ids: Dictionary
) -> bool:
return (
npc_ids.has(int(event.data["actor_id"]))
and int(event.data["actor_id"]) == opportunity.get_interested_npc_id()
and StringName(event.data["event_type"]) == SimulationIds.EVENT_VILLAGER_WEAK
)
static func _is_valid_home_damaged_trigger(
event: EconomicEventRecord, opportunity: OpportunityStateRecord, npc_ids: Dictionary
) -> bool:
return (
npc_ids.has(int(event.data["actor_id"]))
and int(event.data["actor_id"]) == opportunity.get_interested_npc_id()
and StringName(event.data["event_type"]) == SimulationIds.EVENT_HOME_DAMAGED
)
static func _is_valid_relationship_cause(
cause_event: EconomicEventRecord, subject_id: int, is_player_subject: bool
) -> bool:
@@ -721,6 +763,15 @@ static func _is_valid_supply_resolution(
) -> bool:
var actor_id := int(event.data["actor_id"])
var event_type := StringName(event.data["event_type"])
if (
opportunity.get_opportunity_type() == SimulationIds.OPPORTUNITY_FEED_WEAK_VILLAGER
and event_type == SimulationIds.EVENT_ITEM_CONSUMED
):
return (
actor_id == opportunity.get_interested_npc_id()
and StringName(event.data["item_id"]) == SimulationIds.RESOURCE_FOOD
and float(event.data["amount"]) > 0.0
)
if (
StringName(event.data["destination_id"]) != opportunity.get_target_id()
or StringName(event.data["item_id"]) != opportunity.get_resource_id()