feat(simulation): smuggler inventory — CarriedBy, Take/Place verbs (#424)
Implement physical inventory system per D-065: - CarriedBy(StableId) component marks items as carried by an entity - ItemName and InventorySlot components for display and slot assignment - Take verb: removes TilePosition, adds CarriedBy + InventorySlot - Place verb: removes CarriedBy + InventorySlot, adds TilePosition - Observer snapshot populates player_inventory from carried items query - Info boundary: carried items lack TilePosition, naturally excluded from all spatial queries (visibility, interactions) for other entities - 9-slot capacity (3x3 grid per OQ-24), auto-assigns first free slot - 8 new tests covering take, place, sequential slots, full rejection Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ use crate::knowledge::{EntityRegistry, KnowledgeGraph, StableId};
|
||||
use crate::perception::query::{ActivePerceptionMode, VisibilityGeometry};
|
||||
use crate::perception::vision_cone::Facing;
|
||||
use crate::simulation::interaction::NearbyInteractionBuffer;
|
||||
use crate::simulation::inventory::{CarriedBy, InventorySlot, ItemName};
|
||||
use crate::simulation::monologue::MonologueBuffer;
|
||||
use crate::simulation::movement::{PlayerCharacter, TilePosition, WalkabilityMap};
|
||||
use crate::simulation::stance::Stance;
|
||||
@@ -52,7 +53,7 @@ pub fn compute_observer_snapshot(
|
||||
geometry: Res<VisibilityGeometry>,
|
||||
registry: Res<EntityRegistry>,
|
||||
mut observer_query: Query<
|
||||
(&TilePosition, Option<&Facing>, &KnowledgeGraph, &mut NearbyInteractionBuffer, &mut MonologueBuffer, Option<&Stance>, Option<&CharacterArchetype>),
|
||||
(Entity, &TilePosition, Option<&Facing>, &KnowledgeGraph, &mut NearbyInteractionBuffer, &mut MonologueBuffer, Option<&Stance>, Option<&CharacterArchetype>),
|
||||
With<PlayerCharacter>,
|
||||
>,
|
||||
all_entities: Query<(
|
||||
@@ -61,9 +62,10 @@ pub fn compute_observer_snapshot(
|
||||
Option<&PlayerCharacter>,
|
||||
Option<&crate::npc::Npc>,
|
||||
)>,
|
||||
inventory_items: Query<(Entity, &CarriedBy, &ItemName, &InventorySlot)>,
|
||||
mut buffer: ResMut<SnapshotBuffer>,
|
||||
) {
|
||||
let Ok((_observer_pos, facing_opt, observer_kg, mut interaction_buffer, mut monologue_buffer, stance_opt, archetype_opt)) =
|
||||
let Ok((observer_entity, _observer_pos, facing_opt, observer_kg, mut interaction_buffer, mut monologue_buffer, stance_opt, archetype_opt)) =
|
||||
observer_query.single_mut()
|
||||
else {
|
||||
return;
|
||||
@@ -75,6 +77,18 @@ pub fn compute_observer_snapshot(
|
||||
|
||||
let archetype = archetype_opt.copied().unwrap_or_default();
|
||||
|
||||
// Collect player inventory (D-065 info boundary: only own items)
|
||||
let player_inventory = registry
|
||||
.to_stable(observer_entity)
|
||||
.map(|player_sid| {
|
||||
crate::simulation::inventory::collect_inventory_for(
|
||||
player_sid,
|
||||
&inventory_items,
|
||||
®istry,
|
||||
)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let (mut entities, visible_ids) =
|
||||
filter_visible_entities(&geometry, ®istry, observer_kg, &all_entities);
|
||||
|
||||
@@ -114,7 +128,7 @@ pub fn compute_observer_snapshot(
|
||||
game_time,
|
||||
player_facing: facing,
|
||||
player_stance: stance_opt.map(|s| s.0).unwrap_or_default(),
|
||||
player_inventory: Vec::new(),
|
||||
player_inventory,
|
||||
entities,
|
||||
visible_tiles: geometry.visible_tiles.clone(),
|
||||
nearby_interactions,
|
||||
|
||||
Reference in New Issue
Block a user