From b6fbcbb204c234e62936f965ff447064170a88a5 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 14 Apr 2024 12:46:53 -0400 Subject: [PATCH] Fixed bugs with negative DR buffs bypassing admin tabard, auras only being cleared if entity had entered_auras component, and shockwaves with 0 combo cost resetting combo. Other balance feedback. --- assets/common/abilities/axe/defiance.ron | 4 +-- .../abilities/hammer/dual_heavy_whorl.ron | 1 + .../abilities/hammer/dual_intercept.ron | 2 +- .../common/abilities/hammer/dual_upheaval.ron | 9 +++++- .../common/abilities/hammer/earthshaker.ron | 4 +-- .../common/abilities/hammer/heavy_whorl.ron | 1 + assets/common/abilities/hammer/intercept.ron | 2 +- .../common/abilities/hammer/iron_tempest.ron | 4 +-- .../common/abilities/hammer/seismic_shock.ron | 2 +- .../common/abilities/hammer/spine_cracker.ron | 4 +-- assets/common/abilities/hammer/tenacity.ron | 4 +-- .../common/abilities/hammer/thunderclap.ron | 2 +- assets/common/abilities/hammer/upheaval.ron | 9 +++++- .../common/abilities/hammer/wide_wallop.ron | 6 ++-- assets/voxygen/i18n/en/hud/ability.ftl | 2 +- common/src/combat.rs | 7 +++- common/src/comp/ability.rs | 19 ++++++----- common/src/event.rs | 2 ++ common/src/states/shockwave.rs | 12 +++---- common/src/states/static_aura.rs | 1 + server/agent/src/data.rs | 2 +- server/src/events/entity_creation.rs | 25 ++++++++++++--- server/src/events/entity_manipulation.rs | 32 +++++++++++-------- 23 files changed, 101 insertions(+), 55 deletions(-) diff --git a/assets/common/abilities/axe/defiance.ron b/assets/common/abilities/axe/defiance.ron index 246d138950..ad5fc6d654 100644 --- a/assets/common/abilities/axe/defiance.ron +++ b/assets/common/abilities/axe/defiance.ron @@ -1,10 +1,10 @@ SelfBuff( buildup_duration: 0.1, - cast_duration: 2.0, + cast_duration: 1.0, recover_duration: 0.1, buff_kind: Defiance, buff_strength: 1.0, - buff_duration: Some(5.0), + buff_duration: Some(8.0), energy_cost: 20, enforced_limit: false, ) diff --git a/assets/common/abilities/hammer/dual_heavy_whorl.ron b/assets/common/abilities/hammer/dual_heavy_whorl.ron index 67aae07670..94199a8af3 100644 --- a/assets/common/abilities/hammer/dual_heavy_whorl.ron +++ b/assets/common/abilities/hammer/dual_heavy_whorl.ron @@ -13,6 +13,7 @@ BasicMelee( ), range: 3, angle: 360, + multi_target: Some(Normal), simultaneous_hits: 2, ), ori_modifier: 0.2, diff --git a/assets/common/abilities/hammer/dual_intercept.ron b/assets/common/abilities/hammer/dual_intercept.ron index f116cf39ca..0ceb572415 100644 --- a/assets/common/abilities/hammer/dual_intercept.ron +++ b/assets/common/abilities/hammer/dual_intercept.ron @@ -2,7 +2,7 @@ DashMelee( energy_cost: 15, energy_drain: 0, forward_speed: 2.5, - buildup_duration: 0.1, + buildup_duration: 0.2, charge_duration: 1.5, swing_duration: 0.1, recover_duration: 0.3, diff --git a/assets/common/abilities/hammer/dual_upheaval.ron b/assets/common/abilities/hammer/dual_upheaval.ron index a873225ae6..d6145fe4de 100644 --- a/assets/common/abilities/hammer/dual_upheaval.ron +++ b/assets/common/abilities/hammer/dual_upheaval.ron @@ -8,7 +8,7 @@ BasicMelee( kind: Bash( damage: 15, poise: 15, - knockback: 30, + knockback: 0, energy_regen: 0, ), range: 3, @@ -20,6 +20,13 @@ BasicMelee( strength: Value(0.5), chance: 1.0, ))), + attack_effect: Some(( + Knockback(( + direction: Up, + strength: 20, + )), + AnyDamage, + )), ), ori_modifier: 0.2, ) diff --git a/assets/common/abilities/hammer/earthshaker.ron b/assets/common/abilities/hammer/earthshaker.ron index 09f19f8920..a69777a09e 100644 --- a/assets/common/abilities/hammer/earthshaker.ron +++ b/assets/common/abilities/hammer/earthshaker.ron @@ -15,8 +15,8 @@ FinisherMelee( multi_target: Some(Normal), damage_effect: Some(Buff(( kind: Winded, - dur_secs: 5.0, - strength: Value(2.0), + dur_secs: 15.0, + strength: Value(5.0), chance: 1.0, ))), ), diff --git a/assets/common/abilities/hammer/heavy_whorl.ron b/assets/common/abilities/hammer/heavy_whorl.ron index cba4f07302..18ab2e3bb9 100644 --- a/assets/common/abilities/hammer/heavy_whorl.ron +++ b/assets/common/abilities/hammer/heavy_whorl.ron @@ -13,6 +13,7 @@ BasicMelee( ), range: 3, angle: 360, + multi_target: Some(Normal), ), ori_modifier: 0.2, ) diff --git a/assets/common/abilities/hammer/intercept.ron b/assets/common/abilities/hammer/intercept.ron index d73b1e6447..1cd275e17e 100644 --- a/assets/common/abilities/hammer/intercept.ron +++ b/assets/common/abilities/hammer/intercept.ron @@ -2,7 +2,7 @@ DashMelee( energy_cost: 15, energy_drain: 0, forward_speed: 2.5, - buildup_duration: 0.1, + buildup_duration: 0.2, charge_duration: 1.5, swing_duration: 0.1, recover_duration: 0.3, diff --git a/assets/common/abilities/hammer/iron_tempest.ron b/assets/common/abilities/hammer/iron_tempest.ron index 3aca3f1ef5..97d74ab114 100644 --- a/assets/common/abilities/hammer/iron_tempest.ron +++ b/assets/common/abilities/hammer/iron_tempest.ron @@ -4,8 +4,8 @@ RapidMelee( recover_duration: 0.3, melee_constructor: ( kind: Bash( - damage: 12, - poise: 15, + damage: 8, + poise: 10, knockback: 3, energy_regen: 0, ), diff --git a/assets/common/abilities/hammer/seismic_shock.ron b/assets/common/abilities/hammer/seismic_shock.ron index 9dc3155cc4..d453a46cb6 100644 --- a/assets/common/abilities/hammer/seismic_shock.ron +++ b/assets/common/abilities/hammer/seismic_shock.ron @@ -17,6 +17,6 @@ Shockwave( ori_rate: 0.0, timing: PostAction, emit_outcome: false, - minimum_combo: 20, + minimum_combo: Some(20), combo_consumption: Cost, ) \ No newline at end of file diff --git a/assets/common/abilities/hammer/spine_cracker.ron b/assets/common/abilities/hammer/spine_cracker.ron index 329ee0e08e..2ebbbbe66b 100644 --- a/assets/common/abilities/hammer/spine_cracker.ron +++ b/assets/common/abilities/hammer/spine_cracker.ron @@ -5,7 +5,7 @@ FinisherMelee( recover_duration: 0.3, melee_constructor: ( kind: Bash( - damage: 20, + damage: 25, poise: 0, knockback: 0, energy_regen: 0, @@ -13,7 +13,7 @@ FinisherMelee( range: 4.0, angle: 15.0, attack_effect: Some((Poise(50), BehindTarget)), - precision_flank_multipliers: (front: 1.0, side: 1.0, back: 2.0), + precision_flank_multipliers: (front: 1.0, side: 1.0, back: 3.0), ), minimum_combo: 10, combo_consumption: Cost, diff --git a/assets/common/abilities/hammer/tenacity.ron b/assets/common/abilities/hammer/tenacity.ron index 41beb36ec7..9c73a51d65 100644 --- a/assets/common/abilities/hammer/tenacity.ron +++ b/assets/common/abilities/hammer/tenacity.ron @@ -1,10 +1,10 @@ SelfBuff( buildup_duration: 0.1, - cast_duration: 2.0, + cast_duration: 1.0, recover_duration: 0.1, buff_kind: Tenacity, buff_strength: 1.0, - buff_duration: Some(5.0), + buff_duration: Some(8.0), energy_cost: 20, enforced_limit: false, meta: ( diff --git a/assets/common/abilities/hammer/thunderclap.ron b/assets/common/abilities/hammer/thunderclap.ron index 47a7849f78..3c7e7dbd66 100644 --- a/assets/common/abilities/hammer/thunderclap.ron +++ b/assets/common/abilities/hammer/thunderclap.ron @@ -5,7 +5,7 @@ FinisherMelee( recover_duration: 0.7, melee_constructor: ( kind: Bash( - damage: 100, + damage: 80, poise: 100, knockback: 0, energy_regen: 0, diff --git a/assets/common/abilities/hammer/upheaval.ron b/assets/common/abilities/hammer/upheaval.ron index 635ce3ebb2..54d2034af9 100644 --- a/assets/common/abilities/hammer/upheaval.ron +++ b/assets/common/abilities/hammer/upheaval.ron @@ -8,7 +8,7 @@ BasicMelee( kind: Bash( damage: 20, poise: 20, - knockback: 40, + knockback: 0, energy_regen: 0, ), range: 3, @@ -19,6 +19,13 @@ BasicMelee( strength: Value(0.5), chance: 1.0, ))), + attack_effect: Some(( + Knockback(( + direction: Up, + strength: 30, + )), + AnyDamage, + )), ), ori_modifier: 0.2, ) diff --git a/assets/common/abilities/hammer/wide_wallop.ron b/assets/common/abilities/hammer/wide_wallop.ron index 74917486c6..d415fdb6bb 100644 --- a/assets/common/abilities/hammer/wide_wallop.ron +++ b/assets/common/abilities/hammer/wide_wallop.ron @@ -10,15 +10,15 @@ ChargedMelee( ), scaled: Some(( kind: Bash( - damage: 20, - poise: 30, + damage: 40, + poise: 100, knockback: 20, energy_regen: 30, ))), range: 4.5, angle: 15.0, ), - charge_duration: 0.6, + charge_duration: 1.4, swing_duration: 0.2, hit_timing: 0.5, recover_duration: 0.5, diff --git a/assets/voxygen/i18n/en/hud/ability.ftl b/assets/voxygen/i18n/en/hud/ability.ftl index 694fa6a3d6..94605a22c2 100644 --- a/assets/voxygen/i18n/en/hud/ability.ftl +++ b/assets/voxygen/i18n/en/hud/ability.ftl @@ -391,7 +391,7 @@ common-abilities-hammer-tremor = Tremor Strike the earth with enough force that the ground beneath your foes trembles. common-abilities-hammer-vigorous_bash = Vigorous Bash .desc = - Use the head of your hammer to quickly strike your foes. + Use the head of your hammer to quickly strike your foes, giving a surge of adrenaline if the target is off balance. common-abilities-hammer-heavy_whorl = Heavy Whorl .desc = You strike all foes surrounding you with your hammer. diff --git a/common/src/combat.rs b/common/src/combat.rs index 0604981326..19e32b93bc 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -1169,7 +1169,12 @@ impl Damage { } else { 0.0 }; - 1.0 - (1.0 - inventory_dr) * (1.0 - stats_dr) + // Return 100% if either DR is at 100% (admin tabard or safezone buff) + if protection.is_none() || stats_dr >= 1.0 { + 1.0 + } else { + 1.0 - (1.0 - inventory_dr) * (1.0 - stats_dr) + } } pub fn calculate_health_change( diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 4fd732cd73..6d9cc5dcbb 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -942,8 +942,7 @@ pub enum CharacterAbility { damage_effect: Option, timing: shockwave::Timing, emit_outcome: bool, - #[serde(default)] - minimum_combo: u32, + minimum_combo: Option, #[serde(default)] combo_consumption: ComboConsumption, #[serde(default)] @@ -1220,13 +1219,17 @@ impl CharacterAbility { energy_cost, combo_cost: minimum_combo, .. - } - | CharacterAbility::Shockwave { + } => { + data.combo.map_or(false, |c| c.counter() >= *minimum_combo) + && update.energy.try_change_by(-*energy_cost).is_ok() + }, + CharacterAbility::Shockwave { energy_cost, minimum_combo, .. } => { - data.combo.map_or(false, |c| c.counter() >= *minimum_combo) + data.combo + .map_or(false, |c| c.counter() >= minimum_combo.unwrap_or(0)) && update.energy.try_change_by(-*energy_cost).is_ok() }, CharacterAbility::DiveMelee { @@ -1902,11 +1905,11 @@ impl CharacterAbility { } | SelfBuff { combo_cost: combo, .. - } - | Shockwave { + } => *combo, + Shockwave { minimum_combo: combo, .. - } => *combo, + } => combo.unwrap_or(0), BasicMelee { .. } | BasicRanged { .. } | RepeaterRanged { .. } diff --git a/common/src/event.rs b/common/src/event.rs index e056e378cb..67d5f22d67 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -12,6 +12,7 @@ use crate::{ lottery::LootSpec, mounting::VolumePos, outcome::Outcome, + resources::Secs, rtsim::RtSimEntity, terrain::SpriteKind, trade::{TradeAction, TradeId}, @@ -437,6 +438,7 @@ pub struct CreateAuraEntityEvent { pub auras: comp::Auras, pub pos: Pos, pub creator_uid: Uid, + pub duration: Option, } pub struct EventBus { diff --git a/common/src/states/shockwave.rs b/common/src/states/shockwave.rs index 7a9b2cd3d2..06c34939f5 100644 --- a/common/src/states/shockwave.rs +++ b/common/src/states/shockwave.rs @@ -59,7 +59,7 @@ pub struct StaticData { pub ori_rate: f32, /// Timing of shockwave pub timing: Timing, - pub minimum_combo: u32, + pub minimum_combo: Option, pub combo_on_use: u32, pub combo_consumption: ComboConsumption, } @@ -197,11 +197,11 @@ impl CharacterBehavior for Data { impl Data { fn attack(&self, data: &JoinData, output_events: &mut OutputEvents) { - self.static_data.combo_consumption.consume( - data, - output_events, - self.static_data.minimum_combo, - ); + if let Some(min_combo) = self.static_data.minimum_combo { + self.static_data + .combo_consumption + .consume(data, output_events, min_combo); + } let poise = AttackEffect::new( Some(GroupTarget::OutOfGroup), diff --git a/common/src/states/static_aura.rs b/common/src/states/static_aura.rs index 6e829dc86d..37d1b31d6b 100644 --- a/common/src/states/static_aura.rs +++ b/common/src/states/static_aura.rs @@ -126,6 +126,7 @@ impl CharacterBehavior for Data { auras: Auras::new(auras), pos: *data.pos, creator_uid: *data.uid, + duration: self.static_data.aura_duration, }); update.character = CharacterState::StaticAura(Data { static_data: self.static_data.clone(), diff --git a/server/agent/src/data.rs b/server/agent/src/data.rs index f020ca115b..2af684123b 100755 --- a/server/agent/src/data.rs +++ b/server/agent/src/data.rs @@ -717,7 +717,7 @@ impl AbilityData { energy: *energy_cost, angle: *shockwave_angle, range: *shockwave_speed * *shockwave_duration, - combo: *minimum_combo, + combo: minimum_combo.unwrap_or(0), }, StaticAura { energy_cost, .. } => Self::StaticAura { energy: *energy_cost, diff --git a/server/src/events/entity_creation.rs b/server/src/events/entity_creation.rs index 3b72a241a1..26cda7d444 100644 --- a/server/src/events/entity_creation.rs +++ b/server/src/events/entity_creation.rs @@ -8,8 +8,8 @@ use common::{ aura::{Aura, AuraKind, AuraTarget}, buff::{BuffCategory, BuffData, BuffKind, BuffSource}, ship::figuredata::VOXEL_COLLIDER_MANIFEST, - Alignment, BehaviorCapability, ItemDrops, LightEmitter, Ori, Pos, TradingBehavior, Vel, - WaypointArea, + Alignment, BehaviorCapability, ItemDrops, LightEmitter, Ori, Pos, Projectile, + TradingBehavior, Vel, WaypointArea, }, event::{ CreateAuraEntityEvent, CreateItemDropEvent, CreateNpcEvent, CreateObjectEvent, @@ -25,6 +25,7 @@ use common::{ }; use common_net::{msg::ServerGeneral, sync::WorldSyncExt}; use specs::{Builder, Entity as EcsEntity, WorldExt}; +use std::time::Duration; use vek::{Rgb, Vec3}; use super::group_manip::update_map_markers; @@ -491,7 +492,7 @@ pub fn handle_create_object( } pub fn handle_create_aura_entity(server: &mut Server, ev: CreateAuraEntityEvent) { - server + let mut entity = server .state .ecs_mut() .create_entity_synced() @@ -499,6 +500,20 @@ pub fn handle_create_aura_entity(server: &mut Server, ev: CreateAuraEntityEvent) .with(comp::Vel(Vec3::zero())) .with(comp::Ori::default()) .with(ev.auras) - .with(comp::Alignment::Owned(ev.creator_uid)) - .build(); + .with(comp::Alignment::Owned(ev.creator_uid)); + + // If a duration is specified, create a projectile component for the entity + if let Some(dur) = ev.duration { + let projectile = Projectile { + hit_solid: Vec::new(), + hit_entity: Vec::new(), + time_left: Duration::from_secs_f64(dur.0), + owner: Some(ev.creator_uid), + ignore_group: true, + is_sticky: false, + is_point: false, + }; + entity = entity.with(projectile); + } + entity.build(); } diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index a5df997311..ad66f2fa23 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -1570,20 +1570,22 @@ impl ServerEvent for AuraEvent { (mut auras, mut entered_auras): Self::SystemData<'_>, ) { for ev in events { - if let (Some(mut auras), Some(mut entered_auras)) = - (auras.get_mut(ev.entity), entered_auras.get_mut(ev.entity)) - { - use aura::AuraChange; - match ev.aura_change { - AuraChange::Add(new_aura) => { + use aura::AuraChange; + match ev.aura_change { + AuraChange::Add(new_aura) => { + if let Some(mut auras) = auras.get_mut(ev.entity) { auras.insert(new_aura); - }, - AuraChange::RemoveByKey(keys) => { + } + }, + AuraChange::RemoveByKey(keys) => { + if let Some(mut auras) = auras.get_mut(ev.entity) { for key in keys { auras.remove(key); } - }, - AuraChange::EnterAura(uid, key, variant) => { + } + }, + AuraChange::EnterAura(uid, key, variant) => { + if let Some(mut entered_auras) = entered_auras.get_mut(ev.entity) { entered_auras .auras .entry(variant) @@ -1591,8 +1593,10 @@ impl ServerEvent for AuraEvent { entered_auras.insert((uid, key)); }) .or_insert_with(|| <_ as Into<_>>::into([(uid, key)])); - }, - AuraChange::ExitAura(uid, key, variant) => { + } + }, + AuraChange::ExitAura(uid, key, variant) => { + if let Some(mut entered_auras) = entered_auras.get_mut(ev.entity) { if let Some(entered_auras_variant) = entered_auras.auras.get_mut(&variant) { entered_auras_variant.remove(&(uid, key)); @@ -1600,8 +1604,8 @@ impl ServerEvent for AuraEvent { entered_auras.auras.remove(&variant); } } - }, - } + } + }, } } }