diff --git a/assets/voxygen/element/buttons/border_skills.png b/assets/voxygen/element/buttons/border_skills.png new file mode 100644 index 0000000000..59ab4cbd69 --- /dev/null +++ b/assets/voxygen/element/buttons/border_skills.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3605396705e9cf0f6a798b1c7c2cf433cfc5762823ae162cc80906be613560e +size 2033 diff --git a/common/net/src/msg/client.rs b/common/net/src/msg/client.rs index 60266156b5..91a8c305c5 100644 --- a/common/net/src/msg/client.rs +++ b/common/net/src/msg/client.rs @@ -2,7 +2,7 @@ use super::PingMsg; use common::{ character::CharacterId, comp, - comp::{Skill, SkillGroupType}, + comp::{Skill, SkillGroupKind}, terrain::block::Block, }; use serde::{Deserialize, Serialize}; @@ -75,7 +75,7 @@ pub enum ClientGeneral { }, UnlockSkill(Skill), RefundSkill(Skill), - UnlockSkillGroup(SkillGroupType), + UnlockSkillGroup(SkillGroupKind), //Always possible ChatMsg(String), Terminate, diff --git a/common/src/combat.rs b/common/src/combat.rs index 470a7231fb..709a050c5c 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -8,7 +8,7 @@ use crate::{ }, slot::EquipSlot, }, - skills::{SkillGroupType, SkillSet}, + skills::{SkillGroupKind, SkillSet}, BuffKind, Health, HealthChange, HealthSource, Inventory, Stats, }, uid::Uid, @@ -231,16 +231,16 @@ pub fn get_weapons(inv: &Inventory) -> (Option, Option) { ) } -fn max_equipped_weapon_damage(inv: &Inventory, skillset: &SkillSet) -> f32 { +fn offensive_rating(inv: &Inventory, skillset: &SkillSet) -> f32 { let active_damage = equipped_tool(inv, EquipSlot::Mainhand).map_or(0.0, |tool| { tool.base_power() * tool.base_speed() - * (1.0 + 0.05 * skillset.earned_sp(SkillGroupType::Weapon(tool.kind)) as f32) + * (1.0 + 0.05 * skillset.earned_sp(SkillGroupKind::Weapon(tool.kind)) as f32) }); let second_damage = equipped_tool(inv, EquipSlot::Offhand).map_or(0.0, |tool| { tool.base_power() * tool.base_speed() - * (1.0 + 0.05 * skillset.earned_sp(SkillGroupType::Weapon(tool.kind)) as f32) + * (1.0 + 0.05 * skillset.earned_sp(SkillGroupKind::Weapon(tool.kind)) as f32) }); active_damage.max(second_damage) } @@ -251,8 +251,8 @@ pub fn combat_rating(inventory: &Inventory, health: &Health, stats: &Stats) -> f let defensive_rating = health.maximum() as f32 / (1.0 - Damage::compute_damage_reduction(inventory)).max(0.00001) / 100.0; - let offensive_rating = max_equipped_weapon_damage(inventory, &stats.skill_set).max(0.1) - + 0.05 * stats.skill_set.earned_sp(SkillGroupType::General) as f32; + let offensive_rating = offensive_rating(inventory, &stats.skill_set).max(0.1) + + 0.05 * stats.skill_set.earned_sp(SkillGroupKind::General) as f32; let combined_rating = (offensive_rating * offensive_weighting + defensive_rating * defensive_weighting) / (offensive_weighting + defensive_weighting); diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index e7123633df..2b3d47aeaf 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -67,6 +67,6 @@ pub use phys::{ pub use player::Player; pub use projectile::{Projectile, ProjectileConstructor}; pub use shockwave::{Shockwave, ShockwaveHitEntities}; -pub use skills::{Skill, SkillGroup, SkillGroupType, SkillSet}; +pub use skills::{Skill, SkillGroup, SkillGroupKind, SkillSet}; pub use stats::Stats; pub use visual::{LightAnimation, LightEmitter}; diff --git a/common/src/comp/skills.rs b/common/src/comp/skills.rs index 0ad4d74100..51eaa3044d 100644 --- a/common/src/comp/skills.rs +++ b/common/src/comp/skills.rs @@ -9,7 +9,7 @@ use std::hash::Hash; use tracing::{trace, warn}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct SkillTreeMap(HashMap>); +pub struct SkillTreeMap(HashMap>); impl Asset for SkillTreeMap { type Loader = assets::RonLoader; @@ -17,6 +17,11 @@ impl Asset for SkillTreeMap { const EXTENSION: &'static str = "ron"; } +pub struct SkillGroupDef { + pub skills: HashSet, + pub total_skill_point_cost: u16, +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SkillLevelMap(HashMap>); @@ -39,10 +44,35 @@ lazy_static! { // Determines the skills that comprise each skill group - this data is used to determine // which of a player's skill groups a particular skill should be added to when a skill unlock // is requested. - pub static ref SKILL_GROUP_DEFS: HashMap> = { - SkillTreeMap::load_expect_cloned( + pub static ref SKILL_GROUP_DEFS: HashMap = { + let map = SkillTreeMap::load_expect_cloned( "common.skill_trees.skills_skill-groups_manifest", - ).0 + ).0; + map.iter().map(|(sgk, skills)| + (*sgk, SkillGroupDef { skills: skills.clone(), + total_skill_point_cost: skills + .iter() + .map(|skill| { + if let Some(max_level) = skill.max_level() { + (1..=max_level) + .into_iter() + .map(|level| skill.skill_cost(Some(level))) + .sum() + } else { + skill.skill_cost(None) + } + }) + .sum() + }) + ) + .collect() + }; + // Creates a hashmap for the reverse lookup of skill groups from a skill + pub static ref SKILL_GROUP_LOOKUP: HashMap = { + let map = SkillTreeMap::load_expect_cloned( + "common.skill_trees.skills_skill-groups_manifest", + ).0; + map.iter().map(|(sgk, skills)| skills.into_iter().map(move |s| (*s, *sgk))).flatten().collect() }; // Loads the maximum level that a skill can obtain pub static ref SKILL_MAX_LEVEL: HashMap> = { @@ -71,7 +101,7 @@ pub enum Skill { Bow(BowSkill), Staff(StaffSkill), Sceptre(SceptreSkill), - UnlockGroup(SkillGroupType), + UnlockGroup(SkillGroupKind), Roll(RollSkill), } @@ -219,12 +249,12 @@ pub enum RollSkill { } #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] -pub enum SkillGroupType { +pub enum SkillGroupKind { General, Weapon(ToolKind), } -impl SkillGroupType { +impl SkillGroupKind { /// Gets the cost in experience of earning a skill point #[allow(clippy::many_single_char_names)] pub fn skill_point_cost(self, level: u16) -> u16 { @@ -243,21 +273,13 @@ impl SkillGroupType { /// Gets the total amount of skill points that can be spent in a particular /// skill group - pub fn max_skill_points(self) -> u16 { - if let Some(skill_list) = SKILL_GROUP_DEFS.get(&self) { - skill_list - .iter() - .map(|skill| { - if let Some(max_level) = skill.max_level() { - (1..=max_level) - .into_iter() - .map(|level| skill.skill_cost(Some(level))) - .sum() - } else { - skill.skill_cost(None) - } - }) - .sum() + pub fn total_skill_point_cost(self) -> u16 { + if let Some(SkillGroupDef { + total_skill_point_cost, + .. + }) = SKILL_GROUP_DEFS.get(&self) + { + *total_skill_point_cost } else { 0 } @@ -269,16 +291,16 @@ impl SkillGroupType { /// skill group. #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] pub struct SkillGroup { - pub skill_group_type: SkillGroupType, + pub skill_group_kind: SkillGroupKind, pub exp: u16, pub available_sp: u16, pub earned_sp: u16, } impl SkillGroup { - fn new(skill_group_type: SkillGroupType) -> SkillGroup { + fn new(skill_group_kind: SkillGroupKind) -> SkillGroup { SkillGroup { - skill_group_type, + skill_group_kind, exp: 0, available_sp: 0, earned_sp: 0, @@ -303,7 +325,7 @@ impl Default for SkillSet { /// player fn default() -> Self { Self { - skill_groups: vec![SkillGroup::new(SkillGroupType::General)], + skill_groups: vec![SkillGroup::new(SkillGroupKind::General)], skills: HashMap::new(), modify_health: false, modify_energy: false, @@ -312,25 +334,23 @@ impl Default for SkillSet { } impl SkillSet { - // TODO: Game design to determine how skill groups are unlocked /// Unlocks a skill group for a player. It starts with 0 exp and 0 skill /// points. /// /// ``` - /// use veloren_common::comp::skills::{SkillGroupType, SkillSet}; + /// use veloren_common::comp::{ + /// item::tool::ToolKind, + /// skills::{SkillGroupKind, SkillSet}, + /// }; /// - /// let mut skillset = SkillSet::new(); - /// skillset.unlock_skill_group(SkillGroupType::Axes); + /// let mut skillset = SkillSet::default(); + /// skillset.unlock_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)); /// - /// assert_eq!(skillset.skill_groups.len(), 1); + /// assert_eq!(skillset.skill_groups.len(), 2); /// ``` - pub fn unlock_skill_group(&mut self, skill_group_type: SkillGroupType) { - if !self - .skill_groups - .iter() - .any(|x| x.skill_group_type == skill_group_type) - { - self.skill_groups.push(SkillGroup::new(skill_group_type)); + pub fn unlock_skill_group(&mut self, skill_group_kind: SkillGroupKind) { + if !self.contains_skill_group(skill_group_kind) { + self.skill_groups.push(SkillGroup::new(skill_group_kind)); } else { warn!("Tried to unlock already known skill group"); } @@ -340,26 +360,21 @@ impl SkillSet { /// group unlocked and available SP in that skill group. /// /// ``` - /// use veloren_common::comp::skills::{Skill, SkillGroupType, SkillSet}; + /// use veloren_common::comp::skills::{GeneralSkill, Skill, SkillGroupKind, SkillSet}; /// - /// let mut skillset = SkillSet::new(); - /// skillset.unlock_skill_group(SkillGroupType::Axes); - /// skillset.add_skill_points(SkillGroupType::Axes, 1); + /// let mut skillset = SkillSet::default(); + /// skillset.add_skill_points(SkillGroupKind::General, 1); /// - /// skillset.unlock_skill(Skill::TestAxeSkill2); + /// skillset.unlock_skill(Skill::General(GeneralSkill::HealthIncrease)); /// /// assert_eq!(skillset.skills.len(), 1); /// ``` pub fn unlock_skill(&mut self, skill: Skill) { - if let Some(skill_group_type) = skill.skill_group_type() { + if let Some(skill_group_kind) = skill.skill_group_kind() { let next_level = self.next_skill_level(skill); let prerequisites_met = self.prerequisites_met(skill); if !matches!(self.skills.get(&skill), Some(level) if *level == skill.max_level()) { - if let Some(mut skill_group) = self - .skill_groups - .iter_mut() - .find(|x| x.skill_group_type == skill_group_type) - { + if let Some(mut skill_group) = self.skill_group_mut(skill_group_kind) { if prerequisites_met { if skill_group.available_sp >= skill.skill_cost(next_level) { skill_group.available_sp -= skill.skill_cost(next_level); @@ -397,33 +412,25 @@ impl SkillSet { /// skill group. /// /// ``` - /// use veloren_common::comp::skills::{Skill, SkillGroupType, SkillSet}; + /// use veloren_common::comp::skills::{GeneralSkill, Skill, SkillGroupKind, SkillSet}; /// - /// let mut skillset = SkillSet::new(); - /// skillset.unlock_skill_group(SkillGroupType::Axes); - /// skillset.add_skill_points(SkillGroupType::Axes, 1); - /// skillset.unlock_skill(Skill::TestAxeSkill2); + /// let mut skillset = SkillSet::default(); + /// skillset.add_skill_points(SkillGroupKind::General, 1); + /// skillset.unlock_skill(Skill::General(GeneralSkill::HealthIncrease)); /// - /// skillset.refund_skill(Skill::TestAxeSkill2); + /// skillset.refund_skill(Skill::General(GeneralSkill::HealthIncrease)); /// /// assert_eq!(skillset.skills.len(), 0); /// ``` pub fn refund_skill(&mut self, skill: Skill) { - if self.has_skill(skill) { - if let Some(skill_group_type) = skill.skill_group_type() { - if let Some(mut skill_group) = self - .skill_groups - .iter_mut() - .find(|x| x.skill_group_type == skill_group_type) - { - let level = self.skills.get(&skill).copied(); - if let Some(level) = level { - skill_group.available_sp += skill.skill_cost(level); - if level.map_or(false, |l| l > 1) { - self.skills.insert(skill, level.map(|l| l - 1)); - } else { - self.skills.remove(&skill); - } + if let Ok(level) = self.skill_level(skill) { + if let Some(skill_group_kind) = skill.skill_group_kind() { + if let Some(mut skill_group) = self.skill_group_mut(skill_group_kind) { + skill_group.available_sp += skill.skill_cost(level); + if level.map_or(false, |l| l > 1) { + self.skills.insert(skill, level.map(|l| l - 1)); + } else { + self.skills.remove(&skill); } } else { warn!("Tried to refund skill for a skill group that player does not have"); @@ -443,24 +450,19 @@ impl SkillSet { /// group type. /// /// ``` - /// use veloren_common::comp::skills::{SkillGroupType, SkillSet}; + /// use veloren_common::comp::skills::{SkillGroupKind, SkillSet}; /// - /// let mut skillset = SkillSet::new(); - /// skillset.unlock_skill_group(SkillGroupType::Axes); - /// skillset.add_skill_points(SkillGroupType::Axes, 1); + /// let mut skillset = SkillSet::default(); + /// skillset.add_skill_points(SkillGroupKind::General, 1); /// /// assert_eq!(skillset.skill_groups[0].available_sp, 1); /// ``` pub fn add_skill_points( &mut self, - skill_group_type: SkillGroupType, + skill_group_kind: SkillGroupKind, number_of_skill_points: u16, ) { - if let Some(mut skill_group) = self - .skill_groups - .iter_mut() - .find(|x| x.skill_group_type == skill_group_type) - { + if let Some(mut skill_group) = self.skill_group_mut(skill_group_kind) { skill_group.available_sp = skill_group .available_sp .saturating_add(number_of_skill_points); @@ -471,13 +473,9 @@ impl SkillSet { } /// Adds a skill point while subtracting the necessary amount of experience - pub fn earn_skill_point(&mut self, skill_group_type: SkillGroupType) { - let sp_cost = self.skill_point_cost(skill_group_type); - if let Some(mut skill_group) = self - .skill_groups - .iter_mut() - .find(|x| x.skill_group_type == skill_group_type) - { + pub fn earn_skill_point(&mut self, skill_group_kind: SkillGroupKind) { + let sp_cost = self.skill_point_cost(skill_group_kind); + if let Some(mut skill_group) = self.skill_group_mut(skill_group_kind) { skill_group.exp = skill_group.exp.saturating_sub(sp_cost); skill_group.available_sp = skill_group.available_sp.saturating_add(1); skill_group.earned_sp = skill_group.earned_sp.saturating_add(1); @@ -486,20 +484,16 @@ impl SkillSet { /// Checks if the skill set of an entity contains a particular skill group /// type - pub fn contains_skill_group(&self, skill_group_type: SkillGroupType) -> bool { + pub fn contains_skill_group(&self, skill_group_kind: SkillGroupKind) -> bool { self.skill_groups .iter() - .any(|x| x.skill_group_type == skill_group_type) + .any(|x| x.skill_group_kind == skill_group_kind) } /// Adds/subtracts experience to the skill group within an entity's skill /// set - pub fn change_experience(&mut self, skill_group_type: SkillGroupType, amount: i32) { - if let Some(mut skill_group) = self - .skill_groups - .iter_mut() - .find(|x| x.skill_group_type == skill_group_type) - { + pub fn change_experience(&mut self, skill_group_kind: SkillGroupKind, amount: i32) { + if let Some(mut skill_group) = self.skill_group_mut(skill_group_kind) { skill_group.exp = (skill_group.exp as i32 + amount) as u16; } else { warn!("Tried to add experience to a skill group that player does not have"); @@ -509,36 +503,39 @@ impl SkillSet { /// Checks that the skill set contains all prerequisite skills for a /// particular skill pub fn prerequisites_met(&self, skill: Skill) -> bool { - let next_level = self.next_skill_level(skill); - skill.prerequisite_skills(next_level).iter().all(|(s, l)| { - self.skill_level(*s).map_or(false, |l_b| l_b >= *l) - /* self.has_skill(*s) && self.skills.get(s).map_or(false, |l_b| - * l_b >= l) */ - }) + skill + .prerequisite_skills() + .all(|(s, l)| self.skill_level(s).map_or(false, |l_b| l_b >= l)) + } + + /// Returns a reference to a particular skill group in a skillset + fn skill_group(&self, skill_group: SkillGroupKind) -> Option<&SkillGroup> { + self.skill_groups + .iter() + .find(|s_g| s_g.skill_group_kind == skill_group) + } + + /// Returns a reference to a particular skill group in a skillset + fn skill_group_mut(&mut self, skill_group: SkillGroupKind) -> Option<&mut SkillGroup> { + self.skill_groups + .iter_mut() + .find(|s_g| s_g.skill_group_kind == skill_group) } /// Gets the available points for a particular skill group - pub fn available_sp(&self, skill_group: SkillGroupType) -> u16 { - self.skill_groups - .iter() - .find(|s_g| s_g.skill_group_type == skill_group) + pub fn available_sp(&self, skill_group: SkillGroupKind) -> u16 { + self.skill_group(skill_group) .map_or(0, |s_g| s_g.available_sp) } /// Gets the total earned points for a particular skill group - pub fn earned_sp(&self, skill_group: SkillGroupType) -> u16 { - self.skill_groups - .iter() - .find(|s_g| s_g.skill_group_type == skill_group) - .map_or(0, |s_g| s_g.earned_sp) + pub fn earned_sp(&self, skill_group: SkillGroupKind) -> u16 { + self.skill_group(skill_group).map_or(0, |s_g| s_g.earned_sp) } /// Gets the available experience for a particular skill group - pub fn experience(&self, skill_group: SkillGroupType) -> u16 { - self.skill_groups - .iter() - .find(|s_g| s_g.skill_group_type == skill_group) - .map_or(0, |s_g| s_g.exp) + pub fn experience(&self, skill_group: SkillGroupKind) -> u16 { + self.skill_group(skill_group).map_or(0, |s_g| s_g.exp) } /// Gets skill point cost to purchase skill of next level @@ -549,11 +546,11 @@ impl SkillSet { /// Checks if player has sufficient skill points to purchase a skill pub fn sufficient_skill_points(&self, skill: Skill) -> bool { - if let Some(skill_group_type) = skill.skill_group_type() { + if let Some(skill_group_kind) = skill.skill_group_kind() { if let Some(skill_group) = self .skill_groups .iter() - .find(|x| x.skill_group_type == skill_group_type) + .find(|x| x.skill_group_kind == skill_group_kind) { let needed_sp = self.skill_cost(skill); skill_group.available_sp >= needed_sp @@ -569,18 +566,13 @@ impl SkillSet { pub fn has_available_sp(&self) -> bool { self.skill_groups.iter().any(|sg| { sg.available_sp > 0 - && (sg.earned_sp - sg.available_sp) < sg.skill_group_type.max_skill_points() + && (sg.earned_sp - sg.available_sp) < sg.skill_group_kind.total_skill_point_cost() }) } /// Checks how much experience is needed for the next skill point in a tree - pub fn skill_point_cost(&self, skill_group: SkillGroupType) -> u16 { - if let Some(level) = self - .skill_groups - .iter() - .find(|sg| sg.skill_group_type == skill_group) - .map(|sg| sg.earned_sp) - { + pub fn skill_point_cost(&self, skill_group: SkillGroupKind) -> u16 { + if let Some(level) = self.skill_group(skill_group).map(|sg| sg.earned_sp) { skill_group.skill_point_cost(level) } else { skill_group.skill_point_cost(0) @@ -621,36 +613,28 @@ impl SkillSet { impl Skill { /// Returns a vec of prerequisite skills (it should only be necessary to /// note direct prerequisites) - pub fn prerequisite_skills(self, level: Option) -> HashMap> { - let mut prerequisites = HashMap::new(); - if let Some(level) = level { - if level > 1 { - // For skills above level 1, sets prerequisite of skill of lower level - prerequisites.insert(self, Some(level - 1)); - } - } - if let Some(skills) = SKILL_PREREQUISITES.get(&self) { - prerequisites.extend(skills); - } - prerequisites + pub fn prerequisite_skills(&self) -> impl Iterator)> { + SKILL_PREREQUISITES + .get(&self) + .into_iter() + .flatten() + .map(|(skill, level)| (*skill, *level)) } /// Returns the cost in skill points of unlocking a particular skill - pub fn skill_cost(self, level: Option) -> u16 { + pub fn skill_cost(&self, level: Option) -> u16 { // TODO: Better balance the costs later level.unwrap_or(1) } /// Returns the maximum level a skill can reach, returns None if the skill /// doesn't level - pub fn max_level(self) -> Option { SKILL_MAX_LEVEL.get(&self).copied().flatten() } + pub fn max_level(&self) -> Option { SKILL_MAX_LEVEL.get(&self).copied().flatten() } /// Returns the skill group type for a skill from the static skill group /// definitions. - pub fn skill_group_type(self) -> Option { - SKILL_GROUP_DEFS - .iter() - .find_map(|(key, val)| val.contains(&self).then_some(*key)) + pub fn skill_group_kind(&self) -> Option { + SKILL_GROUP_LOOKUP.get(&self).copied() } } @@ -661,8 +645,8 @@ mod tests { #[test] fn test_refund_skill() { let mut skillset = SkillSet::default(); - skillset.unlock_skill_group(SkillGroupType::Weapon(ToolKind::Axe)); - skillset.add_skill_points(SkillGroupType::Weapon(ToolKind::Axe), 1); + skillset.unlock_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)); + skillset.add_skill_points(SkillGroupKind::Weapon(ToolKind::Axe), 1); skillset.unlock_skill(Skill::Axe(AxeSkill::UnlockLeap)); assert_eq!(skillset.skill_groups[1].available_sp, 0); @@ -678,12 +662,12 @@ mod tests { #[test] fn test_unlock_skillgroup() { let mut skillset = SkillSet::default(); - skillset.unlock_skill_group(SkillGroupType::Weapon(ToolKind::Axe)); + skillset.unlock_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)); assert_eq!(skillset.skill_groups.len(), 2); assert_eq!( skillset.skill_groups[1], - SkillGroup::new(SkillGroupType::Weapon(ToolKind::Axe)) + SkillGroup::new(SkillGroupKind::Weapon(ToolKind::Axe)) ); } @@ -691,8 +675,8 @@ mod tests { fn test_unlock_skill() { let mut skillset = SkillSet::default(); - skillset.unlock_skill_group(SkillGroupType::Weapon(ToolKind::Axe)); - skillset.add_skill_points(SkillGroupType::Weapon(ToolKind::Axe), 1); + skillset.unlock_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)); + skillset.add_skill_points(SkillGroupKind::Weapon(ToolKind::Axe), 1); assert_eq!(skillset.skill_groups[1].available_sp, 1); assert_eq!(skillset.skills.len(), 0); @@ -714,8 +698,8 @@ mod tests { #[test] fn test_add_skill_points() { let mut skillset = SkillSet::default(); - skillset.unlock_skill_group(SkillGroupType::Weapon(ToolKind::Axe)); - skillset.add_skill_points(SkillGroupType::Weapon(ToolKind::Axe), 1); + skillset.unlock_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)); + skillset.add_skill_points(SkillGroupKind::Weapon(ToolKind::Axe), 1); assert_eq!(skillset.skill_groups[1].available_sp, 1); } diff --git a/common/src/outcome.rs b/common/src/outcome.rs index 653501ce93..6954c28a43 100644 --- a/common/src/outcome.rs +++ b/common/src/outcome.rs @@ -32,7 +32,7 @@ pub enum Outcome { }, SkillPointGain { uid: Uid, - skill_tree: comp::skills::SkillGroupType, + skill_tree: comp::skills::SkillGroupKind, total_points: u16, // TODO: Access ECS to get position from Uid to conserve bandwidth pos: Vec3, diff --git a/common/src/skillset_builder.rs b/common/src/skillset_builder.rs index 75aec005ab..3898c4dc5d 100644 --- a/common/src/skillset_builder.rs +++ b/common/src/skillset_builder.rs @@ -1,7 +1,7 @@ use crate::comp::{ item::{tool::ToolKind, Item, ItemKind}, skills::{ - AxeSkill, BowSkill, HammerSkill, Skill, SkillGroupType, SkillSet, StaffSkill, SwordSkill, + AxeSkill, BowSkill, HammerSkill, Skill, SkillGroupKind, SkillSet, StaffSkill, SwordSkill, }, }; use tracing::warn; @@ -41,7 +41,7 @@ impl SkillSetBuilder { if let Some(ToolKind::Sword) = active_item { // Sword Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) .with_skill(Skill::Sword(SwordSkill::TsCombo)) .with_skill(Skill::Sword(SwordSkill::TsDamage)) .with_skill(Skill::Sword(SwordSkill::TsRegen)) @@ -66,7 +66,7 @@ impl SkillSetBuilder { Some(ToolKind::Sword) => { // Sword Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) .with_skill(Skill::Sword(SwordSkill::TsCombo)) .with_skill(Skill::Sword(SwordSkill::DDamage)) .with_skill(Skill::Sword(SwordSkill::DCost)) @@ -74,7 +74,7 @@ impl SkillSetBuilder { Some(ToolKind::Axe) => { // Axe Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Axe)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) .with_skill(Skill::Axe(AxeSkill::DsCombo)) .with_skill(Skill::Axe(AxeSkill::SInfinite)) .with_skill(Skill::Axe(AxeSkill::SSpeed)) @@ -83,7 +83,7 @@ impl SkillSetBuilder { Some(ToolKind::Hammer) => { // Hammer Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) .with_skill(Skill::Hammer(HammerSkill::SsKnockback)) .with_skill(Skill::Hammer(HammerSkill::SsSpeed)) .with_skill(Skill::Hammer(HammerSkill::CKnockback)) @@ -92,7 +92,7 @@ impl SkillSetBuilder { Some(ToolKind::Bow) => { // Bow Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Bow)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) .with_skill(Skill::Bow(BowSkill::BDamage)) .with_skill(Skill::Bow(BowSkill::ProjSpeed)) .with_skill(Skill::Bow(BowSkill::CDamage)) @@ -102,7 +102,7 @@ impl SkillSetBuilder { Some(ToolKind::Staff) => { // Staff Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Staff)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) .with_skill(Skill::Staff(StaffSkill::FDamage)) .with_skill(Skill::Staff(StaffSkill::FDrain)) .with_skill(Skill::Staff(StaffSkill::FVelocity)) @@ -115,7 +115,7 @@ impl SkillSetBuilder { Some(ToolKind::Sword) => { // Sword Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) .with_skill(Skill::Sword(SwordSkill::TsCombo)) .with_skill(Skill::Sword(SwordSkill::TsDamage)) .with_skill(Skill::Sword(SwordSkill::DDamage)) @@ -126,7 +126,7 @@ impl SkillSetBuilder { Some(ToolKind::Axe) => { // Axe Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Axe)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) .with_skill(Skill::Axe(AxeSkill::DsCombo)) .with_skill(Skill::Axe(AxeSkill::DsDamage)) .with_skill(Skill::Axe(AxeSkill::SInfinite)) @@ -138,7 +138,7 @@ impl SkillSetBuilder { Some(ToolKind::Hammer) => { // Hammer Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) .with_skill(Skill::Hammer(HammerSkill::SsKnockback)) .with_skill(Skill::Hammer(HammerSkill::SsDamage)) .with_skill(Skill::Hammer(HammerSkill::SsSpeed)) @@ -150,7 +150,7 @@ impl SkillSetBuilder { Some(ToolKind::Bow) => { // Bow Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Bow)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) .with_skill(Skill::Bow(BowSkill::BDamage)) .with_skill(Skill::Bow(BowSkill::CDamage)) .with_skill(Skill::Bow(BowSkill::CKnockback)) @@ -162,7 +162,7 @@ impl SkillSetBuilder { Some(ToolKind::Staff) => { // Staff Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Staff)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) .with_skill(Skill::Staff(StaffSkill::BExplosion)) .with_skill(Skill::Staff(StaffSkill::BRegen)) .with_skill(Skill::Staff(StaffSkill::BRadius)) @@ -179,7 +179,7 @@ impl SkillSetBuilder { Some(ToolKind::Sword) => { // Sword Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) .with_skill(Skill::Sword(SwordSkill::TsCombo)) .with_skill(Skill::Sword(SwordSkill::TsDamage)) .with_skill(Skill::Sword(SwordSkill::DDamage)) @@ -192,7 +192,7 @@ impl SkillSetBuilder { Some(ToolKind::Axe) => { // Axe Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Axe)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) .with_skill(Skill::Axe(AxeSkill::DsCombo)) .with_skill(Skill::Axe(AxeSkill::DsSpeed)) .with_skill(Skill::Axe(AxeSkill::DsRegen)) @@ -206,7 +206,7 @@ impl SkillSetBuilder { Some(ToolKind::Hammer) => { // Hammer Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) .with_skill(Skill::Hammer(HammerSkill::SsKnockback)) .with_skill(Skill::Hammer(HammerSkill::SsDamage)) .with_skill(Skill::Hammer(HammerSkill::SsRegen)) @@ -220,7 +220,7 @@ impl SkillSetBuilder { Some(ToolKind::Bow) => { // Bow Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Bow)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) .with_skill(Skill::Bow(BowSkill::BDamage)) .with_skill(Skill::Bow(BowSkill::ProjSpeed)) .with_skill(Skill::Bow(BowSkill::BRegen)) @@ -234,7 +234,7 @@ impl SkillSetBuilder { Some(ToolKind::Staff) => { // Staff Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Staff)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) .with_skill(Skill::Staff(StaffSkill::BExplosion)) .with_skill(Skill::Staff(StaffSkill::FDamage)) .with_skill(Skill::Staff(StaffSkill::FRange)) @@ -251,7 +251,7 @@ impl SkillSetBuilder { Some(ToolKind::Sword) => { // Sword Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) .with_skill(Skill::Sword(SwordSkill::TsCombo)) .with_skill(Skill::Sword(SwordSkill::TsRegen)) .with_skill(Skill::Sword(SwordSkill::TsSpeed)) @@ -267,7 +267,7 @@ impl SkillSetBuilder { Some(ToolKind::Axe) => { // Axe Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Axe)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) .with_skill(Skill::Axe(AxeSkill::DsCombo)) .with_skill(Skill::Axe(AxeSkill::SInfinite)) .with_skill(Skill::Axe(AxeSkill::SHelicopter)) @@ -279,7 +279,7 @@ impl SkillSetBuilder { Some(ToolKind::Hammer) => { // Hammer Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) .with_skill(Skill::Hammer(HammerSkill::SsKnockback)) .with_skill(Skill::Hammer(HammerSkill::SsSpeed)) .with_skill(Skill::Hammer(HammerSkill::SsRegen)) @@ -294,7 +294,7 @@ impl SkillSetBuilder { Some(ToolKind::Bow) => { // Bow Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Bow)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) .with_skill(Skill::Bow(BowSkill::BDamage)) .with_skill(Skill::Bow(BowSkill::ProjSpeed)) .with_skill(Skill::Bow(BowSkill::CDamage)) @@ -309,7 +309,7 @@ impl SkillSetBuilder { Some(ToolKind::Staff) => { // Staff Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Staff)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) .with_skill(Skill::Staff(StaffSkill::BExplosion)) .with_skill(Skill::Staff(StaffSkill::BDamage)) .with_skill(Skill::Staff(StaffSkill::BRadius)) @@ -329,7 +329,7 @@ impl SkillSetBuilder { Some(ToolKind::Sword) => { // Sword Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) .with_skill(Skill::Sword(SwordSkill::TsCombo)) .with_skill(Skill::Sword(SwordSkill::TsDamage)) .with_skill(Skill::Sword(SwordSkill::TsSpeed)) @@ -343,7 +343,7 @@ impl SkillSetBuilder { Some(ToolKind::Axe) => { // Axe Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Axe)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) .with_skill(Skill::Axe(AxeSkill::DsCombo)) .with_skill(Skill::Axe(AxeSkill::DsDamage)) .with_skill(Skill::Axe(AxeSkill::SInfinite)) @@ -358,7 +358,7 @@ impl SkillSetBuilder { Some(ToolKind::Hammer) => { // Hammer Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) .with_skill(Skill::Hammer(HammerSkill::SsKnockback)) .with_skill(Skill::Hammer(HammerSkill::SsDamage)) .with_skill(Skill::Hammer(HammerSkill::SsRegen)) @@ -372,7 +372,7 @@ impl SkillSetBuilder { Some(ToolKind::Bow) => { // Bow Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Bow)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) .with_skill(Skill::Bow(BowSkill::BDamage)) .with_skill(Skill::Bow(BowSkill::CDamage)) .with_skill(Skill::Bow(BowSkill::CKnockback)) @@ -387,7 +387,7 @@ impl SkillSetBuilder { Some(ToolKind::Staff) => { // Staff Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Staff)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) .with_skill(Skill::Staff(StaffSkill::BExplosion)) .with_skill(Skill::Staff(StaffSkill::BDamage)) .with_skill(Skill::Staff(StaffSkill::BRadius)) @@ -407,7 +407,7 @@ impl SkillSetBuilder { Some(ToolKind::Sword) => { // Sword Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) .with_skill(Skill::Sword(SwordSkill::TsCombo)) .with_skill(Skill::Sword(SwordSkill::TsDamage)) .with_skill(Skill::Sword(SwordSkill::TsRegen)) @@ -423,7 +423,7 @@ impl SkillSetBuilder { Some(ToolKind::Axe) => { // Axe Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Axe)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) .with_skill(Skill::Axe(AxeSkill::DsCombo)) .with_skill(Skill::Axe(AxeSkill::DsDamage)) .with_skill(Skill::Axe(AxeSkill::DsSpeed)) @@ -440,7 +440,7 @@ impl SkillSetBuilder { Some(ToolKind::Hammer) => { // Hammer Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) .with_skill(Skill::Hammer(HammerSkill::SsKnockback)) .with_skill(Skill::Hammer(HammerSkill::SsDamage)) .with_skill(Skill::Hammer(HammerSkill::SsSpeed)) @@ -457,7 +457,7 @@ impl SkillSetBuilder { Some(ToolKind::Bow) => { // Bow Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Bow)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) .with_skill(Skill::Bow(BowSkill::BDamage)) .with_skill(Skill::Bow(BowSkill::BRegen)) .with_skill(Skill::Bow(BowSkill::CDamage)) @@ -474,7 +474,7 @@ impl SkillSetBuilder { Some(ToolKind::Staff) => { // Staff Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Staff)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) .with_skill(Skill::Staff(StaffSkill::BExplosion)) .with_skill(Skill::Staff(StaffSkill::BDamage)) .with_skill(Skill::Staff(StaffSkill::BRegen)) @@ -495,7 +495,7 @@ impl SkillSetBuilder { Some(ToolKind::Sword) => { // Sword Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) .with_skill(Skill::Sword(SwordSkill::TsCombo)) .with_skill(Skill::Sword(SwordSkill::TsDamage)) .with_skill(Skill::Sword(SwordSkill::TsRegen)) @@ -515,7 +515,7 @@ impl SkillSetBuilder { Some(ToolKind::Axe) => { // Axe Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Axe)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) .with_skill(Skill::Axe(AxeSkill::DsCombo)) .with_skill(Skill::Axe(AxeSkill::DsDamage)) .with_skill(Skill::Axe(AxeSkill::DsSpeed)) @@ -534,7 +534,7 @@ impl SkillSetBuilder { Some(ToolKind::Hammer) => { // Hammer Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) .with_skill(Skill::Hammer(HammerSkill::SsKnockback)) .with_skill(Skill::Hammer(HammerSkill::SsDamage)) .with_skill(Skill::Hammer(HammerSkill::SsSpeed)) @@ -553,7 +553,7 @@ impl SkillSetBuilder { Some(ToolKind::Bow) => { // Bow Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Bow)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) .with_skill(Skill::Bow(BowSkill::BDamage)) .with_skill(Skill::Bow(BowSkill::ProjSpeed)) .with_skill(Skill::Bow(BowSkill::BRegen)) @@ -572,7 +572,7 @@ impl SkillSetBuilder { Some(ToolKind::Staff) => { // Staff Self::default() - .with_skill_group(SkillGroupType::Weapon(ToolKind::Staff)) + .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) .with_skill(Skill::Staff(StaffSkill::BExplosion)) .with_skill(Skill::Staff(StaffSkill::BDamage)) .with_skill(Skill::Staff(StaffSkill::BRegen)) @@ -595,7 +595,7 @@ impl SkillSetBuilder { } pub fn with_skill(mut self, skill: Skill) -> Self { - if let Some(skill_group) = skill.skill_group_type() { + if let Some(skill_group) = skill.skill_group_kind() { self.0 .add_skill_points(skill_group, self.0.skill_cost(skill)); self.0.unlock_skill(skill); @@ -615,7 +615,7 @@ impl SkillSetBuilder { self } - pub fn with_skill_group(mut self, skill_group: SkillGroupType) -> Self { + pub fn with_skill_group(mut self, skill_group: SkillGroupKind) -> Self { self.0.unlock_skill_group(skill_group); self } diff --git a/common/sys/src/stats.rs b/common/sys/src/stats.rs index 8a698ca5e1..2f6bfe3aeb 100644 --- a/common/sys/src/stats.rs +++ b/common/sys/src/stats.rs @@ -91,8 +91,8 @@ impl<'a> System<'a> for Sys { .skill_groups .iter() .filter_map(|s_g| { - (s_g.exp >= stat.skill_set.skill_point_cost(s_g.skill_group_type)) - .then(|| s_g.skill_group_type) + (s_g.exp >= stat.skill_set.skill_point_cost(s_g.skill_group_kind)) + .then(|| s_g.skill_group_kind) }) .collect::>(); diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 79a6841d27..0a5aea2244 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -2053,16 +2053,16 @@ fn handle_skill_point( } } -fn parse_skill_tree(skill_tree: &str) -> Option { - use comp::{item::tool::ToolKind, skills::SkillGroupType}; +fn parse_skill_tree(skill_tree: &str) -> Option { + use comp::{item::tool::ToolKind, skills::SkillGroupKind}; match skill_tree { - "general" => Some(SkillGroupType::General), - "sword" => Some(SkillGroupType::Weapon(ToolKind::Sword)), - "axe" => Some(SkillGroupType::Weapon(ToolKind::Axe)), - "hammer" => Some(SkillGroupType::Weapon(ToolKind::Hammer)), - "bow" => Some(SkillGroupType::Weapon(ToolKind::Bow)), - "staff" => Some(SkillGroupType::Weapon(ToolKind::Staff)), - "sceptre" => Some(SkillGroupType::Weapon(ToolKind::Sceptre)), + "general" => Some(SkillGroupKind::General), + "sword" => Some(SkillGroupKind::Weapon(ToolKind::Sword)), + "axe" => Some(SkillGroupKind::Weapon(ToolKind::Axe)), + "hammer" => Some(SkillGroupKind::Weapon(ToolKind::Hammer)), + "bow" => Some(SkillGroupKind::Weapon(ToolKind::Bow)), + "staff" => Some(SkillGroupKind::Weapon(ToolKind::Staff)), + "sceptre" => Some(SkillGroupKind::Weapon(ToolKind::Sceptre)), _ => None, } } diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 4791124e6f..da95b8f51d 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -1,7 +1,7 @@ use crate::{ client::Client, comp::{ - biped_large, quadruped_low, quadruped_medium, quadruped_small, skills::SkillGroupType, + biped_large, quadruped_low, quadruped_medium, quadruped_small, skills::SkillGroupKind, theropod, PhysicsState, }, rtsim::RtSim, @@ -234,7 +234,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc (entity, uid) }) .collect::>(); - // Devides exp reward by square root of number of people in group + // Divides exp reward by square root of number of people in group exp_reward /= (non_pet_group_members_in_range as f32).sqrt(); members_in_range.into_iter().for_each(|(e, uid)| { if let (Some(inventory), Some(mut stats)) = (inventories.get(e), stats.get_mut(e)) { @@ -796,22 +796,22 @@ fn handle_exp_gain( outcomes: &mut Vec, ) { let (main_tool_kind, second_tool_kind) = combat::get_weapons(inventory); - let mut xp_pools = HashSet::::new(); - xp_pools.insert(SkillGroupType::General); + let mut xp_pools = HashSet::::new(); + xp_pools.insert(SkillGroupKind::General); if let Some(w) = main_tool_kind { if stats .skill_set - .contains_skill_group(SkillGroupType::Weapon(w)) + .contains_skill_group(SkillGroupKind::Weapon(w)) { - xp_pools.insert(SkillGroupType::Weapon(w)); + xp_pools.insert(SkillGroupKind::Weapon(w)); } } if let Some(w) = second_tool_kind { if stats .skill_set - .contains_skill_group(SkillGroupType::Weapon(w)) + .contains_skill_group(SkillGroupKind::Weapon(w)) { - xp_pools.insert(SkillGroupType::Weapon(w)); + xp_pools.insert(SkillGroupKind::Weapon(w)); } } let num_pools = xp_pools.len() as f32; diff --git a/server/src/migrations/2020-12-13-172324_skills/up.sql b/server/src/migrations/2020-12-13-172324_skills/up.sql index 507a6ee0d7..7e68474361 100644 --- a/server/src/migrations/2020-12-13-172324_skills/up.sql +++ b/server/src/migrations/2020-12-13-172324_skills/up.sql @@ -34,12 +34,12 @@ DROP TABLE stats; -- Creates new table for skill groups CREATE TABLE skill_group ( entity_id INTEGER NOT NULL, - skill_group_type TEXT NOT NULL, + skill_group_kind TEXT NOT NULL, exp INTEGER NOT NULL, available_sp INTEGER NOT NULL, earned_sp INTEGER NOT NULL, FOREIGN KEY(entity_id) REFERENCES entity(entity_id), - PRIMARY KEY(entity_id,skill_group_type) + PRIMARY KEY(entity_id,skill_group_kind) ); -- Creates new table for skills diff --git a/server/src/persistence/character/conversions.rs b/server/src/persistence/character/conversions.rs index b4f2e38ad1..77f8b67007 100644 --- a/server/src/persistence/character/conversions.rs +++ b/server/src/persistence/character/conversions.rs @@ -367,9 +367,9 @@ fn get_item_from_asset(item_definition_id: &str) -> Result Vec { let mut new_skill_groups = Vec::new(); for skill_group in skill_groups.iter() { - let skill_group_type = json_models::db_string_to_skill_group(&skill_group.skill_group_type); + let skill_group_kind = json_models::db_string_to_skill_group(&skill_group.skill_group_kind); let new_skill_group = skills::SkillGroup { - skill_group_type, + skill_group_kind, exp: skill_group.exp as u16, available_sp: skill_group.available_sp as u16, earned_sp: skill_group.earned_sp as u16, @@ -396,7 +396,7 @@ pub fn convert_skill_groups_to_database( .into_iter() .map(|sg| SkillGroup { entity_id, - skill_group_type: json_models::skill_group_to_db_string(sg.skill_group_type), + skill_group_kind: json_models::skill_group_to_db_string(sg.skill_group_kind), exp: sg.exp as i32, available_sp: sg.available_sp as i32, earned_sp: sg.earned_sp as i32, diff --git a/server/src/persistence/json_models.rs b/server/src/persistence/json_models.rs index 4a09580b5a..99bddbe5ed 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, GeneralSkill, HammerSkill, RollSkill, SceptreSkill, Skill::*, - SkillGroupType, StaffSkill, SwordSkill, + SkillGroupKind, StaffSkill, SwordSkill, }, }; let skill_string = match skill { @@ -133,19 +133,19 @@ 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", - UnlockGroup(SkillGroupType::Weapon(ToolKind::Sword)) => "Unlock Weapon Sword", - UnlockGroup(SkillGroupType::Weapon(ToolKind::Axe)) => "Unlock Weapon Axe", - UnlockGroup(SkillGroupType::Weapon(ToolKind::Hammer)) => "Unlock Weapon Hammer", - UnlockGroup(SkillGroupType::Weapon(ToolKind::Bow)) => "Unlock Weapon Bow", - UnlockGroup(SkillGroupType::Weapon(ToolKind::Staff)) => "Unlock Weapon Staff", - UnlockGroup(SkillGroupType::Weapon(ToolKind::Sceptre)) => "Unlock Weapon Sceptre", - UnlockGroup(SkillGroupType::Weapon(ToolKind::Dagger)) - | UnlockGroup(SkillGroupType::Weapon(ToolKind::Shield)) - | UnlockGroup(SkillGroupType::Weapon(ToolKind::Debug)) - | UnlockGroup(SkillGroupType::Weapon(ToolKind::Farming)) - | UnlockGroup(SkillGroupType::Weapon(ToolKind::Empty)) - | UnlockGroup(SkillGroupType::Weapon(ToolKind::Unique(_))) - | UnlockGroup(SkillGroupType::General) => { + UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sword)) => "Unlock Weapon Sword", + UnlockGroup(SkillGroupKind::Weapon(ToolKind::Axe)) => "Unlock Weapon Axe", + UnlockGroup(SkillGroupKind::Weapon(ToolKind::Hammer)) => "Unlock Weapon Hammer", + UnlockGroup(SkillGroupKind::Weapon(ToolKind::Bow)) => "Unlock Weapon Bow", + UnlockGroup(SkillGroupKind::Weapon(ToolKind::Staff)) => "Unlock Weapon Staff", + UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sceptre)) => "Unlock Weapon Sceptre", + UnlockGroup(SkillGroupKind::Weapon(ToolKind::Dagger)) + | UnlockGroup(SkillGroupKind::Weapon(ToolKind::Shield)) + | UnlockGroup(SkillGroupKind::Weapon(ToolKind::Debug)) + | UnlockGroup(SkillGroupKind::Weapon(ToolKind::Farming)) + | UnlockGroup(SkillGroupKind::Weapon(ToolKind::Empty)) + | UnlockGroup(SkillGroupKind::Weapon(ToolKind::Unique(_))) + | UnlockGroup(SkillGroupKind::General) => { panic!("Tried to add unsupported skill to database: {:?}", skill) }, }; @@ -157,7 +157,7 @@ pub fn db_string_to_skill(skill_string: &str) -> comp::skills::Skill { item::tool::ToolKind, skills::{ AxeSkill, BowSkill, GeneralSkill, HammerSkill, RollSkill, SceptreSkill, Skill::*, - SkillGroupType, StaffSkill, SwordSkill, + SkillGroupKind, StaffSkill, SwordSkill, }, }; match skill_string { @@ -249,12 +249,12 @@ 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), - "Unlock Weapon Sword" => UnlockGroup(SkillGroupType::Weapon(ToolKind::Sword)), - "Unlock Weapon Axe" => UnlockGroup(SkillGroupType::Weapon(ToolKind::Axe)), - "Unlock Weapon Hammer" => UnlockGroup(SkillGroupType::Weapon(ToolKind::Hammer)), - "Unlock Weapon Bow" => UnlockGroup(SkillGroupType::Weapon(ToolKind::Bow)), - "Unlock Weapon Staff" => UnlockGroup(SkillGroupType::Weapon(ToolKind::Staff)), - "Unlock Weapon Sceptre" => UnlockGroup(SkillGroupType::Weapon(ToolKind::Sceptre)), + "Unlock Weapon Sword" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sword)), + "Unlock Weapon Axe" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Axe)), + "Unlock Weapon Hammer" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Hammer)), + "Unlock Weapon Bow" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Bow)), + "Unlock Weapon Staff" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Staff)), + "Unlock Weapon Sceptre" => UnlockGroup(SkillGroupKind::Weapon(ToolKind::Sceptre)), _ => { panic!( "Tried to convert an unsupported string from the database: {}", @@ -264,8 +264,8 @@ pub fn db_string_to_skill(skill_string: &str) -> comp::skills::Skill { } } -pub fn skill_group_to_db_string(skill_group: comp::skills::SkillGroupType) -> String { - use comp::{item::tool::ToolKind, skills::SkillGroupType::*}; +pub fn skill_group_to_db_string(skill_group: comp::skills::SkillGroupKind) -> String { + use comp::{item::tool::ToolKind, skills::SkillGroupKind::*}; let skill_group_string = match skill_group { General => "General", Weapon(ToolKind::Sword) => "Weapon Sword", @@ -287,8 +287,8 @@ pub fn skill_group_to_db_string(skill_group: comp::skills::SkillGroupType) -> St skill_group_string.to_string() } -pub fn db_string_to_skill_group(skill_group_string: &str) -> comp::skills::SkillGroupType { - use comp::{item::tool::ToolKind, skills::SkillGroupType::*}; +pub fn db_string_to_skill_group(skill_group_string: &str) -> comp::skills::SkillGroupKind { + use comp::{item::tool::ToolKind, skills::SkillGroupKind::*}; match skill_group_string { "General" => General, "Weapon Sword" => Weapon(ToolKind::Sword), diff --git a/server/src/persistence/models.rs b/server/src/persistence/models.rs index 288da1492e..ce73a5e146 100644 --- a/server/src/persistence/models.rs +++ b/server/src/persistence/models.rs @@ -57,11 +57,11 @@ pub struct Skill { } #[derive(Associations, Identifiable, Insertable, Queryable, Debug)] -#[primary_key(entity_id, skill_group_type)] +#[primary_key(entity_id, skill_group_kind)] #[table_name = "skill_group"] pub struct SkillGroup { pub entity_id: i64, - pub skill_group_type: String, + pub skill_group_kind: String, pub exp: i32, pub available_sp: i32, pub earned_sp: i32, diff --git a/server/src/persistence/schema.rs b/server/src/persistence/schema.rs index 5f14e3ac98..c054d21e49 100644 --- a/server/src/persistence/schema.rs +++ b/server/src/persistence/schema.rs @@ -41,9 +41,9 @@ table! { } table! { - skill_group (entity_id, skill_group_type) { + skill_group (entity_id, skill_group_kind) { entity_id -> BigInt, - skill_group_type -> Text, + skill_group_kind -> Text, exp -> Integer, available_sp -> Integer, earned_sp -> Integer, diff --git a/server/src/sys/msg/in_game.rs b/server/src/sys/msg/in_game.rs index 1e20a0aaa5..1d90ff70a5 100644 --- a/server/src/sys/msg/in_game.rs +++ b/server/src/sys/msg/in_game.rs @@ -153,10 +153,10 @@ impl Sys { .get_mut(entity) .map(|mut s| s.skill_set.refund_skill(skill)); }, - ClientGeneral::UnlockSkillGroup(skill_group_type) => { + ClientGeneral::UnlockSkillGroup(skill_group_kind) => { stats .get_mut(entity) - .map(|mut s| s.skill_set.unlock_skill_group(skill_group_type)); + .map(|mut s| s.skill_set.unlock_skill_group(skill_group_kind)); }, _ => unreachable!("not a client_in_game msg"), } diff --git a/voxygen/src/hud/bag.rs b/voxygen/src/hud/bag.rs index 81d1f3da21..28601fee5e 100644 --- a/voxygen/src/hud/bag.rs +++ b/voxygen/src/hud/bag.rs @@ -1,11 +1,10 @@ use super::{ + cr_color, img_ids::{Imgs, ImgsRot}, item_imgs::ItemImgs, slots::{ArmorSlot, EquipSlot, InventorySlot, SlotManager}, util::loadout_slot_text, - Show, CRITICAL_HP_COLOR, LOW_HP_COLOR, QUALITY_ARTIFACT, QUALITY_COMMON, QUALITY_DEBUG, - QUALITY_EPIC, QUALITY_HIGH, QUALITY_LEGENDARY, QUALITY_LOW, QUALITY_MODERATE, TEXT_COLOR, - UI_HIGHLIGHT_0, UI_MAIN, XP_COLOR, + Show, CRITICAL_HP_COLOR, LOW_HP_COLOR, QUALITY_COMMON, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, }; use crate::{ hud::get_quality_col, @@ -428,27 +427,9 @@ impl<'a> Widget for Bag<'a> { .stat_txts .resize(STATS.len(), &mut ui.widget_id_generator()) }); - // Thresholds (lower) - let common = 4.3; - let moderate = 6.0; - let high = 8.0; - let epic = 10.0; - let legendary = 79.0; - let artifact = 122.0; - let debug = 200.0; // Stats let combat_rating = combat_rating(inventory, self.health, self.stats).min(999.9); - let indicator_col = match combat_rating { - x if (0.0..common).contains(&x) => QUALITY_LOW, - x if (common..moderate).contains(&x) => QUALITY_COMMON, - x if (moderate..high).contains(&x) => QUALITY_MODERATE, - x if (high..epic).contains(&x) => QUALITY_HIGH, - x if (epic..legendary).contains(&x) => QUALITY_EPIC, - x if (legendary..artifact).contains(&x) => QUALITY_LEGENDARY, - x if (artifact..debug).contains(&x) => QUALITY_ARTIFACT, - x if x >= debug => QUALITY_DEBUG, - _ => XP_COLOR, - }; + let indicator_col = cr_color(combat_rating); for i in STATS.iter().copied().enumerate() { let btn = Button::image(match i.1 { "Health" => self.imgs.health_ico, diff --git a/voxygen/src/hud/diary.rs b/voxygen/src/hud/diary.rs index 8b2f436264..3c961f81db 100644 --- a/voxygen/src/hud/diary.rs +++ b/voxygen/src/hud/diary.rs @@ -219,7 +219,7 @@ impl<'a> Diary<'a> { Achievements, }*/ -pub type SelectedSkillTree = skills::SkillGroupType; +pub type SelectedSkillTree = skills::SkillGroupKind; const TREES: [&str; 7] = [ "General Combat", @@ -379,7 +379,7 @@ impl<'a> Widget for Diary<'a> { ) }) .map_or(false, |(st, a_pts, e_pts)| { - a_pts > 0 && (e_pts - a_pts) < st.max_skill_points() + a_pts > 0 && (e_pts - a_pts) < st.total_skill_point_cost() }); if Button::image( if skill_tree_from_str(i.1).map_or(false, |st| st == *sel_tab || available_pts) { @@ -576,18 +576,26 @@ impl<'a> Widget for Diary<'a> { // // // TOP-LEFT Skills + let offset_0 = 22.0; + let offset_1 = -122.0; + let offset_2 = offset_1 - -20.0; while self.created_btns_top_l < skills_top_l { - let mut img = Button::image(self.imgs.wpn_icon_border).w_h(80.0, 80.0); + let mut img = Button::image(self.imgs.wpn_icon_border_skills).w_h(80.0, 100.0); match self.created_btns_top_l { 0 => img = img.middle_of(state.skills_top_l_align), // Central Skill - 1 => img = img.up_from(state.skills_top_l[0], 4.0), // 12:00 - 2 => img = img.down_from(state.skills_top_l[0], 4.0), // 6:00 - 3 => img = img.left_from(state.skills_top_l[0], 4.0), // 3:00 - 4 => img = img.right_from(state.skills_top_l[0], 4.0), // 9:00 - 5 => img = img.top_left_with_margins_on(state.skills_top_l[0], -84.0, -84.0), /* 10:30 */ - 6 => img = img.top_right_with_margins_on(state.skills_top_l[0], -84.0, -84.0), /* 1:30 */ - 7 => img = img.bottom_left_with_margins_on(state.skills_top_l[0], -84.0, -84.0), /* 4:30 */ - 8 => img = img.bottom_right_with_margins_on(state.skills_top_l[0], -84.0, -84.0), /* 7:30 */ + 1 => img = img.up_from(state.skills_top_l[0], offset_0), // 12:00 + 2 => img = img.down_from(state.skills_top_l[0], offset_0), // 6:00 + 3 => img = img.left_from(state.skills_top_l[0], offset_0), // 3:00 + 4 => img = img.right_from(state.skills_top_l[0], offset_0), // 9:00 + 5 => img = img.top_left_with_margins_on(state.skills_top_l[0], offset_1, offset_2), /* 10:30 */ + 6 => img = img.top_right_with_margins_on(state.skills_top_l[0], offset_1, offset_2), /* 1:30 */ + 7 => { + img = img.bottom_left_with_margins_on(state.skills_top_l[0], offset_1, offset_2) + }, /* 4:30 */ + 8 => { + img = + img.bottom_right_with_margins_on(state.skills_top_l[0], offset_1, offset_2) + }, /* 7:30 */ _ => {}, } img.set(state.skills_top_l[self.created_btns_top_l], ui); @@ -595,17 +603,22 @@ impl<'a> Widget for Diary<'a> { } // TOP-RIGHT Skills while self.created_btns_top_r < skills_top_r { - let mut img = Button::image(self.imgs.wpn_icon_border).w_h(80.0, 80.0); + let mut img = Button::image(self.imgs.wpn_icon_border_skills).w_h(80.0, 100.0); match self.created_btns_top_r { 0 => img = img.middle_of(state.skills_top_r_align), // Central Skill - 1 => img = img.up_from(state.skills_top_r[0], 4.0), // 12:00 - 2 => img = img.down_from(state.skills_top_r[0], 4.0), // 6:00 - 3 => img = img.left_from(state.skills_top_r[0], 4.0), // 3:00 - 4 => img = img.right_from(state.skills_top_r[0], 4.0), // 9:00 - 5 => img = img.top_left_with_margins_on(state.skills_top_r[0], -84.0, -84.0), /* 10:30 */ - 6 => img = img.top_right_with_margins_on(state.skills_top_r[0], -84.0, -84.0), /* 1:30 */ - 7 => img = img.bottom_left_with_margins_on(state.skills_top_r[0], -84.0, -84.0), /* 4:30 */ - 8 => img = img.bottom_right_with_margins_on(state.skills_top_r[0], -84.0, -84.0), /* 7:30 */ + 1 => img = img.up_from(state.skills_top_r[0], offset_0), // 12:00 + 2 => img = img.down_from(state.skills_top_r[0], offset_0), // 6:00 + 3 => img = img.left_from(state.skills_top_r[0], offset_0), // 3:00 + 4 => img = img.right_from(state.skills_top_r[0], offset_0), // 9:00 + 5 => img = img.top_left_with_margins_on(state.skills_top_r[0], offset_1, offset_2), /* 10:30 */ + 6 => img = img.top_right_with_margins_on(state.skills_top_r[0], offset_1, offset_2), /* 1:30 */ + 7 => { + img = img.bottom_left_with_margins_on(state.skills_top_r[0], offset_1, offset_2) + }, /* 4:30 */ + 8 => { + img = + img.bottom_right_with_margins_on(state.skills_top_r[0], offset_1, offset_2) + }, /* 7:30 */ _ => {}, } img.set(state.skills_top_r[self.created_btns_top_r], ui); @@ -613,17 +626,22 @@ impl<'a> Widget for Diary<'a> { } // BOTTOM-LEFT Skills while self.created_btns_bot_l < skills_bot_l { - let mut img = Button::image(self.imgs.wpn_icon_border).w_h(80.0, 80.0); + let mut img = Button::image(self.imgs.wpn_icon_border_skills).w_h(80.0, 100.0); match self.created_btns_bot_l { 0 => img = img.middle_of(state.skills_bot_l_align), // Central Skill - 1 => img = img.up_from(state.skills_bot_l[0], 4.0), // 12:00 - 2 => img = img.down_from(state.skills_bot_l[0], 4.0), // 6:00 - 3 => img = img.left_from(state.skills_bot_l[0], 4.0), // 3:00 - 4 => img = img.right_from(state.skills_bot_l[0], 4.0), // 9:00 - 5 => img = img.top_left_with_margins_on(state.skills_bot_l[0], -84.0, -84.0), /* 10:30 */ - 6 => img = img.top_right_with_margins_on(state.skills_bot_l[0], -84.0, -84.0), /* 1:30 */ - 7 => img = img.bottom_left_with_margins_on(state.skills_bot_l[0], -84.0, -84.0), /* 4:30 */ - 8 => img = img.bottom_right_with_margins_on(state.skills_bot_l[0], -84.0, -84.0), /* 7:30 */ + 1 => img = img.up_from(state.skills_bot_l[0], offset_0), // 12:00 + 2 => img = img.down_from(state.skills_bot_l[0], offset_0), // 6:00 + 3 => img = img.left_from(state.skills_bot_l[0], offset_0), // 3:00 + 4 => img = img.right_from(state.skills_bot_l[0], offset_0), // 9:00 + 5 => img = img.top_left_with_margins_on(state.skills_bot_l[0], offset_1, offset_2), /* 10:30 */ + 6 => img = img.top_right_with_margins_on(state.skills_bot_l[0], offset_1, offset_2), /* 1:30 */ + 7 => { + img = img.bottom_left_with_margins_on(state.skills_bot_l[0], offset_1, offset_2) + }, /* 4:30 */ + 8 => { + img = + img.bottom_right_with_margins_on(state.skills_bot_l[0], offset_1, offset_2) + }, /* 7:30 */ _ => {}, } img.set(state.skills_bot_l[self.created_btns_bot_l], ui); @@ -631,20 +649,25 @@ impl<'a> Widget for Diary<'a> { } // BOTTOM-RIGHT Skills while self.created_btns_bot_r < skills_bot_r { - let mut btn = Image::new(self.imgs.wpn_icon_border).w_h(80.0, 80.0); + let mut img = Image::new(self.imgs.wpn_icon_border_skills).w_h(80.0, 100.0); match self.created_btns_bot_r { - 0 => btn = btn.middle_of(state.skills_bot_r_align), // Central Skill - 1 => btn = btn.up_from(state.skills_bot_r[0], 4.0), // 12:00 - 2 => btn = btn.down_from(state.skills_bot_r[0], 4.0), // 6:00 - 3 => btn = btn.left_from(state.skills_bot_r[0], 4.0), // 3:00 - 4 => btn = btn.right_from(state.skills_bot_r[0], 4.0), // 9:00 - 5 => btn = btn.top_left_with_margins_on(state.skills_bot_r[0], -84.0, -84.0), /* 10:30 */ - 6 => btn = btn.top_right_with_margins_on(state.skills_bot_r[0], -84.0, -84.0), /* 1:30 */ - 7 => btn = btn.bottom_left_with_margins_on(state.skills_bot_r[0], -84.0, -84.0), /* 4:30 */ - 8 => btn = btn.bottom_right_with_margins_on(state.skills_bot_r[0], -84.0, -84.0), /* 7:30 */ + 0 => img = img.middle_of(state.skills_bot_r_align), // Central Skill + 1 => img = img.up_from(state.skills_bot_r[0], offset_0), // 12:00 + 2 => img = img.down_from(state.skills_bot_r[0], offset_0), // 6:00 + 3 => img = img.left_from(state.skills_bot_r[0], offset_0), // 3:00 + 4 => img = img.right_from(state.skills_bot_r[0], offset_0), // 9:00 + 5 => img = img.top_left_with_margins_on(state.skills_bot_r[0], offset_1, offset_2), /* 10:30 */ + 6 => img = img.top_right_with_margins_on(state.skills_bot_r[0], offset_1, offset_2), /* 1:30 */ + 7 => { + img = img.bottom_left_with_margins_on(state.skills_bot_r[0], offset_1, offset_2) + }, /* 4:30 */ + 8 => { + img = + img.bottom_right_with_margins_on(state.skills_bot_r[0], offset_1, offset_2) + }, /* 7:30 */ _ => {}, } - btn.set(state.skills_bot_r[self.created_btns_bot_r], ui); + img.set(state.skills_bot_r[self.created_btns_bot_r], ui); self.created_btns_bot_r += 1; } // Skill-Icons and Functionality @@ -652,7 +675,7 @@ impl<'a> Widget for Diary<'a> { let art_size = [320.0, 320.0]; match sel_tab { SelectedSkillTree::General => { - use skills::{GeneralSkill::*, RollSkill::*, SkillGroupType::*}; + use skills::{GeneralSkill::*, RollSkill::*, SkillGroupKind::*}; use ToolKind::*; // General Combat Image::new( @@ -3395,10 +3418,10 @@ fn create_skill_button<'a>( ) -> Button<'a, button::Image> { Button::image(image) .w_h(74.0, 74.0) - .middle_of(state) + .mid_top_with_margin_on(state, 3.0) .label(label) - .label_y(conrod_core::position::Relative::Scalar(-28.0)) - .label_x(conrod_core::position::Relative::Scalar(32.0)) + .label_y(conrod_core::position::Relative::Scalar(-47.0)) + .label_x(conrod_core::position::Relative::Scalar(0.0)) .label_color(if skill_set.is_at_max_level(skill) { TEXT_COLOR } else if skill_set.sufficient_skill_points(skill) { @@ -3406,7 +3429,7 @@ fn create_skill_button<'a>( } else { CRITICAL_HP_COLOR }) - .label_font_size(fonts.cyri.scale(16)) + .label_font_size(fonts.cyri.scale(15)) .label_font_id(fonts.cyri.conrod_id) .image_color(if skill_set.prerequisites_met(skill) { TEXT_COLOR @@ -3447,7 +3470,7 @@ fn add_sp_cost_tooltip<'a>( localized_strings: &'a Localization, ) -> String { match skill_set.skill_level(skill) { - Ok(level) if level == skill.max_level() => tooltip.replace("{}", ""), + Ok(level) if level == skill.max_level() => tooltip.replace("{SP}", ""), _ => tooltip.replace( "{SP}", &localized_strings diff --git a/voxygen/src/hud/group.rs b/voxygen/src/hud/group.rs index ab5e18823a..98b1d9bea9 100644 --- a/voxygen/src/hud/group.rs +++ b/voxygen/src/hud/group.rs @@ -1,9 +1,8 @@ use super::{ + cr_color, img_ids::{Imgs, ImgsRot}, Show, BLACK, BUFF_COLOR, DEBUFF_COLOR, ERROR_COLOR, GROUP_COLOR, HP_COLOR, KILL_COLOR, - LOW_HP_COLOR, QUALITY_ARTIFACT, QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, - QUALITY_LEGENDARY, QUALITY_LOW, QUALITY_MODERATE, STAMINA_COLOR, TEXT_COLOR, TEXT_COLOR_GREY, - UI_HIGHLIGHT_0, UI_MAIN, XP_COLOR, + LOW_HP_COLOR, STAMINA_COLOR, TEXT_COLOR, TEXT_COLOR_GREY, UI_HIGHLIGHT_0, UI_MAIN, }; use crate::{ @@ -29,8 +28,6 @@ use conrod_core::{ }; use specs::{saveload::MarkerAllocator, WorldExt}; -use inline_tweak::*; - widget_ids! { pub struct Ids { group_button, @@ -436,38 +433,16 @@ impl<'a> Widget for Group<'a> { .middle_of(state.ids.member_panels_bg[i]) .color(Some(UI_HIGHLIGHT_0)) .set(state.ids.member_panels_frame[i], ui); - // Thresholds (lower) - let common = 4.3; - let moderate = 6.0; - let high = 8.0; - let epic = 10.0; - let legendary = 79.0; - let artifact = 122.0; - let debug = 200.0; - let indicator_col = match combat_rating { - x if (0.0..common).contains(&x) => QUALITY_LOW, - x if (common..moderate).contains(&x) => QUALITY_COMMON, - x if (moderate..high).contains(&x) => QUALITY_MODERATE, - x if (high..epic).contains(&x) => QUALITY_HIGH, - x if (epic..legendary).contains(&x) => QUALITY_EPIC, - x if (legendary..artifact).contains(&x) => QUALITY_LEGENDARY, - x if (artifact..debug).contains(&x) => QUALITY_ARTIFACT, - x if x >= debug => QUALITY_DEBUG, - _ => XP_COLOR, - }; + let indicator_col = cr_color(combat_rating); Image::new(self.imgs.combat_rating_ico_shadow) - .w_h(tweak!(18.0), tweak!(18.0)) - .top_left_with_margins_on( - state.ids.member_panels_frame[i], - tweak!(-20.0), - tweak!(2.0), - ) + .w_h(18.0, 18.0) + .top_left_with_margins_on(state.ids.member_panels_frame[i], 20.0, 2.0) .color(Some(indicator_col)) .set(state.ids.combat_rating_indicators[i], ui); // Panel Text Text::new(&char_name) - .top_left_with_margins_on(state.ids.member_panels_frame[i], tweak!(-22.0), tweak!(22.0)) + .top_left_with_margins_on(state.ids.member_panels_frame[i], -22.0, 22.0) .font_size(20) .font_id(self.fonts.cyri.conrod_id) .color(BLACK) diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 2b74de5496..abe66be5ab 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -78,6 +78,7 @@ image_ids! { bow: "voxygen.element.icons.bow", staff: "voxygen.element.icons.staff", lock: "voxygen.element.icons.lock", + wpn_icon_border_skills: "voxygen.element.buttons.border_skills", wpn_icon_border: "voxygen.element.buttons.border", wpn_icon_border_mo: "voxygen.element.buttons.border_mo", wpn_icon_border_press: "voxygen.element.buttons.border_press", diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index c174bf8070..75be629adb 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -62,7 +62,7 @@ use common::{ comp::{ self, item::{tool::ToolKind, ItemDesc, Quality}, - skills::{Skill, SkillGroupType}, + skills::{Skill, SkillGroupKind}, BuffKind, }, outcome::Outcome, @@ -304,7 +304,7 @@ pub struct ExpFloater { pub struct SkillPointGain { pub owner: Uid, - pub skill_tree: SkillGroupType, + pub skill_tree: SkillGroupKind, pub total_points: u16, pub timer: f32, } @@ -1112,24 +1112,29 @@ impl Hud { } else { 1.0 }; - Text::new(&format!("{} Exp", floater.exp_change)) - .font_size(font_size_xp) - .font_id(self.fonts.cyri.conrod_id) - .color(Color::Rgba(0.0, 0.0, 0.0, fade)) - .x_y( - ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25), - ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y - 3.0, - ) - .set(player_sct_bg_id, ui_widgets); - Text::new(&format!("{} Exp", floater.exp_change)) - .font_size(font_size_xp) - .font_id(self.fonts.cyri.conrod_id) - .color(Color::Rgba(0.59, 0.41, 0.67, fade)) - .x_y( - ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25), - ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y, - ) - .set(player_sct_id, ui_widgets); + + if floater.exp_change > 0 { + // Don't show 0 Exp + Text::new(&format!("{} Exp", floater.exp_change.max(1))) + .font_size(font_size_xp) + .font_id(self.fonts.cyri.conrod_id) + .color(Color::Rgba(0.0, 0.0, 0.0, fade)) + .x_y( + ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25), + ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y + - 3.0, + ) + .set(player_sct_bg_id, ui_widgets); + Text::new(&format!("{} Exp", floater.exp_change.max(1))) + .font_size(font_size_xp) + .font_id(self.fonts.cyri.conrod_id) + .color(Color::Rgba(0.59, 0.41, 0.67, fade)) + .x_y( + ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25), + ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y, + ) + .set(player_sct_id, ui_widgets); + } floater.timer -= dt.as_secs_f32(); } } @@ -1205,7 +1210,7 @@ impl Hud { .bottom_left_with_margins_on(self.ids.player_rank_up_txt_1_bg, 2.0, 2.0) .set(self.ids.player_rank_up_txt_1, ui_widgets); // Variable skilltree icon - use crate::hud::SkillGroupType::{General, Weapon}; + use crate::hud::SkillGroupKind::{General, Weapon}; Image::new(match display.skill_tree { General => self.imgs.swords_crossed, Weapon(ToolKind::Hammer) => self.imgs.hammer, @@ -2953,3 +2958,25 @@ fn try_hotbar_slot_from_input(input: GameInput) -> Option { _ => return None, }) } + +pub fn cr_color(combat_rating: f32) -> Color { + let common = 4.3; + let moderate = 6.0; + let high = 8.0; + let epic = 10.0; + let legendary = 79.0; + let artifact = 122.0; + let debug = 200.0; + + match combat_rating { + x if (0.0..common).contains(&x) => QUALITY_LOW, + x if (common..moderate).contains(&x) => QUALITY_COMMON, + x if (moderate..high).contains(&x) => QUALITY_MODERATE, + x if (high..epic).contains(&x) => QUALITY_HIGH, + x if (epic..legendary).contains(&x) => QUALITY_EPIC, + x if (legendary..artifact).contains(&x) => QUALITY_LEGENDARY, + x if (artifact..debug).contains(&x) => QUALITY_ARTIFACT, + x if x >= debug => QUALITY_DEBUG, + _ => XP_COLOR, + } +} diff --git a/voxygen/src/hud/overhead.rs b/voxygen/src/hud/overhead.rs index 567203965d..318ca0934a 100644 --- a/voxygen/src/hud/overhead.rs +++ b/voxygen/src/hud/overhead.rs @@ -1,8 +1,7 @@ use super::{ - img_ids::Imgs, DEFAULT_NPC, ENEMY_HP_COLOR, FACTION_COLOR, GROUP_COLOR, GROUP_MEMBER, HP_COLOR, - LOW_HP_COLOR, QUALITY_ARTIFACT, QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, - QUALITY_LEGENDARY, QUALITY_LOW, QUALITY_MODERATE, REGION_COLOR, SAY_COLOR, STAMINA_COLOR, - TELL_COLOR, TEXT_BG, TEXT_COLOR, XP_COLOR, + cr_color, img_ids::Imgs, DEFAULT_NPC, ENEMY_HP_COLOR, FACTION_COLOR, GROUP_COLOR, GROUP_MEMBER, + HP_COLOR, LOW_HP_COLOR, REGION_COLOR, SAY_COLOR, STAMINA_COLOR, TELL_COLOR, TEXT_BG, + TEXT_COLOR, }; use crate::{ hud::get_buff_info, @@ -18,7 +17,6 @@ use conrod_core::{ widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon, }; const MAX_BUBBLE_WIDTH: f64 = 250.0; -use inline_tweak::*; widget_ids! { struct Ids { // Speech bubble @@ -321,19 +319,19 @@ impl<'a> Widget for Overhead<'a> { // % HP Filling let size_factor = (hp_percentage / 100.0) * BARSIZE; let w = if self.in_group { - tweak!(82.0) * size_factor + 82.0 * size_factor } else { 73.0 * size_factor }; let h = 6.0 * BARSIZE; let x = if self.in_group { - (tweak!(0.0) + (hp_percentage / 100.0 * tweak!(41.0) - tweak!(41.0))) * BARSIZE + (0.0 + (hp_percentage / 100.0 * 41.0 - 41.0)) * BARSIZE } else { (4.5 + (hp_percentage / 100.0 * 36.45 - 36.45)) * BARSIZE }; Image::new(self.imgs.enemy_bar) .w_h(w, h) - .x_y(x, MANA_BAR_Y + tweak!(8.0)) + .x_y(x, MANA_BAR_Y + 8.0) .color(if self.in_group { // Different HP bar colors only for group members Some(match hp_percentage { @@ -363,12 +361,12 @@ impl<'a> Widget for Overhead<'a> { let energy_factor = energy.current() as f64 / energy.maximum() as f64; let size_factor = energy_factor * BARSIZE; let w = if self.in_group { - tweak!(80.0) * size_factor + 80.0 * size_factor } else { 72.0 * size_factor }; let x = if self.in_group { - ((tweak!(0.0) + (energy_factor * tweak!(40.0))) - tweak!(40.0)) * BARSIZE + ((0.0 + (energy_factor * 40.0)) - 40.0) * BARSIZE } else { ((3.5 + (energy_factor * 36.5)) - 36.45) * BARSIZE }; @@ -388,28 +386,10 @@ impl<'a> Widget for Overhead<'a> { .parent(id) .set(state.ids.health_bar_fg, ui); - // Thresholds (lower) - let common = 4.3; - let moderate = 6.0; - let high = 8.0; - let epic = 10.0; - let legendary = 79.0; - let artifact = 122.0; - let debug = 200.0; + let indicator_col = cr_color(combat_rating); + let artifact_diffculty = 122.0; - let indicator_col = match combat_rating { - x if (0.0..common).contains(&x) => QUALITY_LOW, - x if (common..moderate).contains(&x) => QUALITY_COMMON, - x if (moderate..high).contains(&x) => QUALITY_MODERATE, - x if (high..epic).contains(&x) => QUALITY_HIGH, - x if (epic..legendary).contains(&x) => QUALITY_EPIC, - x if (legendary..artifact).contains(&x) => QUALITY_LEGENDARY, - x if (artifact..debug).contains(&x) => QUALITY_ARTIFACT, - x if x >= debug => QUALITY_DEBUG, - _ => XP_COLOR, - }; - - if combat_rating > artifact && !self.in_group { + if combat_rating > artifact_diffculty && !self.in_group { let skull_ani = ((self.pulse * 0.7/* speed factor */).cos() * 0.5 + 0.5) * 10.0; //Animation timer Image::new(if skull_ani as i32 == 1 && rand::random::() < 0.9 { self.imgs.skull_2 @@ -427,8 +407,8 @@ impl<'a> Widget for Overhead<'a> { } else { self.imgs.combat_rating_ico }) - .w_h(tweak!(7.0) * BARSIZE, tweak!(7.0) * BARSIZE) - .x_y(tweak!(-37.0) * BARSIZE, MANA_BAR_Y + tweak!(6.0)) + .w_h(7.0 * BARSIZE, 7.0 * BARSIZE) + .x_y(-37.0 * BARSIZE, MANA_BAR_Y + 6.0) .color(Some(indicator_col)) .parent(id) .set(state.ids.level, ui); diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs index 20f7ec834d..1ad3572d66 100644 --- a/voxygen/src/hud/skillbar.rs +++ b/voxygen/src/hud/skillbar.rs @@ -575,7 +575,7 @@ impl<'a> Widget for Skillbar<'a> { Image::new(self.imgs.skillbar_slot) .w_h(40.0, 40.0) .right_from(state.ids.m1_slot_bg, slot_offset) - .set(state.ids.m2_slot, ui); + .set(state.ids.m2_slot_bg, ui); fn get_tool(inventory: &Inventory, equip_slot: EquipSlot) -> Option<&Tool> { match inventory.equipped(equip_slot).map(|i| i.kind()) { @@ -596,10 +596,6 @@ impl<'a> Widget for Skillbar<'a> { (_, _) => None, }; - Image::new(self.imgs.skillbar_slot) - .w_h(40.0, 40.0) - .middle_of(state.ids.m2_slot) - .set(state.ids.m2_slot_bg, ui); Button::image(match tool.map(|t| t.kind) { Some(ToolKind::Sword) => self.imgs.twohsword_m2, Some(ToolKind::Dagger) => self.imgs.onehdagger_m2, @@ -626,7 +622,10 @@ impl<'a> Widget for Skillbar<'a> { Color::Rgba(0.3, 0.3, 0.3, 0.8) } } else { - Color::Rgba(1.0, 1.0, 1.0, 1.0) + match tool.map(|t| t.kind) { + None => Color::Rgba(1.0, 1.0, 1.0, 0.0), + _ => Color::Rgba(1.0, 1.0, 1.0, 1.0), + } }) .set(state.ids.m2_content, ui); // Slot 6-10 diff --git a/voxygen/src/hud/social.rs b/voxygen/src/hud/social.rs index 91a1c71daa..432b54d470 100644 --- a/voxygen/src/hud/social.rs +++ b/voxygen/src/hud/social.rs @@ -382,9 +382,13 @@ impl<'a> Widget for Social<'a> { players.filter(|(uid, _)| Some(**uid) != my_uid).enumerate() { let hide_username = true; - let zone = "Wilderness"; // TODO Add real zone + let zone = ""; // TODO Add real zone let selected = state.selected_uid.map_or(false, |u| u.0 == uid); let alias = &player_info.player_alias; + let zone_name = match &player_info.character { + None => self.localized_strings.get("hud.group.in_menu").to_string(), /* character select or spectating */ + _ => format!("{} ", &zone), + }; let name_text = match &player_info.character { Some(character) => { if Some(uid) == my_uid { @@ -394,17 +398,13 @@ impl<'a> Widget for Social<'a> { &character.name ) } else if hide_username { - character.name.clone() + format!("{} [{}]", &character.name, zone_name) } else { - format!("[{}] {}", alias, &character.name) + format!("[{}] {} [{}]", alias, &character.name, zone_name) } }, None => alias.clone(), // character select or spectating }; - let zone_name = match &player_info.character { - None => self.localized_strings.get("hud.group.in_menu").to_string(), /* character select or spectating */ - _ => format!("{} ", &zone), - }; // Player name widgets let button = Button::image(if !selected { self.imgs.nothing