refactor(simulation): split the input.rs and dialogue.rs dispatchers (T-1062)

input.rs 2,739 → 858 lines: per-domain action handlers moved to their
owning modules (inventory, movement, stance, examine, follow, interaction,
save_io, settings, bridge::debug, economy, vision_cone, bookmark,
test_world reset + new teleport.rs); input.rs keeps the queue, the thin
dispatch table, and pause/cooldown glue. All 9 type_complexity allows
dissolved via one PlayerInputQuery alias.

dialogue.rs → dialogue/ directory module: selection (631), response
(1,473), confrontation (714), mod.rs (226, shared session components +
re-exports — public paths preserved). Documented seam deviation:
process_walk_away lives with confrontation (D-064/D-063 share the same
world-response shape).

Mechanical, zero behavior change: determinism + golden_suite byte-identical
(independently re-verified); 1,504 lib tests unchanged — 23 input tests
moved with their subjects, 53 dialogue tests redistributed, zero deleted.
System scheduling registrations untouched (input_plugin.rs 0-line diff).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 17:07:36 +02:00
co-authored by Claude Fable 5
parent 3a23378a88
commit 257d979aed
23 changed files with 4819 additions and 4735 deletions
+48
View File
@@ -285,6 +285,54 @@ pub fn process_examine_interaction(
commands.entity(player_entity).remove::<ExamineRequest>();
}
/// Handle Examine verb: insert ExamineRequest marker on the player entity (#242).
/// Examine is available at close range (same as Talk). Range check here matches
/// the server-side guard in process_examine_interaction.
pub fn handle_examine(
commands: &mut Commands,
registry: &EntityRegistry,
player_query: &crate::simulation::input::PlayerInputQuery,
all_positions: &Query<&TilePosition>,
target_entity_id: Option<u64>,
) {
let Some(target_id) = target_entity_id else {
tracing::warn!("Examine verb without target_entity_id");
return;
};
let Ok((player_entity, player_pos, _, _)) = player_query.single() else {
return;
};
let target_stable = crate::knowledge::StableId(target_id);
let Some(target_entity) = registry.to_entity(&target_stable) else {
tracing::warn!(target_id, "Examine: target entity not in registry");
return;
};
// Server-side range check: reject Examine if target is beyond close range
if let Ok(target_pos) = all_positions.get(target_entity) {
let distance = player_pos
.manhattan_distance(target_pos)
.unwrap_or(u32::MAX);
if distance > CLOSE_RANGE {
tracing::info!(
target_id,
distance,
"Examine: target out of range (max {})",
CLOSE_RANGE,
);
return;
}
}
commands.entity(player_entity).insert(ExamineRequest {
target: target_entity,
});
tracing::debug!(target_id, "Examine: ExamineRequest marker set on player");
}
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------