rpg_base/character_window/src/abilities/content.rs

294 lines
9.3 KiB
Rust
Raw Normal View History

2025-02-28 07:43:35 +00:00
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,
2025-03-05 09:31:16 +00:00
content::{Content, ContentUpdate},
2025-02-28 07:43:35 +00:00
};
use super::AbilityPage;
impl<A: Ability + 'static> Content<A, AbilityAddon> {
fn show_addon_tooltip(
2025-03-05 09:31:16 +00:00
world: &mut World,
2025-02-28 07:43:35 +00:00
hero: Entity,
addon_index: usize,
reference: &Weak<CharacterWindow>,
(x, y, w, _h): (i32, i32, u32, u32),
) -> Result<()> {
2025-03-05 09:31:16 +00:00
let entity = unsafe { remove_life_time(world.entity(hero)?) };
let inventory = entity.get_component::<Inventory<A>>()?;
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
let target_x = x + w as i32;
let target_y = y;
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
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::<GuiHandler>(), x, y)?;
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
let window = reference.upgrade().unwrap();
window.add_tooltip(format!("addon_{addon_index}"), gui);
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
Ok(())
2025-02-28 07:43:35 +00:00
}
fn insert_addon(
2025-03-05 09:31:16 +00:00
world: &mut World,
2025-02-28 07:43:35 +00:00
hero: Entity,
addon_index: usize,
ability_page: &AbilityPage<A>,
) -> Result<()> {
2025-03-05 09:31:16 +00:00
let entity = world.entity_mut(hero)?;
let mut multi_mut = entity.multi_mut();
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
let inventory = multi_mut.get::<Inventory<A>>()?;
let abilities = multi_mut.get::<AbilitySlots<A>>()?;
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
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));
2025-02-28 07:43:35 +00:00
}
2025-03-05 09:31:16 +00:00
}
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
Ok(())
2025-02-28 07:43:35 +00:00
}
}
impl<A: Ability + 'static> ContentUpdate for Content<A, AbilityAddon> {
2025-03-05 09:31:16 +00:00
fn update(&mut self, world: &mut World, hero: Entity) -> Result<()> {
2025-02-28 07:43:35 +00:00
let reference = self.reference.clone();
2025-03-05 09:31:16 +00:00
self.update_base(world, |world, button, t, index| {
button.set_icon(world.resources.get_mut::<GuiHandler>(), &t.icon())?;
2025-02-28 07:43:35 +00:00
button.set_custom_callback({
let reference = reference.clone();
2025-03-05 09:31:16 +00:00
move |world, controller_button| {
2025-02-28 07:43:35 +00:00
if let ControllerButton::X = controller_button {
CharacterWindow::salvage_from_inventory::<A, _, _>(
2025-03-05 09:31:16 +00:00
world,
2025-02-28 07:43:35 +00:00
hero,
|inventory| inventory.remove_addon(index),
)?;
if let Some(menu) = reference.upgrade() {
let mut tabs = menu.tabs_mut();
let abilities = tabs.abilities::<A>();
2025-03-05 09:31:16 +00:00
abilities.update_page(world)?;
2025-02-28 07:43:35 +00:00
}
return Ok(true);
}
Ok(false)
}
});
button.set_callback({
let reference = reference.clone();
2025-03-05 09:31:16 +00:00
move |world| {
2025-02-28 07:43:35 +00:00
if let Some(menu) = reference.upgrade() {
let mut tabs = menu.tabs_mut();
let abilities = tabs.abilities();
2025-03-05 09:31:16 +00:00
Self::insert_addon(world, hero, index, abilities)?;
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
abilities.update_page(world)?;
2025-02-28 07:43:35 +00:00
}
Ok(())
}
});
button.set_select_callback({
let weak_button = Arc::downgrade(&button);
let reference = reference.clone();
2025-03-05 09:31:16 +00:00
move |world, selected| {
2025-02-28 07:43:35 +00:00
if selected {
let button_pos = weak_button.upgrade().unwrap().position_extent();
2025-03-05 09:31:16 +00:00
Self::show_addon_tooltip(world, hero, index, &reference, button_pos)?;
2025-02-28 07:43:35 +00:00
} else {
let window = reference.upgrade().unwrap();
window.remove_tooltip(format!("addon_{index}"));
}
Ok(())
}
});
Ok(())
})
}
2025-03-05 09:31:16 +00:00
fn select(&self, world: &mut World) -> Result<()> {
self.select(world.resources.get_mut::<GuiHandler>())
2025-02-28 07:43:35 +00:00
}
}
impl<A: Ability + 'static> Content<A, AbilityBook<A>> {
fn equip_book(
2025-03-05 09:31:16 +00:00
world: &mut World,
2025-02-28 07:43:35 +00:00
hero: Entity,
book_index: usize,
ability_page: &AbilityPage<A>,
) -> Result<()> {
2025-03-05 09:31:16 +00:00
let entity = world.entity_mut(hero)?;
let mut multi_mut = entity.multi_mut();
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
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(())
2025-02-28 07:43:35 +00:00
}
fn show_book_tooltip(
2025-03-05 09:31:16 +00:00
world: &mut World,
2025-02-28 07:43:35 +00:00
hero: Entity,
book_index: usize,
reference: &Weak<CharacterWindow>,
(x, y, w, _h): (i32, i32, u32, u32),
) -> Result<()> {
2025-03-05 09:31:16 +00:00
let entity = unsafe { remove_life_time(world.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(world, statistics, (target_x, target_y))?;
gui.enable(world)?;
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(world, statistics, (target_x, target_y))?;
compare_gui.enable(world)?;
gui.perform_double_check(
&compare_gui,
world.resources.get_mut::<GuiHandler>(),
x,
2,
)?;
window.add_tooltip("active_book", compare_gui);
}
None => {
gui.perform_single_check(world.resources.get_mut::<GuiHandler>(), x, y)?;
2025-02-28 07:43:35 +00:00
}
2025-03-05 09:31:16 +00:00
}
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
window.add_tooltip(format!("book_{book_index}"), gui);
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
Ok(())
2025-02-28 07:43:35 +00:00
}
}
impl<A: Ability + 'static> ContentUpdate for Content<A, AbilityBook<A>> {
2025-03-05 09:31:16 +00:00
fn update(&mut self, world: &mut World, hero: Entity) -> Result<()> {
2025-02-28 07:43:35 +00:00
let reference = self.reference.clone();
2025-03-05 09:31:16 +00:00
self.update_base(world, |world, button, t, index| {
button.set_icon(world.resources.get_mut::<GuiHandler>(), &t.icon())?;
2025-02-28 07:43:35 +00:00
button.set_custom_callback({
let reference = reference.clone();
2025-03-05 09:31:16 +00:00
move |world, controller_button| {
2025-02-28 07:43:35 +00:00
if let ControllerButton::X = controller_button {
CharacterWindow::salvage_from_inventory::<A, _, _>(
2025-03-05 09:31:16 +00:00
world,
2025-02-28 07:43:35 +00:00
hero,
|inventory| inventory.remove_book(index),
)?;
if let Some(menu) = reference.upgrade() {
let mut tabs = menu.tabs_mut();
let abilities = tabs.abilities::<A>();
2025-03-05 09:31:16 +00:00
abilities.update_page(world)?;
2025-02-28 07:43:35 +00:00
}
return Ok(true);
}
Ok(false)
}
});
button.set_callback({
let reference = reference.clone();
2025-03-05 09:31:16 +00:00
move |world| {
2025-02-28 07:43:35 +00:00
if let Some(menu) = reference.upgrade() {
let mut tabs = menu.tabs_mut();
let abilities = tabs.abilities();
2025-03-05 09:31:16 +00:00
Self::equip_book(world, hero, index, abilities)?;
2025-02-28 07:43:35 +00:00
2025-03-05 09:31:16 +00:00
abilities.update_page(world)?;
2025-02-28 07:43:35 +00:00
}
Ok(())
}
});
button.set_select_callback({
let weak_button = Arc::downgrade(&button);
let reference = reference.clone();
2025-03-05 09:31:16 +00:00
move |world, selected| {
2025-02-28 07:43:35 +00:00
if selected {
let button_pos = weak_button.upgrade().unwrap().position_extent();
2025-03-05 09:31:16 +00:00
Self::show_book_tooltip(world, hero, index, &reference, button_pos)?;
2025-02-28 07:43:35 +00:00
} else {
let window = reference.upgrade().unwrap();
window.remove_tooltip(format!("book_{index}"));
window.remove_tooltip("active_book");
}
Ok(())
}
});
Ok(())
})
}
2025-03-05 09:31:16 +00:00
fn select(&self, world: &mut World) -> Result<()> {
self.select(world.resources.get_mut::<GuiHandler>())
2025-02-28 07:43:35 +00:00
}
}