proxisim/src/passives.rs

386 lines
13 KiB
Rust

use bevy_ecs::prelude::*;
use proxisim_models::bundle::{
armour::PlayerArmour,
passive::{DrugAddiction, DrugCooldown, Education, FactionUpgrades, Job, Merits},
player::ActionNullification,
stat::{
AdditiveBonus, CritRate, Defence, Dexterity, MaxHealth, SimpleStatBonus, Speed, Strength,
},
};
use crate::{
Stages,
effect::Effects,
player::status_effect::{
ExtraStatusEffectDuration, ExtraStatusEffectEffectiveness, Hardened, Hastened, Sharpened,
Strengthened,
},
};
fn spawn_permanent_effects(
merit_q: Query<(
Entity,
&Merits,
&Education,
&FactionUpgrades,
Option<&DrugCooldown>,
Option<&DrugAddiction>,
Option<&Job>,
&PlayerArmour,
)>,
mut effects: Effects,
mut commands: Commands,
) {
for (player, merits, edu, faction, drug_cd, addiction, job, armour) in merit_q.iter() {
if merits.brawn > 0 {
effects.spawn(
AdditiveBonus::<Strength>::new("brawn", (merits.brawn as f32) * 0.03),
player,
);
}
if merits.protection > 0 {
effects.spawn(
AdditiveBonus::<Defence>::new("protection", (merits.protection as f32) * 0.03),
player,
);
}
if merits.sharpness > 0 {
effects.spawn(
AdditiveBonus::<Speed>::new("sharpness", (merits.sharpness as f32) * 0.03),
player,
);
}
if merits.evasion > 0 {
effects.spawn(
AdditiveBonus::<Dexterity>::new("evasion", (merits.evasion as f32) * 0.03),
player,
);
}
if merits.crits > 0 {
effects.spawn(
SimpleStatBonus::<CritRate>::new("merits", merits.crits),
player,
);
}
if merits.life > 0 {
effects.spawn(
SimpleStatBonus::<MaxHealth>::new("merits", (merits.life as f32) * 0.05 + 1.0),
player,
);
}
if faction.spd > 0 {
effects.spawn(
AdditiveBonus::<Speed>::new("faction", (faction.spd as f32) * 0.01),
player,
);
}
if faction.str > 0 {
effects.spawn(
AdditiveBonus::<Strength>::new("faction", (faction.str as f32) * 0.01),
player,
);
}
if faction.def > 0 {
effects.spawn(
AdditiveBonus::<Defence>::new("faction", (faction.def as f32) * 0.01),
player,
);
}
if faction.dex > 0 {
effects.spawn(
AdditiveBonus::<Dexterity>::new("faction", (faction.dex as f32) * 0.01),
player,
);
}
if faction.life > 0 {
effects.spawn(
SimpleStatBonus::<MaxHealth>::new("faction", (faction.life as f32) * 0.01 + 1.0),
player,
);
}
#[allow(clippy::too_many_arguments)]
fn spawn_drug_bonuses(
label: &'static str,
player: Entity,
effects: &mut Effects,
str: f32,
def: f32,
spd: f32,
dex: f32,
mit: f32,
) {
fn mitigate(val: f32, mit: f32) -> f32 {
if val.is_sign_negative() {
// NOTE: The rounding here is pure speculation
(val * mit).floor() / 100.0
} else {
val / 100.0
}
}
effects.spawn(
AdditiveBonus::<Strength>::new(label, mitigate(str, mit)),
player,
);
effects.spawn(
AdditiveBonus::<Defence>::new(label, mitigate(def, mit)),
player,
);
effects.spawn(
AdditiveBonus::<Speed>::new(label, mitigate(spd, mit)),
player,
);
effects.spawn(
AdditiveBonus::<Dexterity>::new(label, mitigate(dex, mit)),
player,
);
}
let mit = 1.0 - (faction.side_effects as f32) * 0.03;
match drug_cd {
Some(DrugCooldown::Xanax) => {
spawn_drug_bonuses(
"xanax",
player,
&mut effects,
-35.0,
-35.0,
-35.0,
-35.0,
mit,
);
}
Some(DrugCooldown::Vicodin) => {
spawn_drug_bonuses("vicodin", player, &mut effects, 25.0, 25.0, 25.0, 25.0, mit);
}
_ => (),
}
if let Some(addiction) = addiction {
effects.spawn(
AdditiveBonus::<Strength>::new("addiction", -0.01 * addiction.level as f32),
player,
);
effects.spawn(
AdditiveBonus::<Speed>::new("addiction", -0.01 * addiction.level as f32),
player,
);
effects.spawn(
AdditiveBonus::<Defence>::new("addiction", -0.01 * addiction.level as f32),
player,
);
effects.spawn(
AdditiveBonus::<Dexterity>::new("addiction", -0.01 * addiction.level as f32),
player,
);
}
let mut epi_eff = 1.0;
let mut mela_eff = 1.0;
let mut sero_eff = 1.0;
let mut tyro_eff = 1.0;
let mut epi_dur = 1.0;
let mut sero_dur = 1.0;
let mut tyro_dur = 1.0;
if edu.bio2410 {
effects.spawn(SimpleStatBonus::<CritRate>::new("BIO2410", 6), player);
}
if edu.cbt2790 {
effects.spawn(AdditiveBonus::<Speed>::new("CBT2790", 0.01), player);
}
if edu.haf2104 {
effects.spawn(AdditiveBonus::<Dexterity>::new("HAF2104", 0.01), player);
}
if edu.haf2105 {
effects.spawn(AdditiveBonus::<Speed>::new("HAF2105", 0.01), player);
}
if edu.haf2106 {
effects.spawn(AdditiveBonus::<Strength>::new("HAF2106", 0.01), player);
}
if edu.haf2107 {
effects.spawn(AdditiveBonus::<Strength>::new("HAF2107", 0.02), player);
}
if edu.haf2108 {
effects.spawn(AdditiveBonus::<Dexterity>::new("HAF2108", 0.01), player);
}
if edu.haf2109 {
effects.spawn(AdditiveBonus::<Speed>::new("HAF2109", 0.03), player);
}
if edu.mth2240 {
effects.spawn(AdditiveBonus::<Speed>::new("MTH2240", 0.01), player);
}
if edu.mth2250 {
effects.spawn(AdditiveBonus::<Speed>::new("MTH2250", 0.01), player);
}
if edu.mth2260 {
effects.spawn(AdditiveBonus::<Defence>::new("MTH2260", 0.01), player);
}
if edu.mth2320 {
effects.spawn(AdditiveBonus::<Defence>::new("MTH2320", 0.02), player);
}
if edu.psy2640 {
effects.spawn(AdditiveBonus::<Dexterity>::new("PSY2640", 0.01), player);
}
if edu.psy2650 {
effects.spawn(AdditiveBonus::<Dexterity>::new("PSY2650", 0.02), player);
}
if edu.psy2660 {
effects.spawn(AdditiveBonus::<Dexterity>::new("PSY2660", 0.04), player);
}
if edu.psy2670 {
effects.spawn(AdditiveBonus::<Dexterity>::new("PSY2670", 0.08), player);
}
if edu.def2710 {
effects.spawn(AdditiveBonus::<Defence>::new("DEF2710", 0.01), player);
}
if edu.def2730 {
effects.spawn(AdditiveBonus::<Defence>::new("DEF2730", 0.02), player);
}
if edu.def2740 {
effects.spawn(AdditiveBonus::<Defence>::new("DEF2740", 0.03), player);
}
if edu.def2750 {
effects.spawn(AdditiveBonus::<Speed>::new("DEF2750", 0.02), player);
}
if edu.def2760 {
effects.spawn(AdditiveBonus::<Speed>::new("DEF2760", 0.03), player);
}
if edu.spt2480 {
epi_eff *= 1.1;
mela_eff *= 1.1;
sero_eff *= 1.1;
tyro_eff *= 1.1;
/* commands.entity(player).insert((
ExtraStatusEffectEffectiveness::<1, Strengthened>::new(1.1),
ExtraStatusEffectEffectiveness::<1, Sharpened>::new(1.1),
ExtraStatusEffectEffectiveness::<1, Hardened>::new(1.1),
ExtraStatusEffectEffectiveness::<1, Hastened>::new(1.1),
)); */
}
if edu.spt2490 {
effects.spawn(AdditiveBonus::<Speed>::new("SPT2490", 0.02), player);
effects.spawn(AdditiveBonus::<Strength>::new("SPT2490", 0.02), player);
}
if edu.spt2500 {
effects.spawn(AdditiveBonus::<Defence>::new("SPT2500", 0.02), player);
effects.spawn(AdditiveBonus::<Dexterity>::new("SPT2500", 0.02), player);
}
if let Some(job) = job {
if job.has(Job::AmusementPark7) {
epi_eff *= 1.25;
epi_dur *= 1.25;
}
if job.has(Job::ClothingStore5) {
effects.spawn(
AdditiveBonus::<Dexterity>::new("clothing_store", 0.25),
player,
);
}
if job.has(Job::FurnitureStore7) {
effects.spawn(
AdditiveBonus::<Strength>::new("furniture_store", 0.25),
player,
);
}
if job.has(Job::GasStation3) {
effects.spawn(AdditiveBonus::<Speed>::new("gas_station", 0.25), player);
}
if job.has(Job::GentsStripClub3) {
effects.spawn(
AdditiveBonus::<Dexterity>::new("gents_strip_club", 0.25),
player,
);
}
if job.has(Job::GentsStripClub5) {
tyro_eff *= 1.5;
tyro_dur *= 1.5;
}
if job.has(Job::GentsStripClub10) {
commands
.entity(player)
.with_child(ActionNullification::GentsStripClub);
}
if job.has(Job::LadiesStripClub3) {
effects.spawn(
AdditiveBonus::<Defence>::new("ladies_strip_club", 0.25),
player,
);
}
if job.has(Job::LadiesStripClub5) {
sero_eff *= 1.5;
sero_dur *= 1.5;
}
if job.has(Job::LingeryStore5) && armour.into_iter().count() == 0 {
effects.spawn(
AdditiveBonus::<Dexterity>::new("lingery_store", 0.50),
player,
);
effects.spawn(AdditiveBonus::<Speed>::new("lingery_store", 0.50), player);
}
if job.has(Job::MiningCorporation7) {
effects.spawn(
SimpleStatBonus::<MaxHealth>::new("mining_corporation", 1.1),
player,
);
}
if job.has(Job::MusicStore10) {
effects.spawn(AdditiveBonus::<Strength>::new("music_store", 0.15), player);
effects.spawn(AdditiveBonus::<Speed>::new("music_store", 0.15), player);
effects.spawn(AdditiveBonus::<Defence>::new("music_store", 0.15), player);
effects.spawn(AdditiveBonus::<Dexterity>::new("music_store", 0.15), player);
}
}
if epi_eff >= 1.0 {
commands
.entity(player)
.insert(ExtraStatusEffectEffectiveness::<1, Strengthened>::new(
epi_eff,
));
}
if epi_dur >= 1.0 {
commands
.entity(player)
.insert(ExtraStatusEffectDuration::<1, Strengthened>::new(epi_dur));
}
if mela_eff >= 1.0 {
commands
.entity(player)
.insert(ExtraStatusEffectEffectiveness::<1, Hastened>::new(mela_eff));
}
if sero_eff >= 1.0 {
commands
.entity(player)
.insert(ExtraStatusEffectEffectiveness::<1, Hardened>::new(sero_eff));
}
if sero_dur >= 1.0 {
commands
.entity(player)
.insert(ExtraStatusEffectDuration::<1, Hardened>::new(sero_dur));
}
if tyro_eff >= 1.0 {
commands
.entity(player)
.insert(ExtraStatusEffectEffectiveness::<1, Sharpened>::new(
tyro_eff,
));
}
if tyro_dur >= 1.0 {
commands
.entity(player)
.insert(ExtraStatusEffectDuration::<1, Sharpened>::new(tyro_dur));
}
}
}
pub(crate) fn configure(stages: &mut Stages) {
stages.equip.add_systems(spawn_permanent_effects);
}