feat: let villagers witness and trust the player restock
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
class_name SimulationIds
|
||||
extends RefCounted
|
||||
|
||||
const PLAYER_ACTOR_ID := -1
|
||||
|
||||
const ACTION_IDLE := &"idle"
|
||||
const ACTION_DEAD := &"dead"
|
||||
const ACTION_SLEEP := &"sleep"
|
||||
|
||||
@@ -11,20 +11,25 @@ func observe_event(event: EconomicEventRecord, npcs: Array[SimNPC]) -> Array[Kno
|
||||
var learned: Array[KnownEventStateRecord] = []
|
||||
if not is_knowable_event(event):
|
||||
return learned
|
||||
var actor := _find_npc(int(event.data["actor_id"]), npcs)
|
||||
if actor == null:
|
||||
var actor_id := int(event.data["actor_id"])
|
||||
var is_player_actor := actor_id == SimulationIds.PLAYER_ACTOR_ID
|
||||
var actor := null if is_player_actor else _find_npc(actor_id, npcs)
|
||||
if actor == null and not is_player_actor:
|
||||
return learned
|
||||
var event_id := int(event.data["event_id"])
|
||||
var acquired_tick := int(event.data["tick"])
|
||||
var actor_record := _remember(
|
||||
actor.id, event_id, SimulationIds.KNOWLEDGE_ACQUISITION_PERFORMED, acquired_tick
|
||||
)
|
||||
if actor_record != null:
|
||||
learned.append(actor_record)
|
||||
if actor != null:
|
||||
var actor_record := _remember(
|
||||
actor.id, event_id, SimulationIds.KNOWLEDGE_ACQUISITION_PERFORMED, acquired_tick
|
||||
)
|
||||
if actor_record != null:
|
||||
learned.append(actor_record)
|
||||
var witness_radius_squared := WITNESS_RADIUS * WITNESS_RADIUS
|
||||
var event_position := event.get_world_position()
|
||||
for npc in npcs:
|
||||
if npc.id == actor.id or npc.is_dead:
|
||||
if npc.is_dead:
|
||||
continue
|
||||
if not is_player_actor and npc.id == actor.id:
|
||||
continue
|
||||
if npc.position.distance_squared_to(event_position) > witness_radius_squared:
|
||||
continue
|
||||
@@ -247,6 +252,17 @@ static func is_knowable_event(event: EconomicEventRecord) -> bool:
|
||||
return false
|
||||
if event_type == SimulationIds.EVENT_STORAGE_DEPOSITED:
|
||||
return item_id == SimulationIds.RESOURCE_FOOD
|
||||
if event_type == SimulationIds.EVENT_RESOURCE_EXTRACTED:
|
||||
var player_actor_id := int(event.data["actor_id"])
|
||||
if player_actor_id != SimulationIds.PLAYER_ACTOR_ID:
|
||||
return false
|
||||
return (
|
||||
StringName(event.data["destination_id"])
|
||||
in [
|
||||
SimulationIds.STORAGE_VILLAGE_PANTRY,
|
||||
SimulationIds.STORAGE_VILLAGE_WOODPILE,
|
||||
]
|
||||
)
|
||||
if event_type != SimulationIds.EVENT_STORAGE_WITHDRAWN:
|
||||
return false
|
||||
var actor_id := int(event.data["actor_id"])
|
||||
|
||||
@@ -4,6 +4,7 @@ const AID_HUNGER_THRESHOLD := 80.0
|
||||
const TRUSTED_HELP_THRESHOLD := 0.6
|
||||
const FOOD_AID_TRUST_GAIN := 0.15
|
||||
const SHARED_WORK_FAMILIARITY_GAIN := 0.1
|
||||
const PLAYER_FAMILIARITY_SEED := 0.5
|
||||
|
||||
var relationships: Dictionary = {}
|
||||
|
||||
@@ -58,23 +59,47 @@ func apply_event(
|
||||
event: EconomicEventRecord, npcs: Array[SimNPC], knower_ids: Array[int]
|
||||
) -> Array[RelationshipStateRecord]:
|
||||
var changed: Array[RelationshipStateRecord] = []
|
||||
if StringName(event.data["event_type"]) != SimulationIds.EVENT_STORAGE_DEPOSITED:
|
||||
return changed
|
||||
if StringName(event.data["item_id"]) != SimulationIds.RESOURCE_FOOD:
|
||||
var event_type := StringName(event.data["event_type"])
|
||||
var item_id := StringName(event.data["item_id"])
|
||||
if item_id != SimulationIds.RESOURCE_FOOD:
|
||||
return changed
|
||||
var contributor_id := int(event.data["actor_id"])
|
||||
var event_id := int(event.data["event_id"])
|
||||
if contributor_id < 0 or event_id < 0 or float(event.data["amount"]) <= 0.0:
|
||||
var is_food_supply := false
|
||||
if event_type == SimulationIds.EVENT_STORAGE_DEPOSITED:
|
||||
is_food_supply = true
|
||||
elif (
|
||||
event_type == SimulationIds.EVENT_RESOURCE_EXTRACTED
|
||||
and contributor_id == SimulationIds.PLAYER_ACTOR_ID
|
||||
):
|
||||
is_food_supply = (
|
||||
StringName(event.data["destination_id"]) == SimulationIds.STORAGE_VILLAGE_PANTRY
|
||||
)
|
||||
if (
|
||||
not is_food_supply
|
||||
or event_id < 0
|
||||
or float(event.data["amount"]) <= 0.0
|
||||
or (contributor_id < 0 and contributor_id != SimulationIds.PLAYER_ACTOR_ID)
|
||||
):
|
||||
return changed
|
||||
for observer in npcs:
|
||||
if observer.id == contributor_id or observer.is_dead:
|
||||
if observer.is_dead:
|
||||
continue
|
||||
if contributor_id != SimulationIds.PLAYER_ACTOR_ID and observer.id == contributor_id:
|
||||
continue
|
||||
if observer.id not in knower_ids:
|
||||
continue
|
||||
if observer.hunger < AID_HUNGER_THRESHOLD:
|
||||
continue
|
||||
var relationship := get_relationship(observer.id, contributor_id)
|
||||
if relationship == null or relationship.get_familiarity() <= 0.0:
|
||||
if relationship == null:
|
||||
if contributor_id != SimulationIds.PLAYER_ACTOR_ID:
|
||||
continue
|
||||
relationship = RelationshipStateRecord.create(
|
||||
observer.id, contributor_id, PLAYER_FAMILIARITY_SEED
|
||||
)
|
||||
_add(relationship)
|
||||
if relationship.get_familiarity() <= 0.0:
|
||||
continue
|
||||
if event_id <= relationship.get_last_trust_cause_event_id():
|
||||
continue
|
||||
|
||||
@@ -46,7 +46,10 @@ static func from_dictionary(record_data: Dictionary) -> RelationshipStateRecord:
|
||||
var familiarity := float(record_data["familiarity"])
|
||||
var trust := float(record_data["trust"])
|
||||
var cause_event_id := int(record_data["last_trust_cause_event_id"])
|
||||
if observer_id < 0 or subject_id < 0 or observer_id == subject_id:
|
||||
var is_player_subject := subject_id == SimulationIds.PLAYER_ACTOR_ID
|
||||
if observer_id < 0 or observer_id == subject_id:
|
||||
return null
|
||||
if not is_player_subject and subject_id < 0:
|
||||
return null
|
||||
if familiarity < 0.0 or familiarity > 1.0 or trust < 0.0 or trust > 1.0:
|
||||
return null
|
||||
|
||||
@@ -2,7 +2,7 @@ class_name SimulationStateRecord
|
||||
extends RefCounted
|
||||
|
||||
const SCHEMA_NAME := "the_steward.simulation"
|
||||
const SCHEMA_VERSION := 11
|
||||
const SCHEMA_VERSION := 12
|
||||
const LEGACY_SCHEMA_VERSION := 1
|
||||
const EVENT_LEGACY_SCHEMA_VERSION := 2
|
||||
const RELATIONSHIP_LEGACY_SCHEMA_VERSION := 3
|
||||
@@ -12,6 +12,7 @@ const RETENTION_LEGACY_SCHEMA_VERSION := 6
|
||||
const OPPORTUNITY_LEGACY_SCHEMA_VERSION := 8
|
||||
const ANIMAL_LEGACY_SCHEMA_VERSION := 9
|
||||
const ROUTINE_LEGACY_SCHEMA_VERSION := 10
|
||||
const PLAYER_RELATIONSHIP_SCHEMA_VERSION := 11
|
||||
const PREVIOUS_SCHEMA_VERSION := 7
|
||||
|
||||
var simulation: Dictionary
|
||||
@@ -97,6 +98,7 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
OPPORTUNITY_LEGACY_SCHEMA_VERSION,
|
||||
ANIMAL_LEGACY_SCHEMA_VERSION,
|
||||
ROUTINE_LEGACY_SCHEMA_VERSION,
|
||||
PLAYER_RELATIONSHIP_SCHEMA_VERSION,
|
||||
]
|
||||
):
|
||||
record_data = _migrate_legacy(record_data, version)
|
||||
@@ -386,7 +388,10 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
return null
|
||||
var observer_id := relationship_record.get_observer_id()
|
||||
var subject_id := relationship_record.get_subject_id()
|
||||
if not npc_ids.has(observer_id) or not npc_ids.has(subject_id):
|
||||
var is_player_subject := subject_id == SimulationIds.PLAYER_ACTOR_ID
|
||||
if not npc_ids.has(observer_id):
|
||||
return null
|
||||
if not is_player_subject and not npc_ids.has(subject_id):
|
||||
return null
|
||||
var relationship_key := "%d:%d" % [observer_id, subject_id]
|
||||
if relationship_keys.has(relationship_key):
|
||||
@@ -404,15 +409,7 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
return null
|
||||
if cause_event_id != RelationshipStateRecord.NO_CAUSE_EVENT:
|
||||
var cause_event := event_records_by_id[cause_event_id] as EconomicEventRecord
|
||||
if (
|
||||
int(cause_event.data["actor_id"]) != subject_id
|
||||
or (
|
||||
StringName(cause_event.data["event_type"])
|
||||
!= SimulationIds.EVENT_STORAGE_DEPOSITED
|
||||
)
|
||||
or StringName(cause_event.data["item_id"]) != SimulationIds.RESOURCE_FOOD
|
||||
or float(cause_event.data["amount"]) <= 0.0
|
||||
):
|
||||
if not _is_valid_relationship_cause(cause_event, subject_id, is_player_subject):
|
||||
return null
|
||||
relationship_keys[relationship_key] = true
|
||||
record.relationships.append(relationship_record)
|
||||
@@ -672,6 +669,27 @@ static func _is_valid_pantry_empty_trigger(event: EconomicEventRecord, npc_ids:
|
||||
)
|
||||
|
||||
|
||||
static func _is_valid_relationship_cause(
|
||||
cause_event: EconomicEventRecord, subject_id: int, is_player_subject: bool
|
||||
) -> bool:
|
||||
if not is_player_subject:
|
||||
return (
|
||||
int(cause_event.data["actor_id"]) == subject_id
|
||||
and (
|
||||
StringName(cause_event.data["event_type"]) == SimulationIds.EVENT_STORAGE_DEPOSITED
|
||||
)
|
||||
and StringName(cause_event.data["item_id"]) == SimulationIds.RESOURCE_FOOD
|
||||
and float(cause_event.data["amount"]) > 0.0
|
||||
)
|
||||
return (
|
||||
int(cause_event.data["actor_id"]) == SimulationIds.PLAYER_ACTOR_ID
|
||||
and StringName(cause_event.data["event_type"]) == SimulationIds.EVENT_RESOURCE_EXTRACTED
|
||||
and (StringName(cause_event.data["destination_id"]) == SimulationIds.STORAGE_VILLAGE_PANTRY)
|
||||
and StringName(cause_event.data["item_id"]) == SimulationIds.RESOURCE_FOOD
|
||||
and float(cause_event.data["amount"]) > 0.0
|
||||
)
|
||||
|
||||
|
||||
static func _is_valid_supply_resolution(
|
||||
event: EconomicEventRecord,
|
||||
opportunity: OpportunityStateRecord,
|
||||
@@ -766,6 +784,7 @@ static func _migrate_legacy(legacy_data: Dictionary, version: int) -> Dictionary
|
||||
OPPORTUNITY_LEGACY_SCHEMA_VERSION,
|
||||
ANIMAL_LEGACY_SCHEMA_VERSION,
|
||||
ROUTINE_LEGACY_SCHEMA_VERSION,
|
||||
PLAYER_RELATIONSHIP_SCHEMA_VERSION,
|
||||
]
|
||||
):
|
||||
migrated["opportunities"] = []
|
||||
|
||||
Reference in New Issue
Block a user