diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs
index 872c6e74..96877f0e 100644
--- a/FFXIVClassic Map Server/Database.cs
+++ b/FFXIVClassic Map Server/Database.cs
@@ -1117,7 +1117,7 @@ namespace FFXIVClassic_Map_Server
player.GetItemPackage(ItemPackage.MELDREQUEST).InitList(GetItemPackage(player, 0, ItemPackage.MELDREQUEST));
player.GetItemPackage(ItemPackage.LOOT).InitList(GetItemPackage(player, 0, ItemPackage.LOOT));
- player.GetEquipment().SetEquipment(GetEquipment(player, player.charaWork.parameterSave.state_mainSkill[0]));
+ player.GetEquipment().SetList(GetEquipment(player, player.charaWork.parameterSave.state_mainSkill[0]));
}
catch (MySqlException e)
{
@@ -1131,9 +1131,12 @@ namespace FFXIVClassic_Map_Server
}
- public static InventoryItem[] GetEquipment(Player player, ushort classId)
+ public static uint[] GetEquipment(Player player, ushort classId)
{
- InventoryItem[] equipment = new InventoryItem[player.GetEquipment().GetCapacity()];
+ uint[] equipment = new uint[player.GetEquipment().GetCapacity()];
+
+ for (int i = 0; i < equipment.Length; i++)
+ equipment[i] = 0xFFFFFFFF;
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)))
{
@@ -1159,7 +1162,7 @@ namespace FFXIVClassic_Map_Server
ushort equipSlot = reader.GetUInt16(0);
ulong uniqueItemId = reader.GetUInt16(1);
InventoryItem item = player.GetItemPackage(ItemPackage.NORMAL).GetItemByUniqueId(uniqueItemId);
- equipment[equipSlot] = item;
+ equipment[equipSlot] = (uint)((item.itemPackage << 16) | item.slot);
}
}
}
@@ -1195,7 +1198,7 @@ namespace FFXIVClassic_Map_Server
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@characterId", player.actorId);
- cmd.Parameters.AddWithValue("@classId", (equipSlot == Equipment.SLOT_UNDERSHIRT || equipSlot == Equipment.SLOT_UNDERGARMENT) ? 0 : player.charaWork.parameterSave.state_mainSkill[0]);
+ cmd.Parameters.AddWithValue("@classId", (equipSlot == Player.SLOT_UNDERSHIRT || equipSlot == Player.SLOT_UNDERGARMENT) ? 0 : player.charaWork.parameterSave.state_mainSkill[0]);
cmd.Parameters.AddWithValue("@equipSlot", equipSlot);
cmd.Parameters.AddWithValue("@uniqueItemId", uniqueItemId);
diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
index 00b528b2..5105d83c 100644
--- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
+++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
@@ -139,8 +139,8 @@
-
+
@@ -240,9 +240,6 @@
-
-
-
@@ -254,14 +251,17 @@
-
+
+
+
+
+
-
diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/FFXIVClassic Map Server/actors/chara/Character.cs
index 94e0ca78..3246848a 100644
--- a/FFXIVClassic Map Server/actors/chara/Character.cs
+++ b/FFXIVClassic Map Server/actors/chara/Character.cs
@@ -135,7 +135,7 @@ namespace FFXIVClassic_Map_Server.Actors
//Inventory
protected Dictionary itemPackages = new Dictionary();
- protected Equipment equipment;
+ protected ReferencedItemPackage equipment;
public Character(uint actorID)
: base(actorID)
@@ -1147,7 +1147,7 @@ namespace FFXIVClassic_Map_Server.Actors
return;
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
- itemPackages[(ushort)id].SendFullInventory(player);
+ itemPackages[(ushort)id].SendUpdate(player);
player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
diff --git a/FFXIVClassic Map Server/actors/chara/Equipment.cs b/FFXIVClassic Map Server/actors/chara/Equipment.cs
deleted file mode 100644
index fae856ef..00000000
--- a/FFXIVClassic Map Server/actors/chara/Equipment.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-using FFXIVClassic_Map_Server.Actors;
-using FFXIVClassic_Map_Server.dataobjects;
-using FFXIVClassic_Map_Server.packets.send.actor.inventory;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-namespace FFXIVClassic_Map_Server.actors.chara.player
-{
- ///
- /// This class stores the current equipment that a Player has equipped on themselves. Technically
- /// it is an ItemPackage like other inventories, however due to how this one operates, it is in
- /// it's own class. While on the server this is stored as a list of InventoryItems like other
- /// ItemPackages, on the client it exists as a link to the "normal inventory" package. The Equipment list
- /// therefore is a list of slot values (the slots in the inventory), with each position in the list being
- /// a position on the paper doll (in the game's Gear menu).
- ///
- class Equipment
- {
- public const int SLOT_MAINHAND = 0;
- public const int SLOT_OFFHAND = 1;
- public const int SLOT_THROWINGWEAPON = 4;
- public const int SLOT_PACK = 5;
- public const int SLOT_POUCH = 6;
- public const int SLOT_HEAD = 8;
- public const int SLOT_UNDERSHIRT = 9;
- public const int SLOT_BODY = 10;
- public const int SLOT_UNDERGARMENT = 11;
- public const int SLOT_LEGS = 12;
- public const int SLOT_HANDS = 13;
- public const int SLOT_BOOTS = 14;
- public const int SLOT_WAIST = 15;
- public const int SLOT_NECK = 16;
- public const int SLOT_EARS = 17;
- public const int SLOT_WRISTS = 19;
- public const int SLOT_RIGHTFINGER = 21;
- public const int SLOT_LEFTFINGER = 22;
-
- private const ushort EQUIP_ITEMPACKAGE_CAPACITY = 0x23;
- private const ushort EQUIP_ITEMPACKAGE_CODE = ItemPackage.EQUIPMENT;
-
- readonly private InventoryItem[] list = new InventoryItem[EQUIP_ITEMPACKAGE_CAPACITY];
-
- readonly private Player owner;
- readonly private ItemPackage normalInventory;
-
- private bool writeToDB = true;
-
- /// The player client that owns this ItemPackage.
- /// A reference to the normal inventory ItemPackage this equipment ItemPackage links to.
- public Equipment(Player ownerPlayer, ItemPackage normalInventory)
- {
- owner = ownerPlayer;
- this.normalInventory = normalInventory;
- }
-
- ///
- /// Sets the full equipment ItemPackage to the given list. 's length must
- /// equal EQUIP_ITEMPACKAGE_CAPACITY. Used to initialize the list when loading from the DB.
- ///
- /// The list of inventory items to set the full list to.
- public void SetEquipment(InventoryItem[] toEquip)
- {
- Debug.Assert(toEquip.Length == EQUIP_ITEMPACKAGE_CAPACITY);
- toEquip.CopyTo(list, 0);
- }
-
- ///
- /// Sets the given equipSlots to link to the given itemSlots. The lengths of both must be equal.
- ///
- /// The list of equipmentSlots that get linked.
- /// The list of itemSlots that the equipSlots will link to.
- public void SetEquipment(ushort[] equipSlots, ushort[] itemSlots)
- {
- if (equipSlots.Length != itemSlots.Length)
- return;
-
- for (int i = 0; i < equipSlots.Length; i++)
- {
- InventoryItem item = normalInventory.GetItemAtSlot(itemSlots[i]);
-
- if (item == null)
- continue;
-
- Database.EquipItem(owner, equipSlots[i], item.uniqueId);
- list[equipSlots[i]] = normalInventory.GetItemAtSlot(itemSlots[i]);
- }
-
- owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
- SendFullEquipment(owner);
- owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
- }
-
- ///
- /// Equips the item at the given item slot to the given equipment slot.
- ///
- /// The equipment slot being equipped.
- /// The inventory slot of where the equipped item is.
- public void Equip(ushort equipSlot, ushort invSlot)
- {
- InventoryItem item = normalInventory.GetItemAtSlot(invSlot);
-
- if (item == null)
- return;
-
- Equip(equipSlot, item);
- }
-
- ///
- /// Equips the given inventory item to the given equipment slot.
- ///
- /// The equipment slot being equipped.
- /// The inventory item being equiped.
- public void Equip(ushort equipSlot, InventoryItem item)
- {
- if (equipSlot >= list.Length)
- return;
-
- if (writeToDB)
- Database.EquipItem(owner, equipSlot, item.uniqueId);
-
- owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
-
- if (list[equipSlot] != null)
- normalInventory.RefreshItem(owner, list[equipSlot], item);
- else
- normalInventory.RefreshItem(owner, item);
-
- list[equipSlot] = item;
-
- owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, EQUIP_ITEMPACKAGE_CAPACITY, EQUIP_ITEMPACKAGE_CODE));
- SendSingleEquipmentUpdatePacket(equipSlot);
- owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
-
- owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
-
- owner.CalculateBaseStats();// RecalculateStats();
- }
-
- ///
- /// Toggles if equipment changes are saved to the DB.
- ///
- /// If true, equipment changes are saved to the db.
- public void ToggleDBWrite(bool flag)
- {
- writeToDB = flag;
- }
-
- ///
- /// Removes the linked item at the given .
- ///
- /// The slot that is being cleared.
- public void Unequip(ushort equipSlot)
- {
- if (equipSlot >= list.Length)
- return;
-
- if (writeToDB)
- Database.UnequipItem(owner, equipSlot);
-
- owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
- normalInventory.RefreshItem(owner, list[equipSlot]);
- list[equipSlot] = null;
- SendSingleEquipmentUpdatePacket(equipSlot);
- owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
-
- owner.RecalculateStats();
- }
-
- ///
- /// Returns the item equipped at the given .
- ///
- /// The slot to retrieve from.
- public InventoryItem GetItemAtSlot(ushort equipSlot)
- {
- if (equipSlot < list.Length)
- return list[equipSlot];
- else
- return null;
- }
-
- ///
- /// Returns the capacity of this ItemPackage.
- ///
- public int GetCapacity()
- {
- return list.Length;
- }
-
- #region Packet Functions
-
- ///
- /// Syncs the client the link status of a single equipment slot. If the item was null,
- /// sends a delete packet instead.
- ///
- /// The slot we are updating the client about.
- private void SendSingleEquipmentUpdatePacket(ushort equipSlot)
- {
- owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, EQUIP_ITEMPACKAGE_CAPACITY, EQUIP_ITEMPACKAGE_CODE));
- if (list[equipSlot] == null)
- owner.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, equipSlot));
- else
- owner.QueuePacket(EquipmentListX01Packet.BuildPacket(owner.actorId, equipSlot, list[equipSlot].slot));
- owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
- }
-
- ///
- /// Syncs the full list of equipped items to the client owner of this ItemPackage. Used on login/zone in.
- ///
- public void SendFullEquipment()
- {
- SendFullEquipment(owner);
- }
-
- ///
- /// Syncs the full list of equipped items to a given target. Used to send the equipment list of this ItemPackage to the owner,
- /// or in the case of examining another player, sends the list of this ItemPackage to the player client examining. A different
- /// ItemPackage Code is used for /checking.
- ///
- /// The player client that is being synced.
- public void SendFullEquipment(Player targetPlayer)
- {
- List slotsToUpdate = new List();
-
- for (ushort i = 0; i < list.Length; i++)
- {
- if (list[i] != null)
- slotsToUpdate.Add(i);
- }
-
- if (targetPlayer.Equals(owner))
- targetPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, EQUIP_ITEMPACKAGE_CAPACITY, EQUIP_ITEMPACKAGE_CODE));
- else
- targetPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, 0x23, ItemPackage.EQUIPMENT_OTHERPLAYER));
-
- SendEquipmentPackets(slotsToUpdate, targetPlayer);
-
- targetPlayer.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
- }
-
- ///
- /// Main sync function. Syncs the given targetPlayer client the link status of multiple equipment slots.
- ///
- /// The slots that will be synced.
- /// The player client that is being synced.
- private void SendEquipmentPackets(List slotsToUpdate, Player targetPlayer)
- {
- int currentIndex = 0;
-
- while (true)
- {
- if (slotsToUpdate.Count - currentIndex >= 64)
- targetPlayer.QueuePacket(EquipmentListX64Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
- else if (slotsToUpdate.Count - currentIndex >= 32)
- targetPlayer.QueuePacket(EquipmentListX32Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
- else if (slotsToUpdate.Count - currentIndex >= 16)
- targetPlayer.QueuePacket(EquipmentListX16Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
- else if (slotsToUpdate.Count - currentIndex > 1)
- targetPlayer.QueuePacket(EquipmentListX08Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
- else if (slotsToUpdate.Count - currentIndex == 1)
- {
- targetPlayer.QueuePacket(EquipmentListX01Packet.BuildPacket(owner.actorId, slotsToUpdate[currentIndex], list[slotsToUpdate[currentIndex]].slot));
- currentIndex++;
- }
- else
- break;
- }
- }
-
- #endregion
- }
-}
diff --git a/FFXIVClassic Map Server/actors/chara/ItemPackage.cs b/FFXIVClassic Map Server/actors/chara/ItemPackage.cs
index dd543dc6..ed964671 100644
--- a/FFXIVClassic Map Server/actors/chara/ItemPackage.cs
+++ b/FFXIVClassic Map Server/actors/chara/ItemPackage.cs
@@ -6,7 +6,6 @@ using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
namespace FFXIVClassic_Map_Server.actors.chara.player
{
@@ -22,7 +21,17 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public const ushort EQUIPMENT = 0x00FE; //Max 0x23
public const ushort TRADE = 0x00FD; //Max 0x04
public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23
-
+
+ public const ushort MAXSIZE_NORMAL = 200;
+ public const ushort MAXSIZE_CURRANCY = 320;
+ public const ushort MAXSIZE_KEYITEMS = 500;
+ public const ushort MAXSIZE_LOOT = 10;
+ public const ushort MAXSIZE_TRADE = 4;
+ public const ushort MAXSIZE_MELDREQUEST = 4;
+ public const ushort MAXSIZE_BAZAAR = 10;
+ public const ushort MAXSIZE_EQUIPMENT = 35;
+ public const ushort MAXSIZE_EQUIPMENT_OTHERPLAYER = 0x23;
+
public enum INV_ERROR {
SUCCESS = 0,
INVENTORY_FULL,
@@ -170,7 +179,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
list[endOfListIndex++] = itemRef;
DoDatabaseAdd(itemRef);
- SendUpdatePackets();
+ SendUpdate();
return INV_ERROR.SUCCESS;
}
@@ -233,7 +242,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
DoDatabaseAdd(addedItem);
}
- SendUpdatePackets();
+ SendUpdate();
return INV_ERROR.SUCCESS;
}
@@ -241,7 +250,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public void SetItem(ushort slot, InventoryItem item)
{
list[slot] = item;
- SendUpdatePackets();
+ SendUpdate();
item.RefreshPositioning(owner, itemPackageCode, slot);
}
@@ -300,7 +309,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
}
DoRealign();
- SendUpdatePackets();
+ SendUpdate();
}
public void RemoveItem(InventoryItem item)
@@ -349,7 +358,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
isDirty[slot] = true;
DoRealign();
- SendUpdatePackets();
+ SendUpdate();
}
public void RemoveItemAtSlot(ushort slot)
@@ -364,7 +373,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
isDirty[slot] = true;
DoRealign();
- SendUpdatePackets();
+ SendUpdate();
}
public void RemoveItemAtSlot(ushort slot, int quantity)
@@ -388,7 +397,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
DoDatabaseQuantity(list[slot].uniqueId, list[slot].quantity);
isDirty[slot] = true;
- SendUpdatePackets();
+ SendUpdate();
}
}
@@ -402,7 +411,20 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
}
endOfListIndex = 0;
- SendUpdatePackets();
+ SendUpdate();
+ }
+
+ public void MarkDirty(InventoryItem item)
+ {
+ if (item.itemPackage != itemPackageCode || list[item.slot] == null)
+ return;
+
+ isDirty[item.slot] = true;
+ }
+
+ public void MarkDirty(ushort slot)
+ {
+ isDirty[slot] = true;
}
public InventoryItem[] GetRawList()
@@ -427,19 +449,61 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
#endregion
#region Packet Functions
- public void SendFullInventory(Player player)
+ public void SendFullPackage(Player player)
{
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
- SendInventoryPackets(player, 0);
+ SendItemPackets(player, 0);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
- private void SendInventoryPackets(Player player, InventoryItem item)
+ public void SendUpdate()
+ {
+ if (owner is Player && !holdingUpdates)
+ {
+ SendUpdate((Player)owner);
+ }
+ }
+
+ public void SendUpdate(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 < list.Length; i++)
+ {
+ if (isDirty[i])
+ slotsToRemove.Add((ushort)i);
+ }
+
+ if (!holdingUpdates)
+ Array.Clear(isDirty, 0, isDirty.Length);
+
+ player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
+ //Send Updated Slots
+ SendItemPackets(player, items);
+ //Send Remove packets for tail end
+ SendItemPackets(player, slotsToRemove);
+ player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
+ //If player is updating their normal inventory, we need to send
+ //an equip update as well to resync the slots.
+ if (player.Equals(owner) && itemPackageCode == NORMAL)
+ player.GetEquipment().SendUpdate();
+ }
+
+ private void SendItemPackets(Player player, InventoryItem item)
{
player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, item));
}
- private void SendInventoryPackets(Player player, List items)
+ private void SendItemPackets(Player player, List items)
{
int currentIndex = 0;
@@ -463,7 +527,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
}
}
- private void SendInventoryPackets(Player player, int startOffset)
+ private void SendItemPackets(Player player, int startOffset)
{
int currentIndex = startOffset;
@@ -491,12 +555,12 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
}
}
- private void SendInventoryRemovePackets(Player player, ushort index)
+ private void SendItemPackets(Player player, ushort index)
{
player.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, index));
}
- private void SendInventoryRemovePackets(Player player, List indexes)
+ private void SendItemPackets(Player player, List indexes)
{
int currentIndex = 0;
@@ -519,28 +583,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
break;
}
}
-
- public void RefreshItem(Player player, InventoryItem item)
- {
- player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
- SendInventoryPackets(player, item);
- player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
- }
-
- public void RefreshItem(Player player, params InventoryItem[] items)
- {
- player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
- SendInventoryPackets(player, items.ToList());
- player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
- }
-
- public void RefreshItem(Player player, List items)
- {
- player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
- SendInventoryPackets(player, items);
- player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
- }
-
#endregion
#region Automatic Client and DB Updating
@@ -584,51 +626,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
else if (owner is Retainer)
Database.RemoveItem((Retainer)owner, itemDBId);
}
-
- private void SendUpdatePackets()
- {
- if (owner is Player && !holdingUpdates)
- {
- SendUpdatePackets((Player)owner);
- }
- }
-
- public 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 < list.Length; i++)
- {
- if (isDirty[i])
- slotsToRemove.Add((ushort)i);
- }
-
- if (!holdingUpdates)
- Array.Clear(isDirty, 0, isDirty.Length);
-
- player.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
- player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
- //Send Updated Slots
- SendInventoryPackets(player, items);
- //Send Remove packets for tail end
- SendInventoryRemovePackets(player, slotsToRemove);
- player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
- //If player is updating their normal inventory, we need to send
- //an equip update as well to resync the slots.
- if (player.Equals(owner) && itemPackageCode == NORMAL)
- player.GetEquipment().SendFullEquipment();
- player.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
- }
-
+
public void StartSendUpdate()
{
holdingUpdates = true;
@@ -637,7 +635,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public void DoneSendUpdate()
{
holdingUpdates = false;
- SendUpdatePackets();
+ SendUpdate();
Array.Clear(isDirty, 0, isDirty.Length);
}
diff --git a/FFXIVClassic Map Server/actors/chara/ReferencedItemPackage.cs b/FFXIVClassic Map Server/actors/chara/ReferencedItemPackage.cs
new file mode 100644
index 00000000..2a8e492b
--- /dev/null
+++ b/FFXIVClassic Map Server/actors/chara/ReferencedItemPackage.cs
@@ -0,0 +1,312 @@
+using FFXIVClassic_Map_Server.actors.chara.player;
+using FFXIVClassic_Map_Server.Actors;
+using FFXIVClassic_Map_Server.dataobjects;
+using FFXIVClassic_Map_Server.packets.send.actor.inventory;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace FFXIVClassic_Map_Server.actors.chara
+{
+
+ class ReferencedItemPackage
+ {
+ const uint EMPTY = 0xFFFFFFFF;
+
+ private readonly Player owner;
+ private readonly uint[] contentList;
+ private readonly ushort itemPackageCode;
+ private readonly ushort itemPackageCapacity;
+ private bool writeToDB = false;
+
+ public ReferencedItemPackage(Player owner, ushort capacity, ushort code)
+ {
+ this.owner = owner;
+ itemPackageCode = code;
+ itemPackageCapacity = capacity;
+ contentList = new uint[capacity];
+
+ if (code == ItemPackage.EQUIPMENT)
+ writeToDB = true;
+
+ for (int i = 0; i < contentList.Length; i++)
+ contentList[i] = EMPTY;
+ }
+
+ public void ToggleDBWrite(bool flag)
+ {
+ writeToDB = flag;
+ }
+
+ #region Package Management
+ public void SetList(uint[] toSet)
+ {
+ Debug.Assert(contentList.Length == itemPackageCapacity);
+ toSet.CopyTo(contentList, 0);
+ }
+
+ public void SetList(ushort[] positions, uint[] values)
+ {
+ Debug.Assert(positions.Length == values.Length);
+
+ for (int i = 0; i < positions.Length; i++)
+ {
+ InventoryItem item = GetItem(values[i]);
+
+ if (item == null)
+ continue;
+
+ //Database.EquipItem(owner, positions[i], item.uniqueId);
+ contentList[positions[i]] = values[i];
+ }
+
+ owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
+ SendUpdate();
+ owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
+ }
+
+ public void Set(ushort position, ushort itemPackagePosition, ushort itemPackageCode)
+ {
+ InventoryItem item = owner.GetItemPackage(itemPackageCode).GetItemAtSlot(itemPackagePosition);
+
+ if (item == null)
+ return;
+
+ Set(position, item);
+ }
+
+ public void Set(ushort position, InventoryItem item)
+ {
+ if (position >= contentList.Length)
+ return;
+
+ if (writeToDB)
+ Database.EquipItem(owner, position, item.uniqueId);
+
+ ItemPackage newPackage = owner.GetItemPackage(item.itemPackage);
+ ItemPackage oldPackage = GetItemPackage(contentList[position]);
+ InventoryItem oldItem = GetItem(contentList[position]);
+
+ if (oldPackage != null && oldItem != null)
+ oldPackage.MarkDirty(oldItem);
+ newPackage.MarkDirty(item);
+
+ contentList[position] = GetValue(item.itemPackage, item.slot);
+
+ owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
+ if (oldPackage != null)
+ oldPackage.SendUpdate();
+ newPackage.SendUpdate();
+ SendSingleUpdate(position);
+ owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
+
+ owner.CalculateBaseStats();// RecalculateStats();
+ }
+
+ public void Clear(ushort position)
+ {
+ if (position >= contentList.Length)
+ return;
+
+ if (writeToDB)
+ Database.UnequipItem(owner, position);
+
+ ItemPackage oldItemPackage = GetItemPackage(contentList[position]);
+
+ oldItemPackage.MarkDirty(GetItem(contentList[position]));
+ contentList[position] = EMPTY;
+
+ owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
+ oldItemPackage.SendUpdate();
+ SendSingleUpdate(position);
+ owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
+
+ owner.RecalculateStats();
+ }
+
+ public void ClearAll()
+ {
+ List packagesToRefresh = new List();
+
+ for (int i = 0; i < contentList.Length; i++)
+ {
+ if (contentList[i] == EMPTY)
+ continue;
+
+ if (writeToDB)
+ Database.UnequipItem(owner, (ushort)i);
+
+ ItemPackage package = GetItemPackage(contentList[i]);
+ package.MarkDirty(GetItem(contentList[i]));
+ packagesToRefresh.Add(package);
+
+ contentList[i] = EMPTY;
+ }
+
+ owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
+ for (int i = 0; i < packagesToRefresh.Count; i++)
+ packagesToRefresh[i].SendUpdate();
+ SendUpdate();
+ owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
+
+ owner.RecalculateStats();
+ }
+ #endregion
+
+ #region Send Update Functions
+ public void SendSingleUpdate(ushort position)
+ {
+ owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
+ SendSingleLinkedItemPacket(owner, position);
+ owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
+ }
+
+ public void SendUpdate()
+ {
+ SendUpdate(owner);
+ }
+
+ public void SendUpdate(Player targetPlayer)
+ {
+ List slotsToUpdate = new List();
+
+ for (ushort i = 0; i < contentList.Length; i++)
+ {
+ if (contentList[i] != EMPTY)
+ slotsToUpdate.Add(i);
+ }
+
+ targetPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
+ SendLinkedItemPackets(targetPlayer, slotsToUpdate);
+ targetPlayer.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
+ }
+
+ public void SendUpdateAsItemPackage(Player targetPlayer)
+ {
+ SendUpdateAsItemPackage(targetPlayer, itemPackageCapacity, itemPackageCode);
+ }
+
+ public void SendUpdateAsItemPackage(Player targetPlayer, ushort destinationCapacity, ushort destinationCode)
+ {
+ List items = new List();
+
+ for (int i = 0; i < contentList.Length; i++)
+ {
+ if (contentList[i] == EMPTY)
+ continue;
+ items.Add(GetItem(contentList[i]));
+ }
+
+ targetPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, destinationCapacity, destinationCode));
+ SendItemPackets(targetPlayer, items);
+ targetPlayer.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
+ }
+ #endregion
+
+ #region Packet Functions (Private)
+ private void SendSingleLinkedItemPacket(Player targetPlayer, ushort position)
+ {
+ if (contentList[position] == EMPTY)
+ targetPlayer.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, position));
+ else
+ targetPlayer.QueuePacket(LinkedItemListX01Packet.BuildPacket(owner.actorId, position, contentList[position]));
+ }
+
+ private void SendLinkedItemPackets(Player targetPlayer, List slotsToUpdate)
+ {
+ int currentIndex = 0;
+
+ while (true)
+ {
+ if (slotsToUpdate.Count - currentIndex >= 64)
+ targetPlayer.QueuePacket(LinkedItemListX64Packet.BuildPacket(owner.actorId, contentList, slotsToUpdate, ref currentIndex));
+ else if (slotsToUpdate.Count - currentIndex >= 32)
+ targetPlayer.QueuePacket(LinkedItemListX32Packet.BuildPacket(owner.actorId, contentList, slotsToUpdate, ref currentIndex));
+ else if (slotsToUpdate.Count - currentIndex >= 16)
+ targetPlayer.QueuePacket(LinkedItemListX16Packet.BuildPacket(owner.actorId, contentList, slotsToUpdate, ref currentIndex));
+ else if (slotsToUpdate.Count - currentIndex > 1)
+ targetPlayer.QueuePacket(LinkedItemListX08Packet.BuildPacket(owner.actorId, contentList, slotsToUpdate, ref currentIndex));
+ else if (slotsToUpdate.Count - currentIndex == 1)
+ {
+ targetPlayer.QueuePacket(LinkedItemListX01Packet.BuildPacket(owner.actorId, slotsToUpdate[currentIndex], contentList[slotsToUpdate[currentIndex]]));
+ currentIndex++;
+ }
+ else
+ break;
+ }
+ }
+
+ private void SendItemPackets(Player player, List items)
+ {
+ int currentIndex = 0;
+
+ while (true)
+ {
+ 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)
+ {
+ player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, items[currentIndex]));
+ currentIndex++;
+ }
+ else
+ break;
+ }
+ }
+ #endregion
+
+ #region Getters/Setters
+ public ushort GetCode()
+ {
+ return itemPackageCode;
+ }
+
+ public int GetCapacity()
+ {
+ return itemPackageCapacity;
+ }
+
+ public Player GetOwner()
+ {
+ return owner;
+ }
+
+ public InventoryItem GetItemAtSlot(ushort position)
+ {
+ if (position < contentList.Length)
+ return GetItem(contentList[position]);
+ else
+ return null;
+ }
+ #endregion
+
+ #region Utils
+ private ItemPackage GetItemPackage(uint value)
+ {
+ if (value == EMPTY)
+ return null;
+ return owner.GetItemPackage((ushort)((value >> 16) & 0xFFFF));
+ }
+
+ private InventoryItem GetItem(uint value)
+ {
+ if (value == EMPTY)
+ return null;
+ ItemPackage package = GetItemPackage(value);
+ if (package != null)
+ return package.GetItemAtSlot((ushort)(value & 0xFFFF));
+ return null;
+ }
+
+ private uint GetValue(ushort code, ushort slot)
+ {
+ return (uint) ((code << 16) | slot);
+ }
+ #endregion
+ }
+}
diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs
index 00b85cdf..8c213784 100644
--- a/FFXIVClassic Map Server/actors/chara/player/Player.cs
+++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs
@@ -23,19 +23,12 @@ using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.packets.receive.events;
+using static FFXIVClassic_Map_Server.LuaUtils;
namespace FFXIVClassic_Map_Server.Actors
{
class Player : Character
{
- public const int MAXSIZE_INVENTORY_NORMAL = 200;
- public const int MAXSIZE_INVENTORY_CURRANCY = 320;
- public const int MAXSIZE_INVENTORY_KEYITEMS = 500;
- public const int MAXSIZE_INVENTORY_LOOT = 10;
- public const int MAXSIZE_INVENTORY_MELDREQUEST = 4;
- public const int MAXSIZE_INVENTORY_BAZAAR = 10;
- public const int MAXSIZE_INVENTORY_EQUIPMENT = 35;
-
public const int TIMER_TOTORAK = 0;
public const int TIMER_DZEMAEL = 1;
public const int TIMER_BOWL_OF_EMBERS_HARD = 2;
@@ -62,6 +55,25 @@ namespace FFXIVClassic_Map_Server.Actors
public const int NPCLS_ACTIVE = 2;
public const int NPCLS_ALERT = 3;
+ public const int SLOT_MAINHAND = 0;
+ public const int SLOT_OFFHAND = 1;
+ public const int SLOT_THROWINGWEAPON = 4;
+ public const int SLOT_PACK = 5;
+ public const int SLOT_POUCH = 6;
+ public const int SLOT_HEAD = 8;
+ public const int SLOT_UNDERSHIRT = 9;
+ public const int SLOT_BODY = 10;
+ public const int SLOT_UNDERGARMENT = 11;
+ public const int SLOT_LEGS = 12;
+ public const int SLOT_HANDS = 13;
+ public const int SLOT_BOOTS = 14;
+ public const int SLOT_WAIST = 15;
+ public const int SLOT_NECK = 16;
+ public const int SLOT_EARS = 17;
+ public const int SLOT_WRISTS = 19;
+ public const int SLOT_RIGHTFINGER = 21;
+ public const int SLOT_LEFTFINGER = 22;
+
public static int[] MAXEXP = {570, 700, 880, 1100, 1500, 1800, 2300, 3200, 4300, 5000, //Level <= 10
5900, 6800, 7700, 8700, 9700, 11000, 12000, 13000, 15000, 16000, //Level <= 20
20000, 22000, 23000, 25000, 27000, 29000, 31000, 33000, 35000, 38000, //Level <= 30
@@ -85,9 +97,8 @@ namespace FFXIVClassic_Map_Server.Actors
//Trading
private Player otherTrader = null;
- private ItemPackage myOfferings;
+ private ReferencedItemPackage myOfferings;
private bool isTradeAccepted = false;
- private bool isTradeLocked = false;
//GC Related
public byte gcCurrent;
@@ -143,14 +154,13 @@ namespace FFXIVClassic_Map_Server.Actors
moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
- itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, MAXSIZE_INVENTORY_NORMAL, ItemPackage.NORMAL);
- itemPackages[ItemPackage.KEYITEMS] = new ItemPackage(this, MAXSIZE_INVENTORY_KEYITEMS, ItemPackage.KEYITEMS);
- itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, MAXSIZE_INVENTORY_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
- itemPackages[ItemPackage.MELDREQUEST] = new ItemPackage(this, MAXSIZE_INVENTORY_MELDREQUEST, ItemPackage.MELDREQUEST);
- itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, MAXSIZE_INVENTORY_BAZAAR, ItemPackage.BAZAAR);
- itemPackages[ItemPackage.LOOT] = new ItemPackage(this, MAXSIZE_INVENTORY_LOOT, ItemPackage.LOOT);
-
- equipment = new Equipment(this, itemPackages[ItemPackage.NORMAL]);
+ itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, ItemPackage.MAXSIZE_NORMAL, ItemPackage.NORMAL);
+ itemPackages[ItemPackage.KEYITEMS] = new ItemPackage(this, ItemPackage.MAXSIZE_KEYITEMS, ItemPackage.KEYITEMS);
+ itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, ItemPackage.MAXSIZE_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
+ itemPackages[ItemPackage.MELDREQUEST] = new ItemPackage(this, ItemPackage.MAXSIZE_MELDREQUEST, ItemPackage.MELDREQUEST);
+ itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, ItemPackage.MAXSIZE_BAZAAR, ItemPackage.BAZAAR);
+ itemPackages[ItemPackage.LOOT] = new ItemPackage(this, ItemPackage.MAXSIZE_LOOT, ItemPackage.LOOT);
+ equipment = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT, ItemPackage.EQUIPMENT);
//Set the Skill level caps of all FFXIV (classes)skills to 50
for (int i = 0; i < charaWork.battleSave.skillLevelCap.Length; i++)
@@ -531,13 +541,13 @@ namespace FFXIVClassic_Map_Server.Actors
#region Inventory & Equipment
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
- itemPackages[ItemPackage.NORMAL].SendFullInventory(this);
- itemPackages[ItemPackage.CURRENCY_CRYSTALS].SendFullInventory(this);
- itemPackages[ItemPackage.KEYITEMS].SendFullInventory(this);
- itemPackages[ItemPackage.BAZAAR].SendFullInventory(this);
- itemPackages[ItemPackage.MELDREQUEST].SendFullInventory(this);
- itemPackages[ItemPackage.LOOT].SendFullInventory(this);
- equipment.SendFullEquipment();
+ itemPackages[ItemPackage.NORMAL].SendFullPackage(this);
+ itemPackages[ItemPackage.CURRENCY_CRYSTALS].SendFullPackage(this);
+ itemPackages[ItemPackage.KEYITEMS].SendFullPackage(this);
+ itemPackages[ItemPackage.BAZAAR].SendFullPackage(this);
+ itemPackages[ItemPackage.MELDREQUEST].SendFullPackage(this);
+ itemPackages[ItemPackage.LOOT].SendFullPackage(this);
+ equipment.SendUpdate(this);
playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
#endregion
@@ -972,7 +982,7 @@ namespace FFXIVClassic_Map_Server.Actors
return max;
}
- public InventoryItem[] GetGearset(ushort classId)
+ public uint[] GetGearset(ushort classId)
{
return Database.GetEquipment(this, classId);
}
@@ -1190,7 +1200,7 @@ namespace FFXIVClassic_Map_Server.Actors
return isZoneChanging;
}
- public Equipment GetEquipment()
+ public ReferencedItemPackage GetEquipment()
{
return equipment;
}
@@ -1674,18 +1684,10 @@ namespace FFXIVClassic_Map_Server.Actors
else
return;
- QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId));
- toBeExamined.GetEquipment().SendFullEquipment(this);
+ QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId, true));
+ toBeExamined.GetEquipment().SendUpdateAsItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT_OTHERPLAYER, ItemPackage.EQUIPMENT_OTHERPLAYER);
QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId));
- }
-
- public void SendMyTradeToPlayer(Player player)
- {
- ItemPackage tradeInventory = new ItemPackage(this, 4, ItemPackage.TRADE);
- player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
- tradeInventory.SendFullInventory(player);
- player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
- }
+ }
public void SendDataPacket(params object[] parameters)
{
@@ -2618,7 +2620,7 @@ namespace FFXIVClassic_Map_Server.Actors
base.CalculateBaseStats();
//Add weapon property mod
var equip = GetEquipment();
- var mainHandItem = equip.GetItemAtSlot(Equipment.SLOT_MAINHAND);
+ var mainHandItem = equip.GetItemAtSlot(SLOT_MAINHAND);
var damageAttribute = 0;
var attackDelay = 3000;
var hitCount = 1;
@@ -2631,7 +2633,7 @@ namespace FFXIVClassic_Map_Server.Actors
hitCount = mainHandWeapon.frequency;
}
- var hasShield = equip.GetItemAtSlot(Equipment.SLOT_OFFHAND) != null ? 1 : 0;
+ var hasShield = equip.GetItemAtSlot(SLOT_OFFHAND) != null ? 1 : 0;
SetMod((uint)Modifier.HasShield, hasShield);
SetMod((uint)Modifier.AttackType, damageAttribute);
@@ -2699,14 +2701,7 @@ namespace FFXIVClassic_Map_Server.Actors
public void StartTradeTransaction(Player otherPlayer)
{
- myOfferings = new ItemPackage(this, 4, ItemPackage.TRADE, true);
- ItemPackage otherPlayerOfferings = new ItemPackage(otherPlayer, 4, ItemPackage.TRADE, true);
-
- myOfferings.StartSendUpdate();
- myOfferings.SendUpdatePackets(this);
- myOfferings.SendUpdatePackets(otherPlayer);
- myOfferings.DoneSendUpdate();
-
+ myOfferings = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_TRADE, ItemPackage.TRADE);
otherTrader = otherPlayer;
isTradeAccepted = false;
}
@@ -2716,7 +2711,7 @@ namespace FFXIVClassic_Map_Server.Actors
return otherTrader;
}
- public ItemPackage GetTradeOfferings()
+ public ReferencedItemPackage GetTradeOfferings()
{
return myOfferings;
}
@@ -2730,53 +2725,59 @@ namespace FFXIVClassic_Map_Server.Actors
{
return isTradeAccepted;
}
-
- public void AddTradeItem(ushort slot, ushort linkedSlot, int subquantity)
- {
- if (!IsTrading())
- return;
-
- InventoryItem mine = itemPackages[ItemPackage.NORMAL].GetItemAtSlot(linkedSlot);
-
- InventoryItem tradeItem = new InventoryItem(mine, slot);
-
- myOfferings.StartSendUpdate();
- myOfferings.AddItem(mine.itemId, mine.quantity, mine.quality);
- myOfferings.SendUpdatePackets(otherTrader);
- myOfferings.DoneSendUpdate();
- }
-
- public void AddTradeGil(int quantity)
+
+ public void AddTradeItem(ushort slot, ItemRefParam chosenItem, int tradeQuantity)
{
if (!IsTrading())
return;
- myOfferings.StartSendUpdate();
- myOfferings.AddItem(1000001, quantity, 1);
- myOfferings.SendUpdatePackets(otherTrader);
- myOfferings.DoneSendUpdate();
+ //Get chosen item
+ InventoryItem offeredItem = itemPackages[chosenItem.itemPackage].GetItemAtSlot(chosenItem.slot);
+ offeredItem.SetTradeQuantity(tradeQuantity);
+
+ myOfferings.Set(slot, offeredItem);
+ SendTradePackets();
}
-
+
public void RemoveTradeItem(ushort slot)
- {
- if (!IsTrading())
- return;
-
- myOfferings.StartSendUpdate();
- myOfferings.RemoveItemAtSlot(slot);
- myOfferings.SendUpdatePackets(otherTrader);
- myOfferings.DoneSendUpdate();
- }
-
- public void ClearTradeItems(ushort slot)
{
if (!IsTrading())
return;
- myOfferings.StartSendUpdate();
- myOfferings.Clear();
- myOfferings.SendUpdatePackets(otherTrader);
- myOfferings.DoneSendUpdate();
+ InventoryItem offeredItem = myOfferings.GetItemAtSlot(slot);
+ offeredItem.SetNormal();
+
+ myOfferings.Clear(slot);
+ SendTradePackets();
+ }
+
+ public void ClearTradeItems()
+ {
+ if (!IsTrading())
+ return;
+
+ for (ushort i = 0; i < myOfferings.GetCapacity(); i++)
+ {
+ InventoryItem offeredItem = myOfferings.GetItemAtSlot(i);
+ if (offeredItem != null)
+ offeredItem.SetNormal();
+ }
+
+ myOfferings.ClearAll();
+ SendTradePackets();
+ }
+
+ private void SendTradePackets()
+ {
+ //Send to self
+ QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
+ myOfferings.SendUpdate(this);
+ QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
+
+ //Send to other trader
+ otherTrader.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
+ myOfferings.SendUpdateAsItemPackage(otherTrader);
+ otherTrader.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
public void AcceptTrade(bool accepted)
@@ -2788,31 +2789,25 @@ namespace FFXIVClassic_Map_Server.Actors
public void FinishTradeTransaction()
{
+ if (myOfferings != null)
+ {
+ myOfferings.ClearAll();
+ for (ushort i = 0; i < myOfferings.GetCapacity(); i++)
+ {
+ InventoryItem offeredItem = myOfferings.GetItemAtSlot(i);
+ if (offeredItem != null)
+ offeredItem.SetNormal();
+ }
+
+ QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
+ myOfferings.SendUpdate(this);
+ QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
+ }
+
isTradeAccepted = false;
myOfferings = null;
otherTrader = null;
}
-
- public void Test()
- {
- QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
- QueuePacket(InventorySetBeginPacket.BuildPacket(actorId, 4, ItemPackage.TRADE));
-
- QueuePacket(InventoryRemoveX01Packet.BuildPacket(actorId, 1));
-
- QueuePacket(InventorySetEndPacket.BuildPacket(actorId));
- QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
- }
- public void Test2()
- {
- QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
- QueuePacket(InventorySetBeginPacket.BuildPacket(actorId, 4, ItemPackage.TRADE));
-
- QueuePacket(EquipmentListX01Packet.BuildPacket(actorId, 1, 1));
-
- QueuePacket(InventorySetEndPacket.BuildPacket(actorId));
- QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
- }
-
+
}
}
diff --git a/FFXIVClassic Map Server/dataobjects/InventoryItem.cs b/FFXIVClassic Map Server/dataobjects/InventoryItem.cs
index 284ecb57..a299c016 100644
--- a/FFXIVClassic Map Server/dataobjects/InventoryItem.cs
+++ b/FFXIVClassic Map Server/dataobjects/InventoryItem.cs
@@ -1,5 +1,4 @@
using FFXIVClassic_Map_Server.Actors;
-using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using System;
using System.IO;
@@ -27,9 +26,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
public byte dealingVal = 0;
public byte dealingMode = DEALINGMODE_NONE;
- public uint dealingAttached1 = 0;
- public uint dealingAttached2 = 0;
- public uint dealingAttached3 = 0;
+ public int dealingAttached1 = 0;
+ public int dealingAttached2 = 0;
+ public int dealingAttached3 = 0;
public byte[] tags = new byte[4];
public byte[] tagValues = new byte[4];
@@ -131,25 +130,21 @@ namespace FFXIVClassic_Map_Server.dataobjects
this.itemData = data;
this.quantity = 1;
- ItemData gItem = Server.GetItemGamedata(itemId);
- tags[1] = gItem.isExclusive ? (byte)0x3 : (byte)0x0;
+ tags[1] = itemData.isExclusive ? TAG_EXCLUSIVE : (byte)0;
}
- //For check command
- public InventoryItem(InventoryItem item, ushort equipSlot)
+ //For check and trade commands
+ public InventoryItem(InventoryItem item, ushort slot)
{
this.uniqueId = item.uniqueId;
this.itemData = item.itemData;
this.itemId = item.itemId;
this.quantity = item.quantity;
- this.slot = equipSlot;
-
+ this.slot = slot;
this.tags = item.tags;
this.tagValues = item.tagValues;
-
this.quality = item.quality;
-
- this.modifiers = item.modifiers;
+ this.modifiers = item.modifiers;
}
public InventoryItem(uint uniqueId, ItemData itemData, int quantity, byte qualityNumber, ItemModifier modifiers = null)
@@ -160,6 +155,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
this.quantity = quantity;
this.quality = qualityNumber;
this.modifiers = modifiers;
+
+ tags[1] = itemData.isExclusive ? TAG_EXCLUSIVE : (byte)0;
}
public byte[] ToPacketBytes()
@@ -209,8 +206,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
quantity = 0;
Database.SetQuantity(uniqueId, this.quantity);
- if (owner != null && owner is Player)
- owner.GetItemPackage(itemPackage).RefreshItem((Player)owner, this);
+ if (owner != null)
+ owner.GetItemPackage(itemPackage).MarkDirty(this);
}
}
@@ -230,13 +227,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
Database.SetQuantity(uniqueId, this.quantity);
- if (owner != null && owner is Player)
- {
-
- ((Player)owner).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId, false));
- owner.GetItemPackage(itemPackage).RefreshItem((Player)owner, this);
- ((Player)owner).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
- }
+ if (owner != null)
+ owner.GetItemPackage(itemPackage).MarkDirty(this);
}
}
@@ -245,12 +237,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
this.owner = owner;
this.itemPackage = itemPackage;
this.slot = slot;
- }
-
- public void SetExclusive(bool isExclusive)
- {
- tags[1] = isExclusive ? TAG_EXCLUSIVE : (byte)0;
- }
+ }
public void SetHasAttached(bool isAttached)
{
@@ -258,21 +245,18 @@ namespace FFXIVClassic_Map_Server.dataobjects
}
public void SetNormal()
- {
- for (int i = 0; i < 4; i++)
- {
- if (tags[i] == TAG_DEALING || tags[i] == TAG_ATTACHED)
- {
- tags[i] = 0;
- tagValues[i] = 0;
- attachedTo = 0;
- dealingVal = 0;
- dealingMode = 0;
- dealingAttached1 = 0;
- dealingAttached2 = 0;
- dealingAttached3 = 0;
- }
- }
+ {
+ tags[0] = 0;
+ tagValues[0] = 0;
+ attachedTo = 0;
+ dealingVal = 0;
+ dealingMode = 0;
+ dealingAttached1 = 0;
+ dealingAttached2 = 0;
+ dealingAttached3 = 0;
+
+ if (owner != null)
+ owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public void SetDealing(byte mode, int price)
@@ -285,9 +269,12 @@ namespace FFXIVClassic_Map_Server.dataobjects
dealingVal = 1;
dealingMode = DEALINGMODE_PRICED;
dealingAttached1 = 1;
- dealingAttached2 = (uint) price;
+ dealingAttached2 = price;
dealingAttached3 = 0;
}
+
+ if (owner != null)
+ owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public void SetDealingAttached(byte mode, ulong attached)
@@ -295,6 +282,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
tags[0] = TAG_DEALING;
tagValues[0] = mode;
attachedTo = attached;
+
+ if (owner != null)
+ owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public ulong GetAttached()
@@ -306,9 +296,20 @@ namespace FFXIVClassic_Map_Server.dataobjects
{
dealingVal = 1;
dealingMode = DEALINGMODE_REFERENCED;
- dealingAttached1 = (uint)((package << 16) | index);
+ dealingAttached1 = ((package << 16) | index);
dealingAttached2 = 0;
- dealingAttached3 = 0;
+ dealingAttached3 = 0;
+
+ if (owner != null)
+ owner.GetItemPackage(itemPackage).MarkDirty(this);
+ }
+
+ public void SetTradeQuantity(int quantity)
+ {
+ dealingAttached3 = quantity;
+
+ if (owner != null)
+ owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public ItemData GetItemData()
@@ -318,12 +319,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
public byte GetBazaarMode()
{
- for (int i = 0; i < tags.Length; i++)
- {
- if (tags[i] == 0xC9)
- return tagValues[i];
- }
-
+ if (tags[0] == 0xC9)
+ return tagValues[0];
return 0;
}
diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX01Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX01Packet.cs
deleted file mode 100644
index 925758d7..00000000
--- a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX01Packet.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using System.IO;
-
-using FFXIVClassic.Common;
-
-namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
-{
- class EquipmentListX01Packet
- {
- public const ushort OPCODE = 0x014D;
- public const uint PACKET_SIZE = 0x28;
-
- public static SubPacket BuildPacket(uint playerActorID, ushort equipSlot, uint itemSlot)
- {
- byte[] data = new byte[PACKET_SIZE - 0x20];
-
- using (MemoryStream mem = new MemoryStream(data))
- {
- using (BinaryWriter binWriter = new BinaryWriter(mem))
- {
- binWriter.Write((UInt16)equipSlot);
- binWriter.Write((UInt32)itemSlot);
- }
- }
-
- return new SubPacket(OPCODE, playerActorID, data);
- }
- }
-}
diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX01Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX01Packet.cs
new file mode 100644
index 00000000..59a5c9d2
--- /dev/null
+++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX01Packet.cs
@@ -0,0 +1,46 @@
+using System;
+using System.IO;
+
+using FFXIVClassic.Common;
+
+namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
+{
+ class LinkedItemListX01Packet
+ {
+ public const ushort OPCODE = 0x014D;
+ public const uint PACKET_SIZE = 0x28;
+
+ public static SubPacket BuildPacket(uint playerActorID, ushort position, uint linkedItem)
+ {
+ byte[] data = new byte[PACKET_SIZE - 0x20];
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt16)position);
+ binWriter.Write((UInt32)linkedItem);
+ }
+ }
+
+ return new SubPacket(OPCODE, playerActorID, data);
+ }
+
+ public static SubPacket BuildPacket(uint playerActorID, ushort position, ushort itemSlot, ushort itemPackageCode)
+ {
+ byte[] data = new byte[PACKET_SIZE - 0x20];
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt16)position);
+ binWriter.Write((UInt16)itemSlot);
+ binWriter.Write((UInt16)itemPackageCode);
+ }
+ }
+
+ return new SubPacket(OPCODE, playerActorID, data);
+ }
+ }
+}
diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX08Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX08Packet.cs
similarity index 82%
rename from FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX08Packet.cs
rename to FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX08Packet.cs
index c3f94f37..41f344f0 100644
--- a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX08Packet.cs
+++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX08Packet.cs
@@ -7,12 +7,12 @@ using FFXIVClassic.Common;
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
{
- class EquipmentListX08Packet
+ class LinkedItemListX08Packet
{
public const ushort OPCODE = 0x14E;
public const uint PACKET_SIZE = 0x58;
- public static SubPacket BuildPacket(uint playerActorId, InventoryItem[] equipment, List slotsToUpdate, ref int listOffset)
+ public static SubPacket BuildPacket(uint playerActorId, uint[] linkedItemList, List slotsToUpdate, ref int listOffset)
{
byte[] data = new byte[PACKET_SIZE - 0x20];
@@ -28,8 +28,8 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
for (int i = 0; i < max; i++)
{
- binWriter.Write((UInt16)slotsToUpdate[i]);
- binWriter.Write((UInt32)equipment[slotsToUpdate[i]].slot);
+ binWriter.Write((UInt16)slotsToUpdate[i]); //LinkedItemPackageSlot
+ binWriter.Write((UInt32)linkedItemList[slotsToUpdate[i]]); //ItemPackage Slot + ItemPackage Code
listOffset++;
}
diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX16Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX16Packet.cs
similarity index 81%
rename from FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX16Packet.cs
rename to FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX16Packet.cs
index fe347718..77375726 100644
--- a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX16Packet.cs
+++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX16Packet.cs
@@ -7,12 +7,12 @@ using FFXIVClassic.Common;
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
{
- class EquipmentListX16Packet
+ class LinkedItemListX16Packet
{
public const ushort OPCODE = 0x14F;
public const uint PACKET_SIZE = 0x80;
- public static SubPacket BuildPacket(uint playerActorId, InventoryItem[] equipment, List slotsToUpdate, ref int listOffset)
+ public static SubPacket BuildPacket(uint playerActorId, uint[] linkedItemList, List slotsToUpdate, ref int listOffset)
{
byte[] data = new byte[PACKET_SIZE - 0x20];
@@ -28,8 +28,8 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
for (int i = 0; i < max; i++)
{
- binWriter.Write((UInt16)slotsToUpdate[i]);
- binWriter.Write((UInt32)equipment[slotsToUpdate[i]].slot);
+ binWriter.Write((UInt16)slotsToUpdate[i]); //LinkedItemPackageSlot
+ binWriter.Write((UInt32)linkedItemList[slotsToUpdate[i]]); //ItemPackage Slot + ItemPackage Code
listOffset++;
}
diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX32Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX32Packet.cs
similarity index 81%
rename from FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX32Packet.cs
rename to FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX32Packet.cs
index 82614765..417a085f 100644
--- a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX32Packet.cs
+++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX32Packet.cs
@@ -7,12 +7,12 @@ using FFXIVClassic.Common;
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
{
- class EquipmentListX32Packet
+ class LinkedItemListX32Packet
{
public const ushort OPCODE = 0x150;
public const uint PACKET_SIZE = 0xE0;
- public static SubPacket BuildPacket(uint playerActorId, InventoryItem[] equipment, List slotsToUpdate, ref int listOffset)
+ public static SubPacket BuildPacket(uint playerActorId, uint[] linkedItemList, List slotsToUpdate, ref int listOffset)
{
byte[] data = new byte[PACKET_SIZE - 0x20];
@@ -28,8 +28,8 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
for (int i = 0; i < max; i++)
{
- binWriter.Write((UInt16)slotsToUpdate[i]);
- binWriter.Write((UInt32)equipment[slotsToUpdate[i]].slot);
+ binWriter.Write((UInt16)slotsToUpdate[i]); //LinkedItemPackageSlot
+ binWriter.Write((UInt32)linkedItemList[slotsToUpdate[i]]); //ItemPackage Slot + ItemPackage Code
listOffset++;
}
diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX64Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX64Packet.cs
similarity index 81%
rename from FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX64Packet.cs
rename to FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX64Packet.cs
index 05cb42c4..edc7378a 100644
--- a/FFXIVClassic Map Server/packets/send/Actor/inventory/EquipmentListX64Packet.cs
+++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/LinkedItemListX64Packet.cs
@@ -7,12 +7,12 @@ using FFXIVClassic.Common;
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
{
- class EquipmentListX64Packet
+ class LinkedItemListX64Packet
{
public const ushort OPCODE = 0x151;
public const uint PACKET_SIZE = 0x194;
- public static SubPacket BuildPacket(uint playerActorId, InventoryItem[] equipment, List slotsToUpdate, ref int listOffset)
+ public static SubPacket BuildPacket(uint playerActorId, uint[] linkedItemList, List slotsToUpdate, ref int listOffset)
{
byte[] data = new byte[PACKET_SIZE - 0x20];
@@ -28,8 +28,8 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
for (int i = 0; i < max; i++)
{
- binWriter.Write((UInt16)slotsToUpdate[i]);
- binWriter.Write((UInt32)equipment[slotsToUpdate[i]].slot);
+ binWriter.Write((UInt16)slotsToUpdate[i]); //LinkedItemPackageSlot
+ binWriter.Write((UInt32)linkedItemList[slotsToUpdate[i]]); //ItemPackage Slot + ItemPackage Code
listOffset++;
}
diff --git a/data/scripts/commands/EquipCommand.lua b/data/scripts/commands/EquipCommand.lua
index a73142cf..6c66c03a 100644
--- a/data/scripts/commands/EquipCommand.lua
+++ b/data/scripts/commands/EquipCommand.lua
@@ -6,7 +6,7 @@ Notes:
Gearset activating could be optimized a bit more by doing the item packets in one go.
-The param "invActionInfo" has the vars: actorId, unknown, slot, and inventoryType.
+The param "equippedItem" has the vars: actorId, unknown, slot, and inventoryType.
The param "itemDBIds" has the vars: item1 and item2.
--]]
@@ -53,12 +53,12 @@ GRAPHICSLOT_L_RINGFINGER = 24;
GRAPHICSLOT_R_INDEXFINGER = 25;
GRAPHICSLOT_L_INDEXFINGER = 26;
-function onEventStarted(player, actor, triggerName, invActionInfo, param1, param2, param3, param4, param5, param6, param7, equipSlot, itemDBIds)
+function onEventStarted(player, actor, triggerName, equippedItem, param1, param2, param3, param4, param5, param6, param7, equipSlot, itemDBIds)
equipSlot = equipSlot-1;
--Equip Item
- if (invActionInfo ~= nil) then
- item = player:GetItemPackage(0):GetItemAtSlot(invActionInfo.slot);
+ if (equippedItem ~= nil) then
+ item = player:GetItemPackage(equippedItem.itemPackage):GetItemAtSlot(equippedItem.slot);
equipItem(player, equipSlot, item);
player:SendAppearance();
--Unequip Item
@@ -83,7 +83,7 @@ function loadGearset(player, classId)
for slot = 0, 34 do
if (slot ~= EQUIPSLOT_MAINHAND and slot ~= EQUIPSLOT_UNDERSHIRT and slot ~= EQUIPSLOT_UNDERGARMENT) then
- itemAtSlot = player:GetEquipment():GetItemAtSlot(slot);
+ itemAtSlot = slot;
itemAtGearsetSlot = gearset[slot];
if (itemAtSlot ~= nil or itemAtGearsetSlot ~= nil) then
@@ -98,10 +98,8 @@ function loadGearset(player, classId)
end
end
- end
-
- player:GetEquipment():ToggleDBWrite(true);
-
+ end
+ player:GetEquipment():ToggleDBWrite(true);
end
function equipItem(player, equipSlot, item)
@@ -151,7 +149,7 @@ function equipItem(player, equipSlot, item)
player:DoClassChange(classId);
end
- player:GetEquipment():Equip(equipSlot, item);
+ player:GetEquipment():Set(equipSlot, item);
if (equipSlot == EQUIPSLOT_MAINHAND and gItem:IsNailWeapon() == false) then graphicSlot = GRAPHICSLOT_MAINHAND;
elseif (equipSlot == EQUIPSLOT_OFFHAND) then graphicSlot = GRAPHICSLOT_OFFHAND;
@@ -167,7 +165,7 @@ function equipItem(player, equipSlot, item)
elseif (equipSlot == EQUIPSLOT_RFINGER) then graphicSlot = GRAPHICSLOT_R_RINGFINGER;
elseif (equipSlot == EQUIPSLOT_LFINGER) then graphicSlot = GRAPHICSLOT_L_RINGFINGER;
end
-
+
--Graphic Slot was set, otherwise it's a special case
if (graphicSlot ~= nil) then
player:GraphicChange(graphicSlot, item);
@@ -191,7 +189,7 @@ function unequipItem(player, equipSlot, item)
player:SendGameMessage(player, worldMaster, 30730, 0x20, equipSlot+1, item.itemId, item.quality, 0, 0, 1); --Unable to unequip
elseif (item ~= nil) then
player:SendGameMessage(player, worldMaster, 30602, 0x20, equipSlot+1, item.itemId, item.quality, 0, 0, 1); --Item Removed
- player:GetEquipment():Unequip(equipSlot);
+ player:GetEquipment():Clear(equipSlot);
if (equipSlot == EQUIPSLOT_BODY) then --Show Undershirt
item = player:GetEquipment():GetItemAtSlot(EQUIPSLOT_UNDERSHIRT);
diff --git a/data/scripts/commands/TradeExecuteCommand.lua b/data/scripts/commands/TradeExecuteCommand.lua
index 730f491f..849202e1 100644
--- a/data/scripts/commands/TradeExecuteCommand.lua
+++ b/data/scripts/commands/TradeExecuteCommand.lua
@@ -30,16 +30,22 @@ function onEventStarted(player, actor, triggerName)
tradeOffering = player:GetTradeOfferings();
+ if (player.actorId == 0xA6) then
+ return;
+ end
+
while (true) do
- widgetOpen, chosenOperation, tradeSlot, type7, quantity, packageId, quality = callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processUpdateTradeCommandTrayData");
-
+ widgetOpen, chosenOperation, tradeSlot, itemActor, quantity, itemPackageId, itemSlot = callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processUpdateTradeCommandTrayData");
+
--Abort script if client script dead
if (widgetOpen == false or widgetOpen == nil) then
+ player:FinishTradeTransaction();
break;
end
--Handle you/target canceling/finishing the trade
if (not player:IsTrading() or not player:GetOtherTrader():IsTrading()) then
+ player:FinishTradeTransaction();
break;
end
@@ -63,15 +69,15 @@ function onEventStarted(player, actor, triggerName)
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
--Clear All
elseif (chosenOperation == 2) then
- player:ClearTradeItems(1);
+ player:ClearTradeItems();
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
--Item Chosen
elseif (chosenOperation == 3) then
- player:AddTradeItem(tradeSlot - 1, type7.slot, quantity);
+ player:AddTradeItem(tradeSlot - 1, itemActor, quantity);
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set", 2, 2, 2, 2);
--Gil Chosen
elseif (chosenOperation == 4) then
- player:AddTradeGil(quantity);
+ player:AddTradeItem(tradeSlot - 1, itemActor, quantity);
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
--Cancel
elseif (chosenOperation == 11) then