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.

This commit is contained in:
Sam 2024-04-14 12:46:53 -04:00
parent aeb887963e
commit b6fbcbb204
23 changed files with 101 additions and 55 deletions

View File

@ -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,
)

View File

@ -13,6 +13,7 @@ BasicMelee(
),
range: 3,
angle: 360,
multi_target: Some(Normal),
simultaneous_hits: 2,
),
ori_modifier: 0.2,

View File

@ -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,

View File

@ -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,
)

View File

@ -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,
))),
),

View File

@ -13,6 +13,7 @@ BasicMelee(
),
range: 3,
angle: 360,
multi_target: Some(Normal),
),
ori_modifier: 0.2,
)

View File

@ -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,

View File

@ -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,
),

View File

@ -17,6 +17,6 @@ Shockwave(
ori_rate: 0.0,
timing: PostAction,
emit_outcome: false,
minimum_combo: 20,
minimum_combo: Some(20),
combo_consumption: Cost,
)

View File

@ -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,

View File

@ -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: (

View File

@ -5,7 +5,7 @@ FinisherMelee(
recover_duration: 0.7,
melee_constructor: (
kind: Bash(
damage: 100,
damage: 80,
poise: 100,
knockback: 0,
energy_regen: 0,

View File

@ -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,
)

View File

@ -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,

View File

@ -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.

View File

@ -1169,8 +1169,13 @@ impl Damage {
} else {
0.0
};
// 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(
self,

View File

@ -942,8 +942,7 @@ pub enum CharacterAbility {
damage_effect: Option<CombatEffect>,
timing: shockwave::Timing,
emit_outcome: bool,
#[serde(default)]
minimum_combo: u32,
minimum_combo: Option<u32>,
#[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 { .. }

View File

@ -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<Secs>,
}
pub struct EventBus<E> {

View File

@ -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<u32>,
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),

View File

@ -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(),

View File

@ -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,

View File

@ -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();
}

View File

@ -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) => {
if let Some(mut auras) = auras.get_mut(ev.entity) {
auras.insert(new_aura);
}
},
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) => {
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) => {
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);
}
}
},
}
},
}
}
}