/// <summary> /// Removes an item at a specific slot /// </summary> /// <param name="slot"> The slot to remove from </param> /// <param name="count"> The number of items to remove </param> /// <param name="result"> The result </param> /// <returns> The number of items removed </returns> public int RemoveItemAt(int slot, int count, out InventoryOperationResult result) { result = InventoryOperationResult.Success; // rules check if (!CanRemove) { result = InventoryOperationResult.NotAllowed; return(0); } // range check if (slot < 0 || slot >= this.Size) { result = InventoryOperationResult.NoRemovalDueToItemNotFound; return(0); } // if the slot is empty there will not be any item there var slotslot = this.slots[slot]; if (slotslot.IsEmpty) { result = InventoryOperationResult.NoRemovalDueToItemNotFound; return(0); } // we are not removing any? if (count != MmoItem.INFINITE && count < 1) { result = InventoryOperationResult.Fail; return(0); } // store the about-to-be-removed item before removing it so we can pass it to OnItemRemoved var itemAtSlot = slotslot.Item; // remove the item from the slot var removed = this.DoRemoveItemAt(slot, count); // if none removed return the result if (removed == 0) { result = InventoryOperationResult.NoRemovalDueToItemNotFound; return(0); } // announce the number of items we removed if (OnItemRemoved != null) { OnItemRemoved(itemAtSlot, removed, slot); } // we only removed some of the items so set the error if (removed < count) { result = InventoryOperationResult.PartialRemoval; } // return the removed count return(removed); }
/// <summary> /// Add a certain number of items at a specific slot /// </summary> /// <param name="itemId"> The id of the item </param> /// <param name="slot"> The slot to add to </param> /// <param name="count"> The count of the item </param> /// <param name="result"> The result </param> /// <returns> The number of items added </returns> public int AddItemAt(short itemId, int slot, int count, out InventoryOperationResult result) { result = InventoryOperationResult.Success; // rules check if (!CanAdd) { result = InventoryOperationResult.NotAllowed; return(0); } // if we are not adding any fail the operation if (count < 1) { result = InventoryOperationResult.Fail; return(0); } // range check if (slot < 0 || slot >= this.Size) { result = InventoryOperationResult.NoRemovalDueToItemNotFound; return(0); } // setting the added count to 0 var added = 0; // if the slot is empty create a new stack // otherwise stack the item var slotslot = this.slots[slot]; if (slotslot.IsEmpty) { // loading the item template GameItemData itemData; if (!MmoWorld.Instance.ItemCache.TryGetGameItemData(itemId, out itemData)) { // cannot find item. write to logger Utils.Logger.ErrorFormat("[AddItemAt]: Item (Id={0}) not found", itemId); result = InventoryOperationResult.Fail; return(0); } // create the item to be added var itemToAdd = this.itemCreator(itemData); // remember to add the item count to the added count because a new item may contain a count of 1 // using "itemToAdd.Count" just to be safe added += itemToAdd.StackCount; // if the item can be stacked and the count is more than 1 // then stack rest of the count if (itemToAdd.IsStackable && count > 1) { // stack the item of however many we have left var stacked = itemToAdd.Stack(count - added); if (stacked > 0) { // set the item at the slot this.slots[slot] = new Slot { Item = itemToAdd }; // increase the filled slots count this.FilledSlots++; // announce the amount of items we added if (OnItemAdded != null) { OnItemAdded(itemToAdd, itemToAdd.StackCount, slot); } // increment the added count added += stacked; } } else { // if the count is 1 we can just set the item at the slot this.slots[slot] = new Slot { Item = itemToAdd }; this.FilledSlots++; // announce that we added 1 item if (OnItemAdded != null) { OnItemAdded(itemToAdd, 1, slot); } } } else { // if an item exisits at the slot and its no the same item report error // if the item at the slot isnt the same as the item we are adding // or if the item (same item) is max stacked we cannot add any more at the slot var itemAtSlot = slotslot.Item; if (itemAtSlot.Id != itemId || itemAtSlot.IsStackMaxed) { result = InventoryOperationResult.Fail; return(0); } // stack the item of however many more we have left var stacked = itemAtSlot.Stack(count - added); if (stacked > 0) { // annouce the number of items we added if (OnItemAdded != null) { OnItemAdded(itemAtSlot, stacked, slot); } // increment the added count added += stacked; } } // this should not happen since we already checked whether the inventory is full or not if (added == 0) { result = InventoryOperationResult.NoAdditionDueToSpace; } // if we did not add all the items set the error if (added < count) { result = InventoryOperationResult.PartialAdditionDueToSpace; } // return the added items count return(added); }
/// <summary> /// Remove a certain number of an item or all. /// </summary> /// <param name="itemId"> Id of the item to removed </param> /// <param name="count"> The number of items to be removed. Specify <value>0</value> to remove all items. </param> /// <param name="result"> The result </param> /// <returns> The number of items removed </returns> public int RemoveItem(short itemId, int count, out InventoryOperationResult result) { result = InventoryOperationResult.Success; // rules check if (!CanRemove) { result = InventoryOperationResult.NotAllowed; return(0); } // inventory is empty if (IsEmpty) { result = InventoryOperationResult.NoRemovalDueToItemNotFound; return(0); } // we are not removing any? if (count != MmoItem.INFINITE && count < 1) { result = InventoryOperationResult.Fail; return(0); } var removed = 0; // are we removing all the items if (count == MmoItem.INFINITE) { for (var i = 0; i < this.Size; i++) { // if the slot is empty simply skip this slot var slot = this.slots[i]; if (slot.IsEmpty) { continue; } // if its the same item then perform the removal var itemAtSlot = slot.Item; if (itemAtSlot.Id == itemId) { // add the removed item count removed += itemAtSlot.StackCount; // remove the item stack at the slot completely var removedAtSlot = this.DoRemoveItemAt(i, count); // announce the number of items we removed if (OnItemRemoved != null) { this.OnItemRemoved(itemAtSlot, removed, removedAtSlot); } } } // we did not remove any items because the item was not found if (removed == 0) { result = InventoryOperationResult.NoRemovalDueToItemNotFound; } // we only removed some so set the error if (removed < count) { result = InventoryOperationResult.PartialRemoval; } // return the removed item count return(removed); } // we are removing only a certain number of items for (var i = 0; i < this.Size; i++) { // if the slot is empty simply skip this slot var slot = this.slots[i]; if (slot.IsEmpty) { continue; } // if the items arent the same we can skip this slot var itemAtSlot = slot.Item; if (itemAtSlot.Id != itemId) { continue; } // if the items current stack is less than the left items // we can completely remove the stack from the slot if (itemAtSlot.StackCount <= count - removed) { // add the items removed removed += itemAtSlot.StackCount; // remove the item stack at the slot completely var removedAtSlot = this.DoRemoveItemAt(i, count); // announce the number of items we removed if (OnItemRemoved != null) { OnItemRemoved(itemAtSlot, removed, removedAtSlot); } // if we have no items left to remove we can return if (removed == count) { return(removed); } } else { // if the left items are less than the item count // we can destack the item count from the stack itemAtSlot.Destack(count - removed); // announce the number of items we removed if (OnItemRemoved != null) { OnItemRemoved(itemAtSlot, count - removed, i); } // we have removed all the items so we can return return(removed); } } // we did not remove any items because the item was not found if (removed == 0) { result = InventoryOperationResult.NoRemovalDueToItemNotFound; } // we only removed some so set the error if (removed < count) { result = InventoryOperationResult.PartialRemoval; } // return the removed item count return(removed); }
/// <summary> /// Add a certain number of items /// </summary> /// <param name="itemId"> The id of the item </param> /// <param name="count"> The count of the item </param> /// <param name="result"> The result </param> /// <returns> The number of items added </returns> public int AddItem(short itemId, int count, out InventoryOperationResult result) { result = InventoryOperationResult.Success; // rules check if (!CanAdd) { result = InventoryOperationResult.NotAllowed; return(0); } // if we are not adding any fail the operation if (count < 1) { result = InventoryOperationResult.Fail; return(0); } // loading the item template GameItemData itemData; if (!MmoWorld.Instance.ItemCache.TryGetGameItemData(itemId, out itemData)) { // cannot find item. write to logger Utils.Logger.ErrorFormat("[AddItem]: Item (Id={0}) not found", itemId); result = InventoryOperationResult.Fail; return(0); } // if the item is stackable look for similar items in the inventory which we can stack var added = 0; if (itemData.MaxStack > 1) { // searching for partial stacks and stacking as much as we can for (var i = 0; i < this.Size; i++) { // since we are looking for slots to stack // we can skip an empty slot var slot = slots[i]; if (slot.IsEmpty) { continue; } // if the item at the slot isnt the same as the item we are adding // or if the item (same item) is max stacked we cannot add any more at the slot var itemAtSlot = slot.Item; if (itemData.ItemId != itemAtSlot.Id || itemAtSlot.IsStackMaxed) { continue; } // stack the item of however many more we have left var stacked = itemAtSlot.Stack(count - added); if (stacked > 0) { // annouce the number of items we added if (OnItemAdded != null) { OnItemAdded(itemAtSlot, stacked, i); } // update how many we have left added += stacked; // if we dont have anymore left then we added all items if (added == count) { return(added); } } } } // no more partial stacks left so add to empty slots // if the container is full we can return since we are not stacking but adding to an empty slot if (IsFull) { result = InventoryOperationResult.NoAdditionDueToSpace; return(0); } // searching for an empty slot to add the item to for (var i = 0; i < this.Size; i++) { // if the slot is empty we can skip this slot // since we are not stacking but adding to an empty slot var slotslot = this.slots[i]; if (!slotslot.IsEmpty) { continue; } // create the item to be added var itemToAdd = this.itemCreator(itemData); // remember to add the item count to the added count because a new item may contain a count of 1 // using "itemToAdd.Count" just to be safe added += itemToAdd.StackCount; // if the item can be stacked and the count is more than 1 // then stack rest of the count if (itemToAdd.IsStackable && count > 1) { // stack the item of however many we have left var stacked = itemToAdd.Stack(count - added); if (stacked > 0) { // set the item at the slot this.slots[i] = new Slot { Item = itemToAdd }; // increase the filled slots count this.FilledSlots++; // announce the amount of items we added if (OnItemAdded != null) { OnItemAdded(itemToAdd, itemToAdd.StackCount, i); } // increment the added count added += stacked; } } else { // if the count is 1 we can just set the item at the slot this.slots[i] = new Slot { Item = itemToAdd }; this.FilledSlots++; // announce that we added 1 item if (OnItemAdded != null) { OnItemAdded(itemToAdd, 1, i); } } // if we dont have anymore left then we added all items if (added == count) { return(added); } } // this should not happen since we already checked whether the inventory is full or not if (added == 0) { result = InventoryOperationResult.NoAdditionDueToSpace; } // if we did not add all the items set the error if (added < count) { result = InventoryOperationResult.PartialAdditionDueToSpace; } // return the added items count return(added); }