From 24ce37279febd140ebcba127a54948bc56014bd0 Mon Sep 17 00:00:00 2001 From: Aaron Lee Date: Sat, 8 Apr 2023 11:07:58 -0700 Subject: [PATCH 1/2] added inventory item checks; need to figure out how to handle equips --- .../data/src/services/character/character.rs | 47 ++++++++++++++++--- server/data/src/services/field.rs | 39 ++++++++++----- .../data/src/services/helper/intentory/inv.rs | 17 +++++++ server/data/src/services/helper/pool/drop.rs | 9 ++-- server/game/src/lib.rs | 16 ++++--- 5 files changed, 98 insertions(+), 30 deletions(-) diff --git a/server/data/src/services/character/character.rs b/server/data/src/services/character/character.rs index 2621e6f..2568a0a 100644 --- a/server/data/src/services/character/character.rs +++ b/server/data/src/services/character/character.rs @@ -1,9 +1,19 @@ use std::ops::{Add, Div}; -use proto95::shared::char::{CharStatFlags, CharStatPartial}; +use game_data::wz2::Item; +use proto95::{ + id::ItemId, + shared::char::{CharStatFlags, CharStatPartial}, +}; use shroom_net::packet::CondOption; -use crate::{entities::character::Model, services::helper::intentory::inv::InventorySet}; +use crate::{ + entities::character::Model, + services::{ + helper::intentory::inv::{InventoryExt, InventorySet, InventoryType}, + model::item::{EquipItem, StackItem}, + }, +}; #[derive(Debug, Clone)] pub struct Character { @@ -49,13 +59,38 @@ impl Character { self.char_stat_flags.insert(CharStatFlags::Mp); } - pub fn update_mesos(&mut self, mesos: i32) -> bool { - if self.model.mesos + mesos < 0 { - return false; + pub fn update_mesos(&mut self, mesos: i32) -> anyhow::Result { + if self.model.mesos.checked_add(mesos).is_none() { + return Ok(false); } self.model.mesos = self.model.mesos.saturating_add(mesos); self.char_stat_flags.insert(CharStatFlags::Money); - true + Ok(true) + } + + pub fn update_inventory( + &mut self, + item_id: ItemId, + itype: InventoryType, + item: &Item + ) -> anyhow::Result { + if InventoryType::is_equip(&itype) { + let eq_inv = self.inventory.get_equipped_inventory_mut(itype)?; + let equip_item = EquipItem::from_item_id(item_id, &item_meta).into(); + Ok(eq_inv + .get_inner_mut() + .try_add(equip_item) + .map(|_| true) + .unwrap_or(false)) + } else { + let stack_inv = self.inventory.get_stack_inventory_mut(itype)?; + let stack_item = StackItem::from_item_id(item_id, 1).into(); + Ok(stack_inv + .get_inner_mut() + .try_add(stack_item) + .map(|_| true) + .unwrap_or(false)) + } } pub fn get_char_partial(&mut self) -> CharStatPartial { diff --git a/server/data/src/services/field.rs b/server/data/src/services/field.rs index 051b697..d56f92b 100755 --- a/server/data/src/services/field.rs +++ b/server/data/src/services/field.rs @@ -15,10 +15,17 @@ use proto95::{ use ractor::{Actor, ActorProcessingErr, ActorRef, RpcReplyPort}; use shroom_net::net::service::{packet_buffer::PacketBuffer, server_sess::SharedSessionHandle}; +use crate::services::helper::intentory::inv::InventoryType; + use super::{ character::Character, data::character::CharacterID, - helper::pool::{drop::DropLeaveParam, reactor::Reactor, user::User, Drop, Mob, Npc, Pool}, + helper::pool::{ + drop::{DropLeaveParam, DropTypeValue}, + reactor::Reactor, + user::User, + Drop, Mob, Npc, Pool, + }, meta::{ fh_tree::FhTree, meta_service::{FieldMeta, MetaService}, @@ -28,7 +35,7 @@ use super::{ #[derive(Debug)] pub struct FieldData { - _meta: &'static MetaService, + meta: &'static MetaService, field_meta: FieldMeta, field_fh: &'static FhTree, drop_pool: Pool, @@ -105,7 +112,7 @@ impl FieldData { }); Self { - _meta: meta, + meta: meta, field_meta, field_fh: fh_meta, drop_pool: Pool::new(meta), @@ -240,15 +247,23 @@ impl FieldData { Ok(()) } - // TODO: handle various drop items - pub fn handle_pickup(&self, item: DropId, char: &mut Character) -> anyhow::Result<()> { - match self.drop_pool.is_money(item) { - Some(m) => { - char.update_mesos(m.try_into().unwrap()); - } - None => {} - }; - Ok(()) + pub fn handle_pickup(&self, item: DropId, char: &mut Character) -> anyhow::Result { + match self.drop_pool.get_item(item) { + Some(v) => match v { + DropTypeValue::Item(i) => { + let (item, itype) = match self.meta.get_item_data(i) { + Some(v) => (v, InventoryType::Use), + None => match self.meta.get_eq_data(i) { + Some(v) => (v, InventoryType::Equip), + None => return Ok(false), + }, + }; + Ok(char.update_inventory(i, itype, item)?) + } + DropTypeValue::Mesos(m) => Ok(char.update_mesos(m as i32)?), + }, + None => Ok(false), + } } pub async fn attack_mob( diff --git a/server/data/src/services/helper/intentory/inv.rs b/server/data/src/services/helper/intentory/inv.rs index 723c84b..424a3bb 100755 --- a/server/data/src/services/helper/intentory/inv.rs +++ b/server/data/src/services/helper/intentory/inv.rs @@ -136,6 +136,7 @@ impl InventoryExt for EquippedInventory { fn get_inner_mut(&mut self) -> &mut Inventory { &mut self.0 } + } impl EquippedInventory { @@ -182,6 +183,14 @@ impl EquipInventory { pub fn items_mut(&mut self) -> impl Iterator { self.0.items_mut() } + + pub fn get_inner(&self) -> &Inventory { + &self.0 + } + + pub fn get_inner_mut(&mut self) -> &mut Inventory { + &mut self.0 + } } #[derive(Debug, Clone)] @@ -242,6 +251,14 @@ impl StackInventory { pub fn items_mut(&mut self) -> impl Iterator { self.0.items_mut() } + + pub fn get_inner(&self) -> &Inventory { + &self.0 + } + + pub fn get_inner_mut(&mut self) -> &mut Inventory { + &mut self.0 + } } #[derive(Debug, Clone, Copy, TryFromPrimitive)] diff --git a/server/data/src/services/helper/pool/drop.rs b/server/data/src/services/helper/pool/drop.rs index 249046b..8e73376 100755 --- a/server/data/src/services/helper/pool/drop.rs +++ b/server/data/src/services/helper/pool/drop.rs @@ -30,7 +30,7 @@ pub struct Drop { pub quantity: usize, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum DropTypeValue { Mesos(u32), Item(ItemId), @@ -108,16 +108,13 @@ impl PoolItem for Drop { } impl Pool { - pub fn is_money(&self, item: DropId) -> Option { + pub fn get_item(&self, item: DropId) -> Option { let pool = match self.items.read() { Ok(map) => map, Err(_) => return None, }; match pool.get(&item) { - Some(i) => match i.value { - DropTypeValue::Item(_) => None, - DropTypeValue::Mesos(m) => Some(m), - }, + Some(i) => Some(i.value.clone()), None => None, } } diff --git a/server/game/src/lib.rs b/server/game/src/lib.rs index 3ff3abc..be97c02 100755 --- a/server/game/src/lib.rs +++ b/server/game/src/lib.rs @@ -513,12 +513,16 @@ impl GameHandler { ) -> GameResult { dbg!(&req); - self.field + let remove_drop = self + .field .handle_pickup(req.drop_id, &mut self.session.char)?; - self.field.remove_drop( - req.drop_id, - DropLeaveParam::UserPickup(self.session.char.model.id as u32), - )?; + if remove_drop { + self.field.remove_drop( + req.drop_id, + DropLeaveParam::UserPickup(self.session.char.model.id as u32), + )?; + } + Ok(CharStatChangedResp { excl: true, stats: PartialFlag { @@ -535,7 +539,7 @@ impl GameHandler { &mut self, req: UserDropMoneyReq, ) -> GameResult { - let ok = self.session.char.update_mesos((req.money as i32).neg()); + let ok = self.session.char.update_mesos((req.money as i32).neg())?; if ok { self.field.add_drop(Drop { owner: proto95::game::drop::DropOwner::User(self.session.char.model.id as u32), From 3673a922f12d321da569d0937af1101ddfcf40cf Mon Sep 17 00:00:00 2001 From: Aaron Lee Date: Sat, 8 Apr 2023 13:52:40 -0700 Subject: [PATCH 2/2] need to broadcast to client about inventory changes --- server/data/src/services/character/character.rs | 7 ++++--- server/data/src/services/field.rs | 4 ++-- server/data/src/services/helper/pool/drop.rs | 9 +++------ 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/server/data/src/services/character/character.rs b/server/data/src/services/character/character.rs index 2568a0a..7c152dc 100644 --- a/server/data/src/services/character/character.rs +++ b/server/data/src/services/character/character.rs @@ -1,6 +1,5 @@ use std::ops::{Add, Div}; -use game_data::wz2::Item; use proto95::{ id::ItemId, shared::char::{CharStatFlags, CharStatPartial}, @@ -11,6 +10,7 @@ use crate::{ entities::character::Model, services::{ helper::intentory::inv::{InventoryExt, InventorySet, InventoryType}, + meta::meta_service::ItemMeta, model::item::{EquipItem, StackItem}, }, }; @@ -72,7 +72,8 @@ impl Character { &mut self, item_id: ItemId, itype: InventoryType, - item: &Item + item_meta: ItemMeta, + quantity: usize, ) -> anyhow::Result { if InventoryType::is_equip(&itype) { let eq_inv = self.inventory.get_equipped_inventory_mut(itype)?; @@ -84,7 +85,7 @@ impl Character { .unwrap_or(false)) } else { let stack_inv = self.inventory.get_stack_inventory_mut(itype)?; - let stack_item = StackItem::from_item_id(item_id, 1).into(); + let stack_item = StackItem::from_item_id(item_id, quantity as u16).into(); Ok(stack_inv .get_inner_mut() .try_add(stack_item) diff --git a/server/data/src/services/field.rs b/server/data/src/services/field.rs index d56f92b..5b5c2eb 100755 --- a/server/data/src/services/field.rs +++ b/server/data/src/services/field.rs @@ -249,7 +249,7 @@ impl FieldData { pub fn handle_pickup(&self, item: DropId, char: &mut Character) -> anyhow::Result { match self.drop_pool.get_item(item) { - Some(v) => match v { + Some(v) => match v.value { DropTypeValue::Item(i) => { let (item, itype) = match self.meta.get_item_data(i) { Some(v) => (v, InventoryType::Use), @@ -258,7 +258,7 @@ impl FieldData { None => return Ok(false), }, }; - Ok(char.update_inventory(i, itype, item)?) + Ok(char.update_inventory(i, itype, item, v.quantity)?) } DropTypeValue::Mesos(m) => Ok(char.update_mesos(m as i32)?), }, diff --git a/server/data/src/services/helper/pool/drop.rs b/server/data/src/services/helper/pool/drop.rs index 8e73376..f6d3f72 100755 --- a/server/data/src/services/helper/pool/drop.rs +++ b/server/data/src/services/helper/pool/drop.rs @@ -21,7 +21,7 @@ use crate::services::{ use super::{next_id, Pool, PoolItem}; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Drop { pub owner: DropOwner, pub pos: Vec2, @@ -108,15 +108,12 @@ impl PoolItem for Drop { } impl Pool { - pub fn get_item(&self, item: DropId) -> Option { + pub fn get_item(&self, item: DropId) -> Option { let pool = match self.items.read() { Ok(map) => map, Err(_) => return None, }; - match pool.get(&item) { - Some(i) => Some(i.value.clone()), - None => None, - } + pool.get(&item).cloned() } pub fn add_mob_drops(