PkmnLib_rs/src/static_data/items.rs

146 lines
4.2 KiB
Rust
Executable File

use hashbrown::HashSet;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::fmt::Debug;
use crate::StringKey;
/// An item category defines which bag slot items are stored in.
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum ItemCategory {
/// This is where most items should go.
MiscItem,
/// Pokeballs are used for capturing Pokemons.
Pokeball,
/// Medicine is used for healing HP, PP, and status effects
Medicine,
/// Berry is used for all berries.
Berry,
/// TMHM is used for Technical and Hidden Machines.
TMHM,
/// Form Changer is used for items that change forms, such as mega stones.
FormChanger,
/// Key Items are single stored items, generally used for story progression.
KeyItem,
/// Mail is used for mail items.
Mail,
}
/// A battle item category defines how the item is categorized when in battle.
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum BattleItemCategory {
/// This item can't be used in battle.
None,
/// This item is used for healing Pokemon.
Healing,
/// This item is used for healing Pokemon from a status.
StatusHealing,
/// This item is used for capturing Pokemon.
Pokeball,
/// This item does not belong in above categories, but is still a battle item.
MiscBattleItem,
}
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
pub trait Item: Debug + Any {
/// The name of the item.
fn name(&self) -> &StringKey;
/// Which bag slot items are stored in.
fn category(&self) -> ItemCategory;
/// How the item is categorized when in battle.
fn battle_category(&self) -> BattleItemCategory;
/// The buying value of the item.
fn price(&self) -> i32;
/// A set of arbitrary flags that can be set on the item.
fn flags(&self) -> &HashSet<StringKey>;
/// Checks whether the item has a specific flag.
fn has_flag(&self, key: &StringKey) -> bool;
}
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
#[derive(Debug)]
pub struct ItemImpl {
/// The name of the item.
name: StringKey,
/// Which bag slot items are stored in.
category: ItemCategory,
/// How the item is categorized when in battle.
battle_category: BattleItemCategory,
/// The buying value of the item.
price: i32,
/// A set of arbitrary flags that can be set on the item.
flags: HashSet<StringKey>,
}
impl ItemImpl {
/// Instantiates an item.
pub fn new(
name: &StringKey,
category: ItemCategory,
battle_category: BattleItemCategory,
price: i32,
flags: HashSet<StringKey>,
) -> ItemImpl {
ItemImpl {
name: name.clone(),
category,
battle_category,
price,
flags,
}
}
}
impl Item for ItemImpl {
/// The name of the item.
fn name(&self) -> &StringKey {
&self.name
}
/// Which bag slot items are stored in.
fn category(&self) -> ItemCategory {
self.category
}
/// How the item is categorized when in battle.
fn battle_category(&self) -> BattleItemCategory {
self.battle_category
}
/// The buying value of the item.
fn price(&self) -> i32 {
self.price
}
/// A set of arbitrary flags that can be set on the item.
fn flags(&self) -> &HashSet<StringKey> {
&self.flags
}
/// Checks whether the item has a specific flag.
fn has_flag(&self, key: &StringKey) -> bool {
self.flags.contains(key)
}
}
#[cfg(test)]
#[allow(clippy::indexing_slicing)]
pub(crate) mod tests {
use super::*;
mockall::mock! {
#[derive(Debug)]
pub Item {}
impl Item for Item {
fn name(&self) -> &StringKey;
fn category(&self) -> ItemCategory;
fn battle_category(&self) -> BattleItemCategory;
fn price(&self) -> i32;
fn flags(&self) -> &HashSet<StringKey>;
fn has_flag(&self, key: &StringKey) -> bool;
}
}
}