inventory: early return before HashSet alloc, restore doc comments
This commit is contained in:
@@ -1,4 +1,32 @@
|
||||
//! PersonalInventory — slots, strength-based carry weight, encumbrance tracking.
|
||||
//!
|
||||
//! # Design
|
||||
//! Every entity that can carry items gets a PersonalInventory. Slot count is
|
||||
//! species- and age-defined. Weight limit is strength-based.
|
||||
//!
|
||||
//! # Weight limit
|
||||
//! max_carry_weight = BASE_CARRY_WEIGHT + strength * STRENGTH_CARRY_MULTIPLIER
|
||||
//! + sum(carry_weight_bonus for each Container directly in slots)
|
||||
//!
|
||||
//! The bonus from held containers is re-evaluated whenever the slot contents
|
||||
//! change. It is NOT recursive — containers inside containers do not contribute
|
||||
//! their bonus to the carrier.
|
||||
//!
|
||||
//! # Encumbrance
|
||||
//! When current_weight > max_carry_weight, the entity is encumbered.
|
||||
//! The update_encumbrance system sets Ambulatory.walk_speed to
|
||||
//! base_walk_speed * ENCUMBERED_SPEED_MULTIPLIER when over limit.
|
||||
//!
|
||||
//! # Item placement
|
||||
//! Items are always placed in the best available slot at time of pickup —
|
||||
//! the smallest container whose max_item_size >= item.size with a free slot.
|
||||
//! No automatic reorganisation occurs. Reorganisation is an explicit task.
|
||||
//!
|
||||
//! # Life stage slot counts
|
||||
//! Adult: species value (e.g. DORF_ADULT_SLOTS = 8)
|
||||
//! Child: floor(adult / 2), minimum 0
|
||||
//! Baby: 1 if adult >= 2, else 0
|
||||
//! See slots_for_age().
|
||||
|
||||
use bevy::prelude::*;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
//! Encumbrance system. Fires `InventoryChangedEvent` after any inventory mutation to
|
||||
//! trigger walk_speed recalculation without per-tick iteration over all carriers.
|
||||
//! Encumbrance system — updates walk_speed based on carry weight.
|
||||
//!
|
||||
//! # Event-driven design
|
||||
//! Rather than iterating all carriers every tick, encumbrance recalculates only
|
||||
//! for entities that fired an InventoryChangedEvent. At 5000 entities with rare
|
||||
//! inventory changes, this reduces per-tick work from O(entities) to O(changes).
|
||||
//!
|
||||
//! Any code that mutates a PersonalInventory or a Container held by an entity
|
||||
//! MUST fire InventoryChangedEvent { carrier } after the mutation. The carrier
|
||||
//! is always the top-level entity with PersonalInventory — not a nested container.
|
||||
//!
|
||||
//! # base_walk_speed
|
||||
//! Ambulatory gains base_walk_speed: f32 — the unmodified speed. Encumbrance
|
||||
//! writes walk_speed = base_walk_speed * ENCUMBERED_SPEED_MULTIPLIER.
|
||||
//! Restoring writes walk_speed = base_walk_speed. base_walk_speed is never
|
||||
//! modified by encumbrance.
|
||||
|
||||
use bevy::prelude::*;
|
||||
use rustc_hash::FxHashSet;
|
||||
@@ -19,10 +33,10 @@ pub fn update_encumbrance(
|
||||
mut carriers: Query<(&mut PersonalInventory, &mut Ambulatory)>,
|
||||
containers: Query<&Container>,
|
||||
) {
|
||||
let changed: FxHashSet<Entity> = events.read().map(|e| e.carrier).collect();
|
||||
if changed.is_empty() {
|
||||
if events.is_empty() {
|
||||
return;
|
||||
}
|
||||
let changed: FxHashSet<Entity> = events.read().map(|e| e.carrier).collect();
|
||||
|
||||
for carrier_entity in changed {
|
||||
let Ok((mut inventory, mut ambulatory)) = carriers.get_mut(carrier_entity) else {
|
||||
|
||||
Reference in New Issue
Block a user