Adds poisoned debuff (energy change over time)

This commit is contained in:
Snowram 2021-09-03 01:57:17 +02:00
parent 2871fa83bc
commit ae71f2e4f0
11 changed files with 103 additions and 5 deletions

BIN
assets/voxygen/element/de_buffs/debuff_poisoned_0.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -3691,6 +3691,16 @@ Bomb: Some((
lod_axes: (0.5, 0.5, 0.5),
),
],
wind_sway: 0.6,
)),
EnsnaringWeb: Some((
variations: [
(
model: "voxygen.voxel.sprite.misc.ensnaring_web",
offset: (-5.0, -6.5, 0.0),
lod_axes: (0.0, 0.0, 0.0),
),
],
wind_sway: 0.0,
)),
)

View File

@ -206,6 +206,7 @@ lazy_static! {
BuffKind::Frozen => "frozen",
BuffKind::Wet => "wet",
BuffKind::Ensnared => "ensnared",
BuffKind::Poisoned => "poisoned",
};
let mut buff_parser = HashMap::new();
BuffKind::iter().for_each(|kind| {buff_parser.insert(string_from_buff(kind).to_string(), kind);});

View File

@ -74,6 +74,9 @@ pub enum BuffKind {
/// Strength scales the movement speed debuff non-linearly. 0.5 is 50%
/// speed, 1.0 is 33% speed.
Ensnared,
/// Does damage to a creature over time
/// Strength should be 10x the DPS of the debuff
Poisoned,
}
#[cfg(not(target_arch = "wasm32"))]
@ -96,7 +99,8 @@ impl BuffKind {
| BuffKind::Crippled
| BuffKind::Frozen
| BuffKind::Wet
| BuffKind::Ensnared => false,
| BuffKind::Ensnared
| BuffKind::Poisoned => false,
}
}
@ -144,6 +148,12 @@ pub enum BuffEffect {
accumulated: f32,
kind: ModifierKind,
},
/// Periodically consume entity energy
EnergyChangeOverTime {
rate: f32,
accumulated: f32,
kind: ModifierKind,
},
/// Changes maximum health by a certain amount
MaxHealthModifier { value: f32, kind: ModifierKind },
/// Changes maximum energy by a certain amount
@ -292,6 +302,14 @@ impl Buff {
}],
data.duration,
),
BuffKind::Poisoned => (
vec![BuffEffect::EnergyChangeOverTime {
rate: -data.strength,
accumulated: 0.0,
kind: ModifierKind::Additive,
}],
data.duration,
),
BuffKind::Crippled => (
vec![
BuffEffect::MovementSpeed(1.0 - nn_scaling(data.strength)),

View File

@ -190,6 +190,7 @@ make_case_elim!(
Bomb = 0xA3,
ChristmasOrnament = 0xA4,
ChristmasWreath = 0xA5,
EnsnaringWeb = 0xA6,
}
);
@ -278,7 +279,9 @@ impl SpriteKind {
| SpriteKind::Tin
| SpriteKind::Silver
| SpriteKind::Gold => 0.6,
SpriteKind::EnsnaringVines | SpriteKind::CavernLillypadBlue => 0.1,
SpriteKind::EnsnaringVines
| SpriteKind::CavernLillypadBlue
| SpriteKind::EnsnaringWeb => 0.1,
SpriteKind::LillyPads => 0.1,
_ => return None,
})

View File

