fix(simulation): address PR #26 review comments (13 items)
Warnings fixed: - Add WalkAway to all_player_action_variants_roundtrip test - Warn and skip on unresolvable speaker_entity_id (was silent 0) - Change MonologueState.shown_ids from Vec to HashSet (O(1) lookup) - Add cross-plugin ordering: trigger_recognition_monologue after detect_anomalies (latent determinism bug) - Add TODO for unreachable Secret trust tier Suggestions addressed: - Server-side range check for Talk verb in handle_talk (CLOSE_RANGE) - Emit IncompleteInteraction before overwriting ActiveDialogue - Add different_seed_produces_different_replay determinism test - Replace panic with assert for unknown fixture naming convention - Fix duplicate "Observe" label: ExamineNpc now uses "Examine NPC" - Change DialogueCooldownTracker.used from Vec to BTreeMap (D-041) - Add .after(process_talk_interaction) to process_walk_away ordering - Collapse dead conditional in main.rs (both branches identical) 468 tests pass, 0 failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -90,6 +90,7 @@ pub fn process_player_input(
|
||||
With<PlayerCharacter>,
|
||||
>,
|
||||
inventory_items: Query<(Entity, &CarriedBy, &ItemName, &InventorySlot)>,
|
||||
all_positions: Query<&TilePosition>,
|
||||
) {
|
||||
let current_tick = time.tick;
|
||||
let paused = time.paused();
|
||||
@@ -189,7 +190,7 @@ pub fn process_player_input(
|
||||
handle_place(&mut commands, ®istry, &player_query, target_entity_id);
|
||||
}
|
||||
Some("Talk") => {
|
||||
handle_talk(&mut commands, ®istry, &player_query, target_entity_id);
|
||||
handle_talk(&mut commands, ®istry, &player_query, &all_positions, target_entity_id);
|
||||
}
|
||||
_ => {
|
||||
tracing::info!(
|
||||
@@ -328,6 +329,7 @@ fn handle_take(
|
||||
|
||||
/// Handle Talk verb: set TalkRequest marker on the player entity for the target NPC.
|
||||
/// The actual dialogue pipeline runs in process_talk_interaction (dialogue.rs).
|
||||
/// Server-side range check: Talk requires CLOSE_RANGE (same as interaction system).
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn handle_talk(
|
||||
commands: &mut Commands,
|
||||
@@ -341,6 +343,7 @@ fn handle_talk(
|
||||
),
|
||||
With<PlayerCharacter>,
|
||||
>,
|
||||
all_positions: &Query<&TilePosition>,
|
||||
target_entity_id: Option<u64>,
|
||||
) {
|
||||
let Some(target_id) = target_entity_id else {
|
||||
@@ -348,7 +351,7 @@ fn handle_talk(
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok((player_entity, _, _, _)) = player_query.single() else {
|
||||
let Ok((player_entity, player_pos, _, _)) = player_query.single() else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -358,6 +361,20 @@ fn handle_talk(
|
||||
return;
|
||||
};
|
||||
|
||||
// Server-side range check: reject Talk 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 > crate::simulation::interaction::CLOSE_RANGE {
|
||||
tracing::info!(
|
||||
target_id,
|
||||
distance,
|
||||
"Talk: target out of range (max {})",
|
||||
crate::simulation::interaction::CLOSE_RANGE,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
commands
|
||||
.entity(player_entity)
|
||||
.insert(crate::simulation::dialogue::TalkRequest {
|
||||
|
||||
Reference in New Issue
Block a user