mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04:00
Refactored inventory to "ReferencedItemPackage" as this is a more general approach closer to what the FFXIV client uses. Added itempackage code to the LinkedItemList packets (also renamed from EquipmentList). Cleaned up trade code.
This commit is contained in:
parent
37cca32de8
commit
42ee97d467
@ -1117,7 +1117,7 @@ namespace FFXIVClassic_Map_Server
|
|||||||
player.GetItemPackage(ItemPackage.MELDREQUEST).InitList(GetItemPackage(player, 0, ItemPackage.MELDREQUEST));
|
player.GetItemPackage(ItemPackage.MELDREQUEST).InitList(GetItemPackage(player, 0, ItemPackage.MELDREQUEST));
|
||||||
player.GetItemPackage(ItemPackage.LOOT).InitList(GetItemPackage(player, 0, ItemPackage.LOOT));
|
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)
|
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)))
|
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);
|
ushort equipSlot = reader.GetUInt16(0);
|
||||||
ulong uniqueItemId = reader.GetUInt16(1);
|
ulong uniqueItemId = reader.GetUInt16(1);
|
||||||
InventoryItem item = player.GetItemPackage(ItemPackage.NORMAL).GetItemByUniqueId(uniqueItemId);
|
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);
|
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||||
cmd.Parameters.AddWithValue("@characterId", player.actorId);
|
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("@equipSlot", equipSlot);
|
||||||
cmd.Parameters.AddWithValue("@uniqueItemId", uniqueItemId);
|
cmd.Parameters.AddWithValue("@uniqueItemId", uniqueItemId);
|
||||||
|
|
||||||
|
@ -139,8 +139,8 @@
|
|||||||
<Compile Include="actors\chara\AetheryteWork.cs" />
|
<Compile Include="actors\chara\AetheryteWork.cs" />
|
||||||
<Compile Include="actors\chara\npc\Retainer.cs" />
|
<Compile Include="actors\chara\npc\Retainer.cs" />
|
||||||
<Compile Include="actors\chara\npc\Pet.cs" />
|
<Compile Include="actors\chara\npc\Pet.cs" />
|
||||||
<Compile Include="actors\chara\Equipment.cs" />
|
|
||||||
<Compile Include="actors\chara\ItemPackage.cs" />
|
<Compile Include="actors\chara\ItemPackage.cs" />
|
||||||
|
<Compile Include="actors\chara\ReferencedItemPackage.cs" />
|
||||||
<Compile Include="actors\chara\SubState.cs" />
|
<Compile Include="actors\chara\SubState.cs" />
|
||||||
<Compile Include="actors\chara\Work.cs" />
|
<Compile Include="actors\chara\Work.cs" />
|
||||||
<Compile Include="actors\debug\Debug.cs" />
|
<Compile Include="actors\debug\Debug.cs" />
|
||||||
@ -240,9 +240,6 @@
|
|||||||
<Compile Include="packets\send\actor\inventory\InventoryRemoveX16Packet.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryRemoveX16Packet.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryRemoveX32Packet.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryRemoveX32Packet.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryRemoveX64Packet.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryRemoveX64Packet.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\EquipmentListX64Packet.cs" />
|
|
||||||
<Compile Include="packets\send\actor\inventory\EquipmentListX32Packet.cs" />
|
|
||||||
<Compile Include="packets\send\actor\inventory\EquipmentListX16Packet.cs" />
|
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryListX01Packet.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryListX01Packet.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryListX08Packet.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryListX08Packet.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryListX16Packet.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryListX16Packet.cs" />
|
||||||
@ -254,14 +251,17 @@
|
|||||||
<Compile Include="packets\send\actor\_0x132Packet.cs" />
|
<Compile Include="packets\send\actor\_0x132Packet.cs" />
|
||||||
<Compile Include="packets\send\actor\SetActorIsZoningPacket.cs" />
|
<Compile Include="packets\send\actor\SetActorIsZoningPacket.cs" />
|
||||||
<Compile Include="packets\send\actor\battle\CommandResultX01Packet.cs" />
|
<Compile Include="packets\send\actor\battle\CommandResultX01Packet.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\EquipmentListX01Packet.cs" />
|
<Compile Include="packets\send\actor\inventory\LinkedItemListX01Packet.cs" />
|
||||||
|
<Compile Include="packets\send\actor\inventory\LinkedItemListX08Packet.cs" />
|
||||||
|
<Compile Include="packets\send\actor\inventory\LinkedItemListX16Packet.cs" />
|
||||||
|
<Compile Include="packets\send\actor\inventory\LinkedItemListX32Packet.cs" />
|
||||||
|
<Compile Include="packets\send\actor\inventory\LinkedItemListX64Packet.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryBeginChangePacket.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryBeginChangePacket.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryEndChangePacket.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryEndChangePacket.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryItemEndPacket.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryItemEndPacket.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventoryItemPacket.cs" />
|
<Compile Include="packets\send\actor\inventory\InventoryItemPacket.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventorySetBeginPacket.cs" />
|
<Compile Include="packets\send\actor\inventory\InventorySetBeginPacket.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\InventorySetEndPacket.cs" />
|
<Compile Include="packets\send\actor\inventory\InventorySetEndPacket.cs" />
|
||||||
<Compile Include="packets\send\actor\inventory\EquipmentListX08Packet.cs" />
|
|
||||||
<Compile Include="packets\send\actor\RemoveActorPacket.cs" />
|
<Compile Include="packets\send\actor\RemoveActorPacket.cs" />
|
||||||
<Compile Include="packets\send\actor\SetActorIconPacket.cs" />
|
<Compile Include="packets\send\actor\SetActorIconPacket.cs" />
|
||||||
<Compile Include="packets\send\actor\SetActorSubStatePacket.cs" />
|
<Compile Include="packets\send\actor\SetActorSubStatePacket.cs" />
|
||||||
|
@ -135,7 +135,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
//Inventory
|
//Inventory
|
||||||
protected Dictionary<ushort, ItemPackage> itemPackages = new Dictionary<ushort, ItemPackage>();
|
protected Dictionary<ushort, ItemPackage> itemPackages = new Dictionary<ushort, ItemPackage>();
|
||||||
protected Equipment equipment;
|
protected ReferencedItemPackage equipment;
|
||||||
|
|
||||||
public Character(uint actorID)
|
public Character(uint actorID)
|
||||||
: base(actorID)
|
: base(actorID)
|
||||||
@ -1147,7 +1147,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
|
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
|
||||||
itemPackages[(ushort)id].SendFullInventory(player);
|
itemPackages[(ushort)id].SendUpdate(player);
|
||||||
player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
|
player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class stores the current equipment that a <c>Player</c> has equipped on themselves. Technically
|
|
||||||
/// it is an <c>ItemPackage</c> 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 <c>InventoryItem</c>s 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).
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
|
|
||||||
/// <param name="ownerPlayer">The player client that owns this ItemPackage.</param>
|
|
||||||
/// <param name="normalInventory">A reference to the normal inventory ItemPackage this equipment ItemPackage links to.</param>
|
|
||||||
public Equipment(Player ownerPlayer, ItemPackage normalInventory)
|
|
||||||
{
|
|
||||||
owner = ownerPlayer;
|
|
||||||
this.normalInventory = normalInventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the full equipment ItemPackage to the given list. <paramref name="toEquip"/>'s length must
|
|
||||||
/// equal EQUIP_ITEMPACKAGE_CAPACITY. Used to initialize the list when loading from the DB.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="toEquip">The list of inventory items to set the full list to.</param>
|
|
||||||
public void SetEquipment(InventoryItem[] toEquip)
|
|
||||||
{
|
|
||||||
Debug.Assert(toEquip.Length == EQUIP_ITEMPACKAGE_CAPACITY);
|
|
||||||
toEquip.CopyTo(list, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the given equipSlots to link to the given itemSlots. The lengths of both must be equal.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="equipSlots">The list of equipmentSlots that get linked.</param>
|
|
||||||
/// <param name="itemSlots">The list of itemSlots that the equipSlots will link to.</param>
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Equips the item at the given item slot to the given equipment slot.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="equipSlot">The equipment slot being equipped.</param>
|
|
||||||
/// <param name="invSlot">The inventory slot of where the equipped item is.</param>
|
|
||||||
public void Equip(ushort equipSlot, ushort invSlot)
|
|
||||||
{
|
|
||||||
InventoryItem item = normalInventory.GetItemAtSlot(invSlot);
|
|
||||||
|
|
||||||
if (item == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Equip(equipSlot, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Equips the given inventory item to the given equipment slot.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="equipSlot">The equipment slot being equipped.</param>
|
|
||||||
/// <param name="item">The inventory item being equiped.</param>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggles if equipment changes are saved to the DB.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="flag">If true, equipment changes are saved to the db.</param>
|
|
||||||
public void ToggleDBWrite(bool flag)
|
|
||||||
{
|
|
||||||
writeToDB = flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes the linked item at the given <paramref name="equipSlot"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="equipSlot">The slot that is being cleared.</param>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the item equipped at the given <paramref name="equipSlot"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="equipSlot">The slot to retrieve from.</param>
|
|
||||||
public InventoryItem GetItemAtSlot(ushort equipSlot)
|
|
||||||
{
|
|
||||||
if (equipSlot < list.Length)
|
|
||||||
return list[equipSlot];
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the capacity of this ItemPackage.
|
|
||||||
/// </summary>
|
|
||||||
public int GetCapacity()
|
|
||||||
{
|
|
||||||
return list.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Packet Functions
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Syncs the client the link status of a single equipment slot. If the item was null,
|
|
||||||
/// sends a delete packet instead.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="equipSlot">The slot we are updating the client about.</param>
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Syncs the full list of equipped items to the client owner of this ItemPackage. Used on login/zone in.
|
|
||||||
/// </summary>
|
|
||||||
public void SendFullEquipment()
|
|
||||||
{
|
|
||||||
SendFullEquipment(owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="targetPlayer">The player client that is being synced.</param>
|
|
||||||
public void SendFullEquipment(Player targetPlayer)
|
|
||||||
{
|
|
||||||
List<ushort> slotsToUpdate = new List<ushort>();
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Main sync function. Syncs the given targetPlayer client the link status of multiple equipment slots.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="slotsToUpdate">The slots that will be synced.</param>
|
|
||||||
/// <param name="targetPlayer">The player client that is being synced.</param>
|
|
||||||
private void SendEquipmentPackets(List<ushort> 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
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.actors.chara.player
|
namespace FFXIVClassic_Map_Server.actors.chara.player
|
||||||
{
|
{
|
||||||
@ -23,6 +22,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
public const ushort TRADE = 0x00FD; //Max 0x04
|
public const ushort TRADE = 0x00FD; //Max 0x04
|
||||||
public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23
|
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 {
|
public enum INV_ERROR {
|
||||||
SUCCESS = 0,
|
SUCCESS = 0,
|
||||||
INVENTORY_FULL,
|
INVENTORY_FULL,
|
||||||
@ -170,7 +179,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
list[endOfListIndex++] = itemRef;
|
list[endOfListIndex++] = itemRef;
|
||||||
DoDatabaseAdd(itemRef);
|
DoDatabaseAdd(itemRef);
|
||||||
|
|
||||||
SendUpdatePackets();
|
SendUpdate();
|
||||||
|
|
||||||
return INV_ERROR.SUCCESS;
|
return INV_ERROR.SUCCESS;
|
||||||
}
|
}
|
||||||
@ -233,7 +242,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
DoDatabaseAdd(addedItem);
|
DoDatabaseAdd(addedItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendUpdatePackets();
|
SendUpdate();
|
||||||
|
|
||||||
return INV_ERROR.SUCCESS;
|
return INV_ERROR.SUCCESS;
|
||||||
}
|
}
|
||||||
@ -241,7 +250,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
public void SetItem(ushort slot, InventoryItem item)
|
public void SetItem(ushort slot, InventoryItem item)
|
||||||
{
|
{
|
||||||
list[slot] = item;
|
list[slot] = item;
|
||||||
SendUpdatePackets();
|
SendUpdate();
|
||||||
item.RefreshPositioning(owner, itemPackageCode, slot);
|
item.RefreshPositioning(owner, itemPackageCode, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +309,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
}
|
}
|
||||||
|
|
||||||
DoRealign();
|
DoRealign();
|
||||||
SendUpdatePackets();
|
SendUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveItem(InventoryItem item)
|
public void RemoveItem(InventoryItem item)
|
||||||
@ -349,7 +358,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
isDirty[slot] = true;
|
isDirty[slot] = true;
|
||||||
|
|
||||||
DoRealign();
|
DoRealign();
|
||||||
SendUpdatePackets();
|
SendUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveItemAtSlot(ushort slot)
|
public void RemoveItemAtSlot(ushort slot)
|
||||||
@ -364,7 +373,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
isDirty[slot] = true;
|
isDirty[slot] = true;
|
||||||
|
|
||||||
DoRealign();
|
DoRealign();
|
||||||
SendUpdatePackets();
|
SendUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveItemAtSlot(ushort slot, int quantity)
|
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);
|
DoDatabaseQuantity(list[slot].uniqueId, list[slot].quantity);
|
||||||
|
|
||||||
isDirty[slot] = true;
|
isDirty[slot] = true;
|
||||||
SendUpdatePackets();
|
SendUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +411,20 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
}
|
}
|
||||||
endOfListIndex = 0;
|
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()
|
public InventoryItem[] GetRawList()
|
||||||
@ -427,19 +449,61 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Packet Functions
|
#region Packet Functions
|
||||||
public void SendFullInventory(Player player)
|
public void SendFullPackage(Player player)
|
||||||
{
|
{
|
||||||
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
|
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
|
||||||
SendInventoryPackets(player, 0);
|
SendItemPackets(player, 0);
|
||||||
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
|
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<InventoryItem> items = new List<InventoryItem>();
|
||||||
|
List<ushort> slotsToRemove = new List<ushort>();
|
||||||
|
|
||||||
|
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));
|
player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendInventoryPackets(Player player, List<InventoryItem> items)
|
private void SendItemPackets(Player player, List<InventoryItem> items)
|
||||||
{
|
{
|
||||||
int currentIndex = 0;
|
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;
|
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));
|
player.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendInventoryRemovePackets(Player player, List<ushort> indexes)
|
private void SendItemPackets(Player player, List<ushort> indexes)
|
||||||
{
|
{
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
|
|
||||||
@ -519,28 +583,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
break;
|
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<InventoryItem> items)
|
|
||||||
{
|
|
||||||
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
|
|
||||||
SendInventoryPackets(player, items);
|
|
||||||
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Automatic Client and DB Updating
|
#region Automatic Client and DB Updating
|
||||||
@ -585,50 +627,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
Database.RemoveItem((Retainer)owner, itemDBId);
|
Database.RemoveItem((Retainer)owner, itemDBId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendUpdatePackets()
|
|
||||||
{
|
|
||||||
if (owner is Player && !holdingUpdates)
|
|
||||||
{
|
|
||||||
SendUpdatePackets((Player)owner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendUpdatePackets(Player player)
|
|
||||||
{
|
|
||||||
List<InventoryItem> items = new List<InventoryItem>();
|
|
||||||
List<ushort> slotsToRemove = new List<ushort>();
|
|
||||||
|
|
||||||
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()
|
public void StartSendUpdate()
|
||||||
{
|
{
|
||||||
holdingUpdates = true;
|
holdingUpdates = true;
|
||||||
@ -637,7 +635,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
|||||||
public void DoneSendUpdate()
|
public void DoneSendUpdate()
|
||||||
{
|
{
|
||||||
holdingUpdates = false;
|
holdingUpdates = false;
|
||||||
SendUpdatePackets();
|
SendUpdate();
|
||||||
Array.Clear(isDirty, 0, isDirty.Length);
|
Array.Clear(isDirty, 0, isDirty.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
312
FFXIVClassic Map Server/actors/chara/ReferencedItemPackage.cs
Normal file
312
FFXIVClassic Map Server/actors/chara/ReferencedItemPackage.cs
Normal file
@ -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<ItemPackage> packagesToRefresh = new List<ItemPackage>();
|
||||||
|
|
||||||
|
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<ushort> slotsToUpdate = new List<ushort>();
|
||||||
|
|
||||||
|
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<InventoryItem> items = new List<InventoryItem>();
|
||||||
|
|
||||||
|
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<ushort> 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<InventoryItem> 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
|
||||||
|
}
|
||||||
|
}
|
@ -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.player;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor.battle;
|
using FFXIVClassic_Map_Server.packets.send.actor.battle;
|
||||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||||
|
using static FFXIVClassic_Map_Server.LuaUtils;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.Actors
|
namespace FFXIVClassic_Map_Server.Actors
|
||||||
{
|
{
|
||||||
class Player : Character
|
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_TOTORAK = 0;
|
||||||
public const int TIMER_DZEMAEL = 1;
|
public const int TIMER_DZEMAEL = 1;
|
||||||
public const int TIMER_BOWL_OF_EMBERS_HARD = 2;
|
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_ACTIVE = 2;
|
||||||
public const int NPCLS_ALERT = 3;
|
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
|
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
|
5900, 6800, 7700, 8700, 9700, 11000, 12000, 13000, 15000, 16000, //Level <= 20
|
||||||
20000, 22000, 23000, 25000, 27000, 29000, 31000, 33000, 35000, 38000, //Level <= 30
|
20000, 22000, 23000, 25000, 27000, 29000, 31000, 33000, 35000, 38000, //Level <= 30
|
||||||
@ -85,9 +97,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
//Trading
|
//Trading
|
||||||
private Player otherTrader = null;
|
private Player otherTrader = null;
|
||||||
private ItemPackage myOfferings;
|
private ReferencedItemPackage myOfferings;
|
||||||
private bool isTradeAccepted = false;
|
private bool isTradeAccepted = false;
|
||||||
private bool isTradeLocked = false;
|
|
||||||
|
|
||||||
//GC Related
|
//GC Related
|
||||||
public byte gcCurrent;
|
public byte gcCurrent;
|
||||||
@ -143,14 +154,13 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
|
moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
|
||||||
moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
|
moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
|
||||||
|
|
||||||
itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, MAXSIZE_INVENTORY_NORMAL, ItemPackage.NORMAL);
|
itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, ItemPackage.MAXSIZE_NORMAL, ItemPackage.NORMAL);
|
||||||
itemPackages[ItemPackage.KEYITEMS] = new ItemPackage(this, MAXSIZE_INVENTORY_KEYITEMS, ItemPackage.KEYITEMS);
|
itemPackages[ItemPackage.KEYITEMS] = new ItemPackage(this, ItemPackage.MAXSIZE_KEYITEMS, ItemPackage.KEYITEMS);
|
||||||
itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, MAXSIZE_INVENTORY_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
|
itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, ItemPackage.MAXSIZE_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
|
||||||
itemPackages[ItemPackage.MELDREQUEST] = new ItemPackage(this, MAXSIZE_INVENTORY_MELDREQUEST, ItemPackage.MELDREQUEST);
|
itemPackages[ItemPackage.MELDREQUEST] = new ItemPackage(this, ItemPackage.MAXSIZE_MELDREQUEST, ItemPackage.MELDREQUEST);
|
||||||
itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, MAXSIZE_INVENTORY_BAZAAR, ItemPackage.BAZAAR);
|
itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, ItemPackage.MAXSIZE_BAZAAR, ItemPackage.BAZAAR);
|
||||||
itemPackages[ItemPackage.LOOT] = new ItemPackage(this, MAXSIZE_INVENTORY_LOOT, ItemPackage.LOOT);
|
itemPackages[ItemPackage.LOOT] = new ItemPackage(this, ItemPackage.MAXSIZE_LOOT, ItemPackage.LOOT);
|
||||||
|
equipment = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT, ItemPackage.EQUIPMENT);
|
||||||
equipment = new Equipment(this, itemPackages[ItemPackage.NORMAL]);
|
|
||||||
|
|
||||||
//Set the Skill level caps of all FFXIV (classes)skills to 50
|
//Set the Skill level caps of all FFXIV (classes)skills to 50
|
||||||
for (int i = 0; i < charaWork.battleSave.skillLevelCap.Length; i++)
|
for (int i = 0; i < charaWork.battleSave.skillLevelCap.Length; i++)
|
||||||
@ -531,13 +541,13 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
#region Inventory & Equipment
|
#region Inventory & Equipment
|
||||||
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
|
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
|
||||||
itemPackages[ItemPackage.NORMAL].SendFullInventory(this);
|
itemPackages[ItemPackage.NORMAL].SendFullPackage(this);
|
||||||
itemPackages[ItemPackage.CURRENCY_CRYSTALS].SendFullInventory(this);
|
itemPackages[ItemPackage.CURRENCY_CRYSTALS].SendFullPackage(this);
|
||||||
itemPackages[ItemPackage.KEYITEMS].SendFullInventory(this);
|
itemPackages[ItemPackage.KEYITEMS].SendFullPackage(this);
|
||||||
itemPackages[ItemPackage.BAZAAR].SendFullInventory(this);
|
itemPackages[ItemPackage.BAZAAR].SendFullPackage(this);
|
||||||
itemPackages[ItemPackage.MELDREQUEST].SendFullInventory(this);
|
itemPackages[ItemPackage.MELDREQUEST].SendFullPackage(this);
|
||||||
itemPackages[ItemPackage.LOOT].SendFullInventory(this);
|
itemPackages[ItemPackage.LOOT].SendFullPackage(this);
|
||||||
equipment.SendFullEquipment();
|
equipment.SendUpdate(this);
|
||||||
playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
|
playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -972,7 +982,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InventoryItem[] GetGearset(ushort classId)
|
public uint[] GetGearset(ushort classId)
|
||||||
{
|
{
|
||||||
return Database.GetEquipment(this, classId);
|
return Database.GetEquipment(this, classId);
|
||||||
}
|
}
|
||||||
@ -1190,7 +1200,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return isZoneChanging;
|
return isZoneChanging;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Equipment GetEquipment()
|
public ReferencedItemPackage GetEquipment()
|
||||||
{
|
{
|
||||||
return equipment;
|
return equipment;
|
||||||
}
|
}
|
||||||
@ -1674,19 +1684,11 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId));
|
QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId, true));
|
||||||
toBeExamined.GetEquipment().SendFullEquipment(this);
|
toBeExamined.GetEquipment().SendUpdateAsItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT_OTHERPLAYER, ItemPackage.EQUIPMENT_OTHERPLAYER);
|
||||||
QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId));
|
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)
|
public void SendDataPacket(params object[] parameters)
|
||||||
{
|
{
|
||||||
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
|
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
|
||||||
@ -2618,7 +2620,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
base.CalculateBaseStats();
|
base.CalculateBaseStats();
|
||||||
//Add weapon property mod
|
//Add weapon property mod
|
||||||
var equip = GetEquipment();
|
var equip = GetEquipment();
|
||||||
var mainHandItem = equip.GetItemAtSlot(Equipment.SLOT_MAINHAND);
|
var mainHandItem = equip.GetItemAtSlot(SLOT_MAINHAND);
|
||||||
var damageAttribute = 0;
|
var damageAttribute = 0;
|
||||||
var attackDelay = 3000;
|
var attackDelay = 3000;
|
||||||
var hitCount = 1;
|
var hitCount = 1;
|
||||||
@ -2631,7 +2633,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
hitCount = mainHandWeapon.frequency;
|
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.HasShield, hasShield);
|
||||||
|
|
||||||
SetMod((uint)Modifier.AttackType, damageAttribute);
|
SetMod((uint)Modifier.AttackType, damageAttribute);
|
||||||
@ -2699,14 +2701,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
public void StartTradeTransaction(Player otherPlayer)
|
public void StartTradeTransaction(Player otherPlayer)
|
||||||
{
|
{
|
||||||
myOfferings = new ItemPackage(this, 4, ItemPackage.TRADE, true);
|
myOfferings = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_TRADE, ItemPackage.TRADE);
|
||||||
ItemPackage otherPlayerOfferings = new ItemPackage(otherPlayer, 4, ItemPackage.TRADE, true);
|
|
||||||
|
|
||||||
myOfferings.StartSendUpdate();
|
|
||||||
myOfferings.SendUpdatePackets(this);
|
|
||||||
myOfferings.SendUpdatePackets(otherPlayer);
|
|
||||||
myOfferings.DoneSendUpdate();
|
|
||||||
|
|
||||||
otherTrader = otherPlayer;
|
otherTrader = otherPlayer;
|
||||||
isTradeAccepted = false;
|
isTradeAccepted = false;
|
||||||
}
|
}
|
||||||
@ -2716,7 +2711,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return otherTrader;
|
return otherTrader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemPackage GetTradeOfferings()
|
public ReferencedItemPackage GetTradeOfferings()
|
||||||
{
|
{
|
||||||
return myOfferings;
|
return myOfferings;
|
||||||
}
|
}
|
||||||
@ -2731,30 +2726,17 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return isTradeAccepted;
|
return isTradeAccepted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddTradeItem(ushort slot, ushort linkedSlot, int subquantity)
|
public void AddTradeItem(ushort slot, ItemRefParam chosenItem, int tradeQuantity)
|
||||||
{
|
{
|
||||||
if (!IsTrading())
|
if (!IsTrading())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InventoryItem mine = itemPackages[ItemPackage.NORMAL].GetItemAtSlot(linkedSlot);
|
//Get chosen item
|
||||||
|
InventoryItem offeredItem = itemPackages[chosenItem.itemPackage].GetItemAtSlot(chosenItem.slot);
|
||||||
|
offeredItem.SetTradeQuantity(tradeQuantity);
|
||||||
|
|
||||||
InventoryItem tradeItem = new InventoryItem(mine, slot);
|
myOfferings.Set(slot, offeredItem);
|
||||||
|
SendTradePackets();
|
||||||
myOfferings.StartSendUpdate();
|
|
||||||
myOfferings.AddItem(mine.itemId, mine.quantity, mine.quality);
|
|
||||||
myOfferings.SendUpdatePackets(otherTrader);
|
|
||||||
myOfferings.DoneSendUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddTradeGil(int quantity)
|
|
||||||
{
|
|
||||||
if (!IsTrading())
|
|
||||||
return;
|
|
||||||
|
|
||||||
myOfferings.StartSendUpdate();
|
|
||||||
myOfferings.AddItem(1000001, quantity, 1);
|
|
||||||
myOfferings.SendUpdatePackets(otherTrader);
|
|
||||||
myOfferings.DoneSendUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveTradeItem(ushort slot)
|
public void RemoveTradeItem(ushort slot)
|
||||||
@ -2762,21 +2744,40 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
if (!IsTrading())
|
if (!IsTrading())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
myOfferings.StartSendUpdate();
|
InventoryItem offeredItem = myOfferings.GetItemAtSlot(slot);
|
||||||
myOfferings.RemoveItemAtSlot(slot);
|
offeredItem.SetNormal();
|
||||||
myOfferings.SendUpdatePackets(otherTrader);
|
|
||||||
myOfferings.DoneSendUpdate();
|
myOfferings.Clear(slot);
|
||||||
|
SendTradePackets();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearTradeItems(ushort slot)
|
public void ClearTradeItems()
|
||||||
{
|
{
|
||||||
if (!IsTrading())
|
if (!IsTrading())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
myOfferings.StartSendUpdate();
|
for (ushort i = 0; i < myOfferings.GetCapacity(); i++)
|
||||||
myOfferings.Clear();
|
{
|
||||||
myOfferings.SendUpdatePackets(otherTrader);
|
InventoryItem offeredItem = myOfferings.GetItemAtSlot(i);
|
||||||
myOfferings.DoneSendUpdate();
|
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)
|
public void AcceptTrade(bool accepted)
|
||||||
@ -2788,31 +2789,25 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
public void FinishTradeTransaction()
|
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;
|
isTradeAccepted = false;
|
||||||
myOfferings = null;
|
myOfferings = null;
|
||||||
otherTrader = 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
@ -27,9 +26,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
|
|
||||||
public byte dealingVal = 0;
|
public byte dealingVal = 0;
|
||||||
public byte dealingMode = DEALINGMODE_NONE;
|
public byte dealingMode = DEALINGMODE_NONE;
|
||||||
public uint dealingAttached1 = 0;
|
public int dealingAttached1 = 0;
|
||||||
public uint dealingAttached2 = 0;
|
public int dealingAttached2 = 0;
|
||||||
public uint dealingAttached3 = 0;
|
public int dealingAttached3 = 0;
|
||||||
|
|
||||||
public byte[] tags = new byte[4];
|
public byte[] tags = new byte[4];
|
||||||
public byte[] tagValues = new byte[4];
|
public byte[] tagValues = new byte[4];
|
||||||
@ -131,24 +130,20 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
this.itemData = data;
|
this.itemData = data;
|
||||||
this.quantity = 1;
|
this.quantity = 1;
|
||||||
|
|
||||||
ItemData gItem = Server.GetItemGamedata(itemId);
|
tags[1] = itemData.isExclusive ? TAG_EXCLUSIVE : (byte)0;
|
||||||
tags[1] = gItem.isExclusive ? (byte)0x3 : (byte)0x0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//For check command
|
//For check and trade commands
|
||||||
public InventoryItem(InventoryItem item, ushort equipSlot)
|
public InventoryItem(InventoryItem item, ushort slot)
|
||||||
{
|
{
|
||||||
this.uniqueId = item.uniqueId;
|
this.uniqueId = item.uniqueId;
|
||||||
this.itemData = item.itemData;
|
this.itemData = item.itemData;
|
||||||
this.itemId = item.itemId;
|
this.itemId = item.itemId;
|
||||||
this.quantity = item.quantity;
|
this.quantity = item.quantity;
|
||||||
this.slot = equipSlot;
|
this.slot = slot;
|
||||||
|
|
||||||
this.tags = item.tags;
|
this.tags = item.tags;
|
||||||
this.tagValues = item.tagValues;
|
this.tagValues = item.tagValues;
|
||||||
|
|
||||||
this.quality = item.quality;
|
this.quality = item.quality;
|
||||||
|
|
||||||
this.modifiers = item.modifiers;
|
this.modifiers = item.modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +155,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
this.quantity = quantity;
|
this.quantity = quantity;
|
||||||
this.quality = qualityNumber;
|
this.quality = qualityNumber;
|
||||||
this.modifiers = modifiers;
|
this.modifiers = modifiers;
|
||||||
|
|
||||||
|
tags[1] = itemData.isExclusive ? TAG_EXCLUSIVE : (byte)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] ToPacketBytes()
|
public byte[] ToPacketBytes()
|
||||||
@ -209,8 +206,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
quantity = 0;
|
quantity = 0;
|
||||||
Database.SetQuantity(uniqueId, this.quantity);
|
Database.SetQuantity(uniqueId, this.quantity);
|
||||||
|
|
||||||
if (owner != null && owner is Player)
|
if (owner != null)
|
||||||
owner.GetItemPackage(itemPackage).RefreshItem((Player)owner, this);
|
owner.GetItemPackage(itemPackage).MarkDirty(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,13 +227,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
|
|
||||||
Database.SetQuantity(uniqueId, this.quantity);
|
Database.SetQuantity(uniqueId, this.quantity);
|
||||||
|
|
||||||
if (owner != null && owner is Player)
|
if (owner != null)
|
||||||
{
|
owner.GetItemPackage(itemPackage).MarkDirty(this);
|
||||||
|
|
||||||
((Player)owner).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId, false));
|
|
||||||
owner.GetItemPackage(itemPackage).RefreshItem((Player)owner, this);
|
|
||||||
((Player)owner).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,11 +239,6 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
this.slot = slot;
|
this.slot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetExclusive(bool isExclusive)
|
|
||||||
{
|
|
||||||
tags[1] = isExclusive ? TAG_EXCLUSIVE : (byte)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetHasAttached(bool isAttached)
|
public void SetHasAttached(bool isAttached)
|
||||||
{
|
{
|
||||||
tags[0] = isAttached ? TAG_ATTACHED : (byte)0;
|
tags[0] = isAttached ? TAG_ATTACHED : (byte)0;
|
||||||
@ -259,20 +246,17 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
|
|
||||||
public void SetNormal()
|
public void SetNormal()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; i++)
|
tags[0] = 0;
|
||||||
{
|
tagValues[0] = 0;
|
||||||
if (tags[i] == TAG_DEALING || tags[i] == TAG_ATTACHED)
|
attachedTo = 0;
|
||||||
{
|
dealingVal = 0;
|
||||||
tags[i] = 0;
|
dealingMode = 0;
|
||||||
tagValues[i] = 0;
|
dealingAttached1 = 0;
|
||||||
attachedTo = 0;
|
dealingAttached2 = 0;
|
||||||
dealingVal = 0;
|
dealingAttached3 = 0;
|
||||||
dealingMode = 0;
|
|
||||||
dealingAttached1 = 0;
|
if (owner != null)
|
||||||
dealingAttached2 = 0;
|
owner.GetItemPackage(itemPackage).MarkDirty(this);
|
||||||
dealingAttached3 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDealing(byte mode, int price)
|
public void SetDealing(byte mode, int price)
|
||||||
@ -285,9 +269,12 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
dealingVal = 1;
|
dealingVal = 1;
|
||||||
dealingMode = DEALINGMODE_PRICED;
|
dealingMode = DEALINGMODE_PRICED;
|
||||||
dealingAttached1 = 1;
|
dealingAttached1 = 1;
|
||||||
dealingAttached2 = (uint) price;
|
dealingAttached2 = price;
|
||||||
dealingAttached3 = 0;
|
dealingAttached3 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (owner != null)
|
||||||
|
owner.GetItemPackage(itemPackage).MarkDirty(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDealingAttached(byte mode, ulong attached)
|
public void SetDealingAttached(byte mode, ulong attached)
|
||||||
@ -295,6 +282,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
tags[0] = TAG_DEALING;
|
tags[0] = TAG_DEALING;
|
||||||
tagValues[0] = mode;
|
tagValues[0] = mode;
|
||||||
attachedTo = attached;
|
attachedTo = attached;
|
||||||
|
|
||||||
|
if (owner != null)
|
||||||
|
owner.GetItemPackage(itemPackage).MarkDirty(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong GetAttached()
|
public ulong GetAttached()
|
||||||
@ -306,9 +296,20 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
{
|
{
|
||||||
dealingVal = 1;
|
dealingVal = 1;
|
||||||
dealingMode = DEALINGMODE_REFERENCED;
|
dealingMode = DEALINGMODE_REFERENCED;
|
||||||
dealingAttached1 = (uint)((package << 16) | index);
|
dealingAttached1 = ((package << 16) | index);
|
||||||
dealingAttached2 = 0;
|
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()
|
public ItemData GetItemData()
|
||||||
@ -318,12 +319,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
|
|
||||||
public byte GetBazaarMode()
|
public byte GetBazaarMode()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tags.Length; i++)
|
if (tags[0] == 0xC9)
|
||||||
{
|
return tagValues[0];
|
||||||
if (tags[i] == 0xC9)
|
|
||||||
return tagValues[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,12 @@ using FFXIVClassic.Common;
|
|||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX08Packet
|
class LinkedItemListX08Packet
|
||||||
{
|
{
|
||||||
public const ushort OPCODE = 0x14E;
|
public const ushort OPCODE = 0x14E;
|
||||||
public const uint PACKET_SIZE = 0x58;
|
public const uint PACKET_SIZE = 0x58;
|
||||||
|
|
||||||
public static SubPacket BuildPacket(uint playerActorId, InventoryItem[] equipment, List<ushort> slotsToUpdate, ref int listOffset)
|
public static SubPacket BuildPacket(uint playerActorId, uint[] linkedItemList, List<ushort> slotsToUpdate, ref int listOffset)
|
||||||
{
|
{
|
||||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
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++)
|
for (int i = 0; i < max; i++)
|
||||||
{
|
{
|
||||||
binWriter.Write((UInt16)slotsToUpdate[i]);
|
binWriter.Write((UInt16)slotsToUpdate[i]); //LinkedItemPackageSlot
|
||||||
binWriter.Write((UInt32)equipment[slotsToUpdate[i]].slot);
|
binWriter.Write((UInt32)linkedItemList[slotsToUpdate[i]]); //ItemPackage Slot + ItemPackage Code
|
||||||
listOffset++;
|
listOffset++;
|
||||||
}
|
}
|
||||||
|
|
@ -7,12 +7,12 @@ using FFXIVClassic.Common;
|
|||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX16Packet
|
class LinkedItemListX16Packet
|
||||||
{
|
{
|
||||||
public const ushort OPCODE = 0x14F;
|
public const ushort OPCODE = 0x14F;
|
||||||
public const uint PACKET_SIZE = 0x80;
|
public const uint PACKET_SIZE = 0x80;
|
||||||
|
|
||||||
public static SubPacket BuildPacket(uint playerActorId, InventoryItem[] equipment, List<ushort> slotsToUpdate, ref int listOffset)
|
public static SubPacket BuildPacket(uint playerActorId, uint[] linkedItemList, List<ushort> slotsToUpdate, ref int listOffset)
|
||||||
{
|
{
|
||||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
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++)
|
for (int i = 0; i < max; i++)
|
||||||
{
|
{
|
||||||
binWriter.Write((UInt16)slotsToUpdate[i]);
|
binWriter.Write((UInt16)slotsToUpdate[i]); //LinkedItemPackageSlot
|
||||||
binWriter.Write((UInt32)equipment[slotsToUpdate[i]].slot);
|
binWriter.Write((UInt32)linkedItemList[slotsToUpdate[i]]); //ItemPackage Slot + ItemPackage Code
|
||||||
listOffset++;
|
listOffset++;
|
||||||
}
|
}
|
||||||
|
|
@ -7,12 +7,12 @@ using FFXIVClassic.Common;
|
|||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX32Packet
|
class LinkedItemListX32Packet
|
||||||
{
|
{
|
||||||
public const ushort OPCODE = 0x150;
|
public const ushort OPCODE = 0x150;
|
||||||
public const uint PACKET_SIZE = 0xE0;
|
public const uint PACKET_SIZE = 0xE0;
|
||||||
|
|
||||||
public static SubPacket BuildPacket(uint playerActorId, InventoryItem[] equipment, List<ushort> slotsToUpdate, ref int listOffset)
|
public static SubPacket BuildPacket(uint playerActorId, uint[] linkedItemList, List<ushort> slotsToUpdate, ref int listOffset)
|
||||||
{
|
{
|
||||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
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++)
|
for (int i = 0; i < max; i++)
|
||||||
{
|
{
|
||||||
binWriter.Write((UInt16)slotsToUpdate[i]);
|
binWriter.Write((UInt16)slotsToUpdate[i]); //LinkedItemPackageSlot
|
||||||
binWriter.Write((UInt32)equipment[slotsToUpdate[i]].slot);
|
binWriter.Write((UInt32)linkedItemList[slotsToUpdate[i]]); //ItemPackage Slot + ItemPackage Code
|
||||||
listOffset++;
|
listOffset++;
|
||||||
}
|
}
|
||||||
|
|
@ -7,12 +7,12 @@ using FFXIVClassic.Common;
|
|||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX64Packet
|
class LinkedItemListX64Packet
|
||||||
{
|
{
|
||||||
public const ushort OPCODE = 0x151;
|
public const ushort OPCODE = 0x151;
|
||||||
public const uint PACKET_SIZE = 0x194;
|
public const uint PACKET_SIZE = 0x194;
|
||||||
|
|
||||||
public static SubPacket BuildPacket(uint playerActorId, InventoryItem[] equipment, List<ushort> slotsToUpdate, ref int listOffset)
|
public static SubPacket BuildPacket(uint playerActorId, uint[] linkedItemList, List<ushort> slotsToUpdate, ref int listOffset)
|
||||||
{
|
{
|
||||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
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++)
|
for (int i = 0; i < max; i++)
|
||||||
{
|
{
|
||||||
binWriter.Write((UInt16)slotsToUpdate[i]);
|
binWriter.Write((UInt16)slotsToUpdate[i]); //LinkedItemPackageSlot
|
||||||
binWriter.Write((UInt32)equipment[slotsToUpdate[i]].slot);
|
binWriter.Write((UInt32)linkedItemList[slotsToUpdate[i]]); //ItemPackage Slot + ItemPackage Code
|
||||||
listOffset++;
|
listOffset++;
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,7 @@ Notes:
|
|||||||
|
|
||||||
Gearset activating could be optimized a bit more by doing the item packets in one go.
|
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.
|
The param "itemDBIds" has the vars: item1 and item2.
|
||||||
|
|
||||||
--]]
|
--]]
|
||||||
@ -53,12 +53,12 @@ GRAPHICSLOT_L_RINGFINGER = 24;
|
|||||||
GRAPHICSLOT_R_INDEXFINGER = 25;
|
GRAPHICSLOT_R_INDEXFINGER = 25;
|
||||||
GRAPHICSLOT_L_INDEXFINGER = 26;
|
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;
|
equipSlot = equipSlot-1;
|
||||||
|
|
||||||
--Equip Item
|
--Equip Item
|
||||||
if (invActionInfo ~= nil) then
|
if (equippedItem ~= nil) then
|
||||||
item = player:GetItemPackage(0):GetItemAtSlot(invActionInfo.slot);
|
item = player:GetItemPackage(equippedItem.itemPackage):GetItemAtSlot(equippedItem.slot);
|
||||||
equipItem(player, equipSlot, item);
|
equipItem(player, equipSlot, item);
|
||||||
player:SendAppearance();
|
player:SendAppearance();
|
||||||
--Unequip Item
|
--Unequip Item
|
||||||
@ -83,7 +83,7 @@ function loadGearset(player, classId)
|
|||||||
for slot = 0, 34 do
|
for slot = 0, 34 do
|
||||||
|
|
||||||
if (slot ~= EQUIPSLOT_MAINHAND and slot ~= EQUIPSLOT_UNDERSHIRT and slot ~= EQUIPSLOT_UNDERGARMENT) then
|
if (slot ~= EQUIPSLOT_MAINHAND and slot ~= EQUIPSLOT_UNDERSHIRT and slot ~= EQUIPSLOT_UNDERGARMENT) then
|
||||||
itemAtSlot = player:GetEquipment():GetItemAtSlot(slot);
|
itemAtSlot = slot;
|
||||||
itemAtGearsetSlot = gearset[slot];
|
itemAtGearsetSlot = gearset[slot];
|
||||||
|
|
||||||
if (itemAtSlot ~= nil or itemAtGearsetSlot ~= nil) then
|
if (itemAtSlot ~= nil or itemAtGearsetSlot ~= nil) then
|
||||||
@ -99,9 +99,7 @@ function loadGearset(player, classId)
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
player:GetEquipment():ToggleDBWrite(true);
|
player:GetEquipment():ToggleDBWrite(true);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function equipItem(player, equipSlot, item)
|
function equipItem(player, equipSlot, item)
|
||||||
@ -151,7 +149,7 @@ function equipItem(player, equipSlot, item)
|
|||||||
player:DoClassChange(classId);
|
player:DoClassChange(classId);
|
||||||
end
|
end
|
||||||
|
|
||||||
player:GetEquipment():Equip(equipSlot, item);
|
player:GetEquipment():Set(equipSlot, item);
|
||||||
|
|
||||||
if (equipSlot == EQUIPSLOT_MAINHAND and gItem:IsNailWeapon() == false) then graphicSlot = GRAPHICSLOT_MAINHAND;
|
if (equipSlot == EQUIPSLOT_MAINHAND and gItem:IsNailWeapon() == false) then graphicSlot = GRAPHICSLOT_MAINHAND;
|
||||||
elseif (equipSlot == EQUIPSLOT_OFFHAND) then graphicSlot = GRAPHICSLOT_OFFHAND;
|
elseif (equipSlot == EQUIPSLOT_OFFHAND) then graphicSlot = GRAPHICSLOT_OFFHAND;
|
||||||
@ -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
|
player:SendGameMessage(player, worldMaster, 30730, 0x20, equipSlot+1, item.itemId, item.quality, 0, 0, 1); --Unable to unequip
|
||||||
elseif (item ~= nil) then
|
elseif (item ~= nil) then
|
||||||
player:SendGameMessage(player, worldMaster, 30602, 0x20, equipSlot+1, item.itemId, item.quality, 0, 0, 1); --Item Removed
|
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
|
if (equipSlot == EQUIPSLOT_BODY) then --Show Undershirt
|
||||||
item = player:GetEquipment():GetItemAtSlot(EQUIPSLOT_UNDERSHIRT);
|
item = player:GetEquipment():GetItemAtSlot(EQUIPSLOT_UNDERSHIRT);
|
||||||
|
@ -30,16 +30,22 @@ function onEventStarted(player, actor, triggerName)
|
|||||||
|
|
||||||
tradeOffering = player:GetTradeOfferings();
|
tradeOffering = player:GetTradeOfferings();
|
||||||
|
|
||||||
|
if (player.actorId == 0xA6) then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
while (true) do
|
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
|
--Abort script if client script dead
|
||||||
if (widgetOpen == false or widgetOpen == nil) then
|
if (widgetOpen == false or widgetOpen == nil) then
|
||||||
|
player:FinishTradeTransaction();
|
||||||
break;
|
break;
|
||||||
end
|
end
|
||||||
|
|
||||||
--Handle you/target canceling/finishing the trade
|
--Handle you/target canceling/finishing the trade
|
||||||
if (not player:IsTrading() or not player:GetOtherTrader():IsTrading()) then
|
if (not player:IsTrading() or not player:GetOtherTrader():IsTrading()) then
|
||||||
|
player:FinishTradeTransaction();
|
||||||
break;
|
break;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -63,15 +69,15 @@ function onEventStarted(player, actor, triggerName)
|
|||||||
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
|
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
|
||||||
--Clear All
|
--Clear All
|
||||||
elseif (chosenOperation == 2) then
|
elseif (chosenOperation == 2) then
|
||||||
player:ClearTradeItems(1);
|
player:ClearTradeItems();
|
||||||
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
|
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
|
||||||
--Item Chosen
|
--Item Chosen
|
||||||
elseif (chosenOperation == 3) then
|
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);
|
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set", 2, 2, 2, 2);
|
||||||
--Gil Chosen
|
--Gil Chosen
|
||||||
elseif (chosenOperation == 4) then
|
elseif (chosenOperation == 4) then
|
||||||
player:AddTradeGil(quantity);
|
player:AddTradeItem(tradeSlot - 1, itemActor, quantity);
|
||||||
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
|
callClientFunction(player, "delegateCommand", GetStaticActor("TradeExecuteCommand"), "processTradeCommandReply", "set");
|
||||||
--Cancel
|
--Cancel
|
||||||
elseif (chosenOperation == 11) then
|
elseif (chosenOperation == 11) then
|
||||||
|
Loading…
Reference in New Issue
Block a user