From f7428e317d282856d05ffc37b6ba474c5e9973ce Mon Sep 17 00:00:00 2001 From: Alexander Foremny Date: Sun, 24 Mar 2024 14:32:01 +0100 Subject: feat: damage types --- src/shared/ability.rs | 11 ++++++----- src/shared/champion.rs | 45 ++++++++++++++++++++++++++++++++------------- src/shared/damage.rs | 37 +++++++++++++++++++++++++++++++++++++ src/shared/projectile.rs | 3 ++- src/shared/stats.rs | 2 ++ 5 files changed, 79 insertions(+), 19 deletions(-) create mode 100644 src/shared/damage.rs (limited to 'src/shared') diff --git a/src/shared/ability.rs b/src/shared/ability.rs index 4723e59..a9387f3 100644 --- a/src/shared/ability.rs +++ b/src/shared/ability.rs @@ -1,6 +1,7 @@ use crate::server::entity_map::*; use crate::shared::area_of_effect::*; use crate::shared::buffs::*; +use crate::shared::damage::*; use crate::shared::player::*; use crate::shared::projectile::*; use crate::shared::shape::*; @@ -24,12 +25,12 @@ pub enum TargetedAbility { #[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct MeeleAttack { - pub damage: f32, + pub damage: Damage, } #[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct RangedAttack { - pub damage: f32, + pub damage: Damage, } impl TargetedAbility { @@ -189,7 +190,7 @@ pub enum DirectionalAbility { #[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct Dash { pub max_distance: f32, - pub damage: f32, + pub damage: Damage, } #[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] @@ -200,13 +201,13 @@ pub struct Flash { #[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct Pull { pub max_distance: f32, - pub damage: f32, + pub damage: Damage, } #[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct Spear { pub max_distance: f32, - pub damage: f32, + pub damage: Damage, } // `direction: Vec2` is NOT normalized (cf. `Flash`)! diff --git a/src/shared/champion.rs b/src/shared/champion.rs index 64fc32e..c082ba3 100644 --- a/src/shared/champion.rs +++ b/src/shared/champion.rs @@ -1,4 +1,5 @@ use crate::shared::ability::*; +use crate::shared::damage::*; use crate::shared::shape::*; use crate::shared::stats::*; use crate::shared::*; @@ -43,30 +44,40 @@ impl Champion { attack_speed: 0.75, max_health: 150., movement_speed: 75., + armor: 100., + magic_resist: 100., }), Champion::Ranged => BaseStats(Stats { attack_range: 50., attack_speed: 1.5, max_health: 100., movement_speed: 85., + armor: 50., + magic_resist: 50., }), Champion::Tower => BaseStats(Stats { attack_range: 100., attack_speed: 4.5, max_health: 500., movement_speed: 0., + armor: 0., + magic_resist: 0., }), Champion::Minion => BaseStats(Stats { attack_range: 30., attack_speed: 1., max_health: 50., movement_speed: 60., + armor: 0., + magic_resist: 0., }), Champion::Nexus => BaseStats(Stats { attack_range: 0., attack_speed: 0., max_health: 2000., movement_speed: 0., + armor: 0., + magic_resist: 0., }), } } @@ -80,27 +91,29 @@ impl Champion { })), AbilitySlot::W => Ability::Directional(DirectionalAbility::Dash(Dash { max_distance: 60., - damage: 15., + damage: Damage::Physical(30.), })), AbilitySlot::E => Ability::Directional(DirectionalAbility::Pull(Pull { max_distance: 60., - damage: 10., + damage: Damage::Physical(20.), + })), + AbilitySlot::R => Ability::Targeted(TargetedAbility::MeeleAttack(MeeleAttack { + damage: Damage::True(65.), })), - AbilitySlot::R => { - Ability::Targeted(TargetedAbility::MeeleAttack(MeeleAttack { damage: 45. })) - } AbilitySlot::F => { Ability::Directional(DirectionalAbility::Flash(Flash { max_distance: 100. })) } AbilitySlot::G => { Ability::Activated(ActivatedAbility::Speed(Speed { duration: 2.5 })) } - _ => Ability::Targeted(TargetedAbility::MeeleAttack(MeeleAttack { damage: 5. })), + _ => Ability::Targeted(TargetedAbility::MeeleAttack(MeeleAttack { + damage: Damage::Physical(10.), + })), }, Champion::Ranged => match ability_slot { AbilitySlot::E => Ability::Directional(DirectionalAbility::Spear(Spear { max_distance: 250., - damage: 25., + damage: Damage::Physical(50.), })), AbilitySlot::R => { Ability::Activated(ActivatedAbility::Focus(Focus { duration: 5. })) @@ -111,18 +124,24 @@ impl Champion { AbilitySlot::G => { Ability::Activated(ActivatedAbility::Speed(Speed { duration: 2.5 })) } - _ => Ability::Targeted(TargetedAbility::RangedAttack(RangedAttack { damage: 8. })), + _ => Ability::Targeted(TargetedAbility::RangedAttack(RangedAttack { + damage: Damage::Physical(15.), + })), }, Champion::Tower => match ability_slot { - _ => { - Ability::Targeted(TargetedAbility::RangedAttack(RangedAttack { damage: 100. })) - } + _ => Ability::Targeted(TargetedAbility::RangedAttack(RangedAttack { + damage: Damage::Physical(100.), + })), }, Champion::Minion => match ability_slot { - _ => Ability::Targeted(TargetedAbility::RangedAttack(RangedAttack { damage: 2. })), + _ => Ability::Targeted(TargetedAbility::RangedAttack(RangedAttack { + damage: Damage::Physical(5.), + })), }, Champion::Nexus => match ability_slot { - _ => Ability::Targeted(TargetedAbility::MeeleAttack(MeeleAttack { damage: 0. })), + _ => Ability::Targeted(TargetedAbility::MeeleAttack(MeeleAttack { + damage: Damage::Physical(0.), + })), }, } } diff --git a/src/shared/damage.rs b/src/shared/damage.rs new file mode 100644 index 0000000..c336d87 --- /dev/null +++ b/src/shared/damage.rs @@ -0,0 +1,37 @@ +use crate::shared::stats::*; +use crate::shared::*; + +#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)] +pub enum Damage { + Magical(f32), + Physical(f32), + True(f32), +} + +impl Damage { + pub fn apply(self, stats: Stats) -> f32 { + match self { + Damage::Magical(magical_damage) => { + magical_damage * damage_multiplier(stats.magic_resist) + } + Damage::Physical(physical_damage) => physical_damage * damage_multiplier(stats.armor), + Damage::True(true_damage) => true_damage, + } + } + + pub fn scale(self, factor: f32) -> Self { + match self { + Damage::Magical(magical_damage) => Damage::Magical(magical_damage * factor), + Damage::Physical(physical_damage) => Damage::Physical(physical_damage * factor), + Damage::True(true_damage) => Damage::True(true_damage * factor), + } + } +} + +fn damage_multiplier(resistance: f32) -> f32 { + if resistance >= 0. { + 100. / (100. + resistance) + } else { + 2. - 100. / (100. - resistance) + } +} diff --git a/src/shared/projectile.rs b/src/shared/projectile.rs index f9fb592..5da0526 100644 --- a/src/shared/projectile.rs +++ b/src/shared/projectile.rs @@ -1,3 +1,4 @@ +use crate::shared::damage::*; use crate::shared::player::*; use crate::shared::*; @@ -24,7 +25,7 @@ impl ProjectileBundle { pub struct Projectile { pub type_: ProjectileType, pub source_player: PlayerId, - pub damage: f32, + pub damage: Damage, } #[derive(Component, Message, Serialize, Deserialize, Clone, Debug, PartialEq)] diff --git a/src/shared/stats.rs b/src/shared/stats.rs index 239405e..98c26aa 100644 --- a/src/shared/stats.rs +++ b/src/shared/stats.rs @@ -6,6 +6,8 @@ pub struct Stats { pub attack_speed: f32, pub max_health: f32, pub movement_speed: f32, + pub armor: f32, + pub magic_resist: f32, } #[derive(Component, Message, Clone, Copy, Serialize, Deserialize, PartialEq, Debug)] -- cgit v1.2.3