feat: added special ammo

This commit is contained in:
TotallyNot 2025-11-04 18:06:29 +01:00
parent 9550cd2bbb
commit 1c7a5d1e1b
Signed by: pyrite
GPG key ID: 7F1BA9170CD35D15
3 changed files with 128 additions and 10 deletions

View file

@ -11,7 +11,8 @@ use proxisim_models::bundle::{
SimpleStatEffective, Speed, Strength, WeaponAccuracy,
},
weapon::{
Ammo, DamageStat, NeedsReload, NonTargeted, RateOfFire, Usable, Uses, Weapon, WeaponSlot,
Ammo, AmmoType, DamageStat, NeedsReload, NonTargeted, RateOfFire, Usable, Uses, Weapon,
WeaponSlot,
},
};
use rand::Rng as _;
@ -201,6 +202,7 @@ pub fn use_damaging_weapon(
&SimpleStatEffective<Clips>,
&RateOfFire,
&SimpleStatEffective<AmmoControl>,
&AmmoType,
)>,
Query<&mut Uses>,
),
@ -279,10 +281,13 @@ pub fn use_damaging_weapon(
let mut ammo = ammo_q
.get_mut(weapon)
.ok()
.map(|(ammo, clips, rof, ammo_ctrl)| {
.map(|(ammo, clips, rof, ammo_ctrl, kind)| {
let ammo_ctrl = 1.0 - (ammo_ctrl).value;
let rof_eff = ((rof.0[0] as f32) * ammo_ctrl)..=((rof.0[1] as f32) * ammo_ctrl);
(ammo, clips, rof_eff)
if *kind == AmmoType::Tracer {
acc_eff.value += 10.0 / 50.0;
}
(ammo, clips, rof_eff, kind)
});
enum MultiAttack {
@ -308,7 +313,7 @@ pub fn use_damaging_weapon(
+ 30.0;
loop {
let rounds = ammo.as_mut().map(|(ammo, clips, rof)| {
let rounds = ammo.as_mut().map(|(ammo, clips, rof, _)| {
let rounds = (rng.random_range(rof.clone()).round() as u16).clamp(1, ammo.0);
metrics.increment_counter(Some(player), "rounds_fired", rounds.into());
metrics.increment_counter(Some(weapon), "rounds_fired", rounds.into());
@ -465,11 +470,27 @@ pub fn use_damaging_weapon(
}
};
let spammo_bonus = ammo
.as_ref()
.map(|(_, _, _, kind)| match kind {
AmmoType::HollowPoint if piece.is_none() => {
armour_mitigation *= 1.5;
0.0
}
AmmoType::HollowPoint => 0.50,
AmmoType::Incindiary => 0.40,
AmmoType::Piercer => {
armour_mitigation *= 0.5;
0.0
}
_ => 0.0,
})
.unwrap_or_default();
// TODO: special ammo
let mut dmg = dmg_intrinsic
* w_dmg.0
* (1.0 + dmg_bonus.value)
* (1.0 + dmg_bonus.value + spammo_bonus)
* (1.0 - armour_mitigation)
* (1.0 - def_mitigation)
* (1.0 - bonus_mitigation)
@ -538,7 +559,7 @@ pub fn use_damaging_weapon(
if chance >= 1.0 || rng.random_bool(chance as f64) {
dmg = dmg_intrinsic
* w_dmg.0
* (1.0 + dmg_bonus.value + 5.0)
* (1.0 + dmg_bonus.value + spammo_bonus + 5.0)
* (1.0 - armour_mitigation)
* (1.0 - def_mitigation)
* (1.0 - bonus_mitigation)
@ -619,7 +640,7 @@ pub fn use_damaging_weapon(
// Technically only douple tap and blindfire have this condition, but we can run into
// panics with invalid bonus/weapon combinations without checking this for all bonuses
if ammo.as_ref().is_some_and(|(a, _, _)| a.0 == 0) {
if ammo.as_ref().is_some_and(|(a, _, _, _)| a.0 == 0) {
break;
}