use crate::abi::ItemData;
use crate::{Entity, ItemId};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord, crate::Script)]
pub struct SlotRef(pub u64);
impl SlotRef {
#[must_use]
pub const fn new(inventory: Entity, index: u8) -> Self {
Self(inventory.0 as u64 | (index as u64) << 32)
}
#[must_use]
#[expect(clippy::cast_possible_truncation, reason = "the low half")]
pub const fn inventory(self) -> Entity {
Entity(self.0 as u32)
}
#[must_use]
#[expect(clippy::cast_possible_truncation, reason = "a byte")]
pub const fn index(self) -> u8 {
(self.0 >> 32) as u8
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, crate::Script)]
pub struct InventoryCategory(pub u8);
impl InventoryCategory {
pub const INVALID: Self = Self(0);
pub const CUSTOMIZATION: Self = Self(1);
pub const EQUIPMENT: Self = Self(2);
pub const CURRENCY: Self = Self(3);
pub const GENERIC: Self = Self(4);
pub const VIRTUAL: Self = Self(5);
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, crate::Script)]
pub struct Slot {
pub at: SlotRef,
pub category: InventoryCategory,
pub item: ItemId,
pub count: u32,
pub pide: Option<Entity>,
}
impl Slot {
#[must_use]
pub const fn is_empty(&self) -> bool {
self.item.get() == 0 || self.count == 0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, crate::Script)]
pub struct ItemInfo {
pub id: ItemId,
pub max_stack_size: u16,
pub flags: u32,
pub category: u8,
}
impl ItemInfo {
#[must_use]
pub const fn has_pide(&self) -> bool {
self.flags & ItemData::HAS_PIDE != 0
}
#[must_use]
pub const fn is_container(&self) -> bool {
self.flags & ItemData::IS_CONTAINER != 0
}
#[must_use]
pub const fn is_blueprint(&self) -> bool {
self.flags & ItemData::IS_BLUEPRINT != 0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Bar {
pub current: u16,
pub max: u16,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Fill(pub u16);
impl Fill {
pub const EMPTY: Self = Self(0);
pub const FULL: Self = Self(u16::MAX);
#[must_use]
pub fn of(count: u16, max: u16) -> Self {
if max == 0 {
return Self::EMPTY;
}
let parts = u32::from(count.min(max)) * u32::from(u16::MAX);
let max = u32::from(max);
Self(u16::try_from((parts + max / 2) / max).unwrap_or(u16::MAX))
}
#[must_use]
pub fn fraction(self) -> f32 {
f32::from(self.0) / f32::from(u16::MAX)
}
}