mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed MR comments.
This commit is contained in:
parent
4d3b0736d0
commit
7ae8ed09f6
@ -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
|
||||
|
||||
|
@ -31,7 +31,7 @@ macro_rules! dev_panic {
|
||||
if cfg!(any(debug_assertions, test)) {
|
||||
panic!("{}", $msg);
|
||||
} else {
|
||||
tracing::warn!("{}", $msg);
|
||||
tracing::error!("{}", $msg);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(())
|
||||
}
|
||||
|
||||
|
@ -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<comp::Waypoint>,
|
||||
Vec<(comp::Pet, comp::Body, comp::Stats)>,
|
||||
comp::ActiveAbilities,
|
||||
),
|
||||
loaded_components: PersistedComponents,
|
||||
) {
|
||||
server
|
||||
.state
|
||||
|
@ -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 } => {
|
||||
|
@ -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
|
||||
|
@ -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)?;
|
||||
|
@ -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::<Vec<_>>();
|
||||
match parts.get(0).map(|s| s.as_str()) {
|
||||
Some("Main Weapon") => {
|
||||
if let Some(index) = parts.get(1).and_then(|index| index.parse::<usize>().ok()) {
|
||||
AuxiliaryAbility::MainWeapon(index)
|
||||
} else {
|
||||
let mut parts = ability.split(":index:");
|
||||
match parts.next() {
|
||||
Some("Main Weapon") => match parts
|
||||
.next()
|
||||
.map(|index| index.parse::<usize>().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::<usize>().ok()) {
|
||||
AuxiliaryAbility::OffWeapon(index)
|
||||
} else {
|
||||
Some("Off Weapon") => match parts
|
||||
.next()
|
||||
.map(|index| index.parse::<usize>().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<common::comp::item::tool::ToolKind>) -> 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);
|
||||
}
|
||||
(
|
||||
(
|
||||
|
@ -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<comp::Waypoint>,
|
||||
Vec<PetPersistenceData>,
|
||||
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<comp::Waypoint>,
|
||||
pub pets: Vec<PetPersistenceData>,
|
||||
pub active_abilities: comp::ActiveAbilities,
|
||||
}
|
||||
|
||||
pub type EditableComponents = (comp::Body,);
|
||||
|
||||
|
@ -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::<Uid>(entity) {
|
||||
// Notify clients of a player list update
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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(_)) => {},
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -250,5 +250,10 @@ impl From<AbilitySlot> 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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."
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ pub trait SlotKey<C, I>: 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()
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user