From 5c7705f874fccccc4ca16f2b7d1d7a2c7b7ec48b Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 24 Dec 2020 12:54:00 -0500 Subject: [PATCH] Staff skill tree. --- .../items/debug/cultist_purp_2h_boss-0.ron | 2 +- .../common/skill_trees/skill_max_levels.ron | 12 +++ .../skill_trees/skill_prerequisites.ron | 10 +++ .../skills_skill-groups_manifest.ron | 12 +++ client/src/lib.rs | 65 ++++++++++++++ common/src/combat.rs | 10 +++ common/src/comp/ability.rs | 84 +++++++++++++++++-- common/src/comp/projectile.rs | 62 +++++++++++++- common/src/comp/skills.rs | 15 ++++ common/src/states/utils.rs | 11 ++- 10 files changed, 272 insertions(+), 11 deletions(-) diff --git a/assets/common/items/debug/cultist_purp_2h_boss-0.ron b/assets/common/items/debug/cultist_purp_2h_boss-0.ron index d53c82b1ff..760a44acbd 100644 --- a/assets/common/items/debug/cultist_purp_2h_boss-0.ron +++ b/assets/common/items/debug/cultist_purp_2h_boss-0.ron @@ -3,7 +3,7 @@ ItemDef( description: "Shouldn't this be a hammer?", kind: Tool( ( - kind: Bow, + kind: Staff, stats: ( equip_time_millis: 0, power: 1000.0, diff --git a/assets/common/skill_trees/skill_max_levels.ron b/assets/common/skill_trees/skill_max_levels.ron index 81c0683d41..add2842774 100644 --- a/assets/common/skill_trees/skill_max_levels.ron +++ b/assets/common/skill_trees/skill_max_levels.ron @@ -46,4 +46,16 @@ Bow(RDamage): Some(2), Bow(RArrows): Some(2), Bow(RCost): Some(2), + Staff(BDamage): Some(3), + Staff(BRegen): Some(2), + Staff(BRadius): Some(2), + Staff(FRange): Some(2), + Staff(FDamage): Some(3), + Staff(FDrain): Some(2), + Staff(FVelocity): Some(2), + Staff(UnlockShockwave): Some(2), + Staff(SDamage): Some(2), + Staff(SKnockback): Some(2), + Staff(SRange): Some(2), + Staff(SCost): Some(2), }) \ No newline at end of file diff --git a/assets/common/skill_trees/skill_prerequisites.ron b/assets/common/skill_trees/skill_prerequisites.ron index 8c7a67a594..fa00788b4e 100644 --- a/assets/common/skill_trees/skill_prerequisites.ron +++ b/assets/common/skill_trees/skill_prerequisites.ron @@ -49,4 +49,14 @@ Bow(RLeap): {Bow(UnlockRepeater): None}, Bow(RArrows): {Bow(UnlockRepeater): None}, Bow(RCost): {Bow(UnlockRepeater): None}, + Staff(BDamage): {Staff(BExplosion): None}, + Staff(BRegen): {Staff(BExplosion): None}, + Staff(BRadius): {Staff(BExplosion): None}, + Staff(FRange): {Staff(FDamage): Some(1)}, + Staff(FDrain): {Staff(FDamage): Some(1)}, + Staff(FVelocity): {Staff(FDamage): Some(1)}, + Staff(SDamage): {Staff(UnlockShockwave): None}, + Staff(SKnockback): {Staff(UnlockShockwave): None}, + Staff(SRange): {Staff(UnlockShockwave): None}, + Staff(SCost): {Staff(UnlockShockwave): None}, }) \ No newline at end of file diff --git a/assets/common/skill_trees/skills_skill-groups_manifest.ron b/assets/common/skill_trees/skills_skill-groups_manifest.ron index ba72a766ee..56dcb5b029 100644 --- a/assets/common/skill_trees/skills_skill-groups_manifest.ron +++ b/assets/common/skill_trees/skills_skill-groups_manifest.ron @@ -75,7 +75,19 @@ Bow(RCost), ], Weapon(Staff): [ + Staff(BExplosion), + Staff(BDamage), + Staff(BRegen), + Staff(BRadius), + Staff(FDamage), + Staff(FRange), + Staff(FDrain), + Staff(FVelocity), Staff(UnlockShockwave), + Staff(SDamage), + Staff(SKnockback), + Staff(SRange), + Staff(SCost), ], Weapon(Sceptre): [ Sceptre(Unlock404), diff --git a/client/src/lib.rs b/client/src/lib.rs index d19453c464..4ba7e69c6d 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1249,6 +1249,71 @@ impl Client { SkillGroupType::Weapon(Staff), ))); }, + "@unlock staff fireball" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::BExplosion, + ))); + }, + "@unlock staff fireball damage" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::BDamage, + ))); + }, + "@unlock staff fireball regen" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::BRegen, + ))); + }, + "@unlock staff fireball radius" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::BRadius, + ))); + }, + "@unlock staff beam damage" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::FDamage, + ))); + }, + "@unlock staff beam range" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::FRange, + ))); + }, + "@unlock staff beam drain" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::FDrain, + ))); + }, + "@unlock staff beam velocity" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::FVelocity, + ))); + }, + "@unlock staff shockwave" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::UnlockShockwave, + ))); + }, + "@unlock staff shockwave damage" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::SDamage, + ))); + }, + "@unlock staff shockwave knockback" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::SKnockback, + ))); + }, + "@unlock staff shockwave range" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::SRange, + ))); + }, + "@unlock staff shockwave cost" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff( + StaffSkill::SCost, + ))); + }, "@unlock sceptre" => { self.send_msg(ClientGeneral::UnlockSkill(Skill::UnlockGroup( SkillGroupType::Weapon(Sceptre), diff --git a/common/src/combat.rs b/common/src/combat.rs index 8cb01feba9..4add6e89f9 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -195,6 +195,16 @@ impl Knockback { }, } } + + pub fn modify_strength(mut self, power: f32) -> Self { + use Knockback::*; + match self { + Away(ref mut f) | Towards(ref mut f) | Up(ref mut f) | TowardsUp(ref mut f) => { + *f *= power; + }, + } + self + } } pub fn get_weapons(inv: &Inventory) -> (Option, Option) { diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index ae7787486c..a8d9f9a2f4 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -336,7 +336,7 @@ impl CharacterAbility { } => { *buildup_duration = (*buildup_duration as f32 / speed) as u64; *recover_duration = (*recover_duration as f32 / speed) as u64; - *projectile = projectile.modified_projectile(power, 1_f32); + *projectile = projectile.modified_projectile(power, 1_f32, 1_f32); }, RepeaterRanged { ref mut movement_duration, @@ -350,7 +350,7 @@ impl CharacterAbility { *buildup_duration = (*buildup_duration as f32 / speed) as u64; *shoot_duration = (*shoot_duration as f32 / speed) as u64; *recover_duration = (*recover_duration as f32 / speed) as u64; - *projectile = projectile.modified_projectile(power, 1_f32); + *projectile = projectile.modified_projectile(power, 1_f32, 1_f32); }, Boost { ref mut movement_duration, @@ -493,7 +493,7 @@ impl CharacterAbility { | ChargedRanged { energy_cost, .. } | Shockwave { energy_cost, .. } | BasicBeam { energy_cost, .. } => *energy_cost, - _ => 0, + BasicBlock | Boost { .. } | ComboMelee { .. } => 0, } } @@ -829,7 +829,7 @@ impl CharacterAbility { skills.get(&Bow(BRegen)).copied().flatten().unwrap_or(0); let power = 1.3_f32.powi(damage_level.into()); let regen = 1.5_f32.powi(regen_level.into()); - *projectile = projectile.modified_projectile(power, regen); + *projectile = projectile.modified_projectile(power, regen, 1_f32); } }, ChargedRanged { @@ -879,7 +879,7 @@ impl CharacterAbility { } if let Some(level) = skills.get(&Bow(RDamage)).copied().flatten() { let power = 1.3_f32.powi(level.into()); - *projectile = projectile.modified_projectile(power, 1_f32); + *projectile = projectile.modified_projectile(power, 1_f32, 1_f32); } if !skills.contains_key(&Bow(RLeap)) { *leap = None; @@ -895,6 +895,80 @@ impl CharacterAbility { _ => {}, } }, + ToolKind::Staff => { + use skills::StaffSkill::*; + match self { + BasicRanged { + ref mut projectile, .. + } => { + if !skills.contains_key(&Staff(BExplosion)) { + *projectile = projectile.fireball_to_firebolt(); + } + { + let damage_level = + skills.get(&Staff(BDamage)).copied().flatten().unwrap_or(0); + let regen_level = + skills.get(&Staff(BRegen)).copied().flatten().unwrap_or(0); + let range_level = + skills.get(&Staff(BRadius)).copied().flatten().unwrap_or(0); + let power = 1.2_f32.powi(damage_level.into()); + let regen = 1.2_f32.powi(regen_level.into()); + let range = 1.1_f32.powi(range_level.into()); + *projectile = projectile.modified_projectile(power, regen, range); + } + }, + BasicBeam { + ref mut base_dps, + ref mut range, + ref mut energy_drain, + ref mut beam_duration, + .. + } => { + if let Some(level) = skills.get(&Staff(FDamage)).copied().flatten() { + *base_dps = (*base_dps as f32 * 1.3_f32.powi(level.into())) as u32; + } + if let Some(level) = skills.get(&Staff(FRange)).copied().flatten() { + *range *= 1.25_f32.powi(level.into()); + // Duration modified to keep velocity constant + *beam_duration = + (*beam_duration as f32 * 1.4_f32.powi(level.into())) as u64; + } + if let Some(level) = skills.get(&Staff(FDrain)).copied().flatten() { + *energy_drain = + (*energy_drain as f32 * 0.8_f32.powi(level.into())) as u32; + } + if let Some(level) = skills.get(&Staff(FVelocity)).copied().flatten() { + let velocity_increase = 1.25_f32.powi(level.into()); + let duration_mod = 1.0 / (1.0 + velocity_increase); + *beam_duration = (*beam_duration as f32 * duration_mod) as u64; + } + }, + Shockwave { + ref mut damage, + ref mut knockback, + ref mut shockwave_duration, + ref mut energy_cost, + .. + } => { + if let Some(level) = skills.get(&Staff(SDamage)).copied().flatten() { + *damage = (*damage as f32 * 1.3_f32.powi(level.into())) as u32; + } + if let Some(level) = skills.get(&Staff(SKnockback)).copied().flatten() { + *knockback = knockback.modify_strength(1.3_f32.powi(level.into())); + } + if let Some(level) = skills.get(&Staff(SRange)).copied().flatten() { + *shockwave_duration = (*shockwave_duration as f32 + * 1.2_f32.powi(level.into())) + as u64; + } + if let Some(level) = skills.get(&Staff(SCost)).copied().flatten() { + *energy_cost = + (*energy_cost as f32 * 0.8_f32.powi(level.into())) as u32; + } + }, + _ => {}, + } + }, _ => {}, } } diff --git a/common/src/comp/projectile.rs b/common/src/comp/projectile.rs index d0239718b4..2f458a4fca 100644 --- a/common/src/comp/projectile.rs +++ b/common/src/comp/projectile.rs @@ -53,6 +53,10 @@ pub enum ProjectileConstructor { radius: f32, energy_regen: u32, }, + Firebolt { + damage: f32, + energy_regen: u32, + }, Heal { heal: f32, damage: f32, @@ -134,7 +138,24 @@ impl ProjectileConstructor { }), Effect::Vanish, ], - time_left: Duration::from_secs(20), + time_left: Duration::from_secs(10), + owner, + ignore_group: true, + }, + Firebolt { + damage, + energy_regen, + } => Projectile { + hit_solid: vec![Effect::Vanish], + hit_entity: vec![ + Effect::Damage(Some(GroupTarget::OutOfGroup), Damage { + source: DamageSource::Energy, + value: damage, + }), + Effect::RewardEnergy(energy_regen), + Effect::Vanish, + ], + time_left: Duration::from_secs(10), owner, ignore_group: true, }, @@ -189,7 +210,7 @@ impl ProjectileConstructor { }), Effect::Vanish, ], - time_left: Duration::from_secs(20), + time_left: Duration::from_secs(10), owner, ignore_group: true, }, @@ -203,7 +224,7 @@ impl ProjectileConstructor { } } - pub fn modified_projectile(mut self, power: f32, regen: f32) -> Self { + pub fn modified_projectile(mut self, power: f32, regen: f32, range: f32) -> Self { use ProjectileConstructor::*; match self { Arrow { @@ -214,19 +235,52 @@ impl ProjectileConstructor { *damage *= power; *energy_regen = (*energy_regen as f32 * regen) as u32; }, - Fireball { ref mut damage, .. } => { + Fireball { + ref mut damage, + ref mut energy_regen, + ref mut radius, + .. + } => { *damage *= power; + *energy_regen = (*energy_regen as f32 * regen) as u32; + *radius *= range; + }, + Firebolt { + ref mut damage, + ref mut energy_regen, + .. + } => { + *damage *= power; + *energy_regen = (*energy_regen as f32 * regen) as u32; }, Heal { ref mut damage, ref mut heal, + ref mut radius, .. } => { *damage *= power; *heal *= power; + *radius *= range; }, Possess => {}, } self } + + pub fn fireball_to_firebolt(self) -> Self { + if let ProjectileConstructor::Fireball { + damage, + energy_regen, + .. + } = self + { + ProjectileConstructor::Firebolt { + damage, + energy_regen: energy_regen * 2, + } + } else { + self + } + } } diff --git a/common/src/comp/skills.rs b/common/src/comp/skills.rs index fef5217b15..ce70f23f6a 100644 --- a/common/src/comp/skills.rs +++ b/common/src/comp/skills.rs @@ -164,7 +164,22 @@ pub enum BowSkill { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum StaffSkill { + // Basic ranged upgrades + BExplosion, + BDamage, + BRegen, + BRadius, + // Flamethrower upgrades + FDamage, + FRange, + FDrain, + FVelocity, + // Shockwave upgrades UnlockShockwave, + SDamage, + SKnockback, + SRange, + SCost, } #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index e8841a4281..2102af81a0 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -3,7 +3,7 @@ use crate::{ inventory::slot::EquipSlot, item::{Hands, ItemKind, Tool, ToolKind}, quadruped_low, quadruped_medium, - skills::{AxeSkill, BowSkill, HammerSkill, Skill, SwordSkill}, + skills::{AxeSkill, BowSkill, HammerSkill, Skill, StaffSkill, SwordSkill}, theropod, Body, CharacterState, StateUpdate, }, consts::{FRIC_GROUND, GRAVITY}, @@ -521,6 +521,15 @@ pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) { { None }, + Some(ToolKind::Staff) + if !&data + .stats + .skill_set + .skills + .contains_key(&Skill::Staff(StaffSkill::UnlockShockwave)) => + { + None + }, _ => Some(s), }) .map(|a| {