Health for entities
This commit is contained in:
parent
8604a6bb87
commit
3e3fd85acc
7 changed files with 136 additions and 1 deletions
BIN
assets/sprites/background.png
Normal file
BIN
assets/sprites/background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
assets/sprites/sun.png
Normal file
BIN
assets/sprites/sun.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 706 B |
126
src/health.rs
Normal file
126
src/health.rs
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use std::ops::{Add,Sub,AddAssign,SubAssign};
|
||||||
|
|
||||||
|
pub struct HealthPlugin;
|
||||||
|
|
||||||
|
impl Plugin for HealthPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(PostUpdate, despawn_killed)
|
||||||
|
.add_observer(recieve_damage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Component that holds health information of damageable entity
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Health{
|
||||||
|
health: u32,
|
||||||
|
max_health: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Health {
|
||||||
|
/// Create entity with minimum hp to not despawn immediatly
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { health: 1, max_health: 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<u32> 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<u32> for Health {
|
||||||
|
type Output = u32;
|
||||||
|
|
||||||
|
fn sub(self, rhs: u32) -> Self::Output {
|
||||||
|
if self.health < rhs {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.health - rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddAssign<u32> 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<u32> 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<Unkillable>>) {
|
||||||
|
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<Damage>, mut query: Query<&mut Health, With<Vulnerable>>) {
|
||||||
|
let Ok(mut health) = query.get_mut(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
*health -= event.damage;
|
||||||
|
}
|
||||||
0
src/level/mod.rs
Normal file
0
src/level/mod.rs
Normal file
11
src/main.rs
11
src/main.rs
|
|
@ -1,3 +1,12 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::health::HealthPlugin;
|
||||||
|
|
||||||
|
mod plant;
|
||||||
|
mod zombie;
|
||||||
|
mod health;
|
||||||
|
mod level;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
App::new().add_plugins(DefaultPlugins).add_plugins(HealthPlugin).run();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
0
src/plant/mod.rs
Normal file
0
src/plant/mod.rs
Normal file
0
src/zombie/mod.rs
Normal file
0
src/zombie/mod.rs
Normal file
Loading…
Add table
Add a link
Reference in a new issue