feat: let the player talk to villagers and accept or decline personal requests

This commit is contained in:
2026-08-09 00:10:36 +02:00
parent 5e6c963d23
commit 0936ae6450
10 changed files with 520 additions and 36 deletions
+80
View File
@@ -135,6 +135,58 @@ func on_opportunity_resolved(
return {}
func get_talk_for_requester(
requester_id: int, requester_name: String, opportunity: OpportunityStateRecord
) -> PlayerTalkResult:
var has_need := opportunity != null and opportunity.is_open()
var need_text := ""
if has_need:
need_text = "I'm worried about the %s." % String(opportunity.get_resource_id()).capitalize()
var quest := get_latest_for_requester(requester_id)
var quest_available := quest != null and quest.is_open()
var reward := quest.get_standing_reward() if quest_available else 0.0
var can_accept := has_need and (quest_available or can_request_personally(opportunity))
return PlayerTalkResult.new(
requester_id,
requester_name,
"%s greets you." % requester_name,
has_need,
need_text,
quest_available,
reward,
can_accept,
has_need
)
func accept_opportunity_quest(
opportunity: OpportunityStateRecord,
player_response: OpportunityPlayerResponseResult,
current_tick: int
) -> Dictionary:
var existing := _find_open_quest_for_opportunity(opportunity.get_opportunity_id())
if existing != null:
return {"quest": existing, "created": false}
var created := consider_opportunity_opened(
opportunity, player_response, current_tick, can_request_personally(opportunity)
)
return {"quest": created, "created": created != null}
func decline_opportunity_quest(
opportunity: OpportunityStateRecord, current_tick: int
) -> PlayerQuestRecord:
var quest := _find_open_quest_for_opportunity(opportunity.get_opportunity_id())
if quest == null:
return null
if not quest.expire(current_tick):
return null
var requester_id := quest.get_requester_npc_id()
var gratitude := standing.get_gratitude(requester_id)
standing.data["gratitude"][requester_id] = maxf(gratitude - 0.1, 0.0)
return quest
func on_opportunity_invalidated(
opportunity: OpportunityStateRecord, current_tick: int
) -> PlayerQuestRecord:
@@ -146,6 +198,34 @@ func on_opportunity_invalidated(
return null
func consider_animal_care_quests(
animal_care: AnimalCareSystem,
npcs: Array[SimNPC],
pantry: StorageStateRecord,
current_tick: int
) -> Array[PlayerQuestRecord]:
var opened: Array[PlayerQuestRecord] = []
for animal_state in animal_care.get_all_states():
var requester := _nearest_npc_id(animal_state.get_position(), npcs)
var quest := consider_animal_care(animal_state, requester, current_tick, pantry)
if quest != null:
opened.append(quest)
return opened
static func _nearest_npc_id(from_position: Vector3, npcs: Array[SimNPC]) -> 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(from_position)
if distance < nearest_distance:
nearest_distance = distance
nearest_id = npc.id
return nearest_id
func get_active_quest() -> PlayerQuestRecord:
for quest in quests:
if quest.is_open():