diff --git a/build_resources/cached_build.ron b/build_resources/cached_build.ron index af338a43..3d4a02eb 100644 --- a/build_resources/cached_build.ron +++ b/build_resources/cached_build.ron @@ -476,8 +476,11 @@ 4702218143706120192: 1684295811, 4702268067546975437: 1684295508, 4702275945375989760: 1684295811, + 4702280812815181677: 1693614164, 4702284611398874935: 1680496635, 4702285034992601484: 1684377413, + 4702384682415937290: 1693691570, + 4702389017541177508: 1693676344, 4702690513873010688: 1684295508, 4702705542307176776: 1684379160, 4702715079582705254: 1680496635, @@ -571,7 +574,9 @@ 4709486873968302194: 1681090557, 4709531107822167142: 1680496635, 4710041623934370589: 1680989764, + 4710079802884401835: 1693690173, 4710113204575153609: 1680496635, + 4710123927230917292: 1693614164, 4710139031809800634: 1681090557, 4710183194200462676: 1680496635, 4710408195999638950: 1680496635, diff --git a/build_resources/weapon_formulas.json b/build_resources/weapon_formulas.json index 9178ae70..2ae7d602 100644 --- a/build_resources/weapon_formulas.json +++ b/build_resources/weapon_formulas.json @@ -280,6 +280,7 @@ "4130495068": {"name": "Precision Frame", "cat": "heavy", "subFam": "Precision", "magProf": "adaptive", "pve":1.20 }, "1174163613": {"name": "Parasite", "cat": "parasite","subFam": "Parasite", "magProf": "adaptive" }, "1759472859": {"name": "Double Fire", "cat": "special", "subFam": "TODO", "magProf": "special" }, + "2733244971": {"name": "Dead Messenger", "cat": "special", "subFam": "WaveFrame", "magProf": "special", "pve":1.5}, "cat": { "special": { "range": {"vpp_start": 0.0,"offset_start": 999.0,"vpp_end": 0.0,"offset_end": 999.9, "floor_percent": 0.999}, @@ -323,14 +324,14 @@ } }, "subFam": { - "WaveFrame": {"damage": 130.0, "crit_mult": -25.5, "burst_delay": 20, "burst_size": 1, "inner_burst_delay": 0.0}, - "Lightweight": {"damage": 200.0, "crit_mult": -25.5, "burst_delay": 20, "burst_size": 1, "inner_burst_delay": 0.0}, - "FightingLion": {"damage": 150.0, "crit_mult": -25.5, "burst_delay": 20, "burst_size": 1, "inner_burst_delay": 0.0}, - "Adaptive": {"damage": 280.5, "crit_mult": -25.5, "burst_delay": 15, "burst_size": 1, "inner_burst_delay": 0.0}, - "Rapid-Fire": {"damage": 225.0, "crit_mult": -25.5, "burst_delay": 12, "burst_size": 1, "inner_burst_delay": 0.0}, - "Precision": {"damage": 300.0, "crit_mult": -25.5, "burst_delay": 18, "burst_size": 1, "inner_burst_delay": 0.0}, - "Parasite": {"damage": 835.0, "crit_mult": -25.5, "burst_delay": 18, "burst_size": 1, "inner_burst_delay": 0.0}, - "TODO": {"damage": 0.0, "crit_mult": -25.5, "burst_delay": 0, "burst_size": 0, "inner_burst_delay": 0.0} + "WaveFrame": {"damage": 130.0, "crit_mult": -25.5, "burst_delay": 20, "burst_size": 1, "inner_burst_delay": 0.0}, + "Lightweight": {"damage": 200.0, "crit_mult": -25.5, "burst_delay": 20, "burst_size": 1, "inner_burst_delay": 0.0}, + "FightingLion": {"damage": 150.0, "crit_mult": -25.5, "burst_delay": 20, "burst_size": 1, "inner_burst_delay": 0.0}, + "Adaptive": {"damage": 280.5, "crit_mult": -25.5, "burst_delay": 15, "burst_size": 1, "inner_burst_delay": 0.0}, + "Rapid-Fire": {"damage": 225.0, "crit_mult": -25.5, "burst_delay": 12, "burst_size": 1, "inner_burst_delay": 0.0}, + "Precision": {"damage": 300.0, "crit_mult": -25.5, "burst_delay": 18, "burst_size": 1, "inner_burst_delay": 0.0}, + "Parasite": {"damage": 835.0, "crit_mult": -25.5, "burst_delay": 18, "burst_size": 1, "inner_burst_delay": 0.0}, + "TODO": {"damage": 0.0, "crit_mult": -25.5, "burst_delay": 0, "burst_size": 0, "inner_burst_delay": 0.0} }, "magProf": { "rapid": { diff --git a/src/perks/exotic_perks.rs b/src/perks/exotic_perks.rs index 3e5aa996..3c61b0ee 100644 --- a/src/perks/exotic_perks.rs +++ b/src/perks/exotic_perks.rs @@ -1136,5 +1136,20 @@ pub fn exotic_perks() { ..Default::default() }; }), - ) + ); + + add_dmr( + Perks::TrinaryVision, + Box::new(|_input: ModifierResponseInput| -> DamageModifierResponse { + let dead_messenger_pvp_nerf = 0.65; + if _input.pvp { + DamageModifierResponse { + explosive_dmg_scale: dead_messenger_pvp_nerf, + ..Default::default() + } + } else { + DamageModifierResponse::default() + } + }), + ); } diff --git a/src/perks/meta_perks.rs b/src/perks/meta_perks.rs index 3903d90d..740aac1d 100644 --- a/src/perks/meta_perks.rs +++ b/src/perks/meta_perks.rs @@ -123,29 +123,6 @@ pub fn meta_perks() { Perks::BuiltIn, Box::new( |_input: ModifierResponseInput| -> ExplosivePercentResponse { - if *_input.calc_data.weapon_type == WeaponType::GRENADELAUNCHER { - let blast_radius_struct = - _input.calc_data.stats.get(&StatHashes::BLAST_RADIUS.into()); - let blast_radius; - if blast_radius_struct.is_none() { - blast_radius = 0; - } else { - blast_radius = blast_radius_struct.unwrap().perk_val(); - }; - if _input.calc_data.ammo_type == &AmmoType::SPECIAL { - return ExplosivePercentResponse { - percent: 0.5 + 0.003 * blast_radius as f64, - delyed: 0.0, - retain_base_total: true, - }; - } else if _input.calc_data.ammo_type == &AmmoType::HEAVY { - return ExplosivePercentResponse { - percent: 0.7 + 0.00175 * blast_radius as f64, - delyed: 0.0, - retain_base_total: true, - }; - }; - } if *_input.calc_data.weapon_type == WeaponType::ROCKET && _input.calc_data.intrinsic_hash < 1000 //ensures not exotic diff --git a/src/perks/mod.rs b/src/perks/mod.rs index d64bc08f..b49c3989 100644 --- a/src/perks/mod.rs +++ b/src/perks/mod.rs @@ -442,6 +442,7 @@ pub enum Perks { ColdFusion = 1036269296, BlackHole = 3905543891, TemporalUnlimiter = 806917387, + TrinaryVision = 2733244971, //heavy exotic ReignHavoc = 4148158229, diff --git a/src/perks/perk_options_handler.rs b/src/perks/perk_options_handler.rs index 3efb9c59..924a5e5b 100644 --- a/src/perks/perk_options_handler.rs +++ b/src/perks/perk_options_handler.rs @@ -352,6 +352,7 @@ fn hash_to_perk_option_data(_hash: u32) -> Option { Perks::ColdFusion => Some(PerkOptionData::toggle()), Perks::BlackHole => Some(PerkOptionData::static_()), Perks::TemporalUnlimiter => Some(PerkOptionData::toggle()), + Perks::TrinaryVision => Some(PerkOptionData::static_()), Perks::MarksmanSights => Some(PerkOptionData::static_()), Perks::DexterityMod => Some(PerkOptionData::stacking(3)), Perks::ReserveMod => Some(PerkOptionData::stacking(3)), diff --git a/src/weapons/mod.rs b/src/weapons/mod.rs index c0653145..62cbd2b3 100644 --- a/src/weapons/mod.rs +++ b/src/weapons/mod.rs @@ -23,7 +23,7 @@ use self::dps_calc::complex_dps_calc; #[derive(Debug, Clone)] pub struct PsuedoWeapon {} -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Copy, Serialize)] pub struct Stat { pub base_value: i32, pub part_value: i32, diff --git a/src/weapons/stat_calc.rs b/src/weapons/stat_calc.rs index 2032ce56..b8ee7e95 100644 --- a/src/weapons/stat_calc.rs +++ b/src/weapons/stat_calc.rs @@ -368,13 +368,68 @@ impl Weapon { } } +type ExplosiveDamage = f64; +type ImpactDamage = f64; +type CritMultiplier = f64; +type DamageDelay = f64; +#[derive(Debug)] +enum GrenadeLauncherDamageErr { + NotGrenadeLauncher, + BlastRadiusMissing, + NotImplemented, +} + +impl Weapon { + fn get_grenade_launcher_damage( + &self, + ) -> Result<(ImpactDamage, ExplosiveDamage), GrenadeLauncherDamageErr> { + if self.weapon_type != WeaponType::GRENADELAUNCHER { + return Err(GrenadeLauncherDamageErr::NotGrenadeLauncher); + } + let blast_radius = self + .stats + .get(&StatHashes::BLAST_RADIUS.into()) + .ok_or(GrenadeLauncherDamageErr::BlastRadiusMissing)? + .perk_val() + .clamp(0, 100); + + const RAPID_FRAME: u32 = 902; + const ADAPTIVE_FRAME: u32 = 903; + const LW_FRAME: u32 = 905; + const DOUBLE_FIRE: u32 = 907; + const WAVE_FRAME: u32 = 908; + + let (impact_m, impact_b, explosion_m, explosion_b) = + match (self.intrinsic_hash, blast_radius) { + (RAPID_FRAME, 0..=9) => (-0.4030011045, 68.48685607, 0.3999973161, 156.0004464), + (RAPID_FRAME, 10..=100) => (-1.615571887, 80.60595314, 4.000030486, 120.0001854), + (ADAPTIVE_FRAME, 0..=9) => (-1.2613, 100.7461331, 2.749664189, 150.0067162), + (ADAPTIVE_FRAME, 10..=100) => (-0.5032, 85.58849794, 0.5000, 195.000131), + (LW_FRAME, 0..=100) => (-0.6036133049, 100.6574848823, 0.6000, 100.0001838), + (DOUBLE_FIRE, 0..=100) => (-0.35029693, 58.59289171, 0.31799723, 53.00051995), + (WAVE_FRAME|2733244971, 0..=100) => (-0.590953431, 99.132, 0.0, 130.00025), + _ => return Err(GrenadeLauncherDamageErr::NotImplemented), + }; + + let impact_damge = impact_m * blast_radius as f64 + impact_b; + let explosive_damage = explosion_m * blast_radius as f64 + explosion_b; + Ok((impact_damge, explosive_damage)) + } +} + impl Weapon { - pub fn get_damage_profile(&self) -> (f64, f64, f64, f64) { + pub fn get_damage_profile( + &self, + ) -> (ImpactDamage, ExplosiveDamage, CritMultiplier, DamageDelay) { let impact; let mut explosion = 0.0_f64; let mut crit = 1.0_f64; let delay; + if self.weapon_type == WeaponType::GRENADELAUNCHER { + let (impact_damage, explosive_damage) = self.get_grenade_launcher_damage().unwrap(); + return (impact_damage, explosive_damage,1.0,0.0); + } let epr = get_explosion_data(self.list_perks(), &self.static_calc_input(), false); if epr.percent <= 0.0 { impact = self.firing_data.damage;