56 lines
2.0 KiB
Rust
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 });
|
|
}
|
|
}
|