project-meteor-server/FFXIVClassic Map Server/dataobjects/InventoryItem.cs

336 lines
11 KiB
C#

using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using System;
using System.IO;
namespace FFXIVClassic_Map_Server.dataobjects
{
class InventoryItem
{
public const byte DEALINGMODE_NONE = 0;
public const byte DEALINGMODE_REFERENCED = 1;
public const byte DEALINGMODE_PRICED = 2;
public const byte TAG_EXCLUSIVE = 0x3;
public const byte TAG_DEALING = 0xC9;
public const byte TAG_ATTACHED = 0xCA;
public const byte TYPE_SINGLE = 11;
public const byte TYPE_MULTI = 12;
public const byte TYPE_STACK = 13;
public const byte TYPE_SEEK_ITEM = 20;
public const byte TYPE_SEEK_REPAIR = 30;
public ulong uniqueId;
public uint itemId;
public int quantity = 1;
public byte dealingVal = 0;
public byte dealingMode = DEALINGMODE_NONE;
public uint dealingAttached1 = 0;
public uint dealingAttached2 = 0;
public uint dealingAttached3 = 0;
public byte[] tags = new byte[4];
public byte[] tagValues = new byte[4];
public byte quality = 1;
private ulong attachedTo = 0;
public ItemModifier modifiers;
public readonly ItemData itemData;
public Character owner = null;
public ushort slot = 0xFFFF;
public ushort itemPackage = 0xFFFF;
public class ItemModifier
{
public uint durability = 0;
public ushort use = 0;
public uint materiaId = 0;
public uint materiaLife = 0;
public byte mainQuality = 0;
public byte[] subQuality = new byte[3];
public uint polish = 0;
public uint param1 = 0;
public uint param2 = 0;
public uint param3 = 0;
public ushort spiritbind = 0;
public byte[] materiaType = new byte[5];
public byte[] materiaGrade = new byte[5];
public ItemModifier()
{
}
public ItemModifier(MySql.Data.MySqlClient.MySqlDataReader reader)
{
durability = reader.GetUInt32("durability");
mainQuality = reader.GetByte("mainQuality");
subQuality[0] = reader.GetByte("subQuality1");
subQuality[1] = reader.GetByte("subQuality2");
subQuality[2] = reader.GetByte("subQuality3");
param1 = reader.GetUInt32("param1");
param2 = reader.GetUInt32("param2");
param3 = reader.GetUInt32("param3");
spiritbind = reader.GetUInt16("spiritbind");
ushort materia1 = reader.GetUInt16("materia1");
ushort materia2 = reader.GetUInt16("materia2");
ushort materia3 = reader.GetUInt16("materia3");
ushort materia4 = reader.GetUInt16("materia4");
ushort materia5 = reader.GetUInt16("materia5");
materiaType[0] = (byte)(materia1 & 0xFF);
materiaGrade[0] = (byte)((materia1 >> 8) & 0xFF);
materiaType[1] = (byte)(materia2 & 0xFF);
materiaGrade[1] = (byte)((materia2 >> 8) & 0xFF);
materiaType[2] = (byte)(materia3 & 0xFF);
materiaGrade[2] = (byte)((materia3 >> 8) & 0xFF);
materiaType[3] = (byte)(materia4 & 0xFF);
materiaGrade[3] = (byte)((materia4 >> 8) & 0xFF);
materiaType[4] = (byte)(materia5 & 0xFF);
materiaGrade[4] = (byte)((materia5 >> 8) & 0xFF);
}
public void WriteBytes(BinaryWriter binWriter)
{
binWriter.Write((UInt32) durability);
binWriter.Write((UInt16) use);
binWriter.Write((UInt32) materiaId);
binWriter.Write((UInt32) materiaLife);
binWriter.Write((Byte) mainQuality);
binWriter.Write((Byte) subQuality[0]);
binWriter.Write((Byte) subQuality[1]);
binWriter.Write((Byte) subQuality[2]);
binWriter.Write((UInt32) polish);
binWriter.Write((UInt32) param1);
binWriter.Write((UInt32) param2);
binWriter.Write((UInt32) param3);
binWriter.Write((UInt16) spiritbind);
binWriter.Write((Byte) materiaType[0]);
binWriter.Write((Byte) materiaType[1]);
binWriter.Write((Byte) materiaType[2]);
binWriter.Write((Byte) materiaType[3]);
binWriter.Write((Byte) materiaType[4]);
binWriter.Write((Byte) materiaGrade[0]);
binWriter.Write((Byte) materiaGrade[1]);
binWriter.Write((Byte) materiaGrade[2]);
binWriter.Write((Byte) materiaGrade[3]);
binWriter.Write((Byte) materiaGrade[4]);
}
}
//Bare Minimum
public InventoryItem(uint id, ItemData data)
{
this.uniqueId = id;
this.itemId = data.catalogID;
this.itemData = data;
this.quantity = 1;
ItemData gItem = Server.GetItemGamedata(itemId);
tags[1] = gItem.isExclusive ? (byte)0x3 : (byte)0x0;
}
//For check command
public InventoryItem(InventoryItem item, ushort equipSlot)
{
this.uniqueId = item.uniqueId;
this.itemData = item.itemData;
this.itemId = item.itemId;
this.quantity = item.quantity;
this.slot = equipSlot;
this.tags = item.tags;
this.tagValues = item.tagValues;
this.quality = item.quality;
this.modifiers = item.modifiers;
}
public InventoryItem(uint uniqueId, ItemData itemData, int quantity, byte qualityNumber, ItemModifier modifiers = null)
{
this.uniqueId = uniqueId;
this.itemId = itemData.catalogID;
this.itemData = itemData;
this.quantity = quantity;
this.quality = qualityNumber;
this.modifiers = modifiers;
}
public byte[] ToPacketBytes()
{
byte[] data = new byte[0x70];
using (MemoryStream mem = new MemoryStream(data))
{
using (BinaryWriter binWriter = new BinaryWriter(mem))
{
binWriter.Write((UInt64)uniqueId);
binWriter.Write((Int32)quantity);
binWriter.Write((UInt32)itemId);
binWriter.Write((UInt16)slot);
binWriter.Write((Byte)dealingVal);
binWriter.Write((Byte)dealingMode);
binWriter.Write((UInt32)dealingAttached1);
binWriter.Write((UInt32)dealingAttached2);
binWriter.Write((UInt32)dealingAttached3);
for (int i = 0; i < tags.Length; i++)
binWriter.Write((Byte) tags[i]);
for (int i = 0; i < tagValues.Length; i++)
binWriter.Write((Byte) tagValues[i]);
binWriter.Write((Byte)quality);
if (modifiers != null)
{
binWriter.Write((Byte)0x01);
modifiers.WriteBytes(binWriter);
}
}
}
return data;
}
public void SetQuantity(uint quantity)
{
lock (owner.GetItemPackage(itemPackage))
{
this.quantity = (int)quantity;
if (quantity < 0)
quantity = 0;
Database.SetQuantity(uniqueId, this.quantity);
if (owner != null && owner is Player)
owner.GetItemPackage(itemPackage).RefreshItem((Player)owner, this);
}
}
public void ChangeQuantity(int quantityDelta)
{
lock (owner.GetItemPackage(itemPackage))
{
this.quantity += quantityDelta;
if (quantity < 0)
quantity = 0;
if (quantity == 0)
{
owner.RemoveItem(this);
return;
}
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));
}
}
}
public void RefreshPositioning(Character owner, ushort itemPackage, ushort slot)
{
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)
{
tags[0] = isAttached ? TAG_ATTACHED : (byte)0;
}
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;
}
}
}
public void SetDealing(byte mode, int price)
{
tags[0] = TAG_DEALING;
tagValues[0] = mode;
if (mode == TYPE_SINGLE || mode == TYPE_MULTI || mode == TYPE_STACK)
{
dealingVal = 1;
dealingMode = DEALINGMODE_PRICED;
dealingAttached1 = 1;
dealingAttached2 = (uint) price;
dealingAttached3 = 0;
}
}
public void SetDealingAttached(byte mode, ulong attached)
{
tags[0] = TAG_DEALING;
tagValues[0] = mode;
attachedTo = attached;
}
public ulong GetAttached()
{
return attachedTo;
}
public void SetAttachedIndex(ushort package, ushort index)
{
dealingVal = 1;
dealingMode = DEALINGMODE_REFERENCED;
dealingAttached1 = (uint)((package << 16) | index);
dealingAttached2 = 0;
dealingAttached3 = 0;
}
public ItemData GetItemData()
{
return itemData;
}
public byte GetBazaarMode()
{
for (int i = 0; i < tags.Length; i++)
{
if (tags[i] == 0xC9)
return tagValues[i];
}
return 0;
}
public bool IsSelling()
{
return GetBazaarMode() == TYPE_SINGLE || GetBazaarMode() == TYPE_MULTI || GetBazaarMode() == TYPE_STACK;
}
}
}