From d0aa68a9d21182a60d46af02bb438d8a63b01f9e Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Sat, 20 Mar 2021 17:13:59 +0100 Subject: [PATCH 1/7] Add climbing speed and cost --- .../common/skill_trees/skill_max_levels.ron | 2 + .../skills_skill-groups_manifest.ron | 2 + .../element/icons/skilltree/buff_duration.png | 3 + .../icons/skilltree/debuff_duration.png | 3 + .../element/icons/skilltree/heal_duration.png | 3 + .../icons/skilltree/magic_duration.png | 3 + .../icons/skilltree/physical_duration.png | 3 + .../icons/skilltree/skill_climbing.png | 3 + .../icons/skilltree/utility_duration.png | 3 + assets/voxygen/i18n/en/skills.ron | 8 +- assets/voxygen/i18n/fr_FR/skills.ron | 8 +- common/src/comp/ability.rs | 70 +++++++++++----- common/src/comp/character_state.rs | 2 +- common/src/comp/skills.rs | 7 ++ common/src/states/climb.rs | 28 ++++--- common/src/states/utils.rs | 8 +- common/sys/src/character_behavior.rs | 4 +- common/sys/src/phys.rs | 6 +- server/src/persistence/json_models.rs | 12 ++- voxygen/src/hud/diary.rs | 81 ++++++++++++++++++- voxygen/src/hud/img_ids.rs | 7 ++ 21 files changed, 221 insertions(+), 45 deletions(-) create mode 100644 assets/voxygen/element/icons/skilltree/buff_duration.png create mode 100644 assets/voxygen/element/icons/skilltree/debuff_duration.png create mode 100644 assets/voxygen/element/icons/skilltree/heal_duration.png create mode 100644 assets/voxygen/element/icons/skilltree/magic_duration.png create mode 100644 assets/voxygen/element/icons/skilltree/physical_duration.png create mode 100644 assets/voxygen/element/icons/skilltree/skill_climbing.png create mode 100644 assets/voxygen/element/icons/skilltree/utility_duration.png diff --git a/assets/common/skill_trees/skill_max_levels.ron b/assets/common/skill_trees/skill_max_levels.ron index 47825a83f2..f0c1f07fad 100644 --- a/assets/common/skill_trees/skill_max_levels.ron +++ b/assets/common/skill_trees/skill_max_levels.ron @@ -72,4 +72,6 @@ Roll(Cost): Some(2), Roll(Strength): Some(2), Roll(Duration): Some(2), + Climb(Cost): Some(2), + Climb(Speed): Some(2), }) \ 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 74ec09ff14..f75d99d35b 100644 --- a/assets/common/skill_trees/skills_skill-groups_manifest.ron +++ b/assets/common/skill_trees/skills_skill-groups_manifest.ron @@ -12,6 +12,8 @@ Roll(Cost), Roll(Strength), Roll(Duration), + Climb(Cost), + Climb(Speed) ], Weapon(Sword): [ Sword(InterruptingAttacks), diff --git a/assets/voxygen/element/icons/skilltree/buff_duration.png b/assets/voxygen/element/icons/skilltree/buff_duration.png new file mode 100644 index 0000000000..5862b4de1a --- /dev/null +++ b/assets/voxygen/element/icons/skilltree/buff_duration.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de0d3b71ef3a9ec66fb2deef89d6e98408f66115c4908705c91d03a8453c72d0 +size 311 diff --git a/assets/voxygen/element/icons/skilltree/debuff_duration.png b/assets/voxygen/element/icons/skilltree/debuff_duration.png new file mode 100644 index 0000000000..075d771cf7 --- /dev/null +++ b/assets/voxygen/element/icons/skilltree/debuff_duration.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13361aecfc988b197b21fc3b4cba762485f4fe15211c076e43f4ce25d5be5042 +size 320 diff --git a/assets/voxygen/element/icons/skilltree/heal_duration.png b/assets/voxygen/element/icons/skilltree/heal_duration.png new file mode 100644 index 0000000000..f2b361a2ae --- /dev/null +++ b/assets/voxygen/element/icons/skilltree/heal_duration.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6042aba22c0399a2b7a6105444f558c84e4772769c1eedf8d5bf50c652d1478 +size 312 diff --git a/assets/voxygen/element/icons/skilltree/magic_duration.png b/assets/voxygen/element/icons/skilltree/magic_duration.png new file mode 100644 index 0000000000..a6c9a89bbd --- /dev/null +++ b/assets/voxygen/element/icons/skilltree/magic_duration.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41dc0829fa1127cb2e1375b9e235278022b6557ebda06c374184d6cc3d408ecb +size 316 diff --git a/assets/voxygen/element/icons/skilltree/physical_duration.png b/assets/voxygen/element/icons/skilltree/physical_duration.png new file mode 100644 index 0000000000..00bd0714f2 --- /dev/null +++ b/assets/voxygen/element/icons/skilltree/physical_duration.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12556c461621317c010080803306acf7cdf11c00e595279e38af2ac7c76fce92 +size 321 diff --git a/assets/voxygen/element/icons/skilltree/skill_climbing.png b/assets/voxygen/element/icons/skilltree/skill_climbing.png new file mode 100644 index 0000000000..f1e227b356 --- /dev/null +++ b/assets/voxygen/element/icons/skilltree/skill_climbing.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a264a924c280ff795199fe47335ae07fd2f2208106a7f21a03f53ad51639b119 +size 432 diff --git a/assets/voxygen/element/icons/skilltree/utility_duration.png b/assets/voxygen/element/icons/skilltree/utility_duration.png new file mode 100644 index 0000000000..ba9f43559d --- /dev/null +++ b/assets/voxygen/element/icons/skilltree/utility_duration.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:170d0113075b46999589cc8faaf1a29afe6bfcd22afc9862951728bc7c37fb49 +size 312 diff --git a/assets/voxygen/i18n/en/skills.ron b/assets/voxygen/i18n/en/skills.ron index dcd41959c0..d152f525bd 100644 --- a/assets/voxygen/i18n/en/skills.ron +++ b/assets/voxygen/i18n/en/skills.ron @@ -30,9 +30,15 @@ "hud.skill.roll_stamina_title": "Roll Stamina Cost", "hud.skill.roll_stamina": "Rolling uses 20% less stamina{SP}", "hud.skill.roll_speed_title": "Rolling Speed", - "hud.skill.roll_speed": "Roll 30% faster{SP}", + "hud.skill.roll_speed": "Roll 20% faster{SP}", "hud.skill.roll_dur_title": "Rolling Duration", "hud.skill.roll_dur": "Roll for 20% more time{SP}", + "hud.skill.climbing_title": "Climbing", + "hud.skill.climbing": "Jumping higher", + "hud.skill.climbing_cost_title": "Climbing Cost", + "hud.skill.climbing_cost": "Climbing uses 20% less stamina{SP}", + "hud.skill.climbing_speed_title": "Climbing Speed", + "hud.skill.climbing_speed": "Climb 20% faster{SP}", // Sceptre "hud.skill.sc_lifesteal_title": "Lifesteal Beam", "hud.skill.sc_lifesteal": "Drain the life from your enemies", diff --git a/assets/voxygen/i18n/fr_FR/skills.ron b/assets/voxygen/i18n/fr_FR/skills.ron index 10616dd73f..f9ef193b72 100644 --- a/assets/voxygen/i18n/fr_FR/skills.ron +++ b/assets/voxygen/i18n/fr_FR/skills.ron @@ -30,9 +30,15 @@ "hud.skill.roll_stamina_title": "Coût d'Endurance de la Roulade", "hud.skill.roll_stamina": "Rouler coûte 20% moins d'endurance{SP}", "hud.skill.roll_speed_title": "Vitesse de la Roulade", - "hud.skill.roll_speed": "Rouler 30% plus vite{SP}", + "hud.skill.roll_speed": "Rouler 20% plus vite{SP}", "hud.skill.roll_dur_title": "Durée de la Roulade", "hud.skill.roll_dur": "Augmente de 20% la durée de la roulade{SP}", + "hud.skill.climbing_title": "Escalade", + "hud.skill.climbing": "Sauter encore plus haut", + "hud.skill.climbing_cost_title": "Coût d'endurance de l'Escalade", + "hud.skill.climbing_cost": "Escalader coûte 20% moins d'endurance{SP}", + "hud.skill.climbing_speed_title": "Climbing Speed", + "hud.skill.climbing_speed": "Escalader 20% plus vite{SP}", // Sceptre "hud.skill.sc_lifesteal_title": "Rayon de Vol-Vie", "hud.skill.sc_lifesteal": "Draine la vie de vos ennemis", diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index abf330855e..d5d411bd4d 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -124,6 +124,10 @@ pub enum CharacterAbility { roll_strength: f32, immune_melee: bool, }, + Climb { + energy_cost: f32, + movement_speed: f32, + }, ComboMelee { stage_data: Vec>, initial_energy_gain: f32, @@ -404,6 +408,7 @@ impl CharacterAbility { *movement_duration /= speed; *recover_duration /= speed; }, + Climb { .. } => {}, ComboMelee { ref mut stage_data, .. } => { @@ -538,6 +543,7 @@ impl CharacterAbility { | RepeaterRanged { energy_cost, .. } | DashMelee { energy_cost, .. } | Roll { energy_cost, .. } + | Climb { energy_cost, .. } | LeapMelee { energy_cost, .. } | SpinMelee { energy_cost, .. } | ChargedMelee { energy_cost, .. } @@ -1067,25 +1073,44 @@ impl CharacterAbility { } }, None => { - use skills::RollSkill::*; - if let CharacterAbility::Roll { - ref mut immune_melee, - ref mut energy_cost, - ref mut roll_strength, - ref mut movement_duration, - .. - } = self - { - *immune_melee = skillset.has_skill(Skill::Roll(ImmuneMelee)); - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) { - *energy_cost *= 0.8_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) { - *roll_strength *= 1.2_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) { - *movement_duration *= 1.2_f32.powi(level.into()); - } + use skills::{ + ClimbSkill::{self, *}, + RollSkill::{self, *}, + }; + match self { + CharacterAbility::Roll { + ref mut immune_melee, + ref mut energy_cost, + ref mut roll_strength, + ref mut movement_duration, + .. + } => { + *immune_melee = skillset.has_skill(Skill::Roll(ImmuneMelee)); + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(RollSkill::Cost)) + { + *energy_cost *= 0.8_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) { + *roll_strength *= 1.2_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) { + *movement_duration *= 1.2_f32.powi(level.into()); + } + }, + CharacterAbility::Climb { + ref mut energy_cost, + ref mut movement_speed, + } => { + if let Ok(Some(level)) = + skillset.skill_level(Skill::Climb(ClimbSkill::Cost)) + { + *energy_cost *= 0.8_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Climb(Speed)) { + *movement_speed *= 1.2_f32.powi(level.into()); + } + }, + _ => {}, } }, Some(_) => {}, @@ -1224,6 +1249,13 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState { was_sneak: false, was_combo: None, }), + CharacterAbility::Climb { + energy_cost, + movement_speed, + } => CharacterState::Climb(climb::Data { + energy_cost: *energy_cost, + movement_speed: *movement_speed, + }), CharacterAbility::ComboMelee { stage_data, initial_energy_gain, diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 25d16beeb9..aadbef94e9 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -42,7 +42,7 @@ impl From<&JoinData<'_>> for StateUpdate { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum CharacterState { Idle, - Climb, + Climb(climb::Data), Sit, Dance, Talk, diff --git a/common/src/comp/skills.rs b/common/src/comp/skills.rs index 2829b90039..9892b2672a 100644 --- a/common/src/comp/skills.rs +++ b/common/src/comp/skills.rs @@ -103,6 +103,7 @@ pub enum Skill { Sceptre(SceptreSkill), UnlockGroup(SkillGroupKind), Roll(RollSkill), + Climb(ClimbSkill), } pub enum SkillError { @@ -250,6 +251,12 @@ pub enum RollSkill { Duration, } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] +pub enum ClimbSkill { + Cost, + Speed, +} + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum SkillGroupKind { General, diff --git a/common/src/states/climb.rs b/common/src/states/climb.rs index 040c31ac20..6ba35de9c8 100644 --- a/common/src/states/climb.rs +++ b/common/src/states/climb.rs @@ -11,11 +11,20 @@ use crate::{ use serde::{Deserialize, Serialize}; use vek::*; -const HUMANOID_CLIMB_ACCEL: f32 = 24.0; -const CLIMB_SPEED: f32 = 5.0; +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Data { + pub energy_cost: f32, + pub movement_speed: f32, +} -#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] -pub struct Data; +impl Default for Data { + fn default() -> Self { + Data { + energy_cost: 5.0, + movement_speed: 5.0, + } + } +} impl CharacterBehavior for Data { fn behavior(&self, data: &JoinData) -> StateUpdate { @@ -38,19 +47,18 @@ impl CharacterBehavior for Data { update.character = CharacterState::Idle {}; return update; }; - // Move player update.vel.0 += Vec2::broadcast(data.dt.0) * data.inputs.move_dir - * if update.vel.0.magnitude_squared() < CLIMB_SPEED.powi(2) { - HUMANOID_CLIMB_ACCEL + * if update.vel.0.magnitude_squared() < self.movement_speed.powi(2) { + self.movement_speed.powi(2) } else { 0.0 }; // Expend energy if climbing let energy_use = match climb { - Climb::Up => 5, + Climb::Up => self.energy_cost as i32, Climb::Down => 1, Climb::Hold => 1, }; @@ -74,8 +82,8 @@ impl CharacterBehavior for Data { // Apply Vertical Climbing Movement match climb { - Climb::Down => update.vel.0.z += data.dt.0 * (GRAVITY - HUMANOID_CLIMB_ACCEL), - Climb::Up => update.vel.0.z += data.dt.0 * (GRAVITY + HUMANOID_CLIMB_ACCEL), + Climb::Down => update.vel.0.z += data.dt.0 * (GRAVITY - self.movement_speed.powi(2)), + Climb::Up => update.vel.0.z += data.dt.0 * (GRAVITY + self.movement_speed.powi(2)), Climb::Hold => update.vel.0.z += data.dt.0 * GRAVITY, } diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 68d4e02b1b..9988369ec5 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -407,7 +407,13 @@ pub fn handle_climb(data: &JoinData, update: &mut StateUpdate) { && data.body.can_climb() && update.energy.current() > 100 { - update.character = CharacterState::Climb; + let ability = CharacterAbility::Climb { + energy_cost: 5.0, + movement_speed: 5.0, + } + .adjusted_by_skills(&data.stats.skill_set, None); + let ability_info = AbilityInfo::from_input(data, false, InputKind::Roll); + update.character = CharacterState::from((&ability, ability_info)); } } diff --git a/common/sys/src/character_behavior.rs b/common/sys/src/character_behavior.rs index 3b6c4d2d46..ea9d590551 100644 --- a/common/sys/src/character_behavior.rs +++ b/common/sys/src/character_behavior.rs @@ -267,7 +267,7 @@ impl<'a> System<'a> for Sys { let mut state_update = match j.character { CharacterState::Idle => states::idle::Data.handle_event(&j, action), CharacterState::Talk => states::talk::Data.handle_event(&j, action), - CharacterState::Climb => states::climb::Data.handle_event(&j, action), + CharacterState::Climb(data) => data.handle_event(&j, action), CharacterState::Glide => states::glide::Data.handle_event(&j, action), CharacterState::GlideWield => { states::glide_wield::Data.handle_event(&j, action) @@ -329,7 +329,7 @@ impl<'a> System<'a> for Sys { let mut state_update = match j.character { CharacterState::Idle => states::idle::Data.behavior(&j), CharacterState::Talk => states::talk::Data.behavior(&j), - CharacterState::Climb => states::climb::Data.behavior(&j), + CharacterState::Climb(data) => data.behavior(&j), CharacterState::Glide => states::glide::Data.behavior(&j), CharacterState::GlideWield => states::glide_wield::Data.behavior(&j), CharacterState::Stunned(data) => data.behavior(&j), diff --git a/common/sys/src/phys.rs b/common/sys/src/phys.rs index dc559ffb51..225ab2b7b7 100644 --- a/common/sys/src/phys.rs +++ b/common/sys/src/phys.rs @@ -11,6 +11,7 @@ use common::{ consts::{FRIC_GROUND, GRAVITY}, event::{EventBus, ServerEvent}, resources::DeltaTime, + states::*, terrain::{Block, TerrainGrid}, uid::Uid, vol::{BaseVol, ReadVol}, @@ -669,8 +670,9 @@ impl<'a> PhysicsData<'a> { let was_on_ground = physics_state.on_ground; let block_snap = body.map_or(false, |body| body.jump_impulse().is_some()); - let climbing = - character_state.map_or(false, |cs| matches!(cs, CharacterState::Climb)); + let climbing = character_state.map_or(false, |cs| { + matches!(cs, CharacterState::Climb(climb::Data { .. })) + }); match &collider { Collider::Voxel { .. } => { diff --git a/server/src/persistence/json_models.rs b/server/src/persistence/json_models.rs index 9c58a844c5..ab5703aec5 100644 --- a/server/src/persistence/json_models.rs +++ b/server/src/persistence/json_models.rs @@ -40,8 +40,8 @@ pub fn skill_to_db_string(skill: comp::skills::Skill) -> String { use comp::{ item::tool::ToolKind, skills::{ - AxeSkill, BowSkill, GeneralSkill, HammerSkill, RollSkill, SceptreSkill, Skill::*, - SkillGroupKind, StaffSkill, SwordSkill, + AxeSkill, BowSkill, ClimbSkill, GeneralSkill, HammerSkill, RollSkill, SceptreSkill, + Skill::*, SkillGroupKind, StaffSkill, SwordSkill, }, }; let skill_string = match skill { @@ -134,6 +134,8 @@ pub fn skill_to_db_string(skill: comp::skills::Skill) -> String { Roll(RollSkill::Cost) => "Roll Cost", Roll(RollSkill::Strength) => "Roll Strength", Roll(RollSkill::Duration) => "Roll Duration", + Climb(ClimbSkill::Cost) => "Climbing Cost", + Climb(ClimbSkill::Speed) => "Climbing Speed", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sword)) => "Unlock Weapon Sword", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Axe)) => "Unlock Weapon Axe", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Hammer)) => "Unlock Weapon Hammer", @@ -163,8 +165,8 @@ pub fn db_string_to_skill(skill_string: &str) -> comp::skills::Skill { use comp::{ item::tool::ToolKind, skills::{ - AxeSkill, BowSkill, GeneralSkill, HammerSkill, RollSkill, SceptreSkill, Skill::*, - SkillGroupKind, StaffSkill, SwordSkill, + AxeSkill, BowSkill, ClimbSkill, GeneralSkill, HammerSkill, RollSkill, SceptreSkill, + Skill::*, SkillGroupKind, StaffSkill, SwordSkill, }, }; match skill_string { @@ -257,6 +259,8 @@ pub fn db_string_to_skill(skill_string: &str) -> comp::skills::Skill { "Roll Cost" => Roll(RollSkill::Cost), "Roll Strength" => Roll(RollSkill::Strength), "Roll Duration" => Roll(RollSkill::Duration), + "Climbing Cost" => Climb(ClimbSkill::Cost), + "Climbing Speed" => Climb(ClimbSkill::Speed), "Unlock Weapon Sword" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sword)), "Unlock Weapon Axe" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Axe)), "Unlock Weapon Hammer" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Hammer)), diff --git a/voxygen/src/hud/diary.rs b/voxygen/src/hud/diary.rs index 8f1df1759b..3bc72a3cf0 100644 --- a/voxygen/src/hud/diary.rs +++ b/voxygen/src/hud/diary.rs @@ -163,6 +163,9 @@ widget_ids! { skill_general_roll_1, skill_general_roll_2, skill_general_roll_3, + skill_general_climb_0, + skill_general_climb_1, + skill_general_climb_2, } } @@ -572,6 +575,7 @@ impl<'a> Widget for Diary<'a> { _ => 0, }; let skills_bot_r = match sel_tab { + SelectedSkillTree::General => 3, SelectedSkillTree::Weapon(ToolKind::Sword) => 1, SelectedSkillTree::Weapon(ToolKind::Bow) => 1, _ => 0, @@ -701,7 +705,12 @@ impl<'a> Widget for Diary<'a> { let art_size = [320.0, 320.0]; match sel_tab { SelectedSkillTree::General => { - use skills::{GeneralSkill::*, RollSkill::*, SkillGroupKind::*}; + use skills::{ + ClimbSkill::{self}, + GeneralSkill::*, + RollSkill::{self, *}, + SkillGroupKind::*, + }; use ToolKind::*; // General Combat Image::new(animate_by_pulse( @@ -964,7 +973,7 @@ impl<'a> Widget for Diary<'a> { { events.push(Event::UnlockSkill(skill)); }; - let skill = Skill::Roll(Cost); + let skill = Skill::Roll(RollSkill::Cost); if create_skill_button( self.imgs.utility_cost_skill, state.skills_bot_l[1], @@ -1018,7 +1027,7 @@ impl<'a> Widget for Diary<'a> { }; let skill = Skill::Roll(Duration); if create_skill_button( - self.imgs.utility_amount_skill, + self.imgs.utility_duration_skill, state.skills_bot_l[3], &self.stats.skill_set, skill, @@ -1042,6 +1051,70 @@ impl<'a> Widget for Diary<'a> { { events.push(Event::UnlockSkill(skill)); }; + // Bottom right skills + Button::image(self.imgs.skill_climbing_skill) + .w_h(74.0, 74.0) + .mid_top_with_margin_on(state.skills_bot_r[0], 3.0) + .with_tooltip( + self.tooltip_manager, + &self.localized_strings.get("hud.skill.climbing_title"), + &self.localized_strings.get("hud.skill.climbing"), + &diary_tooltip, + TEXT_COLOR, + ) + .set(state.skill_general_climb_0, ui); + let skill = Skill::Climb(ClimbSkill::Cost); + if create_skill_button( + self.imgs.utility_cost_skill, + state.skills_bot_r[1], + &self.stats.skill_set, + skill, + self.fonts, + &get_skill_label(skill, &self.stats.skill_set), + ) + .with_tooltip( + self.tooltip_manager, + &self.localized_strings.get("hud.skill.climbing_cost_title"), + &add_sp_cost_tooltip( + &self.localized_strings.get("hud.skill.climbing_cost"), + skill, + &self.stats.skill_set, + &self.localized_strings, + ), + &diary_tooltip, + TEXT_COLOR, + ) + .set(state.skill_general_climb_1, ui) + .was_clicked() + { + events.push(Event::UnlockSkill(skill)); + }; + let skill = Skill::Climb(ClimbSkill::Speed); + if create_skill_button( + self.imgs.utility_speed_skill, + state.skills_bot_r[2], + &self.stats.skill_set, + skill, + self.fonts, + &get_skill_label(skill, &self.stats.skill_set), + ) + .with_tooltip( + self.tooltip_manager, + &self.localized_strings.get("hud.skill.climbing_speed_title"), + &add_sp_cost_tooltip( + &self.localized_strings.get("hud.skill.climbing_speed"), + skill, + &self.stats.skill_set, + &self.localized_strings, + ), + &diary_tooltip, + TEXT_COLOR, + ) + .set(state.skill_general_climb_2, ui) + .was_clicked() + { + events.push(Event::UnlockSkill(skill)); + }; }, SelectedSkillTree::Weapon(ToolKind::Sword) => { use skills::SwordSkill::*; @@ -3537,7 +3610,7 @@ impl<'a> Widget for Diary<'a> { }; let skill = Skill::Sceptre(ADuration); if create_skill_button( - self.imgs.buff_speed_skill, + self.imgs.buff_duration_skill, state.skills_bot_l[2], &self.stats.skill_set, skill, diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 958bfd8e2f..6c71300cba 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -181,6 +181,7 @@ image_ids! { unlock_staff_skill0: "voxygen.element.icons.skilltree.unlock_staff-0", unlock_sword_skill: "voxygen.element.icons.skilltree.unlock_sword", skill_dodge_skill: "voxygen.element.icons.skilltree.skill_dodge", + skill_climbing_skill: "voxygen.element.icons.skilltree.skill_climbing", buff_amount_skill: "voxygen.element.icons.skilltree.buff_amount", buff_combo_skill: "voxygen.element.icons.skilltree.buff_combo", @@ -198,6 +199,7 @@ image_ids! { buff_projectile_speed_skill: "voxygen.element.icons.skilltree.buff_projectile_speed", buff_radius_skill: "voxygen.element.icons.skilltree.buff_radius", buff_speed_skill: "voxygen.element.icons.skilltree.buff_speed", + buff_duration_skill: "voxygen.element.icons.skilltree.buff_duration", debuff_amount_skill: "voxygen.element.icons.skilltree.debuff_amount", debuff_combo_skill: "voxygen.element.icons.skilltree.debuff_combo", @@ -215,6 +217,7 @@ image_ids! { debuff_projectile_speed_skill: "voxygen.element.icons.skilltree.debuff_projectile_speed", debuff_radius_skill: "voxygen.element.icons.skilltree.debuff_radius", debuff_speed_skill: "voxygen.element.icons.skilltree.debuff_speed", + debuff_duration_skill: "voxygen.element.icons.skilltree.debuff_duration", heal_amount_skill: "voxygen.element.icons.skilltree.heal_amount", heal_combo_skill: "voxygen.element.icons.skilltree.heal_combo", @@ -232,6 +235,7 @@ image_ids! { heal_projectile_speed_skill: "voxygen.element.icons.skilltree.heal_projectile_speed", heal_radius_skill: "voxygen.element.icons.skilltree.heal_radius", heal_speed_skill: "voxygen.element.icons.skilltree.heal_speed", + heal_duration_skill: "voxygen.element.icons.skilltree.heal_duration", magic_amount_skill: "voxygen.element.icons.skilltree.magic_amount", magic_combo_skill: "voxygen.element.icons.skilltree.magic_combo", @@ -249,6 +253,7 @@ image_ids! { magic_projectile_speed_skill: "voxygen.element.icons.skilltree.magic_projectile_speed", magic_radius_skill: "voxygen.element.icons.skilltree.magic_radius", magic_speed_skill: "voxygen.element.icons.skilltree.magic_speed", + magic_duration_skill: "voxygen.element.icons.skilltree.magic_duration", physical_amount_skill: "voxygen.element.icons.skilltree.physical_amount", physical_combo_skill: "voxygen.element.icons.skilltree.physical_combo", @@ -266,6 +271,7 @@ image_ids! { physical_projectile_speed_skill: "voxygen.element.icons.skilltree.physical_projectile_speed", physical_radius_skill: "voxygen.element.icons.skilltree.physical_radius", physical_speed_skill: "voxygen.element.icons.skilltree.physical_speed", + physical_duration_skill: "voxygen.element.icons.skilltree.physical_duration", utility_amount_skill: "voxygen.element.icons.skilltree.utility_amount", utility_combo_skill: "voxygen.element.icons.skilltree.utility_combo", @@ -283,6 +289,7 @@ image_ids! { utility_projectile_speed_skill: "voxygen.element.icons.skilltree.utility_projectile_speed", utility_radius_skill: "voxygen.element.icons.skilltree.utility_radius", utility_speed_skill: "voxygen.element.icons.skilltree.utility_speed", + utility_duration_skill: "voxygen.element.icons.skilltree.utility_duration", // Skillbar level_up: "voxygen.element.misc_bg.level_up", From 7dad9726323d8236ffe973df02f1043fd16f3838 Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Sat, 20 Mar 2021 17:18:32 +0100 Subject: [PATCH 2/7] add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82c68250b4..871926235c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- New Skills for Climbing: Climbing Speed and Climbing Cost ### Changed From 8b01abde67c347087826626a1d744425fe0ae806 Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Sat, 20 Mar 2021 22:56:54 +0100 Subject: [PATCH 3/7] address comments --- common/src/comp/ability.rs | 79 +++++++++++++-------------- common/src/states/climb.rs | 30 +++++++--- common/sys/src/phys.rs | 6 +- server/src/persistence/json_models.rs | 8 +-- 4 files changed, 65 insertions(+), 58 deletions(-) diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index d5d411bd4d..c27ecfb470 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -1072,46 +1072,39 @@ impl CharacterAbility { _ => {}, } }, - None => { - use skills::{ - ClimbSkill::{self, *}, - RollSkill::{self, *}, - }; - match self { - CharacterAbility::Roll { - ref mut immune_melee, - ref mut energy_cost, - ref mut roll_strength, - ref mut movement_duration, - .. - } => { - *immune_melee = skillset.has_skill(Skill::Roll(ImmuneMelee)); - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(RollSkill::Cost)) - { - *energy_cost *= 0.8_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) { - *roll_strength *= 1.2_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) { - *movement_duration *= 1.2_f32.powi(level.into()); - } - }, - CharacterAbility::Climb { - ref mut energy_cost, - ref mut movement_speed, - } => { - if let Ok(Some(level)) = - skillset.skill_level(Skill::Climb(ClimbSkill::Cost)) - { - *energy_cost *= 0.8_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Climb(Speed)) { - *movement_speed *= 1.2_f32.powi(level.into()); - } - }, - _ => {}, - } + None => match self { + CharacterAbility::Roll { + ref mut immune_melee, + ref mut energy_cost, + ref mut roll_strength, + ref mut movement_duration, + .. + } => { + use skills::RollSkill::*; + *immune_melee = skillset.has_skill(Skill::Roll(ImmuneMelee)); + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) { + *energy_cost *= 0.8_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) { + *roll_strength *= 1.2_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) { + *movement_duration *= 1.2_f32.powi(level.into()); + } + }, + CharacterAbility::Climb { + ref mut energy_cost, + ref mut movement_speed, + } => { + use skills::ClimbSkill::*; + if let Ok(Some(level)) = skillset.skill_level(Skill::Climb(Cost)) { + *energy_cost *= 0.8_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Climb(Speed)) { + *movement_speed *= 1.2_f32.powi(level.into()); + } + }, + _ => {}, }, Some(_) => {}, } @@ -1253,8 +1246,10 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState { energy_cost, movement_speed, } => CharacterState::Climb(climb::Data { - energy_cost: *energy_cost, - movement_speed: *movement_speed, + static_data: climb::StaticData { + energy_cost: *energy_cost, + movement_speed: *movement_speed, + }, }), CharacterAbility::ComboMelee { stage_data, diff --git a/common/src/states/climb.rs b/common/src/states/climb.rs index 6ba35de9c8..7f9645ee0a 100644 --- a/common/src/states/climb.rs +++ b/common/src/states/climb.rs @@ -11,17 +11,27 @@ use crate::{ use serde::{Deserialize, Serialize}; use vek::*; +/// Separated out to condense update portions of character state #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] -pub struct Data { +pub struct StaticData { pub energy_cost: f32, pub movement_speed: f32, } +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Data { + /// Struct containing data that does not change over the course of the + /// character state + pub static_data: StaticData, +} + impl Default for Data { fn default() -> Self { Data { - energy_cost: 5.0, - movement_speed: 5.0, + static_data: StaticData { + energy_cost: 5.0, + movement_speed: 5.0, + }, } } } @@ -50,15 +60,15 @@ impl CharacterBehavior for Data { // Move player update.vel.0 += Vec2::broadcast(data.dt.0) * data.inputs.move_dir - * if update.vel.0.magnitude_squared() < self.movement_speed.powi(2) { - self.movement_speed.powi(2) + * if update.vel.0.magnitude_squared() < self.static_data.movement_speed.powi(2) { + self.static_data.movement_speed.powi(2) } else { 0.0 }; // Expend energy if climbing let energy_use = match climb { - Climb::Up => self.energy_cost as i32, + Climb::Up => self.static_data.energy_cost as i32, Climb::Down => 1, Climb::Hold => 1, }; @@ -82,8 +92,12 @@ impl CharacterBehavior for Data { // Apply Vertical Climbing Movement match climb { - Climb::Down => update.vel.0.z += data.dt.0 * (GRAVITY - self.movement_speed.powi(2)), - Climb::Up => update.vel.0.z += data.dt.0 * (GRAVITY + self.movement_speed.powi(2)), + Climb::Down => { + update.vel.0.z += data.dt.0 * (GRAVITY - self.static_data.movement_speed.powi(2)) + }, + Climb::Up => { + update.vel.0.z += data.dt.0 * (GRAVITY + self.static_data.movement_speed.powi(2)) + }, Climb::Hold => update.vel.0.z += data.dt.0 * GRAVITY, } diff --git a/common/sys/src/phys.rs b/common/sys/src/phys.rs index 225ab2b7b7..0c3cef038e 100644 --- a/common/sys/src/phys.rs +++ b/common/sys/src/phys.rs @@ -11,7 +11,6 @@ use common::{ consts::{FRIC_GROUND, GRAVITY}, event::{EventBus, ServerEvent}, resources::DeltaTime, - states::*, terrain::{Block, TerrainGrid}, uid::Uid, vol::{BaseVol, ReadVol}, @@ -670,9 +669,8 @@ impl<'a> PhysicsData<'a> { let was_on_ground = physics_state.on_ground; let block_snap = body.map_or(false, |body| body.jump_impulse().is_some()); - let climbing = character_state.map_or(false, |cs| { - matches!(cs, CharacterState::Climb(climb::Data { .. })) - }); + let climbing = + character_state.map_or(false, |cs| matches!(cs, CharacterState::Climb(_))); match &collider { Collider::Voxel { .. } => { diff --git a/server/src/persistence/json_models.rs b/server/src/persistence/json_models.rs index ab5703aec5..ba33df2c9c 100644 --- a/server/src/persistence/json_models.rs +++ b/server/src/persistence/json_models.rs @@ -134,8 +134,8 @@ pub fn skill_to_db_string(skill: comp::skills::Skill) -> String { Roll(RollSkill::Cost) => "Roll Cost", Roll(RollSkill::Strength) => "Roll Strength", Roll(RollSkill::Duration) => "Roll Duration", - Climb(ClimbSkill::Cost) => "Climbing Cost", - Climb(ClimbSkill::Speed) => "Climbing Speed", + Climb(ClimbSkill::Cost) => "Climb Cost", + Climb(ClimbSkill::Speed) => "Climb Speed", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sword)) => "Unlock Weapon Sword", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Axe)) => "Unlock Weapon Axe", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Hammer)) => "Unlock Weapon Hammer", @@ -259,8 +259,8 @@ pub fn db_string_to_skill(skill_string: &str) -> comp::skills::Skill { "Roll Cost" => Roll(RollSkill::Cost), "Roll Strength" => Roll(RollSkill::Strength), "Roll Duration" => Roll(RollSkill::Duration), - "Climbing Cost" => Climb(ClimbSkill::Cost), - "Climbing Speed" => Climb(ClimbSkill::Speed), + "Climb Cost" => Climb(ClimbSkill::Cost), + "Climb Speed" => Climb(ClimbSkill::Speed), "Unlock Weapon Sword" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sword)), "Unlock Weapon Axe" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Axe)), "Unlock Weapon Hammer" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Hammer)), From d0df01fe51ac72278feae160448eb471fb03fb4a Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Sun, 21 Mar 2021 00:22:04 +0100 Subject: [PATCH 4/7] move climbing skill adjustment into climb module --- common/src/comp/ability.rs | 51 ++++++++++++++------------------------ common/src/states/climb.rs | 18 +++++++++++++- common/src/states/utils.rs | 8 +----- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index c27ecfb470..4e2da69593 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -1072,39 +1072,24 @@ impl CharacterAbility { _ => {}, } }, - None => match self { - CharacterAbility::Roll { - ref mut immune_melee, - ref mut energy_cost, - ref mut roll_strength, - ref mut movement_duration, - .. - } => { - use skills::RollSkill::*; - *immune_melee = skillset.has_skill(Skill::Roll(ImmuneMelee)); - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) { - *energy_cost *= 0.8_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) { - *roll_strength *= 1.2_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) { - *movement_duration *= 1.2_f32.powi(level.into()); - } - }, - CharacterAbility::Climb { - ref mut energy_cost, - ref mut movement_speed, - } => { - use skills::ClimbSkill::*; - if let Ok(Some(level)) = skillset.skill_level(Skill::Climb(Cost)) { - *energy_cost *= 0.8_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Climb(Speed)) { - *movement_speed *= 1.2_f32.powi(level.into()); - } - }, - _ => {}, + None => if let CharacterAbility::Roll{ + ref mut immune_melee, + ref mut energy_cost, + ref mut roll_strength, + ref mut movement_duration, + .. + } = self { + use skills::RollSkill::*; + *immune_melee = skillset.has_skill(Skill::Roll(ImmuneMelee)); + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) { + *energy_cost *= 0.8_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) { + *roll_strength *= 1.2_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) { + *movement_duration *= 1.2_f32.powi(level.into()); + } }, Some(_) => {}, } diff --git a/common/src/states/climb.rs b/common/src/states/climb.rs index 7f9645ee0a..ec2ecc717c 100644 --- a/common/src/states/climb.rs +++ b/common/src/states/climb.rs @@ -1,5 +1,8 @@ use crate::{ - comp::{CharacterState, Climb, EnergySource, InputKind, Ori, StateUpdate}, + comp::{ + skills::{ClimbSkill::*, Skill}, + CharacterState, Climb, EnergySource, InputKind, Ori, StateUpdate, + }, consts::GRAVITY, event::LocalEvent, states::{ @@ -25,6 +28,19 @@ pub struct Data { pub static_data: StaticData, } +impl Data { + pub fn create_adjusted_by_skills(join_data: &JoinData) -> Self { + let mut data = Data::default(); + if let Ok(Some(level)) = join_data.stats.skill_set.skill_level(Skill::Climb(Cost)) { + data.static_data.energy_cost *= 0.8_f32.powi(level.into()); + } + if let Ok(Some(level)) = join_data.stats.skill_set.skill_level(Skill::Climb(Speed)) { + data.static_data.movement_speed *= 1.2_f32.powi(level.into()); + } + data + } +} + impl Default for Data { fn default() -> Self { Data { diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 9988369ec5..d3c72284ea 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -407,13 +407,7 @@ pub fn handle_climb(data: &JoinData, update: &mut StateUpdate) { && data.body.can_climb() && update.energy.current() > 100 { - let ability = CharacterAbility::Climb { - energy_cost: 5.0, - movement_speed: 5.0, - } - .adjusted_by_skills(&data.stats.skill_set, None); - let ability_info = AbilityInfo::from_input(data, false, InputKind::Roll); - update.character = CharacterState::from((&ability, ability_info)); + update.character = CharacterState::Climb(climb::Data::create_adjusted_by_skills(data)); } } From 9e11a574d252d34bfbf067c23671032aeccba187 Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Sun, 21 Mar 2021 00:35:34 +0100 Subject: [PATCH 5/7] remove CharacterAbility::Climb --- common/src/comp/ability.rs | 52 +++++++++++++++----------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 4e2da69593..25a8433b14 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -124,10 +124,6 @@ pub enum CharacterAbility { roll_strength: f32, immune_melee: bool, }, - Climb { - energy_cost: f32, - movement_speed: f32, - }, ComboMelee { stage_data: Vec>, initial_energy_gain: f32, @@ -408,7 +404,6 @@ impl CharacterAbility { *movement_duration /= speed; *recover_duration /= speed; }, - Climb { .. } => {}, ComboMelee { ref mut stage_data, .. } => { @@ -543,7 +538,6 @@ impl CharacterAbility { | RepeaterRanged { energy_cost, .. } | DashMelee { energy_cost, .. } | Roll { energy_cost, .. } - | Climb { energy_cost, .. } | LeapMelee { energy_cost, .. } | SpinMelee { energy_cost, .. } | ChargedMelee { energy_cost, .. } @@ -1072,23 +1066,26 @@ impl CharacterAbility { _ => {}, } }, - None => if let CharacterAbility::Roll{ - ref mut immune_melee, - ref mut energy_cost, - ref mut roll_strength, - ref mut movement_duration, - .. - } = self { - use skills::RollSkill::*; - *immune_melee = skillset.has_skill(Skill::Roll(ImmuneMelee)); - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) { - *energy_cost *= 0.8_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) { - *roll_strength *= 1.2_f32.powi(level.into()); - } - if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) { - *movement_duration *= 1.2_f32.powi(level.into()); + None => { + if let CharacterAbility::Roll { + ref mut immune_melee, + ref mut energy_cost, + ref mut roll_strength, + ref mut movement_duration, + .. + } = self + { + use skills::RollSkill::*; + *immune_melee = skillset.has_skill(Skill::Roll(ImmuneMelee)); + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) { + *energy_cost *= 0.8_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) { + *roll_strength *= 1.2_f32.powi(level.into()); + } + if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) { + *movement_duration *= 1.2_f32.powi(level.into()); + } } }, Some(_) => {}, @@ -1227,15 +1224,6 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState { was_sneak: false, was_combo: None, }), - CharacterAbility::Climb { - energy_cost, - movement_speed, - } => CharacterState::Climb(climb::Data { - static_data: climb::StaticData { - energy_cost: *energy_cost, - movement_speed: *movement_speed, - }, - }), CharacterAbility::ComboMelee { stage_data, initial_energy_gain, From 985c26dd0a4717209ae3918c01fe9d1a39f2eec7 Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Sun, 21 Mar 2021 13:26:44 +0100 Subject: [PATCH 6/7] improve climbing icon --- assets/voxygen/element/icons/skilltree/skill_climbing.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/voxygen/element/icons/skilltree/skill_climbing.png b/assets/voxygen/element/icons/skilltree/skill_climbing.png index f1e227b356..7ff07682da 100644 --- a/assets/voxygen/element/icons/skilltree/skill_climbing.png +++ b/assets/voxygen/element/icons/skilltree/skill_climbing.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a264a924c280ff795199fe47335ae07fd2f2208106a7f21a03f53ad51639b119 -size 432 +oid sha256:c69cbd266448298000a236d8ebdfa546f9336127e346a5fe5cb667fba829674f +size 426 From e06870702f6e8ac02b00c056b239580d5bc7460f Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Sun, 21 Mar 2021 15:58:38 +0100 Subject: [PATCH 7/7] Add skill for swimming speed --- .../common/skill_trees/skill_max_levels.ron | 1 + .../skills_skill-groups_manifest.ron | 3 +- .../element/icons/skilltree/skill_swim.png | 3 ++ assets/voxygen/i18n/en/skills.ron | 4 ++ assets/voxygen/i18n/fr_FR/skills.ron | 6 ++- common/src/comp/skills.rs | 6 +++ common/src/states/utils.rs | 19 ++++++-- server/src/persistence/json_models.rs | 6 ++- voxygen/src/hud/diary.rs | 45 ++++++++++++++++++- voxygen/src/hud/img_ids.rs | 1 + 10 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 assets/voxygen/element/icons/skilltree/skill_swim.png diff --git a/assets/common/skill_trees/skill_max_levels.ron b/assets/common/skill_trees/skill_max_levels.ron index f0c1f07fad..dc87e72922 100644 --- a/assets/common/skill_trees/skill_max_levels.ron +++ b/assets/common/skill_trees/skill_max_levels.ron @@ -74,4 +74,5 @@ Roll(Duration): Some(2), Climb(Cost): Some(2), Climb(Speed): Some(2), + Swim(Speed): Some(2), }) \ 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 f75d99d35b..5d9f33d7cb 100644 --- a/assets/common/skill_trees/skills_skill-groups_manifest.ron +++ b/assets/common/skill_trees/skills_skill-groups_manifest.ron @@ -13,7 +13,8 @@ Roll(Strength), Roll(Duration), Climb(Cost), - Climb(Speed) + Climb(Speed), + Swim(Speed), ], Weapon(Sword): [ Sword(InterruptingAttacks), diff --git a/assets/voxygen/element/icons/skilltree/skill_swim.png b/assets/voxygen/element/icons/skilltree/skill_swim.png new file mode 100644 index 0000000000..6d310fd729 --- /dev/null +++ b/assets/voxygen/element/icons/skilltree/skill_swim.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:305301b7614fcff87476ae7bd26b0658bbb6708b6ee80cd408d88796b76890a6 +size 255 diff --git a/assets/voxygen/i18n/en/skills.ron b/assets/voxygen/i18n/en/skills.ron index d152f525bd..e6fa12cbf7 100644 --- a/assets/voxygen/i18n/en/skills.ron +++ b/assets/voxygen/i18n/en/skills.ron @@ -39,6 +39,10 @@ "hud.skill.climbing_cost": "Climbing uses 20% less stamina{SP}", "hud.skill.climbing_speed_title": "Climbing Speed", "hud.skill.climbing_speed": "Climb 20% faster{SP}", + "hud.skill.swim_title": "Swimming", + "hud.skill.swim": "Moving in wet environment", + "hud.skill.swim_speed_title": "Swimming Speed", + "hud.skill.swim_speed": "Swim 40% faster{SP}", // Sceptre "hud.skill.sc_lifesteal_title": "Lifesteal Beam", "hud.skill.sc_lifesteal": "Drain the life from your enemies", diff --git a/assets/voxygen/i18n/fr_FR/skills.ron b/assets/voxygen/i18n/fr_FR/skills.ron index f9ef193b72..cbdfcc9045 100644 --- a/assets/voxygen/i18n/fr_FR/skills.ron +++ b/assets/voxygen/i18n/fr_FR/skills.ron @@ -37,8 +37,12 @@ "hud.skill.climbing": "Sauter encore plus haut", "hud.skill.climbing_cost_title": "Coût d'endurance de l'Escalade", "hud.skill.climbing_cost": "Escalader coûte 20% moins d'endurance{SP}", - "hud.skill.climbing_speed_title": "Climbing Speed", + "hud.skill.climbing_speed_title": "Vitesse d'Escalade", "hud.skill.climbing_speed": "Escalader 20% plus vite{SP}", + "hud.skill.swim_title": "Nage", + "hud.skill.swim": "Déplacement en environnement humide", + "hud.skill.swim_speed_title": "Vitesse de nage", + "hud.skill.swim_speed": "Nager 40% plus vite{SP}", // Sceptre "hud.skill.sc_lifesteal_title": "Rayon de Vol-Vie", "hud.skill.sc_lifesteal": "Draine la vie de vos ennemis", diff --git a/common/src/comp/skills.rs b/common/src/comp/skills.rs index 9892b2672a..7582fddf3a 100644 --- a/common/src/comp/skills.rs +++ b/common/src/comp/skills.rs @@ -104,6 +104,7 @@ pub enum Skill { UnlockGroup(SkillGroupKind), Roll(RollSkill), Climb(ClimbSkill), + Swim(SwimSkill), } pub enum SkillError { @@ -257,6 +258,11 @@ pub enum ClimbSkill { Speed, } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] +pub enum SwimSkill { + Speed, +} + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum SkillGroupKind { General, diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index d3c72284ea..e463dd44d8 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -4,7 +4,7 @@ use crate::{ inventory::slot::EquipSlot, item::{Hands, ItemKind, Tool, ToolKind}, quadruped_low, quadruped_medium, quadruped_small, ship, - skills::Skill, + skills::{Skill, SwimSkill}, theropod, Body, CharacterAbility, CharacterState, InputKind, InventoryAction, StateUpdate, }, consts::{FRIC_GROUND, GRAVITY}, @@ -299,11 +299,22 @@ pub fn handle_orientation(data: &JoinData, update: &mut StateUpdate, rate: f32) /// Updates components to move player as if theyre swimming fn swim_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32, depth: f32) { + let mut water_accel = BASE_HUMANOID_WATER_ACCEL; + let mut water_speed = BASE_HUMANOID_WATER_SPEED; + if let Ok(Some(level)) = data + .stats + .skill_set + .skill_level(Skill::Swim(SwimSkill::Speed)) + { + water_speed *= 1.4_f32.powi(level.into()); + water_accel *= 1.4_f32.powi(level.into()); + } + // Update velocity update.vel.0 += Vec2::broadcast(data.dt.0) * data.inputs.move_dir - * if update.vel.0.magnitude_squared() < BASE_HUMANOID_WATER_SPEED.powi(2) { - BASE_HUMANOID_WATER_ACCEL + * if update.vel.0.magnitude_squared() < water_speed.powi(2) { + water_accel } else { 0.0 } @@ -324,7 +335,7 @@ fn swim_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32, depth: .inputs .move_z .clamped(-1.0, depth.clamped(0.0, 1.0).powi(3))) - .min(BASE_HUMANOID_WATER_SPEED); + .min(water_speed); } /// Updates components to move entity as if it's flying diff --git a/server/src/persistence/json_models.rs b/server/src/persistence/json_models.rs index ba33df2c9c..05333b0120 100644 --- a/server/src/persistence/json_models.rs +++ b/server/src/persistence/json_models.rs @@ -41,7 +41,7 @@ pub fn skill_to_db_string(skill: comp::skills::Skill) -> String { item::tool::ToolKind, skills::{ AxeSkill, BowSkill, ClimbSkill, GeneralSkill, HammerSkill, RollSkill, SceptreSkill, - Skill::*, SkillGroupKind, StaffSkill, SwordSkill, + Skill::*, SkillGroupKind, StaffSkill, SwimSkill, SwordSkill, }, }; let skill_string = match skill { @@ -136,6 +136,7 @@ pub fn skill_to_db_string(skill: comp::skills::Skill) -> String { Roll(RollSkill::Duration) => "Roll Duration", Climb(ClimbSkill::Cost) => "Climb Cost", Climb(ClimbSkill::Speed) => "Climb Speed", + Swim(SwimSkill::Speed) => "Swim Speed", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sword)) => "Unlock Weapon Sword", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Axe)) => "Unlock Weapon Axe", UnlockGroup(SkillGroupKind::Weapon(ToolKind::Hammer)) => "Unlock Weapon Hammer", @@ -166,7 +167,7 @@ pub fn db_string_to_skill(skill_string: &str) -> comp::skills::Skill { item::tool::ToolKind, skills::{ AxeSkill, BowSkill, ClimbSkill, GeneralSkill, HammerSkill, RollSkill, SceptreSkill, - Skill::*, SkillGroupKind, StaffSkill, SwordSkill, + Skill::*, SkillGroupKind, StaffSkill, SwimSkill, SwordSkill, }, }; match skill_string { @@ -261,6 +262,7 @@ pub fn db_string_to_skill(skill_string: &str) -> comp::skills::Skill { "Roll Duration" => Roll(RollSkill::Duration), "Climb Cost" => Climb(ClimbSkill::Cost), "Climb Speed" => Climb(ClimbSkill::Speed), + "Swim Speed" => Swim(SwimSkill::Speed), "Unlock Weapon Sword" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sword)), "Unlock Weapon Axe" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Axe)), "Unlock Weapon Hammer" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Hammer)), diff --git a/voxygen/src/hud/diary.rs b/voxygen/src/hud/diary.rs index 3bc72a3cf0..1ac9a256de 100644 --- a/voxygen/src/hud/diary.rs +++ b/voxygen/src/hud/diary.rs @@ -166,6 +166,8 @@ widget_ids! { skill_general_climb_0, skill_general_climb_1, skill_general_climb_2, + skill_general_swim_0, + skill_general_swim_1, } } @@ -575,7 +577,7 @@ impl<'a> Widget for Diary<'a> { _ => 0, }; let skills_bot_r = match sel_tab { - SelectedSkillTree::General => 3, + SelectedSkillTree::General => 5, SelectedSkillTree::Weapon(ToolKind::Sword) => 1, SelectedSkillTree::Weapon(ToolKind::Bow) => 1, _ => 0, @@ -706,10 +708,11 @@ impl<'a> Widget for Diary<'a> { match sel_tab { SelectedSkillTree::General => { use skills::{ - ClimbSkill::{self}, + ClimbSkill, GeneralSkill::*, RollSkill::{self, *}, SkillGroupKind::*, + SwimSkill, }; use ToolKind::*; // General Combat @@ -1115,6 +1118,44 @@ impl<'a> Widget for Diary<'a> { { events.push(Event::UnlockSkill(skill)); }; + + Button::image(self.imgs.skill_swim_skill) + .w_h(74.0, 74.0) + .mid_top_with_margin_on(state.skills_bot_r[3], 3.0) + .with_tooltip( + self.tooltip_manager, + &self.localized_strings.get("hud.skill.swim_title"), + &self.localized_strings.get("hud.skill.swim"), + &diary_tooltip, + TEXT_COLOR, + ) + .set(state.skill_general_swim_0, ui); + let skill = Skill::Swim(SwimSkill::Speed); + if create_skill_button( + self.imgs.utility_speed_skill, + state.skills_bot_r[4], + &self.stats.skill_set, + skill, + self.fonts, + &get_skill_label(skill, &self.stats.skill_set), + ) + .with_tooltip( + self.tooltip_manager, + &self.localized_strings.get("hud.skill.swim_speed_title"), + &add_sp_cost_tooltip( + &self.localized_strings.get("hud.skill.swim_speed"), + skill, + &self.stats.skill_set, + &self.localized_strings, + ), + &diary_tooltip, + TEXT_COLOR, + ) + .set(state.skill_general_swim_1, ui) + .was_clicked() + { + events.push(Event::UnlockSkill(skill)); + }; }, SelectedSkillTree::Weapon(ToolKind::Sword) => { use skills::SwordSkill::*; diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 6c71300cba..5a29788a40 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -182,6 +182,7 @@ image_ids! { unlock_sword_skill: "voxygen.element.icons.skilltree.unlock_sword", skill_dodge_skill: "voxygen.element.icons.skilltree.skill_dodge", skill_climbing_skill: "voxygen.element.icons.skilltree.skill_climbing", + skill_swim_skill: "voxygen.element.icons.skilltree.skill_swim", buff_amount_skill: "voxygen.element.icons.skilltree.buff_amount", buff_combo_skill: "voxygen.element.icons.skilltree.buff_combo",