mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better visuals for skill button labels, don't show "0 EXP" in the SCT
Made functions that were called every frame significantly cheaper. Final UI fixes.
This commit is contained in:
parent
eaa41c7dea
commit
ac60bf5794
BIN
assets/voxygen/element/buttons/border_skills.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/buttons/border_skills.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -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,
|
||||
|
@ -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<ToolKind>, Option<ToolKind>) {
|
||||
)
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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};
|
||||
|
@ -9,7 +9,7 @@ use std::hash::Hash;
|
||||
use tracing::{trace, warn};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SkillTreeMap(HashMap<SkillGroupType, HashSet<Skill>>);
|
||||
pub struct SkillTreeMap(HashMap<SkillGroupKind, HashSet<Skill>>);
|
||||
|
||||
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<Skill>,
|
||||
pub total_skill_point_cost: u16,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SkillLevelMap(HashMap<Skill, Option<u16>>);
|
||||
|
||||
@ -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<SkillGroupType, HashSet<Skill>> = {
|
||||
SkillTreeMap::load_expect_cloned(
|
||||
pub static ref SKILL_GROUP_DEFS: HashMap<SkillGroupKind, SkillGroupDef> = {
|
||||
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<Skill, SkillGroupKind> = {
|
||||
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<Skill, Option<u16>> = {
|
||||
@ -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<u16>) -> HashMap<Skill, Option<u16>> {
|
||||
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<Item = (Skill, Option<u16>)> {
|
||||
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>) -> u16 {
|
||||
pub fn skill_cost(&self, level: Option<u16>) -> 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<u16> { SKILL_MAX_LEVEL.get(&self).copied().flatten() }
|
||||
pub fn max_level(&self) -> Option<u16> { 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<SkillGroupType> {
|
||||
SKILL_GROUP_DEFS
|
||||
.iter()
|
||||
.find_map(|(key, val)| val.contains(&self).then_some(*key))
|
||||
pub fn skill_group_kind(&self) -> Option<SkillGroupKind> {
|
||||
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);
|
||||
}
|
||||
|
@ -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<f32>,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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::<HashSet<_>>();
|
||||
|
||||
|
@ -2053,16 +2053,16 @@ fn handle_skill_point(
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_skill_tree(skill_tree: &str) -> Option<comp::skills::SkillGroupType> {
|
||||
use comp::{item::tool::ToolKind, skills::SkillGroupType};
|
||||
fn parse_skill_tree(skill_tree: &str) -> Option<comp::skills::SkillGroupKind> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
@ -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::<Vec<_>>();
|
||||
// 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<Outcome>,
|
||||
) {
|
||||
let (main_tool_kind, second_tool_kind) = combat::get_weapons(inventory);
|
||||
let mut xp_pools = HashSet::<SkillGroupType>::new();
|
||||
xp_pools.insert(SkillGroupType::General);
|
||||
let mut xp_pools = HashSet::<SkillGroupKind>::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;
|
||||
|
@ -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
|
||||
|
@ -367,9 +367,9 @@ fn get_item_from_asset(item_definition_id: &str) -> Result<common::comp::Item, E
|
||||
fn convert_skill_groups_from_database(skill_groups: &[SkillGroup]) -> Vec<skills::SkillGroup> {
|
||||
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,
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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"),
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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<hotbar::Slot> {
|
||||
_ => 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,
|
||||
}
|
||||
}
|
||||
|
@ -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::<f32>() < 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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user