/// <summary> /// Create a new <see cref="Item"/> in the first available <see cref="EquippedItem"/> bag index. /// </summary> public void ItemCreate(Item2Entry itemEntry) { if (itemEntry == null) { throw new ArgumentNullException(); } Item2TypeEntry typeEntry = GameTableManager.ItemType.GetEntry(itemEntry.Item2TypeId); if (typeEntry.ItemSlotId == 0) { throw new ArgumentException($"Item {itemEntry.Id} isn't equippable!"); } Bag bag = GetBag(InventoryLocation.Equipped); Debug.Assert(bag != null); // find first free bag index, some items can be equipped into multiple slots foreach (uint bagIndex in AssetManager.GetEquippedBagIndexes((ItemSlot)typeEntry.ItemSlotId)) { if (bag.GetItem(bagIndex) != null) { continue; } Item item = new Item(characterId, itemEntry); AddItem(item, InventoryLocation.Equipped, bagIndex); break; } }
/// <summary> /// Create a new <see cref="Inventory"/> from supplied <see cref="CharacterCreationEntry"/>. /// </summary> public Inventory(ulong owner, CharacterCreationEntry creationEntry) { characterId = owner; foreach ((InventoryLocation location, uint defaultCapacity) in AssetManager.InventoryLocationCapacities) { bags.Add(location, new Bag(location, defaultCapacity)); } foreach (uint itemId in creationEntry.ItemIds.Where(i => i != 0u)) { Item2Entry itemEntry = GameTableManager.Item.GetEntry(itemId); if (itemEntry == null) { throw new ArgumentNullException(); } Item2TypeEntry typeEntry = GameTableManager.ItemType.GetEntry(itemEntry.Item2TypeId); if (typeEntry.ItemSlotId == 0) { ItemCreate(itemEntry, 1u); } else { ItemCreate(itemEntry); } } }
/// <summary> /// Create a new <see cref="Item"/> in the first available inventory bag index or stack. /// </summary> public void ItemCreate(Item2Entry itemEntry, uint count, byte reason = 49, uint charges = 0) { if (itemEntry == null) { throw new ArgumentNullException(); } Bag bag = GetBag(InventoryLocation.Inventory); Debug.Assert(bag != null); // update any existing stacks before creating new items if (itemEntry.MaxStackCount > 1) { foreach (Item item in bag.Where(i => i.Entry.Id == itemEntry.Id)) { if (count == 0u) { break; } if (item.StackCount == itemEntry.MaxStackCount) { continue; } uint newStackCount = Math.Min(item.StackCount + count, itemEntry.MaxStackCount); count -= newStackCount - item.StackCount; ItemStackCountUpdate(item, newStackCount); } } // create new stacks for the remaining count while (count > 0) { uint bagIndex = bag.GetFirstAvailableBagIndex(); if (bagIndex == uint.MaxValue) { return; } var item = new Item(characterId, itemEntry, Math.Min(count, itemEntry.MaxStackCount), charges); AddItem(item, InventoryLocation.Inventory, bagIndex); if (!player?.IsLoading ?? false) { player.Session.EnqueueMessageEncrypted(new ServerItemAdd { InventoryItem = new InventoryItem { Item = item.BuildNetworkItem(), Reason = reason } }); } count -= item.StackCount; } }
/// <summary> /// Create a new <see cref="ItemInfo"/> from <see cref="Item2Entry"/> entry. /// </summary> public ItemInfo(Item2Entry entry) { Entry = entry; FamilyEntry = GameTableManager.Instance.Item2Family.GetEntry(Entry.Item2FamilyId); CategoryEntry = GameTableManager.Instance.Item2Category.GetEntry(Entry.Item2CategoryId); TypeEntry = GameTableManager.Instance.Item2Type.GetEntry(Entry.Item2TypeId); SlotEntry = GameTableManager.Instance.ItemSlot.GetEntry(TypeEntry.ItemSlotId); }
/// <summary> /// Create a new <see cref="Item"/> in the first available inventory bag index or stack. /// </summary> public void ItemCreate(uint itemId, uint count, byte reason = 49) { Item2Entry itemEntry = GameTableManager.Item.GetEntry(itemId); if (itemEntry == null) { throw new ArgumentNullException(); } ItemCreate(itemEntry, count, reason); }
/// <summary> /// Create a new <see cref="Item"/> in the first available <see cref="EquippedItem"/> bag index. /// </summary> public void ItemCreate(uint itemId) { Item2Entry itemEntry = GameTableManager.Item.GetEntry(itemId); if (itemEntry == null) { throw new ArgumentNullException(); } ItemCreate(itemEntry); }
/// <summary> /// Create a new <see cref="Item"/> in the first available inventory bag index or stack. /// </summary> public void ItemCreate(uint itemId, uint count, ItemUpdateReason reason = ItemUpdateReason.NoReason, uint charges = 0) { Item2Entry itemEntry = GameTableManager.Instance.Item.GetEntry(itemId); if (itemEntry == null) { throw new ArgumentNullException(); } ItemCreate(itemEntry, count, reason, charges); }
/// <summary> /// Create a new <see cref="Item"/> in the first available inventory bag index or stack. /// </summary> public void ItemCreate(uint itemId, uint count) { Item2Entry itemEntry = GameTableManager.Item.GetEntry(itemId); if (itemEntry == null) { throw new ArgumentNullException(); } Bag bag = GetBag(InventoryLocation.Inventory); Debug.Assert(bag != null); // update any existing stacks before creating new items if (itemEntry.MaxStackCount > 1) { foreach (Item item in bag.Where(i => i.Entry.Id == itemId)) { uint stackCount = Math.Min(itemEntry.MaxStackCount - item.StackCount, itemEntry.MaxStackCount); ItemStackCountUpdate(item, item.StackCount + stackCount); count -= stackCount; } } // create new stacks for the remaining count while (count > 0) { uint bagIndex = bag.GetFirstAvailableBagIndex(); if (bagIndex == uint.MaxValue) { return; } var item = new Item(characterId, itemEntry, Math.Min(count, itemEntry.MaxStackCount)); AddItem(item, InventoryLocation.Inventory, bagIndex); player.Session.EnqueueMessageEncrypted(new ServerItemAdd { InventoryItem = new InventoryItem { Item = item.BuildNetworkItem(), Reason = 49 } }); count -= item.StackCount; } }
public static void HandleVendorPurchase(WorldSession session, ClientVendorPurchase vendorPurchase) { VendorInfo vendorInfo = session.Player.SelectedVendorInfo; if (vendorInfo == null) { return; } EntityVendorItemModel vendorItem = vendorInfo.GetItemAtIndex(vendorPurchase.VendorIndex); if (vendorItem == null) { return; } Item2Entry itemEntry = GameTableManager.Instance.Item.GetEntry(vendorItem.ItemId); float costMultiplier = vendorInfo.BuyPriceMultiplier * vendorPurchase.VendorItemQty; // do all sanity checks before modifying currency var currencyChanges = new List <(CurrencyType CurrencyTypeId, ulong CurrencyAmount)>(); for (int i = 0; i < itemEntry.CurrencyTypeId.Length; i++) { CurrencyType currencyId = (CurrencyType)itemEntry.CurrencyTypeId[i]; if (currencyId == CurrencyType.None) { continue; } ulong currencyAmount = (ulong)(itemEntry.CurrencyAmount[i] * costMultiplier); if (!session.Player.CurrencyManager.CanAfford(currencyId, currencyAmount)) { return; } currencyChanges.Add((currencyId, currencyAmount)); } foreach ((CurrencyType currencyTypeId, ulong currencyAmount) in currencyChanges) { session.Player.CurrencyManager.CurrencySubtractAmount(currencyTypeId, currencyAmount); } session.Player.Inventory.ItemCreate(InventoryLocation.Inventory, itemEntry.Id, vendorPurchase.VendorItemQty * itemEntry.BuyFromVendorStackCount); }
public static void HandleVendorSell(WorldSession session, ClientVendorSell vendorSell) { VendorInfo vendorInfo = session.Player.SelectedVendorInfo; if (vendorInfo == null) { return; } Item2Entry itemEntry = session.Player.Inventory.GetItem(vendorSell.ItemLocation).Entry; if (itemEntry == null) { return; } float costMultiplier = vendorInfo.SellPriceMultiplier * vendorSell.Quantity; // do all sanity checks before modifying currency var currencyChange = new List <(CurrencyType CurrencyTypeId, ulong CurrencyAmount)>(); for (int i = 0; i < itemEntry.CurrencyTypeIdSellToVendor.Length; i++) { CurrencyType currencyId = (CurrencyType)itemEntry.CurrencyTypeIdSellToVendor[i]; if (currencyId == CurrencyType.None) { continue; } ulong currencyAmount = (ulong)(itemEntry.CurrencyAmountSellToVendor[i] * costMultiplier); currencyChange.Add((currencyId, currencyAmount)); } // TODO Insert calculation for cost here foreach ((CurrencyType currencyTypeId, ulong currencyAmount) in currencyChange) { session.Player.CurrencyManager.CurrencyAddAmount(currencyTypeId, currencyAmount); } // TODO Figure out why this is showing "You deleted [item]" Item soldItem = session.Player.Inventory.ItemDelete(vendorSell.ItemLocation); BuybackManager.AddItem(session.Player, soldItem, vendorSell.Quantity, currencyChange); }
/// <summary> /// Send mail to self from a creature. /// </summary> public void SendMail(uint creatureId, DeliveryTime time, uint subject, uint body, IEnumerable <uint> itemIds) { if (GameTableManager.Instance.Creature2.GetEntry(creatureId) == null) { throw new ArgumentException($"Invalid creature {creatureId} for mail sender!"); } if (GameTableManager.Instance.LocalizedText.GetEntry(subject) == null) { throw new ArgumentException($"Invalid localised text {subject} for mail subject!"); } if (GameTableManager.Instance.LocalizedText.GetEntry(body) == null) { throw new ArgumentException($"Invalid localised text {body} for mail body!"); } var parameters = new MailParameters { MessageType = SenderType.Creature, RecipientCharacterId = player.CharacterId, CreatureId = creatureId, SubjectStringId = subject, BodyStringId = body, DeliveryTime = time }; var items = new List <Item>(); foreach (uint itemId in itemIds) { Item2Entry itemEntry = GameTableManager.Instance.Item.GetEntry(itemId); if (itemEntry == null) { throw new ArgumentException($"Invalid item {itemId} for mail attachment!"); } var item = new Item(null, itemEntry); items.Add(item); } SendMail(parameters, items); }
/// <summary> /// Forget costume item unlock of supplied item id. /// </summary> public void ForgetItem(uint itemId) { Item2Entry itemEntry = GameTableManager.Item.GetEntry(itemId); if (itemEntry == null) { SendCostumeItemUnlock(CostumeUnlockResult.InvalidItem); return; } if (!costumeUnlocks.TryGetValue(itemId, out CostumeUnlock costumeUnlock)) { SendCostumeItemUnlock(CostumeUnlockResult.ForgetItemFailed); return; } costumeUnlock.EnqueueDelete(true); SendCostumeItemUnlock(CostumeUnlockResult.ForgetItemSuccess, itemId); }
/// <summary> /// Return the display id for <see cref="Item2Entry"/>. /// </summary> public static ushort GetDisplayId(Item2Entry entry) { if (entry == null) { return(0); } if (entry.ItemSourceId == 0u) { return((ushort)entry.ItemDisplayId); } List <ItemDisplaySourceEntryEntry> entries = AssetManager.GetItemDisplaySource(entry.ItemSourceId) .Where(e => e.Item2TypeId == entry.Item2TypeId) .ToList(); if (entries.Count == 1) { return((ushort)entries[0].ItemDisplayId); } // TODO: research this... throw new NotImplementedException(); }
/// <summary> /// Return the display id for <see cref="Item2Entry"/>. /// </summary> public static ushort GetDisplayId(Item2Entry entry) { if (entry == null) { return(0); } if (entry.ItemSourceId == 0u) { return((ushort)entry.ItemDisplayId); } List <ItemDisplaySourceEntryEntry> entries = AssetManager.Instance.GetItemDisplaySource(entry.ItemSourceId) .Where(e => e.Item2TypeId == entry.Item2TypeId) .ToList(); if (entries.Count == 1) { return((ushort)entries[0].ItemDisplayId); } else if (entries.Count > 1) { if (entry.ItemDisplayId > 0) { return((ushort)entry.ItemDisplayId); // This is what the preview window shows for "Frozen Wrangler Mitts" (Item2Id: 28366). } ItemDisplaySourceEntryEntry fallbackVisual = entries.FirstOrDefault(e => entry.PowerLevel >= e.ItemMinLevel && entry.PowerLevel <= e.ItemMaxLevel); if (fallbackVisual != null) { return((ushort)fallbackVisual.ItemDisplayId); } } // TODO: research this... throw new NotImplementedException(); }
/// <summary> /// Validate then save or update <see cref="Costume"/> from <see cref="ClientCostumeSave"/> packet. /// </summary> public void SaveCostume(ClientCostumeSave costumeSave) { // TODO: used for housing mannequins if (costumeSave.MannequinIndex != 0) { throw new NotImplementedException(); } if (costumeSave.Index < 0 || costumeSave.Index >= MaxCostumes) { SendCostumeSaveResult(CostumeSaveResult.InvalidCostumeIndex); return; } if (costumeSave.Index >= CostumeCap) { SendCostumeSaveResult(CostumeSaveResult.CostumeIndexNotUnlocked); return; } foreach (ClientCostumeSave.CostumeItem costumeItem in costumeSave.Items) { if (costumeItem.ItemId == 0) { continue; } Item2Entry itemEntry = GameTableManager.Item.GetEntry(costumeItem.ItemId); if (itemEntry == null) { SendCostumeSaveResult(CostumeSaveResult.InvalidItem); return; } // TODO: check item family /*if () * { * SendCostumeSaveResult(CostumeSaveResult.UnusableItem); * return; * }*/ if (!costumeUnlocks.ContainsKey(costumeItem.ItemId)) { SendCostumeSaveResult(CostumeSaveResult.ItemNotUnlocked); return; } ItemDisplayEntry itemDisplayEntry = GameTableManager.ItemDisplay.GetEntry(Item.GetDisplayId(itemEntry)); for (int i = 0; i < costumeItem.Dyes.Length; i++) { if (costumeItem.Dyes[i] == 0u) { continue; } if (itemDisplayEntry == null) { SendCostumeSaveResult(CostumeSaveResult.InvalidDye); return; } uint dyeChannelFlag = 1u << i; if ((itemDisplayEntry.DyeChannelFlags & dyeChannelFlag) == 0) { SendCostumeSaveResult(CostumeSaveResult.InvalidDye); return; } if (!player.Session.GenericUnlockManager.IsDyeUnlocked(costumeItem.Dyes[i])) { SendCostumeSaveResult(CostumeSaveResult.DyeNotUnlocked); return; } } } // TODO: charge player if (costumes.TryGetValue((byte)costumeSave.Index, out Costume costume)) { costume.Update(costumeSave); } else { costume = new Costume(player, costumeSave); costumes.Add(costume.Index, costume); } SetCostume((sbyte)costumeSave.Index, costume); SendCostume(costume); SendCostumeSaveResult(CostumeSaveResult.Saved, costumeSave.Index, costumeSave.MannequinIndex); }