From 7ae8ed09f6d60c0eb19f67c05a2c3003a2cd0a62 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 14 Jan 2022 12:45:54 -0500 Subject: [PATCH] Addressed MR comments. --- CHANGELOG.md | 1 + common/base/src/lib.rs | 2 +- common/src/comp/ability.rs | 12 +-- server/src/character_creator.rs | 25 ++--- server/src/events/entity_creation.rs | 12 +-- server/src/events/mod.rs | 16 ++- server/src/lib.rs | 27 ++++- server/src/persistence/character.rs | 26 +++-- server/src/persistence/json_models.rs | 62 +++++++---- server/src/persistence/mod.rs | 21 ++-- server/src/state_ext.rs | 11 +- voxygen/src/hud/diary.rs | 145 +++++++++----------------- voxygen/src/hud/mod.rs | 4 +- voxygen/src/hud/slots.rs | 7 +- voxygen/src/hud/util.rs | 4 +- voxygen/src/ui/widgets/slot.rs | 6 +- 16 files changed, 194 insertions(+), 187 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adbb833221..63c9428937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Slashing damage now reduces target's energy by an amount equal to damage dealt to target post-mitigation - Crushing damage now does poise damage to a target equal to the amount mitigated by armor - UI to select abilities and assign to hotbar +- Position of abilities on hotbar is now persisted through the server ### Changed diff --git a/common/base/src/lib.rs b/common/base/src/lib.rs index 800869cf01..d97aa4a003 100644 --- a/common/base/src/lib.rs +++ b/common/base/src/lib.rs @@ -31,7 +31,7 @@ macro_rules! dev_panic { if cfg!(any(debug_assertions, test)) { panic!("{}", $msg); } else { - tracing::warn!("{}", $msg); + tracing::error!("{}", $msg); } }; diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 90b4669314..9b2bcc3762 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -209,7 +209,7 @@ impl ActiveAbilities { }) } - pub fn default_ability_set<'a>( + fn default_ability_set<'a>( inv: Option<&'a Inventory>, skill_set: Option<&'a SkillSet>, ) -> [AuxiliaryAbility; MAX_ABILITIES] { @@ -220,15 +220,7 @@ impl ActiveAbilities { .map(AuxiliaryAbility::OffWeapon), ); - let mut array = [AuxiliaryAbility::Empty; MAX_ABILITIES]; - - for ability in array.iter_mut() { - if let Some(available_ability) = iter.next() { - *ability = available_ability; - } - } - - array + [(); MAX_ABILITIES].map(|()| iter.next().unwrap_or(AuxiliaryAbility::Empty)) } } diff --git a/server/src/character_creator.rs b/server/src/character_creator.rs index 84b9833c99..a93c7a3ea2 100644 --- a/server/src/character_creator.rs +++ b/server/src/character_creator.rs @@ -1,4 +1,4 @@ -use crate::persistence::character_updater::CharacterUpdater; +use crate::persistence::{character_updater::CharacterUpdater, PersistedComponents}; use common::{ character::CharacterId, comp::{inventory::loadout_builder::LoadoutBuilder, Body, Inventory, Item, SkillSet, Stats}, @@ -65,20 +65,15 @@ pub fn create_character( let waypoint = None; - character_updater.create_character( - entity, - player_uuid, - character_alias, - ( - body, - stats, - skill_set, - inventory, - waypoint, - Vec::new(), - Default::default(), - ), - ); + character_updater.create_character(entity, player_uuid, character_alias, PersistedComponents { + body, + stats, + skill_set, + inventory, + waypoint, + pets: Vec::new(), + active_abilities: Default::default(), + }); Ok(()) } diff --git a/server/src/events/entity_creation.rs b/server/src/events/entity_creation.rs index bd8967b7bf..3402009ac3 100644 --- a/server/src/events/entity_creation.rs +++ b/server/src/events/entity_creation.rs @@ -1,4 +1,4 @@ -use crate::{client::Client, sys, Server, StateExt}; +use crate::{client::Client, persistence::PersistedComponents, sys, Server, StateExt}; use common::{ character::CharacterId, comp::{ @@ -35,15 +35,7 @@ pub fn handle_initialize_character( pub fn handle_loaded_character_data( server: &mut Server, entity: EcsEntity, - loaded_components: ( - comp::Body, - comp::Stats, - comp::SkillSet, - comp::Inventory, - Option, - Vec<(comp::Pet, comp::Body, comp::Stats)>, - comp::ActiveAbilities, - ), + loaded_components: PersistedComponents, ) { server .state diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index 9ab4bf23bd..82c733389e 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -1,4 +1,7 @@ -use crate::{events::interaction::handle_tame_pet, state_ext::StateExt, Server}; +use crate::{ + events::interaction::handle_tame_pet, persistence::PersistedComponents, state_ext::StateExt, + Server, +}; use common::event::{EventBus, ServerEvent}; use common_base::span; use entity_creation::{ @@ -129,6 +132,17 @@ impl Server { character_id, } => handle_initialize_character(self, entity, character_id), ServerEvent::UpdateCharacterData { entity, components } => { + let (body, stats, skill_set, inventory, waypoint, pets, active_abilities) = + components; + let components = PersistedComponents { + body, + stats, + skill_set, + inventory, + waypoint, + pets, + active_abilities, + }; handle_loaded_character_data(self, entity, components); }, ServerEvent::ExitIngame { entity } => { diff --git a/server/src/lib.rs b/server/src/lib.rs index 371a28db3b..fa19904156 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -55,6 +55,7 @@ use crate::{ connection_handler::ConnectionHandler, data_dir::DataDir, login_provider::LoginProvider, + persistence::PersistedComponents, presence::{Presence, RegionSubscription, RepositionOnChunkLoad}, rtsim::RtSim, state_ext::StateExt, @@ -844,9 +845,29 @@ impl Server { }, CharacterLoaderResponseKind::CharacterData(result) => { let message = match *result { - Ok(character_data) => ServerEvent::UpdateCharacterData { - entity: query_result.entity, - components: character_data, + Ok(character_data) => { + let PersistedComponents { + body, + stats, + skill_set, + inventory, + waypoint, + pets, + active_abilities, + } = character_data; + let character_data = ( + body, + stats, + skill_set, + inventory, + waypoint, + pets, + active_abilities, + ); + ServerEvent::UpdateCharacterData { + entity: query_result.entity, + components: character_data, + } }, Err(error) => { // We failed to load data for the character from the DB. Notify the diff --git a/server/src/persistence/character.rs b/server/src/persistence/character.rs index c9c6739aa8..6517d49d5b 100644 --- a/server/src/persistence/character.rs +++ b/server/src/persistence/character.rs @@ -248,20 +248,20 @@ pub fn load_character_data( }) })?; - Ok(( - convert_body_from_database(&body_data.variant, &body_data.body_data)?, - convert_stats_from_database(character_data.alias), - convert_skill_set_from_database(&skill_group_data), - convert_inventory_from_database_items( + Ok(PersistedComponents { + body: convert_body_from_database(&body_data.variant, &body_data.body_data)?, + stats: convert_stats_from_database(character_data.alias), + skill_set: convert_skill_set_from_database(&skill_group_data), + inventory: convert_inventory_from_database_items( character_containers.inventory_container_id, &inventory_items, character_containers.loadout_container_id, &loadout_items, )?, - char_waypoint, + waypoint: char_waypoint, pets, - convert_active_abilities_from_database(&ability_set_data), - )) + active_abilities: convert_active_abilities_from_database(&ability_set_data), + }) } /// Loads a list of characters belonging to the player. This data is a small @@ -346,7 +346,15 @@ pub fn create_character( ) -> CharacterCreationResult { check_character_limit(uuid, transaction)?; - let (body, _stats, skill_set, inventory, waypoint, _, active_abilities) = persisted_components; + let PersistedComponents { + body, + stats: _, + skill_set, + inventory, + waypoint, + pets: _, + active_abilities, + } = persisted_components; // Fetch new entity IDs for character, inventory and loadout let mut new_entity_ids = get_new_entity_ids(transaction, |next_id| next_id + 3)?; diff --git a/server/src/persistence/json_models.rs b/server/src/persistence/json_models.rs index da39d0315d..9522fb2d9c 100644 --- a/server/src/persistence/json_models.rs +++ b/server/src/persistence/json_models.rs @@ -125,36 +125,51 @@ fn aux_ability_to_string(ability: common::comp::ability::AuxiliaryAbility) -> St } } -fn aux_ability_from_string(ability: String) -> common::comp::ability::AuxiliaryAbility { +fn aux_ability_from_string(ability: &str) -> common::comp::ability::AuxiliaryAbility { use common::comp::ability::AuxiliaryAbility; - let parts = ability - .split(":index:") - .map(String::from) - .collect::>(); - match parts.get(0).map(|s| s.as_str()) { - Some("Main Weapon") => { - if let Some(index) = parts.get(1).and_then(|index| index.parse::().ok()) { - AuxiliaryAbility::MainWeapon(index) - } else { + let mut parts = ability.split(":index:"); + match parts.next() { + Some("Main Weapon") => match parts + .next() + .map(|index| index.parse::().map_err(|_| index)) + { + Some(Ok(index)) => AuxiliaryAbility::MainWeapon(index), + Some(Err(error)) => { dev_panic!(format!( - "Converstion from databse to ability set failed. Unable to parse index for \ - mainhand abilities: {:#?}", - parts.get(1) + "Conversion from database to ability set failed. Unable to parse index for \ + mainhand abilities: {}", + error )); AuxiliaryAbility::Empty - } + }, + None => { + dev_panic!(String::from( + "Conversion from database to ability set failed. Unable to find an index for \ + mainhand abilities" + )); + AuxiliaryAbility::Empty + }, }, - Some("Off Weapon") => { - if let Some(index) = parts.get(1).and_then(|index| index.parse::().ok()) { - AuxiliaryAbility::OffWeapon(index) - } else { + Some("Off Weapon") => match parts + .next() + .map(|index| index.parse::().map_err(|_| index)) + { + Some(Ok(index)) => AuxiliaryAbility::OffWeapon(index), + Some(Err(error)) => { dev_panic!(format!( - "Converstion from databse to ability set failed. Unable to parse index for \ - offhand abilities: {:#?}", - parts.get(1) + "Conversion from database to ability set failed. Unable to parse index for \ + offhand abilities: {}", + error )); AuxiliaryAbility::Empty - } + }, + None => { + dev_panic!(String::from( + "Conversion from database to ability set failed. Unable to find an index for \ + offhand abilities" + )); + AuxiliaryAbility::Empty + }, }, Some("Empty") => AuxiliaryAbility::Empty, unknown => { @@ -182,6 +197,7 @@ fn tool_kind_to_string(tool: Option) -> Stri Some(Blowgun) => "Blowgun", Some(Pick) => "Pick", + // Toolkinds that are not anticipated to have many active aiblities (if any at all) Some(Farming) => "Farming", Some(Debug) => "Debug", Some(Natural) => "Natural", @@ -251,7 +267,7 @@ pub fn active_abilities_from_db_model( let mut auxiliary_abilities = [comp::ability::AuxiliaryAbility::Empty; comp::ability::MAX_ABILITIES]; for (empty, ability) in auxiliary_abilities.iter_mut().zip(abilities.into_iter()) { - *empty = aux_ability_from_string(ability); + *empty = aux_ability_from_string(&ability); } ( ( diff --git a/server/src/persistence/mod.rs b/server/src/persistence/mod.rs index 0d78329275..782dcbbca1 100644 --- a/server/src/persistence/mod.rs +++ b/server/src/persistence/mod.rs @@ -21,16 +21,17 @@ use std::{ }; use tracing::info; -/// A tuple of the components that are persisted to the DB for each character -pub type PersistedComponents = ( - comp::Body, - comp::Stats, - comp::SkillSet, - comp::Inventory, - Option, - Vec, - comp::ActiveAbilities, -); +/// A struct of the components that are persisted to the DB for each character +#[derive(Debug)] +pub struct PersistedComponents { + pub body: comp::Body, + pub stats: comp::Stats, + pub skill_set: comp::SkillSet, + pub inventory: comp::Inventory, + pub waypoint: Option, + pub pets: Vec, + pub active_abilities: comp::ActiveAbilities, +} pub type EditableComponents = (comp::Body,); diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index e46c2b072b..3aa1aa030e 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -238,7 +238,6 @@ impl StateExt for State { .unwrap_or(0), )) .with(stats) - // TODO: Figure out way to have this start with sane defaults .with(comp::ActiveAbilities::default()) .with(skill_set) .maybe_with(health) @@ -498,7 +497,15 @@ impl StateExt for State { } fn update_character_data(&mut self, entity: EcsEntity, components: PersistedComponents) { - let (body, stats, skill_set, inventory, waypoint, pets, active_abilities) = components; + let PersistedComponents { + body, + stats, + skill_set, + inventory, + waypoint, + pets, + active_abilities, + } = components; if let Some(player_uid) = self.read_component_copied::(entity) { // Notify clients of a player list update diff --git a/voxygen/src/hud/diary.rs b/voxygen/src/hud/diary.rs index 5eca5c0152..eea5901611 100644 --- a/voxygen/src/hud/diary.rs +++ b/voxygen/src/hud/diary.rs @@ -48,7 +48,6 @@ use common::{ }, consts::{ENERGY_PER_LEVEL, HP_PER_LEVEL}, }; -use inline_tweak::*; use std::borrow::Cow; const ART_SIZE: [f64; 2] = [320.0, 320.0]; @@ -782,12 +781,12 @@ impl<'a> Widget for Diary<'a> { // Background Art Image::new(self.imgs.book_bg) .w_h(299.0 * 4.0, 184.0 * 4.0) - .mid_top_with_margin_on(state.ids.content_align, tweak!(4.0)) + .mid_top_with_margin_on(state.ids.content_align, 4.0) //.graphics_for(state.ids.content_align) .set(state.ids.spellbook_art, ui); Image::new(self.imgs.skills_bg) .w_h(240.0 * 2.0, 40.0 * 2.0) - .mid_bottom_with_margin_on(state.ids.content_align, tweak!(8.0)) + .mid_bottom_with_margin_on(state.ids.content_align, 8.0) .set(state.ids.spellbook_skills_bg, ui); Rectangle::fill_with([299.0 * 2.0, 184.0 * 4.0], color::TRANSPARENT) @@ -816,7 +815,7 @@ impl<'a> Widget for Diary<'a> { background_color: Some(UI_MAIN), content_size: ContentSize { width_height_ratio: 1.0, - max_fraction: tweak!(0.9), + max_fraction: 0.9, }, selected_content_scale: 1.067, amount_font: self.fonts.cyri.conrod_id, @@ -838,11 +837,14 @@ impl<'a> Widget for Diary<'a> { Some(self.skill_set), ) .ability_id(Some(self.inventory)); - let (ability_title, ability_desc) = - util::ability_description(ability_id.unwrap_or("")); + let (ability_title, ability_desc) = if let Some(ability_id) = ability_id { + util::ability_description(ability_id) + } else { + ("Drag an ability here to use it.", "") + }; - let image_size = tweak!(80.0); - let image_offsets = tweak!(92.0) * i as f64; + let image_size = 80.0; + let image_offsets = 92.0 * i as f64; let slot = AbilitySlot::Slot(i); let mut ability_slot = slot_maker.fabricate(slot, [image_size; 2]); @@ -850,8 +852,8 @@ impl<'a> Widget for Diary<'a> { if i == 0 { ability_slot = ability_slot.top_left_with_margins_on( state.ids.spellbook_skills_bg, - tweak!(0.0), - tweak!(32.0) + image_offsets, + 0.0, + 32.0 + image_offsets, ); } else { ability_slot = @@ -870,52 +872,22 @@ impl<'a> Widget for Diary<'a> { // Display Slot Keybinding let keys = &self.global_state.settings.controls; let key_layout = &self.global_state.window.key_layout; - let ability_key: String = match i { - 0 => { - if let Some(key) = keys.get_binding(GameInput::Slot1) { - key.display_string(key_layout) - } else { - String::new() - } - }, - 1 => { - if let Some(key) = keys.get_binding(GameInput::Slot2) { - key.display_string(key_layout) - } else { - String::new() - } - }, - 2 => { - if let Some(key) = keys.get_binding(GameInput::Slot3) { - key.display_string(key_layout) - } else { - String::new() - } - }, - 3 => { - if let Some(key) = keys.get_binding(GameInput::Slot4) { - key.display_string(key_layout) - } else { - String::new() - } - }, - 4 => { - if let Some(key) = keys.get_binding(GameInput::Slot5) { - key.display_string(key_layout) - } else { - String::new() - } - }, - _ => String::new(), - }; + let ability_key = [ + GameInput::Slot1, + GameInput::Slot2, + GameInput::Slot3, + GameInput::Slot4, + GameInput::Slot5, + ] + .get(i) + .and_then(|input| keys.get_binding(*input)) + .map(|key| key.display_string(key_layout)) + .unwrap_or_default(); + Text::new(&ability_key) - .top_left_with_margins_on( - state.ids.active_abilities[i], - tweak!(0.0), - tweak!(4.0), - ) + .top_left_with_margins_on(state.ids.active_abilities[i], 0.0, 4.0) .font_id(self.fonts.cyri.conrod_id) - .font_size(self.fonts.cyri.scale(tweak!(20))) + .font_size(self.fonts.cyri.scale(20)) .color(TEXT_COLOR) .graphics_for(state.ids.active_abilities[i]) .set(state.ids.active_abilities_keys[i], ui); @@ -964,31 +936,30 @@ impl<'a> Widget for Diary<'a> { state.update(|s| s.ability_page = 0); } - let update_length = 12; state.update(|s| { s.ids .abilities - .resize(update_length, &mut ui.widget_id_generator()) + .resize(ABILITIES_PER_PAGE, &mut ui.widget_id_generator()) }); state.update(|s| { s.ids .abilities_dual - .resize(update_length, &mut ui.widget_id_generator()) + .resize(ABILITIES_PER_PAGE, &mut ui.widget_id_generator()) }); state.update(|s| { s.ids .ability_titles - .resize(update_length, &mut ui.widget_id_generator()) + .resize(ABILITIES_PER_PAGE, &mut ui.widget_id_generator()) }); state.update(|s| { s.ids .ability_frames - .resize(update_length, &mut ui.widget_id_generator()) + .resize(ABILITIES_PER_PAGE, &mut ui.widget_id_generator()) }); state.update(|s| { s.ids .ability_descs - .resize(update_length, &mut ui.widget_id_generator()) + .resize(ABILITIES_PER_PAGE, &mut ui.widget_id_generator()) }); // Page button @@ -998,7 +969,7 @@ impl<'a> Widget for Diary<'a> { } else { self.imgs.arrow_l_inactive }) - .bottom_left_with_margins_on(state.ids.spellbook_art, tweak!(-83.0), tweak!(10.0)) + .bottom_left_with_margins_on(state.ids.spellbook_art, -83.0, 10.0) .w_h(48.0, 55.0); // Grey out arrows when inactive if state.ability_page > 0 { @@ -1019,7 +990,7 @@ impl<'a> Widget for Diary<'a> { } else { self.imgs.arrow_r_inactive }) - .bottom_right_with_margins_on(state.ids.spellbook_art, tweak!(-83.0), tweak!(10.0)) + .bottom_right_with_margins_on(state.ids.spellbook_art, -83.0, 10.0) .w_h(48.0, 55.0); if state.ability_page < page_indices { // Only show right button if not on last page @@ -1036,7 +1007,6 @@ impl<'a> Widget for Diary<'a> { } let ability_start = state.ability_page * ABILITIES_PER_PAGE; - let abilities_range = ability_start..(ability_start + ABILITIES_PER_PAGE); let mut slot_maker = SlotMaker { empty_slot: self.imgs.inv_slot, @@ -1045,9 +1015,9 @@ impl<'a> Widget for Diary<'a> { background_color: Some(UI_MAIN), content_size: ContentSize { width_height_ratio: 1.0, - max_fraction: tweak!(1.0), + max_fraction: 1.0, }, - selected_content_scale: tweak!(1.067), + selected_content_scale: 1.067, amount_font: self.fonts.cyri.conrod_id, amount_margins: Vec2::new(-4.0, 0.0), amount_font_size: self.fonts.cyri.scale(12), @@ -1060,10 +1030,8 @@ impl<'a> Widget for Diary<'a> { for (id_index, (ability_id, ability)) in abilities .iter() - .enumerate() - .filter_map(|(i, ability_info)| { - abilities_range.contains(&i).then_some(ability_info) - }) + .skip(ability_start) + .take(ABILITIES_PER_PAGE) .enumerate() { let (ability_title, ability_desc) = @@ -1081,13 +1049,8 @@ impl<'a> Widget for Diary<'a> { self.imgs.ability_frame }) .w_h(566.0, 108.0) - .top_left_with_margins_on( - align_state, - tweak!(16.0) + image_offsets, - tweak!(16.0), - ) + .top_left_with_margins_on(align_state, 16.0 + image_offsets, 16.0) .color(Some(UI_HIGHLIGHT_0)) - //.parent(state.ids.abilities[id_index]) .set(state.ids.ability_frames[id_index], ui); let slot = AbilitySlot::Ability(*ability); @@ -1121,19 +1084,15 @@ impl<'a> Widget for Diary<'a> { Text::new(ability_title) .top_left_with_margins_on(state.ids.abilities[id_index], 5.0, 110.0) .font_id(self.fonts.cyri.conrod_id) - .font_size(self.fonts.cyri.scale(tweak!(28))) + .font_size(self.fonts.cyri.scale(28)) .color(TEXT_COLOR) .w(text_width) .graphics_for(state.ids.abilities[id_index]) .set(state.ids.ability_titles[id_index], ui); Text::new(ability_desc) - .top_left_with_margins_on( - state.ids.abilities[id_index], - tweak!(40.0), - 110.0, - ) + .top_left_with_margins_on(state.ids.abilities[id_index], 40.0, 110.0) .font_id(self.fonts.cyri.conrod_id) - .font_size(self.fonts.cyri.scale(tweak!(18))) + .font_size(self.fonts.cyri.scale(18)) .color(TEXT_COLOR) .w(text_width) .graphics_for(state.ids.abilities[id_index]) @@ -1162,7 +1121,7 @@ impl<'a> Widget for Diary<'a> { // Background Art Image::new(self.imgs.book_bg) .w_h(299.0 * 4.0, 184.0 * 4.0) - .mid_top_with_margin_on(state.ids.content_align, tweak!(4.0)) + .mid_top_with_margin_on(state.ids.content_align, 4.0) .set(state.ids.spellbook_art, ui); state.update(|s| { @@ -1183,13 +1142,9 @@ impl<'a> Widget for Diary<'a> { .color(BLACK); if i == 0 { - txt = txt.top_left_with_margins_on( - state.ids.spellbook_art, - tweak!(20.0), - tweak!(20.0), - ); + txt = txt.top_left_with_margins_on(state.ids.spellbook_art, 20.0, 20.0); } else { - txt = txt.down_from(state.ids.stat_names[i - 1], tweak!(10.0)); + txt = txt.down_from(state.ids.stat_names[i - 1], 10.0); }; txt.set(state.ids.stat_names[i], ui); @@ -1261,7 +1216,7 @@ impl<'a> Widget for Diary<'a> { (Some(stats), None) | (None, Some(stats)) => { format!("{}", stats.power * 10.0) }, - _ => String::new(), + (None, None) => String::new(), }, "Weapon Speed" => { let spd_fmt = |sp| (sp - 1.0) * 100.0; @@ -1288,7 +1243,7 @@ impl<'a> Widget for Diary<'a> { (Some(stats), None) | (None, Some(stats)) => { format!("{}", stats.effect_power * 10.0) }, - _ => String::new(), + (None, None) => String::new(), }, "Weapon Crit-Chance" => { let crit_fmt = |cc| cc * 100.0; @@ -1301,10 +1256,10 @@ impl<'a> Widget for Diary<'a> { (Some(stats), None) | (None, Some(stats)) => { format!("{:.1}%", crit_fmt(stats.crit_chance)) }, - _ => String::new(), + (None, None) => String::new(), } }, - _ => String::new(), + unknown => unreachable!(unknown), }; let mut number = Text::new(&value) @@ -1313,9 +1268,9 @@ impl<'a> Widget for Diary<'a> { .color(BLACK); if i == 0 { - number = number.right_from(state.ids.stat_names[i], tweak!(265.0)); + number = number.right_from(state.ids.stat_names[i], 265.0); } else { - number = number.down_from(state.ids.stat_values[i - 1], tweak!(10.0)); + number = number.down_from(state.ids.stat_values[i - 1], 10.0); }; number.set(state.ids.stat_values[i], ui); } diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 861786b23f..2b03fd478e 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -3392,7 +3392,7 @@ impl Hud { (AbilitySlot::Slot(index), _) => { events.push(Event::ChangeAbility(index, AuxiliaryAbility::Empty)); }, - (_, _) => {}, + (AbilitySlot::Ability(_), AbilitySlot::Ability(_)) => {}, } } }, @@ -3494,7 +3494,7 @@ impl Hud { (AbilitySlot::Slot(index), _) => { events.push(Event::ChangeAbility(index, AuxiliaryAbility::Empty)); }, - (_, _) => {}, + (AbilitySlot::Ability(_), AbilitySlot::Ability(_)) => {}, } } }, diff --git a/voxygen/src/hud/slots.rs b/voxygen/src/hud/slots.rs index 2d8bf99b8a..ec2fd4fb7c 100644 --- a/voxygen/src/hud/slots.rs +++ b/voxygen/src/hud/slots.rs @@ -250,5 +250,10 @@ impl From for SlotKind { } impl SumSlot for SlotKind { - fn is_ability(&self) -> bool { matches!(self, Self::Ability(_)) } + fn drag_size(&self) -> Option<[f64; 2]> { + Some(match self { + Self::Ability(_) => [80.0; 2], + _ => return None, + }) + } } diff --git a/voxygen/src/hud/util.rs b/voxygen/src/hud/util.rs index bd3710b79a..aa38d674c3 100644 --- a/voxygen/src/hud/util.rs +++ b/voxygen/src/hud/util.rs @@ -398,8 +398,8 @@ pub fn ability_description(ability_id: &str) -> (&str, &str) { "Protects you and your group with thorns for a short amount of time.", ), _ => ( - "Drag an ability here to use it.", - "" + "Ability has no title", + "Ability has no description." ), } } diff --git a/voxygen/src/ui/widgets/slot.rs b/voxygen/src/ui/widgets/slot.rs index b26296239c..a8a2898663 100644 --- a/voxygen/src/ui/widgets/slot.rs +++ b/voxygen/src/ui/widgets/slot.rs @@ -20,7 +20,7 @@ pub trait SlotKey: Copy { } pub trait SumSlot: Sized + PartialEq + Copy + Send + 'static { - fn is_ability(&self) -> bool; + fn drag_size(&self) -> Option<[f64; 2]>; } pub struct ContentSize { @@ -219,8 +219,8 @@ where let content_img = *content_img; let drag_amount = *drag_amount; - let dragged_size = if slot.is_ability() { - [inline_tweak::tweak!(80.0); 2] + let dragged_size = if let Some(dragged_size) = slot.drag_size() { + dragged_size } else { self.drag_img_size.map(|e| e as f64).into_array() };