Files
dorf/src/entities/cargo/systems.rs
T
2026-03-21 23:39:58 +00:00

56 lines
2.0 KiB
Rust

//! Cargo systems: carry visual cycling and haul encumbrance.
use bevy::prelude::*;
use crate::entities::cargo::components::{CarryVisualState, HaulSlot};
use crate::entities::item::inventory::constants::ENCUMBERED_SPEED_MULTIPLIER;
use crate::entities::item::inventory::InventoryChangedEvent;
use crate::entities::shared_components::Ambulatory;
/// Cycle the carry visual sprite while the entity's HaulSlot is occupied.
/// When empty, ensure the normal sprite is restored.
///
/// Runs in Update (visual only, no game state change).
pub fn carry_visual_system(
time: Res<Time>,
mut query: Query<(&HaulSlot, &mut CarryVisualState, &mut Sprite)>,
) {
for (haul_slot, mut visual, mut sprite) in query.iter_mut() {
if haul_slot.is_empty() {
if visual.showing_cargo {
sprite.image = visual.normal_sprite.clone();
visual.showing_cargo = false;
}
continue;
}
visual.timer.tick(time.delta());
if visual.timer.just_finished() {
visual.showing_cargo = !visual.showing_cargo;
sprite.image = if visual.showing_cargo {
visual.carry_sprite.clone()
} else {
visual.normal_sprite.clone()
};
}
}
}
/// Apply encumbrance when HaulSlot is occupied, remove when empty.
/// Fires InventoryChangedEvent so update_encumbrance recalculates walk_speed.
///
/// Uses Changed<HaulSlot> so this only runs for entities whose slot changed this frame.
pub fn haul_encumbrance_system(
mut query: Query<(Entity, &HaulSlot, &mut Ambulatory), Changed<HaulSlot>>,
mut events: MessageWriter<InventoryChangedEvent>,
) {
for (entity, haul_slot, mut ambulatory) in query.iter_mut() {
if haul_slot.is_occupied() {
ambulatory.walk_speed = ambulatory.base_walk_speed * ENCUMBERED_SPEED_MULTIPLIER;
} else {
ambulatory.walk_speed = ambulatory.base_walk_speed;
}
events.write(InventoryChangedEvent { carrier: entity });
}
}