mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Reduce extra energy updates
This commit is contained in:
parent
fa42be75b8
commit
cc40058ae2
@ -54,14 +54,31 @@ impl Energy {
|
||||
/// Returns the fraction of energy an entity has remaining
|
||||
pub fn fraction(&self) -> f32 { self.current() / self.maximum().max(1.0) }
|
||||
|
||||
/// Updates the maximum value for energy
|
||||
pub fn update_maximum(&mut self, modifiers: comp::stats::StatsModifier) {
|
||||
/// Calculates a new maximum value and returns it if the value differs from
|
||||
/// the current maximum.
|
||||
///
|
||||
/// Note: The returned value uses an internal format so don't expect it to
|
||||
/// be useful for anything other than a parameter to
|
||||
/// [`Self::update_maximum`].
|
||||
pub fn needs_maximum_update(&self, modifiers: comp::stats::StatsModifier) -> Option<u32> {
|
||||
let maximum = modifiers
|
||||
.compute_maximum(self.base_max())
|
||||
.mul(Self::SCALING_FACTOR_FLOAT)
|
||||
// NaN does not need to be handled here as rust will automatically change to 0 when casting to u32
|
||||
.clamp(0.0, Self::MAX_SCALED_ENERGY as f32) as u32;
|
||||
|
||||
(maximum != self.maximum).then(|| maximum)
|
||||
}
|
||||
|
||||
/// Updates the maximum value for energy.
|
||||
///
|
||||
/// Note: The accepted `u32` value is in the internal format of this type.
|
||||
/// So attempting to pass values that weren't returned from
|
||||
/// [`Self::needs_maximum_update`] can produce strange or unexpected
|
||||
/// results.
|
||||
pub fn update_maximum(&mut self, maximum: u32) {
|
||||
self.maximum = maximum;
|
||||
// Clamp the current health to enforce the current <= maximum invariant.
|
||||
self.current = self.current.min(self.maximum);
|
||||
}
|
||||
|
||||
|
@ -90,13 +90,29 @@ impl Health {
|
||||
/// Returns the fraction of health an entity has remaining
|
||||
pub fn fraction(&self) -> f32 { self.current() / self.maximum().max(1.0) }
|
||||
|
||||
/// Updates the maximum value for health
|
||||
pub fn update_maximum(&mut self, modifiers: comp::stats::StatsModifier) {
|
||||
/// Calculates a new maximum value and returns it if the value differs from
|
||||
/// the current maximum.
|
||||
///
|
||||
/// Note: The returned value uses an internal format so don't expect it to
|
||||
/// be useful for anything other than a parameter to
|
||||
/// [`Self::update_maximum`].
|
||||
pub fn needs_maximum_update(&self, modifiers: comp::stats::StatsModifier) -> Option<u32> {
|
||||
let maximum = modifiers
|
||||
.compute_maximum(self.base_max())
|
||||
.mul(Self::SCALING_FACTOR_FLOAT)
|
||||
// NaN does not need to be handled here as rust will automatically change to 0 when casting to u32
|
||||
.clamp(0.0, Self::MAX_SCALED_HEALTH as f32) as u32;
|
||||
|
||||
(maximum != self.maximum).then(|| maximum)
|
||||
}
|
||||
|
||||
/// Updates the maximum value for health.
|
||||
///
|
||||
/// Note: The accepted `u32` value is in the internal format of this type.
|
||||
/// So attempting to pass values that weren't returned from
|
||||
/// [`Self::needs_maximum_update`] can produce strange or unexpected
|
||||
/// results.
|
||||
pub fn update_maximum(&mut self, maximum: u32) {
|
||||
self.maximum = maximum;
|
||||
// Clamp the current health to enforce the current <= maximum invariant.
|
||||
self.current = self.current.min(self.maximum);
|
||||
|
@ -30,6 +30,7 @@ impl StatsModifier {
|
||||
base_value * self.mult_mod + self.add_mod
|
||||
}
|
||||
|
||||
// Note: unused for now
|
||||
pub fn update_maximum(&self) -> bool {
|
||||
self.add_mod.abs() > f32::EPSILON || (self.mult_mod - 1.0).abs() > f32::EPSILON
|
||||
}
|
||||
|
@ -92,32 +92,19 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
let stat = stats;
|
||||
|
||||
let update_max_hp = {
|
||||
stat.max_health_modifiers.update_maximum()
|
||||
|| (health.base_max() - health.maximum()).abs() > Health::HEALTH_EPSILON
|
||||
};
|
||||
|
||||
if update_max_hp {
|
||||
health.update_maximum(stat.max_health_modifiers);
|
||||
if let Some(new_max) = health.needs_maximum_update(stat.max_health_modifiers) {
|
||||
health.update_maximum(new_max);
|
||||
}
|
||||
|
||||
let (change_energy, energy_mods) = {
|
||||
// Calculates energy scaling from stats and inventory
|
||||
let energy_mods = StatsModifier {
|
||||
add_mod: stat.max_energy_modifiers.add_mod
|
||||
+ combat::compute_max_energy_mod(inventory),
|
||||
mult_mod: stat.max_energy_modifiers.mult_mod,
|
||||
};
|
||||
(
|
||||
energy_mods.update_maximum()
|
||||
|| (energy.base_max() - energy.maximum()).abs() > Energy::ENERGY_EPSILON,
|
||||
energy_mods,
|
||||
)
|
||||
// Calculates energy scaling from stats and inventory
|
||||
let energy_mods = StatsModifier {
|
||||
add_mod: stat.max_energy_modifiers.add_mod
|
||||
+ combat::compute_max_energy_mod(inventory),
|
||||
mult_mod: stat.max_energy_modifiers.mult_mod,
|
||||
};
|
||||
|
||||
// If modifier sufficiently different, mutably access energy
|
||||
if change_energy {
|
||||
energy.update_maximum(energy_mods);
|
||||
if let Some(new_max) = energy.needs_maximum_update(energy_mods) {
|
||||
energy.update_maximum(new_max);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user