Merge branch 'sam/explosions' into 'master'

Staff Rebalancing

See merge request veloren/veloren!2970
This commit is contained in:
Samuel Keiffer
2021-10-29 22:20:53 +00:00
20 changed files with 120 additions and 29 deletions

View File

@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Nerfed some skill values - Nerfed some skill values
- Tweaked critical chance of legendary weapons - Tweaked critical chance of legendary weapons
- Agents using fireball projectiles aim at the feet instead of the eyes - Agents using fireball projectiles aim at the feet instead of the eyes
- Explosions can now have a nonzero minimum falloff
### Removed ### Removed

View File

@ -6,6 +6,7 @@ BasicRanged(
damage: 13.0, damage: 13.0,
radius: 5.0, radius: 5.0,
energy_regen: 0, energy_regen: 0,
min_falloff: 0.5,
), ),
projectile_body: Object(BoltFire), projectile_body: Object(BoltFire),
/*projectile_light: Some(LightEmitter { /*projectile_light: Some(LightEmitter {

View File

@ -6,6 +6,7 @@ BasicRanged(
damage: 10.0, damage: 10.0,
radius: 5.0, radius: 5.0,
energy_regen: 5.0, energy_regen: 5.0,
min_falloff: 0.5,
), ),
projectile_body: Object(BoltFire), projectile_body: Object(BoltFire),
/*projectile_light: Some(LightEmitter { /*projectile_light: Some(LightEmitter {

View File

@ -6,6 +6,7 @@ BasicRanged(
damage: 10.0, damage: 10.0,
radius: 5.0, radius: 5.0,
energy_regen: 5.0, energy_regen: 5.0,
min_falloff: 0.5,
), ),
projectile_body: Object(BoltFire), projectile_body: Object(BoltFire),
/*projectile_light: Some(LightEmitter { /*projectile_light: Some(LightEmitter {

View File

@ -6,6 +6,7 @@ BasicRanged(
damage: 50.0, damage: 50.0,
knockback: 18.0, knockback: 18.0,
radius: 5.0, radius: 5.0,
min_falloff: 0.75,
), ),
projectile_body: Object(ClayRocket), projectile_body: Object(ClayRocket),
projectile_light: None, projectile_light: None,

View File

@ -6,6 +6,7 @@ BasicRanged(
damage: 20.0, damage: 20.0,
knockback: 25.0, knockback: 25.0,
radius: 5.0, radius: 5.0,
min_falloff: 0.6,
), ),
projectile_body: Object(Pumpkin), projectile_body: Object(Pumpkin),
projectile_light: None, projectile_light: None,

View File

@ -6,6 +6,7 @@ BasicRanged(
damage: 26.0, damage: 26.0,
radius: 5.0, radius: 5.0,
energy_regen: 0, energy_regen: 0,
min_falloff: 0.5,
), ),
projectile_body: Object(FireworkPurple), projectile_body: Object(FireworkPurple),
/*projectile_light: Some(LightEmitter { /*projectile_light: Some(LightEmitter {

View File

@ -5,6 +5,7 @@ BasicRanged(
projectile: NecroticSphere( projectile: NecroticSphere(
damage: 45.0, damage: 45.0,
radius: 5.0, radius: 5.0,
min_falloff: 0.9,
), ),
projectile_body: Object(FireworkPurple), projectile_body: Object(FireworkPurple),
projectile_speed: 100.0, projectile_speed: 100.0,

View File

@ -6,6 +6,7 @@ BasicRanged(
damage: 13.0, damage: 13.0,
radius: 5.0, radius: 5.0,
energy_regen: 0, energy_regen: 0,
min_falloff: 0.5,
), ),
projectile_body: Object(FireworkPurple), projectile_body: Object(FireworkPurple),
/*projectile_light: Some(LightEmitter { /*projectile_light: Some(LightEmitter {

View File

@ -5,6 +5,7 @@ BasicRanged(
projectile: Frostball( projectile: Frostball(
damage: 12.0, damage: 12.0,
radius: 5.0, radius: 5.0,
min_falloff: 0.5,
), ),
projectile_body: Object(BoltFire), // TODO: Get ice projectile model projectile_body: Object(BoltFire), // TODO: Get ice projectile model
/*projectile_light: Some(LightEmitter { /*projectile_light: Some(LightEmitter {

View File

@ -5,6 +5,7 @@ BasicRanged(
projectile: Snowball( projectile: Snowball(
damage: 20.0, damage: 20.0,
radius: 5.0, radius: 5.0,
min_falloff: 0.7,
), ),
projectile_body: Object(Snowball), projectile_body: Object(Snowball),
projectile_speed: 60.0, projectile_speed: 60.0,

View File

@ -5,7 +5,8 @@ BasicRanged(
projectile: Fireball( projectile: Fireball(
damage: 9.0, damage: 9.0,
radius: 4.0, radius: 4.0,
energy_regen: 6.0, energy_regen: 10.0,
min_falloff: 0.5,
), ),
projectile_body: Object(BoltFire), projectile_body: Object(BoltFire),
projectile_speed: 60.0, projectile_speed: 60.0,

View File

@ -6,6 +6,7 @@ BasicRanged(
damage: 6.0, damage: 6.0,
radius: 5.0, radius: 5.0,
energy_regen: 5.0, energy_regen: 5.0,
min_falloff: 0.5,
), ),
projectile_body: Object(BoltFire), projectile_body: Object(BoltFire),
/*projectile_light: Some(LightEmitter { /*projectile_light: Some(LightEmitter {

View File

@ -227,7 +227,7 @@ impl Attack {
self.crit_multiplier, self.crit_multiplier,
strength_modifier, strength_modifier,
); );
let applied_damage = -change.amount as f32; let applied_damage = -change.amount;
accumulated_damage += applied_damage; accumulated_damage += applied_damage;
emit_outcome(Outcome::Damage { pos: target.pos }); emit_outcome(Outcome::Damage { pos: target.pos });
if change.amount.abs() > Health::HEALTH_EPSILON { if change.amount.abs() > Health::HEALTH_EPSILON {
@ -238,7 +238,7 @@ impl Attack {
for effect in damage.effects.iter() { for effect in damage.effects.iter() {
match effect { match effect {
CombatEffect::Knockback(kb) => { CombatEffect::Knockback(kb) => {
let impulse = kb.calculate_impulse(dir); let impulse = kb.calculate_impulse(dir) * strength_modifier;
if !impulse.is_approx_zero() { if !impulse.is_approx_zero() {
emit(ServerEvent::Knockback { emit(ServerEvent::Knockback {
entity: target.entity, entity: target.entity,
@ -250,7 +250,9 @@ impl Attack {
if let Some(attacker) = attacker { if let Some(attacker) = attacker {
emit(ServerEvent::EnergyChange { emit(ServerEvent::EnergyChange {
entity: attacker.entity, entity: attacker.entity,
change: *ec * compute_energy_reward_mod(attacker.inventory), change: *ec
* compute_energy_reward_mod(attacker.inventory)
* strength_modifier,
}); });
} }
}, },
@ -258,13 +260,16 @@ impl Attack {
if thread_rng().gen::<f32>() < b.chance { if thread_rng().gen::<f32>() < b.chance {
emit(ServerEvent::Buff { emit(ServerEvent::Buff {
entity: target.entity, entity: target.entity,
buff_change: BuffChange::Add( buff_change: BuffChange::Add(b.to_buff(
b.to_buff(attacker.map(|a| a.uid), applied_damage), attacker.map(|a| a.uid),
), applied_damage,
strength_modifier,
)),
}); });
} }
}, },
CombatEffect::Lifesteal(l) => { CombatEffect::Lifesteal(l) => {
// Not modified by strength_modifer as damage already is
if let Some(attacker_entity) = attacker.map(|a| a.entity) { if let Some(attacker_entity) = attacker.map(|a| a.entity) {
let change = HealthChange { let change = HealthChange {
amount: applied_damage * l, amount: applied_damage * l,
@ -280,7 +285,8 @@ impl Attack {
} }
}, },
CombatEffect::Poise(p) => { CombatEffect::Poise(p) => {
let change = -Poise::apply_poise_reduction(*p, target.inventory); let change = -Poise::apply_poise_reduction(*p, target.inventory)
* strength_modifier;
if change.abs() > Poise::POISE_EPSILON { if change.abs() > Poise::POISE_EPSILON {
emit(ServerEvent::PoiseChange { emit(ServerEvent::PoiseChange {
entity: target.entity, entity: target.entity,
@ -291,7 +297,7 @@ impl Attack {
}, },
CombatEffect::Heal(h) => { CombatEffect::Heal(h) => {
let change = HealthChange { let change = HealthChange {
amount: *h, amount: *h * strength_modifier,
by: attacker.map(|a| a.uid), by: attacker.map(|a| a.uid),
cause: None, cause: None,
}; };
@ -303,6 +309,7 @@ impl Attack {
} }
}, },
CombatEffect::Combo(c) => { CombatEffect::Combo(c) => {
// Not affected by strength modifier as integer
if let Some(attacker_entity) = attacker.map(|a| a.entity) { if let Some(attacker_entity) = attacker.map(|a| a.entity) {
emit(ServerEvent::ComboChange { emit(ServerEvent::ComboChange {
entity: attacker_entity, entity: attacker_entity,
@ -366,7 +373,7 @@ impl Attack {
is_applied = true; is_applied = true;
match effect.effect { match effect.effect {
CombatEffect::Knockback(kb) => { CombatEffect::Knockback(kb) => {
let impulse = kb.calculate_impulse(dir); let impulse = kb.calculate_impulse(dir) * strength_modifier;
if !impulse.is_approx_zero() { if !impulse.is_approx_zero() {
emit(ServerEvent::Knockback { emit(ServerEvent::Knockback {
entity: target.entity, entity: target.entity,
@ -378,7 +385,9 @@ impl Attack {
if let Some(attacker) = attacker { if let Some(attacker) = attacker {
emit(ServerEvent::EnergyChange { emit(ServerEvent::EnergyChange {
entity: attacker.entity, entity: attacker.entity,
change: ec * compute_energy_reward_mod(attacker.inventory), change: ec
* compute_energy_reward_mod(attacker.inventory)
* strength_modifier,
}); });
} }
}, },
@ -386,13 +395,16 @@ impl Attack {
if thread_rng().gen::<f32>() < b.chance { if thread_rng().gen::<f32>() < b.chance {
emit(ServerEvent::Buff { emit(ServerEvent::Buff {
entity: target.entity, entity: target.entity,
buff_change: BuffChange::Add( buff_change: BuffChange::Add(b.to_buff(
b.to_buff(attacker.map(|a| a.uid), accumulated_damage), attacker.map(|a| a.uid),
), accumulated_damage,
strength_modifier,
)),
}); });
} }
}, },
CombatEffect::Lifesteal(l) => { CombatEffect::Lifesteal(l) => {
// Not modified by strength_modifer as damage already is
if let Some(attacker_entity) = attacker.map(|a| a.entity) { if let Some(attacker_entity) = attacker.map(|a| a.entity) {
let change = HealthChange { let change = HealthChange {
amount: accumulated_damage * l, amount: accumulated_damage * l,
@ -408,7 +420,8 @@ impl Attack {
} }
}, },
CombatEffect::Poise(p) => { CombatEffect::Poise(p) => {
let change = -Poise::apply_poise_reduction(p, target.inventory); let change =
-Poise::apply_poise_reduction(p, target.inventory) * strength_modifier;
if change.abs() > Poise::POISE_EPSILON { if change.abs() > Poise::POISE_EPSILON {
emit(ServerEvent::PoiseChange { emit(ServerEvent::PoiseChange {
entity: target.entity, entity: target.entity,
@ -419,7 +432,7 @@ impl Attack {
}, },
CombatEffect::Heal(h) => { CombatEffect::Heal(h) => {
let change = HealthChange { let change = HealthChange {
amount: h, amount: h * strength_modifier,
by: attacker.map(|a| a.uid), by: attacker.map(|a| a.uid),
cause: None, cause: None,
}; };
@ -431,6 +444,7 @@ impl Attack {
} }
}, },
CombatEffect::Combo(c) => { CombatEffect::Combo(c) => {
// Not affected by strength modifier as integer
if let Some(attacker_entity) = attacker.map(|a| a.entity) { if let Some(attacker_entity) = attacker.map(|a| a.entity) {
emit(ServerEvent::ComboChange { emit(ServerEvent::ComboChange {
entity: attacker_entity, entity: attacker_entity,
@ -768,10 +782,11 @@ pub enum CombatBuffStrength {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl CombatBuffStrength { impl CombatBuffStrength {
fn to_strength(self, damage: f32) -> f32 { fn to_strength(self, damage: f32, strength_modifier: f32) -> f32 {
match self { match self {
// Not affected by strength modifier as damage already is
CombatBuffStrength::DamageFraction(f) => damage * f, CombatBuffStrength::DamageFraction(f) => damage * f,
CombatBuffStrength::Value(v) => v, CombatBuffStrength::Value(v) => v * strength_modifier,
} }
} }
} }
@ -788,7 +803,7 @@ impl MulAssign<f32> for CombatBuffStrength {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl CombatBuff { impl CombatBuff {
fn to_buff(self, uid: Option<Uid>, damage: f32) -> Buff { fn to_buff(self, uid: Option<Uid>, damage: f32, strength_modifier: f32) -> Buff {
// TODO: Generate BufCategoryId vec (probably requires damage overhaul?) // TODO: Generate BufCategoryId vec (probably requires damage overhaul?)
let source = if let Some(uid) = uid { let source = if let Some(uid) = uid {
BuffSource::Character { by: uid } BuffSource::Character { by: uid }
@ -798,7 +813,7 @@ impl CombatBuff {
Buff::new( Buff::new(
self.kind, self.kind,
BuffData::new( BuffData::new(
self.strength.to_strength(damage), self.strength.to_strength(damage, strength_modifier),
Some(Duration::from_secs_f32(self.dur_secs)), Some(Duration::from_secs_f32(self.dur_secs)),
), ),
Vec::new(), Vec::new(),

View File

@ -54,29 +54,35 @@ pub enum ProjectileConstructor {
damage: f32, damage: f32,
radius: f32, radius: f32,
energy_regen: f32, energy_regen: f32,
min_falloff: f32,
}, },
Frostball { Frostball {
damage: f32, damage: f32,
radius: f32, radius: f32,
min_falloff: f32,
}, },
NecroticSphere { NecroticSphere {
damage: f32, damage: f32,
radius: f32, radius: f32,
min_falloff: f32,
}, },
Possess, Possess,
ClayRocket { ClayRocket {
damage: f32, damage: f32,
radius: f32, radius: f32,
knockback: f32, knockback: f32,
min_falloff: f32,
}, },
Snowball { Snowball {
damage: f32, damage: f32,
radius: f32, radius: f32,
min_falloff: f32,
}, },
ExplodingPumpkin { ExplodingPumpkin {
damage: f32, damage: f32,
radius: f32, radius: f32,
knockback: f32, knockback: f32,
min_falloff: f32,
}, },
} }
@ -141,9 +147,16 @@ impl ProjectileConstructor {
damage, damage,
radius, radius,
energy_regen, energy_regen,
min_falloff,
} => { } => {
let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy_regen)) let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy_regen))
.with_requirement(CombatRequirement::AnyDamage); .with_requirement(CombatRequirement::AnyDamage);
let buff = CombatEffect::Buff(CombatBuff {
kind: BuffKind::Burning,
dur_secs: 5.0,
strength: CombatBuffStrength::DamageFraction(0.1 * buff_strength),
chance: 0.1,
});
let damage = AttackDamage::new( let damage = AttackDamage::new(
Damage { Damage {
source: DamageSource::Explosion, source: DamageSource::Explosion,
@ -151,7 +164,8 @@ impl ProjectileConstructor {
value: damage, value: damage,
}, },
Some(GroupTarget::OutOfGroup), Some(GroupTarget::OutOfGroup),
); )
.with_effect(buff);
let attack = Attack::default() let attack = Attack::default()
.with_damage(damage) .with_damage(damage)
.with_crit(crit_chance, crit_mult) .with_crit(crit_chance, crit_mult)
@ -164,6 +178,7 @@ impl ProjectileConstructor {
], ],
radius, radius,
reagent: Some(Reagent::Red), reagent: Some(Reagent::Red),
min_falloff,
}; };
Projectile { Projectile {
hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish], hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish],
@ -175,7 +190,11 @@ impl ProjectileConstructor {
is_point: true, is_point: true,
} }
}, },
Frostball { damage, radius } => { Frostball {
damage,
radius,
min_falloff,
} => {
let damage = AttackDamage::new( let damage = AttackDamage::new(
Damage { Damage {
source: DamageSource::Explosion, source: DamageSource::Explosion,
@ -192,6 +211,7 @@ impl ProjectileConstructor {
effects: vec![RadiusEffect::Attack(attack)], effects: vec![RadiusEffect::Attack(attack)],
radius, radius,
reagent: Some(Reagent::White), reagent: Some(Reagent::White),
min_falloff,
}; };
Projectile { Projectile {
hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish], hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish],
@ -203,7 +223,11 @@ impl ProjectileConstructor {
is_point: true, is_point: true,
} }
}, },
NecroticSphere { damage, radius } => { NecroticSphere {
damage,
radius,
min_falloff,
} => {
let damage = AttackDamage::new( let damage = AttackDamage::new(
Damage { Damage {
source: DamageSource::Explosion, source: DamageSource::Explosion,
@ -220,6 +244,7 @@ impl ProjectileConstructor {
effects: vec![RadiusEffect::Attack(attack)], effects: vec![RadiusEffect::Attack(attack)],
radius, radius,
reagent: Some(Reagent::Purple), reagent: Some(Reagent::Purple),
min_falloff,
}; };
Projectile { Projectile {
hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish], hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish],
@ -244,6 +269,7 @@ impl ProjectileConstructor {
damage, damage,
radius, radius,
knockback, knockback,
min_falloff,
} => { } => {
let knockback = AttackEffect::new( let knockback = AttackEffect::new(
Some(GroupTarget::OutOfGroup), Some(GroupTarget::OutOfGroup),
@ -272,6 +298,7 @@ impl ProjectileConstructor {
], ],
radius, radius,
reagent: Some(Reagent::Red), reagent: Some(Reagent::Red),
min_falloff,
}; };
Projectile { Projectile {
hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish], hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish],
@ -283,7 +310,11 @@ impl ProjectileConstructor {
is_point: true, is_point: true,
} }
}, },
Snowball { damage, radius } => { Snowball {
damage,
radius,
min_falloff,
} => {
let damage = AttackDamage::new( let damage = AttackDamage::new(
Damage { Damage {
source: DamageSource::Explosion, source: DamageSource::Explosion,
@ -299,6 +330,7 @@ impl ProjectileConstructor {
effects: vec![RadiusEffect::Attack(attack)], effects: vec![RadiusEffect::Attack(attack)],
radius, radius,
reagent: Some(Reagent::White), reagent: Some(Reagent::White),
min_falloff,
}; };
Projectile { Projectile {
hit_solid: vec![], hit_solid: vec![],
@ -314,6 +346,7 @@ impl ProjectileConstructor {
damage, damage,
radius, radius,
knockback, knockback,
min_falloff,
} => { } => {
let knockback = AttackEffect::new( let knockback = AttackEffect::new(
Some(GroupTarget::OutOfGroup), Some(GroupTarget::OutOfGroup),
@ -353,6 +386,7 @@ impl ProjectileConstructor {
], ],
radius, radius,
reagent: Some(Reagent::Red), reagent: Some(Reagent::Red),
min_falloff,
}; };
Projectile { Projectile {
hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish], hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish],
@ -417,6 +451,7 @@ impl ProjectileConstructor {
Snowball { Snowball {
ref mut damage, ref mut damage,
ref mut radius, ref mut radius,
..
} => { } => {
*damage *= power; *damage *= power;
*radius *= range; *radius *= range;

View File

@ -6,6 +6,7 @@ pub struct Explosion {
pub effects: Vec<RadiusEffect>, pub effects: Vec<RadiusEffect>,
pub radius: f32, pub radius: f32,
pub reagent: Option<Reagent>, pub reagent: Option<Reagent>,
pub min_falloff: f32,
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]

View File

@ -2033,6 +2033,7 @@ fn handle_explosion(
], ],
radius: 3.0 * power, radius: 3.0 * power,
reagent: None, reagent: None,
min_falloff: 0.0,
}, },
owner, owner,
}); });

View File

@ -546,6 +546,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
fn cylinder_sphere_strength( fn cylinder_sphere_strength(
sphere_pos: Vec3<f32>, sphere_pos: Vec3<f32>,
radius: f32, radius: f32,
min_falloff: f32,
cyl_pos: Vec3<f32>, cyl_pos: Vec3<f32>,
cyl_body: Body, cyl_body: Body,
) -> f32 { ) -> f32 {
@ -557,9 +558,19 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
let vert_distance = let vert_distance =
(sphere_pos.z - (cyl_pos.z + half_body_height)).abs() - half_body_height; (sphere_pos.z - (cyl_pos.z + half_body_height)).abs() - half_body_height;
// Compare both checks, take whichever gives weaker effect, sets minimum of 0 so // Use whichever gives maximum distance as that closer to real value. Sets
// that explosions reach a max strength on edge of entity // minimum to 0 as negative values would indicate inside entity.
((horiz_dist.max(vert_distance).max(0.0) / radius).min(1.0) - 1.0).abs() let distance = horiz_dist.max(vert_distance).max(0.0);
if distance > radius {
// If further than exploion radius, no strength
0.0
} else {
// Falloff inversely proportional to radius
let fall_off = ((distance / radius).min(1.0) - 1.0).abs();
let min_falloff = min_falloff.clamp(0.0, 1.0);
min_falloff + fall_off * (1.0 - min_falloff)
}
} }
// TODO: Faster RNG? // TODO: Faster RNG?
@ -714,7 +725,13 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
{ {
// Check if it is a hit // Check if it is a hit
let strength = if let Some(body) = body_b_maybe { let strength = if let Some(body) = body_b_maybe {
cylinder_sphere_strength(pos, explosion.radius, pos_b.0, *body) cylinder_sphere_strength(
pos,
explosion.radius,
explosion.min_falloff,
pos_b.0,
*body,
)
} else { } else {
let distance_squared = pos.distance_squared(pos_b.0); let distance_squared = pos.distance_squared(pos_b.0);
1.0 - distance_squared / explosion.radius.powi(2) 1.0 - distance_squared / explosion.radius.powi(2)
@ -801,7 +818,13 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
.join() .join()
{ {
let strength = if let Some(body) = body_b_maybe { let strength = if let Some(body) = body_b_maybe {
cylinder_sphere_strength(pos, explosion.radius, pos_b.0, *body) cylinder_sphere_strength(
pos,
explosion.radius,
explosion.min_falloff,
pos_b.0,
*body,
)
} else { } else {
let distance_squared = pos.distance_squared(pos_b.0); let distance_squared = pos.distance_squared(pos_b.0);
1.0 - distance_squared / explosion.radius.powi(2) 1.0 - distance_squared / explosion.radius.powi(2)

View File

@ -1862,6 +1862,7 @@ impl<'a> AgentData<'a> {
damage: _, damage: _,
radius: _, radius: _,
energy_regen: _, energy_regen: _,
min_falloff: _,
} => 0.0, } => 0.0,
_ => tgt_eye_offset, _ => tgt_eye_offset,
}; };

View File

@ -61,6 +61,7 @@ impl<'a> System<'a> for Sys {
], ],
radius: 12.0, radius: 12.0,
reagent: None, reagent: None,
min_falloff: 0.75,
}, },
owner: *owner, owner: *owner,
}); });
@ -153,6 +154,7 @@ impl<'a> System<'a> for Sys {
], ],
radius: 12.0, radius: 12.0,
reagent: Some(*reagent), reagent: Some(*reagent),
min_falloff: 0.0,
}, },
owner: *owner, owner: *owner,
}); });