use std::sync::{Arc, Weak}; use rpg_components::components::ability_slots::AbilitySlots; use rpg_components::components::inventory::{Inventory, Storable}; use rpg_components::components::statistics::Statistics; use rpg_components::items::ability_addon::AbilityAddon; use rpg_components::items::ability_book::AbilityBook; use crate::*; use crate::{ CharacterWindow, content::{Content, ContentUpdate}, }; use super::AbilityPage; impl Content { fn show_addon_tooltip( world: &mut World, hero: Entity, addon_index: usize, reference: &Weak, (x, y, w, _h): (i32, i32, u32, u32), ) -> Result<()> { let entity = unsafe { remove_life_time(world.entity(hero)?) }; let inventory = entity.get_component::>()?; let target_x = x + w as i32; let target_y = y; let addon = inventory.addon_at(addon_index); let gui = addon.create_tooltip(world, (target_x, target_y))?; gui.enable(world)?; gui.perform_single_check(world.resources.get_mut::(), x, y)?; let window = reference.upgrade().unwrap(); window.add_tooltip(format!("addon_{addon_index}"), gui); Ok(()) } fn insert_addon( world: &mut World, hero: Entity, addon_index: usize, ability_page: &AbilityPage, ) -> Result<()> { let entity = world.entity_mut(hero)?; let mut multi_mut = entity.multi_mut(); let inventory = multi_mut.get::>()?; let abilities = multi_mut.get::>()?; if let Some(book) = abilities.book_mut(ability_page.right_side.selected_ability()) { if book.has_free_addon_slots() { book.addons_mut() .insert_addon(inventory.remove_addon(addon_index)); } } Ok(()) } } impl ContentUpdate for Content { fn update(&mut self, world: &mut World, hero: Entity) -> Result<()> { let reference = self.reference.clone(); self.update_base(world, |world, button, t, index| { button.set_icon(world.resources.get_mut::(), &t.icon())?; button.set_custom_callback({ let reference = reference.clone(); move |world, controller_button| { if let ControllerButton::X = controller_button { CharacterWindow::salvage_from_inventory::( world, hero, |inventory| inventory.remove_addon(index), )?; if let Some(menu) = reference.upgrade() { let mut tabs = menu.tabs_mut(); let abilities = tabs.abilities::(); abilities.update_page(world)?; } return Ok(true); } Ok(false) } }); button.set_callback({ let reference = reference.clone(); move |world| { if let Some(menu) = reference.upgrade() { let mut tabs = menu.tabs_mut(); let abilities = tabs.abilities(); Self::insert_addon(world, hero, index, abilities)?; abilities.update_page(world)?; } Ok(()) } }); button.set_select_callback({ let weak_button = Arc::downgrade(&button); let reference = reference.clone(); move |world, selected| { if selected { let button_pos = weak_button.upgrade().unwrap().position_extent(); Self::show_addon_tooltip(world, hero, index, &reference, button_pos)?; } else { let window = reference.upgrade().unwrap(); window.remove_tooltip(format!("addon_{index}")); } Ok(()) } }); Ok(()) }) } fn select(&self, world: &mut World) -> Result<()> { self.select(world.resources.get_mut::()) } } impl Content> { fn equip_book( world: &mut World, hero: Entity, book_index: usize, ability_page: &AbilityPage, ) -> Result<()> { let entity = world.entity_mut(hero)?; let mut multi_mut = entity.multi_mut(); let inventory = multi_mut.get::>()?; let abilitiy_slots = multi_mut.get::>()?; if let Some(old_book) = abilitiy_slots.insert_book( inventory.remove_book(book_index), ability_page.right_side.selected_ability(), ) { inventory.insert_book(old_book, book_index); } Ok(()) } fn show_book_tooltip( world: &mut World, hero: Entity, book_index: usize, reference: &Weak, (x, y, w, _h): (i32, i32, u32, u32), ) -> Result<()> { let entity = unsafe { remove_life_time(world.entity(hero)?) }; let inventory = entity.get_component::>()?; let statistics = entity.get_component::()?; let target_x = x + w as i32; let target_y = y; let book = inventory.book_at(book_index); let gui = book.create_tooltip(world, statistics, (target_x, target_y))?; gui.enable(world)?; let window = reference.upgrade().unwrap(); let abilities = entity.get_component::>()?; match abilities.book(window.tabs().abilities::().right_side.selected_ability()) { Some(selected_book) => { let button_pos = gui.position_extent(); let target_x = button_pos.0 + button_pos.2 as i32 + 2; let target_y = button_pos.1; let compare_gui = selected_book.create_tooltip(world, statistics, (target_x, target_y))?; compare_gui.enable(world)?; gui.perform_double_check( &compare_gui, world.resources.get_mut::(), x, 2, )?; window.add_tooltip("active_book", compare_gui); } None => { gui.perform_single_check(world.resources.get_mut::(), x, y)?; } } window.add_tooltip(format!("book_{book_index}"), gui); Ok(()) } } impl ContentUpdate for Content> { fn update(&mut self, world: &mut World, hero: Entity) -> Result<()> { let reference = self.reference.clone(); self.update_base(world, |world, button, t, index| { button.set_icon(world.resources.get_mut::(), &t.icon())?; button.set_custom_callback({ let reference = reference.clone(); move |world, controller_button| { if let ControllerButton::X = controller_button { CharacterWindow::salvage_from_inventory::( world, hero, |inventory| inventory.remove_book(index), )?; if let Some(menu) = reference.upgrade() { let mut tabs = menu.tabs_mut(); let abilities = tabs.abilities::(); abilities.update_page(world)?; } return Ok(true); } Ok(false) } }); button.set_callback({ let reference = reference.clone(); move |world| { if let Some(menu) = reference.upgrade() { let mut tabs = menu.tabs_mut(); let abilities = tabs.abilities(); Self::equip_book(world, hero, index, abilities)?; abilities.update_page(world)?; } Ok(()) } }); button.set_select_callback({ let weak_button = Arc::downgrade(&button); let reference = reference.clone(); move |world, selected| { if selected { let button_pos = weak_button.upgrade().unwrap().position_extent(); Self::show_book_tooltip(world, hero, index, &reference, button_pos)?; } else { let window = reference.upgrade().unwrap(); window.remove_tooltip(format!("book_{index}")); window.remove_tooltip("active_book"); } Ok(()) } }); Ok(()) }) } fn select(&self, world: &mut World) -> Result<()> { self.select(world.resources.get_mut::()) } }