|
|
@ -3,6 +3,7 @@ use libpso::character::character; |
|
|
|
use crate::ship::items::ClientItemId;
|
|
|
|
use crate::entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, InventoryEntity, InventoryItemEntity, EquippedEntity};
|
|
|
|
use std::future::Future;
|
|
|
|
use async_std::sync::{Arc, Mutex};
|
|
|
|
|
|
|
|
use crate::entity::character::CharacterEntityId;
|
|
|
|
use crate::entity::item::tool::ToolType;
|
|
|
@ -117,22 +118,12 @@ impl InventoryItemDetail { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct InventoryItem {
|
|
|
|
pub item_id: ClientItemId,
|
|
|
|
pub item: InventoryItemDetail,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InventoryItem {
|
|
|
|
pub async fn with_entity_id<F, Fut, T>(&self, mut param: T, mut func: F) -> Result<T, anyhow::Error>
|
|
|
|
where
|
|
|
|
F: FnMut(T, ItemEntityId) -> Fut,
|
|
|
|
Fut: Future<Output=Result<T, anyhow::Error>>,
|
|
|
|
{
|
|
|
|
match &self.item {
|
|
|
|
match &self {
|
|
|
|
InventoryItemDetail::Individual(individual_item) => {
|
|
|
|
param = func(param, individual_item.entity_id).await?;
|
|
|
|
},
|
|
|
@ -145,6 +136,23 @@ impl InventoryItem { |
|
|
|
|
|
|
|
Ok(param)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct InventoryItem {
|
|
|
|
pub item_id: ClientItemId,
|
|
|
|
pub item: InventoryItemDetail,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InventoryItem {
|
|
|
|
pub async fn with_entity_id<F, Fut, T>(&self, param: T, func: F) -> Result<T, anyhow::Error>
|
|
|
|
where
|
|
|
|
F: FnMut(T, ItemEntityId) -> Fut,
|
|
|
|
Fut: Future<Output=Result<T, anyhow::Error>>,
|
|
|
|
{
|
|
|
|
self.item.with_entity_id(param, func).await
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn with_mag<F, Fut, T>(&self, mut param: T, mut func: F) -> Result<T, anyhow::Error>
|
|
|
|
where
|
|
|
@ -183,23 +191,38 @@ pub enum InventoryError { |
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct InventoryState {
|
|
|
|
pub character_id: CharacterEntityId,
|
|
|
|
pub item_id_counter: u32,
|
|
|
|
pub item_id_counter: Arc<Mutex<u32>>,
|
|
|
|
pub inventory: Inventory,
|
|
|
|
pub equipped: EquippedEntity,
|
|
|
|
pub meseta: Meseta,
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn new_item_id(item_id_counter: &Arc<Mutex<u32>>) -> ClientItemId {
|
|
|
|
let mut item_id_counter = item_id_counter.lock().await;
|
|
|
|
let item_id = *item_id_counter;
|
|
|
|
*item_id_counter += 1;
|
|
|
|
|
|
|
|
ClientItemId(item_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InventoryState {
|
|
|
|
pub fn initialize_item_ids(&mut self, base_item_id: u32) {
|
|
|
|
pub async fn initialize_item_ids(&mut self, base_item_id: Arc<Mutex<u32>>) {
|
|
|
|
self.item_id_counter = base_item_id;
|
|
|
|
let mut bitem_id = self.item_id_counter.lock().await;
|
|
|
|
|
|
|
|
for (i, item) in self.inventory.0.iter_mut().enumerate() {
|
|
|
|
item.item_id = ClientItemId(base_item_id + i as u32);
|
|
|
|
item.item_id = ClientItemId(*bitem_id + i as u32);
|
|
|
|
}
|
|
|
|
self.item_id_counter = base_item_id + self.inventory.0.len() as u32 + 1;
|
|
|
|
|
|
|
|
*bitem_id = *bitem_id + self.inventory.0.len() as u32;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_item_id(&mut self) -> ClientItemId {
|
|
|
|
self.item_id_counter += 1;
|
|
|
|
ClientItemId(self.item_id_counter)
|
|
|
|
pub async fn new_item_id(&mut self) -> ClientItemId {
|
|
|
|
let mut item_id_counter = self.item_id_counter.lock().await;
|
|
|
|
let item_id = *item_id_counter;
|
|
|
|
*item_id_counter += 1;
|
|
|
|
|
|
|
|
ClientItemId(item_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn count(&self) -> usize {
|
|
|
@ -326,7 +349,36 @@ impl InventoryState { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn take_item(&mut self, item_id: &ClientItemId, amount: u32) -> Option<InventoryItem> {
|
|
|
|
pub async fn remove_item(&mut self, item_id: &ClientItemId, amount: u32) -> Option<InventoryItemDetail> {
|
|
|
|
let idx = self.inventory.0
|
|
|
|
.iter()
|
|
|
|
.position(|i| i.item_id == *item_id)?;
|
|
|
|
match &mut self.inventory.0[idx].item {
|
|
|
|
InventoryItemDetail::Individual(_individual_item) => {
|
|
|
|
Some(self.inventory.0.remove(idx).item)
|
|
|
|
},
|
|
|
|
InventoryItemDetail::Stacked(stacked_item) => {
|
|
|
|
let remove_all = (amount == 0) || match stacked_item.entity_ids.len().cmp(&(amount as usize)) {
|
|
|
|
Ordering::Equal => true,
|
|
|
|
Ordering::Greater => false,
|
|
|
|
Ordering::Less => return None,
|
|
|
|
};
|
|
|
|
|
|
|
|
if remove_all {
|
|
|
|
Some(self.inventory.0.remove(idx).item)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
let entity_ids = stacked_item.entity_ids.drain(..(amount as usize)).collect();
|
|
|
|
Some(InventoryItemDetail::Stacked(StackedItemDetail {
|
|
|
|
entity_ids,
|
|
|
|
tool: stacked_item.tool,
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn take_item(&mut self, item_id: &ClientItemId, amount: u32) -> Option<InventoryItem> {
|
|
|
|
let idx = self.inventory.0
|
|
|
|
.iter()
|
|
|
|
.position(|i| i.item_id == *item_id)?;
|
|
|
@ -346,9 +398,8 @@ impl InventoryState { |
|
|
|
}
|
|
|
|
else {
|
|
|
|
let entity_ids = stacked_item.entity_ids.drain(..(amount as usize)).collect();
|
|
|
|
self.item_id_counter += 1;
|
|
|
|
Some(InventoryItem {
|
|
|
|
item_id: ClientItemId(self.item_id_counter),
|
|
|
|
item_id: new_item_id(&self.item_id_counter).await,
|
|
|
|
item: InventoryItemDetail::Stacked(StackedItemDetail {
|
|
|
|
entity_ids,
|
|
|
|
tool: stacked_item.tool,
|
|
|
|