mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add Exp-Bar
This commit is contained in:
parent
1a92bd7fe1
commit
3abfa4d2cc
@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Doors now animate opening when entities are near them.
|
||||
- Musical instruments can now be crafted, looted and played
|
||||
- NPCs now move to their target's last known position.
|
||||
- Experience bar below the hotbar
|
||||
|
||||
### Changed
|
||||
|
||||
|
BIN
assets/voxygen/element/ui/skillbar/exp_frame.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/skillbar/exp_frame.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/ui/skillbar/exp_frame_bg.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/skillbar/exp_frame_bg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/ui/skillbar/selected_exp_frame.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/skillbar/selected_exp_frame.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/ui/skillbar/selected_exp_frame_bg.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/skillbar/selected_exp_frame_bg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -4,6 +4,7 @@ hud-skill-not_unlocked = Not yet unlocked
|
||||
hud-skill-req_sp ={"\u000A"}
|
||||
|
||||
Requires { $number } SP
|
||||
hud-skill-set_as_exp_bar = Set as Experience Bar
|
||||
hud-skill-inc_health_title = Increase Health
|
||||
hud-skill-inc_health = Increases max health by { $boost }{ $SP }
|
||||
hud-skill-inc_energy_title = Increase Energy
|
||||
|
@ -20,6 +20,7 @@ use crate::{
|
||||
};
|
||||
use conrod_core::{
|
||||
color, image,
|
||||
position::Relative,
|
||||
widget::{self, Button, Image, Rectangle, State, Text},
|
||||
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, UiCell, Widget, WidgetCommon,
|
||||
};
|
||||
@ -70,6 +71,7 @@ widget_ids! {
|
||||
exp_bar_content,
|
||||
exp_bar_rank,
|
||||
exp_bar_txt,
|
||||
active_bar_checkbox,
|
||||
tree_title_txt,
|
||||
lock_imgs[],
|
||||
available_pts_txt,
|
||||
@ -341,6 +343,7 @@ pub enum Event {
|
||||
ChangeSkillTree(SelectedSkillTree),
|
||||
UnlockSkill(Skill),
|
||||
ChangeSection(DiarySection),
|
||||
SelectExpBar(Option<SkillGroupKind>),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
@ -672,6 +675,42 @@ impl<'a> Widget for Diary<'a> {
|
||||
.color(Some(UI_HIGHLIGHT_0))
|
||||
.middle_of(state.ids.exp_bar_bg)
|
||||
.set(state.ids.exp_bar_frame, ui);
|
||||
// Show as Exp bar below skillbar
|
||||
let exp_selected =
|
||||
self.global_state.settings.interface.xp_bar_skillgroup == Some(*sel_tab);
|
||||
if Button::image(if !exp_selected {
|
||||
self.imgs.checkbox
|
||||
} else {
|
||||
self.imgs.checkbox_checked
|
||||
})
|
||||
.w_h(24.0, 25.0)
|
||||
.hover_image(if !exp_selected {
|
||||
self.imgs.checkbox_mo
|
||||
} else {
|
||||
self.imgs.checkbox_checked_mo
|
||||
})
|
||||
.press_image(if !exp_selected {
|
||||
self.imgs.checkbox_press
|
||||
} else {
|
||||
self.imgs.checkbox_checked
|
||||
})
|
||||
.top_right_with_margins_on(state.ids.exp_bar_frame, 50.0, -40.0)
|
||||
.label(&self.localized_strings.get_msg("hud-skill-set_as_exp_bar"))
|
||||
.label_font_size(self.fonts.cyri.scale(14))
|
||||
.label_color(TEXT_COLOR)
|
||||
.label_font_id(self.fonts.cyri.conrod_id)
|
||||
.label_x(Relative::Scalar(87.0))
|
||||
.label_y(Relative::Scalar(2.0))
|
||||
.set(state.ids.active_bar_checkbox, ui)
|
||||
.was_clicked()
|
||||
{
|
||||
if self.global_state.settings.interface.xp_bar_skillgroup != Some(*sel_tab) {
|
||||
events.push(Event::SelectExpBar(Some(*sel_tab)));
|
||||
} else {
|
||||
events.push(Event::SelectExpBar(None));
|
||||
}
|
||||
}
|
||||
|
||||
// Show EXP bar text on hover
|
||||
if ui
|
||||
.widget_input(state.ids.exp_bar_frame)
|
||||
|
@ -367,6 +367,10 @@ image_ids! {
|
||||
skillbar_frame: "voxygen.element.ui.skillbar.frame",
|
||||
health_bg: "voxygen.element.ui.skillbar.health_bg",
|
||||
health_frame: "voxygen.element.ui.skillbar.health_frame",
|
||||
exp_frame: "voxygen.element.ui.skillbar.exp_frame",
|
||||
exp_frame_bg: "voxygen.element.ui.skillbar.exp_frame_bg",
|
||||
selected_exp: "voxygen.element.ui.skillbar.selected_exp_frame",
|
||||
selected_exp_bg: "voxygen.element.ui.skillbar.selected_exp_frame_bg",
|
||||
decayed_bg: "voxygen.element.ui.skillbar.decayed_bg",
|
||||
energy_bg: "voxygen.element.ui.skillbar.energy_bg",
|
||||
energy_frame: "voxygen.element.ui.skillbar.energy_frame",
|
||||
@ -380,6 +384,7 @@ image_ids! {
|
||||
m_click_ico: "voxygen.element.ui.generic.icons.m_click",
|
||||
skillbar_slot: "voxygen.element.ui.skillbar.slot",
|
||||
|
||||
|
||||
// Other Icons/Art
|
||||
skull: "voxygen.element.ui.generic.icons.skull",
|
||||
skull_2: "voxygen.element.ui.generic.icons.skull_2",
|
||||
|
@ -708,6 +708,8 @@ pub enum Event {
|
||||
AssignLeader(Uid),
|
||||
RemoveBuff(BuffKind),
|
||||
UnlockSkill(Skill),
|
||||
SelectExpBar(Option<SkillGroupKind>),
|
||||
|
||||
RequestSiteInfo(SiteId),
|
||||
ChangeAbility(usize, AuxiliaryAbility),
|
||||
|
||||
@ -2887,7 +2889,7 @@ impl Hud {
|
||||
bodies.get(entity),
|
||||
) {
|
||||
let context = AbilityContext::try_from(char_states.get(entity));
|
||||
Skillbar::new(
|
||||
match Skillbar::new(
|
||||
client,
|
||||
&info,
|
||||
global_state,
|
||||
@ -2916,7 +2918,14 @@ impl Hud {
|
||||
combos.get(entity),
|
||||
char_states.get(entity),
|
||||
)
|
||||
.set(self.ids.skillbar, ui_widgets);
|
||||
.set(self.ids.skillbar, ui_widgets)
|
||||
{
|
||||
Some(skillbar::Event::OpenDiary(skillgroup)) => {
|
||||
self.show.diary(true);
|
||||
self.show.open_skill_tree(skillgroup);
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
}
|
||||
// Bag contents
|
||||
if self.show.bag {
|
||||
@ -3357,6 +3366,9 @@ impl Hud {
|
||||
diary::Event::ChangeSection(section) => {
|
||||
self.show.diary_fields.section = section;
|
||||
},
|
||||
diary::Event::SelectExpBar(xp_bar) => {
|
||||
events.push(Event::SelectExpBar(xp_bar))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ use super::{
|
||||
img_ids::{Imgs, ImgsRot},
|
||||
item_imgs::ItemImgs,
|
||||
slots, util, BarNumbers, HudInfo, ShortcutNumbers, BLACK, CRITICAL_HP_COLOR, HP_COLOR,
|
||||
LOW_HP_COLOR, POISEBAR_TICK_COLOR, POISE_COLOR, QUALITY_EPIC, STAMINA_COLOR, TEXT_COLOR,
|
||||
UI_HIGHLIGHT_0,
|
||||
LOW_HP_COLOR, POISEBAR_TICK_COLOR, POISE_COLOR, QUALITY_EPIC, QUALITY_LEGENDARY, STAMINA_COLOR,
|
||||
TEXT_COLOR, UI_HIGHLIGHT_0, XP_COLOR,
|
||||
};
|
||||
use crate::{
|
||||
game_input::GameInput,
|
||||
@ -24,7 +24,11 @@ use client::{self, Client};
|
||||
use common::comp::{
|
||||
self,
|
||||
ability::AbilityInput,
|
||||
item::{tool::AbilityContext, ItemDesc, MaterialStatManifest},
|
||||
item::{
|
||||
tool::{AbilityContext, ToolKind},
|
||||
ItemDesc, MaterialStatManifest,
|
||||
},
|
||||
skillset::SkillGroupKind,
|
||||
Ability, ActiveAbilities, Body, CharacterState, Combo, Energy, Health, Inventory, Poise,
|
||||
PoiseState, SkillSet,
|
||||
};
|
||||
@ -66,9 +70,6 @@ widget_ids! {
|
||||
// Level
|
||||
level_bg,
|
||||
level,
|
||||
// Exp-Bar
|
||||
exp_alignment,
|
||||
exp_filling,
|
||||
// HP-Bar
|
||||
hp_alignment,
|
||||
hp_filling,
|
||||
@ -90,6 +91,14 @@ widget_ids! {
|
||||
poise_txt_alignment,
|
||||
poise_txt_bg,
|
||||
poise_txt,
|
||||
// Exp-Bar
|
||||
exp_frame_bg,
|
||||
exp_frame,
|
||||
exp_filling,
|
||||
exp_img_frame_bg,
|
||||
exp_img_frame,
|
||||
exp_img,
|
||||
exp_lvl,
|
||||
// Combo Counter
|
||||
combo_align,
|
||||
combo_bg,
|
||||
@ -250,6 +259,10 @@ fn slot_entries(state: &State, slot_offset: f64) -> [SlotEntry; 10] {
|
||||
]
|
||||
}
|
||||
|
||||
pub enum Event {
|
||||
OpenDiary(SkillGroupKind),
|
||||
}
|
||||
|
||||
#[derive(WidgetCommon)]
|
||||
pub struct Skillbar<'a> {
|
||||
client: &'a Client,
|
||||
@ -387,7 +400,7 @@ impl<'a> Skillbar<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn show_stat_bars(&self, state: &State, ui: &mut UiCell) {
|
||||
fn show_stat_bars(&self, state: &State, ui: &mut UiCell) -> Option<Event> {
|
||||
let (hp_percentage, energy_percentage, poise_percentage): (f64, f64, f64) =
|
||||
if self.health.is_dead {
|
||||
(0.0, 0.0, 0.0)
|
||||
@ -520,6 +533,83 @@ impl<'a> Skillbar<'a> {
|
||||
.middle_of(state.ids.bg_poise)
|
||||
.set(state.ids.frame_poise, ui);
|
||||
}
|
||||
|
||||
if self
|
||||
.global_state
|
||||
.settings
|
||||
.interface
|
||||
.xp_bar_skillgroup
|
||||
.is_some()
|
||||
{
|
||||
let offset = -81.0;
|
||||
let selected_experience = &self
|
||||
.global_state
|
||||
.settings
|
||||
.interface
|
||||
.xp_bar_skillgroup
|
||||
.unwrap_or(SkillGroupKind::General);
|
||||
let current_exp = self.skillset.available_experience(*selected_experience) as f64;
|
||||
let max_exp = self.skillset.skill_point_cost(*selected_experience) as f64;
|
||||
let exp_percentage = current_exp / max_exp.max(1.0);
|
||||
let level = self.skillset.earned_sp(*selected_experience).to_string();
|
||||
|
||||
// Exp Bar
|
||||
Image::new(self.imgs.exp_frame_bg)
|
||||
.w_h(594.0, 8.0)
|
||||
.mid_top_with_margin_on(state.ids.frame, -offset)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.9)))
|
||||
.set(state.ids.exp_frame_bg, ui);
|
||||
Image::new(self.imgs.exp_frame)
|
||||
.w_h(594.0, 8.0)
|
||||
.middle_of(state.ids.exp_frame_bg)
|
||||
.set(state.ids.exp_frame, ui);
|
||||
|
||||
Image::new(self.imgs.bar_content)
|
||||
.w_h(590.0 * exp_percentage, 4.0)
|
||||
.color(Some(XP_COLOR))
|
||||
.top_left_with_margins_on(state.ids.exp_frame, 2.0, 2.0)
|
||||
.set(state.ids.exp_filling, ui);
|
||||
// Exp Type and Level Display
|
||||
Image::new(self.imgs.selected_exp_bg)
|
||||
.w_h(34.0, 38.0)
|
||||
.top_left_with_margins_on(state.ids.exp_frame, -39.0, 3.0)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.9)))
|
||||
.set(state.ids.exp_img_frame_bg, ui);
|
||||
|
||||
if Button::image(self.imgs.selected_exp)
|
||||
.w_h(34.0, 38.0)
|
||||
.middle_of(state.ids.exp_img_frame_bg)
|
||||
.set(state.ids.exp_img_frame, ui)
|
||||
.was_clicked()
|
||||
{
|
||||
return Some(Event::OpenDiary(*selected_experience));
|
||||
}
|
||||
|
||||
Text::new(&level)
|
||||
.mid_bottom_with_margin_on(state.ids.exp_img_frame, 2.0)
|
||||
.font_size(11)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(QUALITY_LEGENDARY)
|
||||
.graphics_for(state.ids.exp_img_frame)
|
||||
.set(state.ids.exp_lvl, ui);
|
||||
|
||||
Image::new(match selected_experience {
|
||||
SkillGroupKind::General => self.imgs.swords_crossed,
|
||||
SkillGroupKind::Weapon(ToolKind::Sword) => self.imgs.sword,
|
||||
SkillGroupKind::Weapon(ToolKind::Hammer) => self.imgs.hammer,
|
||||
SkillGroupKind::Weapon(ToolKind::Axe) => self.imgs.axe,
|
||||
SkillGroupKind::Weapon(ToolKind::Sceptre) => self.imgs.sceptre,
|
||||
SkillGroupKind::Weapon(ToolKind::Bow) => self.imgs.bow,
|
||||
SkillGroupKind::Weapon(ToolKind::Staff) => self.imgs.staff,
|
||||
SkillGroupKind::Weapon(ToolKind::Pick) => self.imgs.mining,
|
||||
_ => self.imgs.nothing,
|
||||
})
|
||||
.w_h(24.0, 24.0)
|
||||
.graphics_for(state.ids.exp_img_frame)
|
||||
.mid_bottom_with_margin_on(state.ids.exp_img_frame, 13.0)
|
||||
.set(state.ids.exp_img, ui);
|
||||
}
|
||||
|
||||
// Bar Text
|
||||
let bar_text = if self.health.is_dead {
|
||||
Some((
|
||||
@ -597,6 +687,7 @@ impl<'a> Skillbar<'a> {
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.poise_txt, ui);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn show_slotbar(&mut self, state: &State, ui: &mut UiCell, slot_offset: f64) {
|
||||
@ -910,7 +1001,7 @@ pub struct State {
|
||||
}
|
||||
|
||||
impl<'a> Widget for Skillbar<'a> {
|
||||
type Event = ();
|
||||
type Event = Option<Event>;
|
||||
type State = State;
|
||||
type Style = ();
|
||||
|
||||
@ -950,7 +1041,7 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.set(state.ids.frame, ui);
|
||||
|
||||
// Health, Energy and Poise bars
|
||||
self.show_stat_bars(state, ui);
|
||||
let event = self.show_stat_bars(state, ui);
|
||||
|
||||
// Slots
|
||||
self.show_slotbar(state, ui, slot_offset);
|
||||
@ -959,5 +1050,6 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
if let Some(combo_floater) = self.combo_floater {
|
||||
self.show_combo_counter(combo_floater, state, ui);
|
||||
}
|
||||
event
|
||||
}
|
||||
}
|
||||
|
@ -1474,6 +1474,9 @@ impl PlayState for SessionState {
|
||||
self.client.borrow_mut().swap_slots(slot_a, slot_b);
|
||||
}
|
||||
},
|
||||
HudEvent::SelectExpBar(skillgroup) => {
|
||||
global_state.settings.interface.xp_bar_skillgroup = skillgroup;
|
||||
},
|
||||
HudEvent::SplitSwapSlots {
|
||||
slot_a,
|
||||
slot_b,
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
hud::{BarNumbers, BuffPosition, CrosshairType, Intro, ShortcutNumbers, XpBar},
|
||||
ui::ScaleMode,
|
||||
};
|
||||
|
||||
use common::comp::skillset::SkillGroupKind;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// `InterfaceSettings` contains UI, HUD and Map options.
|
||||
@ -48,6 +48,7 @@ pub struct InterfaceSettings {
|
||||
pub minimap_face_north: bool,
|
||||
pub minimap_zoom: f64,
|
||||
pub accum_experience: bool,
|
||||
pub xp_bar_skillgroup: Option<SkillGroupKind>,
|
||||
}
|
||||
|
||||
impl Default for InterfaceSettings {
|
||||
@ -92,6 +93,7 @@ impl Default for InterfaceSettings {
|
||||
minimap_face_north: true,
|
||||
minimap_zoom: 160.0,
|
||||
accum_experience: true,
|
||||
xp_bar_skillgroup: Some(SkillGroupKind::General),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user