Effect power now affects more than just poise

This commit is contained in:
Sam 2023-02-13 21:43:52 -05:00
parent 1a58b7a8d4
commit 610d47f787
23 changed files with 166 additions and 117 deletions

View File

@ -90,7 +90,7 @@ common-rand_name = Random name
common-stats-combat_rating = CR common-stats-combat_rating = CR
common-stats-power = Power common-stats-power = Power
common-stats-speed = Speed common-stats-speed = Speed
common-stats-poise = Poise common-stats-effect-power = Effect Power
common-stats-range = Range common-stats-range = Range
common-stats-energy_efficiency = Energy Efficiency common-stats-energy_efficiency = Energy Efficiency
common-stats-buff_strength = Buff/Debuff Strength common-stats-buff_strength = Buff/Debuff Strength

View File

@ -4,7 +4,11 @@ use crate::{
comp::{ comp::{
ability::Capability, ability::Capability,
inventory::{ inventory::{
item::{armor::Protection, tool::ToolKind, ItemDesc, ItemKind, MaterialStatManifest}, item::{
armor::Protection,
tool::{self, ToolKind},
ItemDesc, ItemKind, MaterialStatManifest,
},
slot::EquipSlot, slot::EquipSlot,
}, },
skillset::SkillGroupKind, skillset::SkillGroupKind,
@ -28,7 +32,7 @@ use crate::{comp::Group, resources::Time};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use specs::{saveload::MarkerAllocator, Entity as EcsEntity, ReadStorage}; use specs::{saveload::MarkerAllocator, Entity as EcsEntity, ReadStorage};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use std::ops::MulAssign; use std::ops::{Mul, MulAssign};
#[cfg(not(target_arch = "wasm32"))] use vek::*; #[cfg(not(target_arch = "wasm32"))] use vek::*;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -832,6 +836,46 @@ pub enum CombatEffect {
StunnedVulnerable(f32), StunnedVulnerable(f32),
} }
impl CombatEffect {
pub fn adjusted_by_stats(self, stats: tool::Stats) -> Self {
match self {
CombatEffect::Heal(h) => CombatEffect::Heal(h * stats.effect_power),
CombatEffect::Buff(CombatBuff {
kind,
dur_secs,
strength,
chance,
}) => CombatEffect::Buff(CombatBuff {
kind,
dur_secs,
strength: strength * stats.buff_strength,
chance,
}),
CombatEffect::Knockback(Knockback {
direction,
strength,
}) => CombatEffect::Knockback(Knockback {
direction,
strength: strength * stats.buff_strength,
}),
CombatEffect::EnergyReward(e) => CombatEffect::EnergyReward(e),
CombatEffect::Lifesteal(l) => CombatEffect::Lifesteal(l * stats.effect_power),
CombatEffect::Poise(p) => CombatEffect::Poise(p * stats.effect_power),
CombatEffect::Combo(c) => CombatEffect::Combo(c),
CombatEffect::StageVulnerable(v, s) => {
CombatEffect::StageVulnerable(v * stats.effect_power, s)
},
CombatEffect::RefreshBuff(c, b) => CombatEffect::RefreshBuff(c, b),
CombatEffect::BuffsVulnerable(v, b) => {
CombatEffect::BuffsVulnerable(v * stats.effect_power, b)
},
CombatEffect::StunnedVulnerable(v) => {
CombatEffect::StunnedVulnerable(v * stats.effect_power)
},
}
}
}
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub enum CombatRequirement { pub enum CombatRequirement {
@ -1106,11 +1150,16 @@ impl CombatBuffStrength {
} }
impl MulAssign<f32> for CombatBuffStrength { impl MulAssign<f32> for CombatBuffStrength {
fn mul_assign(&mut self, mul: f32) { fn mul_assign(&mut self, mul: f32) { *self = *self * mul; }
}
impl Mul<f32> for CombatBuffStrength {
type Output = Self;
fn mul(self, mult: f32) -> Self {
match self { match self {
Self::DamageFraction(ref mut val) | Self::Value(ref mut val) => { Self::DamageFraction(val) => Self::DamageFraction(val * mult),
*val *= mul; Self::Value(val) => Self::Value(val * mult),
},
} }
} }
} }

View File

@ -1305,15 +1305,7 @@ impl CharacterAbility {
*poise_damage *= stats.effect_power; *poise_damage *= stats.effect_power;
*shockwave_duration *= stats.range; *shockwave_duration *= stats.range;
*energy_cost /= stats.energy_efficiency; *energy_cost /= stats.energy_efficiency;
if let Some(CombatEffect::Buff(combat::CombatBuff { *damage_effect = damage_effect.map(|de| de.adjusted_by_stats(stats));
kind: _,
dur_secs: _,
strength,
chance: _,
})) = damage_effect
{
*strength *= stats.buff_strength;
}
}, },
BasicBeam { BasicBeam {
ref mut buildup_duration, ref mut buildup_duration,
@ -1338,15 +1330,7 @@ impl CharacterAbility {
// Duration modified to keep velocity constant // Duration modified to keep velocity constant
*beam_duration *= stats.range; *beam_duration *= stats.range;
*energy_drain /= stats.energy_efficiency; *energy_drain /= stats.energy_efficiency;
if let Some(CombatEffect::Buff(combat::CombatBuff { *damage_effect = damage_effect.map(|de| de.adjusted_by_stats(stats));
kind: _,
dur_secs: _,
strength,
chance: _,
})) = damage_effect
{
*strength *= stats.buff_strength;
}
}, },
BasicAura { BasicAura {
ref mut buildup_duration, ref mut buildup_duration,

View File

@ -913,6 +913,11 @@ impl CharacterState {
} else { } else {
AttackSource::AirShockwave AttackSource::AirShockwave
}), }),
CharacterState::LeapShockwave(data) => Some(if data.static_data.requires_ground {
AttackSource::GroundShockwave
} else {
AttackSource::AirShockwave
}),
CharacterState::BasicBeam(_) => Some(AttackSource::Beam), CharacterState::BasicBeam(_) => Some(AttackSource::Beam),
CharacterState::BasicAura(_) => None, CharacterState::BasicAura(_) => None,
CharacterState::Blink(_) => None, CharacterState::Blink(_) => None,
@ -926,11 +931,6 @@ impl CharacterState {
CharacterState::DiveMelee(_) => Some(AttackSource::Melee), CharacterState::DiveMelee(_) => Some(AttackSource::Melee),
CharacterState::RiposteMelee(_) => Some(AttackSource::Melee), CharacterState::RiposteMelee(_) => Some(AttackSource::Melee),
CharacterState::RapidMelee(_) => Some(AttackSource::Melee), CharacterState::RapidMelee(_) => Some(AttackSource::Melee),
CharacterState::LeapShockwave(data) => Some(if data.static_data.requires_ground {
AttackSource::GroundShockwave
} else {
AttackSource::AirShockwave
}),
} }
} }
} }

