feat: add playable generated dialogue mode

This commit is contained in:
Rijad Zuzo
2026-08-12 21:16:15 +02:00
parent 6b50580598
commit f8734422a0
11 changed files with 1012 additions and 8 deletions
+77 -2
View File
@@ -2,6 +2,8 @@ extends CharacterBody3D
signal interaction_feedback(heading: String, message: String, succeeded: bool)
const DIALOGUE_MODE_CONTROLLER_SCRIPT := preload("res://world/dialogue/DialogueModeController.gd")
@export var move_speed := 7.0
@export var acceleration := 18.0
@export var rotation_speed := 12.0
@@ -21,12 +23,24 @@ signal interaction_feedback(heading: String, message: String, succeeded: bool)
@onready var combat_controller: Node = get_node_or_null("PlayerCombatController")
var dialogue_mode_controller: DialogueModeController
func _ready() -> void:
add_to_group("grass_interactors")
_install_dialogue_mode_controller()
func _physics_process(delta: float) -> void:
if is_dialogue_input_locked():
velocity.x = move_toward(velocity.x, 0.0, acceleration * delta)
velocity.z = move_toward(velocity.z, 0.0, acceleration * delta)
if not is_on_floor():
velocity.y -= 30.0 * delta
else:
velocity.y = 0.0
move_and_slide()
return
if _is_player_downed():
velocity.x = move_toward(velocity.x, 0.0, acceleration * delta)
velocity.z = move_toward(velocity.z, 0.0, acceleration * delta)
@@ -79,16 +93,26 @@ func _is_player_downed() -> bool:
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("interact"):
if is_dialogue_input_locked():
return
if (
event.is_action_pressed("interact")
or (event.is_action_pressed("ui_accept") and _get_nearby_dialogue_npc_id() >= 0)
):
try_interact()
func try_interact() -> void:
if is_dialogue_input_locked():
return
var context := get_interaction_context()
if context == null:
return
match context.kind:
PlayerInteractionResult.KIND_DIALOGUE:
if dialogue_mode_controller != null:
dialogue_mode_controller.begin_conversation(int(String(context.target_id)))
PlayerInteractionResult.KIND_ANIMAL:
_execute_animal_interaction(context)
PlayerInteractionResult.KIND_RESOURCE:
@@ -110,8 +134,19 @@ func try_interact() -> void:
func get_interaction_context() -> PlayerInteractionResult:
if simulation_manager == null:
if simulation_manager == null or is_dialogue_input_locked():
return null
var villager := _find_npc(_get_nearby_dialogue_npc_id())
if villager != null:
return PlayerInteractionResult.new(
PlayerInteractionResult.KIND_DIALOGUE,
DialogueModeController.TALK_ACTION_ID,
StringName(str(villager.id)),
villager.npc_name,
"Talk with %s" % villager.npc_name,
"Ask what is happening nearby",
null
)
var animal := _find_feed_animal()
if animal != null:
return _build_animal_context(animal)
@@ -148,6 +183,46 @@ func get_interaction_context() -> PlayerInteractionResult:
return null
func is_dialogue_input_locked() -> bool:
if (
simulation_manager != null
and simulation_manager.has_method("is_dialogue_active")
and bool(simulation_manager.call("is_dialogue_active"))
):
return true
return (
dialogue_mode_controller != null
and is_instance_valid(dialogue_mode_controller)
and dialogue_mode_controller.is_dialogue_active()
)
func _install_dialogue_mode_controller() -> void:
var existing := get_node_or_null("DialogueModeController") as DialogueModeController
if existing != null:
dialogue_mode_controller = existing
else:
dialogue_mode_controller = DIALOGUE_MODE_CONTROLLER_SCRIPT.new()
dialogue_mode_controller.name = "DialogueModeController"
dialogue_mode_controller.configure(self, simulation_manager, world_view_manager)
add_child(dialogue_mode_controller)
if existing != null:
dialogue_mode_controller.configure(self, simulation_manager, world_view_manager)
func _get_nearby_dialogue_npc_id() -> int:
if (
world_view_manager == null
or not world_view_manager.has_method("find_nearest_active_npc_id")
):
return -1
return int(
world_view_manager.call(
"find_nearest_active_npc_id", global_position, villager_inspection_range
)
)
func get_nearby_villager_inspection() -> VillagerInspectionResult:
if (
simulation_manager == null