Merge branch 'master' of gitlab.com:veloren/veloren into sharp/jungle

This commit is contained in:
Joshua Yanovski 2019-08-19 11:04:09 +02:00
commit 50c90e1cde
77 changed files with 1245 additions and 335 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/element/buttons/checkbox/active.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/buttons/checkbox/hover.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/buttons/checkbox/inactive.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/buttons/checkbox/inactive_hover.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/buttons/checkbox/press.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/icons/2hhammer_m1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/icons/2hhammer_m2.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/icons/2hsword_m1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/icons/2hsword_m2.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/icons/hammer_m1.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/element/misc_bg/level_down.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/misc_bg/level_up.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/element/skill_bar/l.png (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/element/skill_bar/r.png (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/element/skillbar/bar_content.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/energybar_bg.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/healthbar_bg.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/skillbar_slot.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/skillbar_slot_bg.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/skillbar_slot_big.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/skillbar_slot_big_bg.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/skillbar_slot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/skillbar_slot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/xp_bar_content.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/xp_bar_left.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/xp_bar_mid.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skillbar/xp_bar_right.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

View File

@ -12,6 +12,12 @@ pub enum HealthSource {
LevelUp, LevelUp,
Unknown, Unknown,
} }
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum EnergySource {
CastSpell,
LevelUp,
Unknown,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct Health { pub struct Health {
@ -20,6 +26,13 @@ pub struct Health {
pub last_change: Option<(i32, f64, HealthSource)>, pub last_change: Option<(i32, f64, HealthSource)>,
} }
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct Energy {
current: u32,
maximum: u32,
pub last_change: Option<(i32, f64, EnergySource)>,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct Exp { pub struct Exp {
current: f64, current: f64,
@ -57,6 +70,32 @@ impl Health {
} }
} }
impl Energy {
pub fn current(&self) -> u32 {
self.current
}
pub fn maximum(&self) -> u32 {
self.maximum
}
pub fn set_to(&mut self, amount: u32, cause: EnergySource) {
let amount = amount.min(self.maximum);
self.last_change = Some((amount as i32 - self.current as i32, 0.0, cause));
self.current = amount;
}
pub fn change_by(&mut self, amount: i32, cause: EnergySource) {
self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum);
self.last_change = Some((amount, 0.0, cause));
}
pub fn set_maximum(&mut self, amount: u32) {
self.maximum = amount;
self.current = self.current.min(self.maximum);
}
}
impl Exp { impl Exp {
pub fn current(&self) -> f64 { pub fn current(&self) -> f64 {
self.current self.current
@ -103,6 +142,7 @@ impl Level {
pub struct Stats { pub struct Stats {
pub name: String, pub name: String,
pub health: Health, pub health: Health,
pub energy: Energy,
pub level: Level, pub level: Level,
pub exp: Exp, pub exp: Exp,
pub is_dead: bool, pub is_dead: bool,
@ -134,6 +174,11 @@ impl Stats {
current: 0.0, current: 0.0,
maximum: 50.0, maximum: 50.0,
}, },
energy: Energy {
current: 200,
maximum: 200,
last_change: None,
},
is_dead: false, is_dead: false,
} }
} }
@ -143,6 +188,12 @@ impl Stats {
self.health.current = amount; self.health.current = amount;
self self
} }
pub fn with_max_energy(mut self, amount: u32) -> Self {
self.energy.maximum = amount;
self.energy.current = amount;
self
}
} }
impl Component for Stats { impl Component for Stats {

View File

@ -61,7 +61,9 @@ impl ChatCommand {
if !server.entity_is_admin(entity) { if !server.entity_is_admin(entity) {
server.clients.notify( server.clients.notify(
entity, entity,
ServerMsg::private(String::from("You have no permission to do that.")), ServerMsg::private(String::from(
"Unavailable command '/{}'.\nType '/help' for available commands",
)),
); );
return; return;
} else { } else {
@ -211,7 +213,7 @@ fn handle_jump(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
} }
None => server.clients.notify( None => server.clients.notify(
entity, entity,
ServerMsg::private(String::from("You have no position!")), ServerMsg::private(String::from("You have no position.")),
), ),
} }
} }
@ -231,7 +233,7 @@ fn handle_goto(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
} else { } else {
server.clients.notify( server.clients.notify(
entity, entity,
ServerMsg::private(String::from("You don't have a position!")), ServerMsg::private(String::from("You have no position.")),
); );
} }
} else { } else {
@ -279,7 +281,7 @@ fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
0, 0,
); );
let msg = match current_time { let msg = match current_time {
Some(time) => format!("Current time is: {}", time.format("%H:%M").to_string()), Some(time) => format!("It is {}", time.format("%H:%M").to_string()),
None => String::from("Unknown Time"), None => String::from("Unknown Time"),
}; };
server.clients.notify(entity, ServerMsg::private(msg)); server.clients.notify(entity, ServerMsg::private(msg));

View File

