diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index 9642baf3..c50510e1 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -1265,7 +1265,7 @@ namespace FFXIVClassic_Map_Server byte materia4 = reader.GetByte(11); byte materia5 = reader.GetByte(12); - items.Add(new InventoryItem(uniqueId, itemId, quantity, slot, itemType, qualityNumber, durability, spiritBind, materia1, materia2, materia3, materia4, materia5)); + items.Add(new InventoryItem(uniqueId, itemId, quantity, itemType, qualityNumber, durability, spiritBind, materia1, materia2, materia3, materia4, materia5)); } } } @@ -1282,7 +1282,7 @@ namespace FFXIVClassic_Map_Server return items; } - public static InventoryItem AddItem(Player player, uint itemId, int quantity, byte quality, byte itemType, int durability, ushort type) + public static InventoryItem CreateItem(uint itemId, int quantity, byte quality, byte itemType, int durability) { InventoryItem insertedItem = null; @@ -1303,27 +1303,52 @@ namespace FFXIVClassic_Map_Server MySqlCommand cmd = new MySqlCommand(query, conn); - string query2 = @" - INSERT INTO characters_inventory - (characterId, slot, inventoryType, serverItemId, quantity) - SELECT @charId, IFNULL(MAX(SLOT)+1, 0), @inventoryType, LAST_INSERT_ID(), @quantity FROM characters_inventory WHERE characterId = @charId AND inventoryType = @inventoryType; - "; - - MySqlCommand cmd2 = new MySqlCommand(query2, conn); - cmd.Parameters.AddWithValue("@itemId", itemId); cmd.Parameters.AddWithValue("@quality", quality); cmd.Parameters.AddWithValue("@itemType", itemType); cmd.Parameters.AddWithValue("@durability", durability); - cmd2.Parameters.AddWithValue("@charId", player.actorId); - cmd2.Parameters.AddWithValue("@inventoryType", type); - cmd2.Parameters.AddWithValue("@quantity", quantity); - cmd.ExecuteNonQuery(); - cmd2.ExecuteNonQuery(); - insertedItem = new InventoryItem((uint)cmd.LastInsertedId, itemId, quantity, (ushort)player.GetInventory(type).GetNextEmptySlot(), itemType, quality, durability, 0, 0, 0, 0, 0, 0); + insertedItem = new InventoryItem((uint)cmd.LastInsertedId, itemId, quantity, itemType, quality, durability, 0, 0, 0, 0, 0, 0); + } + catch (MySqlException e) + { + Program.Log.Error(e.ToString()); + } + finally + { + conn.Dispose(); + } + } + + return insertedItem; + } + + public static InventoryItem AddItem(Player player, InventoryItem addedItem, uint type) + { + InventoryItem insertedItem = null; + + using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) + { + try + { + conn.Open(); + + string query = @" + INSERT INTO characters_inventory + (characterId, slot, inventoryType, serverItemId, quantity) + SELECT @charId, IFNULL(MAX(SLOT)+1, 0), @inventoryType, @uid, @quantity FROM characters_inventory WHERE characterId = @charId AND inventoryType = @inventoryType; + "; + + MySqlCommand cmd = new MySqlCommand(query, conn); + + cmd.Parameters.AddWithValue("@uid", addedItem.uniqueId); + cmd.Parameters.AddWithValue("@charId", player.actorId); + cmd.Parameters.AddWithValue("@inventoryType", type); + cmd.Parameters.AddWithValue("@quantity", insertedItem.quantity); + + cmd.ExecuteNonQuery(); } catch (MySqlException e) { diff --git a/FFXIVClassic Map Server/actors/chara/player/Equipment.cs b/FFXIVClassic Map Server/actors/chara/player/Equipment.cs index 702af284..9c311e12 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Equipment.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Equipment.cs @@ -106,13 +106,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.player for (int i = 0; i < slots.Length; i++) { - InventoryItem item = normalInventory.GetItemBySlot(itemSlots[i]); + InventoryItem item = normalInventory.GetItemAtSlot(itemSlots[i]); if (item == null) continue; Database.EquipItem(owner, slots[i], item.uniqueId); - list[slots[i]] = normalInventory.GetItemBySlot(itemSlots[i]); + list[slots[i]] = normalInventory.GetItemAtSlot(itemSlots[i]); } owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); @@ -133,7 +133,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player public void Equip(ushort slot, ushort invSlot) { - InventoryItem item = normalInventory.GetItemBySlot(invSlot); + InventoryItem item = normalInventory.GetItemAtSlot(invSlot); if (item == null) return; diff --git a/FFXIVClassic Map Server/actors/chara/player/Inventory.cs b/FFXIVClassic Map Server/actors/chara/player/Inventory.cs index bcd82d56..f9d8493f 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Inventory.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Inventory.cs @@ -20,14 +20,19 @@ namespace FFXIVClassic_Map_Server.actors.chara.player public const ushort CURRENCY = 0x0063; //Max 0x140 public const ushort KEYITEMS = 0x0064; //Max 0x500 public const ushort EQUIPMENT = 0x00FE; //Max 0x23 - public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23 + public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23 + + private int endOfListIndex = 0; - private Player owner; + private Character owner; + private List viewer; private ushort inventoryCapacity; private ushort inventoryCode; - private List list; - - public Inventory(Player ownerPlayer, ushort capacity, ushort code) + private InventoryItem[] list; + private InventoryItem[] lastList; + private bool[] isDirty; + + public Inventory(Character ownerPlayer, ushort capacity, ushort code) { owner = ownerPlayer; inventoryCapacity = capacity; @@ -37,12 +42,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.player #region Inventory Management public void InitList(List itemsFromDB) { - list = itemsFromDB; + int i = 0; + foreach (InventoryItem item in itemsFromDB) + list[i++] = item; } - public InventoryItem GetItemBySlot(ushort slot) + public InventoryItem GetItemAtSlot(ushort slot) { - if (slot < list.Count) + if (slot < list.Length) return list[slot]; else return null; @@ -66,28 +73,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player return item; } return null; - } - - public void RefreshItem(InventoryItem item) - { - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - SendInventoryPackets(item); - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - } - - public void RefreshItem(params InventoryItem[] items) - { - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - SendInventoryPackets(items.ToList()); - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - } - - public void RefreshItem(List items) - { - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - SendInventoryPackets(items); - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - } + } public void AddItem(uint itemId) { @@ -105,9 +91,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player return false; ItemData gItem = Server.GetItemGamedata(itemId); - List slotsToUpdate = new List(); - List addItemPackets = new List(); - + if (gItem == null) { Program.Log.Error("Inventory.AddItem: unable to find item %u", itemId); @@ -115,15 +99,19 @@ namespace FFXIVClassic_Map_Server.actors.chara.player } //Check if item id exists - int quantityCount = quantity; - for (int i = 0; i < list.Count; i++) + int quantityCount = quantity; + for (int i = 0; i < endOfListIndex; i++) { - InventoryItem item = list[i]; + InventoryItem item = list[i]; + + if (item == null) + throw new Exception("Item slot was null!!!"); + if (item.itemId == itemId && item.quantity < gItem.maxStack) { - slotsToUpdate.Add(item.slot); int oldQuantity = item.quantity; - item.quantity = Math.Min(item.quantity + quantityCount, gItem.maxStack); + item.quantity = Math.Min(item.quantity + quantityCount, gItem.maxStack); + isDirty[i] = true; quantityCount -= (gItem.maxStack - oldQuantity); if (quantityCount <= 0) break; @@ -136,68 +124,20 @@ namespace FFXIVClassic_Map_Server.actors.chara.player //If Inventory is full //if (quantityCount > 0 && isInventoryFull()) - // return ITEMERROR_FULL; - - //Update lists and db - owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - - //These had their quantities Changed - foreach (ushort slot in slotsToUpdate) - { - Database.SetQuantity(owner, slot, inventoryCode, list[slot].quantity); - - if (inventoryCode != CURRENCY && inventoryCode != KEYITEMS) - SendInventoryPackets(list[slot]); - } + // return ITEMERROR_FULL; //New item that spilled over while (quantityCount > 0) { - InventoryItem addedItem = Database.AddItem(owner, itemId, Math.Min(quantityCount, gItem.maxStack), quality, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability, inventoryCode); - - - list.Add(addedItem); - - if (inventoryCode != CURRENCY && inventoryCode != KEYITEMS) - SendInventoryPackets(addedItem); - + InventoryItem addedItem = Database.CreateItem(itemId, Math.Min(quantityCount, gItem.maxStack), quality, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability); + isDirty[endOfListIndex] = true; + list[endOfListIndex++] = addedItem; quantityCount -= gItem.maxStack; } - if (inventoryCode == CURRENCY || inventoryCode == KEYITEMS) - SendFullInventory(); - - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); return true; } - public void AddItem(uint[] itemId) - { - if (!IsSpaceForAdd(itemId[0], itemId.Length)) - return; - - //Update lists and db - owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - - int startPos = list.Count; - - //New item that spilled over - for (int i = 0; i < itemId.Length; i++) - { - ItemData gItem = Server.GetItemGamedata(itemId[i]); - InventoryItem addedItem = Database.AddItem(owner, itemId[i], 1, (byte)1, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability, inventoryCode); - list.Add(addedItem); - } - - SendInventoryPackets(startPos); - - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); - } - public void RemoveItem(uint itemId, int quantity) { if (!HasItem(itemId, quantity)) @@ -211,23 +151,24 @@ namespace FFXIVClassic_Map_Server.actors.chara.player //Remove as we go along int quantityCount = quantity; ushort lowestSlot = 0; - for (int i = list.Count - 1; i >= 0; i--) + for (int i = endOfListIndex - 1; i >= 0; i--) { - InventoryItem item = list[i]; + InventoryItem item = list[i]; + + if (item == null) + throw new Exception("Item slot was null!!!"); + if (item.itemId == itemId) { int oldQuantity = item.quantity; //Stack nomnomed - if (item.quantity - quantityCount <= 0) - { - itemsToRemove.Add(item); - slotsToRemove.Add(item.slot); - } - else - { - slotsToUpdate.Add(item.slot); - item.quantity -= quantityCount; //Stack reduced - } + if (item.quantity - quantityCount <= 0) + list[i] = null; + //Stack reduced + else + item.quantity -= quantityCount; + + isDirty[i] = true; quantityCount -= oldQuantity; lowestSlot = item.slot; @@ -235,43 +176,10 @@ namespace FFXIVClassic_Map_Server.actors.chara.player if (quantityCount <= 0) break; } - } + } + + doRealign(); - for (int i = 0; i < slotsToUpdate.Count; i++) - { - Database.SetQuantity(owner, slotsToUpdate[i], inventoryCode, list[slotsToUpdate[i]].quantity); - } - - int oldListSize = list.Count; - for (int i = 0; i < itemsToRemove.Count; i++) - { - Database.RemoveItem(owner, itemsToRemove[i].uniqueId, inventoryCode); - list.Remove(itemsToRemove[i]); - } - - //Realign slots - for (int i = lowestSlot; i < list.Count; i++) - list[i].slot = (ushort)i; - - //Added tail end items that need to be cleared for slot realignment - for (int i = oldListSize-1; i >= oldListSize - itemsToRemove.Count; i--) - { - if (!slotsToRemove.Contains((ushort)i)) - slotsToRemove.Add((ushort)i); - } - - owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - - SendInventoryPackets(lowestSlot); - SendInventoryRemovePackets(slotsToRemove); - - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - - if (inventoryCode == NORMAL) - owner.GetEquipment().SendFullEquipment(false); - - owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); } public void RemoveItemByUniqueId(ulong itemDBId) @@ -291,58 +199,19 @@ namespace FFXIVClassic_Map_Server.actors.chara.player if (toDelete == null) return; - int oldListSize = list.Count; - list.RemoveAt(slot); - Database.RemoveItem(owner, itemDBId, inventoryCode); - - //Realign slots - for (int i = slot; i < list.Count; i++) - list[i].slot = (ushort)i; - - owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - - SendInventoryPackets(slot); - SendInventoryRemovePackets(slot); - if (slot != oldListSize - 1) - SendInventoryRemovePackets((ushort)(oldListSize - 1)); - - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - - if (inventoryCode == NORMAL) - owner.GetEquipment().SendFullEquipment(false); - - owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); - + list[slot] = null; + isDirty[slot] = true; + doRealign(); } public void RemoveItemAtSlot(ushort slot) { - if (slot >= list.Count) + if (slot >= endOfListIndex) return; - - int oldListSize = list.Count; - list.RemoveAt((int)slot); - Database.RemoveItem(owner, slot, inventoryCode); - - //Realign slots - for (int i = slot; i < list.Count; i++) - list[i].slot = (ushort)i; - - owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - - SendInventoryPackets(slot); - SendInventoryRemovePackets(slot); - if (slot != oldListSize - 1) - SendInventoryRemovePackets((ushort)(oldListSize - 1)); - - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - - if (inventoryCode == NORMAL) - owner.GetEquipment().SendFullEquipment(false); - - owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); + + list[slot] = null; + isDirty[slot] = true; + doRealign(); } public void ChangeDurability(uint slot, uint durabilityChange) @@ -362,90 +231,92 @@ namespace FFXIVClassic_Map_Server.actors.chara.player #endregion #region Packet Functions - public void SendFullInventory() - { - owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); - SendInventoryPackets(0); - owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); - } - - private void SendInventoryPackets(InventoryItem item) - { - owner.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, item)); - } - - private void SendInventoryPackets(List items) + public void SendFullInventory(Player player) + { + player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); + SendInventoryPackets(player, 0); + player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); + } + + private void SendInventoryPackets(Player player, InventoryItem item) + { + player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, item)); + } + + private void SendInventoryPackets(Player player, List items) { int currentIndex = 0; while (true) { - if (items.Count - currentIndex >= 64) - owner.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, items, ref currentIndex)); - else if (items.Count - currentIndex >= 32) - owner.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, items, ref currentIndex)); - else if (items.Count - currentIndex >= 16) - owner.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, items, ref currentIndex)); - else if (items.Count - currentIndex > 1) - owner.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, items, ref currentIndex)); + if (items.Count - currentIndex >= 64) + player.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, items, ref currentIndex)); + else if (items.Count - currentIndex >= 32) + player.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, items, ref currentIndex)); + else if (items.Count - currentIndex >= 16) + player.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, items, ref currentIndex)); + else if (items.Count - currentIndex > 1) + player.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, items, ref currentIndex)); else if (items.Count - currentIndex == 1) - { - owner.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, items[currentIndex])); + { + player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, items[currentIndex])); currentIndex++; } else break; } - } - - private void SendInventoryPackets(int startOffset) + } + + private void SendInventoryPackets(Player player, int startOffset) { - int currentIndex = startOffset; + int currentIndex = startOffset; + + List lst = new List(list); while (true) { - if (list.Count - currentIndex >= 64) - owner.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, list, ref currentIndex)); - else if (list.Count - currentIndex >= 32) - owner.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, list, ref currentIndex)); - else if (list.Count - currentIndex >= 16) - owner.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, list, ref currentIndex)); - else if (list.Count - currentIndex > 1) - owner.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, list, ref currentIndex)); - else if (list.Count - currentIndex == 1) - { - owner.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, list[currentIndex])); + if (endOfListIndex - currentIndex >= 64) + player.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, lst, ref currentIndex)); + else if (endOfListIndex - currentIndex >= 32) + player.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, lst, ref currentIndex)); + else if (endOfListIndex - currentIndex >= 16) + player.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, lst, ref currentIndex)); + else if (endOfListIndex - currentIndex > 1) + player.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, lst, ref currentIndex)); + else if (endOfListIndex - currentIndex == 1) + { + player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, list[currentIndex])); currentIndex++; } else break; } - } - - private void SendInventoryRemovePackets(ushort index) + } + + private void SendInventoryRemovePackets(Player player, ushort index) { - owner.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, index)); - } + player.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, index)); + } - private void SendInventoryRemovePackets(List indexes) + private void SendInventoryRemovePackets(Player player, List indexes) { int currentIndex = 0; while (true) { - if (indexes.Count - currentIndex >= 64) - owner.QueuePacket(InventoryRemoveX64Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); - else if (indexes.Count - currentIndex >= 32) - owner.QueuePacket(InventoryRemoveX32Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); - else if (indexes.Count - currentIndex >= 16) - owner.QueuePacket(InventoryRemoveX16Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); - else if (indexes.Count - currentIndex > 1) - owner.QueuePacket(InventoryRemoveX08Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); + if (indexes.Count - currentIndex >= 64) + player.QueuePacket(InventoryRemoveX64Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); + else if (indexes.Count - currentIndex >= 32) + player.QueuePacket(InventoryRemoveX32Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); + else if (indexes.Count - currentIndex >= 16) + player.QueuePacket(InventoryRemoveX16Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); + else if (indexes.Count - currentIndex > 1) + player.QueuePacket(InventoryRemoveX08Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); else if (indexes.Count - currentIndex == 1) - { - owner.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, indexes[currentIndex])); + { + player.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, indexes[currentIndex])); currentIndex++; } else @@ -454,19 +325,47 @@ namespace FFXIVClassic_Map_Server.actors.chara.player } - #endregion - - #region Inventory Utils - + #endregion + + #region Client Updating + private void SendUpdatePackets(Player player) + { + List items = new List(); + List slotsToRemove = new List(); + + for (int i = 0; i < list.Length; i++) + { + if (i == endOfListIndex) + break; + if (isDirty[i]) + items.Add(list[i]); + } + + for (int i = endOfListIndex; i < lastList.Length; i++) + { + if (lastList[i] != null) + slotsToRemove.Add((ushort)i); + } + + //Send Updated Slots + SendInventoryPackets(player, items); + + //Send Remove packets for tail end + SendInventoryRemovePackets(player, slotsToRemove); + } + #endregion + + #region Inventory Utils + public bool IsFull() { - return list.Count >= inventoryCapacity; + return endOfListIndex >= inventoryCapacity; } public bool IsSpaceForAdd(uint itemId, int quantity) { - int quantityCount = quantity; - for (int i = 0; i < list.Count; i++) + int quantityCount = quantity; + for (int i = 0; i < endOfListIndex; i++) { InventoryItem item = list[i]; ItemData gItem = Server.GetItemGamedata(item.itemId); @@ -503,8 +402,33 @@ namespace FFXIVClassic_Map_Server.actors.chara.player } public int GetNextEmptySlot() - { - return list.Count == 0 ? 0 : list.Count(); + { + return endOfListIndex; + } + + private void doRealign() + { + int lastNullSlot = -1; + + for (int i = 0; i < endOfListIndex; i++) + { + if (list[i] == null && lastNullSlot != -1) + { + lastNullSlot = i; + continue; + } + else if (list[i] != null && lastNullSlot != -1) + { + list[lastNullSlot] = list[i]; + list[lastNullSlot].slot = (ushort)lastNullSlot; + list[i] = null; + isDirty[lastNullSlot] = true; + isDirty[i] = true; + lastNullSlot++; + } + } + + endOfListIndex = lastNullSlot; } #endregion diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 1e0ab866..c1ddd5d5 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -533,12 +533,12 @@ namespace FFXIVClassic_Map_Server.Actors #region Inventory & Equipment QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId)); - inventories[Inventory.NORMAL].SendFullInventory(); - inventories[Inventory.CURRENCY].SendFullInventory(); - inventories[Inventory.KEYITEMS].SendFullInventory(); - inventories[Inventory.BAZAAR].SendFullInventory(); - inventories[Inventory.MELDREQUEST].SendFullInventory(); - inventories[Inventory.LOOT].SendFullInventory(); + inventories[Inventory.NORMAL].SendFullInventory(this); + inventories[Inventory.CURRENCY].SendFullInventory(this); + inventories[Inventory.KEYITEMS].SendFullInventory(this); + inventories[Inventory.BAZAAR].SendFullInventory(this); + inventories[Inventory.MELDREQUEST].SendFullInventory(this); + inventories[Inventory.LOOT].SendFullInventory(this); equipment.SendFullEquipment(false); playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId)); #endregion diff --git a/FFXIVClassic Map Server/dataobjects/InventoryItem.cs b/FFXIVClassic Map Server/dataobjects/InventoryItem.cs index 318ff875..13c51499 100644 --- a/FFXIVClassic Map Server/dataobjects/InventoryItem.cs +++ b/FFXIVClassic Map Server/dataobjects/InventoryItem.cs @@ -23,12 +23,11 @@ namespace FFXIVClassic_Map_Server.dataobjects public byte materia5 = 0; //Bare Minimum - public InventoryItem(uint id, uint itemId, ushort slot) + public InventoryItem(uint id, uint itemId) { this.uniqueId = id; this.itemId = itemId; this.quantity = 1; - this.slot = slot; ItemData gItem = Server.GetItemGamedata(itemId); itemType = gItem.isExclusive ? (byte)0x3 : (byte)0x0; @@ -55,12 +54,11 @@ namespace FFXIVClassic_Map_Server.dataobjects this.materia5 = item.materia5; } - public InventoryItem(uint uniqueId, uint itemId, int quantity, ushort slot, byte itemType, byte qualityNumber, int durability, ushort spiritbind, byte materia1, byte materia2, byte materia3, byte materia4, byte materia5) + public InventoryItem(uint uniqueId, uint itemId, int quantity, byte itemType, byte qualityNumber, int durability, ushort spiritbind, byte materia1, byte materia2, byte materia3, byte materia4, byte materia5) { this.uniqueId = uniqueId; this.itemId = itemId; this.quantity = quantity; - this.slot = slot; this.itemType = itemType; this.quality = qualityNumber; this.durability = durability;