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 0ce9a87270..6d57dd5b13 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: Sword, + kind: Axe, 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 1970d5fadb..65e64606ab 100644 --- a/assets/common/skill_trees/skill_max_levels.ron +++ b/assets/common/skill_trees/skill_max_levels.ron @@ -11,4 +11,14 @@ Sword(SSpeed): Some(2), Sword(SCost): Some(2), Sword(SSpins): Some(2), + Axe(DsDamage): Some(3), + Axe(DsRegen): Some(2), + Axe(DsSpeed): Some(3), + Axe(SDamage): Some(3), + Axe(SSpeed): Some(2), + Axe(SCost): Some(2), + Axe(LDamage): Some(2), + Axe(LKnockback): Some(2), + Axe(LCost): Some(2), + Axe(LDistance): 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 14e844640d..a8658d83f3 100644 --- a/assets/common/skill_trees/skill_prerequisites.ron +++ b/assets/common/skill_trees/skill_prerequisites.ron @@ -17,4 +17,15 @@ Sword(TsDamage): {Sword(TsCombo): None}, Sword(TsRegen): {Sword(TsCombo): None}, Sword(TsSpeed): {Sword(TsCombo): None}, + Axe(DsDamage): {Axe(DsCombo): None}, + Axe(DsSpeed): {Axe(DsCombo): None}, + Axe(DsRegen): {Axe(DsCombo): None}, + Axe(SHelicopter): {Axe(SInfinite): None}, + Axe(SDamage): {Axe(SInfinite): None}, + Axe(SSpeed): {Axe(SInfinite): None}, + Axe(SCost): {Axe(SInfinite): None}, + Axe(LDamage): {Axe(LUnlockLeap): None}, + Axe(LKnockback): {Axe(LUnlockLeap): None}, + Axe(LCost): {Axe(LUnlockLeap): None}, + Axe(LDistance): {Axe(LUnlockLeap): 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 2a45ca00a1..5814aefb20 100644 --- a/assets/common/skill_trees/skills_skill-groups_manifest.ron +++ b/assets/common/skill_trees/skills_skill-groups_manifest.ron @@ -27,7 +27,20 @@ Sword(SSpins), ], Weapon(Axe): [ - Axe(UnlockLeap), + Axe(DsCombo), + Axe(DsDamage), + Axe(DsSpeed), + Axe(DsRegen), + Axe(SInfinite), + Axe(SHelicopter), + Axe(SDamage), + Axe(SSpeed), + Axe(SCost), + Axe(LUnlockLeap), + Axe(LDamage), + Axe(LKnockback), + Axe(LCost), + Axe(LDistance), ], Weapon(Hammer): [ Hammer(UnlockLeap), diff --git a/client/src/lib.rs b/client/src/lib.rs index 26265ea8d2..2dd59604ca 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1042,6 +1042,70 @@ impl Client { SkillGroupType::Weapon(Axe), ))); }, + "@unlock axe combo" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::DsCombo, + ))); + }, + "@unlock axe combo damage" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::DsDamage, + ))); + }, + "@unlock axe combo speed" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::DsCombo, + ))); + }, + "@unlock axe combo regen" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::DsRegen, + ))); + }, + "@unlock axe spin infinite" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::SInfinite, + ))); + }, + "@unlock axe spin helicopter" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::SHelicopter, + ))); + }, + "@unlock axe spin damage" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::SDamage, + ))); + }, + "@unlock axe spin speed" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe(AxeSkill::SSpeed))); + }, + "@unlock axe spin cost" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe(AxeSkill::SCost))); + }, + "@unlock axe leap unlock" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::LUnlockLeap, + ))); + }, + "@unlock axe leap damage" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::LDamage, + ))); + }, + "@unlock axe leap knockback" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::LKnockback, + ))); + }, + "@unlock axe leap cost" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe(AxeSkill::LCost))); + }, + "@unlock axe leap distance" => { + self.send_msg(ClientGeneral::UnlockSkill(Skill::Axe( + AxeSkill::LDistance, + ))); + }, "@unlock hammer" => { self.send_msg(ClientGeneral::UnlockSkill(Skill::UnlockGroup( SkillGroupType::Weapon(Hammer), diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 7dc5718ed8..8c386a2e7b 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -615,6 +615,98 @@ impl CharacterAbility { _ => {}, } }, + ToolKind::Axe => { + use skills::AxeSkill::*; + match self { + ComboMelee { + ref mut speed_increase, + ref mut max_speed_increase, + ref mut stage_data, + ref mut max_energy_gain, + ref mut scales_from_combo, + .. + } => { + if !skills.contains_key(&Axe(DsCombo)) { + stage_data.pop(); + } + let speed_segments = Axe(DsSpeed).get_max_level().unwrap_or(1) as f32; + let speed_level = + skills.get(&Axe(DsSpeed)).copied().flatten().unwrap_or(0) as f32; + { + *speed_increase *= speed_level / speed_segments; + *max_speed_increase *= speed_level / speed_segments; + } + let energy_level = + if let Some(level) = skills.get(&Axe(DsRegen)).copied().flatten() { + level + } else { + 0 + }; + { + *max_energy_gain = (*max_energy_gain as f32 + * ((energy_level + 1) * stage_data.len() as u16 - 1) as f32 + / ((Axe(DsRegen).get_max_level().unwrap() + 1) + * stage_data.len() as u16 + - 1) as f32) + as u32; + } + *scales_from_combo = skills + .get(&Axe(DsDamage)) + .copied() + .flatten() + .unwrap_or(0) + .into(); + }, + SpinMelee { + ref mut base_damage, + ref mut swing_duration, + ref mut energy_cost, + ref mut is_infinite, + ref mut is_helicopter, + .. + } => { + *is_infinite = skills.contains_key(&Axe(SInfinite)); + *is_helicopter = skills.contains_key(&Axe(SHelicopter)); + if let Some(level) = skills.get(&Axe(SDamage)).copied().flatten() { + *base_damage = + (*base_damage as f32 * 1.4_f32.powi(level.into())) as u32; + } + if let Some(level) = skills.get(&Axe(SSpeed)).copied().flatten() { + *swing_duration = + (*swing_duration as f32 * 0.8_f32.powi(level.into())) as u64; + } + if let Some(level) = skills.get(&Axe(SCost)).copied().flatten() { + *energy_cost = + (*energy_cost as f32 * 0.75_f32.powi(level.into())) as u32; + } + }, + LeapMelee { + ref mut base_damage, + ref mut knockback, + ref mut energy_cost, + ref mut forward_leap_strength, + ref mut vertical_leap_strength, + .. + } => { + if let Some(level) = skills.get(&Axe(LDamage)).copied().flatten() { + *base_damage = + (*base_damage as f32 * 1.4_f32.powi(level.into())) as u32; + } + if let Some(level) = skills.get(&Axe(LKnockback)).copied().flatten() { + *knockback *= 1.4_f32.powi(level.into()); + } + if let Some(level) = skills.get(&Axe(LCost)).copied().flatten() { + *energy_cost = + (*energy_cost as f32 * 0.75_f32.powi(level.into())) as u32; + } + if let Some(level) = skills.get(&Axe(LDistance)).copied().flatten() { + *forward_leap_strength *= 1.4_f32.powi(level.into()); + *vertical_leap_strength *= 1.4_f32.powi(level.into()); + } + }, + _ => {}, + } + }, _ => {}, } } diff --git a/common/src/comp/skills.rs b/common/src/comp/skills.rs index 4513286398..f35b8ffcc6 100644 --- a/common/src/comp/skills.rs +++ b/common/src/comp/skills.rs @@ -100,7 +100,23 @@ pub enum SwordSkill { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum AxeSkill { - UnlockLeap, + // Double strike upgrades + DsCombo, + DsDamage, + DsSpeed, + DsRegen, + // Spin upgrades + SInfinite, + SHelicopter, + SDamage, + SSpeed, + SCost, + // Leap upgrades + LUnlockLeap, + LDamage, + LKnockback, + LCost, + LDistance, } #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 471cddbe3a..e9bf0f86a8 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::{Skill, SwordSkill}, + skills::{AxeSkill, Skill, SwordSkill}, theropod, Body, CharacterState, StateUpdate, }, consts::{FRIC_GROUND, GRAVITY}, @@ -494,6 +494,15 @@ pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) { { None }, + Some(ToolKind::Axe) + if !&data + .stats + .skill_set + .skills + .contains_key(&Skill::Axe(AxeSkill::LUnlockLeap)) => + { + None + }, _ => Some(s), }) .map(|a| {