386 lines
13 KiB
Rust
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);
|
|
}
|