/// <summary>Don't use this method - but use item.Remove instead.</summary> /// <param name="item"></param> /// <param name="ownerChange"></param> internal void Remove(Item item, bool ownerChange) { if (ownerChange) { item.m_unknown = true; this.OwnerInventory.OnRemove(item); } int slot1 = item.Slot; IItemSlotHandler handler = this.GetHandler(slot1); if (handler != null) { handler.Removed(slot1, item); } int slot2 = item.Slot; this.m_Items[slot2] = (Item)null; if (this.Container != null) { this.SetContainerEntityId(EntityId.Zero, slot2, this); } item.Container = (BaseInventory)null; --this.m_count; }
/// <summary> /// Tries to add a new item with the given template and amount ot the given slot. /// Make sure the given targetSlot is valid before calling this method. /// </summary> /// <returns>The result (InventoryError.OK in case that it worked)</returns> public InventoryError TryAdd(ItemTemplate template, ref int amount, int slot, ItemReceptionType reception = ItemReceptionType.Receive) { if (this.m_Items[slot] != null) { LogManager.GetCurrentClassLogger().Warn("Tried to add Item {0} to {1} in occupied slot {2}", (object)template, (object)this, (object)slot); return(InventoryError.ITEM_DOESNT_GO_TO_SLOT); } InventoryError err = InventoryError.OK; this.CheckUniqueness((IMountableItem)template, ref amount, ref err, true); if (err == InventoryError.OK) { IItemSlotHandler handler = this.GetHandler(slot); if (handler != null) { err = InventoryError.OK; handler.CheckAdd(slot, amount, (IMountableItem)template, ref err); if (err != InventoryError.OK) { return(err); } } this.OnAdded(this.AddUnchecked(slot, template, amount, true), template, amount, reception); } return(err); }
/// <summary> /// /// </summary> /// <param name="slot"></param> /// <param name="item"></param> /// <param name="amount"></param> /// <returns></returns> public InventoryError CheckAdd(int slot, IMountableItem item, int amount) { IItemSlotHandler handler = this.GetHandler(slot); if (handler == null) { return(InventoryError.OK); } InventoryError err = InventoryError.OK; handler.CheckAdd(slot, amount, item, ref err); return(err); }
/// <summary> /// Sets or Gets the Item at the given slot (make sure that slot is valid and unoccupied). /// </summary> /// <remarks>Cannot set to null - Use <see cref="M:WCell.RealmServer.Items.BaseInventory.Remove(System.Int32,System.Boolean)" /> instead.</remarks> /// <param name="slot"></param> /// <returns></returns> public Item this[int slot] { get { if (slot < 0 || slot > this.m_Items.Length) { return((Item)null); } return(this.m_Items[slot]); } set { if (value == null) { throw new NullReferenceException(string.Format( "Cannot set Slot {0} in Inventory \"{1}\" to null - Use the Remove-method instead.", (object)slot, (object)this)); } if (this.m_Items[slot] != null) { string msg = string.Format( "Cannot add Item \"{0}\" to Slot {1} in Inventory \"{2}\" to - Slot is occupied with Item \"{3}\".", (object)value, (object)slot, (object)this, (object)this.m_Items[slot]); LogUtil.ErrorException(msg, new object[0]); value.Destroy(); if (this.Owner == null) { return; } this.Owner.SendSystemMessage(msg); } else { ++this.m_count; value.Container = this; value.Slot = slot; this.SetContainerEntityId(value.EntityId, slot, this); this.m_Items[slot] = value; IItemSlotHandler handler = this.GetHandler(slot); if (handler == null) { return; } handler.Added(value); } } }
private bool CheckFreeSlots(IList <SimpleSlotId> myFreeSlots, Item[] items) { bool flag = true; int index1 = 0; for (int index2 = 0; index2 < 6; ++index2) { if (items[index2] != null) { if (myFreeSlots.Count <= index1) { flag = false; break; } int slot = myFreeSlots[index1].Slot; BaseInventory container = myFreeSlots[index1].Container; IItemSlotHandler handler = container.GetHandler(slot); InventoryError err = InventoryError.OK; handler.CheckAdd(slot, items[index2].Amount, items[index2], ref err); if (err != InventoryError.OK) { flag = false; break; } int amount = items[index2].Amount; container.CheckUniqueness(items[index2], ref amount, ref err, true); if (err != InventoryError.OK) { flag = false; break; } ++index1; } } if (!flag) { m_chr.SendSystemMessage("You don't have enough free slots"); m_otherWindow.m_chr.SendSystemMessage("Other party doesn't have enough free slots"); SendStatus(TradeStatus.StateChanged, true); } return(flag); }
/// <summary> /// Tries to merge an item with the given template and amount to the stack at the given slot. /// If the given slot is empty it adds the item to the slot. /// Make sure the given targetSlot is valid before calling this method. /// </summary> /// <param name="amount">Set to the number of items actually added.</param> /// <returns>The result (InventoryError.OK in case that it worked)</returns> public InventoryError TryMerge(ItemTemplate template, ref int amount, int slot, bool isNew) { InventoryError err = InventoryError.OK; this.CheckUniqueness((IMountableItem)template, ref amount, ref err, isNew); if (err == InventoryError.OK) { IItemSlotHandler handler = this.GetHandler(slot); if (handler != null) { err = InventoryError.OK; handler.CheckAdd(slot, amount, (IMountableItem)template, ref err); if (err != InventoryError.OK) { return(err); } } this.MergeUnchecked(slot, template, ref amount, isNew); } return(err); }
/// <summary> /// </summary> /// <param name="message"> /// </param> /// <param name="cli"> /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// </exception> /// <exception cref="NotImplementedException"> /// </exception> public static void AddItemToContainer(ContainerAddItemMessage message, ZoneClient cli) { bool noAppearanceUpdate = false; /* Container ID's: * 0065 Weaponpage * 0066 Armorpage * 0067 Implantpage * 0068 Inventory (places 64-93) * 0069 Bank * 006B Backpack * 006C KnuBot Trade Window * 006E Overflow window * 006F Trade Window * 0073 Socialpage * 0767 Shop Inventory * 0790 Playershop Inventory * DEAD Trade Window (incoming) It's bank now (when you put something into the bank) */ var fromContainerID = (int)message.SourceContainer.Type; int fromPlacement = message.SourceContainer.Instance; Identity toIdentity = message.Target; int toPlacement = message.TargetPlacement; // Where and what does need to be moved/added? IInventoryPage sendingPage = cli.Character.BaseInventory.Pages[fromContainerID]; IItem itemFrom = sendingPage[fromPlacement]; // Receiver of the item (IInstancedEntity, can be mostly all from NPC, Character or Bag, later even playfields) // Turn 0xDEAD into C350 if instance is the same if (toIdentity.Type == IdentityType.IncomingTradeWindow) { toIdentity.Type = IdentityType.CanbeAffected; } IItemContainer itemReceiver = cli.Playfield.FindByIdentity(toIdentity) as IItemContainer; if (itemReceiver == null) { throw new ArgumentOutOfRangeException( "No Entity found: " + message.Target.Type.ToString() + ":" + message.Target.Instance); } // On which inventorypage should the item be added? IInventoryPage receivingPage; if ((toPlacement == 0x6f) && (message.Target.Type == IdentityType.IncomingTradeWindow)) { receivingPage = itemReceiver.BaseInventory.Pages[(int)IdentityType.Bank]; } else { receivingPage = itemReceiver.BaseInventory.PageFromSlot(toPlacement); } // Get standard page if toplacement cant be found (0x6F for next free slot) // TODO: If Entities are not the same (other player, bag etc) then always add to the standard page if ((receivingPage == null) || (itemReceiver.GetType() != cli.Character.GetType())) { receivingPage = itemReceiver.BaseInventory.Pages[itemReceiver.BaseInventory.StandardPage]; } if (receivingPage == null) { throw new ArgumentOutOfRangeException("No inventorypage found."); } if (toPlacement == 0x6f) { toPlacement = receivingPage.FindFreeSlot(); } // Is there already a item? IItem itemTo; try { itemTo = receivingPage[toPlacement]; } catch (Exception) { itemTo = null; } // Calculating delay for equip/unequip/switch gear int delay = 20; cli.Character.DoNotDoTimers = true; IItemSlotHandler equipTo = receivingPage as IItemSlotHandler; IItemSlotHandler unequipFrom = sendingPage as IItemSlotHandler; noAppearanceUpdate = !((equipTo is WeaponInventoryPage) || (equipTo is ArmorInventoryPage) || (equipTo is SocialArmorInventoryPage)); noAppearanceUpdate &= !((unequipFrom is WeaponInventoryPage) || (unequipFrom is ArmorInventoryPage) || (unequipFrom is SocialArmorInventoryPage)); if (equipTo != null) { if (itemTo != null) { if (receivingPage.NeedsItemCheck) { Actions action = GetAction(sendingPage, itemFrom); if (action.CheckRequirements(cli.Character)) { UnEquip.Send(cli, receivingPage, toPlacement); if (!noAppearanceUpdate) { // Equipmentpages need delays // Delay when equipping/unequipping // has to be redone, jumping breaks the equiping/unequiping // and other messages have to be done too // like heartbeat timer, damage from environment and such delay = (itemFrom.GetAttribute(211) == 1234567890 ? 20 : itemFrom.GetAttribute(211)) + (itemTo.GetAttribute(211) == 1234567890 ? 20 : itemTo.GetAttribute(211)); } Thread.Sleep(delay * 10); // social has to wait for 0.2 secs too (for helmet update) cli.Character.Send(message); equipTo.HotSwap(sendingPage, fromPlacement, toPlacement); Equip.Send(cli, receivingPage, toPlacement); } } } else { if (receivingPage.NeedsItemCheck) { if (itemFrom == null) { throw new NullReferenceException("itemFrom can not be null, possible inventory error"); } Actions action = GetAction(receivingPage, itemFrom); if (action.CheckRequirements(cli.Character)) { if (!noAppearanceUpdate) { // Equipmentpages need delays // Delay when equipping/unequipping // has to be redone, jumping breaks the equiping/unequiping // and other messages have to be done too // like heartbeat timer, damage from environment and such delay = itemFrom.GetAttribute(211); if ((equipTo is SocialArmorInventoryPage) || (delay == 1234567890)) { delay = 20; } Thread.Sleep(delay * 10); } if (sendingPage == receivingPage) { // Switch rings for example UnEquip.Send(cli, sendingPage, fromPlacement); } cli.Character.Send(message); equipTo.Equip(sendingPage, fromPlacement, toPlacement); Equip.Send(cli, receivingPage, toPlacement); } } } } else { if (unequipFrom != null) { // Send to client first if (!noAppearanceUpdate) { // Equipmentpages need delays // Delay when equipping/unequipping // has to be redone, jumping breaks the equiping/unequiping // and other messages have to be done too // like heartbeat timer, damage from environment and such delay = itemFrom.GetAttribute(211); if ((unequipFrom is SocialArmorInventoryPage) || (delay == 1234567890)) { delay = 20; } Thread.Sleep(delay * 10); } UnEquip.Send(cli, sendingPage, fromPlacement); unequipFrom.Unequip(fromPlacement, receivingPage, toPlacement); cli.Character.Send(message); } else { // No equipment page involved, just send ContainerAddItemMessage back message.TargetPlacement = receivingPage.FindFreeSlot(); IItem item = sendingPage.Remove(fromPlacement); receivingPage.Add(message.TargetPlacement, item); cli.Character.Send(message); } } cli.Character.DoNotDoTimers = false; cli.Character.Stats.ClearChangedFlags(); // Apply item functions before sending the appearanceupdate message cli.Character.CalculateSkills(); if (!noAppearanceUpdate) { AppearanceUpdate.AnnounceAppearanceUpdate(cli.Character); } }
public static void AddItemToContainer(ContainerAddItemMessage message, Client cli) { var noAppearanceUpdate = false; /* Container ID's: * 0065 Weaponpage * 0066 Armorpage * 0067 Implantpage * 0068 Inventory (places 64-93) * 0069 Bank * 006B Backpack * 006C KnuBot Trade Window * 006E Overflow window * 006F Trade Window * 0073 Socialpage * 0767 Shop Inventory * 0790 Playershop Inventory * DEAD Trade Window (incoming) */ var fromContainerID = (int)message.SourceContainer.Type; var fromPlacement = message.SourceContainer.Instance; var toIdentity = message.Target; var toPlacement = message.TargetPlacement; // Where and what does need to be moved/added? IInventoryPage sendingPage = cli.Character.BaseInventory.Pages[fromContainerID]; IItem itemFrom = sendingPage[fromPlacement]; // Receiver of the item (IInstancedEntity, can be mostly all from NPC, Character or Bag, later even playfields) IItemContainer itemReceiver = cli.Playfield.FindByIdentity(toIdentity) as IItemContainer; if (itemReceiver == null) { throw new ArgumentOutOfRangeException("No Entity found: " + message.Target.Type.ToString() + ":" + message.Target.Instance); } // On which inventorypage should the item be added? IInventoryPage receivingPage = itemReceiver.BaseInventory.PageFromSlot(toPlacement); // Get standard page if toplacement cant be found (0x6F for next free slot) // TODO: If Entities are not the same (other player, bag etc) then always add to the standard page if (receivingPage == null) { receivingPage = itemReceiver.BaseInventory.Pages[itemReceiver.BaseInventory.StandardPage]; } if (receivingPage == null) { throw new ArgumentOutOfRangeException("No inventorypage found."); } if (toPlacement == 0x6f) { toPlacement = receivingPage.FindFreeSlot(); } // Is there already a item? IItem itemTo; try { itemTo = receivingPage[toPlacement]; } catch (Exception) { itemTo = null; } // Calculating delay for equip/unequip/switch gear var delay = 0; if (itemFrom != null) { delay += itemFrom.GetAttribute(211); } if (itemTo != null) { delay += itemTo.GetAttribute(211); } if (delay == 0) { delay = 200; } int counter; cli.Character.DoNotDoTimers = true; IItemSlotHandler equipTo = receivingPage as IItemSlotHandler; IItemSlotHandler unequipFrom = sendingPage as IItemSlotHandler; if (equipTo != null) { if (itemTo != null) { equipTo.HotSwap(sendingPage, fromPlacement, toPlacement); } else { equipTo.Equip(sendingPage, fromPlacement, toPlacement); } } else { if (unequipFrom != null) { unequipFrom.Unequip(fromPlacement, receivingPage, toPlacement); } } /* * switch (fromContainerID) * { * case 0x68: * * // from Inventory * if (toPlacement <= 30) * { * // to Weaponspage or Armorpage * // TODO: Send some animation * if (itemTo != null) * { * cli.Character.UnequipItem(itemTo, cli.Character, false, fromPlacement); * * // send interpolated item * Unequip.Send(cli, itemTo, InventoryPage(toPlacement), toPlacement); * * // client takes care of hotswap * cli.Character.EquipItem(itemFrom, cli.Character, false, toPlacement); * Equip.Send(cli, itemFrom, InventoryPage(toPlacement), toPlacement); * } * else * { * cli.Character.EquipItem(itemFrom, cli.Character, false, toPlacement); * Equip.Send(cli, itemFrom, InventoryPage(toPlacement), toPlacement); * } * } * else * { * if (toPlacement < 46) * { * if (itemTo == null) * { * cli.Character.EquipItem(itemFrom, cli.Character, false, toPlacement); * Equip.Send(cli, itemFrom, InventoryPage(toPlacement), toPlacement); * } * } * * // Equiping to social page * if ((toPlacement >= 49) && (toPlacement <= 63)) * { * if (itemTo != null) * { * cli.Character.UnequipItem(itemTo, cli.Character, true, fromPlacement); * * // send interpolated item * cli.Character.EquipItem(itemFrom, cli.Character, true, toPlacement); * } * else * { * cli.Character.EquipItem(itemFrom, cli.Character, true, toPlacement); * } * * // cli.Character.switchItems(cli, fromplacement, toplacement); * } * } * * cli.Character.SwitchItems(fromPlacement, toPlacement); * cli.Character.CalculateSkills(); * noAppearanceUpdate = false; * break; * case 0x66: * * // from Armorpage * cli.Character.UnequipItem(itemFrom, cli.Character, false, fromPlacement); * * // send interpolated item * Unequip.Send(cli, itemFrom, InventoryPage(fromPlacement), fromPlacement); * cli.Character.SwitchItems(fromPlacement, toPlacement); * cli.Character.CalculateSkills(); * noAppearanceUpdate = false; * break; * case 0x65: * * // from Weaponspage * cli.Character.UnequipItem(itemFrom, cli.Character, false, fromPlacement); * * // send interpolated item * Unequip.Send(cli, itemFrom, InventoryPage(fromPlacement), fromPlacement); * cli.Character.SwitchItems(fromPlacement, toPlacement); * cli.Character.CalculateSkills(); * noAppearanceUpdate = false; * break; * case 0x67: * * // from Implantpage * cli.Character.UnequipItem(itemFrom, cli.Character, false, fromPlacement); * * // send interpolated item * Unequip.Send(cli, itemFrom, InventoryPage(fromPlacement), fromPlacement); * cli.Character.SwitchItems(fromPlacement, toPlacement); * cli.Character.CalculateSkills(); * noAppearanceUpdate = true; * break; * case 0x73: * cli.Character.UnequipItem(itemFrom, cli.Character, true, fromPlacement); * * cli.Character.SwitchItems(fromPlacement, toPlacement); * cli.Character.CalculateSkills(); * break; * case 0x69: * cli.Character.TransferItemfromBank(fromPlacement, toPlacement); * toPlacement = 0x6f; // setting back to 0x6f for packet reply * noAppearanceUpdate = true; * break; * case 0x6c: * * // KnuBot Trade Window * cli.Character.TransferItemfromKnuBotTrade(fromPlacement, toPlacement); * break; * default: * break; * } * }*/ cli.Character.DoNotDoTimers = false; if ((equipTo != null) || (unequipFrom != null)) { // Equipmentpages need delays // Delay when equipping/unequipping // has to be redone, jumping breaks the equiping/unequiping // and other messages have to be done too // like heartbeat timer, damage from environment and such Thread.Sleep(delay); } else { Thread.Sleep(200); // social has to wait for 0.2 secs too (for helmet update) } /* * SwitchItem.Send( * cli, * fromContainerID, * fromPlacement, * new Identity { Type = toIdentity.Type, Instance = toIdentity.Instance }, * toPlacement); */ cli.Character.Stats.ClearChangedFlags(); if (!noAppearanceUpdate) { throw new NotImplementedException("TODO"); //cli.Character.AppearanceUpdate(); } itemFrom = null; itemTo = null; }
/// <summary> /// Swaps the items at the given slots without further checks. /// </summary> /// <param name="slot1"></param> /// <param name="slot2"></param> /// <remarks>Make sure the slots are valid before calling.</remarks> public void SwapUnchecked(BaseInventory cont1, int slot1, BaseInventory cont2, int slot2) { Item obj = cont1.m_Items[slot1]; Item otherItem = cont2.m_Items[slot2]; IItemSlotHandler handler1 = cont1.GetHandler(slot1); IItemSlotHandler handler2 = cont2.GetHandler(slot2); if (otherItem != null && obj.CanStackWith(otherItem) && otherItem.Amount < otherItem.Template.MaxAmount) { int num = Math.Min(obj.Template.MaxAmount - otherItem.Amount, obj.Amount); obj.Amount -= num; otherItem.Amount += num; } else { if (obj != null) { obj.Slot = slot2; if (handler1 != null) { handler1.Removed(slot1, obj); } } if (otherItem != null) { otherItem.Slot = slot1; if (handler2 != null) { handler2.Removed(slot2, otherItem); } } cont1.m_Items[slot1] = otherItem; cont2.m_Items[slot2] = obj; if (obj != null) { this.SetContainerEntityId(obj.EntityId, slot2, cont2); obj.Container = cont2; if (handler2 != null) { handler2.Added(obj); } } else { this.SetContainerEntityId(EntityId.Zero, slot2, cont2); } if (otherItem != null) { this.SetContainerEntityId(otherItem.EntityId, slot1, cont1); otherItem.Container = cont1; if (handler1 == null) { return; } handler1.Added(otherItem); } else { this.SetContainerEntityId(EntityId.Zero, slot1, cont1); } } }