mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-21 14:28:43 -06:00
implement more item functions
This commit is contained in:
parent
a2e5a29e3a
commit
1251d07c60
|
@ -1,4 +1,4 @@
|
||||||
use shipyard::{IntoWorkload, SystemModificator, Workload, WorkloadModificator, World};
|
use shipyard::{IntoWorkload, Workload, WorkloadModificator, World};
|
||||||
use std::{thread, time::Duration};
|
use std::{thread, time::Duration};
|
||||||
use kubi_shared::fixed_timestamp::{FixedTimestamp, init_fixed_timestamp_storage};
|
use kubi_shared::fixed_timestamp::{FixedTimestamp, init_fixed_timestamp_storage};
|
||||||
|
|
||||||
|
|
|
@ -38,29 +38,194 @@ impl Item {
|
||||||
pub struct ItemCollection(Option<(Item, NonZeroU8)>);
|
pub struct ItemCollection(Option<(Item, NonZeroU8)>);
|
||||||
|
|
||||||
impl ItemCollection {
|
impl ItemCollection {
|
||||||
pub const fn new(item: Item, amount: NonZeroU8) -> Self {
|
/// Create a new item collection with `amount` of `item`
|
||||||
|
///
|
||||||
|
/// If `amount` is 0, the slot will be empty, and the item will be ignored
|
||||||
|
pub const fn new(item: Item, amount: u8) -> Self {
|
||||||
|
if amount == 0 {
|
||||||
|
return Self::new_empty()
|
||||||
|
}
|
||||||
|
// SAFETY: `amount` guaranteed to be non-zero
|
||||||
|
let amount = unsafe { NonZeroU8::new_unchecked(amount) };
|
||||||
|
Self::new_nonzero(item, amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new item collection with `amount` of `item`
|
||||||
|
pub const fn new_nonzero(item: Item, amount: NonZeroU8) -> Self {
|
||||||
Self(Some((item, amount)))
|
Self(Some((item, amount)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new item collection with a single item
|
||||||
pub const fn new_single(item: Item) -> Self {
|
pub const fn new_single(item: Item) -> Self {
|
||||||
Self(Some((item, nz::u8!(1))))
|
Self(Some((item, nz::u8!(1))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new empty item collection
|
||||||
pub const fn new_empty() -> Self {
|
pub const fn new_empty() -> Self {
|
||||||
Self(None)
|
Self(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn with_amount(&self, amount: NonZeroU8) -> Self {
|
/// Set the amount of items in the slot to `amount`\
|
||||||
|
///
|
||||||
|
/// If `amount` is 0, the slot will be emptied\
|
||||||
|
/// If slot is empty, this will do nothing, even if `amount` is non-zero
|
||||||
|
pub const fn with_amount(&self, amount: u8) -> Self {
|
||||||
|
if amount == 0 {
|
||||||
|
return Self::new_empty()
|
||||||
|
}
|
||||||
|
// SAFETY: `amount` guaranteed to be non-zero
|
||||||
|
let amount = unsafe { NonZeroU8::new_unchecked(amount) };
|
||||||
|
self.with_amount_nonzero(amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the amount of items in the slot to `amount`
|
||||||
|
///
|
||||||
|
/// If slot is empty, this will do nothing
|
||||||
|
pub const fn with_amount_nonzero(&self, amount: NonZeroU8) -> Self {
|
||||||
Self(match self.0 {
|
Self(match self.0 {
|
||||||
Some((item, _)) => Some((item, amount)),
|
Some((item, _)) => Some((item, amount)),
|
||||||
None => None,
|
None => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the slot is empty (contains no items)
|
||||||
|
pub const fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_none()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if the slot is full (contains the maximum stack size)
|
||||||
|
pub const fn is_full(&self) -> bool {
|
||||||
|
match self.0 {
|
||||||
|
Some((item, amount)) => {
|
||||||
|
amount.get() >= item.descriptor().stack_size.get()
|
||||||
|
},
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the item in the slot
|
||||||
|
///
|
||||||
|
/// If the slot is empty, returns None
|
||||||
|
pub const fn item(&self) -> Option<Item> {
|
||||||
|
match self.0 {
|
||||||
|
Some((item, _)) => Some(item),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the amount of items in the slot
|
||||||
|
///
|
||||||
|
/// If the slot is empty, returns 0
|
||||||
|
pub const fn amount(&self) -> u8 {
|
||||||
|
match self.0 {
|
||||||
|
Some((_, amount)) => amount.get(),
|
||||||
|
None => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the amount of items in the slot
|
||||||
|
///
|
||||||
|
/// If the slot is empty, returns None
|
||||||
|
pub const fn amount_nonzero(&self) -> Option<NonZeroU8> {
|
||||||
|
match self.0 {
|
||||||
|
Some((_, amount)) => Some(amount),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Add items from another slot, copying them\
|
/// Add items from another slot, copying them\
|
||||||
/// Returns the leftover items
|
/// Returns the leftover items (items that could not be added)
|
||||||
pub fn add(&mut self, from: &Self) -> Self {
|
pub fn add(&mut self, from: &Self) -> Self {
|
||||||
let Some((item, count)) = from.0 else { return Self::new_empty() };
|
// If there are no items to add, return
|
||||||
todo!() //TODO finish item slot system
|
let Some((add_item, add_count)) = from.0 else {
|
||||||
|
return Self::new_empty()
|
||||||
|
};
|
||||||
|
let item_stack_size = add_item.descriptor().stack_size;
|
||||||
|
|
||||||
|
// Add items to the slot
|
||||||
|
let (this_slot, leftovers) = match self.0 {
|
||||||
|
None => (
|
||||||
|
(
|
||||||
|
add_item,
|
||||||
|
add_count.min(item_stack_size)
|
||||||
|
),
|
||||||
|
match add_count > item_stack_size {
|
||||||
|
true => Self::new_nonzero(
|
||||||
|
add_item,
|
||||||
|
NonZeroU8::new(
|
||||||
|
add_count.get() - item_stack_size.get()
|
||||||
|
).unwrap(),
|
||||||
|
),
|
||||||
|
false => Self::new_empty()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
Some((cur_item, cur_count)) if cur_item == add_item => {
|
||||||
|
let total_count = cur_count.checked_add(add_count.get()).unwrap();
|
||||||
|
(
|
||||||
|
(
|
||||||
|
cur_item,
|
||||||
|
total_count.min(item_stack_size),
|
||||||
|
),
|
||||||
|
match total_count > item_stack_size {
|
||||||
|
true => Self::new_nonzero(
|
||||||
|
add_item,
|
||||||
|
NonZeroU8::new(
|
||||||
|
total_count.get() - item_stack_size.get()
|
||||||
|
).unwrap()
|
||||||
|
),
|
||||||
|
false => Self::new_empty()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
// If items are different, do not add anything, everything is leftovers
|
||||||
|
_ => return *from,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.0 = Some(this_slot);
|
||||||
|
leftovers
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move as much as possible items from another slot, removing them
|
||||||
|
///
|
||||||
|
/// This may not be possible if the slot is full or contains a different item
|
||||||
|
pub fn move_all(&mut self, to: &mut Self) {
|
||||||
|
let leftovers = to.add(self);
|
||||||
|
*self = leftovers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move up to `amount` items from another slot, removing them
|
||||||
|
///
|
||||||
|
/// If `amount` is 0, nothing will be moved
|
||||||
|
pub fn move_up_to(&mut self, to: &mut Self, limit: u8) {
|
||||||
|
|
||||||
|
if self.is_empty() { return }
|
||||||
|
// SAFETY: slot is guaranteed to be non-empty
|
||||||
|
let amount = unsafe { self.amount_nonzero().unwrap_unchecked() } ;
|
||||||
|
|
||||||
|
if limit == 0 { return }
|
||||||
|
// SAFETY: `limit` guaranteed to be non-zero
|
||||||
|
let limit = unsafe { NonZeroU8::new_unchecked(limit) };
|
||||||
|
|
||||||
|
let amount_with_limit = amount.min(limit);
|
||||||
|
let self_with_limit = self.with_amount_nonzero(amount_with_limit);
|
||||||
|
|
||||||
|
let mut leftovers = to.add(&self_with_limit);
|
||||||
|
|
||||||
|
// Compensate for the amount of items that were not moved
|
||||||
|
let amount_difference = amount.get() - amount_with_limit.get();
|
||||||
|
if amount_difference > 0 {
|
||||||
|
let correct_item = self.item().unwrap();
|
||||||
|
let correct_amount = leftovers.amount() + amount_difference;
|
||||||
|
leftovers = Self::new(correct_item, correct_amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
*self = leftovers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to move a single item from another slot, removing it
|
||||||
|
///
|
||||||
|
/// This may not be possible if the slot is full or contains a different item
|
||||||
|
pub fn move_single(&mut self, to: &mut Self) {
|
||||||
|
self.move_up_to(to, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue