2022-06-17 17:53:33 +00:00
|
|
|
use hashbrown::HashSet;
|
2022-06-19 19:34:08 +00:00
|
|
|
#[cfg(feature = "serde")]
|
|
|
|
use serde::{Deserialize, Serialize};
|
2022-11-27 16:29:29 +00:00
|
|
|
use std::any::Any;
|
|
|
|
use std::fmt::Debug;
|
2022-06-19 19:34:08 +00:00
|
|
|
|
2023-06-24 12:44:23 +00:00
|
|
|
use crate::StringKey;
|
2022-06-19 19:34:08 +00:00
|
|
|
|
2022-07-01 15:07:22 +00:00
|
|
|
/// An item category defines which bag slot items are stored in.
|
2022-06-19 19:34:08 +00:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
|
|
#[repr(u8)]
|
|
|
|
pub enum ItemCategory {
|
2022-07-01 15:07:22 +00:00
|
|
|
/// This is where most items should go.
|
2022-06-19 19:34:08 +00:00
|
|
|
MiscItem,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Pokeballs are used for capturing Pokemons.
|
2022-06-19 19:34:08 +00:00
|
|
|
Pokeball,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Medicine is used for healing HP, PP, and status effects
|
2022-06-19 19:34:08 +00:00
|
|
|
Medicine,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Berry is used for all berries.
|
2022-06-19 19:34:08 +00:00
|
|
|
Berry,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// TMHM is used for Technical and Hidden Machines.
|
2022-06-19 19:34:08 +00:00
|
|
|
TMHM,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Form Changer is used for items that change forms, such as mega stones.
|
2022-06-19 19:34:08 +00:00
|
|
|
FormChanger,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Key Items are single stored items, generally used for story progression.
|
2022-06-19 19:34:08 +00:00
|
|
|
KeyItem,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Mail is used for mail items.
|
2022-06-19 19:34:08 +00:00
|
|
|
Mail,
|
|
|
|
}
|
|
|
|
|
2022-07-01 15:07:22 +00:00
|
|
|
/// A battle item category defines how the item is categorized when in battle.
|
2022-06-19 19:34:08 +00:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
|
|
#[repr(u8)]
|
|
|
|
pub enum BattleItemCategory {
|
2022-07-01 15:07:22 +00:00
|
|
|
/// This item can't be used in battle.
|
2022-06-19 19:34:08 +00:00
|
|
|
None,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// This item is used for healing Pokemon.
|
2022-06-19 19:34:08 +00:00
|
|
|
Healing,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// This item is used for healing Pokemon from a status.
|
2022-06-19 19:34:08 +00:00
|
|
|
StatusHealing,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// This item is used for capturing Pokemon.
|
2022-06-19 19:34:08 +00:00
|
|
|
Pokeball,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// This item does not belong in above categories, but is still a battle item.
|
2022-06-19 19:34:08 +00:00
|
|
|
MiscBattleItem,
|
|
|
|
}
|
2021-01-30 21:29:59 +00:00
|
|
|
|
2022-11-27 16:29:29 +00:00
|
|
|
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
2023-06-24 12:44:23 +00:00
|
|
|
pub trait Item: Debug + Any {
|
2022-11-27 16:29:29 +00:00
|
|
|
/// 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;
|
|
|
|
}
|
|
|
|
|
2022-07-01 15:07:22 +00:00
|
|
|
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
2022-06-06 12:43:41 +00:00
|
|
|
#[derive(Debug)]
|
2022-11-27 16:29:29 +00:00
|
|
|
pub struct ItemImpl {
|
2022-07-01 15:07:22 +00:00
|
|
|
/// The name of the item.
|
2022-06-11 15:22:46 +00:00
|
|
|
name: StringKey,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Which bag slot items are stored in.
|
2021-01-30 21:29:59 +00:00
|
|
|
category: ItemCategory,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// How the item is categorized when in battle.
|
2021-01-30 21:29:59 +00:00
|
|
|
battle_category: BattleItemCategory,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// The buying value of the item.
|
2021-01-30 21:29:59 +00:00
|
|
|
price: i32,
|
2022-07-01 15:07:22 +00:00
|
|
|
/// A set of arbitrary flags that can be set on the item.
|
2022-06-11 15:22:46 +00:00
|
|
|
flags: HashSet<StringKey>,
|
2021-01-30 21:29:59 +00:00
|
|
|
}
|
|
|
|
|
2022-11-27 16:29:29 +00:00
|
|
|
impl ItemImpl {
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Instantiates an item.
|
2021-01-30 21:29:59 +00:00
|
|
|
pub fn new(
|
2022-06-11 15:22:46 +00:00
|
|
|
name: &StringKey,
|
2021-01-30 21:29:59 +00:00
|
|
|
category: ItemCategory,
|
|
|
|
battle_category: BattleItemCategory,
|
|
|
|
price: i32,
|
2022-06-11 15:22:46 +00:00
|
|
|
flags: HashSet<StringKey>,
|
2022-11-27 16:29:29 +00:00
|
|
|
) -> ItemImpl {
|
|
|
|
ItemImpl {
|
2022-06-11 15:22:46 +00:00
|
|
|
name: name.clone(),
|
2021-01-30 21:29:59 +00:00
|
|
|
category,
|
|
|
|
battle_category,
|
|
|
|
price,
|
|
|
|
flags,
|
|
|
|
}
|
|
|
|
}
|
2022-11-27 16:29:29 +00:00
|
|
|
}
|
2021-01-30 21:29:59 +00:00
|
|
|
|
2022-11-27 16:29:29 +00:00
|
|
|
impl Item for ItemImpl {
|
2022-07-01 15:07:22 +00:00
|
|
|
/// The name of the item.
|
2022-11-27 16:29:29 +00:00
|
|
|
fn name(&self) -> &StringKey {
|
2022-06-06 12:43:41 +00:00
|
|
|
&self.name
|
|
|
|
}
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Which bag slot items are stored in.
|
2022-11-27 16:29:29 +00:00
|
|
|
fn category(&self) -> ItemCategory {
|
2022-06-06 12:43:41 +00:00
|
|
|
self.category
|
|
|
|
}
|
2022-07-01 15:07:22 +00:00
|
|
|
/// How the item is categorized when in battle.
|
2022-11-27 16:29:29 +00:00
|
|
|
fn battle_category(&self) -> BattleItemCategory {
|
2022-06-06 12:43:41 +00:00
|
|
|
self.battle_category
|
|
|
|
}
|
2022-07-01 15:07:22 +00:00
|
|
|
/// The buying value of the item.
|
2022-11-27 16:29:29 +00:00
|
|
|
fn price(&self) -> i32 {
|
2022-06-06 12:43:41 +00:00
|
|
|
self.price
|
|
|
|
}
|
2022-07-01 15:07:22 +00:00
|
|
|
/// A set of arbitrary flags that can be set on the item.
|
2022-11-27 16:29:29 +00:00
|
|
|
fn flags(&self) -> &HashSet<StringKey> {
|
2022-06-06 12:43:41 +00:00
|
|
|
&self.flags
|
|
|
|
}
|
|
|
|
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Checks whether the item has a specific flag.
|
2022-11-27 16:29:29 +00:00
|
|
|
fn has_flag(&self, key: &StringKey) -> bool {
|
2021-01-30 21:29:59 +00:00
|
|
|
self.flags.contains(key)
|
|
|
|
}
|
|
|
|
}
|
2022-10-08 11:15:04 +00:00
|
|
|
|
2022-11-28 20:34:28 +00:00
|
|
|
#[cfg(test)]
|
2023-04-19 16:44:11 +00:00
|
|
|
#[allow(clippy::indexing_slicing)]
|
2022-11-28 20:34:28 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|