2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
|
|
use crate::comp::Body;
|
|
|
|
use crate::{uid::Uid, DamageSource};
|
2020-10-31 22:34:08 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2021-02-17 13:03:20 +00:00
|
|
|
|
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2021-01-07 20:25:12 +00:00
|
|
|
use specs::{Component, DerefFlaggedStorage};
|
2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2020-10-31 22:34:08 +00:00
|
|
|
use specs_idvs::IdvStorage;
|
|
|
|
|
|
|
|
/// Specifies what and how much changed current health
|
|
|
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
pub struct HealthChange {
|
|
|
|
pub amount: i32,
|
|
|
|
pub cause: HealthSource,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
pub enum HealthSource {
|
2020-11-05 01:21:42 +00:00
|
|
|
Damage { kind: DamageSource, by: Option<Uid> },
|
|
|
|
Heal { by: Option<Uid> },
|
|
|
|
//Attack { by: Uid }, // TODO: Implement weapon
|
|
|
|
//Projectile { owner: Option<Uid> },
|
|
|
|
//Explosion { owner: Option<Uid> },
|
|
|
|
//Energy { owner: Option<Uid> },
|
|
|
|
//Buff { owner: Option<Uid> },
|
2020-10-31 22:34:08 +00:00
|
|
|
Suicide,
|
|
|
|
World,
|
|
|
|
Revive,
|
|
|
|
Command,
|
|
|
|
LevelUp,
|
|
|
|
Item,
|
2020-11-05 01:21:42 +00:00
|
|
|
//Healing { by: Option<Uid> },
|
2020-10-31 22:34:08 +00:00
|
|
|
Unknown,
|
|
|
|
}
|
|
|
|
|
2021-07-14 07:40:43 +00:00
|
|
|
impl HealthSource {
|
|
|
|
pub fn damage_by(&self) -> Option<Uid> {
|
|
|
|
if let HealthSource::Damage { by, .. } = self {
|
|
|
|
*by
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-21 05:53:39 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
2020-10-31 22:34:08 +00:00
|
|
|
pub struct Health {
|
|
|
|
current: u32,
|
2021-03-20 17:29:57 +00:00
|
|
|
base_max: u32,
|
2020-10-31 22:34:08 +00:00
|
|
|
maximum: u32,
|
|
|
|
pub last_change: (f64, HealthChange),
|
|
|
|
pub is_dead: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Health {
|
2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2021-01-04 17:16:42 +00:00
|
|
|
pub fn new(body: Body, level: u16) -> Self {
|
2020-10-31 22:34:08 +00:00
|
|
|
let mut health = Health::empty();
|
|
|
|
|
|
|
|
health.update_max_hp(Some(body), level);
|
|
|
|
health.set_to(health.maximum(), HealthSource::Revive);
|
|
|
|
|
|
|
|
health
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn empty() -> Self {
|
|
|
|
Health {
|
|
|
|
current: 0,
|
|
|
|
base_max: 0,
|
2021-03-20 17:29:57 +00:00
|
|
|
maximum: 0,
|
2020-10-31 22:34:08 +00:00
|
|
|
last_change: (0.0, HealthChange {
|
|
|
|
amount: 0,
|
|
|
|
cause: HealthSource::Revive,
|
|
|
|
}),
|
|
|
|
is_dead: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn current(&self) -> u32 { self.current }
|
|
|
|
|
|
|
|
pub fn maximum(&self) -> u32 { self.maximum }
|
|
|
|
|
2021-03-20 17:29:57 +00:00
|
|
|
pub fn base_max(&self) -> u32 { self.base_max }
|
|
|
|
|
2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2020-10-31 22:34:08 +00:00
|
|
|
pub fn set_to(&mut self, amount: u32, cause: HealthSource) {
|
|
|
|
let amount = amount.min(self.maximum);
|
|
|
|
self.last_change = (0.0, HealthChange {
|
|
|
|
amount: amount as i32 - self.current as i32,
|
|
|
|
cause,
|
|
|
|
});
|
|
|
|
self.current = amount;
|
|
|
|
}
|
|
|
|
|
2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2020-10-31 22:34:08 +00:00
|
|
|
pub fn change_by(&mut self, change: HealthChange) {
|
|
|
|
self.current = ((self.current as i32 + change.amount).max(0) as u32).min(self.maximum);
|
|
|
|
self.last_change = (0.0, change);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This function changes the modified max health value, not the base health
|
|
|
|
// value. The modified health value takes into account buffs and other temporary
|
|
|
|
// changes to max health.
|
|
|
|
pub fn set_maximum(&mut self, amount: u32) {
|
|
|
|
self.maximum = amount;
|
|
|
|
self.current = self.current.min(self.maximum);
|
|
|
|
}
|
|
|
|
|
2021-03-20 17:29:57 +00:00
|
|
|
// Scales the temporary max health by a modifier.
|
|
|
|
pub fn scale_maximum(&mut self, scaled: f32) {
|
|
|
|
let scaled_max = (self.base_max as f32 * scaled) as u32;
|
|
|
|
self.set_maximum(scaled_max);
|
|
|
|
}
|
|
|
|
|
2020-10-31 22:34:08 +00:00
|
|
|
// This is private because max hp is based on the level
|
2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2020-10-31 22:34:08 +00:00
|
|
|
fn set_base_max(&mut self, amount: u32) {
|
|
|
|
self.base_max = amount;
|
|
|
|
self.current = self.current.min(self.maximum);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn should_die(&self) -> bool { self.current == 0 }
|
|
|
|
|
2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2020-10-31 22:34:08 +00:00
|
|
|
pub fn revive(&mut self) {
|
|
|
|
self.set_to(self.maximum(), HealthSource::Revive);
|
|
|
|
self.is_dead = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Delete this once stat points will be a thing
|
2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2021-01-04 17:16:42 +00:00
|
|
|
pub fn update_max_hp(&mut self, body: Option<Body>, level: u16) {
|
2020-10-31 22:34:08 +00:00
|
|
|
if let Some(body) = body {
|
2021-01-04 17:16:42 +00:00
|
|
|
self.set_base_max(body.base_health() + body.base_health_increase() * level as u32);
|
|
|
|
self.set_maximum(body.base_health() + body.base_health_increase() * level as u32);
|
2021-01-07 18:01:16 +00:00
|
|
|
self.change_by(HealthChange {
|
|
|
|
amount: body.base_health_increase() as i32,
|
|
|
|
cause: HealthSource::LevelUp,
|
|
|
|
});
|
2020-10-31 22:34:08 +00:00
|
|
|
}
|
|
|
|
}
|
2021-03-21 18:22:14 +00:00
|
|
|
|
|
|
|
/// Returns the fraction of health an entity has remaining
|
2021-03-28 00:38:56 +00:00
|
|
|
pub fn fraction(&self) -> f32 { self.current as f32 / self.maximum.max(1) as f32 }
|
StaminaPlus buff, modifying stamina via buffs
trying to fix this, coming back to this later
please remember to change potion back future self!
this ALMOST works. maybe MR ready, kinda jank tho
so close, and yet so far...
IT WORKS IT WORKS IT WORKS IT WORKS IT WORKS IT WO
did the same with health, ill fix this garbage l8r
think we're basically done here
whoops forgot to change the food back
fixing and cleaning up part 1
fixed everything part 2 now with buff images
ran clippy + fmt, fixed items that i modified
bracket bulldozing, boldly
hopefully this should be good?
need to rebase real quick
please let me be done
StaminaPlus buff, modifying stamina via buffs
trying to fix this, coming back to this later
please remember to change potion back future self!
this ALMOST works. maybe MR ready, kinda jank tho
so close, and yet so far...
IT WORKS IT WORKS IT WORKS IT WORKS IT WORKS IT WO
did the same with health, ill fix this garbage l8r
think we're basically done here
whoops forgot to change the food back
fixing and cleaning up part 1
fixed everything part 2 now with buff images
ran clippy + fmt, fixed items that i modified
hopefully this should be good?
cargo clippy fmt stuff
deleted an extraneous file?? how did that even...?
2021-01-26 22:47:55 +00:00
|
|
|
}
|
2021-02-17 13:03:20 +00:00
|
|
|
|
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2020-10-31 22:34:08 +00:00
|
|
|
impl Component for Health {
|
2021-01-07 20:25:12 +00:00
|
|
|
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
|
2020-10-31 22:34:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
2020-11-01 17:15:46 +00:00
|
|
|
pub struct Dead {
|
2020-10-31 22:34:08 +00:00
|
|
|
pub cause: HealthSource,
|
|
|
|
}
|
|
|
|
|
2021-02-17 13:03:20 +00:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2020-11-01 17:15:46 +00:00
|
|
|
impl Component for Dead {
|
2020-10-31 22:34:08 +00:00
|
|
|
type Storage = IdvStorage<Self>;
|
|
|
|
}
|