From 5caa6a07b0eb5ec8a2c288b4a0a06109e71af2bb Mon Sep 17 00:00:00 2001 From: Nemanja Date: Sat, 18 Jul 2020 02:41:45 +0000 Subject: [PATCH] #612 Fixed utility items not being removed from inventory/hotbar --- common/src/comp/inventory/mod.rs | 126 +++++++++++++++++++++++++++ server/src/events/inventory_manip.rs | 5 +- 2 files changed, 128 insertions(+), 3 deletions(-) diff --git a/common/src/comp/inventory/mod.rs b/common/src/comp/inventory/mod.rs index 657386fec5..ca1c178395 100644 --- a/common/src/comp/inventory/mod.rs +++ b/common/src/comp/inventory/mod.rs @@ -241,6 +241,132 @@ impl Inventory { } } + /// Checks if inserting item exists in given cell. Inserts an item if it + /// exists. + pub fn insert_or_stack(&mut self, cell: usize, item: Item) -> Result, Item> { + match &item.kind { + ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Lantern(_) => { + self.insert(cell, item) + }, + ItemKind::Utility { + amount: new_amount, .. + } => match self.slots.get_mut(cell) { + Some(Some(slot_item)) => { + if slot_item.name() == item.name() + && slot_item.description() == item.description() + { + if let Item { + kind: ItemKind::Utility { amount, .. }, + .. + } = slot_item + { + *amount += *new_amount; + self.recount_items(); + Ok(None) + } else { + let old_item = std::mem::replace(slot_item, item); + self.recount_items(); + Ok(Some(old_item)) + } + } else { + let old_item = std::mem::replace(slot_item, item); + self.recount_items(); + Ok(Some(old_item)) + } + }, + Some(None) => self.insert(cell, item), + None => Err(item), + }, + ItemKind::Ingredient { + amount: new_amount, .. + } => match self.slots.get_mut(cell) { + Some(Some(slot_item)) => { + if slot_item.name() == item.name() + && slot_item.description() == item.description() + { + if let Item { + kind: ItemKind::Ingredient { amount, .. }, + .. + } = slot_item + { + *amount += *new_amount; + self.recount_items(); + Ok(None) + } else { + let old_item = std::mem::replace(slot_item, item); + self.recount_items(); + Ok(Some(old_item)) + } + } else { + let old_item = std::mem::replace(slot_item, item); + self.recount_items(); + Ok(Some(old_item)) + } + }, + Some(None) => self.insert(cell, item), + None => Err(item), + }, + ItemKind::Consumable { + amount: new_amount, .. + } => match self.slots.get_mut(cell) { + Some(Some(slot_item)) => { + if slot_item.name() == item.name() + && slot_item.description() == item.description() + { + if let Item { + kind: ItemKind::Consumable { amount, .. }, + .. + } = slot_item + { + *amount += *new_amount; + self.recount_items(); + Ok(None) + } else { + let old_item = std::mem::replace(slot_item, item); + self.recount_items(); + Ok(Some(old_item)) + } + } else { + let old_item = std::mem::replace(slot_item, item); + self.recount_items(); + Ok(Some(old_item)) + } + }, + Some(None) => self.insert(cell, item), + None => Err(item), + }, + ItemKind::Throwable { + amount: new_amount, .. + } => match self.slots.get_mut(cell) { + Some(Some(slot_item)) => { + if slot_item.name() == item.name() + && slot_item.description() == item.description() + { + if let Item { + kind: ItemKind::Throwable { amount, .. }, + .. + } = slot_item + { + *amount += *new_amount; + self.recount_items(); + Ok(None) + } else { + let old_item = std::mem::replace(slot_item, item); + self.recount_items(); + Ok(Some(old_item)) + } + } else { + let old_item = std::mem::replace(slot_item, item); + self.recount_items(); + Ok(Some(old_item)) + } + }, + Some(None) => self.insert(cell, item), + None => Err(item), + }, + } + } + pub fn is_full(&self) -> bool { self.slots.iter().all(|slot| slot.is_some()) } /// O(n) count the number of items in this inventory. diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs index b33a170e0b..0716eec9cc 100644 --- a/server/src/events/inventory_manip.rs +++ b/server/src/events/inventory_manip.rs @@ -240,14 +240,13 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv }; if reinsert { - let _ = inventory.insert(slot, item); + let _ = inventory.insert_or_stack(slot, item); } Some(comp::InventoryUpdateEvent::Used) }, _ => { - // TODO: this doesn't work for stackable items - inventory.insert(slot, item).unwrap(); + inventory.insert_or_stack(slot, item).unwrap(); None }, }