use bevy::prelude::*; use crate::sounds::PlaySound; #[derive(Event, Reflect)] pub struct Kill; #[derive(Event, Reflect)] pub struct Hit { pub damage: u32, } #[derive(Component, Reflect, Debug)] pub struct Hitpoints { max: u32, current: u32, } impl Hitpoints { pub fn new(v: u32) -> Self { Self { max: v, current: v } } pub fn health(&self) -> f32 { self.current as f32 / self.max as f32 } pub fn set_health(&mut self, v: u32) { self.current = v; } pub fn get(&self) -> (u32, u32) { (self.current, self.max) } pub fn max(&self) -> bool { self.current == self.max } } pub fn plugin(app: &mut App) { app.add_systems(Update, on_hp_added); } fn on_hp_added(mut commands: Commands, query: Query>) { for e in query.iter() { commands.entity(e).observe(on_hit); } } fn on_hit(trigger: Trigger, mut commands: Commands, mut query: Query<&mut Hitpoints>) { let Hit { damage } = trigger.event(); let Ok(mut hp) = query.get_mut(trigger.entity()) else { return; }; commands.trigger(PlaySound::Hit); hp.current = hp.current.saturating_sub(*damage); if hp.current == 0 { commands.trigger_targets(Kill, trigger.entity()); } }