diff --git a/src/subsystems/inventory_subsystem/inventory_subsystem.rs b/src/subsystems/inventory_subsystem/inventory_subsystem.rs new file mode 100644 index 0000000..7e685dd --- /dev/null +++ b/src/subsystems/inventory_subsystem/inventory_subsystem.rs @@ -0,0 +1,83 @@ +use std::sync::{Arc, mpsc}; + +use crate::server::IpcMessage; +use crate::{DatabaseManager, JsonManager}; + +#[macro_use] +use packet_processor::*; + +pub struct InventorySubsystem { + packets_to_send_tx: mpsc::Sender, + db: Arc, + jm: Arc, +} + +impl InventorySubsystem { + pub fn new(jm: Arc, db: Arc, packets_to_send_tx: mpsc::Sender) -> Self { + Self { + packets_to_send_tx: packets_to_send_tx.clone(), + db: db.clone(), + jm: jm.clone(), + } + } + + pub fn add_item(&self, user_id: u32, metadata: &proto::PacketHead, item_id: u32, count: u32, reason: &proto::ActionReasonType, inform_user: bool) { + let (item, is_new) = if self.jm.is_item_weapon(item_id) || self.jm.is_item_reliquary(item_id) { + assert!(count == 1); + (self.db.add_equip(user_id, item_id).unwrap(), false) // TODO: is new equip considered a new item? + } else { + let old_count = self.db.get_item_count_by_item_id(user_id, item_id); + + (self.db.add_stackable(user_id, item_id, count as i32).unwrap(), old_count == 0) + }; + + if inform_user { + build_and_send!(self, user_id, metadata, ItemAddHintNotify { + item_list: vec![build!(ItemHint { + item_id: item_id, + count: count, + is_new: is_new, + })], + reason: *reason as u32, + }); + } + + build_and_send!(self, user_id, metadata, StoreItemChangeNotify { + store_type: proto::StoreType::StorePack as i32, // TODO: hardcoded! + item_list: vec![item], + }); + } + + pub fn sub_item(&self, user_id: u32, metadata: &proto::PacketHead, item_id: u32, count: u32, reason: &proto::ActionReasonType) { + let old_amount = self.db.get_item_count_by_item_id(user_id, item_id); + + assert!(old_amount >= count); + + let (new_amount, item) = if self.jm.is_item_weapon(item_id) || self.jm.is_item_reliquary(item_id) { + panic!("You can't 'substract' a weapon or reliquary {}!", item_id) + } else { + let item = if old_amount > count { + // Just "add" a negative amount of items + self.db.add_stackable(user_id, item_id, -(count as i32)).unwrap() + } else { + self.db.remove_item_by_item_id(user_id, item_id).unwrap() + }; + + (old_amount - count, item) + }; + + if new_amount > 0 { + assert!(item.detail != None); + + build_and_send!(self, user_id, metadata, StoreItemChangeNotify { + store_type: proto::StoreType::StorePack as i32, + item_list: vec![item], + }); + } else { + build_and_send!(self, user_id, metadata, StoreItemDelNotify { + store_type: proto::StoreType::StorePack as i32, // TODO: hardcoded! + guid_list: vec![item.guid], + }); + } + } +} \ No newline at end of file diff --git a/src/subsystems/inventory_subsystem/mod.rs b/src/subsystems/inventory_subsystem/mod.rs new file mode 100644 index 0000000..2ed2620 --- /dev/null +++ b/src/subsystems/inventory_subsystem/mod.rs @@ -0,0 +1,3 @@ +mod inventory_subsystem; + +pub use self::inventory_subsystem::InventorySubsystem; \ No newline at end of file diff --git a/src/subsystems/mod.rs b/src/subsystems/mod.rs index 2330e39..d12aa00 100644 --- a/src/subsystems/mod.rs +++ b/src/subsystems/mod.rs @@ -1,6 +1,8 @@ pub mod entity_subsystem; +pub mod inventory_subsystem; pub mod misc; pub use self::entity_subsystem::EntitySubsystem; +pub use self::inventory_subsystem::InventorySubsystem; pub use self::misc::NpcSubsystem; pub use self::misc::ShopSubsystem; \ No newline at end of file