feat: surface player routes for village needs
This commit is contained in:
@@ -782,24 +782,14 @@ func get_relationship_cause(relationship: RelationshipStateRecord) -> EconomicEv
|
||||
|
||||
|
||||
func get_known_events(npc_id: int, max_count: int = 3) -> Array[EconomicEventRecord]:
|
||||
var known: Array[EconomicEventRecord] = []
|
||||
for event_id in event_knowledge_system.get_known_event_ids(npc_id, max_count):
|
||||
var event := event_log.get_by_id(event_id)
|
||||
if event != null:
|
||||
known.append(event)
|
||||
return known
|
||||
return event_log.get_by_ids(event_knowledge_system.get_known_event_ids(npc_id, max_count))
|
||||
|
||||
|
||||
func get_retained_memory_events(npc_id: int, max_count: int = 4) -> Array[EconomicEventRecord]:
|
||||
var retained: Array[EconomicEventRecord] = []
|
||||
var event_ids := event_knowledge_system.get_retained_event_ids(
|
||||
npc_id, _get_lasting_event_ids(npc_id), max_count
|
||||
)
|
||||
for event_id in event_ids:
|
||||
var event := event_log.get_by_id(event_id)
|
||||
if event != null:
|
||||
retained.append(event)
|
||||
return retained
|
||||
return event_log.get_by_ids(event_ids)
|
||||
|
||||
|
||||
func get_active_opportunity() -> OpportunityStateRecord:
|
||||
@@ -820,18 +810,26 @@ func get_active_opportunity_helper() -> OpportunityHelperResult:
|
||||
)
|
||||
|
||||
|
||||
func get_active_opportunity_player_response() -> OpportunityPlayerResponseResult:
|
||||
var active := get_active_opportunity()
|
||||
if active == null:
|
||||
return null
|
||||
var helper := get_active_opportunity_helper()
|
||||
return opportunity_system.find_player_response(
|
||||
active, economy.get_storage(active.get_target_id()), resource_states, helper != null
|
||||
)
|
||||
|
||||
|
||||
func get_latest_opportunity_for_npc(npc_id: int) -> OpportunityStateRecord:
|
||||
return opportunity_system.get_latest_for_npc(npc_id)
|
||||
|
||||
|
||||
func get_opportunity_trigger_event(opportunity: OpportunityStateRecord) -> EconomicEventRecord:
|
||||
var event_id := opportunity.get_trigger_event_id() if opportunity != null else -1
|
||||
return event_log.get_by_id(event_id)
|
||||
return event_log.get_by_id(opportunity.get_trigger_event_id() if opportunity != null else -1)
|
||||
|
||||
|
||||
func get_opportunity_resolution_event(opportunity: OpportunityStateRecord) -> EconomicEventRecord:
|
||||
var event_id := opportunity.get_resolution_event_id() if opportunity != null else -1
|
||||
return event_log.get_by_id(event_id)
|
||||
return event_log.get_by_id(opportunity.get_resolution_event_id() if opportunity != null else -1)
|
||||
|
||||
|
||||
func npc_knows_event(npc_id: int, event_id: int) -> bool:
|
||||
|
||||
@@ -91,6 +91,15 @@ func get_by_id(event_id: int) -> EconomicEventRecord:
|
||||
return null
|
||||
|
||||
|
||||
func get_by_ids(event_ids: Array[int]) -> Array[EconomicEventRecord]:
|
||||
var results: Array[EconomicEventRecord] = []
|
||||
for event_id in event_ids:
|
||||
var event := get_by_id(event_id)
|
||||
if event != null:
|
||||
results.append(event)
|
||||
return results
|
||||
|
||||
|
||||
func get_consumption_rates(
|
||||
current_tick: int,
|
||||
window_ticks: int = DEFAULT_RATE_WINDOW_TICKS,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
class_name OpportunityPlayerResponseResult
|
||||
extends RefCounted
|
||||
|
||||
var opportunity_id: int
|
||||
var trigger_event_id: int
|
||||
var action_id: StringName
|
||||
var resource_id: StringName
|
||||
var target_id: StringName
|
||||
var available_source_count: int
|
||||
var reason: String
|
||||
|
||||
|
||||
func _init(result: Dictionary) -> void:
|
||||
opportunity_id = int(result["opportunity_id"])
|
||||
trigger_event_id = int(result["trigger_event_id"])
|
||||
action_id = StringName(result["action_id"])
|
||||
resource_id = StringName(result["resource_id"])
|
||||
target_id = StringName(result["target_id"])
|
||||
available_source_count = int(result["available_source_count"])
|
||||
reason = String(result["reason"])
|
||||
@@ -0,0 +1 @@
|
||||
uid://2nyepaa3b77v
|
||||
@@ -193,6 +193,62 @@ func find_capable_helper(
|
||||
)
|
||||
|
||||
|
||||
func find_player_response(
|
||||
opportunity: OpportunityStateRecord,
|
||||
target_storage: StorageStateRecord,
|
||||
resource_states: Dictionary,
|
||||
has_capable_helper: bool
|
||||
) -> OpportunityPlayerResponseResult:
|
||||
if (
|
||||
opportunity == null
|
||||
or not opportunity.is_open()
|
||||
or target_storage == null
|
||||
or target_storage.get_storage_id() != opportunity.get_target_id()
|
||||
or has_capable_helper
|
||||
):
|
||||
return null
|
||||
var remaining := maxf(
|
||||
opportunity.get_target_amount() - target_storage.get_amount(opportunity.get_resource_id()),
|
||||
0.0
|
||||
)
|
||||
if remaining <= 0.0 or target_storage.get_available_capacity() < remaining:
|
||||
return null
|
||||
var action_ids := _get_supply_action_ids(opportunity.get_resource_id())
|
||||
if action_ids.is_empty():
|
||||
return null
|
||||
var gather_definition := SimulationDefinitions.get_action(action_ids["gather"])
|
||||
if gather_definition == null:
|
||||
return null
|
||||
var available_source_count := _count_player_resource_sources(
|
||||
remaining, opportunity.get_resource_id(), gather_definition, resource_states
|
||||
)
|
||||
if available_source_count == 0:
|
||||
return null
|
||||
return (
|
||||
OpportunityPlayerResponseResult
|
||||
. new(
|
||||
{
|
||||
"opportunity_id": opportunity.get_opportunity_id(),
|
||||
"trigger_event_id": opportunity.get_trigger_event_id(),
|
||||
"action_id": gather_definition.action_id,
|
||||
"resource_id": opportunity.get_resource_id(),
|
||||
"target_id": target_storage.get_storage_id(),
|
||||
"available_source_count": available_source_count,
|
||||
"reason":
|
||||
(
|
||||
"No capable helper; %d player-usable finite %s source%s can supply %s"
|
||||
% [
|
||||
available_source_count,
|
||||
String(opportunity.get_resource_id()).capitalize(),
|
||||
"" if available_source_count == 1 else "s",
|
||||
String(target_storage.get_storage_id()),
|
||||
]
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
func _build_helper_candidate(
|
||||
npc: SimNPC,
|
||||
opportunity: OpportunityStateRecord,
|
||||
@@ -299,6 +355,29 @@ static func _count_available_resource_sources(
|
||||
return count
|
||||
|
||||
|
||||
static func _count_player_resource_sources(
|
||||
remaining: float,
|
||||
resource_id: StringName,
|
||||
gather_definition: ActionDefinition,
|
||||
resource_states: Dictionary
|
||||
) -> int:
|
||||
var count := 0
|
||||
for value in resource_states.values():
|
||||
var state := value as ResourceStateRecord
|
||||
if (
|
||||
state == null
|
||||
or state.get_action_id() != gather_definition.resource_action_id
|
||||
or state.get_resource_id() != resource_id
|
||||
or not state.can_player_use_resource()
|
||||
or not state.can_extract()
|
||||
or state.get_yield_per_action() <= 0.0
|
||||
or state.get_amount_remaining() < remaining
|
||||
):
|
||||
continue
|
||||
count += 1
|
||||
return count
|
||||
|
||||
|
||||
static func _sort_helper_candidates(first: Dictionary, second: Dictionary) -> bool:
|
||||
if first["uses_inventory"] != second["uses_inventory"]:
|
||||
return bool(first["uses_inventory"])
|
||||
|
||||
Reference in New Issue
Block a user