From 9f490974a46b910925477664d47d0d902038038d Mon Sep 17 00:00:00 2001 From: Rendo Date: Thu, 7 May 2026 12:36:29 +0500 Subject: [PATCH 1/3] feat: health component, killed cleanup, unkillable component --- src/health/event.rs | 0 src/health/mod.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/health/event.rs diff --git a/src/health/event.rs b/src/health/event.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/health/mod.rs b/src/health/mod.rs index cf0ee62..91c2115 100644 --- a/src/health/mod.rs +++ b/src/health/mod.rs @@ -1,9 +1,73 @@ +use std::ops::Deref; + use bevy::prelude::*; +pub mod event; + +/// Health plugin provides systems to handle health modifications and events pub struct HealthPlugin; impl Plugin for HealthPlugin { fn build(&self, app: &mut App) { - //todo!() + app.add_systems(PostUpdate,cleanup_killed); + } +} + +/// Component that holds health points and max health points of entity +#[derive(Component)] +pub struct Health { + health: usize, + max_health: usize, +} + +impl Default for Health { + fn default() -> Self { + Self { health: 1, max_health: 1 } + } +} + +impl Health { + /// Create new health component with set 'health' and 'max_health'. + pub fn new(health: usize, max_health: usize) -> Self { + Self { + health, + max_health + } + } + /// Create new health component from max health. + pub fn from_max(max_health: usize) -> Self { + Self { + health: max_health, + max_health + } + } + + /// Substract 'damage' amount of health points from component with boundary check. + pub fn damage(&mut self, damage: usize) { + self.health = if damage > self.health {0} else {self.health - damage}; + } + /// Add 'heal' amount of health points to component with max health as a boundary. + pub fn heal_no_overheal(&mut self, heal: usize) { + self.health = if self.health + heal > self.max_health {self.max_health} else {self.health + heal}; + } + /// Add 'heal' amount of health points to component with usize::MAX as a boundary. + pub fn heal_with_overheal(&mut self, heal: usize) { + self.health = if usize::MAX-heal < self.health {usize::MAX} else {self.health + heal}; + } + pub fn get_health(&self) -> usize { + self.health + } +} + +/// Marker component that marks entity to NOT be despawned at the end of frame when health reaches zero +#[derive(Component)] +#[require(Health)] +pub struct Unkillable; + +fn cleanup_killed(mut commands: Commands, query: Query<(Entity, &Health), Without>) { + for (entity, health) in query { + if health.health == 0 { + commands.entity(entity).despawn(); + } } } From 6b2d5d8af18adc57ac4b40a9ba973782c87f1e81 Mon Sep 17 00:00:00 2001 From: Rendo Date: Thu, 7 May 2026 12:50:45 +0500 Subject: [PATCH 2/3] chore: removed unnecessary Deref import --- src/health/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/health/mod.rs b/src/health/mod.rs index 91c2115..c6b5952 100644 --- a/src/health/mod.rs +++ b/src/health/mod.rs @@ -1,5 +1,3 @@ -use std::ops::Deref; - use bevy::prelude::*; pub mod event; From 48c13347fe15dcbadf2503367ffaf5278d25ce7b Mon Sep 17 00:00:00 2001 From: Rendo Date: Thu, 7 May 2026 12:52:58 +0500 Subject: [PATCH 3/3] feat(health): added damage event and vulnerable structs --- src/health/event.rs | 22 ++++++++++++++++++++++ src/health/mod.rs | 6 +++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/health/event.rs b/src/health/event.rs index e69de29..d49d862 100644 --- a/src/health/event.rs +++ b/src/health/event.rs @@ -0,0 +1,22 @@ +use bevy::prelude::*; + +use crate::health::Health; + +/// Event that is called on entities when they should recieve damage +#[derive(EntityEvent)] +pub struct Damage { + entity: Entity, + damage: usize +} + +/// Marker-component that marks entity for an automatic damage handling +#[derive(Component)] +#[require(Health)] +pub struct Vulnerable; + +/// Damages every vulnerable health components. +pub(super) fn damage_vulnerable_system(event: On, mut health_query: Query<&mut Health,With>) { + if let Ok(mut health) = health_query.get_mut(event.entity) { + health.damage(event.damage); + } +} diff --git a/src/health/mod.rs b/src/health/mod.rs index c6b5952..a36ce08 100644 --- a/src/health/mod.rs +++ b/src/health/mod.rs @@ -1,5 +1,9 @@ use bevy::prelude::*; +use event::damage_vulnerable_system; + +pub use event::{Damage,Vulnerable}; + pub mod event; /// Health plugin provides systems to handle health modifications and events @@ -7,7 +11,7 @@ pub struct HealthPlugin; impl Plugin for HealthPlugin { fn build(&self, app: &mut App) { - app.add_systems(PostUpdate,cleanup_killed); + app.add_systems(PostUpdate,cleanup_killed).add_observer(damage_vulnerable_system); } }