use bevy_ecs::{bundle::Bundle, component::Component}; use strum::Display; use crate::bundle::player::BodyPart; #[derive(Component, Debug, Clone, Copy)] #[cfg_attr(feature = "json", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "json", serde(rename_all = "snake_case"))] pub enum WeaponBonusType { // Weapon passives Berserk, Conserve, Expose, Grace, Powerful, Specialist, // Turn triggered passives Empower, Quicken, // First turn effects Assassinate, // Additive status effects triggered by damaging hits Cripple, Demoralise, Freeze, Motivate, Slow, Toxin, Weaken, Wither, // DOT status effects Bleed, Burning, Lacerate, Poison, SevereBurning, // Other status effects Eviscerate, Paralyse, Schock, Stun, // Multi attack bonuses Blindfire, Fury, DoubleTap, Rage, // Body part multipliers Achilles, Crusher, Cupid, Deadeye, Roshambo, Throttle, // Attack nullification types Homerun, Parry, // Armour mitigation Puncture, Penetrate, // Misc Execute, Deadly, Bloodlust, DoubleEdged, Blindside, Comeback, } #[derive(Component)] pub struct BonusValue(pub f32); #[derive(Bundle)] pub struct WeaponBonusBundle { pub bonus: WeaponBonusType, pub value: BonusValue, } impl WeaponBonusBundle { pub fn new(bonus: WeaponBonusType, value: f32) -> Self { Self { bonus, value: BonusValue(value), } } } #[derive(Clone, Copy)] pub enum TurnTriggeredBonus { Empower, Quicken, } #[derive(Clone, Copy)] pub enum FirstTurnBonus { Assassinate, } #[derive(Clone, Copy)] pub enum MultiTurnBonus { Blindfire, Fury, DoubleTap, Rage, } impl MultiTurnBonus { #[inline(always)] pub fn counter_label(self) -> &'static str { match self { Self::Blindfire => "proc_blindfire", Self::Fury => "proc_fury", Self::DoubleTap => "proc_double_tap", Self::Rage => "proc_rage", } } } #[derive(Clone, Copy)] pub enum OpponentStatusEffect { Cripple, // TODO: implement for group fights Demoralise, Freeze, Slow, Toxin, Weaken, Wither, } #[derive(Clone, Copy)] pub enum SelfStatusEffect { Motivate, } #[derive(Clone, Copy)] pub enum BonusPartDamageBonus { Achilles, Crusher, Cupid, Deadeye, Roshambo, Throttle, } impl BonusPartDamageBonus { pub fn dmg_bonus(self, part: BodyPart, value: f32) -> Option { match self { Self::Achilles => match part { BodyPart::LeftFoot | BodyPart::RightFoot => Some(value), _ => None, }, Self::Crusher => { if part == BodyPart::Head { Some(value) } else { None } } Self::Cupid => { if part == BodyPart::Heart { Some(value) } else { None } } Self::Deadeye => match part { BodyPart::Head | BodyPart::Heart | BodyPart::Throat => Some(value), _ => None, }, Self::Roshambo => { if part == BodyPart::Groin { Some(value) } else { None } } Self::Throttle => { if part == BodyPart::Throat { Some(value) } else { None } } } } } #[derive(Debug, Clone, Component)] pub enum ArmourBypassBonus { Puncture { chance: f32 }, Penetrate { mitigation: f32 }, } #[derive(Debug, Clone, Component)] pub enum MiscBonus { Blindside { bonus: f32 }, Comeback { bonus: f32 }, Deadly { chance: f64 }, DoubleEdged { chance: f64 }, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Component, Display)] #[cfg_attr(feature = "json", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "json", serde(rename_all = "snake_case"))] pub enum ArmourBonusType { Impregnable, Impenetrable, Insurmountable, Invulnerable, Imperviable, Immmutable, Irrepressible, Kinetokinesis, Impassable, } #[derive(Clone, Copy, Debug, Component, Display)] pub enum DamageMitigationBonus { Impregnable { mitigation: f32, }, Impenetrable { mitigation: f32, }, Insurmountable { mitigation: f32, }, Impassable { chance: f32, }, Kinetokinesis { mitigation: f32, }, ActiveKinetokinesis { mitigation: f32, remaining_turns: u16, }, }