engine/rpg_components/src/components/ability_slots.rs

188 lines
5.2 KiB
Rust
Raw Normal View History

2024-08-23 17:09:23 +00:00
use crate::config::save_game::SaveGame;
use crate::items::Rarities;
use crate::items::{ability_addon::AbilityAddonTypes, ability_book::AbilityBook};
2024-08-23 11:22:09 +00:00
use anyhow::Result;
use cgmath::{Vector2, Zero};
use engine::prelude::*;
use paste;
2024-08-23 15:17:53 +00:00
use std::{
slice::{Iter, IterMut},
str::FromStr,
};
2024-08-23 11:22:09 +00:00
macro_rules! load {
($me: ident, $save_game:ident, $($index:literal,)+) => {
paste::expr! {
$(
if $save_game.[<ability_ $index>].used {
let item_system = $me.game_handle.upgrade().item_system();
let ability = &$save_game.[<ability_ $index>];
let mut addons = Vec::new();
for addon in ability.addons.iter() {
let mut split = addon.split('|');
let rarity = Rarities::from_str(&split.nth(0).unwrap())?;
let addon_type = AbilityAddonTypes::from_str(&split.nth(0).unwrap())?;
addons.push(Some(item_system.addon(rarity, addon_type)));
}
let book = item_system.ability_book(
&ability.name,
ability.rarity,
addons,
ability.level,
);
$me.abilities[$index] = Some(book);
}
)+
}
};
}
macro_rules! load_npc {
($me: ident, $save_game:ident, $level:ident, $($index:literal,)+) => {
paste::expr! {
$(
if $save_game.[<ability_ $index>].used {
let item_system = $me.game_handle.upgrade().item_system();
let ability = &$save_game.[<ability_ $index>];
let mut addons = Vec::new();
for addon in ability.addons.iter() {
let mut split = addon.split('|');
let rarity = Rarities::from_str(&split.nth(0).unwrap())?;
let addon_type = AbilityAddonTypes::from_str(&split.nth(0).unwrap())?;
addons.push(Some(item_system.addon(rarity, addon_type)));
}
let ability_level = ($level as f32 * ability.level).ceil() as u32;
let book = item_system.ability_book(
&ability.name,
ability.rarity,
addons,
ability_level,
);
$me.abilities[$index] = Some(book);
}
)+
}
};
}
macro_rules! store {
($me: ident, $save_game:ident, $($index:literal,)+) => {
paste::expr! {
$(
if let Some(book) = &$me.abilities[$index] {
let ability = &mut $save_game.[<ability_ $index>];
ability.used = true;
ability.name = book.ability().name().to_string();
ability.rarity = book.rarity();
ability.level = book.level();
for addon in book.addons().iter() {
if let Some(addon) = addon {
ability.addons.push(format!("{}|{}", addon.rarity(), addon.addon_type()));
}
}
}
)+
}
};
}
pub struct AbilitySlots {
pub direction: Vector2<f32>,
abilities: [Option<AbilityBook>; AbilitySlots::MAX_ABILITIES],
}
impl AbilitySlots {
// stupid workaround for serde Deserialize
pub const MAX_ABILITIES: usize = 4;
2024-08-23 17:09:23 +00:00
pub fn empty() -> Self {
2024-08-23 11:22:09 +00:00
Self {
direction: Vector2::zero(),
abilities: Default::default(),
}
}
2024-08-23 17:09:23 +00:00
pub fn load(save_game: &SaveGame) -> Result<Self> {
let mut me = Self::empty();
2024-08-23 11:22:09 +00:00
load!(me, save_game, 0, 1, 2, 3,);
Ok(me)
}
pub fn store(&self, save_game: &mut SaveGame) {
store!(self, save_game, 0, 1, 2, 3,);
}
pub fn insert_book(&mut self, book: AbilityBook, index: usize) -> Option<AbilityBook> {
match self.abilities[index].clone() {
Some(ability) => {
if ability != book {
self.abilities[index] = Some(book);
} else {
self.abilities[index] = Some(book);
}
Some(ability)
}
None => {
self.abilities[index] = Some(book);
None
}
}
}
// pub fn clear_book(&mut self, index: usize) {
// self.abilities[index] = None;
// }
pub fn book(&self, index: usize) -> Option<&AbilityBook> {
self.abilities[index].as_ref()
}
pub fn book_mut(&mut self, index: usize) -> Option<&mut AbilityBook> {
self.abilities[index].as_mut()
}
pub fn iter(&self) -> Iter<'_, Option<AbilityBook>> {
self.abilities.iter()
}
pub fn iter_mut(&mut self) -> IterMut<'_, Option<AbilityBook>> {
self.abilities.iter_mut()
}
}
impl EntityComponent for AbilitySlots {
fn name(&self) -> &str {
Self::debug_name()
}
}
impl ComponentDebug for AbilitySlots {
fn debug_name() -> &'static str {
"AbilitySlots"
}
}