/// <summary> /// Tries to distribute the given amount of the given Item over all available stacks and add the remainder to a free slot. /// Parts of the stack might have distributed over existing stacks, even if adding the remainder failed. /// </summary> /// <returns>InventoryError.OK in case that it could be added</returns> public InventoryError TryAddAmount(Item item, int amount, bool isNew, ItemReceptionType reception = ItemReceptionType.Receive) { int amount1 = amount; InventoryError err = InventoryError.OK; if (!this.Distribute(item.Template, ref amount1)) { this.CheckUniqueness((IMountableItem)item, ref amount, ref err, isNew); if (err == InventoryError.OK) { amount -= amount1; item.Amount = amount; SimpleSlotId freeSlot = this.FindFreeSlot((IMountableItem)item, amount); if (freeSlot.Slot == (int)byte.MaxValue) { return(InventoryError.BAG_FULL); } freeSlot.Container.AddUnchecked(freeSlot.Slot, item.Template, amount, isNew); } } else { amount -= amount1; item.Amount = amount; } if (isNew) { this.OnAdded(item, item.Template, amount1 + amount, reception); } return(err); }
/// <summary> /// Tries to add an item with the given template and amount /// </summary> /// <param name="amount">Amount of items to be added: Will be set to the amount of Items that have actually been added.</param> /// <returns>The result (InventoryError.OK in case that it worked)</returns> public InventoryError TryAdd(ItemTemplate template, ref int amount, ItemReceptionType reception = ItemReceptionType.Receive) { int amount1 = amount; InventoryError err = InventoryError.OK; Item obj = (Item)null; if (!this.Distribute(template, ref amount1)) { amount -= amount1; this.CheckUniqueness((IMountableItem)template, ref amount, ref err, true); if (err == InventoryError.OK) { SimpleSlotId freeSlot = this.FindFreeSlot((IMountableItem)template, amount); if (freeSlot.Slot == (int)byte.MaxValue) { return(this.FullError); } obj = freeSlot.Container.AddUnchecked(freeSlot.Slot, template, amount, true); } } this.OnAdded(obj, template, amount1 + (obj != null ? obj.Amount : 0), reception); return(err); }
/// <summary> /// Tries to distribute the given item over all available stacks and add the remainder to a free slot. /// IMPORTANT: /// 1. The Item will be destroyed if it could successfully be distributed over existing stacks of Items. /// 2. If item.Container == null, parts of the item-stack might have distributed over other stacks of the same type /// but the remainder did not find a free slot or exceeded the max count of the item. /// item.Amount will hold the remaining amount. /// </summary> /// <returns>The result (InventoryError.OK in case that it worked)</returns> public InventoryError TryAdd(Item item, bool isNew, ItemReceptionType reception = ItemReceptionType.Receive) { int amount1 = item.Amount; InventoryError err = InventoryError.OK; int amount2 = amount1; if (!this.Distribute(item.Template, ref amount2)) { int amount3 = amount1 - amount2; item.Amount = amount3; this.CheckUniqueness((IMountableItem)item, ref amount3, ref err, isNew); if (err == InventoryError.OK) { SimpleSlotId freeSlot = this.FindFreeSlot((IMountableItem)item, amount3); if (freeSlot.Slot == (int)byte.MaxValue) { return(this.FullError); } freeSlot.Container.AddUnchecked(freeSlot.Slot, item, isNew); } } else { int num = amount1 - amount2; item.Amount = num; } if (isNew) { this.OnAdded(item, item.Template, amount2 + item.Amount, reception); } return(err); }
/// <summary> /// Finds a free slot for the given template and occpuies it with a placeholder. /// Don't forget to remove it again. /// </summary> /// <param name="templ"></param> /// <param name="amount"></param> /// <returns></returns> internal SimpleSlotId HoldFreeSlot(ItemTemplate templ, int amount) { SimpleSlotId freeSlot = this.FindFreeSlot((IMountableItem)templ, amount); if (freeSlot.Slot != (int)byte.MaxValue) { freeSlot.Container.m_Items[freeSlot.Slot] = Item.PlaceHolder; } return(freeSlot); }
/// <summary> /// Tries to add a new item with the given id to a free slot. /// </summary> /// <returns>The result (InventoryError.OK in case that it worked)</returns> public InventoryError TryAdd(ItemTemplate templ, ItemReceptionType reception = ItemReceptionType.Receive) { if (templ == null) { return(InventoryError.Invalid); } SimpleSlotId freeSlot = this.FindFreeSlot((IMountableItem)templ, 1); if (freeSlot.Slot == (int)byte.MaxValue) { return(this.FullError); } return(freeSlot.Container.TryAdd(templ, freeSlot.Slot, reception)); }
internal void AddLoadedItem(Item item) { try { int slot = item.Slot; BaseInventory baseInventory = this; if (!this.IsValidSlot(slot)) { SimpleSlotId freeSlot = this.OwnerInventory.FindFreeSlot(item, false); if (slot == (int)byte.MaxValue) { LogManager.GetCurrentClassLogger() .Warn("Ignoring loaded Item {0} in {1} because it has an invalid Slot: {2}", (object)item, (object)this, (object)item.Slot); return; } LogManager.GetCurrentClassLogger().Warn("Loaded Item {0} in {1} has invalid Slot: {2}", (object)item, (object)this, (object)item.Slot); slot = freeSlot.Slot; baseInventory = freeSlot.Container; } if (baseInventory[slot] != null) { LogManager.GetCurrentClassLogger() .Warn("Ignoring Item {0} for {1} because slot is already occupied by: {2}", (object)item, (object)this.Owner, (object)baseInventory[slot]); item.Destroy(); } else { Character owner = this.Owner; PlayerInventory ownerInventory = this.OwnerInventory; baseInventory[slot] = item; owner.AddItemToUpdate(item); ownerInventory.OnAddDontNotify(item); } } catch (Exception ex) { LogUtil.ErrorException(ex, "Unable to add Item \"{0}\" to {1}", new object[2] { (object)item, (object)this }); } }
/// <summary> /// Adds all given Items to the given slots. /// Tries to distribute over existing stacks first. /// </summary> /// <param name="items"></param> /// <returns></returns> public void AddAllUnchecked <T>(T[] items, SimpleSlotId[] slots) where T : IItemStack { int length = items.Length; for (int index = 0; index < length; ++index) { T obj = items[index]; int amount1 = obj.Amount; if (!this.Distribute(obj.Template, ref amount1)) { SimpleSlotId slot = slots[index]; int amount2 = obj.Amount - amount1; slot.Container.m_Items[slot.Slot] = (Item)null; slot.Container.AddUnchecked(slot.Slot, items[index].Template, amount2, true); } } }
public InventoryError GetSlots <T>(T[] items, out SimpleSlotId[] slots) where T : IItemStack { var count = items.Length; var err = InventoryError.OK; SimpleSlotId slotId; var i = 0; slots = new SimpleSlotId[count]; for (; i < count; i++) { var item = items[i]; var templ = item.Template; var amount = item.Amount; CheckUniqueness(templ, ref amount, ref err, true); if (err == InventoryError.OK && amount != item.Amount) { err = InventoryError.CANT_CARRY_MORE_OF_THIS; break; } slotId = FindFreeSlot(templ, amount); if (slotId.Slot == INVALID_SLOT) { // TODO: What if Item can be distributed over existing stacks? err = InventoryError.INVENTORY_FULL; break; } // occupy slot with placeholder slotId.Container.m_Items[slotId.Slot] = Item.PlaceHolder; slots[i] = slotId; } if (err != InventoryError.OK) { // remove placeholders for (var j = 0; j < i; j++) { slotId = slots[j]; slotId.Container.m_Items[slotId.Slot] = null; } slots = null; } return(err); }
public InventoryError GetSlots <T>(T[] items, out SimpleSlotId[] slots) where T : IItemStack { int length = items.Length; InventoryError err = InventoryError.OK; int index1 = 0; slots = new SimpleSlotId[length]; SimpleSlotId freeSlot; for (; index1 < length; ++index1) { T obj = items[index1]; ItemTemplate template = obj.Template; int amount = obj.Amount; this.CheckUniqueness((IMountableItem)template, ref amount, ref err, true); if (err == InventoryError.OK && amount != obj.Amount) { err = InventoryError.CANT_CARRY_MORE_OF_THIS; break; } freeSlot = this.FindFreeSlot((IMountableItem)template, amount); if (freeSlot.Slot == (int)byte.MaxValue) { err = InventoryError.INVENTORY_FULL; break; } freeSlot.Container.m_Items[freeSlot.Slot] = Item.PlaceHolder; slots[index1] = freeSlot; } if (err != InventoryError.OK) { for (int index2 = 0; index2 < index1; ++index2) { freeSlot = slots[index2]; freeSlot.Container.m_Items[freeSlot.Slot] = (Item)null; } slots = (SimpleSlotId[])null; } return(err); }
public override SpellFailedReason CheckValidTarget(WorldObject target) { var templId = Effect.ItemId; templ = ItemMgr.GetTemplate(templId); amount = CalcEffectValue(); if (templ == null) { log.Warn("Spell {0} referred to invalid Item {1}", Effect.Spell, templId); return SpellFailedReason.ItemNotFound; } // find a free slot slotId = ((Character)target).Inventory.FindFreeSlotCheck(templ, amount); if (slotId.Slot == BaseInventory.INVALID_SLOT) { ItemHandler.SendInventoryError((Character)target, InventoryError.INVENTORY_FULL); return SpellFailedReason.DontReport; } return SpellFailedReason.Ok; }
public override SpellFailedReason InitializeTarget(WorldObject target) { var templId = Effect.ItemId; templ = ItemMgr.GetTemplate(templId); amount = CalcEffectValue(); if (templ == null) { log.Warn("Spell {0} referred to invalid Item {1}", Effect.Spell, templId); return SpellFailedReason.ItemNotFound; } // find a free slot // TODO: Add & use HoldFreeSlotCheck instead, so slot won't get occupied InventoryError error; slotId = ((Character)target).Inventory.FindFreeSlotCheck(templ, amount, out error); if (error != InventoryError.OK) { ItemHandler.SendInventoryError((Character)target, error); return SpellFailedReason.DontReport; } return SpellFailedReason.Ok; }
/// <summary> /// Gets 0 to max free slots in the backpack or one of the equipped bags and optionally the bank (+ its bags) /// </summary> /// <param name="inclBank">whether to also look in the bank for free slots</param> /// <param name="max">The max of free inventory slots to be returned</param> public IList<SimpleSlotId> FindFreeSlots(bool inclBank, int max) { var slotList = new List<SimpleSlotId>(); var slots = inclBank ? ItemMgr.InvSlotsWithBank : ItemMgr.StorageSlotsWithoutBank; var contLookup = ItemMgr.ContainerSlotsWithBank; for (var i1 = 0; i1 < slots.Length; i1++) { var avlblSlot = (int)slots[i1]; if (contLookup[avlblSlot]) { var container = m_Items[avlblSlot] as Container; if (container != null) { var contInv = container.BaseInventory; var contItems = contInv.Items; for (var i = 0; i < contItems.Length; i++) { if (contItems[i] == null) { var slotId = new SimpleSlotId { Container = contInv, Slot = i }; slotList.Add(slotId); if (slotList.Count == max) return slotList; } } } } else if (m_Items[avlblSlot] == null) { var slotId = new SimpleSlotId { Container = this, Slot = avlblSlot }; slotList.Add(slotId); if (slotList.Count == max) { return slotList; } } } return slotList; }
/// <summary> /// Gets a free slot in the bank or one of the bankbags /// </summary> public SimpleSlotId FindFreeBankSlot(IMountableItem item, int amount) { var slotId = new SimpleSlotId(); for (var i = 0; i < ItemMgr.BankSlots.Length; i++) { var avlblSlot = (int)ItemMgr.BankSlots[i]; if (m_Items[avlblSlot] == null) { slotId.Container = this; slotId.Slot = avlblSlot; return slotId; } } for (var i1 = 0; i1 < ItemMgr.BankBagSlots.Length; i1++) { var avlblSlot = (int)ItemMgr.BankBagSlots[i1]; var container = m_Items[avlblSlot] as Container; if (container != null) { var contInv = container.BaseInventory; if (contInv.CheckAdd(0, item, amount) == InventoryError.OK) { var contItems = contInv.Items; for (var i = 0; i < contItems.Length; i++) { if (contItems[i] == null) { slotId.Container = contInv; slotId.Slot = i; return slotId; } } } } } slotId.Slot = INVALID_SLOT; return slotId; }
/// <summary> /// Sets slotId to the slot that the given templ would prefer (if it has any bag preference). /// </summary> /// <param name="templ"></param> /// <param name="slotId"></param> public void GetPreferredSlot(ItemTemplate templ, int amount, ref SimpleSlotId slotId) { if (templ.IsKey) { slotId.Container = this; slotId.Slot = KeyRing.FindFreeSlot(); } else if (!templ.IsContainer && templ.BagFamily != ItemBagFamilyMask.None) { for (var slot = InventorySlot.Bag1; slot <= InventorySlot.BagLast; slot++) { var bag = this[slot] as Container; if (bag != null && bag.Template.BagFamily != 0) { var inv = bag.BaseInventory; if (bag.Template.MayAddToContainer(templ)) { slotId.Slot = inv.FindFreeSlot(); if (slotId.Slot != INVALID_SLOT) { slotId.Container = inv; break; } } } } } }
/// <summary> /// Finds up to max items that are validated by the given validator and puts them in the given list. /// </summary> /// <param name="inclBank">whether to also search in the bank and its bags (if not enough was found in inventory and bags)</param> /// <param name="max">Maximum amount of items to be looked through</param> /// <param name="list">List of slot-identifiers for the items to be added to</param> /// <returns>The amount of found items</returns> public int Find(bool inclBank, int max, IList<SimpleSlotId> list, Func<Item, bool> validator) { var slots = inclBank ? ItemMgr.InvSlotsWithBank : ItemMgr.StorageSlotsWithoutBank; var found = 0; var contLookup = ItemMgr.ContainerSlotsWithBank; Item item; foreach (int avlblSlot in slots) { item = m_Items[avlblSlot]; if (contLookup[avlblSlot]) { var container = item as Container; if (container != null) { var contInv = container.BaseInventory; var contItems = contInv.Items; for (var i = 0; i < contItems.Length; i++) { item = contItems[i]; if (item != null && validator(item)) { found += item.Amount; var slotId = new SimpleSlotId { Container = contInv, Slot = i }; list.Add(slotId); if (found >= max) { return found; } } } } } else if (item != null && validator(item)) { found += item.Amount; var slotId = new SimpleSlotId { Container = this, Slot = avlblSlot }; list.Add(slotId); if (found >= max) { return found; } } } return found; }
/// <summary> /// Finds up to max items that are validated by the given validator and puts them in the given list. /// </summary> /// <param name="inclBank">whether to also search in the bank and its bags (if not enough was found in inventory and bags)</param> /// <param name="max">Maximum amount of items to be looked through</param> /// <param name="list">List of slot-identifiers for the items to be added to</param> /// <returns>The amount of found items</returns> public int Find(bool inclBank, int max, IList<SimpleSlotId> list, Func<Item, bool> validator) { var found = 0; Iterate(inclBank, item => { if (validator(item)) { found += item.Amount; var slotId = new SimpleSlotId { Container = item.Container, Slot = item.Slot }; list.Add(slotId); if (found >= max) { return false; } } return true; }); return found; }