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::{ content::{Content, ContentUpdate}, CharacterWindow, }; use super::AbilityPage; impl Content { fn show_addon_tooltip( engine: &Arc, hero: Entity, addon_index: usize, reference: &Weak, (x, y, w, _h): (i32, i32, u32, u32), ) -> Result<()> { engine.on_scene(|scene| { let entity = scene.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(engine.gui_handler(), (target_x, target_y))?; gui.enable()?; gui.perform_single_check(x, y)?; let window = reference.upgrade().unwrap(); window.add_tooltip(format!("addon_{addon_index}"), gui); Ok(()) }) } fn insert_addon( engine: &Arc, hero: Entity, addon_index: usize, ability_page: &AbilityPage, ) -> Result<()> { engine.on_scene_mut(|scene| { let entity = scene.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, engine: &Arc, hero: Entity) -> Result<()> { let reference = self.reference.clone(); self.update_base(engine, |button, t, index| { button.set_icon(&t.icon())?; button.set_custom_callback({ let engine = engine.clone(); let reference = reference.clone(); move |controller_button| { if let ControllerButton::X = controller_button { CharacterWindow::salvage_from_inventory::( &engine, 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()?; } return Ok(true); } Ok(false) } }); button.set_callback({ let engine = engine.clone(); let reference = reference.clone(); move || { if let Some(menu) = reference.upgrade() { let mut tabs = menu.tabs_mut(); let abilities = tabs.abilities(); Self::insert_addon(&engine, hero, index, abilities)?; abilities.update_page()?; } Ok(()) } }); button.set_select_callback({ let weak_button = Arc::downgrade(&button); let engine = engine.clone(); let reference = reference.clone(); move |selected| { if selected { let button_pos = weak_button.upgrade().unwrap().position_extent(); Self::show_addon_tooltip(&engine, hero, index, &reference, button_pos)?; } else { let window = reference.upgrade().unwrap(); window.remove_tooltip(format!("addon_{index}")); } Ok(()) } }); Ok(()) }) } fn select(&self) -> Result<()> { self.select() } } impl Content> { fn equip_book( engine: &Arc, hero: Entity, book_index: usize, ability_page: &AbilityPage, ) -> Result<()> { engine.on_scene_mut(|scene| { let entity = scene.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( engine: &Arc, hero: Entity, book_index: usize, reference: &Weak, (x, y, w, _h): (i32, i32, u32, u32), ) -> Result<()> { engine.on_scene(|scene| { let entity = scene.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(engine.gui_handler(), statistics, (target_x, target_y))?; gui.enable()?; 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( engine.gui_handler(), statistics, (target_x, target_y), )?; compare_gui.enable()?; gui.perform_double_check(&compare_gui, x, 2)?; window.add_tooltip("active_book", compare_gui); } None => { gui.perform_single_check(x, y)?; } } window.add_tooltip(format!("book_{book_index}"), gui); Ok(()) }) } } impl ContentUpdate for Content> { fn update(&mut self, engine: &Arc, hero: Entity) -> Result<()> { let reference = self.reference.clone(); self.update_base(engine, |button, t, index| { button.set_icon(&t.icon())?; button.set_custom_callback({ let engine = engine.clone(); let reference = reference.clone(); move |controller_button| { if let ControllerButton::X = controller_button { CharacterWindow::salvage_from_inventory::( &engine, 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()?; } return Ok(true); } Ok(false) } }); button.set_callback({ let engine = engine.clone(); let reference = reference.clone(); move || { if let Some(menu) = reference.upgrade() { let mut tabs = menu.tabs_mut(); let abilities = tabs.abilities(); Self::equip_book(&engine, hero, index, abilities)?; abilities.update_page()?; } Ok(()) } }); button.set_select_callback({ let weak_button = Arc::downgrade(&button); let engine = engine.clone(); let reference = reference.clone(); move |selected| { if selected { let button_pos = weak_button.upgrade().unwrap().position_extent(); Self::show_book_tooltip(&engine, 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) -> Result<()> { self.select() } }