From 3e3fd85accf664bd0e808df3035ef00d80efb910 Mon Sep 17 00:00:00 2001 From: Rendo Date: Thu, 30 Apr 2026 21:58:56 +0500 Subject: [PATCH] Health for entities --- assets/sprites/background.png | Bin 0 -> 4283 bytes assets/sprites/sun.png | Bin 0 -> 706 bytes src/health.rs | 126 ++++++++++++++++++++++++++++++++++ src/level/mod.rs | 0 src/main.rs | 11 ++- src/plant/mod.rs | 0 src/zombie/mod.rs | 0 7 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 assets/sprites/background.png create mode 100644 assets/sprites/sun.png create mode 100644 src/health.rs create mode 100644 src/level/mod.rs create mode 100644 src/plant/mod.rs create mode 100644 src/zombie/mod.rs diff --git a/assets/sprites/background.png b/assets/sprites/background.png new file mode 100644 index 0000000000000000000000000000000000000000..ab14f40f59c27c5df73b8aad21a9af525d625572 GIT binary patch literal 4283 zcmeAS@N?(olHy`uVBq!ia0y~yU}<1rU<%-11B!fellKQwjKx9jP7LeL$-HD>5GeI@ zaSW-L^Y+%pT3i}(T`XZfMkOOBL|RD@MB;CQXRq#Kyp-SG&B@|$zU{X z5Stx#eE!1lpz`nUzr|IDR-7)KJE^d zC|}N9W^Q<1x-;*xu$%3>-(Ok+-@X5*T?~xQo3Fmx-(AMeAoF-ME`d=w6zU3aTz=j0 z9vGLg>u#gQW&KP!hJp$F3P7KX7I(xJcLUdEu=eL?n0Ni@E?<8MNQCa(|9kzJzjy0X zSKt3%G8-6|J)?0sL|Sr?xO}|N-(Lb!&?3iWY8Ar)N4o}Kwj2s2%t&rZTRb^`{QgT$ zU_|{{{`TwJ+WB&fK=y&}9~oJIw17GThPx%d`Uz>R9J=OnK5qbFbsz2hai~@Wb@+jZS~+|bnpQ(_#{0*PtxHXAVZFkLESQX z$yT6Kv$(?p1Dd8pMy3lqydMYaKFN=MK7tH(^bWqP)OeK|^1TutM13Cp_w<{}+^o-7^Ku z1s_kDy4gbW_Bkuyp)W@dFnXHNgTmxd3JGM>cuG2Q>2-GKDeO{jhQ3r!Gjr(cW;@Bb z;dliAfR8`FRquwr9AoK{8uxJMrPbD5WrCCx`f{X@=m0toZ)D6}jn`&D4ach(p&{I6 zkg!IZhZ9ms3zR;S(gWoJD#7vZmqx?9>r<Kz_BX)l6$pu(3-|Qe!u!iv z9k)MR)cFby8LMZp&{0ouP!xsbc825C6s<{)E`hX)=WE?n5CA658p3Td=K1_p6u?5y z3%fQcD&|d8%Bzw+4!c2O3hS{;b2OcE3VjbfZlKU?-5ZWLj4WFGk!@CT6VpuUdEb_nAZ_ls-ZOWmip-e3K=PqTSwI&Si7ba zaB4h`(_oWl{Uf&=u?|UFq_qr2S0OdFYsunOwR_^tEiWUFYzS?RR0PFI=v`;sRkQq) zR&Kd1*&i;2rGiNI)y7#fU=iKf`@^N+p2J*DZAjIlj{r&)B2|83p_YCx<|rOpL%3yo z(W2(`K>q9c$&{$6`?vx+7UCxyjLHEaw7)IW%E!8Ry oa__KCkgx_Qtr-7=y#HeS1}pn(x>sFO@Bjb+07*qoM6N<$f Self { + Self { health: 1, max_health: 1 } + } +} + +impl Add for Health { + type Output = u32; + + fn add(self, rhs: u32) -> Self::Output { + if u32::MAX - self.health < rhs { + u32::MAX + } + else { + self.health + rhs + } + } +} + +impl Sub for Health { + type Output = u32; + + fn sub(self, rhs: u32) -> Self::Output { + if self.health < rhs { + 0 + } + else { + self.health - rhs + } + } +} + +impl AddAssign for Health { + fn add_assign(&mut self, rhs: u32) { + if u32::MAX - self.health < rhs { + self.health = u32::MAX; + } + else { + self.health += rhs; + } + } +} + +impl SubAssign for Health { + fn sub_assign(&mut self, rhs: u32) { + if self.health < rhs { + self.health = 0; + } + else { + self.health -= rhs; + } + } +} + +impl Health { + /// Create new health component with set health and max health + pub fn new(health: u32, max_health: u32) -> Self { + Self { + health, + max_health + } + } + /// Create new health from max health + pub fn new_full(max_health: u32) -> Self { + Self { + health: max_health, + max_health + } + } +} + +/// Event sent on an vulnerable entity to damage it. +#[derive(EntityEvent)] +pub struct Damage{ + entity: Entity, + damage: u32 +} + +/// Marks entity to recieve [`Damage`] events. +#[derive(Component)] +#[require(Health)] +pub struct Vulnerable; + +/// Marks entity to not despawn when health drops to zero. +#[derive(Component)] +#[require(Health)] +pub struct Unkillable; + +/// Despawn all killable entites with health equal to zero +pub fn despawn_killed(mut commands: Commands, query: Query<(Entity, &Health), Without>) { + for (entity, health) in query { + if health.health == 0 { + commands.entity(entity).despawn(); + } + } +} + +/// Process damage event for vulnerable entities +pub fn recieve_damage(event: On, mut query: Query<&mut Health, With>) { + let Ok(mut health) = query.get_mut(event.entity) else { + return; + }; + + *health -= event.damage; +} diff --git a/src/level/mod.rs b/src/level/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/main.rs b/src/main.rs index e7a11a9..1f83b97 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,12 @@ +use bevy::prelude::*; + +use crate::health::HealthPlugin; + +mod plant; +mod zombie; +mod health; +mod level; + fn main() { - println!("Hello, world!"); + App::new().add_plugins(DefaultPlugins).add_plugins(HealthPlugin).run(); } diff --git a/src/plant/mod.rs b/src/plant/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/zombie/mod.rs b/src/zombie/mod.rs new file mode 100644 index 0000000..e69de29