2020-12-01 00:28:00 +00:00
|
|
|
use common::{
|
2020-10-13 00:48:25 +00:00
|
|
|
comp::{
|
2021-06-20 05:37:22 +00:00
|
|
|
buff::{
|
|
|
|
Buff, BuffCategory, BuffChange, BuffData, BuffEffect, BuffId, BuffKind, BuffSource,
|
|
|
|
Buffs,
|
|
|
|
},
|
2021-06-18 20:35:30 +00:00
|
|
|
fluid_dynamics::{Fluid, LiquidKind},
|
|
|
|
Energy, Health, HealthChange, HealthSource, Inventory, ModifierKind, PhysicsState, Stats,
|
2020-10-13 00:48:25 +00:00
|
|
|
},
|
2020-10-01 02:32:38 +00:00
|
|
|
event::{EventBus, ServerEvent},
|
2020-12-01 00:28:00 +00:00
|
|
|
resources::DeltaTime,
|
2021-06-20 05:37:22 +00:00
|
|
|
terrain::SpriteKind,
|
2021-01-08 19:12:09 +00:00
|
|
|
Damage, DamageSource,
|
2020-08-10 22:54:45 +00:00
|
|
|
};
|
2021-03-08 22:40:02 +00:00
|
|
|
use common_ecs::{Job, Origin, Phase, System};
|
2021-05-30 16:40:11 +00:00
|
|
|
use hashbrown::HashMap;
|
2021-02-22 19:03:18 +00:00
|
|
|
use specs::{
|
2021-03-04 14:00:16 +00:00
|
|
|
shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData, World, WriteStorage,
|
2021-02-22 19:03:18 +00:00
|
|
|
};
|
2020-08-10 22:54:45 +00:00
|
|
|
use std::time::Duration;
|
|
|
|
|
2021-02-22 19:03:18 +00:00
|
|
|
#[derive(SystemData)]
|
2021-02-22 21:02:37 +00:00
|
|
|
pub struct ReadData<'a> {
|
2021-02-22 19:03:18 +00:00
|
|
|
entities: Entities<'a>,
|
|
|
|
dt: Read<'a, DeltaTime>,
|
|
|
|
server_bus: Read<'a, EventBus<ServerEvent>>,
|
|
|
|
inventories: ReadStorage<'a, Inventory>,
|
2021-03-20 17:29:57 +00:00
|
|
|
healths: ReadStorage<'a, Health>,
|
2021-05-13 05:34:51 +00:00
|
|
|
physics_states: ReadStorage<'a, PhysicsState>,
|
2021-05-21 00:52:29 +00:00
|
|
|
energies: ReadStorage<'a, Energy>,
|
2021-02-22 19:03:18 +00:00
|
|
|
}
|
|
|
|
|
2021-03-04 14:00:16 +00:00
|
|
|
#[derive(Default)]
|
2020-08-10 22:54:45 +00:00
|
|
|
pub struct Sys;
|
2021-03-08 11:13:59 +00:00
|
|
|
impl<'a> System<'a> for Sys {
|
2020-08-10 22:54:45 +00:00
|
|
|
type SystemData = (
|
2021-02-22 21:02:37 +00:00
|
|
|
ReadData<'a>,
|
2020-08-10 22:54:45 +00:00
|
|
|
WriteStorage<'a, Buffs>,
|
2021-02-28 20:02:03 +00:00
|
|
|
WriteStorage<'a, Stats>,
|
2020-08-10 22:54:45 +00:00
|
|
|
);
|
|
|
|
|
2021-03-04 14:00:16 +00:00
|
|
|
const NAME: &'static str = "buff";
|
|
|
|
const ORIGIN: Origin = Origin::Common;
|
|
|
|
const PHASE: Phase = Phase::Create;
|
|
|
|
|
2021-05-21 00:52:29 +00:00
|
|
|
fn run(_job: &mut Job<Self>, (read_data, mut buffs, mut stats): Self::SystemData) {
|
2021-02-22 21:02:37 +00:00
|
|
|
let mut server_emitter = read_data.server_bus.emitter();
|
|
|
|
let dt = read_data.dt.0;
|
2020-10-19 03:00:35 +00:00
|
|
|
// Set to false to avoid spamming server
|
2020-10-25 01:20:03 +00:00
|
|
|
buffs.set_event_emission(false);
|
2021-02-28 20:02:03 +00:00
|
|
|
stats.set_event_emission(false);
|
2021-06-16 21:40:18 +00:00
|
|
|
for (entity, mut buff_comp, energy, mut stat, health, physics_state) in (
|
2021-02-28 20:02:03 +00:00
|
|
|
&read_data.entities,
|
|
|
|
&mut buffs,
|
2021-05-21 00:52:29 +00:00
|
|
|
&read_data.energies,
|
2021-02-28 20:02:03 +00:00
|
|
|
&mut stats,
|
2021-03-20 17:29:57 +00:00
|
|
|
&read_data.healths,
|
2021-06-16 21:40:18 +00:00
|
|
|
read_data.physics_states.maybe(),
|
2021-02-28 20:02:03 +00:00
|
|
|
)
|
|
|
|
.join()
|
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-06-20 05:37:22 +00:00
|
|
|
// Apply buffs to entity based off of their current physics_state
|
|
|
|
if let Some(physics_state) = physics_state {
|
|
|
|
if matches!(
|
|
|
|
physics_state.on_ground.and_then(|b| b.get_sprite()),
|
|
|
|
Some(SpriteKind::EnsnaringVines)
|
|
|
|
) {
|
2021-06-22 01:50:31 +00:00
|
|
|
// If on ensnaring vines, apply ensnared debuff
|
2021-06-20 05:37:22 +00:00
|
|
|
server_emitter.emit(ServerEvent::Buff {
|
|
|
|
entity,
|
|
|
|
buff_change: BuffChange::Add(Buff::new(
|
|
|
|
BuffKind::Ensnared,
|
|
|
|
BuffData::new(1.5, Some(Duration::from_secs_f32(1.0))),
|
|
|
|
Vec::new(),
|
|
|
|
BuffSource::World,
|
|
|
|
)),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if matches!(
|
|
|
|
physics_state.in_fluid,
|
|
|
|
Some(Fluid::Liquid {
|
|
|
|
kind: LiquidKind::Lava,
|
|
|
|
..
|
|
|
|
})
|
|
|
|
) {
|
2021-06-22 01:50:31 +00:00
|
|
|
// If in lava fluid, apply burning debuff
|
2021-06-20 05:37:22 +00:00
|
|
|
server_emitter.emit(ServerEvent::Buff {
|
|
|
|
entity,
|
|
|
|
buff_change: BuffChange::Add(Buff::new(
|
|
|
|
BuffKind::Burning,
|
|
|
|
BuffData::new(200.0, None),
|
|
|
|
vec![BuffCategory::Natural],
|
|
|
|
BuffSource::World,
|
|
|
|
)),
|
|
|
|
});
|
|
|
|
} else if matches!(
|
|
|
|
physics_state.in_fluid,
|
|
|
|
Some(Fluid::Liquid {
|
|
|
|
kind: LiquidKind::Water,
|
|
|
|
..
|
|
|
|
})
|
2021-06-22 01:50:31 +00:00
|
|
|
) && buff_comp.kinds.contains_key(&BuffKind::Burning)
|
|
|
|
{
|
|
|
|
// If in water fluid and currently burning, remove burning debuffs
|
|
|
|
server_emitter.emit(ServerEvent::Buff {
|
|
|
|
entity,
|
|
|
|
buff_change: BuffChange::RemoveByKind(BuffKind::Burning),
|
|
|
|
});
|
2021-06-20 05:37:22 +00:00
|
|
|
}
|
2021-06-16 21:40:18 +00:00
|
|
|
}
|
|
|
|
|
2021-05-30 16:40:11 +00:00
|
|
|
let (buff_comp_kinds, buff_comp_buffs): (
|
|
|
|
&HashMap<BuffKind, Vec<BuffId>>,
|
|
|
|
&mut HashMap<BuffId, Buff>,
|
|
|
|
) = buff_comp.parts();
|
2020-10-24 20:12:37 +00:00
|
|
|
let mut expired_buffs = Vec::<BuffId>::new();
|
2021-06-16 21:40:18 +00:00
|
|
|
|
2021-02-20 20:37:46 +00:00
|
|
|
// For each buff kind present on entity, if the buff kind queues, only ticks
|
|
|
|
// duration of strongest buff of that kind, else it ticks durations of all buffs
|
|
|
|
// of that kind. Any buffs whose durations expire are marked expired.
|
|
|
|
for (kind, ids) in buff_comp_kinds.iter() {
|
|
|
|
if kind.queues() {
|
|
|
|
if let Some((Some(buff), id)) =
|
|
|
|
ids.get(0).map(|id| (buff_comp_buffs.get_mut(id), id))
|
2020-10-24 20:12:37 +00:00
|
|
|
{
|
2021-06-20 05:37:22 +00:00
|
|
|
tick_buff(*id, buff, dt, |id| expired_buffs.push(id));
|
2021-02-20 20:37:46 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (id, buff) in buff_comp_buffs
|
|
|
|
.iter_mut()
|
|
|
|
.filter(|(i, _)| ids.iter().any(|id| id == *i))
|
|
|
|
{
|
2021-06-20 05:37:22 +00:00
|
|
|
tick_buff(*id, buff, dt, |id| expired_buffs.push(id));
|
2020-10-24 20:12:37 +00:00
|
|
|
}
|
2020-10-19 03:00:35 +00:00
|
|
|
}
|
|
|
|
}
|
2020-08-10 22:54:45 +00:00
|
|
|
|
2021-05-06 18:50:16 +00:00
|
|
|
let damage_reduction = Damage::compute_damage_reduction(
|
|
|
|
read_data.inventories.get(entity),
|
|
|
|
Some(&stat),
|
|
|
|
None,
|
|
|
|
);
|
2021-02-28 20:02:03 +00:00
|
|
|
if (damage_reduction - 1.0).abs() < f32::EPSILON {
|
|
|
|
for (id, buff) in buff_comp.buffs.iter() {
|
|
|
|
if !buff.kind.is_buff() {
|
|
|
|
expired_buffs.push(*id);
|
2020-10-25 18:42:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-21 00:52:29 +00:00
|
|
|
// Call to reset stats to base values
|
2021-03-20 17:29:57 +00:00
|
|
|
stat.reset_temp_modifiers();
|
2020-10-24 23:07:38 +00:00
|
|
|
|
|
|
|
// Iterator over the lists of buffs by kind
|
2021-01-07 20:25:12 +00:00
|
|
|
let buff_comp = &mut *buff_comp;
|
2020-10-24 20:12:37 +00:00
|
|
|
for buff_ids in buff_comp.kinds.values() {
|
2020-10-24 23:07:38 +00:00
|
|
|
// Get the strongest of this buff kind
|
2020-10-24 20:12:37 +00:00
|
|
|
if let Some(buff) = buff_comp.buffs.get_mut(&buff_ids[0]) {
|
2020-10-24 23:07:38 +00:00
|
|
|
// Get buff owner?
|
2020-10-24 20:12:37 +00:00
|
|
|
let buff_owner = if let BuffSource::Character { by: owner } = buff.source {
|
|
|
|
Some(owner)
|
2020-10-19 03:00:35 +00:00
|
|
|
} else {
|
2020-10-24 20:12:37 +00:00
|
|
|
None
|
2020-10-19 03:00:35 +00:00
|
|
|
};
|
2020-10-24 23:07:38 +00:00
|
|
|
|
2020-10-24 20:12:37 +00:00
|
|
|
// Now, execute the buff, based on it's delta
|
|
|
|
for effect in &mut buff.effects {
|
|
|
|
match effect {
|
2020-12-04 22:24:56 +00:00
|
|
|
BuffEffect::HealthChangeOverTime {
|
|
|
|
rate,
|
|
|
|
accumulated,
|
|
|
|
kind,
|
|
|
|
} => {
|
2021-02-22 19:03:18 +00:00
|
|
|
*accumulated += *rate * dt;
|
2021-03-20 17:29:57 +00:00
|
|
|
// Apply health change only once per second, per health, or
|
2020-10-24 20:12:37 +00:00
|
|
|
// when a buff is removed
|
2021-03-20 17:29:57 +00:00
|
|
|
if accumulated.abs() > rate.abs().min(10.0)
|
2020-10-24 20:12:37 +00:00
|
|
|
|| buff.time.map_or(false, |dur| dur == Duration::default())
|
|
|
|
{
|
|
|
|
let cause = if *accumulated > 0.0 {
|
2020-11-05 01:21:42 +00:00
|
|
|
HealthSource::Heal { by: buff_owner }
|
2020-10-24 20:12:37 +00:00
|
|
|
} else {
|
2020-11-05 01:21:42 +00:00
|
|
|
HealthSource::Damage {
|
2021-01-18 05:46:53 +00:00
|
|
|
kind: DamageSource::Buff(buff.kind),
|
2020-11-05 01:21:42 +00:00
|
|
|
by: buff_owner,
|
|
|
|
}
|
2020-10-24 20:12:37 +00:00
|
|
|
};
|
2020-12-04 22:24:56 +00:00
|
|
|
let amount = match *kind {
|
|
|
|
ModifierKind::Additive => *accumulated as i32,
|
|
|
|
ModifierKind::Fractional => {
|
|
|
|
(health.maximum() as f32 * *accumulated) as i32
|
|
|
|
},
|
|
|
|
};
|
2020-10-24 20:12:37 +00:00
|
|
|
server_emitter.emit(ServerEvent::Damage {
|
2020-11-02 00:26:01 +00:00
|
|
|
entity,
|
2020-12-04 22:24:56 +00:00
|
|
|
change: HealthChange { amount, cause },
|
2020-10-24 20:12:37 +00:00
|
|
|
});
|
|
|
|
*accumulated = 0.0;
|
|
|
|
};
|
|
|
|
},
|
2020-10-24 23:07:38 +00:00
|
|
|
BuffEffect::MaxHealthModifier { value, kind } => match kind {
|
|
|
|
ModifierKind::Additive => {
|
2021-05-21 00:52:29 +00:00
|
|
|
stat.max_health_modifier += *value / (health.base_max() as f32);
|
2020-12-04 22:24:56 +00:00
|
|
|
},
|
|
|
|
ModifierKind::Fractional => {
|
2021-03-20 17:29:57 +00:00
|
|
|
stat.max_health_modifier *= *value;
|
2020-10-24 23:07:38 +00:00
|
|
|
},
|
|
|
|
},
|
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
|
|
|
BuffEffect::MaxEnergyModifier { value, kind } => match kind {
|
|
|
|
ModifierKind::Additive => {
|
2021-05-21 00:52:29 +00:00
|
|
|
stat.max_energy_modifier += *value / (energy.base_max() 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
|
|
|
},
|
|
|
|
ModifierKind::Fractional => {
|
2021-05-21 00:52:29 +00:00
|
|
|
stat.max_energy_modifier *= *value;
|
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-03-04 03:43:11 +00:00
|
|
|
BuffEffect::DamageReduction(dr) => {
|
2021-03-16 19:17:08 +00:00
|
|
|
stat.damage_reduction = stat.damage_reduction.max(*dr).min(1.0);
|
2021-02-28 20:02:03 +00:00
|
|
|
},
|
2021-03-20 17:29:57 +00:00
|
|
|
BuffEffect::MaxHealthChangeOverTime {
|
|
|
|
rate,
|
|
|
|
accumulated,
|
|
|
|
kind,
|
|
|
|
target_fraction,
|
|
|
|
} => {
|
|
|
|
*accumulated += *rate * dt;
|
|
|
|
let current_fraction = health.maximum() as f32
|
|
|
|
/ (health.base_max() as f32 * stat.max_health_modifier);
|
|
|
|
let progress = (1.0 - current_fraction) / (1.0 - *target_fraction);
|
|
|
|
if progress > 1.0 {
|
|
|
|
stat.max_health_modifier *= *target_fraction;
|
|
|
|
} else if accumulated.abs() > rate.abs() {
|
|
|
|
match kind {
|
|
|
|
ModifierKind::Additive => {
|
|
|
|
stat.max_health_modifier = stat.max_health_modifier
|
|
|
|
* current_fraction
|
|
|
|
+ *accumulated / health.maximum() as f32;
|
|
|
|
},
|
|
|
|
ModifierKind::Fractional => {
|
|
|
|
stat.max_health_modifier *=
|
|
|
|
current_fraction * (1.0 - *accumulated);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
*accumulated = 0.0;
|
|
|
|
} else {
|
|
|
|
stat.max_health_modifier *= current_fraction;
|
|
|
|
}
|
|
|
|
},
|
2021-05-30 20:40:25 +00:00
|
|
|
BuffEffect::MovementSpeed(speed) => {
|
|
|
|
stat.move_speed_modifier *= *speed;
|
2021-04-16 17:44:11 +00:00
|
|
|
},
|
2021-05-30 20:40:25 +00:00
|
|
|
BuffEffect::AttackSpeed(speed) => {
|
|
|
|
stat.attack_speed_modifier *= *speed;
|
2021-05-30 16:40:11 +00:00
|
|
|
},
|
2021-05-24 00:45:22 +00:00
|
|
|
BuffEffect::GroundFriction(gf) => {
|
|
|
|
stat.friction_modifier *= *gf;
|
|
|
|
},
|
2020-10-24 20:12:37 +00:00
|
|
|
};
|
|
|
|
}
|
2020-10-19 03:00:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-24 20:12:37 +00:00
|
|
|
// Remove buffs that expire
|
|
|
|
if !expired_buffs.is_empty() {
|
2020-10-19 03:00:35 +00:00
|
|
|
server_emitter.emit(ServerEvent::Buff {
|
2020-10-25 01:20:03 +00:00
|
|
|
entity,
|
2020-10-24 20:12:37 +00:00
|
|
|
buff_change: BuffChange::RemoveById(expired_buffs),
|
2020-10-19 03:00:35 +00:00
|
|
|
});
|
|
|
|
}
|
2020-10-11 21:39:52 +00:00
|
|
|
|
2020-10-31 22:34:08 +00:00
|
|
|
// Remove buffs that don't persist on death
|
|
|
|
if health.is_dead {
|
2020-10-13 00:48:25 +00:00
|
|
|
server_emitter.emit(ServerEvent::Buff {
|
2020-10-25 01:20:03 +00:00
|
|
|
entity,
|
2020-10-13 00:48:25 +00:00
|
|
|
buff_change: BuffChange::RemoveByCategory {
|
2020-10-24 20:12:37 +00:00
|
|
|
all_required: vec![],
|
|
|
|
any_required: vec![],
|
|
|
|
none_required: vec![BuffCategory::PersistOnDeath],
|
2020-10-13 00:48:25 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
2020-08-10 22:54:45 +00:00
|
|
|
}
|
2020-10-27 01:17:46 +00:00
|
|
|
// Turned back to true
|
2020-10-25 01:20:03 +00:00
|
|
|
buffs.set_event_emission(true);
|
2021-02-28 20:02:03 +00:00
|
|
|
stats.set_event_emission(true);
|
2020-08-10 22:54:45 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-20 20:37:46 +00:00
|
|
|
|
2021-06-22 01:50:31 +00:00
|
|
|
fn tick_buff(id: u64, buff: &mut Buff, dt: f32, mut expire_buff: impl FnMut(u64)) {
|
2021-02-26 23:15:24 +00:00
|
|
|
// If a buff is recently applied from an aura, do not tick duration
|
2021-02-26 22:35:49 +00:00
|
|
|
if buff
|
|
|
|
.cat_ids
|
|
|
|
.iter()
|
|
|
|
.any(|cat_id| matches!(cat_id, BuffCategory::FromAura(true)))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2021-02-20 20:37:46 +00:00
|
|
|
if let Some(remaining_time) = &mut buff.time {
|
|
|
|
if let Some(new_duration) = remaining_time.checked_sub(Duration::from_secs_f32(dt)) {
|
|
|
|
// The buff still continues.
|
|
|
|
*remaining_time = new_duration;
|
|
|
|
} else {
|
|
|
|
// checked_sub returns None when remaining time
|
|
|
|
// went below 0, so set to 0
|
|
|
|
*remaining_time = Duration::default();
|
|
|
|
// The buff has expired.
|
|
|
|
// Remove it.
|
|
|
|
expire_buff(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|