feat: let the player talk to villagers and accept or decline personal requests
This commit is contained in:
@@ -72,6 +72,8 @@ func try_interact() -> void:
|
||||
_execute_resource_interaction(context)
|
||||
PlayerInteractionResult.KIND_DEPOSIT:
|
||||
_execute_deposit_interaction(context)
|
||||
PlayerInteractionResult.KIND_TALK:
|
||||
_execute_talk_interaction(context)
|
||||
PlayerInteractionResult.KIND_GUARD:
|
||||
simulation_manager.add_safety(3.0)
|
||||
interaction_feedback.emit(
|
||||
@@ -131,9 +133,53 @@ func get_interaction_context() -> PlayerInteractionResult:
|
||||
)
|
||||
if is_near_storage(pantry_storage):
|
||||
return _build_pantry_context()
|
||||
var talk_npc := _find_talk_villager()
|
||||
if talk_npc != null:
|
||||
return _build_talk_context(talk_npc)
|
||||
return null
|
||||
|
||||
|
||||
func _find_talk_villager() -> SimNPC:
|
||||
if (
|
||||
simulation_manager == null
|
||||
or world_view_manager == null
|
||||
or not world_view_manager.has_method("find_nearest_active_npc_id")
|
||||
):
|
||||
return null
|
||||
var npc_id: int = world_view_manager.find_nearest_active_npc_id(
|
||||
global_position, interaction_range
|
||||
)
|
||||
if npc_id < 0:
|
||||
return null
|
||||
var npc := _find_npc(npc_id)
|
||||
if npc == null or npc.is_dead:
|
||||
return null
|
||||
return npc
|
||||
|
||||
|
||||
func _build_talk_context(npc: SimNPC) -> PlayerInteractionResult:
|
||||
var talk: PlayerTalkResult = simulation_manager.get_villager_talk(npc.id)
|
||||
if talk == null or not talk.has_need:
|
||||
return null
|
||||
var prompt := "Talk to %s" % npc.npc_name
|
||||
if talk.quest_available:
|
||||
prompt = "Accept %s's request" % npc.npc_name
|
||||
elif talk.can_accept:
|
||||
prompt = "Offer to help %s" % npc.npc_name
|
||||
var detail := talk.need_text
|
||||
if talk.quest_available:
|
||||
detail = "Help +%.0f Standing" % talk.quest_reward
|
||||
return PlayerInteractionResult.new(
|
||||
PlayerInteractionResult.KIND_TALK,
|
||||
SimulationIds.ACTION_IDLE,
|
||||
SimulationIds.npc_inventory_id(npc.id),
|
||||
npc.npc_name,
|
||||
prompt,
|
||||
detail,
|
||||
null
|
||||
)
|
||||
|
||||
|
||||
func get_nearby_villager_inspection() -> VillagerInspectionResult:
|
||||
if (
|
||||
simulation_manager == null
|
||||
@@ -437,6 +483,38 @@ func _execute_deposit_interaction(context: PlayerInteractionResult) -> void:
|
||||
)
|
||||
|
||||
|
||||
func _execute_talk_interaction(context: PlayerInteractionResult) -> void:
|
||||
var npc_id := _talk_npc_id_from_target(context.target_id)
|
||||
if npc_id < 0:
|
||||
return
|
||||
var quest: PlayerQuestRecord = simulation_manager.accept_villager_request(npc_id)
|
||||
if quest == null:
|
||||
interaction_feedback.emit(
|
||||
"%s declines" % context.display_name,
|
||||
"They have no request you can accept right now.",
|
||||
false
|
||||
)
|
||||
return
|
||||
interaction_feedback.emit(
|
||||
"Request accepted",
|
||||
(
|
||||
"%s asked you for help · +%.0f Standing on completion"
|
||||
% [context.display_name, quest.get_standing_reward()]
|
||||
),
|
||||
true
|
||||
)
|
||||
|
||||
|
||||
func _talk_npc_id_from_target(target_id: StringName) -> int:
|
||||
var prefix := "npc_"
|
||||
var suffix := "_inventory"
|
||||
var raw := String(target_id)
|
||||
if not raw.begins_with(prefix) or not raw.ends_with(suffix):
|
||||
return -1
|
||||
var id_text := raw.trim_prefix(prefix).trim_suffix(suffix)
|
||||
return id_text.to_int()
|
||||
|
||||
|
||||
func _execute_pantry_interaction(context: PlayerInteractionResult) -> void:
|
||||
if not context.is_available():
|
||||
interaction_feedback.emit("The pantry is empty", context.blocked_reason, false)
|
||||
|
||||
Reference in New Issue
Block a user