@ -92,7 +92,7 @@ impl<'a> System<'a> for Sys {
if let Some(physics_state) = physics_state {
if matches!(
physics_state.on_ground.and_then(|b| b.get_sprite()),
Some(SpriteKind::EnsnaringVines)
Some(SpriteKind::EnsnaringVines) | Some(SpriteKind::EnsnaringWeb)
) {
// If on ensnaring vines, apply ensnared debuff
server_emitter.emit(ServerEvent::Buff {
@ -237,6 +237,30 @@ impl<'a> System<'a> for Sys {
*accumulated = 0.0;
};
},
BuffEffect::EnergyChangeOverTime {
rate,
accumulated,
kind,
} => {
*accumulated += *rate * dt;
// Apply energy change only once per second, per energy, or
// when a buff is removed
if accumulated.abs() > rate.abs().min(10.0)
|| buff.time.map_or(false, |dur| dur == Duration::default())
{
let amount = match *kind {
ModifierKind::Additive => *accumulated,
ModifierKind::Fractional => {
health.maximum() as f32 * *accumulated
},
};
server_emitter.emit(ServerEvent::EnergyChange {
entity,
change: amount,
});
*accumulated = 0.0;
};
},
BuffEffect::MaxHealthModifier { value, kind } => match kind {
ModifierKind::Additive => {
stat.max_health_modifiers.add_mod += *value;

View File

@ -1681,6 +1681,38 @@ impl<'a> AgentData<'a> {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None);
}
fn handle_arthropod_attack(
&self,
agent: &mut Agent,
controller: &mut Controller,
attack_data: &AttackData,
tgt_data: &TargetData,
read_data: &ReadData,
) {
if attack_data.angle < 70.0
&& attack_data.dist_sqrd < (1.3 * attack_data.min_attack_dist).powi(2)
{
controller.inputs.move_dir = Vec2::zero();
if agent.action_state.timer > 5.0 {
agent.action_state.timer = 0.0;
} else if agent.action_state.timer > 2.0 {
controller
.actions
.push(ControlAction::basic_input(InputKind::Secondary));
agent.action_state.timer += read_data.dt.0;
} else {
controller
.actions
.push(ControlAction::basic_input(InputKind::Primary));
agent.action_state.timer += read_data.dt.0;
}
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None);
} else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
}
}
pub fn handle_minotaur_attack(
&self,
agent: &mut Agent,

View File

@ -768,6 +768,7 @@ fn insert_killing_buff(buff: BuffKind, localized_strings: &Localization, templat
BuffKind::Cursed => localized_strings.get("hud.outcome.curse"),
BuffKind::Crippled => localized_strings.get("hud.outcome.crippled"),
BuffKind::Frozen => localized_strings.get("hud.outcome.frozen"),
BuffKind::Poisoned => localized_strings.get("hud.outcome.poisoned"),
BuffKind::Regeneration
| BuffKind::Saturation
| BuffKind::Potion

View File

@ -618,6 +618,7 @@ image_ids! {
debuff_frozen_0: "voxygen.element.de_buffs.debuff_frozen_0",
debuff_wet_0: "voxygen.element.de_buffs.debuff_wet_0",
debuff_ensnared_0: "voxygen.element.de_buffs.debuff_ensnared_0",
debuff_poisoned_0: "voxygen.element.de_buffs.debuff_poisoned_0",
// Animation Frames
// Buff Frame

View File

@ -4257,6 +4257,7 @@ pub fn get_buff_image(buff: BuffKind, imgs: &Imgs) -> conrod_core::image::Id {
BuffKind::Frozen { .. } => imgs.debuff_frozen_0,
BuffKind::Wet { .. } => imgs.debuff_wet_0,
BuffKind::Ensnared { .. } => imgs.debuff_ensnared_0,
BuffKind::Poisoned { .. } => imgs.debuff_poisoned_0,
}
}
@ -4280,6 +4281,7 @@ pub fn get_buff_title(buff: BuffKind, localized_strings: &Localization) -> &str
BuffKind::Frozen { .. } => localized_strings.get("buff.title.frozen"),
BuffKind::Wet { .. } => localized_strings.get("buff.title.wet"),
BuffKind::Ensnared { .. } => localized_strings.get("buff.title.ensnared"),
BuffKind::Poisoned { .. } => localized_strings.get("buff.title.poisoned"),
}
}
@ -4315,6 +4317,7 @@ pub fn get_buff_desc(buff: BuffKind, data: BuffData, localized_strings: &Localiz
BuffKind::Frozen { .. } => Cow::Borrowed(localized_strings.get("buff.desc.frozen")),
BuffKind::Wet { .. } => Cow::Borrowed(localized_strings.get("buff.desc.wet")),
BuffKind::Ensnared { .. } => Cow::Borrowed(localized_strings.get("buff.desc.ensnared")),
BuffKind::Poisoned { .. } => Cow::Borrowed(localized_strings.get("buff.desc.poisoned")),
}
}

View File

@ -172,7 +172,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> Vec<String> {
| BuffKind::Frenzied
| BuffKind::Frozen
| BuffKind::Wet
| BuffKind::Ensnared => "".to_owned(),
| BuffKind::Ensnared
| BuffKind::Poisoned => "".to_owned(),
};
write!(&mut description, "{}", buff_desc).unwrap();
@ -197,7 +198,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> Vec<String> {
| BuffKind::Frenzied
| BuffKind::Frozen
| BuffKind::Wet
| BuffKind::Ensnared => "".to_owned(),
| BuffKind::Ensnared
| BuffKind::Poisoned => "".to_owned(),
}
} else if let BuffKind::Saturation | BuffKind::Regeneration = buff.kind {
i18n.get("buff.text.every_second").to_string()