Use generic ability
This commit is contained in:
parent
fc409187df
commit
8e2ed3e5c2
28 changed files with 262 additions and 274 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use rpg_components::components::ability_slots::AbilitySlots;
|
use rpg_components::components::ability_slots::AbilitySlots;
|
||||||
|
@ -11,13 +12,15 @@ use crate::*;
|
||||||
|
|
||||||
use crate::{traits::RightSide, CharacterWindow};
|
use crate::{traits::RightSide, CharacterWindow};
|
||||||
|
|
||||||
pub struct AbilityPageRightSide {
|
pub struct AbilityPageRightSide<A: Ability + 'static> {
|
||||||
snippet: Arc<GuiSnippet>,
|
snippet: Arc<GuiSnippet>,
|
||||||
|
|
||||||
ability_index: usize,
|
ability_index: usize,
|
||||||
|
|
||||||
|
ability_marker: PhantomData<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbilityPageRightSide {
|
impl<A: Ability + 'static> AbilityPageRightSide<A> {
|
||||||
const ABILITY_BUTTON_NAMES: [&'static str; 4] = [
|
const ABILITY_BUTTON_NAMES: [&'static str; 4] = [
|
||||||
"first_ability",
|
"first_ability",
|
||||||
"second_ability",
|
"second_ability",
|
||||||
|
@ -59,7 +62,7 @@ impl AbilityPageRightSide {
|
||||||
move || {
|
move || {
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let abilities = tabs.abilities();
|
let abilities = tabs.abilities::<A>();
|
||||||
|
|
||||||
abilities.right_side.ability_index = index;
|
abilities.right_side.ability_index = index;
|
||||||
abilities.update_page()?;
|
abilities.update_page()?;
|
||||||
|
@ -79,7 +82,7 @@ impl AbilityPageRightSide {
|
||||||
if selected {
|
if selected {
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
let abilities = entity.get_component::<AbilitySlots>()?;
|
let abilities = entity.get_component::<AbilitySlots<A>>()?;
|
||||||
|
|
||||||
if let Some(book) = abilities.book(index) {
|
if let Some(book) = abilities.book(index) {
|
||||||
let button = weak_button.upgrade().unwrap();
|
let button = weak_button.upgrade().unwrap();
|
||||||
|
@ -122,7 +125,7 @@ impl AbilityPageRightSide {
|
||||||
let entity = scene.entity_mut(hero)?;
|
let entity = scene.entity_mut(hero)?;
|
||||||
let mut multi_mut = entity.multi_mut();
|
let mut multi_mut = entity.multi_mut();
|
||||||
|
|
||||||
let abilities = multi_mut.get::<AbilitySlots>()?;
|
let abilities = multi_mut.get::<AbilitySlots<A>>()?;
|
||||||
|
|
||||||
if let Some(ability) = abilities.book_mut(index) {
|
if let Some(ability) = abilities.book_mut(index) {
|
||||||
let materials = multi_mut.get::<CraftingMaterials>()?;
|
let materials = multi_mut.get::<CraftingMaterials>()?;
|
||||||
|
@ -131,7 +134,7 @@ impl AbilityPageRightSide {
|
||||||
|
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
menu.tabs_mut()
|
menu.tabs_mut()
|
||||||
.abilities()
|
.abilities::<A>()
|
||||||
.right_side
|
.right_side
|
||||||
.refresh(&engine, hero)?;
|
.refresh(&engine, hero)?;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +154,7 @@ impl AbilityPageRightSide {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
snippet,
|
snippet,
|
||||||
ability_index: 0,
|
ability_index: 0,
|
||||||
|
ability_marker: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +193,7 @@ impl AbilityPageRightSide {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_active_ability(&self, engine: &Engine, abilities: &AbilitySlots) -> Result<()> {
|
fn update_active_ability(&self, engine: &Engine, abilities: &AbilitySlots<A>) -> Result<()> {
|
||||||
let grid: Arc<Grid> = self.snippet.element("ability_content")?;
|
let grid: Arc<Grid> = self.snippet.element("ability_content")?;
|
||||||
let (_, rows) = grid.dimensions();
|
let (_, rows) = grid.dimensions();
|
||||||
|
|
||||||
|
@ -237,7 +241,7 @@ impl AbilityPageRightSide {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RightSide for AbilityPageRightSide {
|
impl<A: Ability + 'static> RightSide for AbilityPageRightSide<A> {
|
||||||
fn refresh(&mut self, engine: &Engine, hero: Entity) -> Result<()> {
|
fn refresh(&mut self, engine: &Engine, hero: Entity) -> Result<()> {
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
|
@ -251,7 +255,7 @@ impl RightSide for AbilityPageRightSide {
|
||||||
self.update_crafting_count("epic", crafting.count(Rarities::Epic))?;
|
self.update_crafting_count("epic", crafting.count(Rarities::Epic))?;
|
||||||
self.update_crafting_count("legendary", crafting.count(Rarities::Legendary))?;
|
self.update_crafting_count("legendary", crafting.count(Rarities::Legendary))?;
|
||||||
|
|
||||||
let abilities = entity.get_component::<AbilitySlots>()?;
|
let abilities = entity.get_component::<AbilitySlots<A>>()?;
|
||||||
|
|
||||||
for (index, name) in Self::ABILITY_BUTTON_NAMES.iter().enumerate() {
|
for (index, name) in Self::ABILITY_BUTTON_NAMES.iter().enumerate() {
|
||||||
self.update_ability_icon(name, abilities.book(index).map(|book| book.icon()))?;
|
self.update_ability_icon(name, abilities.book(index).map(|book| book.icon()))?;
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
|
|
||||||
use super::AbilityPage;
|
use super::AbilityPage;
|
||||||
|
|
||||||
impl Content<AbilityAddon> {
|
impl<A: Ability + 'static> Content<A, AbilityAddon> {
|
||||||
fn show_addon_tooltip(
|
fn show_addon_tooltip(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
|
@ -25,7 +25,7 @@ impl Content<AbilityAddon> {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
let inventory = entity.get_component::<Inventory>()?;
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||||||
|
|
||||||
let target_x = x + w as i32;
|
let target_x = x + w as i32;
|
||||||
let target_y = y;
|
let target_y = y;
|
||||||
|
@ -46,14 +46,14 @@ impl Content<AbilityAddon> {
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
addon_index: usize,
|
addon_index: usize,
|
||||||
ability_page: &AbilityPage,
|
ability_page: &AbilityPage<A>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
engine.on_scene_mut(|scene| {
|
engine.on_scene_mut(|scene| {
|
||||||
let entity = scene.entity_mut(hero)?;
|
let entity = scene.entity_mut(hero)?;
|
||||||
let mut multi_mut = entity.multi_mut();
|
let mut multi_mut = entity.multi_mut();
|
||||||
|
|
||||||
let inventory = multi_mut.get::<Inventory>()?;
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||||
let abilities = multi_mut.get::<AbilitySlots>()?;
|
let abilities = multi_mut.get::<AbilitySlots<A>>()?;
|
||||||
|
|
||||||
if let Some(book) = abilities.book_mut(ability_page.right_side.selected_ability()) {
|
if let Some(book) = abilities.book_mut(ability_page.right_side.selected_ability()) {
|
||||||
if book.has_free_addon_slots() {
|
if book.has_free_addon_slots() {
|
||||||
|
@ -67,7 +67,7 @@ impl Content<AbilityAddon> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentUpdate for Content<AbilityAddon> {
|
impl<A: Ability + 'static> ContentUpdate for Content<A, AbilityAddon> {
|
||||||
fn update(&mut self, engine: &Arc<Engine>, hero: Entity) -> Result<()> {
|
fn update(&mut self, engine: &Arc<Engine>, hero: Entity) -> Result<()> {
|
||||||
let reference = self.reference.clone();
|
let reference = self.reference.clone();
|
||||||
|
|
||||||
|
@ -80,13 +80,15 @@ impl ContentUpdate for Content<AbilityAddon> {
|
||||||
|
|
||||||
move |controller_button| {
|
move |controller_button| {
|
||||||
if let ControllerButton::X = controller_button {
|
if let ControllerButton::X = controller_button {
|
||||||
CharacterWindow::salvage_from_inventory(&engine, hero, |inventory| {
|
CharacterWindow::salvage_from_inventory::<A, _, _>(
|
||||||
inventory.remove_addon(index)
|
&engine,
|
||||||
})?;
|
hero,
|
||||||
|
|inventory| inventory.remove_addon(index),
|
||||||
|
)?;
|
||||||
|
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let abilities = tabs.abilities();
|
let abilities = tabs.abilities::<A>();
|
||||||
|
|
||||||
abilities.update_page()?;
|
abilities.update_page()?;
|
||||||
}
|
}
|
||||||
|
@ -145,19 +147,19 @@ impl ContentUpdate for Content<AbilityAddon> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Content<AbilityBook> {
|
impl<A: Ability + 'static> Content<A, AbilityBook<A>> {
|
||||||
fn equip_book(
|
fn equip_book(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
book_index: usize,
|
book_index: usize,
|
||||||
ability_page: &AbilityPage,
|
ability_page: &AbilityPage<A>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
engine.on_scene_mut(|scene| {
|
engine.on_scene_mut(|scene| {
|
||||||
let entity = scene.entity_mut(hero)?;
|
let entity = scene.entity_mut(hero)?;
|
||||||
let mut multi_mut = entity.multi_mut();
|
let mut multi_mut = entity.multi_mut();
|
||||||
|
|
||||||
let inventory = multi_mut.get::<Inventory>()?;
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||||
let abilitiy_slots = multi_mut.get::<AbilitySlots>()?;
|
let abilitiy_slots = multi_mut.get::<AbilitySlots<A>>()?;
|
||||||
|
|
||||||
if let Some(old_book) = abilitiy_slots.insert_book(
|
if let Some(old_book) = abilitiy_slots.insert_book(
|
||||||
inventory.remove_book(book_index),
|
inventory.remove_book(book_index),
|
||||||
|
@ -179,7 +181,7 @@ impl Content<AbilityBook> {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
let inventory = entity.get_component::<Inventory>()?;
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||||||
let statistics = entity.get_component::<Statistics>()?;
|
let statistics = entity.get_component::<Statistics>()?;
|
||||||
|
|
||||||
let target_x = x + w as i32;
|
let target_x = x + w as i32;
|
||||||
|
@ -191,9 +193,9 @@ impl Content<AbilityBook> {
|
||||||
gui.enable()?;
|
gui.enable()?;
|
||||||
|
|
||||||
let window = reference.upgrade().unwrap();
|
let window = reference.upgrade().unwrap();
|
||||||
let abilities = entity.get_component::<AbilitySlots>()?;
|
let abilities = entity.get_component::<AbilitySlots<A>>()?;
|
||||||
|
|
||||||
match abilities.book(window.tabs().abilities().right_side.selected_ability()) {
|
match abilities.book(window.tabs().abilities::<A>().right_side.selected_ability()) {
|
||||||
Some(selected_book) => {
|
Some(selected_book) => {
|
||||||
let button_pos = gui.position_extent();
|
let button_pos = gui.position_extent();
|
||||||
|
|
||||||
|
@ -222,7 +224,7 @@ impl Content<AbilityBook> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentUpdate for Content<AbilityBook> {
|
impl<A: Ability + 'static> ContentUpdate for Content<A, AbilityBook<A>> {
|
||||||
fn update(&mut self, engine: &Arc<Engine>, hero: Entity) -> Result<()> {
|
fn update(&mut self, engine: &Arc<Engine>, hero: Entity) -> Result<()> {
|
||||||
let reference = self.reference.clone();
|
let reference = self.reference.clone();
|
||||||
|
|
||||||
|
@ -235,13 +237,15 @@ impl ContentUpdate for Content<AbilityBook> {
|
||||||
|
|
||||||
move |controller_button| {
|
move |controller_button| {
|
||||||
if let ControllerButton::X = controller_button {
|
if let ControllerButton::X = controller_button {
|
||||||
CharacterWindow::salvage_from_inventory(&engine, hero, |inventory| {
|
CharacterWindow::salvage_from_inventory::<A, _, _>(
|
||||||
inventory.remove_book(index)
|
&engine,
|
||||||
})?;
|
hero,
|
||||||
|
|inventory| inventory.remove_book(index),
|
||||||
|
)?;
|
||||||
|
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let abilities = tabs.abilities();
|
let abilities = tabs.abilities::<A>();
|
||||||
|
|
||||||
abilities.update_page()?;
|
abilities.update_page()?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub struct AbilityPage {
|
pub struct AbilityPage<A: Ability + 'static> {
|
||||||
close: Weak<Button>,
|
close: Weak<Button>,
|
||||||
|
|
||||||
engine: Arc<Engine>,
|
engine: Arc<Engine>,
|
||||||
|
@ -31,10 +31,10 @@ pub struct AbilityPage {
|
||||||
|
|
||||||
current_mode: usize,
|
current_mode: usize,
|
||||||
|
|
||||||
right_side: AbilityPageRightSide,
|
right_side: AbilityPageRightSide<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbilityPage {
|
impl<A: Ability + 'static> AbilityPage<A> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
|
@ -65,7 +65,7 @@ impl AbilityPage {
|
||||||
|
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let hero_object = scene.entity(hero)?;
|
let hero_object = scene.entity(hero)?;
|
||||||
let inventory = hero_object.get_component::<Inventory>()?;
|
let inventory = hero_object.get_component::<Inventory<A>>()?;
|
||||||
|
|
||||||
data = inventory.iter_books().cloned().collect();
|
data = inventory.iter_books().cloned().collect();
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ impl AbilityPage {
|
||||||
);
|
);
|
||||||
|
|
||||||
// addons
|
// addons
|
||||||
let addons_mode = PageContent::new(
|
let addons_mode = PageContent::<A, _>::new(
|
||||||
Content::new(&engine, reference.clone(), {
|
Content::new(&engine, reference.clone(), {
|
||||||
let engine = engine.clone();
|
let engine = engine.clone();
|
||||||
let hero = hero.clone();
|
let hero = hero.clone();
|
||||||
|
@ -109,7 +109,7 @@ impl AbilityPage {
|
||||||
|
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let hero_object = scene.entity(hero)?;
|
let hero_object = scene.entity(hero)?;
|
||||||
let inventory = hero_object.get_component::<Inventory>()?;
|
let inventory = hero_object.get_component::<Inventory<A>>()?;
|
||||||
|
|
||||||
data = inventory.iter_addons().cloned().collect();
|
data = inventory.iter_addons().cloned().collect();
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ impl AbilityPage {
|
||||||
move |index| {
|
move |index| {
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let me = tabs.abilities();
|
let me = tabs.abilities::<A>();
|
||||||
|
|
||||||
if me.current_mode != index {
|
if me.current_mode != index {
|
||||||
me.current_mode = index;
|
me.current_mode = index;
|
||||||
|
@ -223,7 +223,7 @@ impl AbilityPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page for AbilityPage {
|
impl<A: Ability + 'static> Page for AbilityPage<A> {
|
||||||
fn enable(&mut self) -> Result<Arc<Grid>> {
|
fn enable(&mut self) -> Result<Arc<Grid>> {
|
||||||
println!("enable AbilityPage");
|
println!("enable AbilityPage");
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use std::sync::{Arc, Weak};
|
use std::{
|
||||||
|
marker::PhantomData,
|
||||||
|
sync::{Arc, Weak},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
@ -15,7 +18,7 @@ pub trait ContentUpdate {
|
||||||
fn select(&self) -> Result<()>;
|
fn select(&self) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Content<T: Send + Sync> {
|
pub struct Content<A: Ability + 'static, T: Send + Sync> {
|
||||||
pub reference: Weak<CharacterWindow>,
|
pub reference: Weak<CharacterWindow>,
|
||||||
base: Arc<GuiSnippet>,
|
base: Arc<GuiSnippet>,
|
||||||
data: Vec<T>,
|
data: Vec<T>,
|
||||||
|
@ -24,9 +27,11 @@ pub struct Content<T: Send + Sync> {
|
||||||
|
|
||||||
page: usize,
|
page: usize,
|
||||||
pages: usize,
|
pages: usize,
|
||||||
|
|
||||||
|
ability_marker: PhantomData<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Send + Sync> Content<T> {
|
impl<A: Ability + 'static, T: Send + Sync> Content<A, T> {
|
||||||
pub fn new<F>(
|
pub fn new<F>(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
reference: Weak<CharacterWindow>,
|
reference: Weak<CharacterWindow>,
|
||||||
|
@ -56,6 +61,8 @@ impl<T: Send + Sync> Content<T> {
|
||||||
|
|
||||||
page: 0,
|
page: 0,
|
||||||
pages: 1,
|
pages: 1,
|
||||||
|
|
||||||
|
ability_marker: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,9 +131,9 @@ impl<T: Send + Sync> Content<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Send + Sync> ContentWrapper for Content<T>
|
impl<A: Ability + 'static, T: Send + Sync> ContentWrapper for Content<A, T>
|
||||||
where
|
where
|
||||||
Content<T>: ContentUpdate,
|
Content<A, T>: ContentUpdate,
|
||||||
{
|
{
|
||||||
fn refresh(&mut self) -> Result<()> {
|
fn refresh(&mut self) -> Result<()> {
|
||||||
self.data = (self.on_enable)()?;
|
self.data = (self.on_enable)()?;
|
||||||
|
|
|
@ -17,9 +17,9 @@ use crate::{
|
||||||
|
|
||||||
use super::jewel_right_side::{LowerJewels, ReferenceItemSource, ReferenceObject};
|
use super::jewel_right_side::{LowerJewels, ReferenceItemSource, ReferenceObject};
|
||||||
|
|
||||||
impl Content<Item> {
|
impl<A: Ability + 'static> Content<A, Item> {
|
||||||
fn salvage_item(engine: &Arc<Engine>, hero: Entity, item_index: usize) -> Result<()> {
|
fn salvage_item(engine: &Arc<Engine>, hero: Entity, item_index: usize) -> Result<()> {
|
||||||
CharacterWindow::salvage_from_inventory(engine, hero, |inventory| {
|
CharacterWindow::salvage_from_inventory::<A, _, _>(engine, hero, |inventory| {
|
||||||
let mut item = inventory.remove_item(item_index);
|
let mut item = inventory.remove_item(item_index);
|
||||||
|
|
||||||
// unsocket jewels and add them into inventory
|
// unsocket jewels and add them into inventory
|
||||||
|
@ -42,7 +42,7 @@ impl Content<Item> {
|
||||||
|
|
||||||
engine.on_scene_mut(|scene| {
|
engine.on_scene_mut(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
let inventory = entity.get_component::<Inventory>()?;
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||||||
let item = inventory.item_at(item_index).clone();
|
let item = inventory.item_at(item_index).clone();
|
||||||
|
|
||||||
if item.affixes.iter().any(|affix| {
|
if item.affixes.iter().any(|affix| {
|
||||||
|
@ -75,7 +75,7 @@ impl Content<Item> {
|
||||||
let mut multi_mut = entity.multi_mut();
|
let mut multi_mut = entity.multi_mut();
|
||||||
|
|
||||||
let hero_items = multi_mut.get::<ItemSlotContainer>()?;
|
let hero_items = multi_mut.get::<ItemSlotContainer>()?;
|
||||||
let inventory = multi_mut.get::<Inventory>()?;
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||||
let attributes = multi_mut.get::<Attributes>()?;
|
let attributes = multi_mut.get::<Attributes>()?;
|
||||||
|
|
||||||
// remove item from inventory
|
// remove item from inventory
|
||||||
|
@ -109,7 +109,7 @@ impl Content<Item> {
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
|
|
||||||
let inventory = entity.get_component::<Inventory>()?;
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||||||
let attributes = entity.get_component::<Attributes>()?;
|
let attributes = entity.get_component::<Attributes>()?;
|
||||||
|
|
||||||
let target_x = x + w as i32;
|
let target_x = x + w as i32;
|
||||||
|
@ -155,7 +155,7 @@ impl Content<Item> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentUpdate for Content<Item> {
|
impl<A: Ability + 'static> ContentUpdate for Content<A, Item> {
|
||||||
fn update(&mut self, engine: &Arc<Engine>, hero: Entity) -> Result<()> {
|
fn update(&mut self, engine: &Arc<Engine>, hero: Entity) -> Result<()> {
|
||||||
let reference = self.reference.clone();
|
let reference = self.reference.clone();
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ impl ContentUpdate for Content<Item> {
|
||||||
|
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.update_page(true)?;
|
inventory.update_page(true)?;
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ impl ContentUpdate for Content<Item> {
|
||||||
if Self::select_to_socket(&engine, hero, index)? {
|
if Self::select_to_socket(&engine, hero, index)? {
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.switch_to_jewels()?;
|
inventory.switch_to_jewels()?;
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ impl ContentUpdate for Content<Item> {
|
||||||
|
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.update_page(true)?;
|
inventory.update_page(true)?;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ impl ContentUpdate for Content<Item> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Content<Jewel> {
|
impl<A: Ability + 'static> Content<A, Jewel> {
|
||||||
fn show_jewel_tooltip(
|
fn show_jewel_tooltip(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
|
@ -257,7 +257,7 @@ impl Content<Jewel> {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
let inventory = entity.get_component::<Inventory>()?;
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||||||
|
|
||||||
let target_x = x + w as i32;
|
let target_x = x + w as i32;
|
||||||
let target_y = y;
|
let target_y = y;
|
||||||
|
@ -285,7 +285,7 @@ impl Content<Jewel> {
|
||||||
fn select_to_combine(engine: &Arc<Engine>, hero: Entity, jewel_index: usize) -> Result<()> {
|
fn select_to_combine(engine: &Arc<Engine>, hero: Entity, jewel_index: usize) -> Result<()> {
|
||||||
engine.on_scene_mut(|scene| {
|
engine.on_scene_mut(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
let inventory = entity.get_component::<Inventory>()?;
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||||||
let jewel = inventory.jewel_at(jewel_index).clone();
|
let jewel = inventory.jewel_at(jewel_index).clone();
|
||||||
|
|
||||||
// add to reference
|
// add to reference
|
||||||
|
@ -312,7 +312,7 @@ impl Content<Jewel> {
|
||||||
fn select_to_lower(engine: &Arc<Engine>, hero: Entity, jewel_index: usize) -> Result<()> {
|
fn select_to_lower(engine: &Arc<Engine>, hero: Entity, jewel_index: usize) -> Result<()> {
|
||||||
engine.on_scene_mut(|scene| {
|
engine.on_scene_mut(|scene| {
|
||||||
let entity = scene.entity(hero)?;
|
let entity = scene.entity(hero)?;
|
||||||
let inventory = entity.get_component::<Inventory>()?;
|
let inventory = entity.get_component::<Inventory<A>>()?;
|
||||||
let jewel = inventory.jewel_at(jewel_index).clone();
|
let jewel = inventory.jewel_at(jewel_index).clone();
|
||||||
|
|
||||||
// remove from reference if placed there
|
// remove from reference if placed there
|
||||||
|
@ -342,7 +342,7 @@ impl Content<Jewel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentUpdate for Content<Jewel> {
|
impl<A: Ability + 'static> ContentUpdate for Content<A, Jewel> {
|
||||||
fn update(&mut self, engine: &Arc<Engine>, hero: Entity) -> Result<()> {
|
fn update(&mut self, engine: &Arc<Engine>, hero: Entity) -> Result<()> {
|
||||||
let reference = self.reference.clone();
|
let reference = self.reference.clone();
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ impl ContentUpdate for Content<Jewel> {
|
||||||
|
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.update_page(true)?;
|
inventory.update_page(true)?;
|
||||||
}
|
}
|
||||||
|
@ -398,7 +398,7 @@ impl ContentUpdate for Content<Jewel> {
|
||||||
|
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.update_page(true)?;
|
inventory.update_page(true)?;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ impl ContentUpdate for Content<Jewel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentUpdate for Content<MapItem> {
|
impl<A: Ability + 'static> ContentUpdate for Content<A, MapItem> {
|
||||||
fn update(&mut self, engine: &Arc<Engine>, _hero: Entity) -> Result<()> {
|
fn update(&mut self, engine: &Arc<Engine>, _hero: Entity) -> Result<()> {
|
||||||
self.update_base(engine, |_button, _t, _index| {
|
self.update_base(engine, |_button, _t, _index| {
|
||||||
// button.set_icon(&t.icon)?;
|
// button.set_icon(&t.icon)?;
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub struct ItemRightSide {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemRightSide {
|
impl ItemRightSide {
|
||||||
pub fn new(
|
pub fn new<A: Ability + 'static>(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
file: &str,
|
file: &str,
|
||||||
reference: &Weak<CharacterWindow>,
|
reference: &Weak<CharacterWindow>,
|
||||||
|
@ -37,12 +37,12 @@ impl ItemRightSide {
|
||||||
empty_icons: icons,
|
empty_icons: icons,
|
||||||
};
|
};
|
||||||
|
|
||||||
me.setup(engine, reference, hero)?;
|
me.setup::<A>(engine, reference, hero)?;
|
||||||
|
|
||||||
Ok(me)
|
Ok(me)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(
|
fn setup<A: Ability + 'static>(
|
||||||
&self,
|
&self,
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
reference: &Weak<CharacterWindow>,
|
reference: &Weak<CharacterWindow>,
|
||||||
|
@ -253,7 +253,7 @@ mod macros {
|
||||||
let mut multi_mut = entity.multi_mut();
|
let mut multi_mut = entity.multi_mut();
|
||||||
|
|
||||||
let items = multi_mut.get::<ItemSlotContainer>()?;
|
let items = multi_mut.get::<ItemSlotContainer>()?;
|
||||||
let inventory = multi_mut.get::<Inventory>()?;
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||||
|
|
||||||
if let Some($item) = items.[<$item>]() {
|
if let Some($item) = items.[<$item>]() {
|
||||||
inventory.add_item($item.clone());
|
inventory.add_item($item.clone());
|
||||||
|
@ -285,7 +285,7 @@ mod macros {
|
||||||
if found_item {
|
if found_item {
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.update_page(true)?;
|
inventory.update_page(true)?;
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ mod macros {
|
||||||
if empty_affixes_found {
|
if empty_affixes_found {
|
||||||
let window = reference.upgrade().unwrap();
|
let window = reference.upgrade().unwrap();
|
||||||
let mut tabs = window.tabs_mut();
|
let mut tabs = window.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.switch_to_jewels()?;
|
inventory.switch_to_jewels()?;
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,7 @@ mod macros {
|
||||||
let mut multi_mut = entity.multi_mut();
|
let mut multi_mut = entity.multi_mut();
|
||||||
|
|
||||||
let items = multi_mut.get::<ItemSlotContainer>()?;
|
let items = multi_mut.get::<ItemSlotContainer>()?;
|
||||||
let inventory = multi_mut.get::<Inventory>()?;
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||||
|
|
||||||
if let Some($item) = items.[<$item>]($index) {
|
if let Some($item) = items.[<$item>]($index) {
|
||||||
inventory.add_item($item.clone());
|
inventory.add_item($item.clone());
|
||||||
|
@ -437,7 +437,7 @@ mod macros {
|
||||||
if found_item {
|
if found_item {
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.update_page(true)?;
|
inventory.update_page(true)?;
|
||||||
}
|
}
|
||||||
|
@ -485,7 +485,7 @@ mod macros {
|
||||||
if empty_affixes_found {
|
if empty_affixes_found {
|
||||||
let window = reference.upgrade().unwrap();
|
let window = reference.upgrade().unwrap();
|
||||||
let mut tabs = window.tabs_mut();
|
let mut tabs = window.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.switch_to_jewels()?;
|
inventory.switch_to_jewels()?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub struct JewelRightSide {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JewelRightSide {
|
impl JewelRightSide {
|
||||||
pub fn new(
|
pub fn new<A: Ability + 'static>(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
file: &str,
|
file: &str,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
|
@ -67,12 +67,12 @@ impl JewelRightSide {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let me = Self { snippet };
|
let me = Self { snippet };
|
||||||
me.setup_select(engine, hero, reference)?;
|
me.setup_select::<A>(engine, hero, reference)?;
|
||||||
|
|
||||||
Ok(me)
|
Ok(me)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_select(
|
fn setup_select<A: Ability + 'static>(
|
||||||
&self,
|
&self,
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
|
@ -180,7 +180,7 @@ impl JewelRightSide {
|
||||||
|
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let inventory = tabs.inventory();
|
let inventory = tabs.inventory::<A>();
|
||||||
|
|
||||||
inventory.update_page(true)?;
|
inventory.update_page(true)?;
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ impl JewelRightSide {
|
||||||
.for_each(|j| *j = None);
|
.for_each(|j| *j = None);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn combine(engine: &Arc<Engine>, hero: Entity) -> Result<bool> {
|
pub fn combine<A: Ability + 'static>(engine: &Arc<Engine>, hero: Entity) -> Result<bool> {
|
||||||
let scene = engine.scene_mut();
|
let scene = engine.scene_mut();
|
||||||
|
|
||||||
let (resources, entity) = scene.entity_resource(hero)?;
|
let (resources, entity) = scene.entity_resource(hero)?;
|
||||||
|
@ -244,7 +244,7 @@ impl JewelRightSide {
|
||||||
|
|
||||||
match source {
|
match source {
|
||||||
ReferenceItemSource::Inventory(index) => {
|
ReferenceItemSource::Inventory(index) => {
|
||||||
let inventory = entity.get_component_mut::<Inventory>()?;
|
let inventory = entity.get_component_mut::<Inventory<A>>()?;
|
||||||
|
|
||||||
let item = inventory.item_mut_at(*index);
|
let item = inventory.item_mut_at(*index);
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ impl JewelRightSide {
|
||||||
|
|
||||||
let mut multi_mut = entity.multi_mut();
|
let mut multi_mut = entity.multi_mut();
|
||||||
|
|
||||||
let inventory = multi_mut.get::<Inventory>()?;
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||||
let item_slots = multi_mut.get::<ItemSlotContainer>()?;
|
let item_slots = multi_mut.get::<ItemSlotContainer>()?;
|
||||||
|
|
||||||
let slot = item.slot;
|
let slot = item.slot;
|
||||||
|
@ -328,9 +328,9 @@ impl JewelRightSide {
|
||||||
}
|
}
|
||||||
|
|
||||||
let item_settings = resources.get::<ItemSettings>();
|
let item_settings = resources.get::<ItemSettings>();
|
||||||
let item_system = resources.get::<ItemSystem>();
|
let item_system = resources.get::<ItemSystem<A>>();
|
||||||
|
|
||||||
let inventory = entity.get_component_mut::<Inventory>()?;
|
let inventory = entity.get_component_mut::<Inventory<A>>()?;
|
||||||
|
|
||||||
let upper_jewel = inventory.jewel_mut_at(*index);
|
let upper_jewel = inventory.jewel_mut_at(*index);
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,13 @@ mod item_right_side;
|
||||||
mod jewel_right_side;
|
mod jewel_right_side;
|
||||||
mod map_right_side;
|
mod map_right_side;
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
use rpg_components::components::inventory::Inventory;
|
use rpg_components::components::inventory::Inventory;
|
||||||
|
use rpg_components::items::ability_book::Ability;
|
||||||
|
|
||||||
use super::page_content::PageContent;
|
use super::page_content::PageContent;
|
||||||
use super::traits::*;
|
use super::traits::*;
|
||||||
|
@ -16,7 +18,7 @@ use item_right_side::ItemRightSide;
|
||||||
use jewel_right_side::JewelRightSide;
|
use jewel_right_side::JewelRightSide;
|
||||||
use map_right_side::MapRightSide;
|
use map_right_side::MapRightSide;
|
||||||
|
|
||||||
pub struct InventoryPage {
|
pub struct InventoryPage<A: Ability + 'static> {
|
||||||
close: Weak<Button>,
|
close: Weak<Button>,
|
||||||
|
|
||||||
engine: Arc<Engine>,
|
engine: Arc<Engine>,
|
||||||
|
@ -30,9 +32,11 @@ pub struct InventoryPage {
|
||||||
modes: [Box<dyn PageContentWrapper>; 3],
|
modes: [Box<dyn PageContentWrapper>; 3],
|
||||||
|
|
||||||
current_mode: usize,
|
current_mode: usize,
|
||||||
|
|
||||||
|
ability_marker: PhantomData<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InventoryPage {
|
impl<A: Ability + 'static> InventoryPage<A> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
|
@ -53,7 +57,7 @@ impl InventoryPage {
|
||||||
let content = left_base.element("content")?;
|
let content = left_base.element("content")?;
|
||||||
|
|
||||||
// items
|
// items
|
||||||
let item_mode = PageContent::new(
|
let item_mode = PageContent::<A, _>::new(
|
||||||
Content::new(engine, reference.clone(), {
|
Content::new(engine, reference.clone(), {
|
||||||
let engine = engine.clone();
|
let engine = engine.clone();
|
||||||
let hero = hero.clone();
|
let hero = hero.clone();
|
||||||
|
@ -63,7 +67,7 @@ impl InventoryPage {
|
||||||
|
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let hero_object = scene.entity(hero)?;
|
let hero_object = scene.entity(hero)?;
|
||||||
let inventory = hero_object.get_component::<Inventory>()?;
|
let inventory = hero_object.get_component::<Inventory<A>>()?;
|
||||||
|
|
||||||
data = inventory.iter_items().cloned().collect();
|
data = inventory.iter_items().cloned().collect();
|
||||||
|
|
||||||
|
@ -93,7 +97,7 @@ impl InventoryPage {
|
||||||
|
|
||||||
ui
|
ui
|
||||||
},
|
},
|
||||||
ItemRightSide::new(
|
ItemRightSide::new::<A>(
|
||||||
engine,
|
engine,
|
||||||
include_str!("../../resources/inventory/items/right_side.xml"),
|
include_str!("../../resources/inventory/items/right_side.xml"),
|
||||||
&reference,
|
&reference,
|
||||||
|
@ -102,7 +106,7 @@ impl InventoryPage {
|
||||||
);
|
);
|
||||||
|
|
||||||
// jewels
|
// jewels
|
||||||
let jewel_mode = PageContent::new(
|
let jewel_mode = PageContent::<A, _>::new(
|
||||||
Content::new(engine, reference.clone(), {
|
Content::new(engine, reference.clone(), {
|
||||||
let engine = engine.clone();
|
let engine = engine.clone();
|
||||||
let hero = hero.clone();
|
let hero = hero.clone();
|
||||||
|
@ -112,7 +116,7 @@ impl InventoryPage {
|
||||||
|
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let hero_object = scene.entity(hero)?;
|
let hero_object = scene.entity(hero)?;
|
||||||
let inventory = hero_object.get_component::<Inventory>()?;
|
let inventory = hero_object.get_component::<Inventory<A>>()?;
|
||||||
|
|
||||||
data = inventory.iter_jewels().cloned().collect();
|
data = inventory.iter_jewels().cloned().collect();
|
||||||
|
|
||||||
|
@ -139,7 +143,7 @@ impl InventoryPage {
|
||||||
|
|
||||||
ui
|
ui
|
||||||
},
|
},
|
||||||
JewelRightSide::new(
|
JewelRightSide::new::<A>(
|
||||||
engine,
|
engine,
|
||||||
include_str!("../../resources/inventory/jewels/right_side.xml"),
|
include_str!("../../resources/inventory/jewels/right_side.xml"),
|
||||||
hero,
|
hero,
|
||||||
|
@ -148,7 +152,7 @@ impl InventoryPage {
|
||||||
);
|
);
|
||||||
|
|
||||||
// maps
|
// maps
|
||||||
let map_mode = PageContent::new(
|
let map_mode = PageContent::<A, _>::new(
|
||||||
Content::new(engine, reference.clone(), {
|
Content::new(engine, reference.clone(), {
|
||||||
let engine = engine.clone();
|
let engine = engine.clone();
|
||||||
let hero: Entity = hero.clone();
|
let hero: Entity = hero.clone();
|
||||||
|
@ -158,7 +162,7 @@ impl InventoryPage {
|
||||||
|
|
||||||
engine.on_scene(|scene| {
|
engine.on_scene(|scene| {
|
||||||
let hero_object = scene.entity(hero)?;
|
let hero_object = scene.entity(hero)?;
|
||||||
let inventory = hero_object.get_component::<Inventory>()?;
|
let inventory = hero_object.get_component::<Inventory<A>>()?;
|
||||||
|
|
||||||
data = inventory.iter_maps().cloned().collect();
|
data = inventory.iter_maps().cloned().collect();
|
||||||
|
|
||||||
|
@ -209,6 +213,8 @@ impl InventoryPage {
|
||||||
],
|
],
|
||||||
|
|
||||||
current_mode: 0,
|
current_mode: 0,
|
||||||
|
|
||||||
|
ability_marker: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +321,7 @@ impl InventoryPage {
|
||||||
move |index| {
|
move |index| {
|
||||||
if let Some(menu) = reference.upgrade() {
|
if let Some(menu) = reference.upgrade() {
|
||||||
let mut tabs = menu.tabs_mut();
|
let mut tabs = menu.tabs_mut();
|
||||||
let me = tabs.inventory();
|
let me = tabs.inventory::<A>();
|
||||||
|
|
||||||
if me.current_mode != index {
|
if me.current_mode != index {
|
||||||
me.current_mode = index;
|
me.current_mode = index;
|
||||||
|
@ -353,7 +359,7 @@ impl InventoryPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page for InventoryPage {
|
impl<A: Ability + 'static> Page for InventoryPage<A> {
|
||||||
fn enable(&mut self) -> Result<Arc<Grid>> {
|
fn enable(&mut self) -> Result<Arc<Grid>> {
|
||||||
println!("enable InventoryPage");
|
println!("enable InventoryPage");
|
||||||
|
|
||||||
|
@ -423,7 +429,7 @@ impl Page for InventoryPage {
|
||||||
ControllerButton::RightStick => {
|
ControllerButton::RightStick => {
|
||||||
// check if jewel page is open
|
// check if jewel page is open
|
||||||
if self.current_mode == 1 {
|
if self.current_mode == 1 {
|
||||||
if JewelRightSide::combine(&self.engine, self.hero)? {
|
if JewelRightSide::combine::<A>(&self.engine, self.hero)? {
|
||||||
JewelRightSide::clear(&self.engine);
|
JewelRightSide::clear(&self.engine);
|
||||||
self.update_page(true)?;
|
self.update_page(true)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,12 @@ mod traits;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
use rpg_components::components::{
|
use rpg_components::{
|
||||||
|
components::{
|
||||||
crafting_materials::CraftingMaterials,
|
crafting_materials::CraftingMaterials,
|
||||||
inventory::{Inventory, Storable},
|
inventory::{Inventory, Storable},
|
||||||
|
},
|
||||||
|
items::ability_book::Ability,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -76,11 +79,11 @@ impl<'a> Tabs<'a> {
|
||||||
Self::downcast_unchecked(&self.tabs[0])
|
Self::downcast_unchecked(&self.tabs[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inventory(&mut self) -> &'a InventoryPage {
|
pub fn inventory<A: Ability + 'static>(&mut self) -> &'a InventoryPage<A> {
|
||||||
Self::downcast_unchecked(&self.tabs[1])
|
Self::downcast_unchecked(&self.tabs[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn abilities(&mut self) -> &'a AbilityPage {
|
pub fn abilities<A: Ability + 'static>(&mut self) -> &'a AbilityPage<A> {
|
||||||
Self::downcast_unchecked(&self.tabs[2])
|
Self::downcast_unchecked(&self.tabs[2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,11 +107,11 @@ impl<'a> TabsMut<'a> {
|
||||||
Self::downcast_mut_unchecked(&mut self.tabs[0])
|
Self::downcast_mut_unchecked(&mut self.tabs[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inventory(&mut self) -> &'a mut InventoryPage {
|
pub fn inventory<A: Ability + 'static>(&mut self) -> &'a mut InventoryPage<A> {
|
||||||
Self::downcast_mut_unchecked(&mut self.tabs[1])
|
Self::downcast_mut_unchecked(&mut self.tabs[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn abilities(&mut self) -> &'a mut AbilityPage {
|
pub fn abilities<A: Ability + 'static>(&mut self) -> &'a mut AbilityPage<A> {
|
||||||
Self::downcast_mut_unchecked(&mut self.tabs[2])
|
Self::downcast_mut_unchecked(&mut self.tabs[2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +140,7 @@ pub struct CharacterWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharacterWindow {
|
impl CharacterWindow {
|
||||||
pub fn new(
|
pub fn new<A: Ability + 'static>(
|
||||||
engine: Arc<Engine>,
|
engine: Arc<Engine>,
|
||||||
hero: Entity,
|
hero: Entity,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -162,8 +165,10 @@ impl CharacterWindow {
|
||||||
|
|
||||||
tabs: RwLock::new([
|
tabs: RwLock::new([
|
||||||
Box::new(CharacterPage::new(&engine, hero, name, me).unwrap()),
|
Box::new(CharacterPage::new(&engine, hero, name, me).unwrap()),
|
||||||
Box::new(InventoryPage::new(&engine, hero, me.clone(), &close_button).unwrap()),
|
Box::new(
|
||||||
Box::new(AbilityPage::new(&engine, hero, me.clone(), &close_button).unwrap()),
|
InventoryPage::<A>::new(&engine, hero, me.clone(), &close_button).unwrap(),
|
||||||
|
),
|
||||||
|
Box::new(AbilityPage::<A>::new(&engine, hero, me.clone(), &close_button).unwrap()),
|
||||||
]),
|
]),
|
||||||
tab: AtomicUsize::new(0),
|
tab: AtomicUsize::new(0),
|
||||||
|
|
||||||
|
@ -250,9 +255,10 @@ impl CharacterWindow {
|
||||||
self.tooltips.lock().unwrap().remove(&name.to_string());
|
self.tooltips.lock().unwrap().remove(&name.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn salvage_from_inventory<F, S>(engine: &Engine, hero: Entity, f: F) -> Result<()>
|
pub fn salvage_from_inventory<A, F, S>(engine: &Engine, hero: Entity, f: F) -> Result<()>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Inventory) -> S,
|
A: Ability + 'static,
|
||||||
|
F: FnOnce(&mut Inventory<A>) -> S,
|
||||||
S: Storable,
|
S: Storable,
|
||||||
{
|
{
|
||||||
engine.on_scene_mut(|scene| {
|
engine.on_scene_mut(|scene| {
|
||||||
|
@ -261,7 +267,7 @@ impl CharacterWindow {
|
||||||
let mut multi_mut = entity.multi_mut();
|
let mut multi_mut = entity.multi_mut();
|
||||||
|
|
||||||
let crafting_materials = multi_mut.get::<CraftingMaterials>()?;
|
let crafting_materials = multi_mut.get::<CraftingMaterials>()?;
|
||||||
let inventory = multi_mut.get::<Inventory>()?;
|
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||||
|
|
||||||
// remove callback
|
// remove callback
|
||||||
let storable = f(inventory);
|
let storable = f(inventory);
|
||||||
|
|
|
@ -17,15 +17,15 @@ impl RightSide for EmptyRightSide {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PageContent<T: Send + Sync> {
|
pub struct PageContent<A: Ability + 'static, T: Send + Sync> {
|
||||||
content: Content<T>,
|
content: Content<A, T>,
|
||||||
tooltip: Arc<GuiSnippet>,
|
tooltip: Arc<GuiSnippet>,
|
||||||
|
|
||||||
right_side: Box<dyn RightSide>,
|
right_side: Box<dyn RightSide>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Send + Sync> PageContent<T> {
|
impl<A: Ability + 'static, T: Send + Sync> PageContent<A, T> {
|
||||||
pub fn new<R>(content: Content<T>, tooltip: Arc<GuiSnippet>, right_side: R) -> Self
|
pub fn new<R>(content: Content<A, T>, tooltip: Arc<GuiSnippet>, right_side: R) -> Self
|
||||||
where
|
where
|
||||||
R: RightSide + 'static,
|
R: RightSide + 'static,
|
||||||
{
|
{
|
||||||
|
@ -37,9 +37,9 @@ impl<T: Send + Sync> PageContent<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Send + Sync> PageContentWrapper for PageContent<T>
|
impl<A: Ability + 'static, T: Send + Sync> PageContentWrapper for PageContent<A, T>
|
||||||
where
|
where
|
||||||
Content<T>: ContentUpdate,
|
Content<A, T>: ContentUpdate,
|
||||||
{
|
{
|
||||||
fn content(&self) -> &dyn ContentWrapper {
|
fn content(&self) -> &dyn ContentWrapper {
|
||||||
&self.content
|
&self.content
|
||||||
|
|
|
@ -5,14 +5,6 @@ use engine::prelude::*;
|
||||||
use cgmath::Vector3;
|
use cgmath::Vector3;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
ability_type::AbilityType,
|
|
||||||
damage_type::DamageType,
|
|
||||||
items::{ability_addon::AbilityAddonCollection, ability_book::Ability},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::statistics::Statistics;
|
|
||||||
|
|
||||||
const ABILITY_SUFFIX: &str = ".abil";
|
const ABILITY_SUFFIX: &str = ".abil";
|
||||||
|
|
||||||
create_settings_section!(
|
create_settings_section!(
|
|
@ -1,4 +1,5 @@
|
||||||
mod ability_location_info;
|
mod ability_location_info;
|
||||||
|
pub mod abilityloader;
|
||||||
pub mod ai;
|
pub mod ai;
|
||||||
mod aoe;
|
mod aoe;
|
||||||
pub mod aoe_arc;
|
pub mod aoe_arc;
|
||||||
|
|
|
@ -2,5 +2,6 @@ pub mod abilities;
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod objects;
|
pub mod objects;
|
||||||
|
|
||||||
|
pub mod ability_type;
|
||||||
pub mod lightning;
|
pub mod lightning;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
pub use super::abilities::prelude::*;
|
pub use super::abilities::prelude::*;
|
||||||
|
pub use super::ability_type::AbilityType;
|
||||||
pub use super::components::*;
|
pub use super::components::*;
|
||||||
pub use super::lightning::{Lightning, LightningMarker};
|
pub use super::lightning::{Lightning, LightningMarker};
|
||||||
pub use super::objects::hero::{Hero, MainUser};
|
pub use super::objects::hero::{Hero, MainUser};
|
||||||
|
|
|
@ -8,9 +8,9 @@ use std::{
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::config::save_game::SaveGame;
|
|
||||||
use crate::items::{ability_addon::AbilityAddonTypes, ability_book::AbilityBook, Rarities};
|
use crate::items::{ability_addon::AbilityAddonTypes, ability_book::AbilityBook, Rarities};
|
||||||
use crate::{components::inventory::Storable, items::ItemSystem};
|
use crate::{components::inventory::Storable, items::ItemSystem};
|
||||||
|
use crate::{config::save_game::SaveGame, items::ability_book::Ability};
|
||||||
|
|
||||||
macro_rules! load {
|
macro_rules! load {
|
||||||
($me: ident, $item_system:ident, $save_game:ident, $($index:literal,)+) => {
|
($me: ident, $item_system:ident, $save_game:ident, $($index:literal,)+) => {
|
||||||
|
@ -67,16 +67,16 @@ macro_rules! store {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AbilitySlots {
|
|
||||||
pub direction: Vector2<f32>,
|
|
||||||
|
|
||||||
abilities: [Option<AbilityBook>; AbilitySlots::MAX_ABILITIES],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AbilitySlots {
|
|
||||||
// stupid workaround for serde Deserialize
|
// stupid workaround for serde Deserialize
|
||||||
pub const MAX_ABILITIES: usize = 4;
|
pub const MAX_ABILITIES: usize = 4;
|
||||||
|
|
||||||
|
pub struct AbilitySlots<A: Ability> {
|
||||||
|
pub direction: Vector2<f32>,
|
||||||
|
|
||||||
|
abilities: [Option<AbilityBook<A>>; MAX_ABILITIES],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Ability> AbilitySlots<A> {
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self {
|
Self {
|
||||||
direction: Vector2::zero(),
|
direction: Vector2::zero(),
|
||||||
|
@ -84,7 +84,7 @@ impl AbilitySlots {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(item_system: &ItemSystem, save_game: &SaveGame) -> Result<Self> {
|
pub fn load(item_system: &ItemSystem<A>, save_game: &SaveGame) -> Result<Self> {
|
||||||
let mut me = Self::empty();
|
let mut me = Self::empty();
|
||||||
|
|
||||||
load!(me, item_system, save_game, 0, 1, 2, 3,);
|
load!(me, item_system, save_game, 0, 1, 2, 3,);
|
||||||
|
@ -96,7 +96,7 @@ impl AbilitySlots {
|
||||||
store!(self, save_game, 0, 1, 2, 3,);
|
store!(self, save_game, 0, 1, 2, 3,);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_book(&mut self, book: AbilityBook, index: usize) -> Option<AbilityBook> {
|
pub fn insert_book(&mut self, book: AbilityBook<A>, index: usize) -> Option<AbilityBook<A>> {
|
||||||
match self.abilities[index].clone() {
|
match self.abilities[index].clone() {
|
||||||
Some(ability) => {
|
Some(ability) => {
|
||||||
if ability != book {
|
if ability != book {
|
||||||
|
@ -119,30 +119,30 @@ impl AbilitySlots {
|
||||||
// self.abilities[index] = None;
|
// self.abilities[index] = None;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn book(&self, index: usize) -> Option<&AbilityBook> {
|
pub fn book(&self, index: usize) -> Option<&AbilityBook<A>> {
|
||||||
self.abilities[index].as_ref()
|
self.abilities[index].as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn book_mut(&mut self, index: usize) -> Option<&mut AbilityBook> {
|
pub fn book_mut(&mut self, index: usize) -> Option<&mut AbilityBook<A>> {
|
||||||
self.abilities[index].as_mut()
|
self.abilities[index].as_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> Iter<'_, Option<AbilityBook>> {
|
pub fn iter(&self) -> Iter<'_, Option<AbilityBook<A>>> {
|
||||||
self.abilities.iter()
|
self.abilities.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> IterMut<'_, Option<AbilityBook>> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, Option<AbilityBook<A>>> {
|
||||||
self.abilities.iter_mut()
|
self.abilities.iter_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EntityComponent for AbilitySlots {
|
impl<A: Ability + 'static> EntityComponent for AbilitySlots<A> {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
Self::debug_name()
|
Self::debug_name()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentDebug for AbilitySlots {
|
impl<A: Ability> ComponentDebug for AbilitySlots<A> {
|
||||||
fn debug_name() -> &'static str {
|
fn debug_name() -> &'static str {
|
||||||
"AbilitySlots"
|
"AbilitySlots"
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{cmp::Ordering, slice::Iter, str::FromStr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::attributes::{AttributeColorSettings, StartingAttributes},
|
config::attributes::{AttributeColorSettings, StartingAttributes},
|
||||||
items::ItemSystem,
|
items::{ability_book::Ability, ItemSystem},
|
||||||
};
|
};
|
||||||
|
|
||||||
generate_stat!(Agility, u32, "Agility");
|
generate_stat!(Agility, u32, "Agility");
|
||||||
|
@ -37,12 +37,12 @@ impl Attribute {
|
||||||
ATTRIBUTES.iter()
|
ATTRIBUTES.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_color(
|
pub fn apply_color<A: Ability>(
|
||||||
&self,
|
&self,
|
||||||
base_image: &RgbaImage,
|
base_image: &RgbaImage,
|
||||||
color_settins: &AttributeColorSettings,
|
color_settins: &AttributeColorSettings,
|
||||||
) -> RgbaImage {
|
) -> RgbaImage {
|
||||||
ItemSystem::apply_color(base_image, color_settins.from_attribute(*self))
|
ItemSystem::<A>::apply_color(base_image, color_settins.from_attribute(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,9 @@ use std::sync::Arc;
|
||||||
use crate::{
|
use crate::{
|
||||||
config::save_game::SaveGame,
|
config::save_game::SaveGame,
|
||||||
items::{
|
items::{
|
||||||
ability_addon::AbilityAddon, ability_book::AbilityBook, Item, ItemSystem, Jewel, MapItem,
|
ability_addon::AbilityAddon,
|
||||||
Rarities,
|
ability_book::{Ability, AbilityBook},
|
||||||
|
Item, ItemSystem, Jewel, MapItem, Rarities,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,15 +18,15 @@ pub trait Storable {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct Inventory {
|
pub struct Inventory<A: Ability> {
|
||||||
items: Vec<Item>,
|
items: Vec<Item>,
|
||||||
addons: Vec<AbilityAddon>,
|
addons: Vec<AbilityAddon>,
|
||||||
books: Vec<AbilityBook>,
|
books: Vec<AbilityBook<A>>,
|
||||||
jewels: Vec<Jewel>,
|
jewels: Vec<Jewel>,
|
||||||
maps: Vec<MapItem>,
|
maps: Vec<MapItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Inventory {
|
impl<A: Ability> Inventory<A> {
|
||||||
// ------- items --------
|
// ------- items --------
|
||||||
pub fn add_item(&mut self, item: Item) {
|
pub fn add_item(&mut self, item: Item) {
|
||||||
self.items.push(item);
|
self.items.push(item);
|
||||||
|
@ -123,30 +124,30 @@ impl Inventory {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------- books --------
|
// ------- books --------
|
||||||
pub fn add_book(&mut self, book: AbilityBook) {
|
pub fn add_book(&mut self, book: AbilityBook<A>) {
|
||||||
self.books.push(book);
|
self.books.push(book);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_book(&mut self, book: AbilityBook, index: usize) {
|
pub fn insert_book(&mut self, book: AbilityBook<A>, index: usize) {
|
||||||
self.books.insert(index, book);
|
self.books.insert(index, book);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_book(&mut self, index: usize) -> AbilityBook {
|
pub fn remove_book(&mut self, index: usize) -> AbilityBook<A> {
|
||||||
self.books.remove(index)
|
self.books.remove(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_books(&self) -> Iter<'_, AbilityBook> {
|
pub fn iter_books(&self) -> Iter<'_, AbilityBook<A>> {
|
||||||
self.books.iter()
|
self.books.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn book_at(&self, index: usize) -> &AbilityBook {
|
pub fn book_at(&self, index: usize) -> &AbilityBook<A> {
|
||||||
&self.books[index]
|
&self.books[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Inventory {
|
impl<A: Ability> Inventory<A> {
|
||||||
pub fn load(save_game: &SaveGame, item_system: &ItemSystem) -> Result<Self> {
|
pub fn load(save_game: &SaveGame, item_system: &ItemSystem<A>) -> Result<Self> {
|
||||||
let mut inventory = Inventory::default();
|
let mut inventory: Inventory<A> = Default::default();
|
||||||
|
|
||||||
for item_string in save_game.inventory.items.iter() {
|
for item_string in save_game.inventory.items.iter() {
|
||||||
if !item_string.is_empty() {
|
if !item_string.is_empty() {
|
||||||
|
@ -219,13 +220,13 @@ impl Inventory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EntityComponent for Inventory {
|
impl<A: Ability + 'static> EntityComponent for Inventory<A> {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
Self::debug_name()
|
Self::debug_name()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentDebug for Inventory {
|
impl<A: Ability> ComponentDebug for Inventory<A> {
|
||||||
fn debug_name() -> &'static str {
|
fn debug_name() -> &'static str {
|
||||||
"Inventory"
|
"Inventory"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{items::ItemSettings, save_game::SaveGame},
|
config::{items::ItemSettings, save_game::SaveGame},
|
||||||
items::{Item, ItemAffix, ItemSlots, ItemSystem, Rarities},
|
items::{ability_book::Ability, Item, ItemAffix, ItemSlots, ItemSystem, Rarities},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -177,7 +177,7 @@ impl ItemSlotContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(save_game: &SaveGame, item_system: &ItemSystem) -> Result<Self> {
|
pub fn load<A: Ability>(save_game: &SaveGame, item_system: &ItemSystem<A>) -> Result<Self> {
|
||||||
let mut me = Self::new();
|
let mut me = Self::new();
|
||||||
|
|
||||||
load_item!(me, chest_plate, ChestPlate, save_game, item_system);
|
load_item!(me, chest_plate, ChestPlate, save_game, item_system);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
|
|
||||||
pub mod ability_slots;
|
pub mod ability_slots;
|
||||||
pub mod abilityloader;
|
|
||||||
pub mod attributes;
|
pub mod attributes;
|
||||||
pub mod character_status;
|
pub mod character_status;
|
||||||
pub mod crafting_materials;
|
pub mod crafting_materials;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
crafting_materials::CraftingMaterials, inventory::Inventory, item_slots::ItemSlotContainer,
|
crafting_materials::CraftingMaterials, inventory::Inventory, item_slots::ItemSlotContainer,
|
||||||
level::Level, statistics::Statistics,
|
level::Level, statistics::Statistics,
|
||||||
},
|
},
|
||||||
items::{ItemAffix, ItemSystem, Rarities},
|
items::{ability_book::Ability, ItemAffix, ItemSystem, Rarities},
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::env::var;
|
use std::env::var;
|
||||||
|
@ -359,13 +359,16 @@ create_settings_container!(
|
||||||
);
|
);
|
||||||
|
|
||||||
impl SaveGame {
|
impl SaveGame {
|
||||||
pub fn to_entity_object(self, engine: &Engine) -> Result<(Entity, String)> {
|
pub fn to_entity_object<A: Ability + 'static>(
|
||||||
|
self,
|
||||||
|
engine: &Engine,
|
||||||
|
) -> Result<(Entity, String)> {
|
||||||
let scene = engine.scene_mut();
|
let scene = engine.scene_mut();
|
||||||
|
|
||||||
let experience_settings = scene.resources.get::<ExperienceSettings>();
|
let experience_settings = scene.resources.get::<ExperienceSettings>();
|
||||||
let attribute_settings = scene.resources.get::<AttributeSettings>();
|
let attribute_settings = scene.resources.get::<AttributeSettings>();
|
||||||
let item_settings = scene.resources.get::<ItemSettings>();
|
let item_settings = scene.resources.get::<ItemSettings>();
|
||||||
let item_system = scene.resources.get::<ItemSystem>();
|
let item_system = scene.resources.get::<ItemSystem<A>>();
|
||||||
|
|
||||||
let mut entity_object = engine.assets().empty_entity();
|
let mut entity_object = engine.assets().empty_entity();
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,9 @@ use std::{
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{components::inventory::Storable, config::abilities::AbilitySettings};
|
||||||
ability_type::AbilityType, components::inventory::Storable, config::abilities::AbilitySettings,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{ItemSystem, Rarities, Tooltip};
|
use super::{ability_book::Ability, ItemSystem, Rarities, Tooltip};
|
||||||
|
|
||||||
const COOL_DOWN_REDUCTION_CAP: f32 = 0.7;
|
const COOL_DOWN_REDUCTION_CAP: f32 = 0.7;
|
||||||
|
|
||||||
|
@ -102,32 +100,6 @@ impl AbilityAddonTypes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_allowed_for(&self, ability_type: AbilityType) -> bool {
|
|
||||||
match ability_type {
|
|
||||||
AbilityType::SelfCast => match self {
|
|
||||||
Self::Damage(_) => true,
|
|
||||||
Self::ProjectileSpeed(_) => false,
|
|
||||||
Self::Bounce => false,
|
|
||||||
Self::Explosion(_) => false,
|
|
||||||
Self::Size(_) => true,
|
|
||||||
Self::Projectiles(_) => false,
|
|
||||||
Self::CoolDown(_) => true,
|
|
||||||
Self::Distance(_) => false,
|
|
||||||
},
|
|
||||||
|
|
||||||
AbilityType::Projectile => match self {
|
|
||||||
Self::Damage(_) => true,
|
|
||||||
Self::ProjectileSpeed(_) => true,
|
|
||||||
Self::Bounce => true,
|
|
||||||
Self::Explosion(_) => true,
|
|
||||||
Self::Size(_) => true,
|
|
||||||
Self::Projectiles(_) => true,
|
|
||||||
Self::CoolDown(_) => true,
|
|
||||||
Self::Distance(_) => true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_zero(self) -> Self {
|
pub fn into_zero(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
AbilityAddonTypes::Damage(_) => AbilityAddonTypes::Damage(0),
|
AbilityAddonTypes::Damage(_) => AbilityAddonTypes::Damage(0),
|
||||||
|
@ -262,9 +234,9 @@ impl AbilityAddon {
|
||||||
format!("{}|{}", self.addon_type(), self.rarity())
|
format!("{}|{}", self.addon_type(), self.rarity())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_persistent<'a>(
|
pub fn from_persistent<'a, A: Ability>(
|
||||||
mut split: impl Iterator<Item = &'a str>,
|
mut split: impl Iterator<Item = &'a str>,
|
||||||
item_system: &ItemSystem,
|
item_system: &ItemSystem<A>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let addon_type = AbilityAddonTypes::from_str(split.next().unwrap())?;
|
let addon_type = AbilityAddonTypes::from_str(split.next().unwrap())?;
|
||||||
let rarity = Rarities::from_str(split.next().unwrap())?;
|
let rarity = Rarities::from_str(split.next().unwrap())?;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use assetpath::AssetPath;
|
||||||
use cgmath::{Vector2, Vector3};
|
use cgmath::{Vector2, Vector3};
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
|
||||||
|
@ -6,10 +7,11 @@ use std::{fmt::Debug, str::FromStr, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
components::{
|
components::{
|
||||||
abilityloader::AbilityLoader, character_status::CharacterStatus,
|
character_status::CharacterStatus, crafting_materials::CraftingMaterials,
|
||||||
crafting_materials::CraftingMaterials, inventory::Storable, statistics::Statistics,
|
inventory::Storable, statistics::Statistics,
|
||||||
},
|
},
|
||||||
config::abilities::{AbilityLevel, AbilitySettings},
|
config::abilities::{AbilityLevel, AbilitySettings},
|
||||||
|
damage_type::DamageType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -17,19 +19,17 @@ use super::{
|
||||||
ItemSystem, Rarities, Tooltip,
|
ItemSystem, Rarities, Tooltip,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
pub trait Ability: Send + Sync + Clone + Default {
|
||||||
pub struct Ability {
|
fn create(asset_path: impl Into<AssetPath>) -> Result<Self>;
|
||||||
pub(crate) data: AbilityLoader,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ability {
|
fn name(&self) -> &str;
|
||||||
pub fn data(&self) -> &AbilityLoader {
|
fn icon_path(&self) -> &AssetPath;
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name(&self) -> &str {
|
fn cool_down(&self) -> Duration;
|
||||||
self.data.name()
|
fn mana_cost(&self) -> u32;
|
||||||
}
|
fn mana_cost_per_level(&self) -> u32;
|
||||||
|
fn damage_type(&self) -> DamageType;
|
||||||
|
fn damage(&self, level: u32, addons: &AbilityAddonCollection, statistics: &Statistics) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
@ -40,8 +40,8 @@ pub struct CastInformation {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AbilityBook {
|
pub struct AbilityBook<A: Ability> {
|
||||||
ability: Ability,
|
ability: A,
|
||||||
|
|
||||||
// meta
|
// meta
|
||||||
icon: Arc<Image>,
|
icon: Arc<Image>,
|
||||||
|
@ -57,9 +57,9 @@ pub struct AbilityBook {
|
||||||
last_cast: Option<CastInformation>,
|
last_cast: Option<CastInformation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbilityBook {
|
impl<A: Ability> AbilityBook<A> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
ability: Ability,
|
ability: A,
|
||||||
icon: Arc<Image>,
|
icon: Arc<Image>,
|
||||||
rarity: Rarities,
|
rarity: Rarities,
|
||||||
ability_settings: &AbilitySettings,
|
ability_settings: &AbilitySettings,
|
||||||
|
@ -83,7 +83,7 @@ impl AbilityBook {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(
|
pub fn load(
|
||||||
ability: Ability,
|
ability: A,
|
||||||
icon: Arc<Image>,
|
icon: Arc<Image>,
|
||||||
rarity: Rarities,
|
rarity: Rarities,
|
||||||
addons: Vec<Option<AbilityAddon>>,
|
addons: Vec<Option<AbilityAddon>>,
|
||||||
|
@ -122,7 +122,7 @@ impl AbilityBook {
|
||||||
|
|
||||||
if let Some(cast_information) = &self.last_cast {
|
if let Some(cast_information) = &self.last_cast {
|
||||||
let total_cool_down = Duration::from_secs_f32({
|
let total_cool_down = Duration::from_secs_f32({
|
||||||
let d: Duration = self.ability.data().settings.parameter.cool_down.into();
|
let d = self.ability.cool_down();
|
||||||
|
|
||||||
d.as_secs_f32() * (1.0 - self.addons.cool_down_reduction())
|
d.as_secs_f32() * (1.0 - self.addons.cool_down_reduction())
|
||||||
});
|
});
|
||||||
|
@ -174,12 +174,7 @@ impl AbilityBook {
|
||||||
match &self.last_cast {
|
match &self.last_cast {
|
||||||
Some(cast_information) => {
|
Some(cast_information) => {
|
||||||
let total_cool_down = Duration::from_secs_f32(
|
let total_cool_down = Duration::from_secs_f32(
|
||||||
self.ability
|
self.ability.cool_down().as_secs_f32()
|
||||||
.data()
|
|
||||||
.settings
|
|
||||||
.parameter
|
|
||||||
.cool_down
|
|
||||||
.as_secs_f32()
|
|
||||||
* (1.0 - self.addons.cool_down_reduction()),
|
* (1.0 - self.addons.cool_down_reduction()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -197,7 +192,7 @@ impl AbilityBook {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ability(&self) -> &Ability {
|
pub fn ability(&self) -> &A {
|
||||||
&self.ability
|
&self.ability
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,10 +237,7 @@ impl AbilityBook {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mana_cost(&self) -> u32 {
|
pub fn mana_cost(&self) -> u32 {
|
||||||
let data = self.ability.data();
|
self.ability.mana_cost() + self.ability.mana_cost_per_level() * (self.level - 1)
|
||||||
|
|
||||||
data.settings.parameter.base_mana_cost
|
|
||||||
+ data.settings.parameter.mana_cost_per_level * (self.level - 1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_persistent(&self) -> String {
|
pub fn into_persistent(&self) -> String {
|
||||||
|
@ -260,7 +252,7 @@ impl AbilityBook {
|
||||||
|
|
||||||
pub fn from_persistent<'a>(
|
pub fn from_persistent<'a>(
|
||||||
mut split: impl Iterator<Item = &'a str>,
|
mut split: impl Iterator<Item = &'a str>,
|
||||||
item_system: &ItemSystem,
|
item_system: &ItemSystem<A>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let name = split.next().unwrap();
|
let name = split.next().unwrap();
|
||||||
let rarity = Rarities::from_str(split.next().unwrap())?;
|
let rarity = Rarities::from_str(split.next().unwrap())?;
|
||||||
|
@ -315,22 +307,19 @@ impl AbilityBook {
|
||||||
let damage: Arc<Label> = gui.element("damage")?;
|
let damage: Arc<Label> = gui.element("damage")?;
|
||||||
let cooldown: Arc<Label> = gui.element("cooldown")?;
|
let cooldown: Arc<Label> = gui.element("cooldown")?;
|
||||||
|
|
||||||
let data = self.ability().data();
|
|
||||||
|
|
||||||
mana_costs.set_text(self.mana_cost())?;
|
mana_costs.set_text(self.mana_cost())?;
|
||||||
damage.set_text(data.damage(self.level(), self.addons(), statistics))?;
|
damage.set_text(self.ability.damage(self.level(), self.addons(), statistics))?;
|
||||||
damage.set_text_color(data.settings.parameter.damage_type.into())?;
|
damage.set_text_color(self.ability.damage_type().into())?;
|
||||||
cooldown.set_text(format!(
|
cooldown.set_text(format!(
|
||||||
"{:.1} s",
|
"{:.1} s",
|
||||||
data.settings.parameter.cool_down.as_secs_f32()
|
self.ability.cool_down().as_secs_f32() * (1.0 - self.addons().cool_down_reduction())
|
||||||
* (1.0 - self.addons().cool_down_reduction())
|
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
Ok(Tooltip::new(inspector_grid, gui, gui_handler.clone()))
|
Ok(Tooltip::new(inspector_grid, gui, gui_handler.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for AbilityBook {
|
impl<A: Ability> Debug for AbilityBook<A> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("AbilityBook")
|
f.debug_struct("AbilityBook")
|
||||||
.field("rarity", &self.rarity)
|
.field("rarity", &self.rarity)
|
||||||
|
@ -341,16 +330,16 @@ impl Debug for AbilityBook {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for AbilityBook {
|
impl<A: Ability> PartialEq for AbilityBook<A> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.ability.data() == other.ability.data()
|
self.ability.name() == other.ability.name()
|
||||||
&& self.rarity == other.rarity
|
&& self.rarity == other.rarity
|
||||||
&& self.addons == other.addons
|
&& self.addons == other.addons
|
||||||
&& self.level == other.level
|
&& self.level == other.level
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Storable for AbilityBook {
|
impl<A: Ability> Storable for AbilityBook<A> {
|
||||||
fn rarity(&self) -> Rarities {
|
fn rarity(&self) -> Rarities {
|
||||||
self.rarity
|
self.rarity
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
||||||
config::items::ItemSettings,
|
config::items::ItemSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{ItemSlots, ItemSystem, Jewel, Rarities, Tooltip};
|
use super::{ability_book::Ability, ItemSlots, ItemSystem, Jewel, Rarities, Tooltip};
|
||||||
|
|
||||||
const ITEM_SNIPPETS: [&'static str; 8] = [
|
const ITEM_SNIPPETS: [&'static str; 8] = [
|
||||||
include_str!("../../resources/items/slots_0.xml"),
|
include_str!("../../resources/items/slots_0.xml"),
|
||||||
|
@ -155,9 +155,9 @@ impl Item {
|
||||||
base
|
base
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_persistent<'a>(
|
pub fn from_persistent<'a, A: Ability>(
|
||||||
mut split: impl Iterator<Item = &'a str>,
|
mut split: impl Iterator<Item = &'a str>,
|
||||||
item_system: &ItemSystem,
|
item_system: &ItemSystem<A>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let slot = ItemSlots::from_str(split.next().unwrap())?;
|
let slot = ItemSlots::from_str(split.next().unwrap())?;
|
||||||
let rarity = Rarities::from_str(split.next().unwrap())?;
|
let rarity = Rarities::from_str(split.next().unwrap())?;
|
||||||
|
|
|
@ -7,7 +7,6 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use image::{imageops::FilterType, DynamicImage, ImageBuffer, Pixel, Rgba, RgbaImage};
|
use image::{imageops::FilterType, DynamicImage, ImageBuffer, Pixel, Rgba, RgbaImage};
|
||||||
|
|
||||||
use crate::components::abilityloader::AbilityLoader;
|
|
||||||
use crate::components::attributes::{Attribute, Attributes};
|
use crate::components::attributes::{Attribute, Attributes};
|
||||||
use crate::components::inventory::Storable;
|
use crate::components::inventory::Storable;
|
||||||
use crate::components::statistic_types::{
|
use crate::components::statistic_types::{
|
||||||
|
@ -22,14 +21,14 @@ use super::ability_book::{Ability, AbilityBook};
|
||||||
use super::{Item, ItemAffix, ItemSlots, Jewel, Rarities};
|
use super::{Item, ItemAffix, ItemSlots, Jewel, Rarities};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Loot {
|
pub enum Loot<A: Ability> {
|
||||||
Item(Item),
|
Item(Item),
|
||||||
AbilityBook(AbilityBook),
|
AbilityBook(AbilityBook<A>),
|
||||||
AbilityAddOn(AbilityAddon),
|
AbilityAddOn(AbilityAddon),
|
||||||
Jewel(Jewel),
|
Jewel(Jewel),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Loot {
|
impl<A: Ability> Loot<A> {
|
||||||
pub fn storable(&self) -> &dyn Storable {
|
pub fn storable(&self) -> &dyn Storable {
|
||||||
match self {
|
match self {
|
||||||
Loot::Item(item) => item,
|
Loot::Item(item) => item,
|
||||||
|
@ -40,7 +39,7 @@ impl Loot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ItemSystem {
|
pub struct ItemSystem<A: Ability> {
|
||||||
pub item_settings: ItemSettings,
|
pub item_settings: ItemSettings,
|
||||||
ability_settings: AbilitySettings,
|
ability_settings: AbilitySettings,
|
||||||
|
|
||||||
|
@ -49,25 +48,24 @@ pub struct ItemSystem {
|
||||||
addon_icon_combinations: HashMap<(Rarities, AbilityAddonTypes), Arc<Image>>,
|
addon_icon_combinations: HashMap<(Rarities, AbilityAddonTypes), Arc<Image>>,
|
||||||
jewel_icon_combinations: HashMap<(Rarities, u32, Attribute), Arc<Image>>,
|
jewel_icon_combinations: HashMap<(Rarities, u32, Attribute), Arc<Image>>,
|
||||||
|
|
||||||
abilities: Vec<Ability>,
|
abilities: Vec<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemSystem {
|
impl<A: Ability> ItemSystem<A> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
engine: &Arc<Engine>,
|
engine: &Arc<Engine>,
|
||||||
item_settings: &ItemSettings,
|
item_settings: &ItemSettings,
|
||||||
ability_settings: &AbilitySettings,
|
ability_settings: &AbilitySettings,
|
||||||
attribute_settings: &AttributeSettings,
|
attribute_settings: &AttributeSettings,
|
||||||
ability_directory: &AssetPath,
|
ability_directory: &AssetPath,
|
||||||
data_directory: &str,
|
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
// verify that drop chances sum up to 1.0
|
// verify that drop chances sum up to 1.0
|
||||||
item_settings.rarity_drop_rates.verify();
|
item_settings.rarity_drop_rates.verify();
|
||||||
|
|
||||||
let ability_loader = AbilityLoader::list_all_ability_files(ability_directory)?
|
let abilities = search_dir_recursively(&ability_directory.full_path(), ".abil")?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|path| AbilityLoader::load(data_directory, path))
|
.map(|path| A::create(path))
|
||||||
.collect::<Result<Vec<AbilityLoader>>>()?;
|
.collect::<Result<Vec<A>>>()?;
|
||||||
|
|
||||||
let (
|
let (
|
||||||
item_icon_combinations,
|
item_icon_combinations,
|
||||||
|
@ -89,8 +87,8 @@ impl ItemSystem {
|
||||||
// image for ability book
|
// image for ability book
|
||||||
let mut ability_images = Vec::new();
|
let mut ability_images = Vec::new();
|
||||||
|
|
||||||
for loader in ability_loader.iter() {
|
for loader in abilities.iter() {
|
||||||
let path = &loader.settings.meta.icon;
|
let path = loader.icon_path();
|
||||||
|
|
||||||
if !path.is_empty() {
|
if !path.is_empty() {
|
||||||
ability_images.push((loader.name().to_string(), Self::dyn_image(path)?));
|
ability_images.push((loader.name().to_string(), Self::dyn_image(path)?));
|
||||||
|
@ -140,7 +138,10 @@ impl ItemSystem {
|
||||||
for rarity in Rarities::iter() {
|
for rarity in Rarities::iter() {
|
||||||
let final_image = Self::blend_background(
|
let final_image = Self::blend_background(
|
||||||
icon,
|
icon,
|
||||||
&rarity.apply_color(&base_background, &item_settings.rarity_color_settings),
|
&rarity.apply_color::<A>(
|
||||||
|
&base_background,
|
||||||
|
&item_settings.rarity_color_settings,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (width, height) = final_image.dimensions();
|
let (width, height) = final_image.dimensions();
|
||||||
|
@ -165,7 +166,10 @@ impl ItemSystem {
|
||||||
for rarity in Rarities::iter() {
|
for rarity in Rarities::iter() {
|
||||||
let final_image = Self::blend_background(
|
let final_image = Self::blend_background(
|
||||||
&image,
|
&image,
|
||||||
&rarity.apply_color(&base_background, &item_settings.rarity_color_settings),
|
&rarity.apply_color::<A>(
|
||||||
|
&base_background,
|
||||||
|
&item_settings.rarity_color_settings,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (width, height) = final_image.dimensions();
|
let (width, height) = final_image.dimensions();
|
||||||
|
@ -189,8 +193,10 @@ impl ItemSystem {
|
||||||
for (addon_type, icon) in ability_addon_icons.iter() {
|
for (addon_type, icon) in ability_addon_icons.iter() {
|
||||||
for rarity in Rarities::iter() {
|
for rarity in Rarities::iter() {
|
||||||
let final_image = Self::blend_apply(
|
let final_image = Self::blend_apply(
|
||||||
&rarity
|
&rarity.apply_color::<A>(
|
||||||
.apply_color(&addon_background, &item_settings.rarity_color_settings),
|
&addon_background,
|
||||||
|
&item_settings.rarity_color_settings,
|
||||||
|
),
|
||||||
icon,
|
icon,
|
||||||
|rarity_color, icon_color| {
|
|rarity_color, icon_color| {
|
||||||
// let (r1, g1, b1, a1) = rarity_color.channels4();
|
// let (r1, g1, b1, a1) = rarity_color.channels4();
|
||||||
|
@ -224,13 +230,13 @@ impl ItemSystem {
|
||||||
|
|
||||||
for (level, icon) in jewel_icons.iter() {
|
for (level, icon) in jewel_icons.iter() {
|
||||||
for attribute in Attribute::iter() {
|
for attribute in Attribute::iter() {
|
||||||
let attribute_icon =
|
let attribute_icon = attribute
|
||||||
attribute.apply_color(&icon, &attribute_settings.attribute_color_settings);
|
.apply_color::<A>(&icon, &attribute_settings.attribute_color_settings);
|
||||||
|
|
||||||
for rarity in Rarities::iter() {
|
for rarity in Rarities::iter() {
|
||||||
let final_image = Self::blend_background(
|
let final_image = Self::blend_background(
|
||||||
&attribute_icon,
|
&attribute_icon,
|
||||||
&rarity.apply_color(
|
&rarity.apply_color::<A>(
|
||||||
&base_background,
|
&base_background,
|
||||||
&item_settings.rarity_color_settings,
|
&item_settings.rarity_color_settings,
|
||||||
),
|
),
|
||||||
|
@ -260,11 +266,6 @@ impl ItemSystem {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let abilities = ability_loader
|
|
||||||
.into_iter()
|
|
||||||
.map(|loader| loader.create_ability())
|
|
||||||
.collect::<Vec<Ability>>();
|
|
||||||
|
|
||||||
Ok(ItemSystem {
|
Ok(ItemSystem {
|
||||||
item_settings: item_settings.clone(),
|
item_settings: item_settings.clone(),
|
||||||
ability_settings: ability_settings.clone(),
|
ability_settings: ability_settings.clone(),
|
||||||
|
@ -293,7 +294,7 @@ impl ItemSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// only here for debugging
|
/// only here for debugging
|
||||||
pub fn get_legendary_random_loot(&self, level: u32) -> Loot {
|
pub fn get_legendary_random_loot(&self, level: u32) -> Loot<A> {
|
||||||
// decide which type of loot gets dropped
|
// decide which type of loot gets dropped
|
||||||
let loot_type_p = Random::range_f32(0.0, 1.0);
|
let loot_type_p = Random::range_f32(0.0, 1.0);
|
||||||
let rarity = Rarities::Legendary;
|
let rarity = Rarities::Legendary;
|
||||||
|
@ -320,7 +321,11 @@ impl ItemSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_random_loot(&self, level: u32, drop_chance_multiplier: Option<f32>) -> Option<Loot> {
|
pub fn get_random_loot(
|
||||||
|
&self,
|
||||||
|
level: u32,
|
||||||
|
drop_chance_multiplier: Option<f32>,
|
||||||
|
) -> Option<Loot<A>> {
|
||||||
let drop_chance = match drop_chance_multiplier {
|
let drop_chance = match drop_chance_multiplier {
|
||||||
Some(multiplier) => multiplier * self.item_settings.general.drop_chance,
|
Some(multiplier) => multiplier * self.item_settings.general.drop_chance,
|
||||||
None => self.item_settings.general.drop_chance,
|
None => self.item_settings.general.drop_chance,
|
||||||
|
@ -358,7 +363,7 @@ impl ItemSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn random_ability_book(&self, rarity: Rarities) -> AbilityBook {
|
pub fn random_ability_book(&self, rarity: Rarities) -> AbilityBook<A> {
|
||||||
let ability = self.random_ability();
|
let ability = self.random_ability();
|
||||||
let ability_icon = self.ability_icon(ability.name(), rarity);
|
let ability_icon = self.ability_icon(ability.name(), rarity);
|
||||||
|
|
||||||
|
@ -451,7 +456,7 @@ impl ItemSystem {
|
||||||
rarity: Rarities,
|
rarity: Rarities,
|
||||||
addons: Vec<Option<AbilityAddon>>,
|
addons: Vec<Option<AbilityAddon>>,
|
||||||
level: u32,
|
level: u32,
|
||||||
) -> AbilityBook {
|
) -> AbilityBook<A> {
|
||||||
AbilityBook::load(
|
AbilityBook::load(
|
||||||
self.find_ability(ability_name),
|
self.find_ability(ability_name),
|
||||||
self.ability_icon(ability_name, rarity),
|
self.ability_icon(ability_name, rarity),
|
||||||
|
@ -545,7 +550,7 @@ impl ItemSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn find_ability(&self, name: &str) -> Ability {
|
pub fn find_ability(&self, name: &str) -> A {
|
||||||
self.abilities
|
self.abilities
|
||||||
.iter()
|
.iter()
|
||||||
.find(|a| a.name() == name)
|
.find(|a| a.name() == name)
|
||||||
|
@ -554,7 +559,7 @@ impl ItemSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn random_ability(&self) -> Ability {
|
pub fn random_ability(&self) -> A {
|
||||||
let n = Random::range(0, self.abilities.len() as u32);
|
let n = Random::range(0, self.abilities.len() as u32);
|
||||||
self.abilities[n as usize].clone()
|
self.abilities[n as usize].clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use engine::prelude::*;
|
||||||
|
|
||||||
use crate::components::inventory::Storable;
|
use crate::components::inventory::Storable;
|
||||||
|
|
||||||
use super::{ItemSystem, Rarities};
|
use super::{ability_book::Ability, ItemSystem, Rarities};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MapItem {
|
pub struct MapItem {
|
||||||
|
@ -18,9 +18,9 @@ impl MapItem {
|
||||||
pub fn into_persistent(&self) -> String {
|
pub fn into_persistent(&self) -> String {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
pub fn from_persistent<'a>(
|
pub fn from_persistent<'a, A: Ability>(
|
||||||
mut _split: impl Iterator<Item = &'a str>,
|
mut _split: impl Iterator<Item = &'a str>,
|
||||||
_item_system: &ItemSystem,
|
_item_system: &ItemSystem<A>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::{fmt, slice::Iter};
|
||||||
|
|
||||||
use crate::config::items::{ItemSettings, RarityColorSettings};
|
use crate::config::items::{ItemSettings, RarityColorSettings};
|
||||||
|
|
||||||
use super::ItemSystem;
|
use super::{ability_book::Ability, ItemSystem};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum Rarities {
|
pub enum Rarities {
|
||||||
|
@ -83,12 +83,12 @@ impl Rarities {
|
||||||
p >= l && p <= h
|
p >= l && p <= h
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_color(
|
pub(crate) fn apply_color<A: Ability>(
|
||||||
&self,
|
&self,
|
||||||
base_image: &RgbaImage,
|
base_image: &RgbaImage,
|
||||||
rarity_color_settings: &RarityColorSettings,
|
rarity_color_settings: &RarityColorSettings,
|
||||||
) -> RgbaImage {
|
) -> RgbaImage {
|
||||||
ItemSystem::apply_color(base_image, rarity_color_settings.from_rarity(*self))
|
ItemSystem::<A>::apply_color(base_image, rarity_color_settings.from_rarity(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
#[macro_use]
|
|
||||||
pub mod components;
|
pub mod components;
|
||||||
|
|
||||||
pub mod ability_type;
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod damage_type;
|
pub mod damage_type;
|
||||||
pub mod items;
|
pub mod items;
|
||||||
|
|
Loading…
Reference in a new issue