Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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);
        }
Example #5
0
        /// <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));
        }
Example #6
0
        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
                });
            }
        }
Example #7
0
        /// <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);
                }
            }
        }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
		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;
		}
Example #11
0
		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;
		}
Example #12
0
		/// <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;
		}
Example #13
0
		/// <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;
		}
Example #14
0
		/// <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;
							}
						}
					}
				}
			}
		}
Example #15
0
		/// <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;
		}
Example #16
0
		/// <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;
		}