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 diff --git a/assets/common/skill_trees/skill_max_levels.ron b/assets/common/skill_trees/skill_max_levels.ron index 47825a83f2..dc87e72922 100644 --- a/assets/common/skill_trees/skill_max_levels.ron +++ b/assets/common/skill_trees/skill_max_levels.ron @@ -72,4 +72,7 @@ Roll(Cost): Some(2), Roll(Strength): Some(2), 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 74ec09ff14..5d9f33d7cb 100644 --- a/assets/common/skill_trees/skills_skill-groups_manifest.ron +++ b/assets/common/skill_trees/skills_skill-groups_manifest.ron @@ -12,6 +12,9 @@ Roll(Cost), Roll(Strength), Roll(Duration), + Climb(Cost), + Climb(Speed), + Swim(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..7ff07682da --- /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:c69cbd266448298000a236d8ebdfa546f9336127e346a5fe5cb667fba829674f +size 426 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/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..e6fa12cbf7 100644 --- a/assets/voxygen/i18n/en/skills.ron +++ b/assets/voxygen/i18n/en/skills.ron @@ -30,9 +30,19 @@ "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}", + "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 d6da2ef4c4..d63352a702 100644 --- a/assets/voxygen/i18n/fr_FR/skills.ron +++ b/assets/voxygen/i18n/fr_FR/skills.ron @@ -30,9 +30,19 @@ "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": "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/ability.rs b/common/src/comp/ability.rs index abf330855e..25a8433b14 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -1067,7 +1067,6 @@ impl CharacterAbility { } }, None => { - use skills::RollSkill::*; if let CharacterAbility::Roll { ref mut immune_melee, ref mut energy_cost, @@ -1076,6 +1075,7 @@ impl CharacterAbility { .. } = 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()); 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..7582fddf3a 100644 --- a/common/src/comp/skills.rs +++ b/common/src/comp/skills.rs @@ -103,6 +103,8 @@ pub enum Skill { Sceptre(SceptreSkill), UnlockGroup(SkillGroupKind), Roll(RollSkill), + Climb(ClimbSkill), + Swim(SwimSkill), } pub enum SkillError { @@ -250,6 +252,17 @@ 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 SwimSkill { + 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..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::{ @@ -11,11 +14,43 @@ use crate::{ use serde::{Deserialize, Serialize}; use vek::*; -const HUMANOID_CLIMB_ACCEL: f32 = 24.0; -const CLIMB_SPEED: f32 = 5.0; +/// Separated out to condense update portions of character state +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct StaticData { + pub energy_cost: f32, + pub movement_speed: f32, +} -#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] -pub struct Data; +#[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 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 { + static_data: StaticData { + energy_cost: 5.0, + movement_speed: 5.0, + }, + } + } +} impl CharacterBehavior for Data { fn behavior(&self, data: &JoinData) -> StateUpdate { @@ -38,19 +73,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.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 => 5, + Climb::Up => self.static_data.energy_cost as i32, Climb::Down => 1, Climb::Hold => 1, }; @@ -74,8 +108,12 @@ 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.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/src/states/utils.rs b/common/src/states/utils.rs index 68d4e02b1b..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 @@ -407,7 +418,7 @@ pub fn handle_climb(data: &JoinData, update: &mut StateUpdate) { && data.body.can_climb() && update.energy.current() > 100 { - update.character = CharacterState::Climb; + update.character = CharacterState::Climb(climb::Data::create_adjusted_by_skills(data)); } } 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 e45a5a766c..42c3c8788d 100644 --- a/common/sys/src/phys.rs +++ b/common/sys/src/phys.rs @@ -675,7 +675,7 @@ 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)); + 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 9c58a844c5..05333b0120 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, SwimSkill, SwordSkill, }, }; let skill_string = match skill { @@ -134,6 +134,9 @@ 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) => "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", @@ -163,8 +166,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, SwimSkill, SwordSkill, }, }; match skill_string { @@ -257,6 +260,9 @@ 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), + "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 8f1df1759b..1ac9a256de 100644 --- a/voxygen/src/hud/diary.rs +++ b/voxygen/src/hud/diary.rs @@ -163,6 +163,11 @@ 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, + skill_general_swim_0, + skill_general_swim_1, } } @@ -572,6 +577,7 @@ impl<'a> Widget for Diary<'a> { _ => 0, }; let skills_bot_r = match sel_tab { + SelectedSkillTree::General => 5, SelectedSkillTree::Weapon(ToolKind::Sword) => 1, SelectedSkillTree::Weapon(ToolKind::Bow) => 1, _ => 0, @@ -701,7 +707,13 @@ 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, + GeneralSkill::*, + RollSkill::{self, *}, + SkillGroupKind::*, + SwimSkill, + }; use ToolKind::*; // General Combat Image::new(animate_by_pulse( @@ -964,7 +976,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 +1030,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 +1054,108 @@ 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)); + }; + + 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::*; @@ -3537,7 +3651,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..5a29788a40 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -181,6 +181,8 @@ 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", + 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", @@ -198,6 +200,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 +218,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 +236,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 +254,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 +272,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 +290,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",