From ae71f2e4f0444e59548efcb99e72098c59b4dc1b Mon Sep 17 00:00:00 2001 From: Snowram Date: Fri, 3 Sep 2021 01:57:17 +0200 Subject: [PATCH] Adds poisoned debuff (energy change over time) --- .../element/de_buffs/debuff_poisoned_0.png | 3 ++ assets/voxygen/voxel/sprite_manifest.ron | 10 ++++++ common/src/cmd.rs | 1 + common/src/comp/buff.rs | 20 +++++++++++- common/src/terrain/sprite.rs | 5 ++- common/systems/src/buff.rs | 26 ++++++++++++++- server/src/sys/agent/attack.rs | 32 +++++++++++++++++++ voxygen/src/hud/chat.rs | 1 + voxygen/src/hud/img_ids.rs | 1 + voxygen/src/hud/mod.rs | 3 ++ voxygen/src/hud/util.rs | 6 ++-- 11 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 assets/voxygen/element/de_buffs/debuff_poisoned_0.png diff --git a/assets/voxygen/element/de_buffs/debuff_poisoned_0.png b/assets/voxygen/element/de_buffs/debuff_poisoned_0.png new file mode 100644 index 0000000000..6ddc994466 --- /dev/null +++ b/assets/voxygen/element/de_buffs/debuff_poisoned_0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98028353fc4e1b2c354f2d5195d694480c8feac7b843867143b0bf7366143b98 +size 158 diff --git a/assets/voxygen/voxel/sprite_manifest.ron b/assets/voxygen/voxel/sprite_manifest.ron index 25aa9b6ff0..6abd0b08e3 100644 --- a/assets/voxygen/voxel/sprite_manifest.ron +++ b/assets/voxygen/voxel/sprite_manifest.ron @@ -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, )), ) diff --git a/common/src/cmd.rs b/common/src/cmd.rs index 363aee8df0..8e76d5515e 100644 --- a/common/src/cmd.rs +++ b/common/src/cmd.rs @@ -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);}); diff --git a/common/src/comp/buff.rs b/common/src/comp/buff.rs index b224710692..474c8cd66f 100644 --- a/common/src/comp/buff.rs +++ b/common/src/comp/buff.rs @@ -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)), diff --git a/common/src/terrain/sprite.rs b/common/src/terrain/sprite.rs index e6fdd6c28a..dbd42ceccc 100644 --- a/common/src/terrain/sprite.rs +++ b/common/src/terrain/sprite.rs @@ -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, }) diff --git a/common/systems/src/buff.rs b/common/systems/src/buff.rs index 4bd3516a7b..8272cb4f74 100644 --- a/common/systems/src/buff.rs +++ b/common/systems/src/buff.rs @@ -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; diff --git a/server/src/sys/agent/attack.rs b/server/src/sys/agent/attack.rs index 936b467a17..c5e6c475f8 100644 --- a/server/src/sys/agent/attack.rs +++ b/server/src/sys/agent/attack.rs @@ -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, diff --git a/voxygen/src/hud/chat.rs b/voxygen/src/hud/chat.rs index c4d8f176df..be9e25ef1c 100644 --- a/voxygen/src/hud/chat.rs +++ b/voxygen/src/hud/chat.rs @@ -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 diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 0d795e563f..e214322c07 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -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 diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 175bcd88e0..6322d7c486 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -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")), } } diff --git a/voxygen/src/hud/util.rs b/voxygen/src/hud/util.rs index aa38d674c3..a2d2bef185 100644 --- a/voxygen/src/hud/util.rs +++ b/voxygen/src/hud/util.rs @@ -172,7 +172,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> Vec { | 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 { | 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()