@ -1167,7 +1167,7 @@ impl Server {
self.clients.notify( self.clients.notify(
entity, entity,
ServerMsg::private(format!( ServerMsg::private(format!(
"Unrecognised command: '/{}'\ntype '/help' for a list of available commands", "Unknown command '/{}'.\nType '/help' for available commands",
kwd kwd
)), )),
); );

View File

@ -24,7 +24,7 @@ impl Default for ServerSettings {
server_description: "This is the best Veloren server.".to_owned(), server_description: "This is the best Veloren server.".to_owned(),
max_players: 100, max_players: 100,
start_time: 9.0 * 3600.0, start_time: 9.0 * 3600.0,
admins: vec![], admins: vec!["Pfau".to_owned()],
} }
} }
} }
@ -66,7 +66,7 @@ impl ServerSettings {
address: SocketAddr::from(([0; 4], 14004)), address: SocketAddr::from(([0; 4], 14004)),
world_seed: 1337, world_seed: 1337,
server_name: "Singleplayer".to_owned(), server_name: "Singleplayer".to_owned(),
server_description: "The main feature is loneliness!".to_owned(), server_description: "Who needs friends anyway?".to_owned(),
max_players: 100, max_players: 100,
start_time: 9.0 * 3600.0, start_time: 9.0 * 3600.0,
admins: vec!["singleplayer".to_string()], // TODO: Let the player choose if they want to use admin commands or not admins: vec!["singleplayer".to_string()], // TODO: Let the player choose if they want to use admin commands or not

View File

@ -13,6 +13,22 @@ image_ids! {
bag_mid: "voxygen.element.bag.mid", bag_mid: "voxygen.element.bag.mid",
bag_bot: "voxygen.element.bag.bot", bag_bot: "voxygen.element.bag.bot",
// Skillbar
xp_bar_mid: "voxygen.element.skillbar.xp_bar_mid",
xp_bar_left: "voxygen.element.skillbar.xp_bar_left",
xp_bar_right: "voxygen.element.skillbar.xp_bar_right",
skillbar_slot: "voxygen.element.skillbar.skillbar_slot",
skillbar_slot_l: "voxygen.element.skillbar.skillbar_slot_l",
skillbar_slot_r: "voxygen.element.skillbar.skillbar_slot_r",
skillbar_slot_bg: "voxygen.element.skillbar.skillbar_slot_bg",
skillbar_slot_big: "voxygen.element.skillbar.skillbar_slot_big",
skillbar_slot_big_bg: "voxygen.element.skillbar.skillbar_slot_big_bg",
healthbar_bg: "voxygen.element.skillbar.healthbar_bg",
energybar_bg: "voxygen.element.skillbar.energybar_bg",
bar_content: "voxygen.element.skillbar.bar_content",
level_up: "voxygen.element.misc_bg.level_up",
level_down:"voxygen.element.misc_bg.level_down",
// Window Parts // Window Parts
window_3: "voxygen.element.frames.window_3", window_3: "voxygen.element.frames.window_3",
tab_bg: "voxygen.element.frames.tab_bg", tab_bg: "voxygen.element.frames.tab_bg",
@ -41,11 +57,6 @@ image_ids! {
settings_button_pressed: "voxygen.element.buttons.settings_button_pressed", settings_button_pressed: "voxygen.element.buttons.settings_button_pressed",
settings_button_hover: "voxygen.element.buttons.settings_button_hover", settings_button_hover: "voxygen.element.buttons.settings_button_hover",
settings_button_press: "voxygen.element.buttons.settings_button_press", settings_button_press: "voxygen.element.buttons.settings_button_press",
check: "voxygen.element.buttons.check.no",
check_mo: "voxygen.element.buttons.check.no_mo",
check_press: "voxygen.element.buttons.check.press",
check_checked: "voxygen.element.buttons.check.yes",
check_checked_mo: "voxygen.element.buttons.check.yes_mo",
slider: "voxygen.element.slider.track", slider: "voxygen.element.slider.track",
slider_indicator: "voxygen.element.slider.indicator", slider_indicator: "voxygen.element.slider.indicator",
esc_frame: "voxygen.element.frames.esc_menu", esc_frame: "voxygen.element.frames.esc_menu",
@ -64,6 +75,12 @@ image_ids! {
// Crosshair // Crosshair
crosshair_inner: "voxygen.element.misc_bg.crosshair_inner", crosshair_inner: "voxygen.element.misc_bg.crosshair_inner",
// Icons
twohsword_m1: "voxygen.element.icons.2hsword_m1",
twohsword_m2: "voxygen.element.icons.2hsword_m2",
twohhammer_m1: "voxygen.element.icons.2hhammer_m1",
twohhammer_m2: "voxygen.element.icons.2hhammer_m2",
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
<VoxelMs9Graphic> <VoxelMs9Graphic>
@ -76,6 +93,19 @@ image_ids! {
crosshair_bg_press: "voxygen.element.misc_bg.crosshair_bg_press", crosshair_bg_press: "voxygen.element.misc_bg.crosshair_bg_press",
crosshair_bg_pressed: "voxygen.element.misc_bg.crosshair_bg_pressed", crosshair_bg_pressed: "voxygen.element.misc_bg.crosshair_bg_pressed",
// Checkboxes and Radio buttons
check: "voxygen.element.buttons.radio.inactive",
check_mo: "voxygen.element.buttons.radio.inactive_hover",
check_press: "voxygen.element.buttons.radio.press",
check_checked: "voxygen.element.buttons.radio.active",
check_checked_mo: "voxygen.element.buttons.radio.hover",
checkbox: "voxygen.element.buttons.checkbox.inactive",
checkbox_mo: "voxygen.element.buttons.checkbox.inactive_hover",
checkbox_press: "voxygen.element.buttons.checkbox.press",
checkbox_checked: "voxygen.element.buttons.checkbox.active",
checkbox_checked_mo: "voxygen.element.buttons.checkbox.hover",
// Buttons // Buttons
mmap_closed: "voxygen.element.buttons.button_mmap_closed", mmap_closed: "voxygen.element.buttons.button_mmap_closed",
mmap_closed_hover: "voxygen.element.buttons.button_mmap_closed_hover", mmap_closed_hover: "voxygen.element.buttons.button_mmap_closed_hover",
@ -150,6 +180,7 @@ image_ids! {
key: "voxygen.voxel.object.key", key: "voxygen.voxel.object.key",
key_gold: "voxygen.voxel.object.key_gold", key_gold: "voxygen.voxel.object.key_gold",
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
<ImageGraphic> <ImageGraphic>
@ -173,15 +204,6 @@ image_ids! {
grid_button_press: "voxygen.element.buttons.border_press", grid_button_press: "voxygen.element.buttons.border_press",
grid_button_open: "voxygen.element.buttons.border_pressed", grid_button_open: "voxygen.element.buttons.border_pressed",
// Skillbar Module
sb_grid: "voxygen.element.skill_bar.sbar_grid",
sb_grid_bg: "voxygen.element.skill_bar.sbar_grid_bg",
l_click: "voxygen.element.skill_bar.l",
r_click: "voxygen.element.skill_bar.r",
mana_bar: "voxygen.element.skill_bar.mana_bar",
health_bar: "voxygen.element.skill_bar.health_bar",
xp_bar: "voxygen.element.skill_bar.xp_bar",
esc_bg: "voxygen.element.frames.menu", esc_bg: "voxygen.element.frames.menu",
window_frame_2: "voxygen.element.frames.window_2", window_frame_2: "voxygen.element.frames.window_2",

View File

@ -1,10 +1,12 @@
use conrod_core::{ use conrod_core::{
color, color,
widget::{self, Button, Image, Rectangle, Text}, widget::{self, Button, Image, Rectangle, Text},
widget_ids, Colorable, Positionable, Sizeable, Widget, WidgetCommon, widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon,
}; };
use super::{img_ids::Imgs, Fonts, Show, TEXT_COLOR}; use std::time::{Duration, Instant};
use super::{img_ids::Imgs, Fonts, Show, HP_COLOR, TEXT_COLOR};
use client::{self, Client}; use client::{self, Client};
widget_ids! { widget_ids! {
@ -13,6 +15,7 @@ widget_ids! {
mmap_frame_bg, mmap_frame_bg,
mmap_location, mmap_location,
mmap_button, mmap_button,
zone_display,
} }
} }
@ -42,6 +45,9 @@ impl<'a> MiniMap<'a> {
pub struct State { pub struct State {
ids: Ids, ids: Ids,
last_region_name: Option<String>,
last_update: Instant,
} }
pub enum Event { pub enum Event {
@ -56,6 +62,9 @@ impl<'a> Widget for MiniMap<'a> {
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State { fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
State { State {
ids: Ids::new(id_gen), ids: Ids::new(id_gen),
last_region_name: None,
last_update: Instant::now(),
} }
} }
@ -105,6 +114,53 @@ impl<'a> Widget for MiniMap<'a> {
return Some(Event::Toggle); return Some(Event::Toggle);
} }
// Display zone name on entry
const FADE_IN: f32 = 0.5;
const FADE_HOLD: f32 = 1.0;
const FADE_OUT: f32 = 3.0;
match self.client.current_chunk() {
Some(chunk) => {
let current = chunk.meta().name();
// Check if no other popup is displayed and a new one is needed
if state.last_update.elapsed()
> Duration::from_secs_f32(FADE_IN + FADE_HOLD + FADE_OUT)
&& state
.last_region_name
.as_ref()
.map(|l| l != current)
.unwrap_or(true)
{
// Update last_region
state.update(|s| s.last_region_name = Some(current.to_owned()));
state.update(|s| s.last_update = Instant::now());
}
let seconds = state.last_update.elapsed().as_secs_f32();
let fade = if seconds < FADE_IN {
seconds / FADE_IN
} else if seconds < FADE_IN + FADE_HOLD {
1.0
} else {
(1.0 - (seconds - FADE_IN - FADE_HOLD) / FADE_OUT).max(0.0)
};
// Region Name
Text::new(state.last_region_name.as_ref().unwrap_or(&"".to_owned()))
.mid_top_with_margin_on(ui.window, 200.0)
.font_size(80)
.color(Color::Rgba(1.0, 1.0, 1.0, fade))
.set(state.ids.zone_display, ui);
}
None => Text::new(" ")
.middle_of(ui.window)
.font_size(14)
.color(HP_COLOR)
.set(state.ids.zone_display, ui),
}
// TODO: Subregion name display
// Title // Title
match self.client.current_chunk() { match self.client.current_chunk() {
Some(chunk) => Text::new(chunk.meta().name()) Some(chunk) => Text::new(chunk.meta().name())

View File

@ -55,8 +55,13 @@ const XP_COLOR: Color = Color::Rgba(0.59, 0.41, 0.67, 1.0);
const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0); const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
const TEXT_COLOR_2: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0); const TEXT_COLOR_2: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0);
const TEXT_COLOR_3: Color = Color::Rgba(1.0, 1.0, 1.0, 0.1); const TEXT_COLOR_3: Color = Color::Rgba(1.0, 1.0, 1.0, 0.1);
//const BG_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 0.8);
const HP_COLOR: Color = Color::Rgba(0.33, 0.63, 0.0, 1.0); const HP_COLOR: Color = Color::Rgba(0.33, 0.63, 0.0, 1.0);
const MANA_COLOR: Color = Color::Rgba(0.42, 0.41, 0.66, 1.0); const LOW_HP_COLOR: Color = Color::Rgba(0.93, 0.59, 0.03, 1.0);
const CRITICAL_HP_COLOR: Color = Color::Rgba(1.0, 0.0, 0.0, 1.0);
const MANA_COLOR: Color = Color::Rgba(0.47, 0.55, 1.0, 0.9);
//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);
const META_COLOR: Color = Color::Rgba(1.0, 1.0, 0.0, 1.0); const META_COLOR: Color = Color::Rgba(1.0, 1.0, 0.0, 1.0);
const TELL_COLOR: Color = Color::Rgba(0.98, 0.71, 1.0, 1.0); const TELL_COLOR: Color = Color::Rgba(0.98, 0.71, 1.0, 1.0);
const PRIVATE_COLOR: Color = Color::Rgba(1.0, 1.0, 0.0, 1.0); // Difference between private and tell? const PRIVATE_COLOR: Color = Color::Rgba(1.0, 1.0, 0.0, 1.0); // Difference between private and tell?
@ -151,6 +156,10 @@ pub enum Event {
ChangeFOV(u16), ChangeFOV(u16),
CrosshairTransp(f32), CrosshairTransp(f32),
CrosshairType(CrosshairType), CrosshairType(CrosshairType),
ToggleXpBar(XpBar),
ToggleEnBars(EnBars),
ToggleBarNumbers(BarNumbers),
ToggleShortcutNumbers(ShortcutNumbers),
UiScale(ScaleChange), UiScale(ScaleChange),
CharacterSelection, CharacterSelection,
SwapInventorySlots(usize, usize), SwapInventorySlots(usize, usize),
@ -174,6 +183,28 @@ pub enum CrosshairType {
RoundEdges, RoundEdges,
Edges, Edges,
} }
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum XpBar {
Always,
OnGain,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum EnBars {
Always,
OnLoss,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum BarNumbers {
Values,
Percent,
Off,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum ShortcutNumbers {
On,
Off,
}
pub struct Show { pub struct Show {
ui: bool, ui: bool,
@ -686,7 +717,8 @@ impl Hud {
.read_storage::<comp::Stats>() .read_storage::<comp::Stats>()
.get(client.entity()) .get(client.entity())
{ {
Skillbar::new(&self.imgs, &self.fonts, stats).set(self.ids.skillbar, ui_widgets); Skillbar::new(global_state, &self.imgs, &self.fonts, stats)
.set(self.ids.skillbar, ui_widgets);
} }
// Chat box // Chat box
@ -722,10 +754,7 @@ impl Hud {
.set(self.ids.settings_window, ui_widgets) .set(self.ids.settings_window, ui_widgets)
{ {
match event { match event {
settings_window::Event::ToggleHelp => self.show.toggle_help(), settings_window::Event::ToggleHelp => self.show.help = !self.show.help,
settings_window::Event::ToggleInventoryTestButton => {
self.show.inventory_test_button = !self.show.inventory_test_button
}
settings_window::Event::ToggleDebug => self.show.debug = !self.show.debug, settings_window::Event::ToggleDebug => self.show.debug = !self.show.debug,
settings_window::Event::ChangeTab(tab) => self.show.open_setting_tab(tab), settings_window::Event::ChangeTab(tab) => self.show.open_setting_tab(tab),
settings_window::Event::Close => self.show.settings(false), settings_window::Event::Close => self.show.settings(false),
@ -753,6 +782,18 @@ impl Hud {
settings_window::Event::CrosshairType(crosshair_type) => { settings_window::Event::CrosshairType(crosshair_type) => {
events.push(Event::CrosshairType(crosshair_type)); events.push(Event::CrosshairType(crosshair_type));
} }
settings_window::Event::ToggleXpBar(xp_bar) => {
events.push(Event::ToggleXpBar(xp_bar));
}
settings_window::Event::ToggleEnBars(en_bars) => {
events.push(Event::ToggleEnBars(en_bars));
}
settings_window::Event::ToggleBarNumbers(bar_numbers) => {
events.push(Event::ToggleBarNumbers(bar_numbers));
}
settings_window::Event::ToggleShortcutNumbers(shortcut_numbers) => {
events.push(Event::ToggleShortcutNumbers(shortcut_numbers));
}
settings_window::Event::UiScale(scale_change) => { settings_window::Event::UiScale(scale_change) => {
events.push(Event::UiScale(scale_change)); events.push(Event::UiScale(scale_change));
} }

View File

@ -1,4 +1,7 @@
use super::{img_ids::Imgs, CrosshairType, Fonts, Show, TEXT_COLOR}; use super::{
img_ids::Imgs, BarNumbers, CrosshairType, EnBars, Fonts, ShortcutNumbers, Show, XpBar,
TEXT_COLOR,
};
use crate::{ use crate::{
audio::base::Genre, audio::base::Genre,
ui::{ImageSlider, ScaleMode, ToggleButton}, ui::{ImageSlider, ScaleMode, ToggleButton},
@ -42,8 +45,6 @@ widget_ids! {
debug_button, debug_button,
debug_button_label, debug_button_label,
interface, interface,
inventory_test_button,
inventory_test_button_label,
mouse_pan_slider, mouse_pan_slider,
mouse_pan_label, mouse_pan_label,
mouse_pan_value, mouse_pan_value,
@ -81,6 +82,21 @@ widget_ids! {
audio_volume_text, audio_volume_text,
audio_device_list, audio_device_list,
audio_device_text, audio_device_text,
hotbar_title,
bar_numbers_title,
show_bar_numbers_none_button,
show_bar_numbers_none_text,
show_bar_numbers_values_button,
show_bar_numbers_values_text,
show_bar_numbers_percentage_button,
show_bar_numbers_percentage_text,
show_shortcuts_button,
show_shortcuts_text,
show_xpbar_button,
show_xpbar_text,
show_bars_button,
show_bars_text,
placeholder,
} }
} }
@ -100,7 +116,6 @@ pub struct SettingsWindow<'a> {
imgs: &'a Imgs, imgs: &'a Imgs,
fonts: &'a Fonts, fonts: &'a Fonts,
#[conrod(common_builder)] #[conrod(common_builder)]
common: widget::CommonBuilder, common: widget::CommonBuilder,
} }
@ -128,8 +143,11 @@ pub struct State {
pub enum Event { pub enum Event {
ToggleHelp, ToggleHelp,
ToggleInventoryTestButton,
ToggleDebug, ToggleDebug,
ToggleXpBar(XpBar),
ToggleEnBars(EnBars),
ToggleBarNumbers(BarNumbers),
ToggleShortcutNumbers(ShortcutNumbers),
ChangeTab(SettingsTab), ChangeTab(SettingsTab),
Close, Close,
AdjustMousePan(u32), AdjustMousePan(u32),
@ -169,6 +187,9 @@ impl<'a> Widget for SettingsWindow<'a> {
let widget::UpdateArgs { state, ui, .. } = args; let widget::UpdateArgs { state, ui, .. } = args;
let mut events = Vec::new(); let mut events = Vec::new();
let bar_values = self.global_state.settings.gameplay.bar_numbers;
//let mut xp_bar = self.global_state.settings.gameplay.xp_bar;
// Frame Alignment // Frame Alignment
Rectangle::fill_with([824.0, 488.0], color::TRANSPARENT) Rectangle::fill_with([824.0, 488.0], color::TRANSPARENT)
@ -254,19 +275,22 @@ impl<'a> Widget for SettingsWindow<'a> {
.set(state.ids.general_txt, ui); .set(state.ids.general_txt, ui);
// Help // Help
let show_help = let show_help = ToggleButton::new(
ToggleButton::new(self.show.help, self.imgs.check, self.imgs.check_checked) self.show.help,
.w_h(288.0 / 24.0, 288.0 / 24.0) self.imgs.checkbox,
.down_from(state.ids.general_txt, 20.0) self.imgs.checkbox_checked,
.hover_images(self.imgs.check_checked_mo, self.imgs.check_mo) )
.press_images(self.imgs.check_press, self.imgs.check_press) .w_h(18.0, 18.0)
.set(state.ids.button_help, ui); .down_from(state.ids.general_txt, 20.0)
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
.set(state.ids.button_help, ui);
if self.show.help != show_help { if self.show.help != show_help {
events.push(Event::ToggleHelp); events.push(Event::ToggleHelp);
} }
Text::new("Show Help") Text::new("Show Help Window")
.right_from(state.ids.button_help, 10.0) .right_from(state.ids.button_help, 10.0)
.font_size(14) .font_size(14)
.font_id(self.fonts.opensans) .font_id(self.fonts.opensans)
@ -274,44 +298,23 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.show_help_label, ui); .set(state.ids.show_help_label, ui);
// Inventory test
let inventory_test_button = ToggleButton::new(
self.show.inventory_test_button,
self.imgs.check,
self.imgs.check_checked,
)
.w_h(288.0 / 24.0, 288.0 / 24.0)
.down_from(state.ids.button_help, 7.0)
.hover_images(self.imgs.check_checked_mo, self.imgs.check_mo)
.press_images(self.imgs.check_press, self.imgs.check_press)
.set(state.ids.inventory_test_button, ui);
if self.show.inventory_test_button != inventory_test_button {
events.push(Event::ToggleInventoryTestButton);
}
Text::new("Show Inventory Test Button")
.right_from(state.ids.inventory_test_button, 10.0)
.font_size(14)
.font_id(self.fonts.opensans)
.graphics_for(state.ids.inventory_test_button)
.color(TEXT_COLOR)
.set(state.ids.inventory_test_button_label, ui);
// Debug // Debug
let show_debug = let show_debug = ToggleButton::new(
ToggleButton::new(self.show.debug, self.imgs.check, self.imgs.check_checked) self.show.debug,
.w_h(288.0 / 24.0, 288.0 / 24.0) self.imgs.checkbox,
.down_from(state.ids.inventory_test_button, 7.0) self.imgs.checkbox_checked,
.hover_images(self.imgs.check_checked_mo, self.imgs.check_mo) )
.press_images(self.imgs.check_press, self.imgs.check_press) .w_h(18.0, 18.0)
.set(state.ids.debug_button, ui); .down_from(state.ids.button_help, 8.0)
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
.set(state.ids.debug_button, ui);
if self.show.debug != show_debug { if self.show.debug != show_debug {
events.push(Event::ToggleDebug); events.push(Event::ToggleDebug);
} }
Text::new("Show Debug Window") Text::new("Show Debug Info")
.right_from(state.ids.debug_button, 10.0) .right_from(state.ids.debug_button, 10.0)
.font_size(14) .font_size(14)
.font_id(self.fonts.opensans) .font_id(self.fonts.opensans)
@ -331,7 +334,7 @@ impl<'a> Widget for SettingsWindow<'a> {
let (check_img, check_mo_img, check_press_img, relative_selected) = match ui_scale { let (check_img, check_mo_img, check_press_img, relative_selected) = match ui_scale {
ScaleMode::RelativeToWindow(_) => ( ScaleMode::RelativeToWindow(_) => (
self.imgs.check_checked, self.imgs.check_checked,
self.imgs.check_checked, self.imgs.check_checked_mo,
self.imgs.check_checked, self.imgs.check_checked,
true, true,
), ),
@ -366,7 +369,7 @@ impl<'a> Widget for SettingsWindow<'a> {
let (check_img, check_mo_img, check_press_img, absolute_selected) = match ui_scale { let (check_img, check_mo_img, check_press_img, absolute_selected) = match ui_scale {
ScaleMode::Absolute(_) => ( ScaleMode::Absolute(_) => (
self.imgs.check_checked, self.imgs.check_checked,
self.imgs.check_checked, self.imgs.check_checked_mo,
self.imgs.check_checked, self.imgs.check_checked,
true, true,
), ),
@ -379,7 +382,7 @@ impl<'a> Widget for SettingsWindow<'a> {
}; };
if Button::image(check_img) if Button::image(check_img)
.w_h(288.0 / 24.0, 288.0 / 24.0) .w_h(288.0 / 24.0, 288.0 / 24.0)
.down_from(state.ids.relative_to_win_button, 20.0) .down_from(state.ids.relative_to_win_button, 8.0)
.hover_image(check_mo_img) .hover_image(check_mo_img)
.press_image(check_press_img) .press_image(check_press_img)
.set(state.ids.absolute_scale_button, ui) .set(state.ids.absolute_scale_button, ui)
@ -415,13 +418,15 @@ impl<'a> Widget for SettingsWindow<'a> {
{ {
events.push(Event::UiScale(ScaleChange::Adjust(2.0f64.powf(new_val)))); events.push(Event::UiScale(ScaleChange::Adjust(2.0f64.powf(new_val))));
} }
// Custom Scaling Text
Text::new(&format!("{:.2}", scale)) Text::new(&format!("{:.2}", scale))
.up_from(state.ids.ch_transp_value, 75.0) .right_from(state.ids.ui_scale_slider, 10.0)
.font_size(14) .font_size(14)
.font_id(self.fonts.opensans) .font_id(self.fonts.opensans)
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.ui_scale_value, ui); .set(state.ids.ui_scale_value, ui);
} else { } else {
// Grey and unfunctional slider when Relative is selected
ImageSlider::continuous(0.0, 0.0, 1.0, self.imgs.nothing, self.imgs.slider) ImageSlider::continuous(0.0, 0.0, 1.0, self.imgs.nothing, self.imgs.slider)
.w_h(208.0, 22.0) .w_h(208.0, 22.0)
.right_from(state.ids.absolute_scale_text, 10.0) .right_from(state.ids.absolute_scale_text, 10.0)
@ -434,43 +439,6 @@ impl<'a> Widget for SettingsWindow<'a> {
} }
// Crosshair Options // Crosshair Options
// Crosshair Transparency
Text::new("Crosshair")
.down_from(state.ids.absolute_scale_button, 20.0)
.font_size(18)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.ch_title, ui);
if let Some(new_val) = ImageSlider::continuous(
crosshair_transp,
0.0,
1.0,
self.imgs.slider_indicator,
self.imgs.slider,
)
.w_h(104.0, 22.0)
.down_from(state.ids.ch_transp_text, 8.0)
.track_breadth(12.0)
.slider_length(10.0)
.pad_track((5.0, 5.0))
.set(state.ids.ch_transp_slider, ui)
{
events.push(Event::CrosshairTransp(new_val));
}
Text::new(&format!("{:.2}", crosshair_transp,))
.right_from(state.ids.ch_transp_slider, 8.0)
.font_size(14)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.ch_transp_value, ui);
Text::new("Transparency")
.right_from(state.ids.ch_3_bg, 20.0)
.font_size(14)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.ch_transp_text, ui);
// Crosshair Types // Crosshair Types
// Round // Round
if Button::image(if let CrosshairType::Round = crosshair_type { if Button::image(if let CrosshairType::Round = crosshair_type {
@ -600,6 +568,252 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.6))) .color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.6)))
.graphics_for(state.ids.ch_3_bg) .graphics_for(state.ids.ch_3_bg)
.set(state.ids.crosshair_inner_3, ui); .set(state.ids.crosshair_inner_3, ui);
// Crosshair Transparency Text and Slider
Text::new("Crosshair")
.down_from(state.ids.absolute_scale_button, 20.0)
.font_size(18)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.ch_title, ui);
Text::new("Transparency")
.right_from(state.ids.ch_3_bg, 20.0)
.font_size(14)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.ch_transp_text, ui);
if let Some(new_val) = ImageSlider::continuous(
crosshair_transp,
0.0,
1.0,
self.imgs.slider_indicator,
self.imgs.slider,
)
.w_h(104.0, 22.0)
.down_from(state.ids.ch_transp_text, 8.0)
.track_breadth(12.0)
.slider_length(10.0)
.pad_track((5.0, 5.0))
.set(state.ids.ch_transp_slider, ui)
{
events.push(Event::CrosshairTransp(new_val));
}
Text::new(&format!("{:.2}", crosshair_transp,))
.right_from(state.ids.ch_transp_slider, 8.0)
.font_size(14)
.graphics_for(state.ids.ch_transp_slider)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.ch_transp_value, ui);
// Hotbar text
Text::new("Hotbar")
.down_from(state.ids.ch_1_bg, 20.0)
.font_size(18)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.hotbar_title, ui);
// Show xp bar
if Button::image(match self.global_state.settings.gameplay.xp_bar {
XpBar::Always => self.imgs.checkbox_checked,
XpBar::OnGain => self.imgs.checkbox,
})
.w_h(18.0, 18.0)
.hover_image(match self.global_state.settings.gameplay.xp_bar {
XpBar::Always => self.imgs.checkbox_checked_mo,
XpBar::OnGain => self.imgs.checkbox_mo,
})
.press_image(match self.global_state.settings.gameplay.xp_bar {
XpBar::Always => self.imgs.checkbox_checked,
XpBar::OnGain => self.imgs.checkbox_press,
})
.down_from(state.ids.hotbar_title, 8.0)
.set(state.ids.show_xpbar_button, ui)
.was_clicked()
{
match self.global_state.settings.gameplay.xp_bar {
XpBar::Always => events.push(Event::ToggleXpBar(XpBar::OnGain)),
XpBar::OnGain => events.push(Event::ToggleXpBar(XpBar::Always)),
}
}
Text::new("Always show Experience Bar")
.right_from(state.ids.show_xpbar_button, 10.0)
.font_size(14)
.font_id(self.fonts.opensans)
.graphics_for(state.ids.show_xpbar_button)
.color(TEXT_COLOR)
.set(state.ids.show_xpbar_text, ui);
// Show Health & Energy Bars
if Button::image(match self.global_state.settings.gameplay.en_bars {
EnBars::Always => self.imgs.checkbox_checked,
EnBars::OnLoss => self.imgs.checkbox,
})
.w_h(18.0, 18.0)
.hover_image(match self.global_state.settings.gameplay.en_bars {
EnBars::Always => self.imgs.checkbox_checked_mo,
EnBars::OnLoss => self.imgs.checkbox_mo,
})
.press_image(match self.global_state.settings.gameplay.en_bars {
EnBars::Always => self.imgs.checkbox_checked,
EnBars::OnLoss => self.imgs.checkbox_press,
})
.down_from(state.ids.show_xpbar_button, 8.0)
.set(state.ids.show_bars_button, ui)
.was_clicked()
{
match self.global_state.settings.gameplay.en_bars {
EnBars::Always => events.push(Event::ToggleEnBars(EnBars::OnLoss)),
EnBars::OnLoss => events.push(Event::ToggleEnBars(EnBars::Always)),
}
}
Text::new("Always show Health and Energy Bars")
.right_from(state.ids.show_bars_button, 10.0)
.font_size(14)
.font_id(self.fonts.opensans)
.graphics_for(state.ids.show_bars_button)
.color(TEXT_COLOR)
.set(state.ids.show_bars_text, ui);
// Show Shortcut Numbers
if Button::image(match self.global_state.settings.gameplay.shortcut_numbers {
ShortcutNumbers::On => self.imgs.checkbox_checked,
ShortcutNumbers::Off => self.imgs.checkbox,
})
.w_h(18.0, 18.0)
.hover_image(match self.global_state.settings.gameplay.shortcut_numbers {
ShortcutNumbers::On => self.imgs.checkbox_checked_mo,
ShortcutNumbers::Off => self.imgs.checkbox_mo,
})
.press_image(match self.global_state.settings.gameplay.shortcut_numbers {
ShortcutNumbers::On => self.imgs.checkbox_checked,
ShortcutNumbers::Off => self.imgs.checkbox_press,
})
.down_from(state.ids.show_bars_button, 8.0)
.set(state.ids.show_shortcuts_button, ui)
.was_clicked()
{
match self.global_state.settings.gameplay.shortcut_numbers {
ShortcutNumbers::On => {
events.push(Event::ToggleShortcutNumbers(ShortcutNumbers::Off))
}
ShortcutNumbers::Off => {
events.push(Event::ToggleShortcutNumbers(ShortcutNumbers::On))
}
}
}
Text::new("Always show Shortcuts")
.right_from(state.ids.show_shortcuts_button, 10.0)
.font_size(14)
.font_id(self.fonts.opensans)
.graphics_for(state.ids.show_shortcuts_button)
.color(TEXT_COLOR)
.set(state.ids.show_shortcuts_text, ui);
// Energybars Numbers
// Hotbar text
Text::new("Energybar Numbers")
.down_from(state.ids.show_shortcuts_button, 20.0)
.font_size(18)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(state.ids.bar_numbers_title, ui);
// None
if Button::image(if let BarNumbers::Off = bar_values {
self.imgs.check_checked
} else {
self.imgs.check
})
.w_h(288.0 / 24.0, 288.0 / 24.0)
.hover_image(if let BarNumbers::Off = bar_values {
self.imgs.check_checked_mo
} else {
self.imgs.check_mo
})
.press_image(if let BarNumbers::Off = bar_values {
self.imgs.check_checked
} else {
self.imgs.check_press
})
.down_from(state.ids.bar_numbers_title, 8.0)
.set(state.ids.show_bar_numbers_none_button, ui)
.was_clicked()
{
events.push(Event::ToggleBarNumbers(BarNumbers::Off))
}
Text::new("None")
.right_from(state.ids.show_bar_numbers_none_button, 10.0)
.font_size(14)
.font_id(self.fonts.opensans)
.graphics_for(state.ids.show_bar_numbers_none_button)
.color(TEXT_COLOR)
.set(state.ids.show_bar_numbers_none_text, ui);
// Values
if Button::image(if let BarNumbers::Values = bar_values {
self.imgs.check_checked
} else {
self.imgs.check
})
.w_h(288.0 / 24.0, 288.0 / 24.0)
.hover_image(if let BarNumbers::Values = bar_values {
self.imgs.check_checked_mo
} else {
self.imgs.check_mo
})
.press_image(if let BarNumbers::Values = bar_values {
self.imgs.check_checked
} else {
self.imgs.check_press
})
.down_from(state.ids.show_bar_numbers_none_button, 8.0)
.set(state.ids.show_bar_numbers_values_button, ui)
.was_clicked()
{
events.push(Event::ToggleBarNumbers(BarNumbers::Values))
}
Text::new("Values")
.right_from(state.ids.show_bar_numbers_values_button, 10.0)
.font_size(14)
.font_id(self.fonts.opensans)
.graphics_for(state.ids.show_bar_numbers_values_button)
.color(TEXT_COLOR)
.set(state.ids.show_bar_numbers_values_text, ui);
// Percentages
if Button::image(if let BarNumbers::Percent = bar_values {
self.imgs.check_checked
} else {
self.imgs.check
})
.w_h(288.0 / 24.0, 288.0 / 24.0)
.hover_image(if let BarNumbers::Percent = bar_values {
self.imgs.check_checked_mo
} else {
self.imgs.check_mo
})
.press_image(if let BarNumbers::Percent = bar_values {
self.imgs.check_checked
} else {
self.imgs.check_press
})
.down_from(state.ids.show_bar_numbers_values_button, 8.0)
.set(state.ids.show_bar_numbers_percentage_button, ui)
.was_clicked()
{
events.push(Event::ToggleBarNumbers(BarNumbers::Percent))
}
Text::new("Percentages")
.right_from(state.ids.show_bar_numbers_percentage_button, 10.0)
.font_size(14)
.font_id(self.fonts.opensans)
.graphics_for(state.ids.show_bar_numbers_percentage_button)
.color(TEXT_COLOR)
.set(state.ids.show_bar_numbers_percentage_text, ui);
Rectangle::fill_with([20.0 * 4.0, 1.0 * 4.0], color::TRANSPARENT)
.down_from(state.ids.show_bar_numbers_percentage_button, 8.0)
.set(state.ids.placeholder, ui);
} }
// 2) Gameplay Tab -------------------------------- // 2) Gameplay Tab --------------------------------

View File

@ -1,48 +1,113 @@
use super::{img_ids::Imgs, Fonts, HP_COLOR, MANA_COLOR, TEXT_COLOR, XP_COLOR}; use super::{
img_ids::Imgs, BarNumbers, EnBars, Fonts, ShortcutNumbers, XpBar, CRITICAL_HP_COLOR,
/*FOCUS_COLOR, RAGE_COLOR,*/ HP_COLOR, LOW_HP_COLOR, MANA_COLOR, TEXT_COLOR, XP_COLOR,
};
use crate::GlobalState;
use common::comp::Stats; use common::comp::Stats;
use conrod_core::{ use conrod_core::{
widget::{self, Image, Rectangle, Text}, color,
widget_ids, Colorable, Positionable, Sizeable, Widget, WidgetCommon, widget::{self, Button, Image, Rectangle, Text},
widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon,
}; };
use std::time::{Duration, Instant};
widget_ids! { widget_ids! {
struct Ids { struct Ids {
health_bar, death_message_1,
health_bar_color, death_message_2,
health_tooltip,
l_click,
level_text, level_text,
mana_bar,
mana_bar_color,
next_level_text, next_level_text,
r_click, xp_bar_mid,
sb_grid_bg_l, xp_bar_mid_top,
sb_grid_bg_r, xp_bar_left,
sb_grid_l, xp_bar_left_top,
sb_grid_r, xp_bar_right,
test, xp_bar_right_top,
xp_bar, xp_bar_filling,
xp_bar_progress, xp_bar_filling_top,
crosshair, hotbar_align,
xp_bar_subdivision,
m1_slot,
m1_slot_bg,
m1_text,
m1_content,
m2_slot,
m2_slot_bg,
m2_text,
m2_content,
slot1,
slot1_bg,
slot1_text,
slot2,
slot2_bg,
slot2_text,
slot3,
slot3_bg,
slot3_text,
slot4,
slot4_bg,
slot4_text,
slot5,
slot5_bg,
slot5_text,
slot6,
slot6_bg,
slot6_text,
slot7,
slot7_bg,
slot7_text,
slot8,
slot8_bg,
slot8_text,
slot9,
slot9_bg,
slot9_text,
slotq,
slotq_bg,
slotq_text,
healthbar_bg,
healthbar_filling,
health_text,
energybar_bg,
energybar_filling,
energy_text,
level_up,
level_down,
level_align,
level_message,
} }
} }
pub enum ResourceType {
Mana,
//Rage,
//Focus,
}
#[derive(WidgetCommon)] #[derive(WidgetCommon)]
pub struct Skillbar<'a> { pub struct Skillbar<'a> {
global_state: &'a GlobalState,
imgs: &'a Imgs, imgs: &'a Imgs,
_fonts: &'a Fonts, _fonts: &'a Fonts,
stats: &'a Stats, stats: &'a Stats,
#[conrod(common_builder)] #[conrod(common_builder)]
common: widget::CommonBuilder, common: widget::CommonBuilder,
current_resource: ResourceType,
} }
impl<'a> Skillbar<'a> { impl<'a> Skillbar<'a> {
pub fn new(imgs: &'a Imgs, fonts: &'a Fonts, stats: &'a Stats) -> Self { pub fn new(
global_state: &'a GlobalState,
imgs: &'a Imgs,
fonts: &'a Fonts,
stats: &'a Stats,
) -> Self {
Self { Self {
imgs, imgs,
_fonts: fonts, _fonts: fonts,
stats, stats,
global_state,
current_resource: ResourceType::Mana,
common: widget::CommonBuilder::default(), common: widget::CommonBuilder::default(),
} }
} }
@ -50,18 +115,26 @@ impl<'a> Skillbar<'a> {
pub struct State { pub struct State {
ids: Ids, ids: Ids,
}
pub enum Event {} last_xp_value: f64,
last_level: u32,
last_update_xp: Instant,
last_update_level: Instant,
}
impl<'a> Widget for Skillbar<'a> { impl<'a> Widget for Skillbar<'a> {
type State = State; type State = State;
type Style = (); type Style = ();
type Event = Option<Event>; type Event = ();
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State { fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
State { State {
ids: Ids::new(id_gen), ids: Ids::new(id_gen),
last_xp_value: 0.0,
last_level: 1,
last_update_xp: Instant::now(),
last_update_level: Instant::now(),
} }
} }
@ -77,107 +150,554 @@ impl<'a> Widget for Skillbar<'a> {
let exp_percentage = self.stats.exp.current() / self.stats.exp.maximum(); let exp_percentage = self.stats.exp.current() / self.stats.exp.maximum();
let hp_percentage = self.stats.health.current() as f64 / self.stats.health.maximum() as f64; let hp_percentage =
let mana_percentage = 1.0; self.stats.health.current() as f64 / self.stats.health.maximum() as f64 * 100.0;
let energy_percentage =
self.stats.energy.current() as f64 / self.stats.energy.maximum() as f64 * 100.0;
// TODO: Only show while aiming with a bow or when casting a spell. let scale = 2.0;
// Crosshair
// Image::new(self.imgs.crosshair)
// .w_h(101.0 * 0.5, 101.0 * 0.5)
// .mid_top_with_margin_on(ui.window, 500.0)
// .set(state.ids.crosshair, ui);
let bar_values = self.global_state.settings.gameplay.bar_numbers;
let shortcuts = self.global_state.settings.gameplay.shortcut_numbers;
const BG_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 0.8);
// Level Up Message
let current_level = self.stats.level.level();
const FADE_IN_LVL: f32 = 1.0;
const FADE_HOLD_LVL: f32 = 3.0;
const FADE_OUT_LVL: f32 = 2.0;
// Fade
// Check if no other popup is displayed and a new one is needed
if state.last_update_level.elapsed()
> Duration::from_secs_f32(FADE_IN_LVL + FADE_HOLD_LVL + FADE_OUT_LVL)
&& state.last_level != current_level
{
// Update last_value
state.update(|s| s.last_level = current_level);
state.update(|s| s.last_update_level = Instant::now());
}
let seconds_level = state.last_update_level.elapsed().as_secs_f32();
let fade_level = if current_level == 1 {
0.0
} else if seconds_level < FADE_IN_LVL {
seconds_level / FADE_IN_LVL
} else if seconds_level < FADE_IN_LVL + FADE_HOLD_LVL {
1.0
} else {
(1.0 - (seconds_level - FADE_IN_LVL - FADE_HOLD_LVL) / FADE_OUT_LVL).max(0.0)
};
// Contents
Rectangle::fill_with([82.0 * 4.0, 40.0 * 4.0], color::TRANSPARENT)
.mid_top_with_margin_on(ui.window, 300.0)
.set(state.ids.level_align, ui);
let level_up_text = format!("Level {}", self.stats.level.level() as u32);
Text::new(&level_up_text)
.middle_of(state.ids.level_align)
.font_size(30)
.color(Color::Rgba(1.0, 1.0, 1.0, fade_level))
.set(state.ids.level_message, ui);
Image::new(self.imgs.level_up)
.w_h(82.0 * 4.0, 9.0 * 4.0)
.mid_top_with_margin_on(state.ids.level_align, 0.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_level)))
.graphics_for(state.ids.level_align)
.set(state.ids.level_up, ui);
Image::new(self.imgs.level_down)
.w_h(82.0 * 4.0, 9.0 * 4.0)
.mid_bottom_with_margin_on(state.ids.level_align, 0.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_level)))
.graphics_for(state.ids.level_align)
.set(state.ids.level_down, ui);
// Death message
if hp_percentage == 0.0 {
Text::new("You Died")
.mid_top_with_margin_on(ui.window, 60.0)
.font_size(40)
.color(CRITICAL_HP_COLOR)
.set(state.ids.death_message_1, ui);
Text::new("Press L-Mouse to respawn.")
.mid_bottom_with_margin_on(state.ids.death_message_1, -30.0)
.font_size(15)
.color(CRITICAL_HP_COLOR)
.set(state.ids.death_message_2, ui);
}
// Experience-Bar // Experience-Bar
Image::new(self.imgs.xp_bar) match self.global_state.settings.gameplay.xp_bar {
.w_h(672.0 / 1.5, 29.0 / 1.5) XpBar::Always => {
.mid_bottom_of(ui.window) // Constant Display of the Exp Bar at the bottom of the screen
.set(state.ids.xp_bar, ui); Image::new(self.imgs.xp_bar_mid)
.w_h(80.0 * scale, 10.0 * scale)
.mid_bottom_with_margin_on(ui.window, 2.0)
.set(state.ids.xp_bar_mid, ui);
Image::new(self.imgs.xp_bar_right)
.w_h(100.0 * scale, 10.0 * scale)
.right_from(state.ids.xp_bar_mid, 0.0)
.set(state.ids.xp_bar_right, ui);
Image::new(self.imgs.xp_bar_left)
.w_h(100.0 * scale, 10.0 * scale)
.left_from(state.ids.xp_bar_mid, 0.0)
.set(state.ids.xp_bar_left, ui);
Image::new(self.imgs.bar_content)
.w_h(260.0 * scale * exp_percentage, 5.0 * scale)
.color(Some(XP_COLOR))
.top_left_with_margins_on(state.ids.xp_bar_left, 2.0 * scale, 10.0 * scale)
.set(state.ids.xp_bar_filling, ui);
// Level Display
Text::new(&level)
.bottom_left_with_margins_on(state.ids.xp_bar_left, 3.5 * scale, 4.0 * scale)
.font_size(10)
.color(Color::Rgba(1.0, 1.0, 1.0, 1.0))
.set(state.ids.level_text, ui);
Text::new(&next_level)
.bottom_right_with_margins_on(state.ids.xp_bar_right, 3.5 * scale, 4.0 * scale)
.font_size(10)
.color(Color::Rgba(1.0, 1.0, 1.0, 1.0))
.set(state.ids.next_level_text, ui);
// M1 Slot
Image::new(self.imgs.skillbar_slot_big)
.w_h(40.0 * scale, 40.0 * scale)
.top_left_with_margins_on(state.ids.xp_bar_mid, -40.0 * scale, 0.0)
.set(state.ids.m1_slot, ui);
}
XpBar::OnGain => {
// Displays the Exp Bar at the top of the screen when exp is gained and fades it out afterwards
const FADE_IN_XP: f32 = 1.0;
const FADE_HOLD_XP: f32 = 3.0;
const FADE_OUT_XP: f32 = 2.0;
let current_xp = self.stats.exp.current();
// Check if no other popup is displayed and a new one is needed
if state.last_update_xp.elapsed()
> Duration::from_secs_f32(FADE_IN_XP + FADE_HOLD_XP + FADE_OUT_XP)
&& state.last_xp_value != current_xp
{
// Update last_value
state.update(|s| s.last_xp_value = current_xp);
state.update(|s| s.last_update_xp = Instant::now());
}
Rectangle::fill_with([406.0 * (exp_percentage), 5.0], XP_COLOR) // "W=406*[Exp. %]" let seconds_xp = state.last_update_xp.elapsed().as_secs_f32();
.top_left_with_margins_on(state.ids.xp_bar, 5.0, 21.0) let fade_xp = if current_xp == 0.0 {
.set(state.ids.xp_bar_progress, ui); 0.0
} else if seconds_xp < FADE_IN_XP {
seconds_xp / FADE_IN_XP
} else if seconds_xp < FADE_IN_XP + FADE_HOLD_XP {
1.0
} else {
(1.0 - (seconds_xp - FADE_IN_XP - FADE_HOLD_XP) / FADE_OUT_XP).max(0.0)
};
// Hotbar parts
Image::new(self.imgs.xp_bar_mid)
.w_h(80.0 * scale * 1.5, 10.0 * scale * 1.5)
.mid_top_with_margin_on(ui.window, 20.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_xp)))
.set(state.ids.xp_bar_mid_top, ui);
Image::new(self.imgs.xp_bar_right)
.w_h(100.0 * scale * 1.5, 10.0 * scale * 1.5)
.right_from(state.ids.xp_bar_mid_top, 0.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_xp)))
.set(state.ids.xp_bar_right_top, ui);
Image::new(self.imgs.xp_bar_left)
.w_h(100.0 * scale * 1.5, 10.0 * scale * 1.5)
.left_from(state.ids.xp_bar_mid_top, 0.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_xp)))
.set(state.ids.xp_bar_left_top, ui);
Image::new(self.imgs.bar_content)
.w_h(260.0 * scale * 1.5 * exp_percentage, 6.0 * scale * 1.5)
.color(Some(Color::Rgba(0.59, 0.41, 0.67, fade_xp)))
.top_left_with_margins_on(
state.ids.xp_bar_left_top,
2.0 * scale * 1.5,
10.0 * scale * 1.5,
)
.set(state.ids.xp_bar_filling_top, ui);
// Level Display
Text::new(&level)
.bottom_left_with_margins_on(
state.ids.xp_bar_left_top,
3.0 * scale * 1.5,
4.0 * scale * 1.5,
)
.font_size(17)
.color(Color::Rgba(1.0, 1.0, 1.0, fade_xp))
.set(state.ids.level_text, ui);
Text::new(&next_level)
.bottom_right_with_margins_on(
state.ids.xp_bar_right_top,
3.0 * scale * 1.5,
4.0 * scale * 1.5,
)
.font_size(17)
.color(Color::Rgba(1.0, 1.0, 1.0, fade_xp))
.set(state.ids.next_level_text, ui);
// Alignment for hotbar
Rectangle::fill_with([80.0 * scale, 1.0], color::TRANSPARENT)
.mid_bottom_with_margin_on(ui.window, 9.0)
.set(state.ids.hotbar_align, ui);
// M1 Slot
Image::new(self.imgs.skillbar_slot_big)
.w_h(40.0 * scale, 40.0 * scale)
.top_left_with_margins_on(state.ids.hotbar_align, -40.0 * scale, 0.0)
.set(state.ids.m1_slot, ui);
}
}
// M1 Slot
Image::new(self.imgs.skillbar_slot_big_bg)
.w_h(37.0 * scale, 37.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.m1_slot)
.set(state.ids.m1_slot_bg, ui);
Button::image(self.imgs.twohhammer_m1) // Insert Icon here
.w_h(38.0 * scale, 38.0 * scale)
.middle_of(state.ids.m1_slot_bg)
.set(state.ids.m1_content, ui);
// M2 Slot
Image::new(self.imgs.skillbar_slot_big)
.w_h(40.0 * scale, 40.0 * scale)
.right_from(state.ids.m1_slot, 0.0)
.set(state.ids.m2_slot, ui);
Image::new(self.imgs.skillbar_slot_big_bg)
.w_h(37.0 * scale, 37.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.m2_slot)
.set(state.ids.m2_slot_bg, ui);
Button::image(self.imgs.twohhammer_m2) // Insert Icon here
.w_h(38.0 * scale, 38.0 * scale)
.middle_of(state.ids.m2_slot_bg)
.set(state.ids.m2_content, ui);
//Slot 5
Image::new(self.imgs.skillbar_slot)
.w_h(20.0 * scale, 20.0 * scale)
.bottom_left_with_margins_on(state.ids.m1_slot, 0.0, -20.0 * scale)
.set(state.ids.slot5, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot5)
.set(state.ids.slot5_bg, ui);
// Slot 4
Image::new(self.imgs.skillbar_slot)
.w_h(20.0 * scale, 20.0 * scale)
.left_from(state.ids.slot5, 0.0)
.set(state.ids.slot4, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot4)
.set(state.ids.slot4_bg, ui);
// Slot 3
Image::new(self.imgs.skillbar_slot)
.w_h(20.0 * scale, 20.0 * scale)
.left_from(state.ids.slot4, 0.0)
.set(state.ids.slot3, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot3)
.set(state.ids.slot3_bg, ui);
// Slot 2
Image::new(self.imgs.skillbar_slot)
.w_h(20.0 * scale, 20.0 * scale)
.left_from(state.ids.slot3, 0.0)
.set(state.ids.slot2, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot2)
.set(state.ids.slot2_bg, ui);
// Slot 1
Image::new(self.imgs.skillbar_slot_l)
.w_h(20.0 * scale, 20.0 * scale)
.left_from(state.ids.slot2, 0.0)
.set(state.ids.slot1, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot1)
.set(state.ids.slot1_bg, ui);
// Slot 6
Image::new(self.imgs.skillbar_slot)
.w_h(20.0 * scale, 20.0 * scale)
.bottom_right_with_margins_on(state.ids.m2_slot, 0.0, -20.0 * scale)
.set(state.ids.slot6, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot6)
.set(state.ids.slot6_bg, ui);
// Slot 7
Image::new(self.imgs.skillbar_slot)
.w_h(20.0 * scale, 20.0 * scale)
.right_from(state.ids.slot6, 0.0)
.set(state.ids.slot7, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot7)
.set(state.ids.slot7_bg, ui);
// Slot 8
Image::new(self.imgs.skillbar_slot)
.w_h(20.0 * scale, 20.0 * scale)
.right_from(state.ids.slot7, 0.0)
.set(state.ids.slot8, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot8)
.set(state.ids.slot8_bg, ui);
// Slot 9
Image::new(self.imgs.skillbar_slot)
.w_h(20.0 * scale, 20.0 * scale)
.right_from(state.ids.slot8, 0.0)
.set(state.ids.slot9, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slot9)
.set(state.ids.slot9_bg, ui);
// Quickslot
Image::new(self.imgs.skillbar_slot_r)
.w_h(20.0 * scale, 20.0 * scale)
.right_from(state.ids.slot9, 0.0)
.set(state.ids.slotq, ui);
Image::new(self.imgs.skillbar_slot_bg)
.w_h(19.0 * scale, 19.0 * scale)
.color(Some(BG_COLOR))
.middle_of(state.ids.slotq)
.set(state.ids.slotq_bg, ui);
// Shortcuts
// Left Grid if let ShortcutNumbers::On = shortcuts {
Image::new(self.imgs.sb_grid) Text::new("1")
.w_h(280.0 / 1.5, 56.0 / 1.5) .top_right_with_margins_on(state.ids.slot1_bg, 1.0, 1.0)
.up_from(state.ids.xp_bar, 0.0) .font_size(8)
.align_left_of(state.ids.xp_bar) .color(TEXT_COLOR)
.set(state.ids.sb_grid_l, ui); .set(state.ids.slot1_text, ui);
Text::new("2")
.top_right_with_margins_on(state.ids.slot2_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slot2_text, ui);
Text::new("3")
.top_right_with_margins_on(state.ids.slot3_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slot3_text, ui);
Text::new("4")
.top_right_with_margins_on(state.ids.slot4_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slot4_text, ui);
Text::new("5")
.top_right_with_margins_on(state.ids.slot5_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slot5_text, ui);
Text::new("M1")
.top_left_with_margins_on(state.ids.m1_slot, 5.0, 5.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.m1_text, ui);
Text::new("M2")
.top_right_with_margins_on(state.ids.m2_slot, 5.0, 5.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.m2_text, ui);
Text::new("6")
.top_left_with_margins_on(state.ids.slot6_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slot6_text, ui);
Text::new("7")
.top_left_with_margins_on(state.ids.slot7_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slot7_text, ui);
Text::new("8")
.top_left_with_margins_on(state.ids.slot8_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slot8_text, ui);
Text::new("9")
.top_left_with_margins_on(state.ids.slot9_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slot9_text, ui);
Text::new("Q")
.top_left_with_margins_on(state.ids.slotq_bg, 1.0, 1.0)
.font_size(8)
.color(TEXT_COLOR)
.set(state.ids.slotq_text, ui);
};
Image::new(self.imgs.sb_grid_bg) // Option to show Energy Bars only on loss or Always
.w_h(280.0 / 1.5, 56.0 / 1.5) match self.global_state.settings.gameplay.en_bars {
.middle_of(state.ids.sb_grid_l) EnBars::OnLoss => {
.set(state.ids.sb_grid_bg_l, ui); if { self.stats.health.current() < self.stats.health.maximum() } || {
self.stats.energy.current() < self.stats.energy.maximum()
// Right Grid } {
Image::new(self.imgs.sb_grid) // Lifebar
.w_h(280.0 / 1.5, 56.0 / 1.5) Image::new(self.imgs.healthbar_bg)
.up_from(state.ids.xp_bar, 0.0) .w_h(100.0 * scale, 20.0 * scale)
.align_right_of(state.ids.xp_bar) .top_left_with_margins_on(state.ids.m1_slot, 0.0, -100.0 * scale)
.set(state.ids.sb_grid_r, ui); .set(state.ids.healthbar_bg, ui);
Image::new(self.imgs.bar_content)
Image::new(self.imgs.sb_grid_bg) .w_h(97.0 * scale * hp_percentage / 100.0, 16.0 * scale)
.w_h(280.0 / 1.5, 56.0 / 1.5) .color(Some(if hp_percentage <= 20.0 {
.middle_of(state.ids.sb_grid_r) CRITICAL_HP_COLOR
.set(state.ids.sb_grid_bg_r, ui); } else if hp_percentage <= 40.0 {
LOW_HP_COLOR
// Right and Left Click } else {
Image::new(self.imgs.l_click) HP_COLOR
.w_h(56.0 / 1.5, 80.0 / 1.5) }))
.right_from(state.ids.sb_grid_bg_l, 0.0) .top_right_with_margins_on(state.ids.healthbar_bg, 2.0 * scale, 1.0 * scale)
.align_bottom_of(state.ids.sb_grid_bg_l) .set(state.ids.healthbar_filling, ui);
.set(state.ids.l_click, ui); // Energybar
Image::new(self.imgs.energybar_bg)
Image::new(self.imgs.r_click) .w_h(100.0 * scale, 20.0 * scale)
.w_h(56.0 / 1.5, 80.0 / 1.5) .top_right_with_margins_on(state.ids.m2_slot, 0.0, -100.0 * scale)
.left_from(state.ids.sb_grid_bg_r, 0.0) .set(state.ids.energybar_bg, ui);
.align_bottom_of(state.ids.sb_grid_bg_r) Image::new(self.imgs.bar_content)
.set(state.ids.r_click, ui); .w_h(97.0 * scale * energy_percentage / 100.0, 16.0 * scale)
.top_left_with_margins_on(state.ids.energybar_bg, 2.0 * scale, 1.0 * scale)
// Health Bar .color(Some(match self.current_resource {
Image::new(self.imgs.health_bar) ResourceType::Mana => MANA_COLOR,
.w_h(1120.0 / 6.0, 96.0 / 6.0) //ResourceType::Focus => FOCUS_COLOR,
.left_from(state.ids.l_click, 0.0) //ResourceType::Rage => RAGE_COLOR,
.align_top_of(state.ids.l_click) }))
.set(state.ids.health_bar, ui); .set(state.ids.energybar_filling, ui);
// Bar Text
// Filling // Values
Rectangle::fill_with([182.0 * hp_percentage, 6.0], HP_COLOR) // "W=182.0 * [Health. %]" if let BarNumbers::Values = bar_values {
.top_right_with_margins_on(state.ids.health_bar, 5.0, 0.0) let hp_text = format!(
.set(state.ids.health_bar_color, ui); "{}/{}",
self.stats.health.current() as u32,
// Mana Bar self.stats.health.maximum() as u32
Image::new(self.imgs.mana_bar) );
.w_h(1120.0 / 6.0, 96.0 / 6.0) Text::new(&hp_text)
.right_from(state.ids.r_click, 0.0) .mid_top_with_margin_on(state.ids.healthbar_bg, 5.0 * scale)
.align_top_of(state.ids.r_click) .font_size(14)
.set(state.ids.mana_bar, ui); .color(TEXT_COLOR)
.set(state.ids.health_text, ui);
// Filling let energy_text = format!(
Rectangle::fill_with([182.0 * mana_percentage, 6.0], MANA_COLOR) // "W=182.0 * [Mana. %]" "{}/{}",
.top_left_with_margins_on(state.ids.mana_bar, 5.0, 0.0) self.stats.energy.current() as u32,
.set(state.ids.mana_bar_color, ui); self.stats.energy.maximum() as u32
);
// Buffs/Debuffs Text::new(&energy_text)
.mid_top_with_margin_on(state.ids.energybar_bg, 5.0 * scale)
.font_size(14)
.color(TEXT_COLOR)
.set(state.ids.energy_text, ui);
}
//Percentages
if let BarNumbers::Percent = bar_values {
let hp_text = format!("{}%", hp_percentage as u32);
Text::new(&hp_text)
.mid_top_with_margin_on(state.ids.healthbar_bg, 5.0 * scale)
.font_size(14)
.color(TEXT_COLOR)
.set(state.ids.health_text, ui);
let energy_text = format!("{}%", energy_percentage as u32);
Text::new(&energy_text)
.mid_top_with_margin_on(state.ids.energybar_bg, 5.0 * scale)
.font_size(14)
.color(TEXT_COLOR)
.set(state.ids.energy_text, ui);
}
} else {
// Lifebar
Image::new(self.imgs.healthbar_bg)
.w_h(100.0 * scale, 20.0 * scale)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.8)))
.top_left_with_margins_on(state.ids.m1_slot, 0.0, -100.0 * scale)
.set(state.ids.healthbar_bg, ui);
// Energybar
Image::new(self.imgs.energybar_bg)
.w_h(100.0 * scale, 20.0 * scale)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.8)))
.top_right_with_margins_on(state.ids.m2_slot, 0.0, -100.0 * scale)
.set(state.ids.energybar_bg, ui);
}
}
EnBars::Always => {
// Lifebar
Image::new(self.imgs.healthbar_bg)
.w_h(100.0 * scale, 20.0 * scale)
.top_left_with_margins_on(state.ids.m1_slot, 0.0, -100.0 * scale)
.set(state.ids.healthbar_bg, ui);
Image::new(self.imgs.bar_content)
.w_h(97.0 * scale * hp_percentage / 100.0, 16.0 * scale)
.color(Some(if hp_percentage <= 20.0 {
CRITICAL_HP_COLOR
} else if hp_percentage <= 40.0 {
LOW_HP_COLOR
} else {
HP_COLOR
}))
.top_right_with_margins_on(state.ids.healthbar_bg, 2.0 * scale, 1.0 * scale)
.set(state.ids.healthbar_filling, ui);
// Energybar
Image::new(self.imgs.energybar_bg)
.w_h(100.0 * scale, 20.0 * scale)
.top_right_with_margins_on(state.ids.m2_slot, 0.0, -100.0 * scale)
.set(state.ids.energybar_bg, ui);
Image::new(self.imgs.bar_content)
.w_h(97.0 * scale * energy_percentage / 100.0, 16.0 * scale)
.top_left_with_margins_on(state.ids.energybar_bg, 2.0 * scale, 1.0 * scale)
.color(Some(match self.current_resource {
ResourceType::Mana => MANA_COLOR,
//ResourceType::Focus => FOCUS_COLOR,
//ResourceType::Rage => RAGE_COLOR,
}))
.set(state.ids.energybar_filling, ui);
// Bar Text
// Values
if let BarNumbers::Values = bar_values {
let hp_text = format!(
"{}/{}",
self.stats.health.current() as u32,
self.stats.health.maximum() as u32
);
Text::new(&hp_text)
.mid_top_with_margin_on(state.ids.healthbar_bg, 5.0 * scale)
.font_size(14)
.color(TEXT_COLOR)
.set(state.ids.health_text, ui);
let energy_text = format!(
"{}/{}",
self.stats.energy.current() as u32,
self.stats.energy.maximum() as u32
);
Text::new(&energy_text)
.mid_top_with_margin_on(state.ids.energybar_bg, 5.0 * scale)
.font_size(14)
.color(TEXT_COLOR)
.set(state.ids.energy_text, ui);
}
//Percentages
if let BarNumbers::Percent = bar_values {
let hp_text = format!("{}%", hp_percentage as u32);
Text::new(&hp_text)
.mid_top_with_margin_on(state.ids.healthbar_bg, 5.0 * scale)
.font_size(14)
.color(TEXT_COLOR)
.set(state.ids.health_text, ui);
let energy_text = format!("{}%", energy_percentage as u32);
Text::new(&energy_text)
.mid_top_with_margin_on(state.ids.energybar_bg, 5.0 * scale)
.font_size(14)
.color(TEXT_COLOR)
.set(state.ids.energy_text, ui);
}
}
}
// Buffs // Buffs
// Add debuff slots above the health bar
// Add buff slots above the mana bar
// Debuffs // Debuffs
// Level Display
Text::new(&level)
.left_from(state.ids.xp_bar, -15.0)
.font_size(10)
.color(TEXT_COLOR)
.set(state.ids.level_text, ui);
Text::new(&next_level)
.right_from(state.ids.xp_bar, -15.0)
.font_size(10)
.color(TEXT_COLOR)
.set(state.ids.next_level_text, ui);
None
} }
} }