View File

@ -62,7 +62,7 @@ pub struct MeleeConstructor {
} }
impl MeleeConstructor { impl MeleeConstructor {
pub fn create_melee(self, (crit_chance, crit_mult): (f32, f32), buff_strength: f32) -> Melee { pub fn create_melee(self, (crit_chance, crit_mult): (f32, f32), tool_stats: Stats) -> Melee {
use MeleeConstructorKind::*; use MeleeConstructorKind::*;
if self.scaled.is_some() { if self.scaled.is_some() {
dev_panic!( dev_panic!(
@ -83,9 +83,10 @@ impl MeleeConstructor {
let buff = CombatEffect::Buff(CombatBuff { let buff = CombatEffect::Buff(CombatBuff {
kind: BuffKind::Bleeding, kind: BuffKind::Bleeding,
dur_secs: 10.0, dur_secs: 10.0,
strength: CombatBuffStrength::DamageFraction(0.1 * buff_strength), strength: CombatBuffStrength::DamageFraction(0.1),
chance: 0.1, chance: 0.1,
}); })
.adjusted_by_stats(tool_stats);
let mut damage = AttackDamage::new( let mut damage = AttackDamage::new(
Damage { Damage {
source: DamageSource::Melee, source: DamageSource::Melee,
@ -109,7 +110,8 @@ impl MeleeConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: knockback, strength: knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
@ -132,9 +134,10 @@ impl MeleeConstructor {
let buff = CombatEffect::Buff(CombatBuff { let buff = CombatEffect::Buff(CombatBuff {
kind: BuffKind::Bleeding, kind: BuffKind::Bleeding,
dur_secs: 5.0, dur_secs: 5.0,
strength: CombatBuffStrength::DamageFraction(0.05 * buff_strength), strength: CombatBuffStrength::DamageFraction(0.05),
chance: 0.1, chance: 0.1,
}); })
.adjusted_by_stats(tool_stats);
let mut damage = AttackDamage::new( let mut damage = AttackDamage::new(
Damage { Damage {
source: DamageSource::Melee, source: DamageSource::Melee,
@ -158,7 +161,8 @@ impl MeleeConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: knockback, strength: knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
@ -200,7 +204,8 @@ impl MeleeConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: knockback, strength: knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
@ -239,7 +244,8 @@ impl MeleeConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: pull, strength: pull,
direction: KnockbackDir::Towards, direction: KnockbackDir::Towards,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
@ -276,7 +282,8 @@ impl MeleeConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: knockback, strength: knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
@ -419,9 +426,7 @@ impl MeleeConstructor {
if let Some(ref mut scaled) = &mut self.scaled { if let Some(ref mut scaled) = &mut self.scaled {
*scaled = scaled.adjusted_by_stats(stats); *scaled = scaled.adjusted_by_stats(stats);
} }
if let Some(CombatEffect::Buff(CombatBuff { strength, .. })) = &mut self.damage_effect { self.damage_effect = self.damage_effect.map(|de| de.adjusted_by_stats(stats));
*strength *= stats.buff_strength;
}
self self
} }
} }

View File

@ -3,7 +3,10 @@ use crate::{
Attack, AttackDamage, AttackEffect, CombatBuff, CombatBuffStrength, CombatEffect, Attack, AttackDamage, AttackEffect, CombatBuff, CombatBuffStrength, CombatEffect,
CombatRequirement, Damage, DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir, CombatRequirement, Damage, DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
}, },
comp::{buff::BuffKind, item::Reagent}, comp::{
buff::BuffKind,
item::{tool, Reagent},
},
uid::Uid, uid::Uid,
Explosion, RadiusEffect, Explosion, RadiusEffect,
}; };
@ -119,7 +122,7 @@ impl ProjectileConstructor {
owner: Option<Uid>, owner: Option<Uid>,
crit_chance: f32, crit_chance: f32,
crit_mult: f32, crit_mult: f32,
buff_strength: f32, tool_stats: tool::Stats,
damage_effect: Option<CombatEffect>, damage_effect: Option<CombatEffect>,
) -> Projectile { ) -> Projectile {
let instance = rand::random(); let instance = rand::random();
@ -135,7 +138,8 @@ impl ProjectileConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: knockback, strength: knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy_regen)) let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy_regen))
@ -143,9 +147,10 @@ impl ProjectileConstructor {
let buff = CombatEffect::Buff(CombatBuff { let buff = CombatEffect::Buff(CombatBuff {
kind: BuffKind::Bleeding, kind: BuffKind::Bleeding,
dur_secs: 10.0, dur_secs: 10.0,
strength: CombatBuffStrength::DamageFraction(0.1 * buff_strength), strength: CombatBuffStrength::DamageFraction(0.1),
chance: 0.1, chance: 0.1,
}); })
.adjusted_by_stats(tool_stats);
let mut damage = AttackDamage::new( let mut damage = AttackDamage::new(
Damage { Damage {
source: DamageSource::Projectile, source: DamageSource::Projectile,
@ -187,9 +192,10 @@ impl ProjectileConstructor {
let buff = CombatEffect::Buff(CombatBuff { let buff = CombatEffect::Buff(CombatBuff {
kind: BuffKind::Burning, kind: BuffKind::Burning,
dur_secs: 5.0, dur_secs: 5.0,
strength: CombatBuffStrength::DamageFraction(0.1 * buff_strength), strength: CombatBuffStrength::DamageFraction(0.1),
chance: 0.1, chance: 0.1,
}); })
.adjusted_by_stats(tool_stats);
let damage = AttackDamage::new( let damage = AttackDamage::new(
Damage { Damage {
source: DamageSource::Explosion, source: DamageSource::Explosion,
@ -268,9 +274,10 @@ impl ProjectileConstructor {
CombatEffect::Buff(CombatBuff { CombatEffect::Buff(CombatBuff {
kind: BuffKind::Poisoned, kind: BuffKind::Poisoned,
dur_secs: 5.0, dur_secs: 5.0,
strength: CombatBuffStrength::DamageFraction(0.8 * buff_strength), strength: CombatBuffStrength::DamageFraction(0.8),
chance: 1.0, chance: 1.0,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let damage = AttackDamage::new( let damage = AttackDamage::new(
@ -359,7 +366,8 @@ impl ProjectileConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: knockback, strength: knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let damage = AttackDamage::new( let damage = AttackDamage::new(
@ -506,7 +514,8 @@ impl ProjectileConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: knockback, strength: knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let buff = AttackEffect::new( let buff = AttackEffect::new(
@ -514,9 +523,10 @@ impl ProjectileConstructor {
CombatEffect::Buff(CombatBuff { CombatEffect::Buff(CombatBuff {
kind: BuffKind::Burning, kind: BuffKind::Burning,
dur_secs: 5.0, dur_secs: 5.0,
strength: CombatBuffStrength::DamageFraction(0.2 * buff_strength), strength: CombatBuffStrength::DamageFraction(0.2),
chance: 1.0, chance: 1.0,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let damage = AttackDamage::new( let damage = AttackDamage::new(
@ -563,7 +573,8 @@ impl ProjectileConstructor {
CombatEffect::Knockback(Knockback { CombatEffect::Knockback(Knockback {
strength: knockback, strength: knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let buff = AttackEffect::new( let buff = AttackEffect::new(
@ -571,9 +582,10 @@ impl ProjectileConstructor {
CombatEffect::Buff(CombatBuff { CombatEffect::Buff(CombatBuff {
kind: BuffKind::Burning, kind: BuffKind::Burning,
dur_secs: 5.0, dur_secs: 5.0,
strength: CombatBuffStrength::DamageFraction(0.2 * buff_strength), strength: CombatBuffStrength::DamageFraction(0.2),
chance: 1.0, chance: 1.0,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let damage = AttackDamage::new( let damage = AttackDamage::new(
@ -628,9 +640,10 @@ impl ProjectileConstructor {
CombatEffect::Buff(CombatBuff { CombatEffect::Buff(CombatBuff {
kind: BuffKind::Frozen, kind: BuffKind::Frozen,
dur_secs: 5.0, dur_secs: 5.0,
strength: CombatBuffStrength::DamageFraction(0.05 * buff_strength), strength: CombatBuffStrength::DamageFraction(0.05),
chance: 1.0, chance: 1.0,
}), })
.adjusted_by_stats(tool_stats),
) )
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let damage = AttackDamage::new( let damage = AttackDamage::new(

View File

@ -75,13 +75,13 @@ impl CharacterBehavior for Data {
}); });
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
self.static_data self.static_data
.melee_constructor .melee_constructor
.create_melee(crit_data, buff_strength) .create_melee(crit_data, tool_stats)
.with_block_breaking( .with_block_breaking(
data.inputs data.inputs
.break_block_pos .break_block_pos

View File

@ -80,12 +80,12 @@ impl CharacterBehavior for Data {
// Fire // Fire
let (crit_chance, crit_mult) = let (crit_chance, crit_mult) =
get_crit_data(data, self.static_data.ability_info); get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
let projectile = self.static_data.projectile.create_projectile( let projectile = self.static_data.projectile.create_projectile(
Some(*data.uid), Some(*data.uid),
crit_chance, crit_chance,
crit_mult, crit_mult,
buff_strength, tool_stats,
self.static_data.damage_effect, self.static_data.damage_effect,
); );
// Shoots all projectiles simultaneously // Shoots all projectiles simultaneously

View File

@ -71,9 +71,9 @@ impl CharacterBehavior for Data {
} }
} else { } else {
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater data.updater
.insert(data.entity, strike.create_melee(crit_data, buff_strength)); .insert(data.entity, strike.create_melee(crit_data, tool_stats));
if let CharacterState::ChargedMelee(c) = &mut update.character { if let CharacterState::ChargedMelee(c) = &mut update.character {
c.stage_section = StageSection::Charge; c.stage_section = StageSection::Charge;
@ -141,14 +141,14 @@ impl CharacterBehavior for Data {
}); });
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
self.static_data self.static_data
.melee_constructor .melee_constructor
.handle_scaling(self.charge_amount) .handle_scaling(self.charge_amount)
.create_melee(crit_data, buff_strength), .create_melee(crit_data, tool_stats),
); );
if let Some(FrontendSpecifier::GroundCleave) = self.static_data.specifier { if let Some(FrontendSpecifier::GroundCleave) = self.static_data.specifier {

View File

@ -112,7 +112,7 @@ impl CharacterBehavior for Data {
// Fire // Fire
let (crit_chance, crit_mult) = let (crit_chance, crit_mult) =
get_crit_data(data, self.static_data.ability_info); get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
// Gets offsets // Gets offsets
let body_offsets = data.body.projectile_offsets(update.ori.look_vec()); let body_offsets = data.body.projectile_offsets(update.ori.look_vec());
let pos = Pos(data.pos.0 + body_offsets); let pos = Pos(data.pos.0 + body_offsets);
@ -120,7 +120,7 @@ impl CharacterBehavior for Data {
Some(*data.uid), Some(*data.uid),
crit_chance, crit_chance,
crit_mult, crit_mult,
buff_strength, tool_stats,
self.static_data.damage_effect, self.static_data.damage_effect,
); );
output_events.emit_server(ServerEvent::Shoot { output_events.emit_server(ServerEvent::Shoot {

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
combat::{Attack, AttackDamage, AttackEffect, CombatBuff, CombatEffect, CombatRequirement}, combat::{Attack, AttackDamage, AttackEffect, CombatEffect, CombatRequirement},
comp::{ comp::{
character_state::OutputEvents, character_state::OutputEvents,
melee::MultiTarget, melee::MultiTarget,
@ -72,16 +72,7 @@ impl Stage<f32> {
} }
#[must_use] #[must_use]
pub fn adjusted_by_stats(mut self, stats: Stats) -> Self { pub fn adjusted_by_stats(self, stats: Stats) -> Self {
if let Some(CombatEffect::Buff(CombatBuff {
kind: _,
dur_secs: _,
ref mut strength,
chance: _,
})) = self.damage_effect
{
*strength *= stats.buff_strength;
}
Self { Self {
stage: self.stage, stage: self.stage,
base_damage: self.base_damage * stats.power, base_damage: self.base_damage * stats.power,
@ -97,7 +88,7 @@ impl Stage<f32> {
base_recover_duration: self.base_recover_duration / stats.speed, base_recover_duration: self.base_recover_duration / stats.speed,
forward_movement: self.forward_movement, forward_movement: self.forward_movement,
damage_kind: self.damage_kind, damage_kind: self.damage_kind,
damage_effect: self.damage_effect, damage_effect: self.damage_effect.map(|de| de.adjusted_by_stats(stats)),
} }
} }

View File

@ -154,13 +154,13 @@ impl CharacterBehavior for Data {
} }
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
strike_data strike_data
.melee_constructor .melee_constructor
.create_melee(crit_data, buff_strength), .create_melee(crit_data, tool_stats),
); );
} else if self.timer < strike_data.swing_duration { } else if self.timer < strike_data.swing_duration {
// Swings // Swings

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
comp::{ comp::{
character_state::OutputEvents, CharacterState, Melee, MeleeConstructor, character_state::OutputEvents, item::tool, CharacterState, Melee, MeleeConstructor,
MeleeConstructorKind, StateUpdate, MeleeConstructorKind, StateUpdate,
}, },
states::{ states::{
@ -62,11 +62,11 @@ impl CharacterBehavior for Data {
let create_melee = |charge_frac: f32| { let create_melee = |charge_frac: f32| {
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
self.static_data self.static_data
.melee_constructor .melee_constructor
.handle_scaling(charge_frac) .handle_scaling(charge_frac)
.create_melee(crit_data, buff_strength) .create_melee(crit_data, tool_stats)
}; };
match self.stage_section { match self.stage_section {
@ -208,14 +208,14 @@ impl CharacterBehavior for Data {
.min(1.0); .min(1.0);
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
self.static_data self.static_data
.melee_constructor .melee_constructor
.handle_scaling(charge_frac) .handle_scaling(charge_frac)
.create_melee(crit_data, buff_strength), .create_melee(crit_data, tool_stats),
); );
update.character = CharacterState::DashMelee(Data { update.character = CharacterState::DashMelee(Data {
@ -277,5 +277,5 @@ fn create_test_melee(static_data: StaticData) -> Melee {
multi_target: None, multi_target: None,
damage_effect: None, damage_effect: None,
}; };
melee.create_melee((0.0, 0.0), 0.0) melee.create_melee((0.0, 0.0), tool::Stats::one())
} }

View File

@ -95,7 +95,7 @@ impl CharacterBehavior for Data {
if !self.exhausted { if !self.exhausted {
// Attack // Attack
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
let scaling = self.max_vertical_speed / self.static_data.vertical_speed; let scaling = self.max_vertical_speed / self.static_data.vertical_speed;
let scaling = scaling.min(self.static_data.max_scaling); let scaling = scaling.min(self.static_data.max_scaling);
@ -104,7 +104,7 @@ impl CharacterBehavior for Data {
self.static_data self.static_data
.melee_constructor .melee_constructor
.handle_scaling(scaling) .handle_scaling(scaling)
.create_melee(crit_data, buff_strength), .create_melee(crit_data, tool_stats),
); );
if let CharacterState::DiveMelee(c) = &mut update.character { if let CharacterState::DiveMelee(c) = &mut update.character {

View File

@ -107,11 +107,11 @@ impl CharacterBehavior for Data {
} }
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
melee_constructor.create_melee(crit_data, buff_strength), melee_constructor.create_melee(crit_data, tool_stats),
); );
} else if self.timer < self.static_data.swing_duration { } else if self.timer < self.static_data.swing_duration {
// Swings // Swings

View File

@ -120,13 +120,13 @@ impl CharacterBehavior for Data {
StageSection::Recover => { StageSection::Recover => {
if !self.exhausted { if !self.exhausted {
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
self.static_data self.static_data
.melee_constructor .melee_constructor
.create_melee(crit_data, buff_strength), .create_melee(crit_data, tool_stats),
); );
update.character = CharacterState::LeapMelee(Data { update.character = CharacterState::LeapMelee(Data {

View File

@ -85,13 +85,13 @@ impl CharacterBehavior for Data {
} }
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
self.static_data self.static_data
.melee_constructor .melee_constructor
.create_melee(crit_data, buff_strength), .create_melee(crit_data, tool_stats),
); );
} else if self.timer < self.static_data.swing_duration { } else if self.timer < self.static_data.swing_duration {
// Swings // Swings

View File

@ -93,7 +93,7 @@ impl CharacterBehavior for Data {
// Fire if input is pressed still // Fire if input is pressed still
let (crit_chance, crit_mult) = let (crit_chance, crit_mult) =
get_crit_data(data, self.static_data.ability_info); get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
// Gets offsets // Gets offsets
let body_offsets = data.body.projectile_offsets(update.ori.look_vec()); let body_offsets = data.body.projectile_offsets(update.ori.look_vec());
let pos = Pos(data.pos.0 + body_offsets); let pos = Pos(data.pos.0 + body_offsets);
@ -101,7 +101,7 @@ impl CharacterBehavior for Data {
Some(*data.uid), Some(*data.uid),
crit_chance, crit_chance,
crit_mult, crit_mult,
buff_strength, tool_stats,
self.static_data.damage_effect, self.static_data.damage_effect,
); );
output_events.emit_server(ServerEvent::Shoot { output_events.emit_server(ServerEvent::Shoot {

View File

@ -65,13 +65,13 @@ impl CharacterBehavior for Data {
} }
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
self.static_data self.static_data
.melee_constructor .melee_constructor
.create_melee(crit_data, buff_strength), .create_melee(crit_data, tool_stats),
); );
} else if self.timer < self.static_data.swing_duration { } else if self.timer < self.static_data.swing_duration {
// Swings // Swings

View File

@ -93,13 +93,13 @@ impl CharacterBehavior for Data {
}); });
let crit_data = get_crit_data(data, self.static_data.ability_info); let crit_data = get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
data.updater.insert( data.updater.insert(
data.entity, data.entity,
self.static_data self.static_data
.melee_constructor .melee_constructor
.create_melee(crit_data, buff_strength), .create_melee(crit_data, tool_stats),
); );
} else if self.timer < self.static_data.swing_duration { } else if self.timer < self.static_data.swing_duration {
if matches!( if matches!(

View File

@ -7,7 +7,11 @@ use crate::{
character_state::OutputEvents, character_state::OutputEvents,
controller::InventoryManip, controller::InventoryManip,
inventory::slot::{ArmorSlot, EquipSlot, Slot}, inventory::slot::{ArmorSlot, EquipSlot, Slot},
item::{armor::Friction, tool::AbilityContext, Hands, ItemKind, ToolKind}, item::{
armor::Friction,
tool::{self, AbilityContext},
Hands, ItemKind, ToolKind,
},
quadruped_low, quadruped_medium, quadruped_small, quadruped_low, quadruped_medium, quadruped_small,
skills::{Skill, SwimSkill, SKILL_MODIFIERS}, skills::{Skill, SwimSkill, SKILL_MODIFIERS},
theropod, Body, CharacterAbility, CharacterState, Density, InputAttr, InputKind, theropod, Body, CharacterAbility, CharacterState, Density, InputAttr, InputKind,
@ -1269,8 +1273,7 @@ pub fn get_crit_data(data: &JoinData<'_>, ai: AbilityInfo) -> (f32, f32) {
(crit_chance, crit_mult) (crit_chance, crit_mult)
} }
/// Returns buff strength from the weapon used in the ability pub fn get_tool_stats(data: &JoinData<'_>, ai: AbilityInfo) -> tool::Stats {
pub fn get_buff_strength(data: &JoinData<'_>, ai: AbilityInfo) -> f32 {
ai.hand ai.hand
.map(|hand| match hand { .map(|hand| match hand {
HandInfo::TwoHanded | HandInfo::MainHand => EquipSlot::ActiveMainhand, HandInfo::TwoHanded | HandInfo::MainHand => EquipSlot::ActiveMainhand,
@ -1279,12 +1282,12 @@ pub fn get_buff_strength(data: &JoinData<'_>, ai: AbilityInfo) -> f32 {
.and_then(|slot| data.inventory.and_then(|inv| inv.equipped(slot))) .and_then(|slot| data.inventory.and_then(|inv| inv.equipped(slot)))
.and_then(|item| { .and_then(|item| {
if let ItemKind::Tool(tool) = &*item.kind() { if let ItemKind::Tool(tool) = &*item.kind() {
Some(tool.base_buff_strength()) Some(tool.stats)
} else { } else {
None None
} }
}) })
.unwrap_or(1.0) .unwrap_or(tool::Stats::one())
} }
pub fn input_is_pressed(data: &JoinData<'_>, input: InputKind) -> bool { pub fn input_is_pressed(data: &JoinData<'_>, input: InputKind) -> bool {

View File

@ -1,5 +1,5 @@
use common::{ use common::{
comp::{object, Body, LightEmitter, PhysicsState, Pos, ProjectileConstructor}, comp::{item::tool, object, Body, LightEmitter, PhysicsState, Pos, ProjectileConstructor},
event::{Emitter, ServerEvent}, event::{Emitter, ServerEvent},
terrain::{Block, TerrainChunkSize}, terrain::{Block, TerrainChunkSize},
util::Dir, util::Dir,
@ -188,7 +188,13 @@ impl WiringAction {
pos, pos,
dir: Dir::forward(), dir: Dir::forward(),
body: Body::Object(object::Body::Arrow), body: Body::Object(object::Body::Arrow),
projectile: constr.create_projectile(None, 0.0, 1.0, 1.0, None), projectile: constr.create_projectile(
None,
0.0,
1.0,
tool::Stats::one(),
None,
),
light: None, light: None,
speed: 5.0, speed: 5.0,
object: None, object: None,

View File

@ -620,12 +620,10 @@ impl<'a> Widget for ItemTooltip<'a> {
); );
// Effect Power // Effect Power
// TODO: Allow effect power to have different terminology based on what it is
// affecting.
stat_text( stat_text(
format!( format!(
"{} : {:+.0}%", "{} : {:+.0}%",
i18n.get_msg("common-stats-poise"), i18n.get_msg("common-stats-effect-power"),
(stats.effect_power - 1.0) * 100.0 (stats.effect_power - 1.0) * 100.0
), ),
2, 2,
@ -1053,13 +1051,13 @@ impl<'a> Widget for ItemTooltip<'a> {
let effect_power_text = if is_primary { let effect_power_text = if is_primary {
format!( format!(
"{} : {:+.0}%", "{} : {:+.0}%",
i18n.get_msg("common-stats-poise"), i18n.get_msg("common-stats-effect-power"),
(stats.effect_power - 1.0) * 100.0 (stats.effect_power - 1.0) * 100.0
) )
} else { } else {
format!( format!(
"{} : x{:.2}", "{} : x{:.2}",
i18n.get_msg("common-stats-poise"), i18n.get_msg("common-stats-effect-power"),
stats.effect_power stats.effect_power
) )
}; };