diff --git a/src/bin/main.rs b/src/bin/main.rs index 05da369..7d5c4f5 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -120,7 +120,7 @@ fn main() { Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), None,], tekked: false, - wrapping: Some(item::weapon::WrappingPaper::Black_Yellow), + wrapping: Some(item::WrappingPaper::Black_Yellow), } ), location: ItemLocation::Inventory { diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index b3a6136..fe055db 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -286,7 +286,7 @@ pub struct PgWeapon { grind: u8, attrs: HashMap, tekked: bool, - wrapping: Option, + wrapping: Option, } impl From for PgWeapon { diff --git a/src/entity/item/armor.rs b/src/entity/item/armor.rs index 62f2c64..83c900b 100644 --- a/src/entity/item/armor.rs +++ b/src/entity/item/armor.rs @@ -1,5 +1,5 @@ use serde::{Serialize, Deserialize}; -use crate::entity::item::ItemEntityId; +use crate::entity::item::{ItemEntityId, WrappingPaper}; #[derive(Debug, Copy, Clone)] pub enum ItemParseError { diff --git a/src/entity/item/esweapon.rs b/src/entity/item/esweapon.rs index ace5ec1..73e54e1 100644 --- a/src/entity/item/esweapon.rs +++ b/src/entity/item/esweapon.rs @@ -1,4 +1,5 @@ use serde::{Serialize, Deserialize}; +use crate::entity::item::{WrappingPaper}; // TODO: actually use this #[derive(Debug)] pub enum ItemParseError { diff --git a/src/entity/item/mag.rs b/src/entity/item/mag.rs index 0cb0384..3501aac 100644 --- a/src/entity/item/mag.rs +++ b/src/entity/item/mag.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use serde::{Serialize, Deserialize}; use crate::entity::item::tool::ToolType; use crate::entity::character::{CharacterClass, SectionID}; -use crate::entity::item::ItemEntityId; +use crate::entity::item::{ItemEntityId, WrappingPaper}; use std::io::Read; use std::cmp::Ordering::{Less, Greater, Equal}; diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 22e2913..8aa3155 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -159,6 +159,35 @@ impl ItemDetail { _ => None, } } + + pub fn is_wrapped(self) -> bool { + match self { + ItemDetail::Weapon(w) => w.wrapping.is_some(), + // ItemDetail::Armor(a) => a.wrapping.is_some(), + // ItemDetail::Shield(s) => s.wrapping.is_some(), + // ItemDetail::Unit(u) => u.wrapping.is_some(), + // ItemDetail::Tool(t) => t.wrapping.is_some(), + // ItemDetail::TechniqueDisk(d) => d.wrapping.is_some(), + // ItemDetail::Mag(m) => m.wrapping.is_some(), + // ItemDetail::ESWeapon(e) => e.wrapping.is_some(), + _ => false + } + } + + pub fn unwrap_present(self) -> ItemDetail { + match self { + ItemDetail::Weapon(mut w) => w.wrapping = None, + // ItemDetail::Armor(a) => a.wrapping.is_some(), + // ItemDetail::Shield(s) => s.wrapping.is_some(), + // ItemDetail::Unit(u) => u.wrapping.is_some(), + // ItemDetail::Tool(t) => t.wrapping.is_some(), + // ItemDetail::TechniqueDisk(d) => d.wrapping.is_some(), + // ItemDetail::Mag(m) => m.wrapping.is_some(), + // ItemDetail::ESWeapon(e) => e.wrapping.is_some(), + _ => {}, + }; + self + } } #[derive(Clone, Debug)] @@ -301,3 +330,41 @@ impl BankEntity { } } } + +#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +pub enum WrappingPaper { + White_Pink, // 0 + Yellow_Blue, // 1 + Black_Yellow, // 2 + LightBlue_Orange, // 3 + Pink_YellowGreen, // 4 + Red_Green, // 5 + Magenta, // 6 + Blue, // 7 + Yellow, // 8 + Vermillion, // 9 + Green, // 10 +} + +impl WrappingPaper { + pub fn value(&self) -> u8 { + *self as u8 + } + + pub fn from(data: u8) -> Option { + match data { + 0 => Some(WrappingPaper::White_Pink), + 1 => Some(WrappingPaper::Yellow_Blue), + 2 => Some(WrappingPaper::Black_Yellow), + 3 => Some(WrappingPaper::LightBlue_Orange), + 4 => Some(WrappingPaper::Pink_YellowGreen), + 5 => Some(WrappingPaper::Red_Green), + 6 => Some(WrappingPaper::Magenta), + 7 => Some(WrappingPaper::Blue), + 8 => Some(WrappingPaper::Yellow), + 9 => Some(WrappingPaper::Vermillion), + 10 => Some(WrappingPaper::Green), + _ => None, + } + } +} diff --git a/src/entity/item/shield.rs b/src/entity/item/shield.rs index 852e3a0..7f4a1e6 100644 --- a/src/entity/item/shield.rs +++ b/src/entity/item/shield.rs @@ -1,4 +1,5 @@ use serde::{Serialize, Deserialize}; +use crate::entity::item::{WrappingPaper}; #[derive(Debug, Copy, Clone)] pub enum ItemParseError { diff --git a/src/entity/item/tech.rs b/src/entity/item/tech.rs index 49882fc..4cd3290 100644 --- a/src/entity/item/tech.rs +++ b/src/entity/item/tech.rs @@ -1,4 +1,5 @@ use serde::{Serialize, Deserialize}; +use crate::entity::item::{WrappingPaper}; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, enum_utils::FromStr, derive_more::Display, strum_macros::EnumIter)] diff --git a/src/entity/item/tool.rs b/src/entity/item/tool.rs index 707b61b..688aa7d 100644 --- a/src/entity/item/tool.rs +++ b/src/entity/item/tool.rs @@ -1,4 +1,5 @@ use serde::{Serialize, Deserialize}; +use crate::entity::item::{WrappingPaper}; #[derive(Debug, Copy, Clone)] pub enum ItemParseError { diff --git a/src/entity/item/unit.rs b/src/entity/item/unit.rs index 1f9dd4c..a39b9ad 100644 --- a/src/entity/item/unit.rs +++ b/src/entity/item/unit.rs @@ -1,4 +1,5 @@ use serde::{Serialize, Deserialize}; +use crate::entity::item::{WrappingPaper}; #[derive(Debug, Copy, Clone)] pub enum ItemParseError { diff --git a/src/entity/item/weapon.rs b/src/entity/item/weapon.rs index 8009abc..1d7071e 100644 --- a/src/entity/item/weapon.rs +++ b/src/entity/item/weapon.rs @@ -1,4 +1,4 @@ -use crate::entity::item::ItemEntityId; +use crate::entity::item::{ItemEntityId, WrappingPaper}; use serde::{Serialize, Deserialize}; #[derive(Debug, Copy, Clone)] @@ -1454,45 +1454,45 @@ pub enum WeaponModifier { }, } +// #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +// pub enum WrappingPaper { +// White_Pink, // 0 +// Yellow_Blue, +// Black_Yellow, +// LightBlue_Orange, +// Pink_YellowGreen, +// Red_Green, +// Magenta, +// Blue, +// Yellow, +// Vermillion, +// Green, +// } + +// impl WrappingPaper { +// pub fn value(&self) -> u8 { +// *self as u8 +// } + +// pub fn from(data: u8) -> Option { +// match data { +// 0 => Some(WrappingPaper::White_Pink), +// 1 => Some(WrappingPaper::Yellow_Blue), +// 2 => Some(WrappingPaper::Black_Yellow), +// 3 => Some(WrappingPaper::LightBlue_Orange), +// 4 => Some(WrappingPaper::Pink_YellowGreen), +// 5 => Some(WrappingPaper::Red_Green), +// 6 => Some(WrappingPaper::Magenta), +// 7 => Some(WrappingPaper::Blue), +// 8 => Some(WrappingPaper::Yellow), +// 9 => Some(WrappingPaper::Vermillion), +// 10 => Some(WrappingPaper::Green), +// _ => None, +// } +// } +// } + #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] -pub enum WrappingPaper { - White_Pink, // 0 - Yellow_Blue, - Black_Yellow, - LightBlue_Orange, - Pink_YellowGreen, - Red_Green, - Magenta, - Blue, - Yellow, - Vermillion, - Green, -} - -impl WrappingPaper { - pub fn value(&self) -> u8 { - *self as u8 - } - - pub fn from(data: u8) -> Option { - match data { - 0 => Some(WrappingPaper::White_Pink), - 1 => Some(WrappingPaper::Yellow_Blue), - 2 => Some(WrappingPaper::Black_Yellow), - 3 => Some(WrappingPaper::LightBlue_Orange), - 4 => Some(WrappingPaper::Pink_YellowGreen), - 5 => Some(WrappingPaper::Red_Green), - 6 => Some(WrappingPaper::Magenta), - 7 => Some(WrappingPaper::Blue), - 8 => Some(WrappingPaper::Yellow), - 9 => Some(WrappingPaper::Vermillion), - 10 => Some(WrappingPaper::Green), - _ => None, - } - } -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Weapon { pub weapon: WeaponType, pub special: Option, @@ -1560,6 +1560,14 @@ impl Weapon { } } + pub fn wrap_present(&mut self, value: u8) { + self.wrapping = WrappingPaper::from(value); + } + + pub fn unwrap_present(&mut self) { + self.wrapping = None; + } + pub fn as_bytes(&self) -> [u8; 16] { let mut result = [0u8; 16]; result[0..3].copy_from_slice(&self.weapon.value()); diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index 35cef9f..f70335b 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -44,6 +44,17 @@ impl IndividualInventoryItem { _ => None } } + + pub fn is_wrapped(self) -> bool { + self.clone().item.is_wrapped() + } + + pub fn weapon_mut(&mut self) -> Option<&mut Weapon> { + match self.item { + ItemDetail::Weapon(ref mut weapon) => Some(weapon), + _ => None + } + } } #[derive(Debug, Clone)] @@ -66,6 +77,11 @@ impl StackedInventoryItem { None } } + + pub fn is_wrapped(&self) -> bool { + // TODO: add wrapping to Tool + false + } } #[derive(Debug, Clone)] @@ -219,6 +235,48 @@ impl InventoryItem { _ => None } } + + pub fn item_detail(&self) -> ItemDetail { + match self { + InventoryItem::Individual(individual_inventory_item) => individual_inventory_item.item.clone(), + InventoryItem::Stacked(stacked_inventory_item) => ItemDetail::Tool(stacked_inventory_item.tool), + } + } + + pub fn as_consumed_item(&self) -> ConsumedItem { + match self { + InventoryItem::Individual(individual_inventory_item) => {ConsumedItem::Individual(IndividualConsumedItem { + entity_id: individual_inventory_item.entity_id, + item: individual_inventory_item.item.clone(), + })}, + InventoryItem::Stacked(stacked_inventory_item) => {ConsumedItem::Stacked(StackedConsumedItem { + entity_ids: stacked_inventory_item.entity_ids.clone(), + tool: stacked_inventory_item.tool, + })}, + } + } + + pub fn is_wrapped(self) -> bool { + match self { + InventoryItem::Individual(i) => i.is_wrapped(), + InventoryItem::Stacked(s) => s.is_wrapped(), + } + } + + pub fn unwrap_present(self) -> InventoryItem { + match self { + InventoryItem::Individual(i) => InventoryItem::Individual(IndividualInventoryItem { + entity_id: i.entity_id, + item_id: i.item_id, + item: i.item.unwrap_present(), + }), + InventoryItem::Stacked(s) => InventoryItem::Stacked(StackedInventoryItem { + entity_ids: s.entity_ids, + item_id: s.item_id, + tool: s.tool, // s.unwrap_present() + }), + } + } } diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index ff554ea..cbd10f9 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -4,7 +4,7 @@ use thiserror::Error; use crate::entity::gateway::EntityGateway; use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel}; use crate::entity::item::{ItemDetail, ItemLocation, BankName}; -use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, EquippedEntity, InventoryEntity, BankItemEntity, BankEntity}; +use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, EquippedEntity, InventoryEntity, BankItemEntity, BankEntity, ItemType}; use crate::entity::item::tool::{Tool, ToolType}; use crate::entity::item::unit; use crate::entity::item::weapon; @@ -636,114 +636,141 @@ impl ItemManager { } pub async fn use_item(&mut self, - used_item: ConsumedItem, entity_gateway: &mut EG, - character: &mut CharacterEntity) -> Result<(), anyhow::Error> { + character: &mut CharacterEntity, + client_item_id: ClientItemId) -> Result<(), anyhow::Error> { + // println!("manager::use_item(): ClientItemId: {:?}", client_item_id); let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - match &used_item.item() { - ItemDetail::Weapon(_w) => { - // something like when items are used to combine/transform them? - //_ => {} + + let mut used_item_handle = inventory.get_item_handle_by_id(client_item_id).ok_or(ItemManagerError::ItemIdNotInInventory(client_item_id))?; + let used_item = used_item_handle.item_mut().ok_or(ItemManagerError::CannotGetMutItem)?; + match used_item.item_type() { + ItemType::Armor(_) => { + }, - ItemDetail::Tool(t) => { - match t.tool { - ToolType::PowerMaterial => { - use_tool::power_material(entity_gateway, character).await; - }, - ToolType::MindMaterial => { - use_tool::mind_material(entity_gateway, character).await; - }, - ToolType::EvadeMaterial => { - use_tool::evade_material(entity_gateway, character).await; - }, - ToolType::DefMaterial => { - use_tool::def_material(entity_gateway, character).await; - }, - ToolType::LuckMaterial => { - use_tool::luck_material(entity_gateway, character).await; - }, - ToolType::HpMaterial => { - use_tool::hp_material(entity_gateway, character).await; - }, - ToolType::TpMaterial => { - use_tool::tp_material(entity_gateway, character).await; - }, - ToolType::CellOfMag502 => { - use_tool::cell_of_mag_502(entity_gateway, &used_item, inventory).await?; - }, - ToolType::CellOfMag213 => { - use_tool::cell_of_mag_213(entity_gateway, &used_item, inventory).await?; - }, - ToolType::PartsOfRobochao => { - use_tool::parts_of_robochao(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfOpaOpa => { - use_tool::heart_of_opaopa(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfPian => { - use_tool::heart_of_pian(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfChao=> { - use_tool::heart_of_chao(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfAngel => { - use_tool::heart_of_angel(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfHamburger => { - use_tool::kit_of_hamburger(entity_gateway, &used_item, inventory).await?; - }, - ToolType::PanthersSpirit => { - use_tool::panthers_spirit(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfMark3 => { - use_tool::kit_of_mark3(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfMasterSystem=> { - use_tool::kit_of_master_system(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfGenesis => { - use_tool::kit_of_genesis(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfSegaSaturn => { - use_tool::kit_of_sega_saturn(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfDreamcast => { - use_tool::kit_of_dreamcast(entity_gateway, &used_item, inventory).await?; - }, - ToolType::Tablet => { - use_tool::tablet(entity_gateway, &used_item, inventory).await?; - }, - ToolType::DragonScale => { - use_tool::dragon_scale(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeavenStrikerCoat => { - use_tool::heaven_striker_coat(entity_gateway, &used_item, inventory).await?; - }, - ToolType::PioneerParts => { - use_tool::pioneer_parts(entity_gateway, &used_item, inventory).await?; - }, - ToolType::AmitiesMemo => { - use_tool::amities_memo(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfMorolian => { - use_tool::heart_of_morolian(entity_gateway, &used_item, inventory).await?; - }, - ToolType::RappysBeak => { - use_tool::rappys_beak(entity_gateway, &used_item, inventory).await?; - }, - ToolType::YahoosEngine => { - use_tool::yahoos_engine(entity_gateway, &used_item, inventory).await?; - }, - ToolType::DPhotonCore => { - use_tool::d_photon_core(entity_gateway, &used_item, inventory).await?; - }, - ToolType::LibertaKit => { - use_tool::liberta_kit(entity_gateway, &used_item, inventory).await?; - }, + ItemType::ESWeapon(_) => { + + }, + ItemType::Mag(_) => { + + }, + ItemType::Shield(_) => { + + }, + ItemType::TechniqueDisk(_) => { + + }, + ItemType::Tool(_) => { + let consumed_item = used_item.as_consumed_item(); + match &used_item.item_detail() { + ItemDetail::Tool(t) => { + match t.tool { + ToolType::PowerMaterial => { + use_tool::power_material(entity_gateway, character).await; + }, + ToolType::MindMaterial => { + use_tool::mind_material(entity_gateway, character).await; + }, + ToolType::EvadeMaterial => { + use_tool::evade_material(entity_gateway, character).await; + }, + ToolType::DefMaterial => { + use_tool::def_material(entity_gateway, character).await; + }, + ToolType::LuckMaterial => { + use_tool::luck_material(entity_gateway, character).await; + }, + ToolType::HpMaterial => { + use_tool::hp_material(entity_gateway, character).await; + }, + ToolType::TpMaterial => { + use_tool::tp_material(entity_gateway, character).await; + }, + ToolType::CellOfMag502 => { + use_tool::cell_of_mag_502(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::CellOfMag213 => { + use_tool::cell_of_mag_213(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::PartsOfRobochao => { + use_tool::parts_of_robochao(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::HeartOfOpaOpa => { + use_tool::heart_of_opaopa(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::HeartOfPian => { + use_tool::heart_of_pian(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::HeartOfChao=> { + use_tool::heart_of_chao(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::HeartOfAngel => { + use_tool::heart_of_angel(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::KitOfHamburger => { + use_tool::kit_of_hamburger(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::PanthersSpirit => { + use_tool::panthers_spirit(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::KitOfMark3 => { + use_tool::kit_of_mark3(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::KitOfMasterSystem=> { + use_tool::kit_of_master_system(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::KitOfGenesis => { + use_tool::kit_of_genesis(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::KitOfSegaSaturn => { + use_tool::kit_of_sega_saturn(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::KitOfDreamcast => { + use_tool::kit_of_dreamcast(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::Tablet => { + use_tool::tablet(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::DragonScale => { + use_tool::dragon_scale(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::HeavenStrikerCoat => { + use_tool::heaven_striker_coat(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::PioneerParts => { + use_tool::pioneer_parts(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::AmitiesMemo => { + use_tool::amities_memo(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::HeartOfMorolian => { + use_tool::heart_of_morolian(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::RappysBeak => { + use_tool::rappys_beak(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::YahoosEngine => { + use_tool::yahoos_engine(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::DPhotonCore => { + use_tool::d_photon_core(entity_gateway, &consumed_item, inventory).await?; + }, + ToolType::LibertaKit => { + use_tool::liberta_kit(entity_gateway, &consumed_item, inventory).await?; + }, + _ => {} + } + } _ => {} } - } - _ => {} + }, + ItemType::Unit(_) => { + + }, + ItemType::Weapon(_) => { + let actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.weapon_mut().ok_or(ItemManagerError::CannotGetMutItem)?; + actual_used_item.unwrap_present(); + }, } entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(()) @@ -923,4 +950,10 @@ impl ItemManager { Ok(weapon) } + + pub fn get_inventory_item_by_id(&mut self, character: &CharacterEntity, item_id: ClientItemId) -> Result<&InventoryItem, anyhow::Error> { + let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; + println!("item_manager.get_inventory_item_by_id() inventory: {:?}", inventory); + Ok(inventory.get_item_by_id(item_id).ok_or(ItemManagerError::ItemIdNotInInventory(item_id))?) + } } diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 0ce969a..a71ebd2 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -1,12 +1,12 @@ use libpso::packet::ship::*; use libpso::packet::messages::*; use crate::entity::gateway::EntityGateway; -use crate::entity::item::{ItemType}; +use crate::entity::item::{ItemType, ItemDetail}; use crate::common::serverstate::ClientId; use crate::common::leveltable::CharacterLevelTable; use crate::ship::ship::{SendShipPacket, ShipError, Rooms, Clients, ItemDropLocation}; use crate::ship::location::{ClientLocation, ClientLocationError}; -use crate::ship::items::{ItemManager, ClientItemId, InventoryItem}; +use crate::ship::items::{ItemManager, ClientItemId, InventoryItem, ItemManagerError}; use crate::ship::packet::builder; pub async fn request_exp(id: ClientId, @@ -272,9 +272,12 @@ where EG: EntityGateway { let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; - let item_used_type = item_manager.player_consumes_tool(entity_gateway, &mut client.character, ClientItemId(player_use_tool.item_id), 1).await?; + item_manager.use_item(entity_gateway, &mut client.character, ClientItemId(player_use_tool.item_id)).await?; - item_manager.use_item(item_used_type, entity_gateway, &mut client.character).await?; + if let ItemDetail::Tool(_t) = item_manager.get_inventory_item_by_id(&client.character, ClientItemId(player_use_tool.item_id))?.item_detail() { + item_manager.player_consumes_tool(entity_gateway, &mut client.character, ClientItemId(player_use_tool.item_id), 1).await?; + } + Ok(Box::new(None.into_iter())) }