use rpg_components::{ components::{ attributes::Attributes, character_status::CharacterStatus, inventory::Inventory, item_slots::ItemSlotContainer, statistics::Statistics, }, config::{attributes::AttributeSettings, items::ItemSettings}, items::{Item, ItemAffix, Tooltip}, }; use crate::*; use std::sync::{Arc, Weak}; use super::{ super::traits::*, jewel_right_side::{ReferenceItemSource, ReferenceObject}, }; pub struct ItemRightSide { snippet: Arc, empty_icons: InventoryEmptyIcons, } impl ItemRightSide { pub fn new( engine: &Arc, file: &str, reference: &Weak, hero: Entity, ) -> Result { let snippet = GuiSnippet::from_str(engine.gui_handler(), file)?; let icons = InventoryEmptyIcons::new(engine)?; let me = Self { snippet, empty_icons: icons, }; me.setup::(engine, reference, hero)?; Ok(me) } fn setup( &self, engine: &Arc, reference: &Weak, hero: Entity, ) -> Result<()> { button_setup!(self, engine, reference, hero, helmet, "helmet"); button_setup!(self, engine, reference, hero, chest, "chest"); button_setup!(self, engine, reference, hero, gloves, "gloves"); button_setup!(self, engine, reference, hero, belt, "belt"); button_setup!(self, engine, reference, hero, boots, "boots"); #[rustfmt::skip] button_setup!(self, engine, reference, hero, primary_hand, "main hand"); #[rustfmt::skip] button_setup!(self, engine, reference, hero, secondary_hand, "off hand"); #[rustfmt::skip] button_setup!(self, engine, reference, hero, amulet, "amulet_0", 0); #[rustfmt::skip] button_setup!(self, engine, reference, hero, amulet, "amulet_1", 1); #[rustfmt::skip] button_setup!(self, engine, reference, hero, ring, "ring_0", 0); #[rustfmt::skip] button_setup!(self, engine, reference, hero, ring, "ring_1", 1); #[rustfmt::skip] button_setup!(self, engine, reference, hero, ring, "ring_2", 2); #[rustfmt::skip] button_setup!(self, engine, reference, hero, ring, "ring_3", 3); Ok(()) } fn update_icons(&self, items: &ItemSlotContainer) -> Result<()> { let ui = &self.snippet; let empty_icons = &self.empty_icons; equip_update!(ui, items, helmet, empty_icons); equip_update!(ui, items, chest, empty_icons); equip_update!(ui, items, boots, empty_icons); equip_update!(ui, items, gloves, empty_icons); equip_update!(ui, items, belt, empty_icons); equip_update!(ui, items, primary_hand, empty_icons, "main hand"); equip_update!(ui, items, secondary_hand, empty_icons, "off hand"); equip_update!(ui, items, ring, empty_icons, "ring_0", 0); equip_update!(ui, items, ring, empty_icons, "ring_1", 1); equip_update!(ui, items, ring, empty_icons, "ring_2", 2); equip_update!(ui, items, ring, empty_icons, "ring_3", 3); equip_update!(ui, items, amulet, empty_icons, "amulet_0", 0); equip_update!(ui, items, amulet, empty_icons, "amulet_1", 1); Ok(()) } fn create_tooltip( engine: &Arc, item: &Item, attributes: &Attributes, (x, y, w, _h): (i32, i32, u32, u32), ) -> Result { let target_x = x + w as i32; let target_y = y; let gui = item.create_tooltip(engine.gui_handler(), attributes, (target_x, target_y))?; gui.enable()?; gui.perform_single_check(x, y)?; Ok(gui) } } impl RightSide for ItemRightSide { fn refresh(&mut self, engine: &Engine, hero: Entity) -> Result<()> { engine.on_scene(|scene| { let hero_object = scene.entity(hero)?; let items = hero_object.get_component::()?; self.update_icons(items)?; Ok(()) })?; Ok(()) } fn base(&self) -> &Arc { &self.snippet } } struct InventoryEmptyIcons { helmet: Arc, chest: Arc, belt: Arc, boots: Arc, gloves: Arc, primary_hand: Arc, secondary_hand: Arc, ring: Arc, amulet: Arc, } impl InventoryEmptyIcons { fn new(engine: &Engine) -> Result { let place_holder_settings = &engine .scene() .resources .get::() .icon_place_holder_paths; Ok(Self { helmet: Image::from_file(place_holder_settings.helmet.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, chest: Image::from_file(place_holder_settings.chest.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, belt: Image::from_file(place_holder_settings.belt.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, boots: Image::from_file(place_holder_settings.boots.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, gloves: Image::from_file(place_holder_settings.gloves.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, primary_hand: Image::from_file(place_holder_settings.main_hand.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, secondary_hand: Image::from_file(place_holder_settings.off_hand.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, ring: Image::from_file(place_holder_settings.ring.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, amulet: Image::from_file(place_holder_settings.amulet.clone())? .attach_sampler(Sampler::pretty_sampler().build(engine.device())?) .build(engine.device(), engine.queue())?, }) } } mod macros { #[macro_export] macro_rules! button_setup { ($self:ident, $engine:ident, $reference:ident, $hero:ident, $item:ident, $button:literal) => { paste::expr! { let [<$item _button>]: Arc