111 lines
3.4 KiB
Rust
111 lines
3.4 KiB
Rust
|
use crate::handling::cached_value::CachedValue;
|
||
|
use crate::handling::Cacheable;
|
||
|
use crate::{cached_value, ExternRef, ExternalReferenceType, StringKey};
|
||
|
use alloc::rc::Rc;
|
||
|
|
||
|
/// An item category defines which bag slot items are stored in.
|
||
|
#[repr(u8)]
|
||
|
#[derive(Clone)]
|
||
|
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.
|
||
|
#[repr(u8)]
|
||
|
#[derive(Clone)]
|
||
|
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,
|
||
|
}
|
||
|
|
||
|
struct ItemInner {
|
||
|
ptr: ExternRef<Item>,
|
||
|
name: CachedValue<StringKey>,
|
||
|
category: CachedValue<ItemCategory>,
|
||
|
battle_category: CachedValue<BattleItemCategory>,
|
||
|
price: CachedValue<i32>,
|
||
|
}
|
||
|
|
||
|
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
||
|
#[derive(Clone)]
|
||
|
pub struct Item {
|
||
|
inner: Rc<ItemInner>,
|
||
|
}
|
||
|
|
||
|
impl Item {
|
||
|
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
|
||
|
Self::from_ref(ptr, &|ptr| Self {
|
||
|
inner: Rc::new(ItemInner {
|
||
|
ptr,
|
||
|
name: cached_value!({ StringKey::new(item_get_name(ptr)) }),
|
||
|
category: cached_value!({ item_get_category(ptr) }),
|
||
|
battle_category: cached_value!({ item_get_battle_category(ptr) }),
|
||
|
price: cached_value!({ item_get_price(ptr) }),
|
||
|
}),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
pub(crate) fn ptr(&self) -> ExternRef<Self> {
|
||
|
self.inner.ptr
|
||
|
}
|
||
|
|
||
|
/// The name of the item.
|
||
|
pub fn name(&self) -> StringKey {
|
||
|
self.inner.name.value()
|
||
|
}
|
||
|
/// Which bag slot items are stored in.
|
||
|
pub fn category(&self) -> ItemCategory {
|
||
|
self.inner.category.value()
|
||
|
}
|
||
|
/// How the item is categorized when in battle.
|
||
|
pub fn battle_category(&self) -> BattleItemCategory {
|
||
|
self.inner.battle_category.value()
|
||
|
}
|
||
|
/// The buying value of the item.
|
||
|
pub fn price(&self) -> i32 {
|
||
|
self.inner.price.value()
|
||
|
}
|
||
|
pub fn has_flag(&self, flag: &StringKey) -> bool {
|
||
|
unsafe { item_has_flag(self.ptr(), flag.ptr()) }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
crate::handling::cacheable::cacheable!(Item);
|
||
|
|
||
|
impl ExternalReferenceType for Item {
|
||
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||
|
Item::new(reference)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern "wasm" {
|
||
|
fn item_get_name(ptr: ExternRef<Item>) -> ExternRef<StringKey>;
|
||
|
fn item_get_category(ptr: ExternRef<Item>) -> ItemCategory;
|
||
|
fn item_get_battle_category(ptr: ExternRef<Item>) -> BattleItemCategory;
|
||
|
fn item_get_price(ptr: ExternRef<Item>) -> i32;
|
||
|
fn item_has_flag(ptr: ExternRef<Item>, flag: ExternRef<StringKey>) -> bool;
|
||
|
}
|