307 lines
9.6 KiB
Rust
307 lines
9.6 KiB
Rust
|
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<A: Ability + 'static> Content<A, AbilityAddon> {
|
||
|
fn show_addon_tooltip(
|
||
|
engine: &Arc<Engine>,
|
||
|
hero: Entity,
|
||
|
addon_index: usize,
|
||
|
reference: &Weak<CharacterWindow>,
|
||
|
(x, y, w, _h): (i32, i32, u32, u32),
|
||
|
) -> Result<()> {
|
||
|
engine.on_scene(|scene| {
|
||
|
let entity = scene.entity(hero)?;
|
||
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||
|
|
||
|
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<Engine>,
|
||
|
hero: Entity,
|
||
|
addon_index: usize,
|
||
|
ability_page: &AbilityPage<A>,
|
||
|
) -> Result<()> {
|
||
|
engine.on_scene_mut(|scene| {
|
||
|
let entity = scene.entity_mut(hero)?;
|
||
|
let mut multi_mut = entity.multi_mut();
|
||
|
|
||
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||
|
let abilities = multi_mut.get::<AbilitySlots<A>>()?;
|
||
|
|
||
|
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<A: Ability + 'static> ContentUpdate for Content<A, AbilityAddon> {
|
||
|
fn update(&mut self, engine: &Arc<Engine>, 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::<A, _, _>(
|
||
|
&engine,
|
||
|
hero,
|
||
|
|inventory| inventory.remove_addon(index),
|
||
|
)?;
|
||
|
|
||
|
if let Some(menu) = reference.upgrade() {
|
||
|
let mut tabs = menu.tabs_mut();
|
||
|
let abilities = tabs.abilities::<A>();
|
||
|
|
||
|
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<A: Ability + 'static> Content<A, AbilityBook<A>> {
|
||
|
fn equip_book(
|
||
|
engine: &Arc<Engine>,
|
||
|
hero: Entity,
|
||
|
book_index: usize,
|
||
|
ability_page: &AbilityPage<A>,
|
||
|
) -> Result<()> {
|
||
|
engine.on_scene_mut(|scene| {
|
||
|
let entity = scene.entity_mut(hero)?;
|
||
|
let mut multi_mut = entity.multi_mut();
|
||
|
|
||
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||
|
let abilitiy_slots = multi_mut.get::<AbilitySlots<A>>()?;
|
||
|
|
||
|
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<Engine>,
|
||
|
hero: Entity,
|
||
|
book_index: usize,
|
||
|
reference: &Weak<CharacterWindow>,
|
||
|
(x, y, w, _h): (i32, i32, u32, u32),
|
||
|
) -> Result<()> {
|
||
|
engine.on_scene(|scene| {
|
||
|
let entity = scene.entity(hero)?;
|
||
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||
|
let statistics = entity.get_component::<Statistics>()?;
|
||
|
|
||
|
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::<AbilitySlots<A>>()?;
|
||
|
|
||
|
match abilities.book(window.tabs().abilities::<A>().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<A: Ability + 'static> ContentUpdate for Content<A, AbilityBook<A>> {
|
||
|
fn update(&mut self, engine: &Arc<Engine>, 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::<A, _, _>(
|
||
|
&engine,
|
||
|
hero,
|
||
|
|inventory| inventory.remove_book(index),
|
||
|
)?;
|
||
|
|
||
|
if let Some(menu) = reference.upgrade() {
|
||
|
let mut tabs = menu.tabs_mut();
|
||
|
let abilities = tabs.abilities::<A>();
|
||
|
|
||
|
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()
|
||
|
}
|
||
|
}
|