/// <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> /// Checks if supplied <see cref="InventoryLocation"/> and bag index valid for <see cref="Item"/>. /// </summary> private bool IsValidLocationForItem(Item item, InventoryLocation location, uint bagIndex) { Bag bag = GetBag(location); if (bag == null) { return(false); } if (location == InventoryLocation.Equipped) { Item2TypeEntry typeEntry = GameTableManager.ItemType.GetEntry(item.Entry.Item2TypeId); if (typeEntry.ItemSlotId == 0) { return(false); } ImmutableList <EquippedItem> bagIndexes = AssetManager.GetEquippedBagIndexes((ItemSlot)typeEntry.ItemSlotId); if (bagIndexes.All(i => i != (EquippedItem)bagIndex)) { return(false); } /*if (owner.Character.Class != item.Entry.ClassRequired) * return false; * * if (owner.Character.Race != item.Entry.RaceRequired) * return false;*/ } return(true); }
/// <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> /// Update <see cref="ItemVisual"/> and broadcast <see cref="ServerItemVisualUpdate"/> for supplied <see cref="Item"/> /// </summary> private void VisualUpdate(Item item) { if (item == null) { throw new ArgumentNullException(); } var itemVisualUpdate = new ServerItemVisualUpdate { Guid = player.Guid }; Item2TypeEntry typeEntry = GameTableManager.ItemType.GetEntry(item.Entry.Item2TypeId); Costume costume = null; if (player.CostumeIndex >= 0) { costume = player.CostumeManager.GetCostume((byte)player.CostumeIndex); } itemVisualUpdate.ItemVisuals.Add(VisualUpdate((ItemSlot)typeEntry.ItemSlotId, costume)); if (!player.IsLoading) { player.EnqueueToVisible(itemVisualUpdate, true); } }
/// <summary> /// Returns <see cref="ItemVisual"/> for any visible items. /// </summary> public IEnumerable <ItemVisual> GetItemVisuals() { Bag bag = GetBag(InventoryLocation.Equipped); Debug.Assert(bag != null); foreach (Item item in bag) { ushort displayId = item.DisplayId; if (displayId == 0) { continue; } Item2TypeEntry itemTypeEntry = GameTableManager.ItemType.GetEntry(item.Entry.Item2TypeId); yield return(new ItemVisual { Slot = (ItemSlot)itemTypeEntry.ItemSlotId, DisplayId = displayId, // TODO: send colour and dye data ColourSetId = 0, DyeData = 0 }); } }
/// <summary> /// Broadcast <see cref="ServerItemVisualUpdate"/> for supplied <see cref="Item"/>, this will update the players look in the world. /// </summary> private void SendItemVisualUpdate(Item item) { if (item == null) { throw new ArgumentNullException(); } Item2TypeEntry typeEntry = GameTableManager.ItemType.GetEntry(item.Entry.Item2TypeId); if (typeEntry.ItemSlotId == 0) { throw new ArgumentException($"Item {item.Entry.Id} isn't equippable!"); } if (!player?.IsLoading ?? false) { bool visible = item.Location != InventoryLocation.None; player.EnqueueToVisible(new ServerItemVisualUpdate { Guid = player.Guid, ItemVisuals = new List <ItemVisual> { new ItemVisual { Slot = (ItemSlot)typeEntry.ItemSlotId, DisplayId = (ushort)(visible ? item.DisplayId : 0), // TODO: send colour and dye data ColourSetId = 0, DyeData = 0 } } }, true); } }
/// <summary> /// Returns <see cref="ItemVisual"/> for any visible items. /// </summary> public IEnumerable <ItemVisual> GetItemVisuals(Costume costume) { Bag bag = GetBag(InventoryLocation.Equipped); Debug.Assert(bag != null); foreach (Item item in bag) { Item2TypeEntry itemTypeEntry = GameTableManager.ItemType.GetEntry(item.Entry.Item2TypeId); ItemVisual visual = GetItemVisual((ItemSlot)itemTypeEntry.ItemSlotId, costume); if (visual != null) { yield return(visual); } } }