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 rpg_components::components::ability_slots::AbilitySlots;
|
||||
|
@ -11,13 +12,15 @@ use crate::*;
|
|||
|
||||
use crate::{traits::RightSide, CharacterWindow};
|
||||
|
||||
pub struct AbilityPageRightSide {
|
||||
pub struct AbilityPageRightSide<A: Ability + 'static> {
|
||||
snippet: Arc<GuiSnippet>,
|
||||
|
||||
ability_index: usize,
|
||||
|
||||
ability_marker: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl AbilityPageRightSide {
|
||||
impl<A: Ability + 'static> AbilityPageRightSide<A> {
|
||||
const ABILITY_BUTTON_NAMES: [&'static str; 4] = [
|
||||
"first_ability",
|
||||
"second_ability",
|
||||
|
@ -59,7 +62,7 @@ impl AbilityPageRightSide {
|
|||
move || {
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let abilities = tabs.abilities();
|
||||
let abilities = tabs.abilities::<A>();
|
||||
|
||||
abilities.right_side.ability_index = index;
|
||||
abilities.update_page()?;
|
||||
|
@ -79,7 +82,7 @@ impl AbilityPageRightSide {
|
|||
if selected {
|
||||
engine.on_scene(|scene| {
|
||||
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) {
|
||||
let button = weak_button.upgrade().unwrap();
|
||||
|
@ -122,7 +125,7 @@ impl AbilityPageRightSide {
|
|||
let entity = scene.entity_mut(hero)?;
|
||||
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) {
|
||||
let materials = multi_mut.get::<CraftingMaterials>()?;
|
||||
|
@ -131,7 +134,7 @@ impl AbilityPageRightSide {
|
|||
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
menu.tabs_mut()
|
||||
.abilities()
|
||||
.abilities::<A>()
|
||||
.right_side
|
||||
.refresh(&engine, hero)?;
|
||||
}
|
||||
|
@ -151,6 +154,7 @@ impl AbilityPageRightSide {
|
|||
Ok(Self {
|
||||
snippet,
|
||||
ability_index: 0,
|
||||
ability_marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -189,7 +193,7 @@ impl AbilityPageRightSide {
|
|||
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 (_, 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<()> {
|
||||
engine.on_scene(|scene| {
|
||||
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("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() {
|
||||
self.update_ability_icon(name, abilities.book(index).map(|book| book.icon()))?;
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
|||
|
||||
use super::AbilityPage;
|
||||
|
||||
impl Content<AbilityAddon> {
|
||||
impl<A: Ability + 'static> Content<A, AbilityAddon> {
|
||||
fn show_addon_tooltip(
|
||||
engine: &Arc<Engine>,
|
||||
hero: Entity,
|
||||
|
@ -25,7 +25,7 @@ impl Content<AbilityAddon> {
|
|||
) -> Result<()> {
|
||||
engine.on_scene(|scene| {
|
||||
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_y = y;
|
||||
|
@ -46,14 +46,14 @@ impl Content<AbilityAddon> {
|
|||
engine: &Arc<Engine>,
|
||||
hero: Entity,
|
||||
addon_index: usize,
|
||||
ability_page: &AbilityPage,
|
||||
ability_page: &AbilityPage<A>,
|
||||
) -> Result<()> {
|
||||
engine.on_scene_mut(|scene| {
|
||||
let entity = scene.entity_mut(hero)?;
|
||||
let mut multi_mut = entity.multi_mut();
|
||||
|
||||
let inventory = multi_mut.get::<Inventory>()?;
|
||||
let abilities = multi_mut.get::<AbilitySlots>()?;
|
||||
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||
let abilities = multi_mut.get::<AbilitySlots<A>>()?;
|
||||
|
||||
if let Some(book) = abilities.book_mut(ability_page.right_side.selected_ability()) {
|
||||
if book.has_free_addon_slots() {
|
||||
|
@ -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<()> {
|
||||
let reference = self.reference.clone();
|
||||
|
||||
|
@ -80,13 +80,15 @@ impl ContentUpdate for Content<AbilityAddon> {
|
|||
|
||||
move |controller_button| {
|
||||
if let ControllerButton::X = controller_button {
|
||||
CharacterWindow::salvage_from_inventory(&engine, hero, |inventory| {
|
||||
inventory.remove_addon(index)
|
||||
})?;
|
||||
CharacterWindow::salvage_from_inventory::<A, _, _>(
|
||||
&engine,
|
||||
hero,
|
||||
|inventory| inventory.remove_addon(index),
|
||||
)?;
|
||||
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let abilities = tabs.abilities();
|
||||
let abilities = tabs.abilities::<A>();
|
||||
|
||||
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(
|
||||
engine: &Arc<Engine>,
|
||||
hero: Entity,
|
||||
book_index: usize,
|
||||
ability_page: &AbilityPage,
|
||||
ability_page: &AbilityPage<A>,
|
||||
) -> Result<()> {
|
||||
engine.on_scene_mut(|scene| {
|
||||
let entity = scene.entity_mut(hero)?;
|
||||
let mut multi_mut = entity.multi_mut();
|
||||
|
||||
let inventory = multi_mut.get::<Inventory>()?;
|
||||
let abilitiy_slots = multi_mut.get::<AbilitySlots>()?;
|
||||
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),
|
||||
|
@ -179,7 +181,7 @@ impl Content<AbilityBook> {
|
|||
) -> Result<()> {
|
||||
engine.on_scene(|scene| {
|
||||
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 target_x = x + w as i32;
|
||||
|
@ -191,9 +193,9 @@ impl Content<AbilityBook> {
|
|||
gui.enable()?;
|
||||
|
||||
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) => {
|
||||
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<()> {
|
||||
let reference = self.reference.clone();
|
||||
|
||||
|
@ -235,13 +237,15 @@ impl ContentUpdate for Content<AbilityBook> {
|
|||
|
||||
move |controller_button| {
|
||||
if let ControllerButton::X = controller_button {
|
||||
CharacterWindow::salvage_from_inventory(&engine, hero, |inventory| {
|
||||
inventory.remove_book(index)
|
||||
})?;
|
||||
CharacterWindow::salvage_from_inventory::<A, _, _>(
|
||||
&engine,
|
||||
hero,
|
||||
|inventory| inventory.remove_book(index),
|
||||
)?;
|
||||
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let abilities = tabs.abilities();
|
||||
let abilities = tabs.abilities::<A>();
|
||||
|
||||
abilities.update_page()?;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use super::{
|
|||
};
|
||||
use crate::*;
|
||||
|
||||
pub struct AbilityPage {
|
||||
pub struct AbilityPage<A: Ability + 'static> {
|
||||
close: Weak<Button>,
|
||||
|
||||
engine: Arc<Engine>,
|
||||
|
@ -31,10 +31,10 @@ pub struct AbilityPage {
|
|||
|
||||
current_mode: usize,
|
||||
|
||||
right_side: AbilityPageRightSide,
|
||||
right_side: AbilityPageRightSide<A>,
|
||||
}
|
||||
|
||||
impl AbilityPage {
|
||||
impl<A: Ability + 'static> AbilityPage<A> {
|
||||
pub fn new(
|
||||
engine: &Arc<Engine>,
|
||||
hero: Entity,
|
||||
|
@ -65,7 +65,7 @@ impl AbilityPage {
|
|||
|
||||
engine.on_scene(|scene| {
|
||||
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();
|
||||
|
||||
|
@ -99,7 +99,7 @@ impl AbilityPage {
|
|||
);
|
||||
|
||||
// addons
|
||||
let addons_mode = PageContent::new(
|
||||
let addons_mode = PageContent::<A, _>::new(
|
||||
Content::new(&engine, reference.clone(), {
|
||||
let engine = engine.clone();
|
||||
let hero = hero.clone();
|
||||
|
@ -109,7 +109,7 @@ impl AbilityPage {
|
|||
|
||||
engine.on_scene(|scene| {
|
||||
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();
|
||||
|
||||
|
@ -192,7 +192,7 @@ impl AbilityPage {
|
|||
move |index| {
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let me = tabs.abilities();
|
||||
let me = tabs.abilities::<A>();
|
||||
|
||||
if 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>> {
|
||||
println!("enable AbilityPage");
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use std::sync::{Arc, Weak};
|
||||
use std::{
|
||||
marker::PhantomData,
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
@ -15,7 +18,7 @@ pub trait ContentUpdate {
|
|||
fn select(&self) -> Result<()>;
|
||||
}
|
||||
|
||||
pub struct Content<T: Send + Sync> {
|
||||
pub struct Content<A: Ability + 'static, T: Send + Sync> {
|
||||
pub reference: Weak<CharacterWindow>,
|
||||
base: Arc<GuiSnippet>,
|
||||
data: Vec<T>,
|
||||
|
@ -24,9 +27,11 @@ pub struct Content<T: Send + Sync> {
|
|||
|
||||
page: 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>(
|
||||
engine: &Arc<Engine>,
|
||||
reference: Weak<CharacterWindow>,
|
||||
|
@ -56,6 +61,8 @@ impl<T: Send + Sync> Content<T> {
|
|||
|
||||
page: 0,
|
||||
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
|
||||
Content<T>: ContentUpdate,
|
||||
Content<A, T>: ContentUpdate,
|
||||
{
|
||||
fn refresh(&mut self) -> Result<()> {
|
||||
self.data = (self.on_enable)()?;
|
||||
|
|
|
@ -17,9 +17,9 @@ use crate::{
|
|||
|
||||
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<()> {
|
||||
CharacterWindow::salvage_from_inventory(engine, hero, |inventory| {
|
||||
CharacterWindow::salvage_from_inventory::<A, _, _>(engine, hero, |inventory| {
|
||||
let mut item = inventory.remove_item(item_index);
|
||||
|
||||
// unsocket jewels and add them into inventory
|
||||
|
@ -42,7 +42,7 @@ impl Content<Item> {
|
|||
|
||||
engine.on_scene_mut(|scene| {
|
||||
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();
|
||||
|
||||
if item.affixes.iter().any(|affix| {
|
||||
|
@ -75,7 +75,7 @@ impl Content<Item> {
|
|||
let mut multi_mut = entity.multi_mut();
|
||||
|
||||
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>()?;
|
||||
|
||||
// remove item from inventory
|
||||
|
@ -109,7 +109,7 @@ impl Content<Item> {
|
|||
engine.on_scene(|scene| {
|
||||
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 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<()> {
|
||||
let reference = self.reference.clone();
|
||||
|
||||
|
@ -173,7 +173,7 @@ impl ContentUpdate for Content<Item> {
|
|||
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
inventory.update_page(true)?;
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ impl ContentUpdate for Content<Item> {
|
|||
if Self::select_to_socket(&engine, hero, index)? {
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
inventory.switch_to_jewels()?;
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ impl ContentUpdate for Content<Item> {
|
|||
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
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(
|
||||
engine: &Arc<Engine>,
|
||||
hero: Entity,
|
||||
|
@ -257,7 +257,7 @@ impl Content<Jewel> {
|
|||
) -> Result<()> {
|
||||
engine.on_scene(|scene| {
|
||||
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_y = y;
|
||||
|
@ -285,7 +285,7 @@ impl Content<Jewel> {
|
|||
fn select_to_combine(engine: &Arc<Engine>, hero: Entity, jewel_index: usize) -> Result<()> {
|
||||
engine.on_scene_mut(|scene| {
|
||||
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();
|
||||
|
||||
// add to reference
|
||||
|
@ -312,7 +312,7 @@ impl Content<Jewel> {
|
|||
fn select_to_lower(engine: &Arc<Engine>, hero: Entity, jewel_index: usize) -> Result<()> {
|
||||
engine.on_scene_mut(|scene| {
|
||||
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();
|
||||
|
||||
// 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<()> {
|
||||
let reference = self.reference.clone();
|
||||
|
||||
|
@ -378,7 +378,7 @@ impl ContentUpdate for Content<Jewel> {
|
|||
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
inventory.update_page(true)?;
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ impl ContentUpdate for Content<Jewel> {
|
|||
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
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<()> {
|
||||
self.update_base(engine, |_button, _t, _index| {
|
||||
// button.set_icon(&t.icon)?;
|
||||
|
|
|
@ -23,7 +23,7 @@ pub struct ItemRightSide {
|
|||
}
|
||||
|
||||
impl ItemRightSide {
|
||||
pub fn new(
|
||||
pub fn new<A: Ability + 'static>(
|
||||
engine: &Arc<Engine>,
|
||||
file: &str,
|
||||
reference: &Weak<CharacterWindow>,
|
||||
|
@ -37,12 +37,12 @@ impl ItemRightSide {
|
|||
empty_icons: icons,
|
||||
};
|
||||
|
||||
me.setup(engine, reference, hero)?;
|
||||
me.setup::<A>(engine, reference, hero)?;
|
||||
|
||||
Ok(me)
|
||||
}
|
||||
|
||||
fn setup(
|
||||
fn setup<A: Ability + 'static>(
|
||||
&self,
|
||||
engine: &Arc<Engine>,
|
||||
reference: &Weak<CharacterWindow>,
|
||||
|
@ -253,7 +253,7 @@ mod macros {
|
|||
let mut multi_mut = entity.multi_mut();
|
||||
|
||||
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>]() {
|
||||
inventory.add_item($item.clone());
|
||||
|
@ -285,7 +285,7 @@ mod macros {
|
|||
if found_item {
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
inventory.update_page(true)?;
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ mod macros {
|
|||
if empty_affixes_found {
|
||||
let window = reference.upgrade().unwrap();
|
||||
let mut tabs = window.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
inventory.switch_to_jewels()?;
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ mod macros {
|
|||
let mut multi_mut = entity.multi_mut();
|
||||
|
||||
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) {
|
||||
inventory.add_item($item.clone());
|
||||
|
@ -437,7 +437,7 @@ mod macros {
|
|||
if found_item {
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
inventory.update_page(true)?;
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ mod macros {
|
|||
if empty_affixes_found {
|
||||
let window = reference.upgrade().unwrap();
|
||||
let mut tabs = window.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
inventory.switch_to_jewels()?;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ pub struct JewelRightSide {
|
|||
}
|
||||
|
||||
impl JewelRightSide {
|
||||
pub fn new(
|
||||
pub fn new<A: Ability + 'static>(
|
||||
engine: &Arc<Engine>,
|
||||
file: &str,
|
||||
hero: Entity,
|
||||
|
@ -67,12 +67,12 @@ impl JewelRightSide {
|
|||
})?;
|
||||
|
||||
let me = Self { snippet };
|
||||
me.setup_select(engine, hero, reference)?;
|
||||
me.setup_select::<A>(engine, hero, reference)?;
|
||||
|
||||
Ok(me)
|
||||
}
|
||||
|
||||
fn setup_select(
|
||||
fn setup_select<A: Ability + 'static>(
|
||||
&self,
|
||||
engine: &Arc<Engine>,
|
||||
hero: Entity,
|
||||
|
@ -180,7 +180,7 @@ impl JewelRightSide {
|
|||
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let inventory = tabs.inventory();
|
||||
let inventory = tabs.inventory::<A>();
|
||||
|
||||
inventory.update_page(true)?;
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ impl JewelRightSide {
|
|||
.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 (resources, entity) = scene.entity_resource(hero)?;
|
||||
|
@ -244,7 +244,7 @@ impl JewelRightSide {
|
|||
|
||||
match source {
|
||||
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);
|
||||
|
||||
|
@ -276,7 +276,7 @@ impl JewelRightSide {
|
|||
|
||||
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 slot = item.slot;
|
||||
|
@ -328,9 +328,9 @@ impl JewelRightSide {
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -3,11 +3,13 @@ mod item_right_side;
|
|||
mod jewel_right_side;
|
||||
mod map_right_side;
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
use anyhow::Result;
|
||||
use engine::prelude::*;
|
||||
use rpg_components::components::inventory::Inventory;
|
||||
use rpg_components::items::ability_book::Ability;
|
||||
|
||||
use super::page_content::PageContent;
|
||||
use super::traits::*;
|
||||
|
@ -16,7 +18,7 @@ use item_right_side::ItemRightSide;
|
|||
use jewel_right_side::JewelRightSide;
|
||||
use map_right_side::MapRightSide;
|
||||
|
||||
pub struct InventoryPage {
|
||||
pub struct InventoryPage<A: Ability + 'static> {
|
||||
close: Weak<Button>,
|
||||
|
||||
engine: Arc<Engine>,
|
||||
|
@ -30,9 +32,11 @@ pub struct InventoryPage {
|
|||
modes: [Box<dyn PageContentWrapper>; 3],
|
||||
|
||||
current_mode: usize,
|
||||
|
||||
ability_marker: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl InventoryPage {
|
||||
impl<A: Ability + 'static> InventoryPage<A> {
|
||||
pub fn new(
|
||||
engine: &Arc<Engine>,
|
||||
hero: Entity,
|
||||
|
@ -53,7 +57,7 @@ impl InventoryPage {
|
|||
let content = left_base.element("content")?;
|
||||
|
||||
// items
|
||||
let item_mode = PageContent::new(
|
||||
let item_mode = PageContent::<A, _>::new(
|
||||
Content::new(engine, reference.clone(), {
|
||||
let engine = engine.clone();
|
||||
let hero = hero.clone();
|
||||
|
@ -63,7 +67,7 @@ impl InventoryPage {
|
|||
|
||||
engine.on_scene(|scene| {
|
||||
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();
|
||||
|
||||
|
@ -93,7 +97,7 @@ impl InventoryPage {
|
|||
|
||||
ui
|
||||
},
|
||||
ItemRightSide::new(
|
||||
ItemRightSide::new::<A>(
|
||||
engine,
|
||||
include_str!("../../resources/inventory/items/right_side.xml"),
|
||||
&reference,
|
||||
|
@ -102,7 +106,7 @@ impl InventoryPage {
|
|||
);
|
||||
|
||||
// jewels
|
||||
let jewel_mode = PageContent::new(
|
||||
let jewel_mode = PageContent::<A, _>::new(
|
||||
Content::new(engine, reference.clone(), {
|
||||
let engine = engine.clone();
|
||||
let hero = hero.clone();
|
||||
|
@ -112,7 +116,7 @@ impl InventoryPage {
|
|||
|
||||
engine.on_scene(|scene| {
|
||||
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();
|
||||
|
||||
|
@ -139,7 +143,7 @@ impl InventoryPage {
|
|||
|
||||
ui
|
||||
},
|
||||
JewelRightSide::new(
|
||||
JewelRightSide::new::<A>(
|
||||
engine,
|
||||
include_str!("../../resources/inventory/jewels/right_side.xml"),
|
||||
hero,
|
||||
|
@ -148,7 +152,7 @@ impl InventoryPage {
|
|||
);
|
||||
|
||||
// maps
|
||||
let map_mode = PageContent::new(
|
||||
let map_mode = PageContent::<A, _>::new(
|
||||
Content::new(engine, reference.clone(), {
|
||||
let engine = engine.clone();
|
||||
let hero: Entity = hero.clone();
|
||||
|
@ -158,7 +162,7 @@ impl InventoryPage {
|
|||
|
||||
engine.on_scene(|scene| {
|
||||
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();
|
||||
|
||||
|
@ -209,6 +213,8 @@ impl InventoryPage {
|
|||
],
|
||||
|
||||
current_mode: 0,
|
||||
|
||||
ability_marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -315,7 +321,7 @@ impl InventoryPage {
|
|||
move |index| {
|
||||
if let Some(menu) = reference.upgrade() {
|
||||
let mut tabs = menu.tabs_mut();
|
||||
let me = tabs.inventory();
|
||||
let me = tabs.inventory::<A>();
|
||||
|
||||
if 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>> {
|
||||
println!("enable InventoryPage");
|
||||
|
||||
|
@ -423,7 +429,7 @@ impl Page for InventoryPage {
|
|||
ControllerButton::RightStick => {
|
||||
// check if jewel page is open
|
||||
if self.current_mode == 1 {
|
||||
if JewelRightSide::combine(&self.engine, self.hero)? {
|
||||
if JewelRightSide::combine::<A>(&self.engine, self.hero)? {
|
||||
JewelRightSide::clear(&self.engine);
|
||||
self.update_page(true)?;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,12 @@ mod traits;
|
|||
|
||||
use anyhow::Result;
|
||||
use engine::prelude::*;
|
||||
use rpg_components::components::{
|
||||
crafting_materials::CraftingMaterials,
|
||||
inventory::{Inventory, Storable},
|
||||
use rpg_components::{
|
||||
components::{
|
||||
crafting_materials::CraftingMaterials,
|
||||
inventory::{Inventory, Storable},
|
||||
},
|
||||
items::ability_book::Ability,
|
||||
};
|
||||
|
||||
use std::{
|
||||
|
@ -76,11 +79,11 @@ impl<'a> Tabs<'a> {
|
|||
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])
|
||||
}
|
||||
|
||||
pub fn abilities(&mut self) -> &'a AbilityPage {
|
||||
pub fn abilities<A: Ability + 'static>(&mut self) -> &'a AbilityPage<A> {
|
||||
Self::downcast_unchecked(&self.tabs[2])
|
||||
}
|
||||
|
||||
|
@ -104,11 +107,11 @@ impl<'a> TabsMut<'a> {
|
|||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
|
@ -137,7 +140,7 @@ pub struct CharacterWindow {
|
|||
}
|
||||
|
||||
impl CharacterWindow {
|
||||
pub fn new(
|
||||
pub fn new<A: Ability + 'static>(
|
||||
engine: Arc<Engine>,
|
||||
hero: Entity,
|
||||
name: &str,
|
||||
|
@ -162,8 +165,10 @@ impl CharacterWindow {
|
|||
|
||||
tabs: RwLock::new([
|
||||
Box::new(CharacterPage::new(&engine, hero, name, me).unwrap()),
|
||||
Box::new(InventoryPage::new(&engine, hero, me.clone(), &close_button).unwrap()),
|
||||
Box::new(AbilityPage::new(&engine, hero, me.clone(), &close_button).unwrap()),
|
||||
Box::new(
|
||||
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),
|
||||
|
||||
|
@ -250,9 +255,10 @@ impl CharacterWindow {
|
|||
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
|
||||
F: FnOnce(&mut Inventory) -> S,
|
||||
A: Ability + 'static,
|
||||
F: FnOnce(&mut Inventory<A>) -> S,
|
||||
S: Storable,
|
||||
{
|
||||
engine.on_scene_mut(|scene| {
|
||||
|
@ -261,7 +267,7 @@ impl CharacterWindow {
|
|||
let mut multi_mut = entity.multi_mut();
|
||||
|
||||
let crafting_materials = multi_mut.get::<CraftingMaterials>()?;
|
||||
let inventory = multi_mut.get::<Inventory>()?;
|
||||
let inventory = multi_mut.get::<Inventory<A>>()?;
|
||||
|
||||
// remove callback
|
||||
let storable = f(inventory);
|
||||
|
|
|
@ -17,15 +17,15 @@ impl RightSide for EmptyRightSide {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct PageContent<T: Send + Sync> {
|
||||
content: Content<T>,
|
||||
pub struct PageContent<A: Ability + 'static, T: Send + Sync> {
|
||||
content: Content<A, T>,
|
||||
tooltip: Arc<GuiSnippet>,
|
||||
|
||||
right_side: Box<dyn RightSide>,
|
||||
}
|
||||
|
||||
impl<T: Send + Sync> PageContent<T> {
|
||||
pub fn new<R>(content: Content<T>, tooltip: Arc<GuiSnippet>, right_side: R) -> Self
|
||||
impl<A: Ability + 'static, T: Send + Sync> PageContent<A, T> {
|
||||
pub fn new<R>(content: Content<A, T>, tooltip: Arc<GuiSnippet>, right_side: R) -> Self
|
||||
where
|
||||
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
|
||||
Content<T>: ContentUpdate,
|
||||
Content<A, T>: ContentUpdate,
|
||||
{
|
||||
fn content(&self) -> &dyn ContentWrapper {
|
||||
&self.content
|
||||
|
|
|
@ -5,14 +5,6 @@ use engine::prelude::*;
|
|||
use cgmath::Vector3;
|
||||
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";
|
||||
|
||||
create_settings_section!(
|
|
@ -1,4 +1,5 @@
|
|||
mod ability_location_info;
|
||||
pub mod abilityloader;
|
||||
pub mod ai;
|
||||
mod aoe;
|
||||
pub mod aoe_arc;
|
||||
|
|
|
@ -2,5 +2,6 @@ pub mod abilities;
|
|||
pub mod components;
|
||||
pub mod objects;
|
||||
|
||||
pub mod ability_type;
|
||||
pub mod lightning;
|
||||
pub mod prelude;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub use super::abilities::prelude::*;
|
||||
pub use super::ability_type::AbilityType;
|
||||
pub use super::components::*;
|
||||
pub use super::lightning::{Lightning, LightningMarker};
|
||||
pub use super::objects::hero::{Hero, MainUser};
|
||||
|
|
|
@ -8,9 +8,9 @@ use std::{
|
|||
str::FromStr,
|
||||
};
|
||||
|
||||
use crate::config::save_game::SaveGame;
|
||||
use crate::items::{ability_addon::AbilityAddonTypes, ability_book::AbilityBook, Rarities};
|
||||
use crate::{components::inventory::Storable, items::ItemSystem};
|
||||
use crate::{config::save_game::SaveGame, items::ability_book::Ability};
|
||||
|
||||
macro_rules! load {
|
||||
($me: ident, $item_system:ident, $save_game:ident, $($index:literal,)+) => {
|
||||
|
@ -67,16 +67,16 @@ macro_rules! store {
|
|||
};
|
||||
}
|
||||
|
||||
pub struct AbilitySlots {
|
||||
// stupid workaround for serde Deserialize
|
||||
pub const MAX_ABILITIES: usize = 4;
|
||||
|
||||
pub struct AbilitySlots<A: Ability> {
|
||||
pub direction: Vector2<f32>,
|
||||
|
||||
abilities: [Option<AbilityBook>; AbilitySlots::MAX_ABILITIES],
|
||||
abilities: [Option<AbilityBook<A>>; MAX_ABILITIES],
|
||||
}
|
||||
|
||||
impl AbilitySlots {
|
||||
// stupid workaround for serde Deserialize
|
||||
pub const MAX_ABILITIES: usize = 4;
|
||||
|
||||
impl<A: Ability> AbilitySlots<A> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
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();
|
||||
|
||||
load!(me, item_system, save_game, 0, 1, 2, 3,);
|
||||
|
@ -96,7 +96,7 @@ impl AbilitySlots {
|
|||
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() {
|
||||
Some(ability) => {
|
||||
if ability != book {
|
||||
|
@ -119,30 +119,30 @@ impl AbilitySlots {
|
|||
// 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()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter<'_, Option<AbilityBook>> {
|
||||
pub fn iter(&self) -> Iter<'_, Option<AbilityBook<A>>> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
impl EntityComponent for AbilitySlots {
|
||||
impl<A: Ability + 'static> EntityComponent for AbilitySlots<A> {
|
||||
fn name(&self) -> &str {
|
||||
Self::debug_name()
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentDebug for AbilitySlots {
|
||||
impl<A: Ability> ComponentDebug for AbilitySlots<A> {
|
||||
fn debug_name() -> &'static str {
|
||||
"AbilitySlots"
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::{cmp::Ordering, slice::Iter, str::FromStr};
|
|||
|
||||
use crate::{
|
||||
config::attributes::{AttributeColorSettings, StartingAttributes},
|
||||
items::ItemSystem,
|
||||
items::{ability_book::Ability, ItemSystem},
|
||||
};
|
||||
|
||||
generate_stat!(Agility, u32, "Agility");
|
||||
|
@ -37,12 +37,12 @@ impl Attribute {
|
|||
ATTRIBUTES.iter()
|
||||
}
|
||||
|
||||
pub fn apply_color(
|
||||
pub fn apply_color<A: Ability>(
|
||||
&self,
|
||||
base_image: &RgbaImage,
|
||||
color_settins: &AttributeColorSettings,
|
||||
) -> 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::{
|
||||
config::save_game::SaveGame,
|
||||
items::{
|
||||
ability_addon::AbilityAddon, ability_book::AbilityBook, Item, ItemSystem, Jewel, MapItem,
|
||||
Rarities,
|
||||
ability_addon::AbilityAddon,
|
||||
ability_book::{Ability, AbilityBook},
|
||||
Item, ItemSystem, Jewel, MapItem, Rarities,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -17,15 +18,15 @@ pub trait Storable {
|
|||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct Inventory {
|
||||
pub struct Inventory<A: Ability> {
|
||||
items: Vec<Item>,
|
||||
addons: Vec<AbilityAddon>,
|
||||
books: Vec<AbilityBook>,
|
||||
books: Vec<AbilityBook<A>>,
|
||||
jewels: Vec<Jewel>,
|
||||
maps: Vec<MapItem>,
|
||||
}
|
||||
|
||||
impl Inventory {
|
||||
impl<A: Ability> Inventory<A> {
|
||||
// ------- items --------
|
||||
pub fn add_item(&mut self, item: Item) {
|
||||
self.items.push(item);
|
||||
|
@ -123,30 +124,30 @@ impl Inventory {
|
|||
}
|
||||
|
||||
// ------- books --------
|
||||
pub fn add_book(&mut self, book: AbilityBook) {
|
||||
pub fn add_book(&mut self, book: AbilityBook<A>) {
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn remove_book(&mut self, index: usize) -> AbilityBook {
|
||||
pub fn remove_book(&mut self, index: usize) -> AbilityBook<A> {
|
||||
self.books.remove(index)
|
||||
}
|
||||
|
||||
pub fn iter_books(&self) -> Iter<'_, AbilityBook> {
|
||||
pub fn iter_books(&self) -> Iter<'_, AbilityBook<A>> {
|
||||
self.books.iter()
|
||||
}
|
||||
|
||||
pub fn book_at(&self, index: usize) -> &AbilityBook {
|
||||
pub fn book_at(&self, index: usize) -> &AbilityBook<A> {
|
||||
&self.books[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl Inventory {
|
||||
pub fn load(save_game: &SaveGame, item_system: &ItemSystem) -> Result<Self> {
|
||||
let mut inventory = Inventory::default();
|
||||
impl<A: Ability> Inventory<A> {
|
||||
pub fn load(save_game: &SaveGame, item_system: &ItemSystem<A>) -> Result<Self> {
|
||||
let mut inventory: Inventory<A> = Default::default();
|
||||
|
||||
for item_string in save_game.inventory.items.iter() {
|
||||
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 {
|
||||
Self::debug_name()
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentDebug for Inventory {
|
||||
impl<A: Ability> ComponentDebug for Inventory<A> {
|
||||
fn debug_name() -> &'static str {
|
||||
"Inventory"
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::collections::HashMap;
|
|||
|
||||
use crate::{
|
||||
config::{items::ItemSettings, save_game::SaveGame},
|
||||
items::{Item, ItemAffix, ItemSlots, ItemSystem, Rarities},
|
||||
items::{ability_book::Ability, Item, ItemAffix, ItemSlots, ItemSystem, Rarities},
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
load_item!(me, chest_plate, ChestPlate, save_game, item_system);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
pub mod macros;
|
||||
|
||||
pub mod ability_slots;
|
||||
pub mod abilityloader;
|
||||
pub mod attributes;
|
||||
pub mod character_status;
|
||||
pub mod crafting_materials;
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
crafting_materials::CraftingMaterials, inventory::Inventory, item_slots::ItemSlotContainer,
|
||||
level::Level, statistics::Statistics,
|
||||
},
|
||||
items::{ItemAffix, ItemSystem, Rarities},
|
||||
items::{ability_book::Ability, ItemAffix, ItemSystem, Rarities},
|
||||
};
|
||||
|
||||
use std::env::var;
|
||||
|
@ -359,13 +359,16 @@ create_settings_container!(
|
|||
);
|
||||
|
||||
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 experience_settings = scene.resources.get::<ExperienceSettings>();
|
||||
let attribute_settings = scene.resources.get::<AttributeSettings>();
|
||||
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();
|
||||
|
||||
|
|
|
@ -12,11 +12,9 @@ use std::{
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
ability_type::AbilityType, components::inventory::Storable, config::abilities::AbilitySettings,
|
||||
};
|
||||
use crate::{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;
|
||||
|
||||
|
@ -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 {
|
||||
match self {
|
||||
AbilityAddonTypes::Damage(_) => AbilityAddonTypes::Damage(0),
|
||||
|
@ -262,9 +234,9 @@ impl AbilityAddon {
|
|||
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>,
|
||||
item_system: &ItemSystem,
|
||||
item_system: &ItemSystem<A>,
|
||||
) -> Result<Self> {
|
||||
let addon_type = AbilityAddonTypes::from_str(split.next().unwrap())?;
|
||||
let rarity = Rarities::from_str(split.next().unwrap())?;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use anyhow::Result;
|
||||
use assetpath::AssetPath;
|
||||
use cgmath::{Vector2, Vector3};
|
||||
use engine::prelude::*;
|
||||
|
||||
|
@ -6,10 +7,11 @@ use std::{fmt::Debug, str::FromStr, sync::Arc, time::Duration};
|
|||
|
||||
use crate::{
|
||||
components::{
|
||||
abilityloader::AbilityLoader, character_status::CharacterStatus,
|
||||
crafting_materials::CraftingMaterials, inventory::Storable, statistics::Statistics,
|
||||
character_status::CharacterStatus, crafting_materials::CraftingMaterials,
|
||||
inventory::Storable, statistics::Statistics,
|
||||
},
|
||||
config::abilities::{AbilityLevel, AbilitySettings},
|
||||
damage_type::DamageType,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
@ -17,19 +19,17 @@ use super::{
|
|||
ItemSystem, Rarities, Tooltip,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Ability {
|
||||
pub(crate) data: AbilityLoader,
|
||||
}
|
||||
pub trait Ability: Send + Sync + Clone + Default {
|
||||
fn create(asset_path: impl Into<AssetPath>) -> Result<Self>;
|
||||
|
||||
impl Ability {
|
||||
pub fn data(&self) -> &AbilityLoader {
|
||||
&self.data
|
||||
}
|
||||
fn name(&self) -> &str;
|
||||
fn icon_path(&self) -> &AssetPath;
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
self.data.name()
|
||||
}
|
||||
fn cool_down(&self) -> Duration;
|
||||
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)]
|
||||
|
@ -40,8 +40,8 @@ pub struct CastInformation {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AbilityBook {
|
||||
ability: Ability,
|
||||
pub struct AbilityBook<A: Ability> {
|
||||
ability: A,
|
||||
|
||||
// meta
|
||||
icon: Arc<Image>,
|
||||
|
@ -57,9 +57,9 @@ pub struct AbilityBook {
|
|||
last_cast: Option<CastInformation>,
|
||||
}
|
||||
|
||||
impl AbilityBook {
|
||||
impl<A: Ability> AbilityBook<A> {
|
||||
pub fn new(
|
||||
ability: Ability,
|
||||
ability: A,
|
||||
icon: Arc<Image>,
|
||||
rarity: Rarities,
|
||||
ability_settings: &AbilitySettings,
|
||||
|
@ -83,7 +83,7 @@ impl AbilityBook {
|
|||
}
|
||||
|
||||
pub fn load(
|
||||
ability: Ability,
|
||||
ability: A,
|
||||
icon: Arc<Image>,
|
||||
rarity: Rarities,
|
||||
addons: Vec<Option<AbilityAddon>>,
|
||||
|
@ -122,7 +122,7 @@ impl AbilityBook {
|
|||
|
||||
if let Some(cast_information) = &self.last_cast {
|
||||
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())
|
||||
});
|
||||
|
@ -174,12 +174,7 @@ impl AbilityBook {
|
|||
match &self.last_cast {
|
||||
Some(cast_information) => {
|
||||
let total_cool_down = Duration::from_secs_f32(
|
||||
self.ability
|
||||
.data()
|
||||
.settings
|
||||
.parameter
|
||||
.cool_down
|
||||
.as_secs_f32()
|
||||
self.ability.cool_down().as_secs_f32()
|
||||
* (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
|
||||
}
|
||||
|
||||
|
@ -242,10 +237,7 @@ impl AbilityBook {
|
|||
}
|
||||
|
||||
pub fn mana_cost(&self) -> u32 {
|
||||
let data = self.ability.data();
|
||||
|
||||
data.settings.parameter.base_mana_cost
|
||||
+ data.settings.parameter.mana_cost_per_level * (self.level - 1)
|
||||
self.ability.mana_cost() + self.ability.mana_cost_per_level() * (self.level - 1)
|
||||
}
|
||||
|
||||
pub fn into_persistent(&self) -> String {
|
||||
|
@ -260,7 +252,7 @@ impl AbilityBook {
|
|||
|
||||
pub fn from_persistent<'a>(
|
||||
mut split: impl Iterator<Item = &'a str>,
|
||||
item_system: &ItemSystem,
|
||||
item_system: &ItemSystem<A>,
|
||||
) -> Result<Self> {
|
||||
let name = 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 cooldown: Arc<Label> = gui.element("cooldown")?;
|
||||
|
||||
let data = self.ability().data();
|
||||
|
||||
mana_costs.set_text(self.mana_cost())?;
|
||||
damage.set_text(data.damage(self.level(), self.addons(), statistics))?;
|
||||
damage.set_text_color(data.settings.parameter.damage_type.into())?;
|
||||
damage.set_text(self.ability.damage(self.level(), self.addons(), statistics))?;
|
||||
damage.set_text_color(self.ability.damage_type().into())?;
|
||||
cooldown.set_text(format!(
|
||||
"{:.1} s",
|
||||
data.settings.parameter.cool_down.as_secs_f32()
|
||||
* (1.0 - self.addons().cool_down_reduction())
|
||||
self.ability.cool_down().as_secs_f32() * (1.0 - self.addons().cool_down_reduction())
|
||||
))?;
|
||||
|
||||
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 {
|
||||
f.debug_struct("AbilityBook")
|
||||
.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 {
|
||||
self.ability.data() == other.ability.data()
|
||||
self.ability.name() == other.ability.name()
|
||||
&& self.rarity == other.rarity
|
||||
&& self.addons == other.addons
|
||||
&& self.level == other.level
|
||||
}
|
||||
}
|
||||
|
||||
impl Storable for AbilityBook {
|
||||
impl<A: Ability> Storable for AbilityBook<A> {
|
||||
fn rarity(&self) -> Rarities {
|
||||
self.rarity
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
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] = [
|
||||
include_str!("../../resources/items/slots_0.xml"),
|
||||
|
@ -155,9 +155,9 @@ impl Item {
|
|||
base
|
||||
}
|
||||
|
||||
pub fn from_persistent<'a>(
|
||||
pub fn from_persistent<'a, A: Ability>(
|
||||
mut split: impl Iterator<Item = &'a str>,
|
||||
item_system: &ItemSystem,
|
||||
item_system: &ItemSystem<A>,
|
||||
) -> Result<Self> {
|
||||
let slot = ItemSlots::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 crate::components::abilityloader::AbilityLoader;
|
||||
use crate::components::attributes::{Attribute, Attributes};
|
||||
use crate::components::inventory::Storable;
|
||||
use crate::components::statistic_types::{
|
||||
|
@ -22,14 +21,14 @@ use super::ability_book::{Ability, AbilityBook};
|
|||
use super::{Item, ItemAffix, ItemSlots, Jewel, Rarities};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Loot {
|
||||
pub enum Loot<A: Ability> {
|
||||
Item(Item),
|
||||
AbilityBook(AbilityBook),
|
||||
AbilityBook(AbilityBook<A>),
|
||||
AbilityAddOn(AbilityAddon),
|
||||
Jewel(Jewel),
|
||||
}
|
||||
|
||||
impl Loot {
|
||||
impl<A: Ability> Loot<A> {
|
||||
pub fn storable(&self) -> &dyn Storable {
|
||||
match self {
|
||||
Loot::Item(item) => item,
|
||||
|
@ -40,7 +39,7 @@ impl Loot {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ItemSystem {
|
||||
pub struct ItemSystem<A: Ability> {
|
||||
pub item_settings: ItemSettings,
|
||||
ability_settings: AbilitySettings,
|
||||
|
||||
|
@ -49,25 +48,24 @@ pub struct ItemSystem {
|
|||
addon_icon_combinations: HashMap<(Rarities, AbilityAddonTypes), 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(
|
||||
engine: &Arc<Engine>,
|
||||
item_settings: &ItemSettings,
|
||||
ability_settings: &AbilitySettings,
|
||||
attribute_settings: &AttributeSettings,
|
||||
ability_directory: &AssetPath,
|
||||
data_directory: &str,
|
||||
) -> Result<Self> {
|
||||
// verify that drop chances sum up to 1.0
|
||||
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()
|
||||
.map(|path| AbilityLoader::load(data_directory, path))
|
||||
.collect::<Result<Vec<AbilityLoader>>>()?;
|
||||
.map(|path| A::create(path))
|
||||
.collect::<Result<Vec<A>>>()?;
|
||||
|
||||
let (
|
||||
item_icon_combinations,
|
||||
|
@ -89,8 +87,8 @@ impl ItemSystem {
|
|||
// image for ability book
|
||||
let mut ability_images = Vec::new();
|
||||
|
||||
for loader in ability_loader.iter() {
|
||||
let path = &loader.settings.meta.icon;
|
||||
for loader in abilities.iter() {
|
||||
let path = loader.icon_path();
|
||||
|
||||
if !path.is_empty() {
|
||||
ability_images.push((loader.name().to_string(), Self::dyn_image(path)?));
|
||||
|
@ -140,7 +138,10 @@ impl ItemSystem {
|
|||
for rarity in Rarities::iter() {
|
||||
let final_image = Self::blend_background(
|
||||
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();
|
||||
|
@ -165,7 +166,10 @@ impl ItemSystem {
|
|||
for rarity in Rarities::iter() {
|
||||
let final_image = Self::blend_background(
|
||||
&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();
|
||||
|
@ -189,8 +193,10 @@ impl ItemSystem {
|
|||
for (addon_type, icon) in ability_addon_icons.iter() {
|
||||
for rarity in Rarities::iter() {
|
||||
let final_image = Self::blend_apply(
|
||||
&rarity
|
||||
.apply_color(&addon_background, &item_settings.rarity_color_settings),
|
||||
&rarity.apply_color::<A>(
|
||||
&addon_background,
|
||||
&item_settings.rarity_color_settings,
|
||||
),
|
||||
icon,
|
||||
|rarity_color, icon_color| {
|
||||
// let (r1, g1, b1, a1) = rarity_color.channels4();
|
||||
|
@ -224,13 +230,13 @@ impl ItemSystem {
|
|||
|
||||
for (level, icon) in jewel_icons.iter() {
|
||||
for attribute in Attribute::iter() {
|
||||
let attribute_icon =
|
||||
attribute.apply_color(&icon, &attribute_settings.attribute_color_settings);
|
||||
let attribute_icon = attribute
|
||||
.apply_color::<A>(&icon, &attribute_settings.attribute_color_settings);
|
||||
|
||||
for rarity in Rarities::iter() {
|
||||
let final_image = Self::blend_background(
|
||||
&attribute_icon,
|
||||
&rarity.apply_color(
|
||||
&rarity.apply_color::<A>(
|
||||
&base_background,
|
||||
&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 {
|
||||
item_settings: item_settings.clone(),
|
||||
ability_settings: ability_settings.clone(),
|
||||
|
@ -293,7 +294,7 @@ impl ItemSystem {
|
|||
}
|
||||
|
||||
/// 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
|
||||
let loot_type_p = Random::range_f32(0.0, 1.0);
|
||||
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 {
|
||||
Some(multiplier) => multiplier * 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_icon = self.ability_icon(ability.name(), rarity);
|
||||
|
||||
|
@ -451,7 +456,7 @@ impl ItemSystem {
|
|||
rarity: Rarities,
|
||||
addons: Vec<Option<AbilityAddon>>,
|
||||
level: u32,
|
||||
) -> AbilityBook {
|
||||
) -> AbilityBook<A> {
|
||||
AbilityBook::load(
|
||||
self.find_ability(ability_name),
|
||||
self.ability_icon(ability_name, rarity),
|
||||
|
@ -545,7 +550,7 @@ impl ItemSystem {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn find_ability(&self, name: &str) -> Ability {
|
||||
pub fn find_ability(&self, name: &str) -> A {
|
||||
self.abilities
|
||||
.iter()
|
||||
.find(|a| a.name() == name)
|
||||
|
@ -554,7 +559,7 @@ impl ItemSystem {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn random_ability(&self) -> Ability {
|
||||
pub fn random_ability(&self) -> A {
|
||||
let n = Random::range(0, self.abilities.len() as u32);
|
||||
self.abilities[n as usize].clone()
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use engine::prelude::*;
|
|||
|
||||
use crate::components::inventory::Storable;
|
||||
|
||||
use super::{ItemSystem, Rarities};
|
||||
use super::{ability_book::Ability, ItemSystem, Rarities};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MapItem {
|
||||
|
@ -18,9 +18,9 @@ impl MapItem {
|
|||
pub fn into_persistent(&self) -> String {
|
||||
String::new()
|
||||
}
|
||||
pub fn from_persistent<'a>(
|
||||
pub fn from_persistent<'a, A: Ability>(
|
||||
mut _split: impl Iterator<Item = &'a str>,
|
||||
_item_system: &ItemSystem,
|
||||
_item_system: &ItemSystem<A>,
|
||||
) -> Result<Self> {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::{fmt, slice::Iter};
|
|||
|
||||
use crate::config::items::{ItemSettings, RarityColorSettings};
|
||||
|
||||
use super::ItemSystem;
|
||||
use super::{ability_book::Ability, ItemSystem};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Rarities {
|
||||
|
@ -83,12 +83,12 @@ impl Rarities {
|
|||
p >= l && p <= h
|
||||
}
|
||||
|
||||
pub fn apply_color(
|
||||
pub(crate) fn apply_color<A: Ability>(
|
||||
&self,
|
||||
base_image: &RgbaImage,
|
||||
rarity_color_settings: &RarityColorSettings,
|
||||
) -> 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 ability_type;
|
||||
pub mod config;
|
||||
pub mod damage_type;
|
||||
pub mod items;
|
||||
|
|
Loading…
Reference in a new issue