View File

@ -1,4 +1,4 @@
#![feature(drain_filter)] #![feature(duration_float, drain_filter)]
#![recursion_limit = "2048"] #![recursion_limit = "2048"]
#[cfg(feature = "discord")] #[cfg(feature = "discord")]

View File

@ -19,7 +19,7 @@ use common::{
}; };
use dot_vox::DotVoxData; use dot_vox::DotVoxData;
use hashbrown::HashMap; use hashbrown::HashMap;
use log::warn; use log::debug;
use specs::{Entity as EcsEntity, Join}; use specs::{Entity as EcsEntity, Join};
use std::f32; use std::f32;
use vek::*; use vek::*;
@ -913,7 +913,7 @@ impl FigureMgr {
renderer.render_figure(model, globals, locals, bone_consts, lights); renderer.render_figure(model, globals, locals, bone_consts, lights);
} else { } else {
warn!("Body has no saved figure"); debug!("Body has no saved figure");
} }
} }
} }

View File

@ -345,6 +345,22 @@ impl PlayState for SessionState {
global_state.settings.gameplay.crosshair_type = crosshair_type; global_state.settings.gameplay.crosshair_type = crosshair_type;
global_state.settings.save_to_file_warn(); global_state.settings.save_to_file_warn();
} }
HudEvent::ToggleXpBar(xp_bar) => {
global_state.settings.gameplay.xp_bar = xp_bar;
global_state.settings.save_to_file_warn();
}
HudEvent::ToggleEnBars(en_bars) => {
global_state.settings.gameplay.en_bars = en_bars;
global_state.settings.save_to_file_warn();
}
HudEvent::ToggleBarNumbers(bar_numbers) => {
global_state.settings.gameplay.bar_numbers = bar_numbers;
global_state.settings.save_to_file_warn();
}
HudEvent::ToggleShortcutNumbers(shortcut_numbers) => {
global_state.settings.gameplay.shortcut_numbers = shortcut_numbers;
global_state.settings.save_to_file_warn();
}
HudEvent::UiScale(scale_change) => { HudEvent::UiScale(scale_change) => {
global_state.settings.gameplay.ui_scale = global_state.settings.gameplay.ui_scale =
self.hud.scale_change(scale_change); self.hud.scale_change(scale_change);

View File

@ -1,4 +1,8 @@
use crate::{hud::CrosshairType, ui::ScaleMode, window::KeyMouse}; use crate::{
hud::{BarNumbers, CrosshairType, EnBars, ShortcutNumbers, XpBar},
ui::ScaleMode,
window::KeyMouse,
};
use directories::ProjectDirs; use directories::ProjectDirs;
use glutin::{MouseButton, VirtualKeyCode}; use glutin::{MouseButton, VirtualKeyCode};
use log::warn; use log::warn;
@ -80,6 +84,10 @@ pub struct GameplaySettings {
pub zoom_sensitivity: u32, pub zoom_sensitivity: u32,
pub crosshair_transp: f32, pub crosshair_transp: f32,
pub crosshair_type: CrosshairType, pub crosshair_type: CrosshairType,
pub xp_bar: XpBar,
pub en_bars: EnBars,
pub shortcut_numbers: ShortcutNumbers,
pub bar_numbers: BarNumbers,
pub ui_scale: ScaleMode, pub ui_scale: ScaleMode,
} }
@ -90,6 +98,10 @@ impl Default for GameplaySettings {
zoom_sensitivity: 100, zoom_sensitivity: 100,
crosshair_transp: 0.6, crosshair_transp: 0.6,
crosshair_type: CrosshairType::Round, crosshair_type: CrosshairType::Round,
xp_bar: XpBar::OnGain,
en_bars: EnBars::OnLoss,
shortcut_numbers: ShortcutNumbers::On,
bar_numbers: BarNumbers::Off,
ui_scale: ScaleMode::RelativeToWindow([1920.0, 1080.0].into()), ui_scale: ScaleMode::RelativeToWindow([1920.0, 1080.0].into()),
} }
} }