mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
EXP bar and available points UI
fix overhead UI Add WIP overhead difficulty indicator readd commented out exp counter for later use Wired skill information into UI.
This commit is contained in:
parent
c0c45a1996
commit
48bd921d0a
BIN
assets/voxygen/element/icons/indicator_bubble.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/icons/indicator_bubble.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/misc_bg/diary_exp_bg.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/misc_bg/diary_exp_bg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/misc_bg/diary_exp_frame.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/misc_bg/diary_exp_frame.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -37,12 +37,12 @@
|
||||
(0.0, 0.0, 0.0), (90.0, 90.0, 0.0), 1.0,
|
||||
),
|
||||
Tool("example_general_combat_left"): VoxTrans(
|
||||
"voxel.weapon.shield.wood-0",
|
||||
(0.0, 0.0, 0.0), (90.0, 90.0, 0.0), 1.0,
|
||||
"voxel.weapon.sword.long_2h_saurok",
|
||||
(0.0, 0.0, 0.0), (85.0, -90.0, -40.0), 1.0,
|
||||
),
|
||||
Tool("example_general_combat_right"): VoxTrans(
|
||||
"voxel.weapon.sword.long_2h_saurok",
|
||||
(0.0, 0.0, 0.0), (90.0, 90.0, 0.0), 1.0,
|
||||
(0.0, 0.0, 0.0), (125.0, 90.0, 80.0), 1.0,
|
||||
),
|
||||
// Bows
|
||||
Tool("common.items.weapons.bow.starter_bow"): VoxTrans(
|
||||
|
BIN
assets/voxygen/voxel/weapon/shield/wood-0.vox
(Stored with Git LFS)
BIN
assets/voxygen/voxel/weapon/shield/wood-0.vox
(Stored with Git LFS)
Binary file not shown.
@ -220,6 +220,11 @@ pub enum SkillGroupType {
|
||||
Weapon(ToolKind),
|
||||
}
|
||||
|
||||
impl SkillGroupType {
|
||||
/// Gets the cost in experience of earning a skill point
|
||||
pub fn skill_point_cost(self) -> u16 { 300 }
|
||||
}
|
||||
|
||||
/// A group of skills that have been unlocked by a player. Each skill group has
|
||||
/// independent exp and skill points which are used to unlock skills in that
|
||||
/// skill group.
|
||||
@ -228,6 +233,7 @@ pub struct SkillGroup {
|
||||
pub skill_group_type: SkillGroupType,
|
||||
pub exp: u16,
|
||||
pub available_sp: u16,
|
||||
pub earned_sp: u16,
|
||||
}
|
||||
|
||||
impl SkillGroup {
|
||||
@ -236,6 +242,7 @@ impl SkillGroup {
|
||||
skill_group_type,
|
||||
exp: 0,
|
||||
available_sp: 0,
|
||||
earned_sp: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -433,6 +440,7 @@ impl SkillSet {
|
||||
.find(|x| x.skill_group_type == skill_group_type)
|
||||
{
|
||||
skill_group.available_sp += number_of_skill_points;
|
||||
skill_group.earned_sp += number_of_skill_points;
|
||||
} else {
|
||||
warn!("Tried to add skill points to a skill group that player does not have");
|
||||
}
|
||||
@ -467,6 +475,33 @@ impl SkillSet {
|
||||
self.skills.contains_key(s) && self.skills.get(s).map_or(false, |l_b| l_b >= l)
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets the available points for a particular skill group
|
||||
pub fn get_available_sp(&self, skill_group: SkillGroupType) -> u16 {
|
||||
let mut skill_groups = self
|
||||
.skill_groups
|
||||
.iter()
|
||||
.filter(|s_g| s_g.skill_group_type == skill_group);
|
||||
skill_groups.next().map_or(0, |s_g| s_g.available_sp)
|
||||
}
|
||||
|
||||
/// Gets the total earned points for a particular skill group
|
||||
pub fn get_earned_sp(&self, skill_group: SkillGroupType) -> u16 {
|
||||
let mut skill_groups = self
|
||||
.skill_groups
|
||||
.iter()
|
||||
.filter(|s_g| s_g.skill_group_type == skill_group);
|
||||
skill_groups.next().map_or(0, |s_g| s_g.earned_sp)
|
||||
}
|
||||
|
||||
/// Gets the available experience for a particular skill group
|
||||
pub fn get_experience(&self, skill_group: SkillGroupType) -> u16 {
|
||||
let mut skill_groups = self
|
||||
.skill_groups
|
||||
.iter()
|
||||
.filter(|s_g| s_g.skill_group_type == skill_group);
|
||||
skill_groups.next().map_or(0, |s_g| s_g.exp)
|
||||
}
|
||||
}
|
||||
|
||||
impl Skill {
|
||||
|
@ -79,7 +79,7 @@ impl<'a> System<'a> for Sys {
|
||||
let stat = stats.get_unchecked();
|
||||
{
|
||||
for skill_group in stat.skill_set.skill_groups.iter() {
|
||||
if skill_group.exp >= 300 {
|
||||
if skill_group.exp >= skill_group.skill_group_type.skill_point_cost() {
|
||||
skills_to_level.insert(skill_group.skill_group_type);
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,8 @@ impl<'a> System<'a> for Sys {
|
||||
if !skills_to_level.is_empty() {
|
||||
let mut stat = stats.get_mut_unchecked();
|
||||
for skill_group in skills_to_level.drain() {
|
||||
stat.skill_set.change_experience(skill_group, -300);
|
||||
stat.skill_set
|
||||
.change_experience(skill_group, -(skill_group.skill_point_cost() as i32));
|
||||
stat.skill_set.add_skill_points(skill_group, 1);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ CREATE TABLE "_character_new" (
|
||||
"character_id" INT NOT NULL,
|
||||
"player_uuid" TEXT NOT NULL,
|
||||
"alias" TEXT NOT NULL,
|
||||
"waypoint" TEXT NOT NULL,
|
||||
"waypoint" TEXT,
|
||||
PRIMARY KEY("character_id"),
|
||||
FOREIGN KEY("character_id") REFERENCES "body"("body_id"),
|
||||
FOREIGN KEY("character_id") REFERENCES "item"("item_id")
|
||||
@ -37,6 +37,7 @@ CREATE TABLE skill_group (
|
||||
skill_group_type TEXT NOT NULL,
|
||||
exp INTEGER NOT NULL,
|
||||
available_sp INTEGER NOT NULL,
|
||||
earned_sp INTEGER NOT NULL,
|
||||
FOREIGN KEY(character_id) REFERENCES character(character_id),
|
||||
PRIMARY KEY(character_id,skill_group_type)
|
||||
);
|
||||
@ -52,5 +53,5 @@ CREATE TABLE skill (
|
||||
|
||||
-- Inserts starting skill group for everyone
|
||||
INSERT INTO skill_group
|
||||
SELECT c.character_id, '"General"', 0, 0
|
||||
SELECT c.character_id, '"General"', 0, 0, 0
|
||||
FROM character c
|
@ -381,6 +381,7 @@ fn convert_skill_groups_from_database(skill_groups: &[SkillGroup]) -> Vec<skills
|
||||
skill_group_type,
|
||||
exp: skill_group.exp as u16,
|
||||
available_sp: skill_group.available_sp as u16,
|
||||
earned_sp: skill_group.earned_sp as u16,
|
||||
};
|
||||
new_skill_groups.push(new_skill_group);
|
||||
}
|
||||
@ -414,6 +415,7 @@ pub fn convert_skill_groups_to_database(
|
||||
skill_group_type: serde_json::to_string(&sg.skill_group_type).unwrap(),
|
||||
exp: sg.exp as i32,
|
||||
available_sp: sg.available_sp as i32,
|
||||
earned_sp: sg.earned_sp as i32,
|
||||
})
|
||||
.collect();
|
||||
db_skill_groups
|
||||
|
@ -64,4 +64,5 @@ pub struct SkillGroup {
|
||||
pub skill_group_type: String,
|
||||
pub exp: i32,
|
||||
pub available_sp: i32,
|
||||
pub earned_sp: i32,
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ table! {
|
||||
skill_group_type -> Text,
|
||||
exp -> Integer,
|
||||
available_sp -> Integer,
|
||||
earned_sp -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,7 +335,7 @@ impl<'a> Widget for Buttons<'a> {
|
||||
.press_image(self.imgs.spellbook_press)
|
||||
.with_tooltip(
|
||||
self.tooltip_manager,
|
||||
&localized_strings.get("hud.spell"),
|
||||
&localized_strings.get("hud.diary"),
|
||||
"",
|
||||
&button_tooltip,
|
||||
TEXT_COLOR,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{
|
||||
img_ids::{Imgs, ImgsRot},
|
||||
item_imgs::{ItemImgs, ItemKey::Tool},
|
||||
Show, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
||||
Show, QUALITY_LEGENDARY, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, XP_COLOR,
|
||||
};
|
||||
use crate::{
|
||||
i18n::Localization,
|
||||
@ -29,6 +29,13 @@ widget_ids! {
|
||||
close,
|
||||
title,
|
||||
content_align,
|
||||
exp_bar_bg,
|
||||
exp_bar_frame,
|
||||
exp_bar_content_align,
|
||||
exp_bar_content,
|
||||
exp_bar_rank,
|
||||
exp_bar_txt,
|
||||
available_pts_txt,
|
||||
weapon_imgs[],
|
||||
weapon_btns[],
|
||||
skills_top_l_align,
|
||||
@ -127,7 +134,8 @@ widget_ids! {
|
||||
skill_sceptre_bomb_2,
|
||||
skill_sceptre_bomb_3,
|
||||
skill_sceptre_bomb_4,
|
||||
general_combat_render,
|
||||
general_combat_render_0,
|
||||
general_combat_render_1,
|
||||
skill_general_stat_0,
|
||||
skill_general_stat_1,
|
||||
skill_general_tree_0,
|
||||
@ -162,6 +170,7 @@ pub struct Diary<'a> {
|
||||
created_btns_top_r: usize,
|
||||
created_btns_bot_l: usize,
|
||||
created_btns_bot_r: usize,
|
||||
hovering_exp_bar: bool,
|
||||
}
|
||||
|
||||
impl<'a> Diary<'a> {
|
||||
@ -191,6 +200,7 @@ impl<'a> Diary<'a> {
|
||||
created_btns_top_r: 0,
|
||||
created_btns_bot_l: 0,
|
||||
created_btns_bot_r: 0,
|
||||
hovering_exp_bar: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,16 +214,7 @@ impl<'a> Diary<'a> {
|
||||
Achievements,
|
||||
}*/
|
||||
|
||||
pub enum SelectedSkillTree {
|
||||
None,
|
||||
Sword,
|
||||
Hammer,
|
||||
Axe,
|
||||
Sceptre,
|
||||
Bow,
|
||||
StaffFire,
|
||||
GeneralCombat,
|
||||
}
|
||||
pub type SelectedSkillTree = skills::SkillGroupType;
|
||||
|
||||
const WEAPONS: [&str; 7] = [
|
||||
"General Combat",
|
||||
@ -227,7 +228,7 @@ const WEAPONS: [&str; 7] = [
|
||||
|
||||
pub enum Event {
|
||||
Close,
|
||||
ChangeWeaponTree(SelectedSkillTree),
|
||||
ChangeSkillTree(SelectedSkillTree),
|
||||
UnlockSkill(Skill),
|
||||
}
|
||||
|
||||
@ -346,31 +347,35 @@ impl<'a> Widget for Diary<'a> {
|
||||
// Weapon icons
|
||||
if Button::image(match i.1 {
|
||||
"General Combat" => match sel_tab {
|
||||
SelectedSkillTree::GeneralCombat => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::General => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
},
|
||||
"Sword" => match sel_tab {
|
||||
SelectedSkillTree::Sword => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sword) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
},
|
||||
"Hammer" => match sel_tab {
|
||||
SelectedSkillTree::Hammer => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => {
|
||||
self.imgs.wpn_icon_border_pressed
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
},
|
||||
"Axe" => match sel_tab {
|
||||
SelectedSkillTree::Axe => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Axe) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
},
|
||||
"Sceptre" => match sel_tab {
|
||||
SelectedSkillTree::Sceptre => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sceptre) => {
|
||||
self.imgs.wpn_icon_border_pressed
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
},
|
||||
"Bow" => match sel_tab {
|
||||
SelectedSkillTree::Bow => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Bow) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
},
|
||||
"Fire Staff" => match sel_tab {
|
||||
SelectedSkillTree::StaffFire => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Staff) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
@ -378,62 +383,70 @@ impl<'a> Widget for Diary<'a> {
|
||||
.w_h(tweak!(50.0), tweak!(50.0))
|
||||
.hover_image(match i.1 {
|
||||
"General Combat" => match sel_tab {
|
||||
SelectedSkillTree::GeneralCombat => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::General => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_mo,
|
||||
},
|
||||
"Sword" => match sel_tab {
|
||||
SelectedSkillTree::Sword => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sword) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_mo,
|
||||
},
|
||||
"Hammer" => match sel_tab {
|
||||
SelectedSkillTree::Hammer => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => {
|
||||
self.imgs.wpn_icon_border_pressed
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border_mo,
|
||||
},
|
||||
"Axe" => match sel_tab {
|
||||
SelectedSkillTree::Axe => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Axe) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_mo,
|
||||
},
|
||||
"Sceptre" => match sel_tab {
|
||||
SelectedSkillTree::Sceptre => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sceptre) => {
|
||||
self.imgs.wpn_icon_border_pressed
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border_mo,
|
||||
},
|
||||
"Bow" => match sel_tab {
|
||||
SelectedSkillTree::Bow => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Bow) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_mo,
|
||||
},
|
||||
"Fire Staff" => match sel_tab {
|
||||
SelectedSkillTree::StaffFire => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Staff) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_mo,
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
})
|
||||
.press_image(match i.1 {
|
||||
"General Combat" => match sel_tab {
|
||||
SelectedSkillTree::GeneralCombat => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::General => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_press,
|
||||
},
|
||||
"Sword" => match sel_tab {
|
||||
SelectedSkillTree::Sword => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sword) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_press,
|
||||
},
|
||||
"Hammer" => match sel_tab {
|
||||
SelectedSkillTree::Hammer => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => {
|
||||
self.imgs.wpn_icon_border_pressed
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border_press,
|
||||
},
|
||||
"Axe" => match sel_tab {
|
||||
SelectedSkillTree::Axe => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Axe) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_press,
|
||||
},
|
||||
"Sceptre" => match sel_tab {
|
||||
SelectedSkillTree::Sceptre => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sceptre) => {
|
||||
self.imgs.wpn_icon_border_pressed
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border_press,
|
||||
},
|
||||
"Bow" => match sel_tab {
|
||||
SelectedSkillTree::Bow => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Bow) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_press,
|
||||
},
|
||||
"Fire Staff" => match sel_tab {
|
||||
SelectedSkillTree::StaffFire => self.imgs.wpn_icon_border_pressed,
|
||||
SelectedSkillTree::Weapon(ToolKind::Staff) => self.imgs.wpn_icon_border_pressed,
|
||||
_ => self.imgs.wpn_icon_border_press,
|
||||
},
|
||||
_ => self.imgs.wpn_icon_border,
|
||||
@ -444,21 +457,84 @@ impl<'a> Widget for Diary<'a> {
|
||||
{
|
||||
match i.1 {
|
||||
"General Combat" => {
|
||||
events.push(Event::ChangeWeaponTree(SelectedSkillTree::GeneralCombat))
|
||||
events.push(Event::ChangeSkillTree(SelectedSkillTree::General))
|
||||
},
|
||||
"Sword" => events.push(Event::ChangeWeaponTree(SelectedSkillTree::Sword)),
|
||||
"Hammer" => events.push(Event::ChangeWeaponTree(SelectedSkillTree::Hammer)),
|
||||
"Axe" => events.push(Event::ChangeWeaponTree(SelectedSkillTree::Axe)),
|
||||
"Sceptre" => events.push(Event::ChangeWeaponTree(SelectedSkillTree::Sceptre)),
|
||||
"Bow" => events.push(Event::ChangeWeaponTree(SelectedSkillTree::Bow)),
|
||||
"Fire Staff" => {
|
||||
events.push(Event::ChangeWeaponTree(SelectedSkillTree::StaffFire))
|
||||
},
|
||||
_ => events.push(Event::ChangeWeaponTree(SelectedSkillTree::None)),
|
||||
"Sword" => events.push(Event::ChangeSkillTree(SelectedSkillTree::Weapon(
|
||||
ToolKind::Sword,
|
||||
))),
|
||||
"Hammer" => events.push(Event::ChangeSkillTree(SelectedSkillTree::Weapon(
|
||||
ToolKind::Hammer,
|
||||
))),
|
||||
"Axe" => events.push(Event::ChangeSkillTree(SelectedSkillTree::Weapon(
|
||||
ToolKind::Axe,
|
||||
))),
|
||||
"Sceptre" => events.push(Event::ChangeSkillTree(SelectedSkillTree::Weapon(
|
||||
ToolKind::Sceptre,
|
||||
))),
|
||||
"Bow" => events.push(Event::ChangeSkillTree(SelectedSkillTree::Weapon(
|
||||
ToolKind::Bow,
|
||||
))),
|
||||
"Fire Staff" => events.push(Event::ChangeSkillTree(SelectedSkillTree::Weapon(
|
||||
ToolKind::Staff,
|
||||
))),
|
||||
_ => events.push(Event::Close),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exp Bars and Rank Display
|
||||
let current_exp = self.stats.skill_set.get_experience(*sel_tab) as f64;
|
||||
let max_exp = sel_tab.skill_point_cost() as f64;
|
||||
let exp_percentage = current_exp / max_exp;
|
||||
let rank = self.stats.skill_set.get_earned_sp(*sel_tab);
|
||||
let rank_txt = format!("{}", rank);
|
||||
let exp_txt = format!("{}/{}", current_exp, max_exp);
|
||||
let available_pts = self.stats.skill_set.get_available_sp(*sel_tab);
|
||||
let available_pts_txt = format!("{} SP available!", available_pts);
|
||||
Image::new(self.imgs.diary_exp_bg)
|
||||
.w_h(480.0, 76.0)
|
||||
.mid_bottom_with_margin_on(state.content_align, tweak!(10.0))
|
||||
.set(state.exp_bar_bg, ui);
|
||||
Rectangle::fill_with([400.0, 40.0], color::TRANSPARENT)
|
||||
.top_left_with_margins_on(state.exp_bar_bg, 32.0, 40.0)
|
||||
.set(state.exp_bar_content_align, ui);
|
||||
Image::new(self.imgs.bar_content)
|
||||
.w_h(400.0 * exp_percentage, 40.0)
|
||||
.top_left_with_margins_on(state.exp_bar_content_align, 0.0, 0.0)
|
||||
.color(Some(XP_COLOR))
|
||||
.set(state.exp_bar_content, ui);
|
||||
Image::new(self.imgs.diary_exp_frame)
|
||||
.w_h(480.0, 76.0)
|
||||
.color(Some(UI_HIGHLIGHT_0))
|
||||
.middle_of(state.exp_bar_bg)
|
||||
.set(state.exp_bar_frame, ui);
|
||||
// Show EXP bar text on hover
|
||||
self.hovering_exp_bar = ui
|
||||
.widget_input(state.exp_bar_frame)
|
||||
.mouse()
|
||||
.map_or(false, |m| m.is_over());
|
||||
if self.hovering_exp_bar {
|
||||
Text::new(&exp_txt)
|
||||
.mid_top_with_margin_on(state.exp_bar_frame, tweak!(47.0))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(tweak!(14)))
|
||||
.color(TEXT_COLOR)
|
||||
.graphics_for(state.exp_bar_frame)
|
||||
.set(state.exp_bar_txt, ui);
|
||||
}
|
||||
Text::new(&rank_txt)
|
||||
.mid_top_with_margin_on(state.exp_bar_frame, tweak!(5.0))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(tweak!(28)))
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.exp_bar_rank, ui);
|
||||
if available_pts > 0 {
|
||||
Text::new(&available_pts_txt)
|
||||
.mid_top_with_margin_on(state.content_align, tweak!(10.0))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(tweak!(28)))
|
||||
.color(QUALITY_LEGENDARY)
|
||||
.set(state.available_pts_txt, ui);
|
||||
}
|
||||
// Skill Trees
|
||||
// Alignment Placing
|
||||
let x = tweak!(200.0);
|
||||
@ -479,37 +555,37 @@ impl<'a> Widget for Diary<'a> {
|
||||
// Number of skills per rectangle per weapon, start counting at 0
|
||||
// Maximum of 9 skills/8 indices
|
||||
let skills_top_l = match sel_tab {
|
||||
SelectedSkillTree::GeneralCombat => 2,
|
||||
SelectedSkillTree::Sword => 4,
|
||||
SelectedSkillTree::Axe => 4,
|
||||
SelectedSkillTree::Hammer => 4,
|
||||
SelectedSkillTree::Bow => 2,
|
||||
SelectedSkillTree::StaffFire => 4,
|
||||
SelectedSkillTree::Sceptre => 6,
|
||||
SelectedSkillTree::General => 2,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sword) => 4,
|
||||
SelectedSkillTree::Weapon(ToolKind::Axe) => 4,
|
||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => 4,
|
||||
SelectedSkillTree::Weapon(ToolKind::Bow) => 2,
|
||||
SelectedSkillTree::Weapon(ToolKind::Staff) => 4,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sceptre) => 6,
|
||||
_ => 0,
|
||||
};
|
||||
let skills_top_r = match sel_tab {
|
||||
SelectedSkillTree::GeneralCombat => 6,
|
||||
SelectedSkillTree::Sword => 6,
|
||||
SelectedSkillTree::Axe => 5,
|
||||
SelectedSkillTree::Hammer => 4,
|
||||
SelectedSkillTree::Bow => 6,
|
||||
SelectedSkillTree::StaffFire => 4,
|
||||
SelectedSkillTree::Sceptre => 5,
|
||||
SelectedSkillTree::General => 6,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sword) => 6,
|
||||
SelectedSkillTree::Weapon(ToolKind::Axe) => 5,
|
||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => 4,
|
||||
SelectedSkillTree::Weapon(ToolKind::Bow) => 6,
|
||||
SelectedSkillTree::Weapon(ToolKind::Staff) => 4,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sceptre) => 5,
|
||||
_ => 0,
|
||||
};
|
||||
let skills_bot_l = match sel_tab {
|
||||
SelectedSkillTree::GeneralCombat => 4,
|
||||
SelectedSkillTree::Sword => 5,
|
||||
SelectedSkillTree::Axe => 5,
|
||||
SelectedSkillTree::Hammer => 6,
|
||||
SelectedSkillTree::Bow => 5,
|
||||
SelectedSkillTree::StaffFire => 5,
|
||||
SelectedSkillTree::General => 4,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sword) => 5,
|
||||
SelectedSkillTree::Weapon(ToolKind::Axe) => 5,
|
||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => 6,
|
||||
SelectedSkillTree::Weapon(ToolKind::Bow) => 5,
|
||||
SelectedSkillTree::Weapon(ToolKind::Staff) => 5,
|
||||
_ => 0,
|
||||
};
|
||||
let skills_bot_r = match sel_tab {
|
||||
SelectedSkillTree::Sword => 1,
|
||||
SelectedSkillTree::Bow => 1,
|
||||
SelectedSkillTree::Weapon(ToolKind::Sword) => 1,
|
||||
SelectedSkillTree::Weapon(ToolKind::Bow) => 1,
|
||||
_ => 0,
|
||||
};
|
||||
// Update widget id array len
|
||||
@ -614,16 +690,26 @@ impl<'a> Widget for Diary<'a> {
|
||||
let art_size = [tweak!(320.0), tweak!(320.0)];
|
||||
let skills = &self.stats.skill_set.skills;
|
||||
match sel_tab {
|
||||
SelectedSkillTree::GeneralCombat => {
|
||||
SelectedSkillTree::General => {
|
||||
use skills::{GeneralSkill::*, RollSkill::*, SkillGroupType::*};
|
||||
use ToolKind::*;
|
||||
// General Combat
|
||||
Image::new(self.imgs.not_found)
|
||||
.wh(art_size)
|
||||
.middle_of(state.content_align)
|
||||
.graphics_for(state.content_align)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, tweak!(1.0))))
|
||||
.set(state.general_combat_render, ui);
|
||||
Image::new(
|
||||
self.item_imgs
|
||||
.img_id_or_not_found_img(Tool("example_general_combat_left".to_string())),
|
||||
)
|
||||
.wh(art_size)
|
||||
.middle_of(state.content_align)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, tweak!(1.0))))
|
||||
.set(state.general_combat_render_0, ui);
|
||||
Image::new(
|
||||
self.item_imgs
|
||||
.img_id_or_not_found_img(Tool("example_general_combat_right".to_string())),
|
||||
)
|
||||
.wh(art_size)
|
||||
.middle_of(state.general_combat_render_0)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, tweak!(1.0))))
|
||||
.set(state.general_combat_render_1, ui);
|
||||
// Top Left skills
|
||||
// 5 1 6
|
||||
// 3 0 4
|
||||
@ -943,7 +1029,7 @@ impl<'a> Widget for Diary<'a> {
|
||||
events.push(Event::UnlockSkill(skill));
|
||||
};
|
||||
},
|
||||
SelectedSkillTree::Sword => {
|
||||
SelectedSkillTree::Weapon(ToolKind::Sword) => {
|
||||
use skills::SwordSkill::*;
|
||||
// Sword
|
||||
Image::new(
|
||||
@ -952,7 +1038,6 @@ impl<'a> Widget for Diary<'a> {
|
||||
)
|
||||
.wh(art_size)
|
||||
.middle_of(state.content_align)
|
||||
.graphics_for(state.content_align)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, tweak!(1.0))))
|
||||
.set(state.sword_render, ui);
|
||||
// Top Left skills
|
||||
@ -1379,7 +1464,7 @@ impl<'a> Widget for Diary<'a> {
|
||||
events.push(Event::UnlockSkill(skill));
|
||||
};
|
||||
},
|
||||
SelectedSkillTree::Axe => {
|
||||
SelectedSkillTree::Weapon(ToolKind::Axe) => {
|
||||
use skills::AxeSkill::*;
|
||||
// Axe
|
||||
Image::new(
|
||||
@ -1388,7 +1473,6 @@ impl<'a> Widget for Diary<'a> {
|
||||
)
|
||||
.wh(art_size)
|
||||
.middle_of(state.content_align)
|
||||
.graphics_for(state.content_align)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, tweak!(1.0))))
|
||||
.set(state.axe_render, ui);
|
||||
// Top Left skills
|
||||
@ -1762,7 +1846,7 @@ impl<'a> Widget for Diary<'a> {
|
||||
events.push(Event::UnlockSkill(skill));
|
||||
};
|
||||
},
|
||||
SelectedSkillTree::Hammer => {
|
||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => {
|
||||
use skills::HammerSkill::*;
|
||||
// Hammer
|
||||
Image::new(
|
||||
@ -1771,7 +1855,6 @@ impl<'a> Widget for Diary<'a> {
|
||||
)
|
||||
.wh(art_size)
|
||||
.middle_of(state.content_align)
|
||||
.graphics_for(state.content_align)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, tweak!(1.0))))
|
||||
.set(state.hammer_render, ui);
|
||||
// Top Left skills
|
||||
@ -2145,7 +2228,7 @@ impl<'a> Widget for Diary<'a> {
|
||||
events.push(Event::UnlockSkill(skill));
|
||||
};
|
||||
},
|
||||
SelectedSkillTree::Bow => {
|
||||
SelectedSkillTree::Weapon(ToolKind::Bow) => {
|
||||
use skills::BowSkill::*;
|
||||
// Bow
|
||||
Image::new(
|
||||
@ -2154,7 +2237,6 @@ impl<'a> Widget for Diary<'a> {
|
||||
)
|
||||
.wh(art_size)
|
||||
.middle_of(state.content_align)
|
||||
.graphics_for(state.content_align)
|
||||
.set(state.bow_render, ui);
|
||||
// Top Left skills
|
||||
// 5 1 6
|
||||
@ -2528,7 +2610,7 @@ impl<'a> Widget for Diary<'a> {
|
||||
events.push(Event::UnlockSkill(skill));
|
||||
};
|
||||
},
|
||||
SelectedSkillTree::StaffFire => {
|
||||
SelectedSkillTree::Weapon(ToolKind::Staff) => {
|
||||
use skills::StaffSkill::*;
|
||||
// Staff
|
||||
Image::new(
|
||||
@ -2537,7 +2619,6 @@ impl<'a> Widget for Diary<'a> {
|
||||
)
|
||||
.wh(art_size)
|
||||
.middle_of(state.content_align)
|
||||
.graphics_for(state.content_align)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, tweak!(1.0))))
|
||||
.set(state.staff_render, ui);
|
||||
// Top Left skills
|
||||
@ -2885,7 +2966,7 @@ impl<'a> Widget for Diary<'a> {
|
||||
events.push(Event::UnlockSkill(skill));
|
||||
};
|
||||
},
|
||||
SelectedSkillTree::Sceptre => {
|
||||
SelectedSkillTree::Weapon(ToolKind::Sceptre) => {
|
||||
use skills::SceptreSkill::*;
|
||||
// Sceptre
|
||||
Image::new(
|
||||
@ -2894,7 +2975,6 @@ impl<'a> Widget for Diary<'a> {
|
||||
)
|
||||
.wh(art_size)
|
||||
.middle_of(state.content_align)
|
||||
.graphics_for(state.content_align)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, tweak!(1.0))))
|
||||
.set(state.sceptre_render, ui);
|
||||
// Top Left skills
|
||||
|
@ -65,6 +65,8 @@ image_ids! {
|
||||
// Diary Window
|
||||
diary_bg: "voxygen.element.misc_bg.diary_bg",
|
||||
diary_frame: "voxygen.element.misc_bg.diary_frame",
|
||||
diary_exp_bg: "voxygen.element.misc_bg.diary_exp_bg",
|
||||
diary_exp_frame: "voxygen.element.misc_bg.diary_exp_frame",
|
||||
|
||||
// Skill Trees
|
||||
sceptre: "voxygen.element.icons.sceptre",
|
||||
@ -184,6 +186,7 @@ image_ids! {
|
||||
// Other Icons/Art
|
||||
skull: "voxygen.element.icons.skull",
|
||||
skull_2: "voxygen.element.icons.skull_2",
|
||||
indicator_bubble: "voxygen.element.icons.indicator_bubble",
|
||||
fireplace: "voxygen.element.misc_bg.fireplace",
|
||||
|
||||
// Crosshair
|
||||
|
@ -99,6 +99,7 @@ const LOW_HP_COLOR: Color = Color::Rgba(0.93, 0.59, 0.03, 1.0);
|
||||
const CRITICAL_HP_COLOR: Color = Color::Rgba(0.79, 0.19, 0.17, 1.0);
|
||||
const STAMINA_COLOR: Color = Color::Rgba(0.29, 0.62, 0.75, 0.9);
|
||||
const ENEMY_HP_COLOR: Color = Color::Rgba(0.93, 0.1, 0.29, 1.0);
|
||||
const XP_COLOR: Color = Color::Rgba(0.59, 0.41, 0.67, 1.0);
|
||||
//const TRANSPARENT: Color = Color::Rgba(0.0, 0.0, 0.0, 0.0);
|
||||
//const FOCUS_COLOR: Color = Color::Rgba(1.0, 0.56, 0.04, 1.0);
|
||||
//const RAGE_COLOR: Color = Color::Rgba(0.5, 0.04, 0.13, 1.0);
|
||||
@ -756,7 +757,7 @@ impl Hud {
|
||||
group_menu: false,
|
||||
mini_map: true,
|
||||
settings_tab: SettingsTab::Interface,
|
||||
skilltreetab: SelectedSkillTree::GeneralCombat,
|
||||
skilltreetab: SelectedSkillTree::General,
|
||||
social_tab: SocialTab::Online,
|
||||
want_grab: true,
|
||||
ingame: true,
|
||||
@ -1057,6 +1058,111 @@ impl Hud {
|
||||
}
|
||||
}
|
||||
}
|
||||
// EXP Numbers
|
||||
/*if let (Some(floaters), Some(stats)) = (
|
||||
Some(&*ecs.read_resource::<crate::ecs::MyExpFloaterList>())
|
||||
.map(|l| &l.floaters)
|
||||
.filter(|f| !f.is_empty()),
|
||||
stats.get(me),
|
||||
) {
|
||||
// TODO replace with setting
|
||||
let batched_sct = false;
|
||||
if batched_sct {
|
||||
let number_speed = 50.0; // Number Speed for Cumulated EXP
|
||||
let player_sct_bg_id = player_sct_bg_id_walker.next(
|
||||
&mut self.ids.player_sct_bgs,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
);
|
||||
let player_sct_id = player_sct_id_walker.next(
|
||||
&mut self.ids.player_scts,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
);
|
||||
// Sum xp change
|
||||
let exp_change = floaters.iter().fold(0, |acc, f| f.exp_change + acc);
|
||||
// Can't fail since we filtered out empty lists above
|
||||
let (timer, rand) = floaters
|
||||
.last()
|
||||
.map(|f| (f.timer, f.rand))
|
||||
.expect("Impossible");
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size_xp = 30
|
||||
+ ((exp_change.abs() as f32 / stats.exp.maximum() as f32).min(1.0)
|
||||
* 50.0) as u32
|
||||
+ if timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let y = timer as f64 * number_speed; // Timer sets the widget offset
|
||||
let fade = ((4.0 - timer as f32) * 0.25) + 0.2; // Timer sets text transparency
|
||||
|
||||
Text::new(&format!("{} Exp", 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 * rand.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * rand.1 as f64) + y - 3.0,
|
||||
)
|
||||
.set(player_sct_bg_id, ui_widgets);
|
||||
Text::new(&format!("{} Exp", 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 * rand.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * rand.1 as f64) + y,
|
||||
)
|
||||
.set(player_sct_id, ui_widgets);
|
||||
} else {
|
||||
for floater in floaters {
|
||||
let number_speed = 50.0; // Number Speed for Single EXP
|
||||
let player_sct_bg_id = player_sct_bg_id_walker.next(
|
||||
&mut self.ids.player_sct_bgs,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
);
|
||||
let player_sct_id = player_sct_id_walker.next(
|
||||
&mut self.ids.player_scts,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
);
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size_xp = 30
|
||||
+ ((floater.exp_change.abs() as f32 / stats.exp.maximum() as f32)
|
||||
.min(1.0)
|
||||
* 50.0) as u32
|
||||
+ if floater.timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - floater.timer / 0.1) * 10.0) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let y = floater.timer as f64 * number_speed; // Timer sets the widget offset
|
||||
let fade = ((4.0 - floater.timer as f32) * 0.25) + 0.2; // Timer sets text transparency
|
||||
|
||||
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.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * floater.rand.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.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * floater.rand.1 as f64) + y,
|
||||
)
|
||||
.set(player_sct_id, ui_widgets);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// Pop speech bubbles
|
||||
@ -2222,7 +2328,7 @@ impl Hud {
|
||||
self.show.want_grab = true;
|
||||
self.force_ungrab = false;
|
||||
},
|
||||
diary::Event::ChangeWeaponTree(tree_sel) => {
|
||||
diary::Event::ChangeSkillTree(tree_sel) => {
|
||||
self.show.open_skill_tree(tree_sel)
|
||||
},
|
||||
diary::Event::UnlockSkill(skill) => events.push(Event::UnlockSkill(skill)),
|
||||
|
@ -1,6 +1,8 @@
|
||||
use super::{
|
||||
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,
|
||||
img_ids::Imgs, DEFAULT_NPC, 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, ENEMY_HP_COLOR
|
||||
};
|
||||
use crate::{
|
||||
hud::get_buff_info,
|
||||
@ -17,6 +19,8 @@ use conrod_core::{
|
||||
};
|
||||
const MAX_BUBBLE_WIDTH: f64 = 250.0;
|
||||
|
||||
use inline_tweak::*;
|
||||
|
||||
widget_ids! {
|
||||
struct Ids {
|
||||
// Speech bubble
|
||||
@ -119,7 +123,8 @@ impl<'a> Ingameable for Overhead<'a> {
|
||||
// - 2 Text::new for name
|
||||
//
|
||||
// If HP Info is shown:
|
||||
// - 1 for level: either Text or Image
|
||||
// - 1 for level: either Text or Image <-- Not used currently, will be replaced
|
||||
// by something else
|
||||
// - 3 for HP + fg + bg
|
||||
// - 1 for HP text
|
||||
// - If there's mana
|
||||
@ -365,9 +370,34 @@ impl<'a> Widget for Overhead<'a> {
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.99)))
|
||||
.parent(id)
|
||||
.set(state.ids.health_bar_fg, ui);
|
||||
|
||||
// TODO: Add strength comparison here, this is just an example
|
||||
// Factors to take into account:
|
||||
// Maximum HP
|
||||
// Protection
|
||||
// Mainhand Weapon DPS
|
||||
// "Boss Factor" (?)
|
||||
// For players: Highest skilltree rank
|
||||
|
||||
let indicator_col = match health_max as u32 {
|
||||
0..=50 => QUALITY_LOW,
|
||||
51..=100 => QUALITY_COMMON,
|
||||
101..=150 => QUALITY_MODERATE,
|
||||
151..=200 => QUALITY_HIGH,
|
||||
201..=250 => QUALITY_EPIC,
|
||||
251..=300 => QUALITY_LEGENDARY,
|
||||
301..=350 => QUALITY_ARTIFACT,
|
||||
351..=9999 => QUALITY_DEBUG,
|
||||
_ => XP_COLOR,
|
||||
};
|
||||
Image::new(self.imgs.indicator_bubble)
|
||||
.w_h(5.0 * BARSIZE, 5.0 * BARSIZE)
|
||||
.x_y(tweak!(-37.0) * BARSIZE, MANA_BAR_Y + tweak!(7.5))
|
||||
.color(Some(indicator_col))
|
||||
.parent(id)
|
||||
.set(state.ids.level, ui);
|
||||
}
|
||||
}
|
||||
|
||||
// Speech bubble
|
||||
if let Some(bubble) = self.bubble {
|
||||
let dark_mode = self.settings.speech_bubble_dark_mode;
|
||||
|
Loading…
Reference in New Issue
Block a user