diff --git a/Cargo.lock b/Cargo.lock index 6ed5058..e85e554 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,6 +172,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "async-recursion" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-std" version = "1.11.0" @@ -587,6 +598,7 @@ version = "0.1.0" dependencies = [ "ages-prs", "anyhow", + "async-recursion", "async-std", "async-trait", "barrel", diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index 49c9c7f..10af797 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -11,7 +11,6 @@ use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateAction, Item use crate::ship::items::apply_item::apply_item; use crate::entity::item::{ItemDetail, NewItemEntity, TradeId}; use crate::entity::item::tool::Tool; -use crate::entity::item::weapon::WeaponModifier; use crate::entity::item::ItemModifier; use crate::ship::shops::ShopItem; use crate::ship::trade::TradeItem; diff --git a/src/ship/items/apply_item.rs b/src/ship/items/apply_item.rs index 1028ed7..ce4a701 100644 --- a/src/ship/items/apply_item.rs +++ b/src/ship/items/apply_item.rs @@ -1,12 +1,11 @@ use thiserror::Error; -use std::convert::TryFrom; use std::convert::TryInto; use crate::entity::gateway::{EntityGateway, GatewayError}; use crate::entity::character::CharacterEntity; use crate::entity::item::mag::{MagCell, MagCellError}; use crate::entity::item::tool::ToolType; use crate::entity::item::{ItemDetail, ItemEntityId}; -use crate::ship::items::state::{ItemStateProxy, InventoryState, InventoryItem, InventoryItemDetail, ItemStateError}; +use crate::ship::items::state::{ItemStateProxy, InventoryItem, InventoryItemDetail, ItemStateError}; #[derive(Error, Debug)] diff --git a/src/ship/items/bank.rs b/src/ship/items/bank.rs deleted file mode 100644 index dab026f..0000000 --- a/src/ship/items/bank.rs +++ /dev/null @@ -1,324 +0,0 @@ -use crate::ship::items::ClientItemId; -use libpso::character::character;//::InventoryItem; -use crate::entity::item::{ItemEntityId, ItemEntity, ItemDetail, BankEntity, BankItemEntity, BankName}; -use crate::entity::character::CharacterEntityId; -use crate::entity::item::tool::Tool; -use crate::ship::items::inventory::{InventoryItemHandle, InventoryItem}; - -const BANK_CAPACITY: usize = 200; - -#[derive(Debug, Clone)] -pub struct IndividualBankItem { - pub entity_id: ItemEntityId, - pub item_id: ClientItemId, - pub item: ItemDetail, -} - -#[derive(Debug, Clone)] -pub struct StackedBankItem { - pub entity_ids: Vec, - pub item_id: ClientItemId, - pub tool: Tool, -} - -impl StackedBankItem { - pub fn count(&self) -> usize { - self.entity_ids.len() - } - - pub fn take_entity_ids(&mut self, amount: usize) -> Option> { - if amount <= self.count() { - Some(self.entity_ids.drain(..amount).collect()) - } - else { - None - } - } -} - -#[derive(Debug, Clone)] -pub enum BankItem { - Individual(IndividualBankItem), - Stacked(StackedBankItem), -} - - -impl std::cmp::PartialEq for BankItem { - fn eq(&self, other: &BankItem) -> bool { - let mut self_bytes = [0u8; 4]; - let mut other_bytes = [0u8; 4]; - self_bytes.copy_from_slice(&self.as_client_bytes()[0..4]); - other_bytes.copy_from_slice(&other.as_client_bytes()[0..4]); - - let self_value = u32::from_be_bytes(self_bytes); - let other_value = u32::from_be_bytes(other_bytes); - - self_value.eq(&other_value) - } -} - -impl std::cmp::Eq for BankItem {} - -impl std::cmp::PartialOrd for BankItem { - fn partial_cmp(&self, other: &BankItem) -> Option { - //let self_bytes = self.as_client_bytes(); - //let other_bytes = other.as_client_bytes(); - let mut self_bytes = [0u8; 4]; - let mut other_bytes = [0u8; 4]; - self_bytes.copy_from_slice(&self.as_client_bytes()[0..4]); - other_bytes.copy_from_slice(&other.as_client_bytes()[0..4]); - - - let self_value = u32::from_be_bytes(self_bytes); - let other_value = u32::from_be_bytes(other_bytes); - - self_value.partial_cmp(&other_value) - } -} - -impl std::cmp::Ord for BankItem { - fn cmp(&self, other: &BankItem) -> std::cmp::Ordering { - //let self_bytes = self.as_client_bytes(); - //let other_bytes = other.as_client_bytes(); - let mut self_bytes = [0u8; 4]; - let mut other_bytes = [0u8; 4]; - self_bytes.copy_from_slice(&self.as_client_bytes()[0..4]); - other_bytes.copy_from_slice(&other.as_client_bytes()[0..4]); - - - let self_value = u32::from_le_bytes(self_bytes); - let other_value = u32::from_le_bytes(other_bytes); - - self_value.cmp(&other_value) - } -} - -impl BankItem { - pub fn set_item_id(&mut self, item_id: ClientItemId) { - match self { - BankItem::Individual(individual_bank_item) => { - individual_bank_item.item_id = item_id - }, - BankItem::Stacked(stacked_bank_item) => { - stacked_bank_item.item_id = item_id - } - } - } - - pub fn item_id(&self) -> ClientItemId { - match self { - BankItem::Individual(individual_bank_item) => { - individual_bank_item.item_id - }, - BankItem::Stacked(stacked_bank_item) => { - stacked_bank_item.item_id - } - } - } - - pub fn as_client_bytes(&self) -> [u8; 16] { - match self { - BankItem::Individual(item) => { - match &item.item { - ItemDetail::Weapon(w) => w.as_bytes(), - ItemDetail::Armor(a) => a.as_bytes(), - ItemDetail::Shield(s) => s.as_bytes(), - ItemDetail::Unit(u) => u.as_bytes(), - ItemDetail::Tool(t) => t.as_individual_bytes(), - ItemDetail::TechniqueDisk(d) => d.as_bytes(), - ItemDetail::Mag(m) => m.as_bytes(), - ItemDetail::ESWeapon(e) => e.as_bytes(), - } - }, - BankItem::Stacked(item) => { - item.tool.as_stacked_bytes(item.entity_ids.len()) - }, - } - } -} - - -pub struct BankItemHandle<'a> { - bank: &'a mut CharacterBank, - index: usize -} - -impl<'a> BankItemHandle<'a> { - pub fn item(&'a self) -> Option<&'a BankItem> { - self.bank.items.get(self.index) - } - - pub fn item_mut(&mut self) -> Option<&mut BankItem> { - self.bank.items.get_mut(self.index) - } - - pub fn remove_from_bank(self) { - self.bank.items.remove(self.index); - } -} - -pub struct CharacterBank { - item_id_counter: u32, - items: Vec -} - -impl CharacterBank { - pub fn new(mut items: Vec) -> CharacterBank { - items.sort(); - CharacterBank { - item_id_counter: 0, - items, - } - } - - pub fn initialize_item_ids(&mut self, base_item_id: u32) { - for (i, item) in self.items.iter_mut().enumerate() { - item.set_item_id(ClientItemId(base_item_id + i as u32)); - } - self.item_id_counter = base_item_id + self.items.len() as u32 + 1; - } - - pub fn get_item_handle_by_id(&mut self, item_id: ClientItemId) -> Option { - let (index, _) = self.items.iter() - .enumerate() - .find(|(_, item)| { - item.item_id() == item_id - })?; - Some(BankItemHandle { - bank: self, - index, - }) - } - - pub fn as_client_bank_items(&self) -> character::Bank { - self.items.iter() - .enumerate() - .fold(character::Bank::default(), |mut bank, (slot, item)| { - bank.item_count = (slot + 1) as u32; - let bytes = item.as_client_bytes(); - bank.items[slot].data1.copy_from_slice(&bytes[0..12]); - bank.items[slot].data2.copy_from_slice(&bytes[12..16]); - bank.items[slot].item_id = item.item_id().0; - - bank - }) - } - - pub fn as_client_bank_request(&self) -> Vec { - self.items.iter() - .map(|item| { - let bytes = item.as_client_bytes(); - let mut data1 = [0; 12]; - let mut data2 = [0; 4]; - data1.copy_from_slice(&bytes[0..12]); - data2.copy_from_slice(&bytes[12..16]); - let amount = match item { - BankItem::Individual(_individual_bank_item) => { - 1 - }, - BankItem::Stacked(stacked_bank_item) => { - stacked_bank_item.count() - }, - }; - character::BankItem { - data1, - data2, - item_id: item.item_id().0, - amount: amount as u16, - flags: 1, - } - }) - .collect() - } - - pub fn count(&self) -> usize { - self.items.len() - } - - pub fn deposit_item(&mut self, mut inventory_item: InventoryItemHandle, amount: usize) -> Option<&BankItem> { - let remove = match inventory_item.item_mut()? { - InventoryItem::Individual(individual_inventory_item) => { - if self.items.len() >= BANK_CAPACITY { - return None - } - self.items.push(BankItem::Individual(IndividualBankItem { - entity_id: individual_inventory_item.entity_id, - item_id: individual_inventory_item.item_id, - item: individual_inventory_item.item.clone(), - })); - true - }, - InventoryItem::Stacked(stacked_inventory_item) => { - let existing_bank_item = self.items.iter_mut() - .find_map(|item| { - if let BankItem::Stacked(stacked_bank_item) = item { - if stacked_bank_item.tool == stacked_inventory_item.tool { - return Some(stacked_bank_item) - } - } - None - }); - - match existing_bank_item { - Some(stacked_bank_item) => { - if stacked_bank_item.count() + stacked_inventory_item.count() > stacked_inventory_item.tool.max_stack() { - return None - } - - let mut deposited_entity_ids = stacked_inventory_item.take_entity_ids(amount)?; - stacked_bank_item.entity_ids.append(&mut deposited_entity_ids); - } - None => { - if self.items.len() >= BANK_CAPACITY { - return None - } - let deposited_entity_ids = stacked_inventory_item.take_entity_ids(amount)?; - - self.item_id_counter += 1; - self.items.push(BankItem::Stacked(StackedBankItem { - entity_ids: deposited_entity_ids, - item_id: ClientItemId(self.item_id_counter), - tool: stacked_inventory_item.tool, - })) - } - } - stacked_inventory_item.count() == 0 - } - }; - - if remove { - inventory_item.remove_from_inventory(); - } - - self.items.last() - } - - pub fn as_bank_entity(&self, _character_id: &CharacterEntityId, _bank_name: &BankName) -> BankEntity { - BankEntity { - items: self.items.iter() - .map(|item| { - match item { - BankItem::Individual(item) => { - BankItemEntity::Individual(ItemEntity { - id: item.entity_id, - item: item.item.clone(), - }) - }, - BankItem::Stacked(items) => { - BankItemEntity::Stacked(items.entity_ids.iter() - .map(|id| { - ItemEntity { - id: *id, - item: ItemDetail::Tool(items.tool) - } - }) - .collect()) - }, - } - }) - .collect() - } - } -} - - diff --git a/src/ship/items/floor.rs b/src/ship/items/floor.rs deleted file mode 100644 index f2720c0..0000000 --- a/src/ship/items/floor.rs +++ /dev/null @@ -1,253 +0,0 @@ -use crate::ship::items::ClientItemId; -use crate::entity::item::{ItemEntityId, ItemDetail}; -use crate::entity::item::Meseta; -use crate::entity::item::tool::Tool; -use crate::ship::map::MapArea; -use crate::ship::items::inventory::{IndividualInventoryItem, StackedInventoryItem, InventoryItemHandle}; - - -#[derive(Debug, Clone)] -pub struct IndividualFloorItem { - pub entity_id: ItemEntityId, - pub item_id: ClientItemId, - pub item: ItemDetail, - pub map_area: MapArea, - pub x: f32, - pub y: f32, - pub z: f32, -} - -#[derive(Debug, Clone)] -pub struct StackedFloorItem { - pub entity_ids: Vec, - pub item_id: ClientItemId, - pub tool: Tool, - pub map_area: MapArea, - pub x: f32, - pub y: f32, - pub z: f32, -} - -impl StackedFloorItem { - pub fn count(&self) -> usize { - self.entity_ids.len() - } - - pub fn as_client_bytes(&self) -> [u8; 16] { - self.tool.as_stacked_bytes(self.count()) - } -} - -#[derive(Debug, Clone)] -pub struct MesetaFloorItem { - pub item_id: ClientItemId, - pub meseta: Meseta, - pub map_area: MapArea, - pub x: f32, - pub y: f32, - pub z: f32, -} - -#[derive(Debug, Clone)] -pub enum FloorItem { - Individual(IndividualFloorItem), - Stacked(StackedFloorItem), - Meseta(MesetaFloorItem), -} - -impl FloorItem { - pub fn item_id(&self) -> ClientItemId { - match self { - FloorItem::Individual(individual_floor_item) => { - individual_floor_item.item_id - }, - FloorItem::Stacked(stacked_floor_item) => { - stacked_floor_item.item_id - }, - FloorItem::Meseta(meseta_floor_item) => { - meseta_floor_item.item_id - } - } - } - - pub fn x(&self) -> f32 { - match self { - FloorItem::Individual(individual_floor_item) => { - individual_floor_item.x - }, - FloorItem::Stacked(stacked_floor_item) => { - stacked_floor_item.x - }, - FloorItem::Meseta(meseta_floor_item) => { - meseta_floor_item.x - } - } - } - - pub fn y(&self) -> f32 { - match self { - FloorItem::Individual(individual_floor_item) => { - individual_floor_item.y - }, - FloorItem::Stacked(stacked_floor_item) => { - stacked_floor_item.y - }, - FloorItem::Meseta(meseta_floor_item) => { - meseta_floor_item.y - } - } - } - - pub fn z(&self) -> f32 { - match self { - FloorItem::Individual(individual_floor_item) => { - individual_floor_item.z - }, - FloorItem::Stacked(stacked_floor_item) => { - stacked_floor_item.z - }, - FloorItem::Meseta(meseta_floor_item) => { - meseta_floor_item.z - } - } - } - - pub fn map_area(&self) -> MapArea { - match self { - FloorItem::Individual(individual_floor_item) => { - individual_floor_item.map_area - }, - FloorItem::Stacked(stacked_floor_item) => { - stacked_floor_item.map_area - }, - FloorItem::Meseta(meseta_floor_item) => { - meseta_floor_item.map_area - } - } - } - - pub fn as_client_bytes(&self) -> [u8; 16] { - match self { - FloorItem::Individual(individual_floor_item) => { - individual_floor_item.item.as_client_bytes() - }, - FloorItem::Stacked(stacked_floor_item) => { - stacked_floor_item.as_client_bytes() - }, - FloorItem::Meseta(meseta_floor_item) => { - meseta_floor_item.meseta.as_bytes() - } - } - } -} - - - -pub struct FloorItemHandle<'a> { - floor: &'a mut RoomFloorItems, - index: usize, -} - -impl<'a> FloorItemHandle<'a> { - pub fn item(&'a self) -> Option<&'a FloorItem> { - self.floor.0.get(self.index) - } - - pub fn remove_from_floor(self) { - self.floor.0.remove(self.index); - } -} - -// TODO: floors should keep track of their own item_ids -#[derive(Debug, Default)] -pub struct RoomFloorItems(Vec); - -impl RoomFloorItems { - pub fn add_item(&mut self, item: FloorItem) { - self.0.push(item); - } - - pub fn remove_item(&mut self, item_id: &ClientItemId) { - self.0.retain(|item| item.item_id() != *item_id); - } - - // TODO: &ClientItemId - pub fn get_item_by_id(&self, item_id: ClientItemId) -> Option<&FloorItem> { - self.0.iter().find(|item| item.item_id() == item_id) - } - - // TODO: &ClientItemId - pub fn get_item_handle_by_id(&mut self, item_id: ClientItemId) -> Option { - let index = self.0.iter().position(|item| item.item_id() == item_id)?; - Some(FloorItemHandle { - floor: self, - index, - }) - } - - pub fn take_item_by_id(&mut self, item_id: ClientItemId) -> Option { - self.0 - .drain_filter(|i| i.item_id() == item_id) - .next() - } - - pub fn drop_individual_inventory_item(&mut self, individual_inventory_item: IndividualInventoryItem, item_drop_location: (MapArea, f32, f32, f32)) -> &IndividualFloorItem { - self.0.push(FloorItem::Individual(IndividualFloorItem { - entity_id: individual_inventory_item.entity_id, - item_id: individual_inventory_item.item_id, - item: individual_inventory_item.item, - map_area: item_drop_location.0, - x: item_drop_location.1, - y: item_drop_location.2, - z: item_drop_location.3, - })); - - match self.0.last().unwrap() { - FloorItem::Individual(item) => item, - _ => unreachable!(), - } - } - - pub fn drop_stacked_inventory_item(&mut self, stacked_inventory_item: StackedInventoryItem, item_drop_location: (MapArea, f32, f32, f32)) -> &StackedFloorItem { - self.0.push(FloorItem::Stacked(StackedFloorItem { - entity_ids: stacked_inventory_item.entity_ids, - item_id: stacked_inventory_item.item_id, - tool: stacked_inventory_item.tool, - map_area: item_drop_location.0, - x: item_drop_location.1, - y: item_drop_location.2, - z: item_drop_location.3, - })); - - match self.0.last().unwrap() { - FloorItem::Stacked(item) => item, - _ => unreachable!(), - } - } - - // TODO: Result - // TODO: if consumed_item is not a tool items do not get placed back into inventory (should I care?) - pub fn drop_partial_stacked_inventory_item(&mut self, inventory_item: InventoryItemHandle, amount: usize, new_item_id: ClientItemId, item_drop_location: (MapArea, f32, f32, f32)) -> Option<&StackedFloorItem> { - let consumed_item = inventory_item.consume(amount).ok()?; - - if let ItemDetail::Tool(tool) = consumed_item.item() { - self.0.push(FloorItem::Stacked(StackedFloorItem { - entity_ids: consumed_item.entity_ids(), - item_id: new_item_id, - tool, - map_area: item_drop_location.0, - x: item_drop_location.1, - y: item_drop_location.2, - z: item_drop_location.3, - })) - } - else { - return None - } - - match self.0.last().unwrap() { - FloorItem::Stacked(item) => Some(item), - _ => unreachable!(), - } - } -} diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs deleted file mode 100644 index da4c4b0..0000000 --- a/src/ship/items/inventory.rs +++ /dev/null @@ -1,988 +0,0 @@ -use std::cmp::Ordering; -use thiserror::Error; -use libpso::character::character; -use crate::entity::character::CharacterEntityId; -use crate::entity::item::{ItemEntityId, ItemDetail, ItemEntity, ItemType, InventoryEntity, InventoryItemEntity, EquippedEntity}; -use crate::entity::item::tool::{Tool, ToolType}; -use crate::entity::item::mag::Mag; -use crate::entity::item::weapon::Weapon; -use crate::ship::items::{ClientItemId, BankItem, BankItemHandle, ItemManagerError}; -use crate::ship::items::floor::{IndividualFloorItem, StackedFloorItem}; -use crate::ship::shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem}; - -const INVENTORY_CAPACITY: usize = 30; - - -#[derive(Debug, Clone)] -pub struct InventorySlot(pub usize); - - -#[derive(Debug, Clone)] -pub struct IndividualInventoryItem { - pub entity_id: ItemEntityId, - pub item_id: ClientItemId, - pub item: ItemDetail, -} - -impl IndividualInventoryItem { - pub fn mag(&self) -> Option<&Mag> { - match self.item { - ItemDetail::Mag(ref mag) => Some(mag), - _ => None - } - } - - pub fn weapon(&self) -> Option<&Weapon> { - match self.item { - ItemDetail::Weapon(ref weapon) => Some(weapon), - _ => None - } - } - - pub fn mag_mut(&mut self) -> Option<&mut Mag> { - match self.item { - ItemDetail::Mag(ref mut mag) => Some(mag), - _ => None - } - } -} - -#[derive(Debug, Clone)] -pub struct StackedInventoryItem { - pub entity_ids: Vec, - pub item_id: ClientItemId, - pub tool: Tool, -} - -impl StackedInventoryItem { - pub fn count(&self) -> usize { - self.entity_ids.len() - } - - pub fn take_entity_ids(&mut self, amount: usize) -> Option> { - if amount <= self.count() { - Some(self.entity_ids.drain(..amount).collect()) - } - else { - None - } - } -} - -#[derive(Debug, Clone)] -pub enum InventoryItem { - Individual(IndividualInventoryItem), - Stacked(StackedInventoryItem), -} - -#[derive(Error, Debug, Clone)] -#[error("")] -pub enum InventoryItemAddToError { - BothAreNotStacked, - DifferentTool, - ExceedsCapacity, -} - -#[derive(Error, Debug, Clone)] -#[error("")] -pub enum InventoryAddError { -} - -#[derive(Debug, Clone)] -pub enum YesThereIsSpace { - NewStack, - ExistingStack, -} - -#[derive(Debug, Clone)] -pub enum NoThereIsNotSpace { - FullStack, - FullInventory, -} - -#[derive(Debug, Clone)] -pub enum SpaceForStack { - Yes(YesThereIsSpace), - No(NoThereIsNotSpace), -} - -impl InventoryItem { - pub fn entity_ids(&self) -> Vec { - match self { - InventoryItem::Individual(individual_inventory_item) => { - vec![individual_inventory_item.entity_id] - }, - InventoryItem::Stacked(stacked_inventory_item) => { - stacked_inventory_item.entity_ids.clone() - } - } - } - - pub fn item_id(&self) -> ClientItemId { - match self { - InventoryItem::Individual(individual_inventory_item) => { - individual_inventory_item.item_id - }, - InventoryItem::Stacked(stacked_inventory_item) => { - stacked_inventory_item.item_id - } - } - } - - pub fn set_item_id(&mut self, item_id: ClientItemId) { - match self { - InventoryItem::Individual(individual_inventory_item) => { - individual_inventory_item.item_id = item_id - }, - InventoryItem::Stacked(stacked_inventory_item) => { - stacked_inventory_item.item_id = item_id - } - } - } - - pub fn item_type(&self) -> ItemType { - match self { - InventoryItem::Individual(individual_inventory_item) => { - individual_inventory_item.item.item_type() - }, - InventoryItem::Stacked(stacked_inventory_item) => { - ItemType::Tool(stacked_inventory_item.tool.tool) - } - } - } - - // TOOD: delete? - pub fn are_same_stackable_tool(&self, other_stacked_item: &StackedFloorItem) -> bool { - match self { - InventoryItem::Stacked(self_stacked_item) => { - self_stacked_item.tool == other_stacked_item.tool - && self_stacked_item.tool.is_stackable() && other_stacked_item.tool.is_stackable() - }, - _ => false - } - } - - // TOOD: delete? - pub fn can_combine_stacks(&self, other_stacked_item: &StackedFloorItem) -> bool { - match self { - InventoryItem::Stacked(self_stacked_item) => { - self_stacked_item.tool == other_stacked_item.tool - && self_stacked_item.tool.is_stackable() && other_stacked_item.tool.is_stackable() - && self_stacked_item.count() + other_stacked_item.count() <= self_stacked_item.tool.max_stack() - }, - _ => false - } - } - - // TODO: result - // TOOD: delete? - pub fn combine_stacks(&mut self, other_stacked_item: &mut StackedFloorItem) { - if let InventoryItem::Stacked(self_stacked_item) = self { - self_stacked_item.entity_ids.append(&mut other_stacked_item.entity_ids); - } - } - - pub fn as_client_bytes(&self) -> [u8; 16] { - match self { - InventoryItem::Individual(item) => { - match &item.item { - ItemDetail::Weapon(w) => w.as_bytes(), - ItemDetail::Armor(a) => a.as_bytes(), - ItemDetail::Shield(s) => s.as_bytes(), - ItemDetail::Unit(u) => u.as_bytes(), - ItemDetail::Tool(t) => t.as_individual_bytes(), - ItemDetail::TechniqueDisk(d) => d.as_bytes(), - ItemDetail::Mag(m) => m.as_bytes(), - ItemDetail::ESWeapon(e) => e.as_bytes(), - } - }, - InventoryItem::Stacked(item) => { - item.tool.as_stacked_bytes(item.entity_ids.len()) - }, - } - } - - pub fn can_add_to(&mut self, stacked_floor_item: &StackedFloorItem) -> Result<(), InventoryItemAddToError> { - if let InventoryItem::Stacked(stacked_inventory_item) = self { - if stacked_floor_item.tool != stacked_inventory_item.tool { - return Err(InventoryItemAddToError::DifferentTool) - } - - if stacked_floor_item.tool.tool.max_stack() < (stacked_floor_item.count() + stacked_inventory_item.count()) { - return Err(InventoryItemAddToError::ExceedsCapacity) - } - Ok(()) - } - else { - Err(InventoryItemAddToError::BothAreNotStacked) - } - } - - pub fn add_to(&mut self, mut stacked_floor_item: StackedFloorItem) -> Result<(), InventoryItemAddToError> { - self.can_add_to(&stacked_floor_item)?; - if let InventoryItem::Stacked(stacked_inventory_item) = self { - stacked_inventory_item.entity_ids.append(&mut stacked_floor_item.entity_ids); - } - Ok(()) - } - - pub fn individual(&self) -> Option<&IndividualInventoryItem> { - match self { - InventoryItem::Individual(ref individual_inventory_item) => Some(individual_inventory_item), - _ => None - } - } - - pub fn individual_mut(&mut self) -> Option<&mut IndividualInventoryItem> { - match self { - InventoryItem::Individual(ref mut individual_inventory_item) => Some(individual_inventory_item), - _ => None - } - } - - pub fn get_sell_price(&self) -> Result { - match self { - InventoryItem::Individual(individual_item) => { - match &individual_item.item { - // TODO: can wrapped items be sold? - ItemDetail::Weapon(w) => { - if !w.tekked { - return Ok(1u32) - } - if w.is_rare_item() { - return Ok(10u32) - } - Ok((WeaponShopItem::from(w).price() / 8) as u32) - }, - ItemDetail::Armor(a) => { - if a.is_rare_item() { - return Ok(10u32) - } - Ok((ArmorShopItem::from(a).price() / 8) as u32) - }, - ItemDetail::Shield(s) => { - if s.is_rare_item() { - return Ok(10u32) - } - Ok((ArmorShopItem::from(s).price() / 8) as u32) - }, - ItemDetail::Unit(u) => { - if u.is_rare_item() { - return Ok(10u32) - } - Ok((ArmorShopItem::from(u).price() / 8) as u32) - }, - ItemDetail::Tool(t) => { - if !matches!(t.tool, ToolType::PhotonDrop | ToolType::PhotonSphere | ToolType::PhotonCrystal) && t.is_rare_item() { - return Ok(10u32) - } - Ok((ToolShopItem::from(t).price() / 8) as u32) - }, - ItemDetail::TechniqueDisk(d) => { - Ok((ToolShopItem::from(d).price() / 8) as u32) - }, - ItemDetail::Mag(_m) => { - Err(ItemManagerError::ItemNotSellable(self.clone())) - }, - ItemDetail::ESWeapon(_e) => { - Ok(10u32) - }, - } - }, - // the number of stacked items sold is handled by the caller. this is just the price of 1 - InventoryItem::Stacked(stacked_item) => { - Ok((ToolShopItem::from(&stacked_item.tool).price() / 8) as u32) - }, - } - } - - pub fn stacked(&self) -> Option<&StackedInventoryItem> { - match self { - InventoryItem::Stacked(ref stacked_inventory_item) => Some(stacked_inventory_item), - _ => None - } - } - - pub fn stacked_mut(&mut self) -> Option<&mut StackedInventoryItem> { - match self { - InventoryItem::Stacked(ref mut stacked_inventory_item) => Some(stacked_inventory_item), - _ => None - } - } - - pub fn mag(&self) -> Option<&Mag> { - match self { - InventoryItem::Individual(individual_inventory_item) => individual_inventory_item.mag(), - _ => None - } - } -} - - - - -#[derive(Error, Debug, Clone)] -#[error("")] -pub enum InventoryItemConsumeError { - InconsistentState, - InvalidAmount, -} - -pub struct IndividualConsumedItem { - pub entity_id: ItemEntityId, - pub item: ItemDetail, -} - -pub struct StackedConsumedItem { - pub entity_ids: Vec, - pub tool: Tool -} - -pub enum ConsumedItem { - Individual(IndividualConsumedItem), - Stacked(StackedConsumedItem), -} - -impl ConsumedItem { - pub fn entity_ids(&self) -> Vec { - match self { - ConsumedItem::Individual(individual_consumed_item) => { - vec![individual_consumed_item.entity_id] - }, - ConsumedItem::Stacked(stacked_consumed_item) => { - stacked_consumed_item.entity_ids.clone() - } - } - } - - pub fn item(&self) -> ItemDetail { - match self { - ConsumedItem::Individual(individual_consumed_item) => { - individual_consumed_item.item.clone() - }, - ConsumedItem::Stacked(stacked_consumed_item) => { - ItemDetail::Tool(stacked_consumed_item.tool) - } - } - } -} - - -pub struct InventoryItemHandle<'a> { - inventory: &'a mut CharacterInventory, - slot: usize, -} - -impl<'a> InventoryItemHandle<'a> { - pub fn item(&'a self) -> Option<&'a InventoryItem> { - self.inventory.items.get(self.slot) - } - - pub fn item_mut(&mut self) -> Option<&mut InventoryItem> { - self.inventory.items.get_mut(self.slot) - } - - pub fn remove_from_inventory(self) { - self.inventory.items.remove(self.slot); - } - - pub fn consume(self, amount: usize) -> Result { - enum RemoveMethod { - EntireThing(ConsumedItem), - Partial(Tool), - } - - let inventory_item = self.inventory.items.get(self.slot).ok_or(InventoryItemConsumeError::InconsistentState)?; - let remove_method = match inventory_item { - InventoryItem::Individual(individual_inventory_item) => { - RemoveMethod::EntireThing(ConsumedItem::Individual(IndividualConsumedItem { - entity_id: individual_inventory_item.entity_id, - item: individual_inventory_item.item.clone() - })) - }, - InventoryItem::Stacked(stacked_inventory_item) => { - match stacked_inventory_item.count().cmp(&amount) { - Ordering::Equal => { - RemoveMethod::EntireThing(ConsumedItem::Stacked(StackedConsumedItem { - entity_ids: stacked_inventory_item.entity_ids.clone(), - tool: stacked_inventory_item.tool, - })) - }, - Ordering::Greater => { - RemoveMethod::Partial(stacked_inventory_item.tool) - }, - Ordering::Less => { - return Err(InventoryItemConsumeError::InvalidAmount) - } - } - }, - }; - - match remove_method { - RemoveMethod::EntireThing(consumed_item) => { - self.inventory.items.remove(self.slot); - Ok(consumed_item) - }, - RemoveMethod::Partial(tool) => { - let entity_ids = self.inventory.items.get_mut(self.slot) - .and_then(|item| { - if let InventoryItem::Stacked(stacked_inventory_item) = item { - Some(stacked_inventory_item.entity_ids.drain(..amount).collect::>()) - } - else { - None - } - }) - .ok_or(InventoryItemConsumeError::InvalidAmount)?; - Ok(ConsumedItem::Stacked(StackedConsumedItem { - entity_ids, - tool, - })) - } - } - } - - pub fn get_slot(&self) -> usize { - self.slot - } -} - - - - -#[derive(Debug)] -pub struct CharacterInventory { - item_id_counter: u32, - items: Vec, - equipped: EquippedEntity, -} - -impl CharacterInventory { - pub fn new(items: Vec, equipped: &EquippedEntity) -> CharacterInventory { - CharacterInventory{ - item_id_counter: 0, - items, - equipped: equipped.clone(), - } - } - - pub fn initialize_item_ids(&mut self, base_item_id: u32) { - for (i, item) in self.items.iter_mut().enumerate() { - item.set_item_id(ClientItemId(base_item_id + i as u32)); - } - self.item_id_counter = base_item_id + self.items.len() as u32 + 1; - } - - pub fn as_client_inventory_items(&self) -> [character::InventoryItem; 30] { - self.items.iter() - .enumerate() - .fold([character::InventoryItem::default(); 30], |mut inventory, (slot, item)| { - let bytes = item.as_client_bytes(); - inventory[slot].data1.copy_from_slice(&bytes[0..12]); - inventory[slot].data2.copy_from_slice(&bytes[12..16]); - inventory[slot].item_id = item.item_id().0; - inventory[slot].equipped = 0; - inventory[slot].flags = 0; - - if let InventoryItem::Individual(individual_item) = item { - if self.equipped.is_equipped(&individual_item.entity_id) { - if let ItemDetail::Unit(_) = individual_item.item { - inventory[slot].data1[4] = self.equipped.unit.iter() - .enumerate() - .find(|(_, u_id)| **u_id == Some(individual_item.entity_id)) - .map(|(a, _)| a) - .unwrap_or(0) as u8 - } - inventory[slot].equipped = 1; - inventory[slot].flags |= 8; - } - } - inventory - }) - } - - pub fn slot(&self, slot: usize) -> Option<&InventoryItem> { - self.items.get(slot) - } - - pub fn count(&self) -> usize { - self.items.len() - } - - pub fn space_for_individual_item(&self) -> bool { - self.count() < INVENTORY_CAPACITY - } - - pub fn space_for_stacked_item(&self, tool: &Tool, amount: usize) -> SpaceForStack { - let existing_item = self.items.iter() - .filter_map(|item| { - match item { - InventoryItem::Stacked(s_item) => { - Some(s_item) - }, - _ => None - } - }) - .find(|s_item| { - s_item.tool == *tool - }); - - match existing_item { - Some(item) => { - if item.count() + amount <= tool.tool.max_stack() { - SpaceForStack::Yes(YesThereIsSpace::ExistingStack) - } - else { - SpaceForStack::No(NoThereIsNotSpace::FullStack) - } - } - None => { - if self.count() < INVENTORY_CAPACITY { - SpaceForStack::Yes(YesThereIsSpace::NewStack) - } - else { - SpaceForStack::No(NoThereIsNotSpace::FullInventory) - } - } - } - } - - pub fn stack_item_id(&self, tool: &Tool) -> Option { - self.items.iter() - .filter_map(|item| { - match item { - InventoryItem::Stacked(s_item) => { - Some(s_item) - }, - _ => None - } - }) - .find(|s_item| { - s_item.tool == *tool - }) - .map(|item| { - item.item_id - }) - } - - pub fn get_item_handle_by_id(&mut self, item_id: ClientItemId) -> Option { - let (slot, _) = self.items.iter() - .enumerate() - .find(|(_, item)| { - item.item_id() == item_id - })?; - Some(InventoryItemHandle { - inventory: self, - slot, - }) - } - - pub fn get_equipped_mag_handle(&mut self) -> Option { - let (slot, _) = self.items.iter() - .enumerate() - .find(|(_, item)| { - if let InventoryItem::Individual(individual_inventory_item) = item { - if let ItemDetail::Mag(_) = &individual_inventory_item.item { - return self.equipped.is_equipped(&individual_inventory_item.entity_id) - } - } - false - })?; - Some(InventoryItemHandle { - inventory: self, - slot, - }) - } - - pub fn get_equipped_armor_handle(&mut self) -> Option { - let (slot, _) = self.items.iter() - .enumerate() - .find(|(_, item)| { - if let InventoryItem::Individual(individual_inventory_item) = item { - if let ItemDetail::Armor(_) = &individual_inventory_item.item { - return self.equipped.is_equipped(&individual_inventory_item.entity_id) - } - } - false - })?; - Some(InventoryItemHandle { - inventory: self, - slot, - }) - } - - pub fn get_equipped_shield_handle(&mut self) -> Option { - let (slot, _) = self.items.iter() - .enumerate() - .find(|(_, item)| { - if let InventoryItem::Individual(individual_inventory_item) = item { - if let ItemDetail::Shield(_) = &individual_inventory_item.item { - return self.equipped.is_equipped(&individual_inventory_item.entity_id) - } - } - false - })?; - Some(InventoryItemHandle { - inventory: self, - slot, - }) - } - - pub fn get_equipped_weapon_handle(&mut self) -> Option { - let (slot, _) = self.items.iter() - .enumerate() - .find(|(_, item)| { - if let InventoryItem::Individual(individual_inventory_item) = item { - if let ItemDetail::Weapon(_) = &individual_inventory_item.item { - return self.equipped.is_equipped(&individual_inventory_item.entity_id) - } - } - false - })?; - Some(InventoryItemHandle { - inventory: self, - slot, - }) - } - - pub fn get_item_by_id(&self, item_id: ClientItemId) -> Option<&InventoryItem> { - self.items.iter() - .find(|item| { - item.item_id() == item_id - }) - } - - pub fn take_item_by_id(&mut self, item_id: ClientItemId) -> Option { - self.items - .drain_filter(|i| i.item_id() == item_id) - .next() - } - - pub fn take_stacked_item_by_id(&mut self, item_id: ClientItemId, amount: usize) -> Option { - let idx = self.items - .iter_mut() - .position(|i| i.item_id() == item_id)?; - let item: &mut StackedInventoryItem = self.items.get_mut(idx)?.stacked_mut()?; - match item.entity_ids.len().cmp(&amount) { - Ordering::Equal => { - let item = self.items.remove(idx); - item.stacked().cloned() - }, - Ordering::Greater => { - let entity_ids = item.entity_ids.drain(..amount).collect(); - Some(StackedInventoryItem { - entity_ids, - tool: item.tool, - item_id: item.item_id, - }) - }, - Ordering::Less => { - None - } - } - } - - pub fn add_item(&mut self, item: InventoryItem) { - self.items.push(item); - } - - pub fn add_stacked_item(&mut self, mut item: StackedInventoryItem) { - let existing_item = self.items - .iter_mut() - .filter_map(|i| { - match i { - InventoryItem::Stacked(stacked) => { - Some(stacked) - }, - _ => None - } - }) - .find(|i| { - i.tool == item.tool - }); - - match existing_item { - Some(existing_item) => { - existing_item.entity_ids.append(&mut item.entity_ids) - }, - None => { - self.items.push(InventoryItem::Stacked(item)) - } - } - } - - pub fn add_item_with_new_item_id(&mut self, item: InventoryItem, item_id: ClientItemId) { - match item { - InventoryItem::Individual(mut individual_inventory_item) => { - individual_inventory_item.item_id = item_id; - self.add_item(InventoryItem::Individual(individual_inventory_item)); - }, - InventoryItem::Stacked(mut stacked_inventory_item) => { - stacked_inventory_item.item_id = item_id; - self.add_stacked_item(stacked_inventory_item) - } - } - } - - pub fn add_individual_floor_item(&mut self, floor_item: &IndividualFloorItem) -> &InventoryItem { - self.items.push(InventoryItem::Individual(IndividualInventoryItem { - entity_id: floor_item.entity_id, - item_id: floor_item.item_id, - item: floor_item.item.clone(), - })); - - self.items.last().unwrap() - } - - // TODO: should these pick up functions take floor_item as mut and remove the ids? - pub fn pick_up_individual_floor_item(&mut self, floor_item: &IndividualFloorItem) -> Option<(&IndividualInventoryItem, InventorySlot)> { - if self.count() >= 30 { - return None; - } - - self.items.push(InventoryItem::Individual(IndividualInventoryItem { - entity_id: floor_item.entity_id, - item_id: floor_item.item_id, - item: floor_item.item.clone(), - })); - - if let Some(InventoryItem::Individual(new_item)) = self.items.last() { - Some((new_item, InventorySlot(self.count()-1))) - } - else { - None - } - } - - pub fn add_stacked_floor_item(&mut self, floor_item: &StackedFloorItem) { - let existing_item = self.items.iter_mut() - .filter_map(|item| { - match item { - InventoryItem::Stacked(s_item) => Some(s_item), - _ => None, - } - - }) - .find(|item| { - item.tool == floor_item.tool - }); - - match existing_item { - Some(item) => { - item.entity_ids.append(&mut floor_item.entity_ids.clone()) - }, - None => { - self.items.push(InventoryItem::Stacked(StackedInventoryItem { - entity_ids: floor_item.entity_ids.clone(), - item_id: floor_item.item_id, - tool: floor_item.tool, - })); - } - } - } - - // TODO: can be simplified using find instead of position - pub fn pick_up_stacked_floor_item(&mut self, floor_item: &StackedFloorItem) -> Option<(&StackedInventoryItem, InventorySlot)> { - let existing_stack_position = self.items.iter() - .position(|inventory_item| { - if let InventoryItem::Stacked(stacked_inventory_item) = inventory_item { - if stacked_inventory_item.tool == floor_item.tool { - return true - } - } - false - }); - - if let Some(existing_stack_position) = existing_stack_position { - if let Some(InventoryItem::Stacked(stacked_item)) = self.items.get_mut(existing_stack_position) { - if stacked_item.count() + floor_item.count() <= stacked_item.tool.max_stack() { - stacked_item.entity_ids.append(&mut floor_item.entity_ids.clone()); - Some((stacked_item, InventorySlot(existing_stack_position))) - } - else { - None - } - } - else { - None - } - } - else { - let new_stacked_item = InventoryItem::Stacked(StackedInventoryItem { - entity_ids: floor_item.entity_ids.clone(), - item_id: floor_item.item_id, - tool: floor_item.tool, - }); - - self.items.push(new_stacked_item); - if let Some(InventoryItem::Stacked(new_item)) = self.items.last() { - Some((new_item, InventorySlot(self.count()-1))) - } - else { - None - } - } - } - - pub fn withdraw_item(&mut self, mut bank_item: BankItemHandle, amount: usize) -> Option<(&InventoryItem, usize)> { - let (remove, slot) = match bank_item.item_mut()? { - BankItem::Individual(individual_bank_item) => { - if self.items.len() >= INVENTORY_CAPACITY { - return None - } - self.items.push(InventoryItem::Individual(IndividualInventoryItem { - entity_id: individual_bank_item.entity_id, - item_id: individual_bank_item.item_id, - item: individual_bank_item.item.clone(), - })); - (true, self.count()-1) - }, - BankItem::Stacked(stacked_bank_item) => { - let existing_inventory_item = self.items.iter_mut() - .enumerate() - .find_map(|(index, item)| { - if let InventoryItem::Stacked(stacked_inventory_item) = item { - if stacked_bank_item.tool == stacked_inventory_item.tool { - return Some((index, stacked_inventory_item)) - } - } - None - }); - - let slot = match existing_inventory_item { - Some((slot, stacked_inventory_item)) => { - if stacked_inventory_item.count() + stacked_bank_item.count() > stacked_bank_item.tool.max_stack() { - return None - } - - let mut withdrawn_entity_ids = stacked_bank_item.take_entity_ids(amount)?; - stacked_inventory_item.entity_ids.append(&mut withdrawn_entity_ids); - slot - } - None => { - if self.items.len() >= INVENTORY_CAPACITY { - return None - } - let withdrawn_entity_ids = stacked_bank_item.take_entity_ids(amount)?; - - self.item_id_counter += 1; // oh no - self.items.push(InventoryItem::Stacked(StackedInventoryItem { - entity_ids: withdrawn_entity_ids, - item_id: ClientItemId(self.item_id_counter), - tool: stacked_bank_item.tool, - })); - self.count()-1 - } - }; - (stacked_bank_item.count() == 0, slot) - } - }; - - if remove { - bank_item.remove_from_bank(); - } - - self.items.last().map(|item| { - (item, slot) - }) - } - - pub fn iter(&self) -> impl Iterator { - self.items.iter() - } - - pub fn items(&self) -> &Vec { - &self.items - } - - pub fn set_items(&mut self, sorted_items: Vec) { - self.items = sorted_items; - } - - pub fn remove_by_id(&mut self, id: ClientItemId) -> Option { - self.items.iter() - .position(|i| i.item_id() == id) - .map(|position| { - self.items.remove(position) - }) - } - - pub fn equip(&mut self, id: &ClientItemId, equip_slot: u8) { - for item in &self.items { - if let InventoryItem::Individual(inventory_item) = item { - if inventory_item.item_id == *id { - match inventory_item.item { - ItemDetail::Weapon(_) => self.equipped.weapon = Some(inventory_item.entity_id), - ItemDetail::Armor(_) => self.equipped.armor = Some(inventory_item.entity_id), - ItemDetail::Shield(_) => self.equipped.shield = Some(inventory_item.entity_id), - ItemDetail::Unit(_) => { - if let Some(unit) = self.equipped.unit.get_mut(equip_slot as usize) { - *unit = Some(inventory_item.entity_id) - } - } - ItemDetail::Mag(_) => self.equipped.mag = Some(inventory_item.entity_id), - _ => {} - } - } - } - } - } - - pub fn unequip(&mut self, id: &ClientItemId) { - for item in &self.items { - if let InventoryItem::Individual(inventory_item) = item { - if inventory_item.item_id == *id { - match inventory_item.item { - ItemDetail::Weapon(_) => self.equipped.weapon = None, - ItemDetail::Armor(_) => { - self.equipped.armor = None; - self.equipped.unit = [None; 4]; - } - ItemDetail::Shield(_) => self.equipped.shield = None, - ItemDetail::Unit(_) => { - for unit in self.equipped.unit.iter_mut() { - if *unit == Some(inventory_item.entity_id) { - *unit = None - } - } - } - ItemDetail::Mag(_) => self.equipped.mag = Some(inventory_item.entity_id), - _ => {} - } - } - } - } - } - - pub fn as_inventory_entity(&self, _character_id: &CharacterEntityId) -> InventoryEntity { - InventoryEntity { - items: self.items.iter() - .map(|item| { - match item { - InventoryItem::Individual(item) => { - InventoryItemEntity::Individual(ItemEntity { - id: item.entity_id, - item: item.item.clone(), - }) - }, - InventoryItem::Stacked(items) => { - InventoryItemEntity::Stacked(items.entity_ids.iter() - .map(|id| { - ItemEntity { - id: *id, - item: ItemDetail::Tool(items.tool) - } - }) - .collect()) - }, - } - }) - .collect() - } - } - - pub fn as_equipped_entity(&self) -> EquippedEntity { - self.equipped.clone() - } -} - diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index c7b7fbf..e9251c4 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -20,7 +20,6 @@ use crate::ship::packet::handler::trade::{TradeError, OTHER_MESETA_ITEM_ID}; use crate::ship::items::bank::*; use crate::ship::items::floor::*; use crate::ship::items::inventory::*; -use crate::ship::items::use_tool; use crate::ship::items::transaction::{ItemTransaction, ItemAction, TransactionError, TransactionCommitError}; #[derive(PartialEq, Eq)] diff --git a/src/ship/items/mod.rs b/src/ship/items/mod.rs index a3956ba..f2a8da1 100644 --- a/src/ship/items/mod.rs +++ b/src/ship/items/mod.rs @@ -1,9 +1,3 @@ -mod bank; -mod floor; -pub mod inventory; -pub mod manager; -pub mod transaction; -pub mod use_tool; pub mod state; pub mod actions; pub mod apply_item; @@ -12,10 +6,4 @@ use serde::{Serialize, Deserialize}; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, derive_more::Display)] pub struct ClientItemId(pub u32); -// TODO: remove these and fix use statements in the rest of the codebase -pub use inventory::*; -pub use floor::*; -pub use bank::*; -pub use manager::*; - diff --git a/src/ship/items/transaction.rs b/src/ship/items/transaction.rs deleted file mode 100644 index bc0d0a9..0000000 --- a/src/ship/items/transaction.rs +++ /dev/null @@ -1,337 +0,0 @@ -use crate::entity::gateway::EntityGateway; -use thiserror::Error; -use crate::ship::items::manager::{ItemManager, ItemManagerError}; -use crate::entity::gateway::GatewayError; - -#[derive(Error, Debug)] -pub enum TransactionCommitError { - #[error("transaction commit gateway error {0}")] - Gateway(#[from] GatewayError), - #[error("transaction commit itemmanager error {0}")] - ItemManager(#[from] ItemManagerError), -} - -#[async_trait::async_trait] -pub trait ItemAction: std::marker::Send + std::marker::Sync + std::fmt::Debug { - async fn commit(&self, manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError>; -} - -pub struct ItemTransactionActions<'a, EG: EntityGateway> { - action_queue: Vec>>, - pub manager: &'a ItemManager, -} - - -impl<'a, EG: EntityGateway> ItemTransactionActions<'a, EG> { - fn new(manager: &'a ItemManager) -> ItemTransactionActions<'a, EG> { - ItemTransactionActions { - action_queue: Vec::new(), - manager - } - } - - pub fn action(&mut self, action: Box>) { - self.action_queue.push(action) - } -} - - -pub struct ItemTransaction<'a, T, EG: EntityGateway> { - data: T, - actions: ItemTransactionActions<'a, EG>, -} - -impl<'a, T, EG: EntityGateway> ItemTransaction<'a, T, EG> { - pub fn new(manager: &'a ItemManager, arg: T) -> ItemTransaction<'a, T, EG> { - ItemTransaction { - data: arg, - actions: ItemTransactionActions::new(manager), - } - } - - pub fn act(mut self, action: fn(&mut ItemTransactionActions, &T) -> Result) -> FinalizedItemTransaction { - match action(&mut self.actions, &self.data) { - Ok(k) => { - FinalizedItemTransaction { - value: Ok(k), - action_queue: self.actions.action_queue, - } - }, - Err(err) => { - FinalizedItemTransaction { - value: Err(err), - action_queue: Vec::new(), - } - } - } - } -} - - -#[derive(Error, Debug)] -pub enum TransactionError { - #[error("transaction action error {0:?}")] - Action(E), - #[error("transaction commit error {0}")] - Commit(#[from] TransactionCommitError), - -} - -// this only exists to drop the ItemManager borrow of ItemTransaction so a mutable ItemTransaction can be passed in later -pub struct FinalizedItemTransaction { - value: Result, - action_queue: Vec>>, -} - -impl FinalizedItemTransaction { - pub async fn commit(self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result> { - match self.value { - Ok(value) => { - for action in self.action_queue.into_iter() { - // TODO: better handle rolling back if this ever errors out - action.commit(item_manager, entity_gateway).await.map_err(|err| TransactionError::Commit(err))?; - } - Ok(value) - }, - Err(err) => Err(TransactionError::Action(err)), - } - } -} - - -#[cfg(test)] -mod test { - use super::*; - use crate::entity::account::{UserAccountId, NewUserAccountEntity, UserAccountEntity}; - use crate::entity::character::{NewCharacterEntity, CharacterEntity}; - use crate::entity::gateway::GatewayError; - use thiserror::Error; - - #[async_std::test] - async fn test_item_transaction() { - #[derive(Debug)] - struct DummyAction1 { - name: String, - } - #[derive(Debug)] - struct DummyAction2 { - value: u32, - } - - #[derive(Error, Debug)] - #[error("")] - enum DummyError { - Error - } - - #[derive(Default, Clone)] - struct DummyGateway { - d1_set: String, - d2_inc: u32, - } - - #[async_trait::async_trait] - impl EntityGateway for DummyGateway { - async fn create_user(&mut self, user: NewUserAccountEntity) -> Result { - self.d1_set = user.username; - Ok(UserAccountEntity::default()) - } - - async fn create_character(&mut self, char: NewCharacterEntity) -> Result { - self.d2_inc += char.slot; - Ok(CharacterEntity::default()) - } - } - - - #[async_trait::async_trait] - impl ItemAction for DummyAction1 { - async fn commit(&self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - item_manager.id_counter = 55555; - entity_gateway.create_user(NewUserAccountEntity { - username: self.name.clone(), - ..NewUserAccountEntity::default() - }) - .await?; - Ok(()) - } - } - - #[async_trait::async_trait] - impl ItemAction for DummyAction2 { - async fn commit(&self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - item_manager.id_counter += self.value; - entity_gateway.create_character(NewCharacterEntity { - slot: self.value, - ..NewCharacterEntity::new(UserAccountId(0), 1) // TODO: handle different keyboard_config_presets - }) - .await?; - Ok(()) - } - } - - let mut item_manager = ItemManager::default(); - let mut entity_gateway = DummyGateway::default(); - - let result = ItemTransaction::new(&item_manager, 12) - .act(|it, k| { - it.action(Box::new(DummyAction1 {name: "asdf".into()})); - it.action(Box::new(DummyAction2 {value: 11})); - it.action(Box::new(DummyAction2 {value: *k})); - if *k == 99 { - return Err(DummyError::Error) - } - Ok(String::from("hello")) - }) - .commit(&mut item_manager, &mut entity_gateway) - .await; - - assert!(entity_gateway.d1_set == "asdf"); - assert!(entity_gateway.d2_inc == 23); - assert!(item_manager.id_counter == 55578); - assert!(result.unwrap() == "hello"); - } - - #[async_std::test] - async fn test_item_transaction_with_action_error() { - #[derive(Debug)] - struct DummyAction1 { - } - #[derive(Debug)] - struct DummyAction2 { - } - - #[derive(Error, Debug, PartialEq, Eq)] - #[error("")] - enum DummyError { - Error - } - - #[derive(Default, Clone)] - struct DummyGateway { - _d1_set: String, - d2_inc: u32, - } - - #[async_trait::async_trait] - impl EntityGateway for DummyGateway { - async fn create_character(&mut self, char: NewCharacterEntity) -> Result { - self.d2_inc += char.slot; - Ok(CharacterEntity::default()) - } - } - - - #[async_trait::async_trait] - impl ItemAction for DummyAction1 { - async fn commit(&self, _item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - entity_gateway.create_character(NewCharacterEntity { - slot: 1, - ..NewCharacterEntity::new(UserAccountId(0), 1) // TODO: handle different keyboard_config_presets - }) - .await?; - Ok(()) - } - } - - #[async_trait::async_trait] - impl ItemAction for DummyAction2 { - async fn commit(&self, _item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - entity_gateway.create_character(NewCharacterEntity { - slot: 1, - ..NewCharacterEntity::new(UserAccountId(0), 1) // TODO: handle different keyboard_config_presets - }) - .await?; - Ok(()) - } - } - - let mut item_manager = ItemManager::default(); - let mut entity_gateway = DummyGateway::default(); - - let result = ItemTransaction::new(&item_manager, 12) - .act(|it, _| -> Result<(), _> { - it.action(Box::new(DummyAction1 {})); - it.action(Box::new(DummyAction2 {})); - it.action(Box::new(DummyAction2 {})); - Err(DummyError::Error) - }) - .commit(&mut item_manager, &mut entity_gateway) - .await; - - assert!(entity_gateway.d2_inc == 0); - assert!(matches!(result, Err(TransactionError::Action(DummyError::Error)))); - } - - #[async_std::test] - async fn test_item_transaction_with_commit_error() { - #[derive(Debug)] - struct DummyAction1 { - } - #[derive(Debug)] - struct DummyAction2 { - } - - #[derive(Error, Debug, PartialEq, Eq)] - #[error("")] - enum DummyError { - } - - #[derive(Default, Clone)] - struct DummyGateway { - _d1_set: String, - d2_inc: u32, - } - - #[async_trait::async_trait] - impl EntityGateway for DummyGateway { - async fn create_character(&mut self, char: NewCharacterEntity) -> Result { - self.d2_inc += char.slot; - Ok(CharacterEntity::default()) - } - } - - - #[async_trait::async_trait] - impl ItemAction for DummyAction1 { - async fn commit(&self, _item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - entity_gateway.create_character(NewCharacterEntity { - slot: 1, - ..NewCharacterEntity::new(UserAccountId(0), 1) // TODO: handle different keyboard_config_presets - }) - .await?; - Err(GatewayError::Error.into()) - } - } - - #[async_trait::async_trait] - impl ItemAction for DummyAction2 { - async fn commit(&self, _item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - entity_gateway.create_character(NewCharacterEntity { - slot: 1, - ..NewCharacterEntity::new(UserAccountId(0), 1) // TODO: handle different keyboard_config_presets - }) - .await?; - Ok(()) - } - } - - let mut item_manager = ItemManager::default(); - let mut entity_gateway = DummyGateway::default(); - - let result = ItemTransaction::new(&item_manager, 12) - .act(|it, _| -> Result<_, DummyError> { - it.action(Box::new(DummyAction1 {})); - it.action(Box::new(DummyAction2 {})); - it.action(Box::new(DummyAction2 {})); - Ok(()) - }) - .commit(&mut item_manager, &mut entity_gateway) - .await; - - // in an ideal world this would be 0 as rollbacks would occur - assert!(entity_gateway.d2_inc == 1); - assert!(matches!(result, Err(TransactionError::Commit(TransactionCommitError::Gateway(GatewayError::Error))))); - } -} - diff --git a/src/ship/items/use_tool.rs b/src/ship/items/use_tool.rs deleted file mode 100644 index 6440b84..0000000 --- a/src/ship/items/use_tool.rs +++ /dev/null @@ -1,163 +0,0 @@ -use thiserror::Error; -use crate::entity::gateway::EntityGateway; -use crate::entity::character::CharacterEntity; -use crate::entity::item::mag::MagCell; -use crate::ship::items::{CharacterInventory, ConsumedItem}; - -#[derive(Error, Debug)] -#[error("")] -pub enum UseItemError { - NoCharacter, - ItemNotEquipped, - InvalidItem, -} - -pub async fn power_material(entity_gateway: &mut EG, character: &mut CharacterEntity) { - character.materials.power += 1; - entity_gateway.save_character(character).await.unwrap(); -} - -pub async fn mind_material(entity_gateway: &mut EG, character: &mut CharacterEntity) { - character.materials.mind += 1; - entity_gateway.save_character(character).await.unwrap(); -} - -pub async fn evade_material(entity_gateway: &mut EG, character: &mut CharacterEntity) { - character.materials.evade += 1; - entity_gateway.save_character(character).await.unwrap(); -} - -pub async fn def_material(entity_gateway: &mut EG, character: &mut CharacterEntity) { - character.materials.def += 1; - entity_gateway.save_character(character).await.unwrap(); -} - -pub async fn luck_material(entity_gateway: &mut EG, character: &mut CharacterEntity) { - character.materials.luck += 1; - entity_gateway.save_character(character).await.unwrap(); -} - -pub async fn hp_material(entity_gateway: &mut EG, character: &mut CharacterEntity) { - character.materials.hp += 1; - entity_gateway.save_character(character).await.unwrap(); -} - -pub async fn tp_material(entity_gateway: &mut EG, character: &mut CharacterEntity) { - character.materials.tp += 1; - entity_gateway.save_character(character).await.unwrap(); -} - -async fn mag_cell(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory, mag_cell_type: MagCell) -> Result<(), UseItemError> { - let mut mag_handle = inventory.get_equipped_mag_handle().ok_or(UseItemError::ItemNotEquipped)?; - let mag_item = mag_handle.item_mut() - .ok_or(UseItemError::InvalidItem)?; - let actual_mag = mag_item - .individual_mut() - .ok_or(UseItemError::InvalidItem)? - .mag_mut() - .ok_or(UseItemError::InvalidItem)?; - actual_mag.apply_mag_cell(mag_cell_type); - for mag_entity_id in mag_item.entity_ids() { - for cell_entity_id in used_cell.entity_ids() { - entity_gateway.use_mag_cell(&mag_entity_id, &cell_entity_id).await.unwrap(); - } - } - - Ok(()) -} - -pub async fn cell_of_mag_502(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::CellOfMag502).await -} - -pub async fn cell_of_mag_213(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::CellOfMag213).await -} - -pub async fn parts_of_robochao(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::PartsOfRobochao).await -} - -pub async fn heart_of_opaopa(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfOpaOpa).await -} - -pub async fn heart_of_pian(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfPian).await -} - -pub async fn heart_of_chao(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfChao).await -} - -pub async fn heart_of_angel(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfAngel).await -} - -pub async fn kit_of_hamburger(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfHamburger).await -} - -pub async fn panthers_spirit(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::PanthersSpirit).await -} - -pub async fn kit_of_mark3(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfMark3).await -} - -pub async fn kit_of_master_system(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfMasterSystem).await -} - -pub async fn kit_of_genesis(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfGenesis).await -} - -pub async fn kit_of_sega_saturn(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfSegaSaturn).await -} - -pub async fn kit_of_dreamcast(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfDreamcast).await -} - -pub async fn tablet(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::Tablet).await -} - -pub async fn dragon_scale(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::DragonScale).await -} - -pub async fn heaven_striker_coat(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::HeavenStrikerCoat).await -} - -pub async fn pioneer_parts(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::PioneerParts).await -} - -pub async fn amities_memo(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::AmitiesMemo).await -} - -pub async fn heart_of_morolian(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfMorolian).await -} - -pub async fn rappys_beak(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::RappysBeak).await -} - -pub async fn yahoos_engine(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::YahoosEngine).await -} - -pub async fn d_photon_core(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::DPhotonCore).await -} - -pub async fn liberta_kit(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { - mag_cell(entity_gateway, used_cell, inventory, MagCell::LibertaKit).await -} diff --git a/src/ship/packet/builder/lobby.rs b/src/ship/packet/builder/lobby.rs index aefe96f..13c9dd5 100644 --- a/src/ship/packet/builder/lobby.rs +++ b/src/ship/packet/builder/lobby.rs @@ -5,7 +5,6 @@ use crate::ship::ship::{ShipError, Clients}; use crate::ship::location::{ClientLocation, LobbyId, ClientLocationError}; use crate::ship::packet::builder::{player_info}; use crate::ship::items::state::ItemState; -use crate::ship::items::ItemManager; pub fn join_lobby(id: ClientId, diff --git a/src/ship/packet/builder/message.rs b/src/ship/packet/builder/message.rs index 827aec9..fb135f7 100644 --- a/src/ship/packet/builder/message.rs +++ b/src/ship/packet/builder/message.rs @@ -3,16 +3,14 @@ use libpso::packet::ship::*; use crate::entity::item; use crate::common::leveltable::CharacterStats; use crate::ship::ship::{ShipError}; -use crate::ship::items::{ClientItemId, InventoryItem, StackedFloorItem, FloorItem, CharacterBank}; -use crate::ship::items::state::FloorItem as FloorItem2; -use crate::ship::items::state::InventoryItem as InventoryItem2; -use crate::ship::items::state::{BankState, IndividualItemDetail}; +use crate::ship::items::ClientItemId; +use crate::ship::items::state::{InventoryItem, FloorItem, BankState, IndividualItemDetail}; use crate::ship::location::AreaClient; use std::convert::TryInto; use crate::ship::shops::ShopItem; -pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem2) -> Result { +pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> Result { let item_bytes = item_drop.as_client_bytes(); Ok(ItemDrop { client, @@ -68,7 +66,7 @@ pub fn create_meseta(area_client: AreaClient, amount: usize) -> CreateItem { } } -pub fn create_withdrawn_inventory_item(area_client: AreaClient, item: &InventoryItem2) -> Result { +pub fn create_withdrawn_inventory_item(area_client: AreaClient, item: &InventoryItem) -> Result { let bytes = item.item.as_client_bytes(); Ok(CreateItem { client: area_client.local_client.id(), @@ -80,7 +78,7 @@ pub fn create_withdrawn_inventory_item(area_client: AreaClient, item: &Inventory }) } -pub fn create_withdrawn_inventory_item2(area_client: AreaClient, item: &InventoryItem2) -> Result { +pub fn create_withdrawn_inventory_item2(area_client: AreaClient, item: &InventoryItem) -> Result { let bytes = item.item.as_client_bytes(); Ok(CreateItem { client: area_client.local_client.id(), @@ -92,7 +90,7 @@ pub fn create_withdrawn_inventory_item2(area_client: AreaClient, item: &Inventor }) } -pub fn remove_item_from_floor(area_client: AreaClient, item: &FloorItem2) -> Result { +pub fn remove_item_from_floor(area_client: AreaClient, item: &FloorItem) -> Result { Ok(RemoveItemFromFloor { client: area_client.local_client.id(), target: 0, @@ -104,7 +102,7 @@ pub fn remove_item_from_floor(area_client: AreaClient, item: &FloorItem2) -> Res }) } -pub fn drop_split_stack(area_client: AreaClient, item: &FloorItem2) -> Result { +pub fn drop_split_stack(area_client: AreaClient, item: &FloorItem) -> Result { let item_bytes = item.as_client_bytes(); Ok(DropSplitStack { client: area_client.local_client.id(), @@ -121,7 +119,7 @@ pub fn drop_split_stack(area_client: AreaClient, item: &FloorItem2) -> Result Result { +pub fn drop_split_meseta_stack(area_client: AreaClient, item: &FloorItem) -> Result { let item_bytes = item.as_client_bytes(); Ok(DropSplitStack { client: area_client.local_client.id(), diff --git a/src/ship/packet/builder/room.rs b/src/ship/packet/builder/room.rs index a97d8b8..29dc0f2 100644 --- a/src/ship/packet/builder/room.rs +++ b/src/ship/packet/builder/room.rs @@ -5,7 +5,6 @@ use crate::ship::ship::{ShipError, ClientState, Clients}; use crate::ship::location::{ClientLocation, RoomId, AreaClient, ClientLocationError}; use crate::ship::room::RoomState; use crate::ship::items::state::ItemState; -use crate::ship::items::ItemManager; use crate::ship::packet::builder::{player_header, player_info}; use std::convert::TryInto; diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index e5df411..79ed06d 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -8,13 +8,13 @@ use crate::common::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, Clients, Rooms, ItemShops}; use crate::ship::location::{ClientLocation, ClientLocationError}; use crate::ship::drops::ItemDrop; -use crate::ship::items::{ItemManager, ItemManagerError, ClientItemId, FloorItem}; +use crate::ship::items::ClientItemId; use crate::entity::gateway::EntityGateway; use crate::entity::item; use libpso::utf8_to_utf16_array; use crate::ship::packet::builder; use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem}; -use crate::ship::items::state::{ItemState, FloorType, FloorItemDetail}; +use crate::ship::items::state::{ItemState, ItemStateError, FloorType, FloorItemDetail}; use crate::ship::items::actions::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, take_meseta, apply_modifier, TriggerCreateItem}; const BANK_ACTION_DEPOSIT: u8 = 0; @@ -431,11 +431,11 @@ where let inventory = item_state.get_character_inventory(&client.character)?; let item = inventory.get_by_client_id(&ClientItemId(tek_request.item_id)) - .ok_or(ItemManagerError::WrongItemType(ClientItemId(tek_request.item_id)))?; + .ok_or(ItemStateError::WrongItemType(ClientItemId(tek_request.item_id)))?; let mut weapon = item.item.as_individual() - .ok_or(ItemManagerError::WrongItemType(ClientItemId(tek_request.item_id)))? + .ok_or(ItemStateError::WrongItemType(ClientItemId(tek_request.item_id)))? .as_weapon() - .ok_or(ItemManagerError::WrongItemType(ClientItemId(tek_request.item_id)))? + .ok_or(ItemStateError::WrongItemType(ClientItemId(tek_request.item_id)))? .clone(); weapon.apply_modifier(&item::weapon::WeaponModifier::Tekked { diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 55048d3..e886b1b 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -61,7 +61,6 @@ pub enum ShipError { ItemError, // TODO: refine this PickUpInvalidItemId(u32), DropInvalidItemId(u32), - ItemManagerError(#[from] items::ItemManagerError), ItemStateError(#[from] items::state::ItemStateError), #[error("")] ItemDropLocationNotSet, @@ -406,7 +405,6 @@ impl ShipServerStateBuilder { clients: HashMap::new(), level_table: CharacterLevelTable::default(), name: self.name.unwrap_or_else(|| "NAMENOTSET".into()), - item_manager: items::ItemManager::default(), item_state: items::state::ItemState::default(), ip: self.ip.unwrap_or_else(|| Ipv4Addr::new(127,0,0,1)), port: self.port.unwrap_or(SHIP_PORT), @@ -451,7 +449,6 @@ pub struct ShipServerState { pub clients: Clients, level_table: CharacterLevelTable, name: String, - item_manager: items::ItemManager, item_state: items::state::ItemState, shops: Box, pub blocks: Blocks, diff --git a/tests/test_shops.rs b/tests/test_shops.rs index fa6da02..c127c09 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -3,7 +3,6 @@ use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; use elseware::ship::room::Difficulty; -use elseware::ship::items::manager::ItemManagerError; use elseware::ship::items::state::ItemStateError; use libpso::packet::ship::*; diff --git a/tests/test_trade.rs b/tests/test_trade.rs index 1da0049..8e35222 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -4,7 +4,6 @@ use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket, ShipError}; use elseware::entity::item::{Meseta, ItemEntity}; -use elseware::ship::items::transaction::TransactionError; use elseware::ship::packet::handler::trade::TradeError; use elseware::ship::items::state::{ItemStateError, InventoryError};