Start reworking character window

This commit is contained in:
hodasemi 2025-03-04 18:40:56 +01:00
parent 1157473d3f
commit 5de2c86f09
12 changed files with 234 additions and 224 deletions

View file

@ -45,4 +45,4 @@ audio = { git = "https://gavania.de/hodasemi/audio.git" }
library_loader = { git = "https://gavania.de/hodasemi/vulkan_lib.git" } library_loader = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
ui = { git = "https://gavania.de/hodasemi/ui.git" } ui = { git = "https://gavania.de/hodasemi/ui.git" }
engine = { git = "https://gavania.de/hodasemi/engine.git" } engine = { git = "https://gavania.de/hodasemi/engine.git" }
ecs = { git = "https://gavania.de/hodasemi/engine.git" } ecs = { git = "https://gavania.de/hodasemi/ecs.git" }

View file

@ -10,7 +10,7 @@ use rpg_components::items::Rarities;
use crate::*; use crate::*;
use crate::{traits::RightSide, CharacterWindow}; use crate::{CharacterWindow, traits::RightSide};
pub struct AbilityPageRightSide<A: Ability + 'static> { pub struct AbilityPageRightSide<A: Ability + 'static> {
snippet: Arc<GuiSnippet>, snippet: Arc<GuiSnippet>,
@ -28,21 +28,13 @@ impl<A: Ability + 'static> AbilityPageRightSide<A> {
"fourth_ability", "fourth_ability",
]; ];
pub fn new( pub fn new(world: &World, hero: Entity) -> Result<Self> {
engine: &Arc<Engine>,
reference: &Weak<CharacterWindow>,
hero: Entity,
) -> Result<Self> {
let snippet = GuiSnippet::from_str( let snippet = GuiSnippet::from_str(
engine.gui_handler(), world.resources.get::<Arc<GuiHandler>>(),
include_str!("../../resources/abilities/right_side.xml"), include_str!("../../resources/abilities/right_side.xml"),
)?; )?;
let color_settings = &engine let color_settings = world.resources.get::<ItemSettings>().rarity_color_settings;
.scene()
.resources
.get::<ItemSettings>()
.rarity_color_settings;
Self::rarity_icon_background(&snippet, "common", color_settings.common)?; Self::rarity_icon_background(&snippet, "common", color_settings.common)?;
Self::rarity_icon_background(&snippet, "uncommon", color_settings.uncommon)?; Self::rarity_icon_background(&snippet, "uncommon", color_settings.uncommon)?;
@ -54,12 +46,13 @@ impl<A: Ability + 'static> AbilityPageRightSide<A> {
for (index, name) in Self::ABILITY_BUTTON_NAMES.iter().enumerate() { for (index, name) in Self::ABILITY_BUTTON_NAMES.iter().enumerate() {
let button: Arc<Button> = snippet.element(name)?; let button: Arc<Button> = snippet.element(name)?;
button.set_info_icon(&engine.controller_icon(ControllerButton::RightStick)?)?; button.set_info_icon(&world.resources.get::<EngineSettings>().controller_icon(
world.resources.get::<Context>(),
ControllerButton::RightStick,
)?)?;
button.set_callback({ button.set_callback({
let reference = reference.clone(); || {
move || {
if let Some(menu) = reference.upgrade() { if let Some(menu) = reference.upgrade() {
let mut tabs = menu.tabs_mut(); let mut tabs = menu.tabs_mut();
let abilities = tabs.abilities::<A>(); let abilities = tabs.abilities::<A>();

View file

@ -9,10 +9,10 @@ use rpg_components::components::inventory::Inventory;
use self::ability_right_side::AbilityPageRightSide; use self::ability_right_side::AbilityPageRightSide;
use super::{ use super::{
CharacterWindow, Page,
content::Content, content::Content,
page_content::{EmptyRightSide, PageContent}, page_content::{EmptyRightSide, PageContent},
traits::{PageContentWrapper, RightSide}, traits::{PageContentWrapper, RightSide},
CharacterWindow, Page,
}; };
use crate::*; use crate::*;
@ -36,18 +36,19 @@ pub struct AbilityPage<A: Ability + 'static> {
impl<A: Ability + 'static> AbilityPage<A> { impl<A: Ability + 'static> AbilityPage<A> {
pub fn new( pub fn new(
engine: &Arc<Engine>, world: &mut World,
hero: Entity, hero: Entity,
reference: Weak<CharacterWindow>, reference: Weak<CharacterWindow>,
close: &Arc<Button>, close: &Arc<Button>,
) -> Result<Self> { ) -> Result<Self> {
let grid = Grid::new(engine.gui_handler().clone(), 2, 1, false)?; let gui_handler = world.resources.get_mut::<GuiHandler>();
let grid = Grid::new(gui_handler, 2, 1, false)?;
let left_base = GuiSnippet::from_str( let left_base = GuiSnippet::from_str(
engine.gui_handler(), gui_handler,
include_str!("../../resources/abilities/left_side.xml"), include_str!("../../resources/abilities/left_side.xml"),
)?; )?;
grid.attach(left_base.clone(), 0, 0, 1, 1)?; grid.attach(gui_handler, left_base.clone(), 0, 0, 1, 1)?;
Self::setup_content_switch(&left_base, reference.clone())?; Self::setup_content_switch(&left_base, reference.clone())?;

View file

@ -15,7 +15,6 @@ use super::{CharacterWindow, Page};
use crate::*; use crate::*;
pub struct CharacterPage { pub struct CharacterPage {
engine: Arc<Engine>,
hero: Entity, hero: Entity,
snippet: Arc<GuiSnippet>, snippet: Arc<GuiSnippet>,
@ -24,20 +23,21 @@ pub struct CharacterPage {
impl CharacterPage { impl CharacterPage {
pub fn new( pub fn new(
engine: &Arc<Engine>, world: &mut World,
hero: Entity, hero: Entity,
hero_name: &str, hero_name: &str,
reference: &Weak<CharacterWindow>, reference: &Weak<CharacterWindow>,
) -> Result<Self> { ) -> Result<Self> {
let gui_handler = world.resources.get_mut::<GuiHandler>();
let snippet = GuiSnippet::from_str( let snippet = GuiSnippet::from_str(
engine.gui_handler(), gui_handler,
include_str!("../../resources/character/statistics.xml"), include_str!("../../resources/character/statistics.xml"),
)?; )?;
let grid: Arc<Grid> = snippet.element("statistic_tab")?; let grid: Arc<Grid> = snippet.element("statistic_tab")?;
let name: Arc<Label> = snippet.element("character_name")?; let name: Arc<Label> = snippet.element("character_name")?;
name.set_text(hero_name)?; name.set_text(gui_handler, hero_name)?;
let strength: Arc<Button> = snippet.element("strength_field")?; let strength: Arc<Button> = snippet.element("strength_field")?;
strength.set_callback({ strength.set_callback({
@ -73,7 +73,6 @@ impl CharacterPage {
}); });
Ok(Self { Ok(Self {
engine: engine.clone(),
hero, hero,
snippet, snippet,
@ -88,7 +87,7 @@ impl CharacterPage {
Ok(()) Ok(())
} }
fn update_stats(&self) -> Result<()> { fn update_stats(&self, world: &World) -> Result<()> {
let air_def: Arc<Label> = self.snippet.element("air_def_info")?; let air_def: Arc<Label> = self.snippet.element("air_def_info")?;
let fire_def: Arc<Label> = self.snippet.element("fire_def_info")?; let fire_def: Arc<Label> = self.snippet.element("fire_def_info")?;
let water_def: Arc<Label> = self.snippet.element("water_def_info")?; let water_def: Arc<Label> = self.snippet.element("water_def_info")?;
@ -107,36 +106,34 @@ impl CharacterPage {
let mana: Arc<Label> = self.snippet.element("mana_info")?; let mana: Arc<Label> = self.snippet.element("mana_info")?;
let mana_regen: Arc<Label> = self.snippet.element("mana_regen_info")?; let mana_regen: Arc<Label> = self.snippet.element("mana_regen_info")?;
self.engine.on_scene(|scene| { let entity = world.entity(self.hero)?;
let entity = scene.entity(self.hero)?; let statistics = entity.get_component::<Statistics>()?;
let statistics = entity.get_component::<Statistics>()?;
air_def.set_text(&format!("{}", statistics.air_resistance.raw()))?; air_def.set_text(&format!("{}", statistics.air_resistance.raw()))?;
fire_def.set_text(&format!("{}", statistics.fire_resistance.raw()))?; fire_def.set_text(&format!("{}", statistics.fire_resistance.raw()))?;
water_def.set_text(&format!("{}", statistics.water_resistance.raw()))?; water_def.set_text(&format!("{}", statistics.water_resistance.raw()))?;
armor.set_text(&format!("{}", statistics.armor.raw()))?; armor.set_text(&format!("{}", statistics.armor.raw()))?;
air_dmg.set_text(&format!("{}", statistics.air_damage.raw()))?; air_dmg.set_text(&format!("{}", statistics.air_damage.raw()))?;
fire_dmg.set_text(&format!("{}", statistics.fire_damage.raw()))?; fire_dmg.set_text(&format!("{}", statistics.fire_damage.raw()))?;
water_dmg.set_text(&format!("{}", statistics.water_damage.raw()))?; water_dmg.set_text(&format!("{}", statistics.water_damage.raw()))?;
phys_dmg.set_text(&format!("{}", statistics.physical_damage.raw()))?; phys_dmg.set_text(&format!("{}", statistics.physical_damage.raw()))?;
crit_chance.set_text(&format!("{:.2} %", statistics.critical_hit_chance.raw()))?; crit_chance.set_text(&format!("{:.2} %", statistics.critical_hit_chance.raw()))?;
crit_dmg.set_text(&format!( crit_dmg.set_text(&format!(
"{:.2} %", "{:.2} %",
statistics.critical_hit_damage.raw() + 100.0 statistics.critical_hit_damage.raw() + 100.0
))?; ))?;
health.set_text(&format!("{:.0}", statistics.health.raw()))?; health.set_text(&format!("{:.0}", statistics.health.raw()))?;
health_regen.set_text(&format!("{:.2}", statistics.health_regeneration.raw()))?; health_regen.set_text(&format!("{:.2}", statistics.health_regeneration.raw()))?;
mana.set_text(&format!("{:.0}", statistics.mana.raw()))?; mana.set_text(&format!("{:.0}", statistics.mana.raw()))?;
mana_regen.set_text(&format!("{:.2}", statistics.mana_regeneration.raw()))?; mana_regen.set_text(&format!("{:.2}", statistics.mana_regeneration.raw()))?;
Ok(()) Ok(())
})
} }
fn update_attributes(&self) -> Result<()> { fn update_attributes(&self, world: &World) -> Result<()> {
let level_label: Arc<Label> = self.snippet.element("level")?; let level_label: Arc<Label> = self.snippet.element("level")?;
let level_progress: Arc<ProgressBar> = self.snippet.element("level_progress")?; let level_progress: Arc<ProgressBar> = self.snippet.element("level_progress")?;
@ -145,33 +142,31 @@ impl CharacterPage {
let agility: Arc<Button> = self.snippet.element("agility_field")?; let agility: Arc<Button> = self.snippet.element("agility_field")?;
let intelligence: Arc<Button> = self.snippet.element("intelligence_field")?; let intelligence: Arc<Button> = self.snippet.element("intelligence_field")?;
self.engine.on_scene(|scene| { let entity = world.entity(self.hero)?;
let entity = scene.entity(self.hero)?;
let level = entity.get_component::<Level>()?; let level = entity.get_component::<Level>()?;
let attributes = entity.get_component::<Attributes>()?; let attributes = entity.get_component::<Attributes>()?;
level_label.set_text(format!("Level: {}", level.level()))?; level_label.set_text(format!("Level: {}", level.level()))?;
level_progress.set_text(format!( level_progress.set_text(format!(
"{} / {}", "{} / {}",
level.current_experience, level.experience_needed level.current_experience, level.experience_needed
))?; ))?;
attributes_label.set_text(format!( attributes_label.set_text(format!(
"Attributes ({})", "Attributes ({})",
Self::available_attribute_points( Self::available_attribute_points(
&scene.resources.get::<AttributeSettings>(), world.resources.get::<AttributeSettings>(),
attributes, attributes,
level level
) )
))?; ))?;
strength.set_text(attributes.strength().raw())?; strength.set_text(attributes.strength().raw())?;
agility.set_text(attributes.agility().raw())?; agility.set_text(attributes.agility().raw())?;
intelligence.set_text(attributes.intelligence().raw())?; intelligence.set_text(attributes.intelligence().raw())?;
Ok(()) Ok(())
})
} }
fn available_attribute_points( fn available_attribute_points(

View file

@ -46,25 +46,20 @@ pub struct JewelRightSide {
} }
impl JewelRightSide { impl JewelRightSide {
pub fn new<A: Ability + 'static>( pub fn new<A: Ability + 'static>(world: &mut World, file: &str, hero: Entity) -> Result<Self> {
engine: &Arc<Engine>, let snippet = GuiSnippet::from_str(world.resources.get_mut::<GuiHandler>(), file)?;
file: &str,
hero: Entity,
reference: &Weak<CharacterWindow>,
) -> Result<Self> {
let snippet = GuiSnippet::from_str(engine.gui_handler(), file)?;
let combine: Arc<Label> = snippet.element("combine")?; let combine: Arc<Label> = snippet.element("combine")?;
combine.set_info_icon(&engine.controller_icon(ControllerButton::RightStick)?)?; let icon = world.resources.get::<EngineSettings>().controller_icon(
world.resources.get::<Context>(),
ControllerButton::RightStick,
)?;
combine.set_info_icon(world.resources.get_mut::<GuiHandler>(), &icon)?;
engine.on_scene_mut(|scene| { world
scene .resources
.resources .insert_if_not_exists::<Option<ReferenceObject>>();
.insert_if_not_exists::<Option<ReferenceObject>>(); world.resources.insert_if_not_exists::<LowerJewels>();
scene.resources.insert_if_not_exists::<LowerJewels>();
Ok(())
})?;
let me = Self { snippet }; let me = Self { snippet };
me.setup_select::<A>(engine, hero, reference)?; me.setup_select::<A>(engine, hero, reference)?;
@ -96,7 +91,6 @@ impl JewelRightSide {
let (x, y, w, _h) = button.position_extent(); let (x, y, w, _h) = button.position_extent();
let scene = engine.scene(); let scene = engine.scene();
let reference_info = scene.resources.get::<Option<ReferenceObject>>(); let reference_info = scene.resources.get::<Option<ReferenceObject>>();
if let Some(reference_info) = reference_info { if let Some(reference_info) = reference_info {

View file

@ -13,7 +13,7 @@ use rpg_components::items::ability_book::Ability;
use super::page_content::PageContent; use super::page_content::PageContent;
use super::traits::*; use super::traits::*;
use super::{content::Content, CharacterWindow, Page}; use super::{CharacterWindow, Page, content::Content};
use item_right_side::ItemRightSide; use item_right_side::ItemRightSide;
use jewel_right_side::JewelRightSide; use jewel_right_side::JewelRightSide;
use map_right_side::MapRightSide; use map_right_side::MapRightSide;
@ -38,12 +38,13 @@ pub struct InventoryPage<A: Ability + 'static> {
impl<A: Ability + 'static> InventoryPage<A> { impl<A: Ability + 'static> InventoryPage<A> {
pub fn new( pub fn new(
engine: &Arc<Engine>, world: &mut World,
hero: Entity, hero: Entity,
reference: Weak<CharacterWindow>, reference: Weak<CharacterWindow>,
close: &Arc<Button>, close: &Arc<Button>,
) -> Result<Self> { ) -> Result<Self> {
let grid = Grid::new(engine.gui_handler().clone(), 2, 1, false)?; let gui_handler = world.resources.get_mut::<GuiHandler>();
let grid = Grid::new(gui_handler, 2, 1, false)?;
let left_base = GuiSnippet::from_str( let left_base = GuiSnippet::from_str(
engine.gui_handler(), engine.gui_handler(),

View file

@ -129,13 +129,13 @@ pub struct CharacterWindow {
impl CharacterWindow { impl CharacterWindow {
pub fn new<A: Ability + 'static>( pub fn new<A: Ability + 'static>(
world: &World, world: &mut World,
hero: Entity, hero: Entity,
name: &str, name: &str,
close: Box<dyn FutureStateChange>, close: Box<dyn FutureStateChange>,
) -> Result<Arc<Self>> { ) -> Result<Arc<Self>> {
let menu_gui = GuiBuilder::from_str( let menu_gui = GuiBuilder::from_str(
world.resources.get::<Arc<GuiHandler>>(), world.resources.get_mut::<GuiHandler>(),
include_str!("../resources/menu.xml"), include_str!("../resources/menu.xml"),
)?; )?;
@ -154,26 +154,22 @@ impl CharacterWindow {
tooltips: Mutex::default(), tooltips: Mutex::default(),
tabs: RwLock::new([ tabs: RwLock::new([
Box::new(CharacterPage::new(&engine, hero, name, me).unwrap()), Box::new(CharacterPage::new(world, hero, name, me).unwrap()),
Box::new( Box::new(InventoryPage::<A>::new(world, hero, me.clone(), &close_button).unwrap()),
InventoryPage::<A>::new(&engine, hero, me.clone(), &close_button).unwrap(), Box::new(AbilityPage::<A>::new(world, hero, me.clone(), &close_button).unwrap()),
),
Box::new(AbilityPage::<A>::new(&engine, hero, me.clone(), &close_button).unwrap()),
]), ]),
tab: AtomicUsize::new(0), tab: AtomicUsize::new(0),
engine,
}); });
let open_tab = { let open_tab = {
let weak_me = Arc::downgrade(&character_window); let weak_me = Arc::downgrade(&character_window);
move |index| { move |gui_handler: &mut GuiHandler, index| {
if let Some(me) = weak_me.upgrade() { if let Some(me) = weak_me.upgrade() {
me.tab.store(index, SeqCst); me.tab.store(index, SeqCst);
me.tab_content_grid me.tab_content_grid
.attach(me.tab_mut().enable()?, 0, 0, 1, 1)?; .attach(gui_handler, me.tab_mut().enable()?, 0, 0, 1, 1)?;
me.tab().select()?; me.tab().select()?;
} }
@ -184,19 +180,19 @@ impl CharacterWindow {
open_character_page.set_callback({ open_character_page.set_callback({
let open_tab = open_tab.clone(); let open_tab = open_tab.clone();
move || open_tab(0) move |world| open_tab(world.resources.get_mut::<GuiHandler>(), 0)
}); });
open_inventory_page.set_callback({ open_inventory_page.set_callback({
let open_tab = open_tab.clone(); let open_tab = open_tab.clone();
move || open_tab(1) move |world| open_tab(world.resources.get_mut::<GuiHandler>(), 1)
}); });
open_ability_page.set_callback({ open_ability_page.set_callback({
let open_tab = open_tab.clone(); let open_tab = open_tab.clone();
move || open_tab(2) move |world| open_tab(world.resources.get_mut::<GuiHandler>(), 2)
}); });
Self::setup_menu(&character_window)?; Self::setup_menu(&character_window)?;
@ -245,27 +241,24 @@ impl CharacterWindow {
self.tooltips.lock().unwrap().remove(&name.to_string()); self.tooltips.lock().unwrap().remove(&name.to_string());
} }
pub fn salvage_from_inventory<A, F, S>(engine: &Engine, hero: Entity, f: F) -> Result<()> pub fn salvage_from_inventory<A, F, S>(world: &mut World, hero: Entity, f: F) -> Result<()>
where where
A: Ability + 'static, A: Ability + 'static,
F: FnOnce(&mut Inventory<A>) -> S, F: FnOnce(&mut Inventory<A>) -> S,
S: Storable, S: Storable,
{ {
engine.on_scene_mut(|scene| { let entity = world.entity_mut(hero)?;
let entity = scene.entity_mut(hero)?; let mut multi_mut = entity.multi_mut();
let mut multi_mut = entity.multi_mut(); let crafting_materials = multi_mut.get::<CraftingMaterials>()?;
let inventory = multi_mut.get::<Inventory<A>>()?;
let crafting_materials = multi_mut.get::<CraftingMaterials>()?; // remove callback
let inventory = multi_mut.get::<Inventory<A>>()?; let storable = f(inventory);
// remove callback crafting_materials.increment(storable.rarity());
let storable = f(inventory);
crafting_materials.increment(storable.rarity()); Ok(())
Ok(())
})
} }
} }
@ -286,27 +279,36 @@ impl TopLevelGui for CharacterWindow {
None None
} }
fn enable(&self) -> Result<()> { fn enable(&self, gui_handler: &mut GuiHandler) -> Result<()> {
self.menu_gui.enable()?; self.menu_gui.enable(gui_handler)?;
self.tab_content_grid self.tab_content_grid
.attach(self.tab_mut().enable()?, 0, 0, 1, 1)?; .attach(gui_handler, self.tab_mut().enable()?, 0, 0, 1, 1)?;
self.tab().select()?; self.tab().select()?;
let close_button: Arc<Button> = self.menu_gui.element("close")?; let close_button: Arc<Button> = self.menu_gui.element("close")?;
close_button.set_info_icon(&self.engine.controller_icon(ControllerButton::B)?)?; close_button.set_info_icon(
gui_handler,
&self.engine.controller_icon(ControllerButton::B)?,
)?;
let left_info: Arc<Icon> = self.menu_gui.element("left_info")?; let left_info: Arc<Icon> = self.menu_gui.element("left_info")?;
left_info.set_icon(&self.engine.controller_icon(ControllerButton::LeftButton)?)?; left_info.set_icon(
gui_handler,
&self.engine.controller_icon(ControllerButton::LeftButton)?,
)?;
let right_info: Arc<Icon> = self.menu_gui.element("right_info")?; let right_info: Arc<Icon> = self.menu_gui.element("right_info")?;
right_info.set_icon(&self.engine.controller_icon(ControllerButton::RightButton)?)?; right_info.set_icon(
gui_handler,
&self.engine.controller_icon(ControllerButton::RightButton)?,
)?;
Ok(()) Ok(())
} }
fn disable(&self) -> Result<()> { fn disable(&self, gui_handler: &mut GuiHandler) -> Result<()> {
self.menu_gui.disable()?; self.menu_gui.disable(gui_handler)?;
Ok(()) Ok(())
} }
@ -327,11 +329,11 @@ impl GuiElementTraits for CharacterWindow {
} }
impl TopGui for CharacterWindow { impl TopGui for CharacterWindow {
fn decline(&self) -> Result<()> { fn decline(&self, world: &mut World) -> Result<()> {
(self.close)() (self.close)(world)
} }
fn next_tab(&self, second_level: bool) -> Result<()> { fn next_tab(&self, world: &mut World, second_level: bool) -> Result<()> {
match second_level { match second_level {
false => { false => {
// disable old tab // disable old tab
@ -341,8 +343,14 @@ impl TopGui for CharacterWindow {
self.tab.store((self.tab.load(SeqCst) + 1) % 3, SeqCst); self.tab.store((self.tab.load(SeqCst) + 1) % 3, SeqCst);
// update tab content // update tab content
self.tab_content_grid self.tab_content_grid.attach(
.attach(self.tab_mut().enable()?, 0, 0, 1, 1)?; world.resources.get_mut::<GuiHandler>(),
self.tab_mut().enable()?,
0,
0,
1,
1,
)?;
self.tab().select()?; self.tab().select()?;
} }
true => { true => {
@ -353,7 +361,7 @@ impl TopGui for CharacterWindow {
Ok(()) Ok(())
} }
fn previous_tab(&self, second_level: bool) -> Result<()> { fn previous_tab(&self, world: &mut World, second_level: bool) -> Result<()> {
match second_level { match second_level {
false => { false => {
// disable old tab // disable old tab
@ -367,8 +375,14 @@ impl TopGui for CharacterWindow {
} }
// update tab content // update tab content
self.tab_content_grid self.tab_content_grid.attach(
.attach(self.tab_mut().enable()?, 0, 0, 1, 1)?; world.resources.get_mut::<GuiHandler>(),
self.tab_mut().enable()?,
0,
0,
1,
1,
)?;
self.tab().select()?; self.tab().select()?;
} }
true => { true => {
@ -393,7 +407,7 @@ impl CharacterWindow {
// .add("open_statistics", open_statistics) // .add("open_statistics", open_statistics)
// .add("open_abilities", open_abilities) // .add("open_abilities", open_abilities)
// .add("open_inventory", open_inventory) // .add("open_inventory", open_inventory)
.add("close", close) .add("close", |world, _gui_handler| close(world))
.into(), .into(),
)?; )?;

View file

@ -15,7 +15,7 @@ use std::sync::Arc;
use crate::{components::inventory::Storable, config::abilities::AbilitySettings}; use crate::{components::inventory::Storable, config::abilities::AbilitySettings};
use super::{ability_book::Ability, ItemSystem, Rarities, Tooltip}; use super::{ItemSystem, Rarities, Tooltip, ability_book::Ability};
const COOL_DOWN_REDUCTION_CAP: f32 = 0.7; const COOL_DOWN_REDUCTION_CAP: f32 = 0.7;
@ -133,7 +133,7 @@ impl std::str::FromStr for AbilityAddonTypes {
return Err(anyhow::Error::msg(format!( return Err(anyhow::Error::msg(format!(
"Failed parsing AbilityAddonTypes from {}", "Failed parsing AbilityAddonTypes from {}",
s s
))) )));
} }
} }
} }
@ -247,7 +247,7 @@ impl AbilityAddon {
pub fn create_tooltip( pub fn create_tooltip(
&self, &self,
gui_handler: &Arc<GuiHandler>, gui_handler: &mut GuiHandler,
position: (i32, i32), position: (i32, i32),
) -> Result<Tooltip> { ) -> Result<Tooltip> {
let gui = GuiBuilder::from_str( let gui = GuiBuilder::from_str(
@ -261,15 +261,15 @@ impl AbilityAddon {
let value_label: Arc<Label> = gui.element("value")?; let value_label: Arc<Label> = gui.element("value")?;
let grid: Arc<Grid> = gui.element("addon_grid")?; let grid: Arc<Grid> = gui.element("addon_grid")?;
grid.change_position_unscaled(position.0, position.1)?; grid.change_position_unscaled(gui_handler, position.0, position.1)?;
icon.set_icon(&self.icon())?; icon.set_icon(gui_handler, &self.icon())?;
rarity_label.set_text(&format!("{}", self.rarity()))?; rarity_label.set_text(gui_handler, &format!("{}", self.rarity()))?;
type_label.set_text(&format!("{}", self.addon_type()))?; type_label.set_text(gui_handler, &format!("{}", self.addon_type()))?;
value_label.set_text(&self.addon_type().val_as_str())?; value_label.set_text(gui_handler, &self.addon_type().val_as_str())?;
Ok(Tooltip::new(grid, gui, gui_handler.clone())) Ok(Tooltip::new(grid, gui))
} }
} }

View file

@ -298,7 +298,7 @@ impl<A: Ability> AbilityBook<A> {
pub fn create_tooltip( pub fn create_tooltip(
&self, &self,
gui_handler: &Arc<GuiHandler>, gui_handler: &mut GuiHandler,
statistics: &Statistics, statistics: &Statistics,
position: (i32, i32), position: (i32, i32),
) -> Result<Tooltip> { ) -> Result<Tooltip> {
@ -314,32 +314,35 @@ impl<A: Ability> AbilityBook<A> {
let slot_info: Arc<Label> = gui.element("slot_info")?; let slot_info: Arc<Label> = gui.element("slot_info")?;
let level: Arc<Label> = gui.element("level")?; let level: Arc<Label> = gui.element("level")?;
inspector_grid.change_position_unscaled(position.0, position.1)?; inspector_grid.change_position_unscaled(gui_handler, position.0, position.1)?;
ability_icon.set_icon(&self.icon())?; ability_icon.set_icon(gui_handler, &self.icon())?;
ability_name.set_text(self.ability().name())?; ability_name.set_text(gui_handler, self.ability().name())?;
rarity_label.set_text(&format!("{}", self.rarity()))?; rarity_label.set_text(gui_handler, &format!("{}", self.rarity()))?;
level.set_text(&format!("Lvl: {}", self.level()))?; level.set_text(gui_handler, &format!("Lvl: {}", self.level()))?;
slot_info.set_text(&format!( slot_info.set_text(
"Slots: {}/{}", gui_handler,
self.attached_count(), &format!("Slots: {}/{}", self.attached_count(), self.addons().len()),
self.addons().len() )?;
))?;
let mana_costs: Arc<Label> = gui.element("mana_costs")?; let mana_costs: Arc<Label> = gui.element("mana_costs")?;
let damage: Arc<Label> = gui.element("damage")?; let damage: Arc<Label> = gui.element("damage")?;
let cooldown: Arc<Label> = gui.element("cooldown")?; let cooldown: Arc<Label> = gui.element("cooldown")?;
mana_costs.set_text(self.mana_cost())?; mana_costs.set_text(gui_handler, self.mana_cost())?;
damage.set_text(self.damage(statistics))?; damage.set_text(gui_handler, self.damage(statistics))?;
damage.set_text_color(self.ability.damage_type().into())?; damage.set_text_color(gui_handler, self.ability.damage_type().into())?;
cooldown.set_text(format!( cooldown.set_text(
"{:.1} s", gui_handler,
self.ability.cool_down().as_secs_f32() * (1.0 - self.addons().cool_down_reduction()) format!(
))?; "{:.1} s",
self.ability.cool_down().as_secs_f32()
* (1.0 - self.addons().cool_down_reduction())
),
)?;
Ok(Tooltip::new(inspector_grid, gui, gui_handler.clone())) Ok(Tooltip::new(inspector_grid, gui))
} }
} }

View file

@ -233,7 +233,7 @@ impl Item {
pub fn create_tooltip( pub fn create_tooltip(
&self, &self,
gui_handler: &Arc<GuiHandler>, gui_handler: &mut GuiHandler,
attributes: &Attributes, attributes: &Attributes,
position: (i32, i32), position: (i32, i32),
) -> Result<Tooltip> { ) -> Result<Tooltip> {
@ -251,15 +251,21 @@ impl Item {
let intelligence_field: Arc<Label> = inspector_snippet.element("intelligence_field")?; let intelligence_field: Arc<Label> = inspector_snippet.element("intelligence_field")?;
let inspector_grid: Arc<Grid> = inspector_snippet.element("item_grid")?; let inspector_grid: Arc<Grid> = inspector_snippet.element("item_grid")?;
inspector_grid.change_position_unscaled(position.0, position.1)?; inspector_grid.change_position_unscaled(gui_handler, position.0, position.1)?;
item_icon.set_icon(&self.icon)?; item_icon.set_icon(gui_handler, &self.icon)?;
slot_label.set_text(&format!("{}", self.slot))?; slot_label.set_text(gui_handler, &format!("{}", self.slot))?;
level_label.set_text(&format!("Lvl {}", self.level))?; level_label.set_text(gui_handler, &format!("Lvl {}", self.level))?;
rarity_label.set_text(&format!("{}", self.rarity))?; rarity_label.set_text(gui_handler, &format!("{}", self.rarity))?;
strength_field.set_text(&format!("{}", self.attributes.strength().raw()))?; strength_field.set_text(
agility_field.set_text(&format!("{}", self.attributes.agility().raw()))?; gui_handler,
intelligence_field.set_text(&format!("{}", self.attributes.intelligence().raw()))?; &format!("{}", self.attributes.strength().raw()),
)?;
agility_field.set_text(gui_handler, &format!("{}", self.attributes.agility().raw()))?;
intelligence_field.set_text(
gui_handler,
&format!("{}", self.attributes.intelligence().raw()),
)?;
let too_low_stat_background = FillTypeInfo::Element( let too_low_stat_background = FillTypeInfo::Element(
ElementDescriptor::new(Color::try_from("#AB7474")?, Color::try_from("#824040")?, 2), ElementDescriptor::new(Color::try_from("#AB7474")?, Color::try_from("#824040")?, 2),
@ -267,15 +273,15 @@ impl Item {
); );
if attributes.strength().raw() < self.attributes.strength().raw() { if attributes.strength().raw() < self.attributes.strength().raw() {
strength_field.set_background(too_low_stat_background.clone())?; strength_field.set_background(gui_handler, too_low_stat_background.clone())?;
} }
if attributes.agility().raw() < self.attributes.agility().raw() { if attributes.agility().raw() < self.attributes.agility().raw() {
agility_field.set_background(too_low_stat_background.clone())?; agility_field.set_background(gui_handler, too_low_stat_background.clone())?;
} }
if attributes.intelligence().raw() < self.attributes.intelligence().raw() { if attributes.intelligence().raw() < self.attributes.intelligence().raw() {
intelligence_field.set_background(too_low_stat_background)?; intelligence_field.set_background(gui_handler, too_low_stat_background)?;
} }
let mut index = Self::INSPECTOR_OFFSET; let mut index = Self::INSPECTOR_OFFSET;
@ -289,10 +295,10 @@ impl Item {
let stat_type_label: Arc<Label> = stat_type_snippet.element("stat_type")?; let stat_type_label: Arc<Label> = stat_type_snippet.element("stat_type")?;
let stat_value_label: Arc<Label> = stat_type_snippet.element("stat_value")?; let stat_value_label: Arc<Label> = stat_type_snippet.element("stat_value")?;
stat_type_label.set_text(&format!("{}", stat))?; stat_type_label.set_text(gui_handler, &format!("{}", stat))?;
stat_value_label.set_text(&stat.display_value())?; stat_value_label.set_text(gui_handler, &stat.display_value())?;
inspector_grid.attach(stat_type_snippet, 0, index, 1, 1)?; inspector_grid.attach(gui_handler, stat_type_snippet, 0, index, 1, 1)?;
index += 1; index += 1;
} }
@ -308,30 +314,27 @@ impl Item {
match jewel { match jewel {
Some(jewel) => { Some(jewel) => {
socket_icon.set_icon(&jewel.icon())?; socket_icon.set_icon(gui_handler, &jewel.icon())?;
stat_type.set_text(format!("{}", jewel.stat))?; stat_type.set_text(gui_handler, format!("{}", jewel.stat))?;
} }
None => { None => {
socket_icon.set_icon( socket_icon.set_icon(
gui_handler,
&Image::from_slice(include_bytes!("../../resources/circle.png"))? &Image::from_slice(include_bytes!("../../resources/circle.png"))?
.attach_pretty_sampler(gui_handler.device())? .attach_pretty_sampler(gui_handler.device())?
.build(gui_handler.device(), gui_handler.queue())?, .build(gui_handler.device(), gui_handler.queue())?,
)?; )?;
stat_type.set_text("Empty Socket")? stat_type.set_text(gui_handler, "Empty Socket")?
} }
} }
inspector_grid.attach(socket_snippet, 0, index, 1, 1)?; inspector_grid.attach(gui_handler, socket_snippet, 0, index, 1, 1)?;
index += 1; index += 1;
} }
Ok(Tooltip::new( Ok(Tooltip::new(inspector_grid, inspector_snippet))
inspector_grid,
inspector_snippet,
gui_handler.clone(),
))
} }
} }

View file

@ -1,5 +1,5 @@
use std::{ use std::{
str::{from_utf8, FromStr}, str::{FromStr, from_utf8},
sync::Arc, sync::Arc,
}; };
@ -60,7 +60,7 @@ impl Jewel {
pub fn create_tooltip( pub fn create_tooltip(
&self, &self,
gui_handler: &Arc<GuiHandler>, gui_handler: &mut GuiHandler,
item_settings: &ItemSettings, item_settings: &ItemSettings,
position: (i32, i32), position: (i32, i32),
) -> Result<Tooltip> { ) -> Result<Tooltip> {
@ -70,7 +70,7 @@ impl Jewel {
)?; )?;
let main_grid: Arc<Grid> = inspector_snippet.element("main_grid")?; let main_grid: Arc<Grid> = inspector_snippet.element("main_grid")?;
main_grid.change_position_unscaled(position.0, position.1)?; main_grid.change_position_unscaled(gui_handler, position.0, position.1)?;
let jewel_icon: Arc<Icon> = inspector_snippet.element("jewel_icon")?; let jewel_icon: Arc<Icon> = inspector_snippet.element("jewel_icon")?;
let rarity_label: Arc<Label> = inspector_snippet.element("rarity_label")?; let rarity_label: Arc<Label> = inspector_snippet.element("rarity_label")?;
@ -81,10 +81,10 @@ impl Jewel {
let stat_type: Arc<Label> = inspector_snippet.element("stat_type")?; let stat_type: Arc<Label> = inspector_snippet.element("stat_type")?;
let stat_value: Arc<Label> = inspector_snippet.element("stat_value")?; let stat_value: Arc<Label> = inspector_snippet.element("stat_value")?;
jewel_icon.set_icon(&self.icon())?; jewel_icon.set_icon(gui_handler, &self.icon())?;
rarity_label.set_text(format!("{} ({})", self.rarity, self.level))?; rarity_label.set_text(gui_handler, format!("{} ({})", self.rarity, self.level))?;
attribute_type.set_text({ attribute_type.set_text(gui_handler, {
let mut s = self.attribute.to_string(); let mut s = self.attribute.to_string();
s.replace_range( s.replace_range(
0..1, 0..1,
@ -95,6 +95,7 @@ impl Jewel {
})?; })?;
attribute_value.set_text( attribute_value.set_text(
gui_handler,
item_settings item_settings
.jewel_rarity_multiplier .jewel_rarity_multiplier
.from_rarity(self.rarity) .from_rarity(self.rarity)
@ -102,14 +103,10 @@ impl Jewel {
* item_settings.general.jewel_level_multiplier, * item_settings.general.jewel_level_multiplier,
)?; )?;
stat_type.set_text(&self.stat)?; stat_type.set_text(gui_handler, &self.stat)?;
stat_value.set_text(self.stat.display_value())?; stat_value.set_text(gui_handler, self.stat.display_value())?;
Ok(Tooltip::new( Ok(Tooltip::new(main_grid, inspector_snippet))
main_grid,
inspector_snippet,
gui_handler.clone(),
))
} }
} }

View file

@ -1,4 +1,4 @@
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use engine::prelude::*; use engine::prelude::*;
use std::sync::Arc; use std::sync::Arc;
@ -11,23 +11,21 @@ pub struct FittingResult {
pub struct Tooltip { pub struct Tooltip {
grid: Arc<Grid>, grid: Arc<Grid>,
gui: Arc<GuiBuilder>, gui: Arc<GuiBuilder>,
gui_handler: Arc<GuiHandler>,
} }
impl Tooltip { impl Tooltip {
pub fn new(grid: Arc<Grid>, gui: Arc<GuiBuilder>, gui_handler: Arc<GuiHandler>) -> Self { pub fn new(grid: Arc<Grid>, gui: Arc<GuiBuilder>) -> Self {
Self { Self { grid, gui }
grid,
gui,
gui_handler,
}
} }
pub fn enable(&self) -> Result<()> { pub fn enable(&self, gui_handler: &mut GuiHandler) -> Result<()> {
self.gui.enable() self.gui.enable(gui_handler)
} }
pub fn check_fitting(&self) -> Result<(FittingResult, FittingResult)> { pub fn check_fitting(
&self,
gui_handler: &GuiHandler,
) -> Result<(FittingResult, FittingResult)> {
if !self.grid.visible() { if !self.grid.visible() {
bail!("enable item tooltip first"); bail!("enable item tooltip first");
} }
@ -36,28 +34,28 @@ impl Tooltip {
Ok(( Ok((
FittingResult { FittingResult {
fit: (x + w as i32) <= self.gui_handler.width() as i32, fit: (x + w as i32) <= gui_handler.width() as i32,
start: x, start: x,
extent: w, extent: w,
}, },
FittingResult { FittingResult {
fit: (y + h as i32) <= self.gui_handler.height() as i32, fit: (y + h as i32) <= gui_handler.height() as i32,
start: y, start: y,
extent: h, extent: h,
}, },
)) ))
} }
pub fn move_to(&self, x: i32, y: i32) -> Result<()> { pub fn move_to(&self, gui_handler: &mut GuiHandler, x: i32, y: i32) -> Result<()> {
self.grid.change_position_unscaled(x, y) self.grid.change_position_unscaled(gui_handler, x, y)
} }
pub fn position_extent(&self) -> (i32, i32, u32, u32) { pub fn position_extent(&self) -> (i32, i32, u32, u32) {
self.grid.position_extent() self.grid.position_extent()
} }
pub fn perform_single_check(&self, x: i32, y: i32) -> Result<()> { pub fn perform_single_check(&self, gui_handler: &mut GuiHandler, x: i32, y: i32) -> Result<()> {
let (width_fitting, height_fitting) = self.check_fitting()?; let (width_fitting, height_fitting) = self.check_fitting(gui_handler)?;
let mut width_shift = None; let mut width_shift = None;
let mut height_shift = None; let mut height_shift = None;
@ -74,6 +72,7 @@ impl Tooltip {
if width_shift.is_some() || height_shift.is_some() { if width_shift.is_some() || height_shift.is_some() {
self.move_to( self.move_to(
gui_handler,
width_shift.unwrap_or(gui_pos.0), width_shift.unwrap_or(gui_pos.0),
height_shift.unwrap_or(gui_pos.1), height_shift.unwrap_or(gui_pos.1),
)?; )?;
@ -82,9 +81,15 @@ impl Tooltip {
Ok(()) Ok(())
} }
pub fn perform_double_check(&self, other: &Self, x: i32, spacing: u32) -> Result<()> { pub fn perform_double_check(
let (_left_width_fitting, left_height_fitting) = self.check_fitting()?; &self,
let (right_width_fitting, right_height_fitting) = other.check_fitting()?; other: &Self,
gui_handler: &mut GuiHandler,
x: i32,
spacing: u32,
) -> Result<()> {
let (_left_width_fitting, left_height_fitting) = self.check_fitting(gui_handler)?;
let (right_width_fitting, right_height_fitting) = other.check_fitting(gui_handler)?;
let mut width_shift = None; let mut width_shift = None;
let mut height_shift = None; let mut height_shift = None;
@ -96,7 +101,7 @@ impl Tooltip {
width_shift = Some(x - right_gui_pos.2 as i32 - spacing as i32); width_shift = Some(x - right_gui_pos.2 as i32 - spacing as i32);
} }
let window_height = self.gui_handler.height(); let window_height = gui_handler.height();
if !left_height_fitting.fit { if !left_height_fitting.fit {
height_shift = Some(window_height as i32 - left_gui_pos.3 as i32 - spacing as i32); height_shift = Some(window_height as i32 - left_gui_pos.3 as i32 - spacing as i32);
@ -121,8 +126,12 @@ impl Tooltip {
let width = width_shift.unwrap_or(right_gui_pos.0); let width = width_shift.unwrap_or(right_gui_pos.0);
let height = height_shift.unwrap_or(right_gui_pos.1); let height = height_shift.unwrap_or(right_gui_pos.1);
other.move_to(width, height)?; other.move_to(gui_handler, width, height)?;
self.move_to(width - spacing as i32 - left_gui_pos.2 as i32, height)?; self.move_to(
gui_handler,
width - spacing as i32 - left_gui_pos.2 as i32,
height,
)?;
} }
Ok(()) Ok(())