feat: let trusted villagers ask the player directly as standing grows
This commit is contained in:
@@ -28,6 +28,7 @@ signal player_quest_opened(quest: PlayerQuestRecord)
|
||||
signal player_quest_completed(quest: PlayerQuestRecord)
|
||||
signal player_quest_expired(quest: PlayerQuestRecord)
|
||||
signal player_standing_changed(standing: PlayerStandingRecord)
|
||||
signal player_tier_advanced(tier: int, tier_name: String)
|
||||
|
||||
var village := SimVillage.new()
|
||||
|
||||
@@ -51,6 +52,7 @@ var relationship_system := RelationshipSystemScript.new()
|
||||
var event_knowledge_system := EventKnowledgeSystemScript.new()
|
||||
var opportunity_system := VillageOpportunitySystem.new()
|
||||
var player_quest_system := PlayerQuestSystem.new()
|
||||
var _last_player_tier := PlayerStandingRecord.TIER_STRANGER
|
||||
var storage_states: Dictionary:
|
||||
get:
|
||||
return economy.storage_states
|
||||
@@ -578,19 +580,30 @@ func _on_economic_event_recorded(event: EconomicEventRecord) -> void:
|
||||
|
||||
|
||||
func _resolve_animal_care_quest(event: EconomicEventRecord) -> void:
|
||||
var animal_id := StringName(event.data["destination_id"])
|
||||
var animal_state := animal_care.get_state(animal_id)
|
||||
var animal_state := animal_care.get_state(StringName(event.data["destination_id"]))
|
||||
var resolution := player_quest_system.on_animal_fed(animal_state, event, tick_count)
|
||||
_finish_quest_resolution(resolution)
|
||||
|
||||
|
||||
func _finish_quest_resolution(resolution: Dictionary) -> void:
|
||||
if not resolution.has("quest"):
|
||||
return
|
||||
var quest: PlayerQuestRecord = resolution["quest"]
|
||||
if resolution["completed"]:
|
||||
player_quest_completed.emit(quest)
|
||||
player_standing_changed.emit(player_quest_system.standing)
|
||||
_emit_standing_change_and_tier()
|
||||
else:
|
||||
player_quest_expired.emit(quest)
|
||||
|
||||
|
||||
func _emit_standing_change_and_tier() -> void:
|
||||
var standing := player_quest_system.standing
|
||||
player_standing_changed.emit(standing)
|
||||
if standing.get_tier() > _last_player_tier:
|
||||
_last_player_tier = standing.get_tier()
|
||||
player_tier_advanced.emit(standing.get_tier(), standing.get_tier_name())
|
||||
|
||||
|
||||
func try_communicate_at_shared_activity(speaker_id: int, listener_id: int) -> bool:
|
||||
var speaker := _find_npc_by_id(speaker_id)
|
||||
var listener := _find_npc_by_id(listener_id)
|
||||
@@ -674,20 +687,18 @@ func _update_opportunity_from_event(event: EconomicEventRecord) -> void:
|
||||
if changed.get_status() == OpportunityStateRecord.STATUS_OPEN:
|
||||
opportunity_opened.emit(changed)
|
||||
var quest := player_quest_system.consider_opportunity_opened(
|
||||
changed, get_active_opportunity_player_response(), tick_count
|
||||
changed,
|
||||
get_active_opportunity_player_response(),
|
||||
tick_count,
|
||||
player_quest_system.can_request_personally(changed)
|
||||
)
|
||||
if quest != null:
|
||||
player_quest_opened.emit(quest)
|
||||
return
|
||||
opportunity_resolved.emit(changed, event)
|
||||
var resolution := player_quest_system.on_opportunity_resolved(changed, event, tick_count)
|
||||
if resolution.has("quest"):
|
||||
var quest: PlayerQuestRecord = resolution["quest"]
|
||||
if resolution["completed"]:
|
||||
player_quest_completed.emit(quest)
|
||||
player_standing_changed.emit(player_quest_system.standing)
|
||||
else:
|
||||
player_quest_expired.emit(quest)
|
||||
_finish_quest_resolution(
|
||||
player_quest_system.on_opportunity_resolved(changed, event, tick_count)
|
||||
)
|
||||
_maintain_event_knowledge(false)
|
||||
|
||||
|
||||
@@ -780,22 +791,20 @@ func get_active_player_quest() -> PlayerQuestRecord:
|
||||
func _consider_animal_care_quests() -> void:
|
||||
var pantry: StorageStateRecord = get_pantry()
|
||||
for animal_state in animal_care.get_all_states():
|
||||
var requester := _find_animal_requester(animal_state)
|
||||
var quest := player_quest_system.consider_animal_care(
|
||||
animal_state, requester, tick_count, pantry
|
||||
animal_state, _nearest_npc_id(animal_state.get_position()), tick_count, pantry
|
||||
)
|
||||
if quest != null:
|
||||
player_quest_opened.emit(quest)
|
||||
|
||||
|
||||
func _find_animal_requester(animal_state: AnimalStateRecord) -> int:
|
||||
var animal_position := animal_state.get_position()
|
||||
func _nearest_npc_id(from_position: Vector3) -> int:
|
||||
var nearest_id := -1
|
||||
var nearest_distance := INF
|
||||
for npc in npcs:
|
||||
if npc.is_dead:
|
||||
continue
|
||||
var distance := npc.position.distance_squared_to(animal_position)
|
||||
var distance := npc.position.distance_squared_to(from_position)
|
||||
if distance < nearest_distance:
|
||||
nearest_distance = distance
|
||||
nearest_id = npc.id
|
||||
@@ -1172,6 +1181,7 @@ func restore_state(record: SimulationStateRecord) -> bool:
|
||||
player_quest_system.restore(
|
||||
record.player_quests, int(record.simulation.get("next_quest_id", 0)), record.player_standing
|
||||
)
|
||||
_last_player_tier = player_quest_system.standing.get_tier()
|
||||
_maintain_event_knowledge(tick_count % get_knowledge_review_interval() == 0)
|
||||
wander_random_sources.clear()
|
||||
var wander_streams: Array = record.simulation["wander_random_streams"]
|
||||
|
||||
@@ -4,6 +4,8 @@ extends RefCounted
|
||||
const PANTRY_STANDING_REWARD := 8.0
|
||||
const WOOD_STANDING_REWARD := 8.0
|
||||
const ANIMAL_CARE_STANDING_REWARD := 6.0
|
||||
const PERSONAL_TRUST_THRESHOLD := 0.5
|
||||
const MIN_PERSONAL_REQUEST_TIER := PlayerStandingRecord.TIER_KNOWN_HAND
|
||||
|
||||
var quests: Array[PlayerQuestRecord] = []
|
||||
var next_quest_id := 0
|
||||
@@ -77,14 +79,12 @@ func on_animal_fed(
|
||||
func consider_opportunity_opened(
|
||||
opportunity: OpportunityStateRecord,
|
||||
player_response: OpportunityPlayerResponseResult,
|
||||
current_tick: int
|
||||
current_tick: int,
|
||||
personal_request_eligible := false
|
||||
) -> PlayerQuestRecord:
|
||||
if (
|
||||
opportunity == null
|
||||
or not opportunity.is_open()
|
||||
or player_response == null
|
||||
or current_tick < 0
|
||||
):
|
||||
if opportunity == null or not opportunity.is_open() or current_tick < 0:
|
||||
return null
|
||||
if player_response == null and not personal_request_eligible:
|
||||
return null
|
||||
if _find_open_quest_for_opportunity(opportunity.get_opportunity_id()) != null:
|
||||
return null
|
||||
@@ -107,6 +107,16 @@ func consider_opportunity_opened(
|
||||
return quest
|
||||
|
||||
|
||||
func can_request_personally(opportunity: OpportunityStateRecord) -> bool:
|
||||
if (
|
||||
opportunity == null
|
||||
or not opportunity.is_open()
|
||||
or standing.get_tier() < MIN_PERSONAL_REQUEST_TIER
|
||||
):
|
||||
return false
|
||||
return standing.get_gratitude(opportunity.get_interested_npc_id()) >= PERSONAL_TRUST_THRESHOLD
|
||||
|
||||
|
||||
func on_opportunity_resolved(
|
||||
opportunity: OpportunityStateRecord, resolution_event: EconomicEventRecord, current_tick: int
|
||||
) -> Dictionary:
|
||||
|
||||
Reference in New Issue
Block a user