1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-22 04:37:47 +00:00

Merge branch 'inventory_overhaul' into retainers

This commit is contained in:
Filip Maj 2017-09-09 12:21:51 -04:00
commit 9529a1374e
8 changed files with 478 additions and 424 deletions

View file

@ -1225,7 +1225,6 @@ namespace FFXIVClassic_Map_Server
serverItemId, serverItemId,
itemId, itemId,
quantity, quantity,
slot,
itemType, itemType,
quality, quality,
durability, durability,
@ -1237,35 +1236,37 @@ namespace FFXIVClassic_Map_Server
materia5 materia5
FROM characters_inventory FROM characters_inventory
INNER JOIN server_items ON serverItemId = server_items.id INNER JOIN server_items ON serverItemId = server_items.id
WHERE characterId = @charId AND inventoryType = @type AND slot >= @slot ORDER BY slot"; WHERE characterId = @charId AND inventoryType = @type";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@slot", slotOffset);
cmd.Parameters.AddWithValue("@type", type); cmd.Parameters.AddWithValue("@type", type);
ushort slot = 0;
using (MySqlDataReader reader = cmd.ExecuteReader()) using (MySqlDataReader reader = cmd.ExecuteReader())
{ {
while (reader.Read()) while (reader.Read())
{ {
uint uniqueId = reader.GetUInt32(0); uint uniqueId = reader.GetUInt32("serverItemId");
uint itemId = reader.GetUInt32(1); uint itemId = reader.GetUInt32("itemId");
int quantity = reader.GetInt32(2); int quantity = reader.GetInt32("quantity");
ushort slot = reader.GetUInt16(3);
byte itemType = reader.GetByte(4); byte itemType = reader.GetByte("itemType");
byte qualityNumber = reader.GetByte(5); byte qualityNumber = reader.GetByte("quality");
int durability = reader.GetInt32(6); int durability = reader.GetInt32("durability");
ushort spiritBind = reader.GetUInt16(7); ushort spiritBind = reader.GetUInt16("spiritBind");
byte materia1 = reader.GetByte(8); byte materia1 = reader.GetByte("materia1");
byte materia2 = reader.GetByte(9); byte materia2 = reader.GetByte("materia2");
byte materia3 = reader.GetByte(10); byte materia3 = reader.GetByte("materia3");
byte materia4 = reader.GetByte(11); byte materia4 = reader.GetByte("materia4");
byte materia5 = reader.GetByte(12); byte materia5 = reader.GetByte("materia5");
items.Add(new InventoryItem(uniqueId, itemId, quantity, slot, itemType, qualityNumber, durability, spiritBind, materia1, materia2, materia3, materia4, materia5)); InventoryItem item = new InventoryItem(uniqueId, itemId, quantity, itemType, qualityNumber, durability, spiritBind, materia1, materia2, materia3, materia4, materia5);
item.slot = slot;
slot++;
items.Add(item);
} }
} }
} }
@ -1282,7 +1283,7 @@ namespace FFXIVClassic_Map_Server
return items; return items;
} }
public static InventoryItem AddItem(Player player, uint itemId, int quantity, byte quality, byte itemType, int durability, ushort type) public static InventoryItem CreateItem(uint itemId, int quantity, byte quality, byte itemType, int durability)
{ {
InventoryItem insertedItem = null; InventoryItem insertedItem = null;
@ -1303,27 +1304,14 @@ namespace FFXIVClassic_Map_Server
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
string query2 = @"
INSERT INTO characters_inventory
(characterId, slot, inventoryType, serverItemId, quantity)
SELECT @charId, IFNULL(MAX(SLOT)+1, 0), @inventoryType, LAST_INSERT_ID(), @quantity FROM characters_inventory WHERE characterId = @charId AND inventoryType = @inventoryType;
";
MySqlCommand cmd2 = new MySqlCommand(query2, conn);
cmd.Parameters.AddWithValue("@itemId", itemId); cmd.Parameters.AddWithValue("@itemId", itemId);
cmd.Parameters.AddWithValue("@quality", quality); cmd.Parameters.AddWithValue("@quality", quality);
cmd.Parameters.AddWithValue("@itemType", itemType); cmd.Parameters.AddWithValue("@itemType", itemType);
cmd.Parameters.AddWithValue("@durability", durability); cmd.Parameters.AddWithValue("@durability", durability);
cmd2.Parameters.AddWithValue("@charId", player.actorId);
cmd2.Parameters.AddWithValue("@inventoryType", type);
cmd2.Parameters.AddWithValue("@quantity", quantity);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
cmd2.ExecuteNonQuery();
insertedItem = new InventoryItem((uint)cmd.LastInsertedId, itemId, quantity, (ushort)player.GetInventory(type).GetNextEmptySlot(), itemType, quality, durability, 0, 0, 0, 0, 0, 0); insertedItem = new InventoryItem((uint)cmd.LastInsertedId, itemId, quantity, itemType, quality, durability, 0, 0, 0, 0, 0, 0);
} }
catch (MySqlException e) catch (MySqlException e)
{ {
@ -1338,7 +1326,42 @@ namespace FFXIVClassic_Map_Server
return insertedItem; return insertedItem;
} }
public static void SetQuantity(Player player, uint slot, ushort type, int quantity) public static void AddItem(Player player, InventoryItem addedItem, uint type)
{
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
INSERT INTO characters_inventory
(characterId, inventoryType, serverItemId, quantity)
VALUES
(@charId, @inventoryType, @serverItemId, @quantity)
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@serverItemId", addedItem.uniqueId);
cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@inventoryType", type);
cmd.Parameters.AddWithValue("@quantity", addedItem.quantity);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
}
public static void SetQuantity(Player player, ulong serverItemId, int quantity)
{ {
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)))
{ {
@ -1349,54 +1372,13 @@ namespace FFXIVClassic_Map_Server
string query = @" string query = @"
UPDATE characters_inventory UPDATE characters_inventory
SET quantity = @quantity SET quantity = @quantity
WHERE characterId = @charId AND slot = @slot AND inventoryType = @type; WHERE characterId = @charId and serverItemId = @serverItemId;
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@quantity", quantity);
cmd.Parameters.AddWithValue("@slot", slot);
cmd.Parameters.AddWithValue("@type", type);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
}
public static void RemoveItem(Player player, ulong serverItemId, ushort type)
{
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}; Allow User Variables=True", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
SELECT slot INTO @slotToDelete FROM characters_inventory WHERE serverItemId = @serverItemId;
UPDATE characters_inventory
SET slot = slot - 1
WHERE characterId = @charId AND slot > @slotToDelete AND inventoryType = @type;
DELETE FROM characters_inventory
WHERE serverItemId = @serverItemId AND inventoryType = @type;
DELETE FROM server_items
WHERE id = @serverItemId;
"; ";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@serverItemId", serverItemId); cmd.Parameters.AddWithValue("@serverItemId", serverItemId);
cmd.Parameters.AddWithValue("@type", type); cmd.Parameters.AddWithValue("@quantity", quantity);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
@ -1412,7 +1394,7 @@ namespace FFXIVClassic_Map_Server
} }
public static void RemoveItem(Player player, ushort slot, ushort type) public static void RemoveItem(Player player, ulong serverItemId)
{ {
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}; Allow User Variables=True", 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}; Allow User Variables=True", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{ {
@ -1421,23 +1403,13 @@ namespace FFXIVClassic_Map_Server
conn.Open(); conn.Open();
string query = @" string query = @"
SELECT serverItemId INTO @serverItemId FROM characters_inventory WHERE characterId = @charId AND slot = @slot;
DELETE FROM characters_inventory DELETE FROM characters_inventory
WHERE characterId = @charId AND slot = @slot AND inventoryType = @type; WHERE characterId = @charId and serverItemId = @serverItemId;
DELETE FROM server_items
WHERE id = @serverItemId;
UPDATE characters_inventory
SET slot = slot - 1
WHERE characterId = @charId AND slot > @slot AND inventoryType = @type;
"; ";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@slot", slot); cmd.Parameters.AddWithValue("@serverItemId", serverItemId);
cmd.Parameters.AddWithValue("@type", type);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }

View file

@ -182,8 +182,12 @@ namespace FFXIVClassic_Map_Server
if (ownerActor == null) if (ownerActor == null)
{ {
//Is it your retainer?
if (session.GetActor().currentSpawnedRetainer != null && session.GetActor().currentSpawnedRetainer.actorId == eventStart.scriptOwnerActorID)
ownerActor = session.GetActor().currentSpawnedRetainer;
//Is it a instance actor? //Is it a instance actor?
ownerActor = session.GetActor().zone.FindActorInArea(session.GetActor().currentEventOwner); if (ownerActor == null)
ownerActor = session.GetActor().zone.FindActorInArea(session.GetActor().currentEventOwner);
if (ownerActor == null) if (ownerActor == null)
{ {
//Is it a Director? //Is it a Director?

View file

@ -1,5 +1,7 @@
using FFXIVClassic_Map_Server.actors.chara.player; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -10,22 +12,45 @@ namespace FFXIVClassic_Map_Server.actors.chara.npc
{ {
class Retainer : Npc class Retainer : Npc
{ {
public Retainer(uint id, string retainerName, ActorClass actorClass, Player player, float posX, float posY, float posZ, float rot) Player player;
: base(0, actorClass, String.Format("_rtnre{0:x7}", id), player.GetZone(), posX, posY, posZ, rot, 0, 0, retainerName)
public Retainer(string retainerName, ActorClass actorClass, Player player, float posX, float posY, float posZ, float rot)
: base(0, actorClass, "myretainer", player.GetZone(), posX, posY, posZ, rot, 0, 0, retainerName)
{ {
this.actorId = 0xD0000000 | id; this.player = player;
this.actorName = String.Format("_rtnre{0:x7}", actorId);
} }
public void SendBazaarItems(Player player) public void SendBazaarItems(Player player)
{ {
Inventory bazaar = new Inventory(this, 4, Inventory.RETAINER_BAZAAR); Inventory bazaar = new Inventory(this, 150, (ushort)0);
bazaar.SendFullInventory(player); bazaar.AddItem(1000001);
bazaar.AddItem(3020517);
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
bazaar.SendFullInventory(player);
player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
} }
public void SendStorageItems(Player player) public void SendStorageItems(Player player)
{ {
Inventory storage = new Inventory(this, 4, 1); Inventory storage = new Inventory(this, 10, Inventory.CURRENCY);
storage.AddItem(1000001);
storage.AddItem(3020519);
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
storage.SendFullInventory(player); storage.SendFullInventory(player);
player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
} }
public void SendHuhItems(Player player)
{
Inventory storage = new Inventory(this, 20, 7);
storage.AddItem(1000003);
storage.AddItem(1000016);
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
storage.SendFullInventory(player);
player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
} }
} }

View file

@ -106,13 +106,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
for (int i = 0; i < slots.Length; i++) for (int i = 0; i < slots.Length; i++)
{ {
InventoryItem item = normalInventory.GetItemBySlot(itemSlots[i]); InventoryItem item = normalInventory.GetItemAtSlot(itemSlots[i]);
if (item == null) if (item == null)
continue; continue;
Database.EquipItem(owner, slots[i], item.uniqueId); Database.EquipItem(owner, slots[i], item.uniqueId);
list[slots[i]] = normalInventory.GetItemBySlot(itemSlots[i]); list[slots[i]] = normalInventory.GetItemAtSlot(itemSlots[i]);
} }
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
@ -133,7 +133,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public void Equip(ushort slot, ushort invSlot) public void Equip(ushort slot, ushort invSlot)
{ {
InventoryItem item = normalInventory.GetItemBySlot(invSlot); InventoryItem item = normalInventory.GetItemAtSlot(invSlot);
if (item == null) if (item == null)
return; return;
@ -152,9 +152,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
if (list[slot] != null) if (list[slot] != null)
normalInventory.RefreshItem(list[slot], item); normalInventory.RefreshItem(owner, list[slot], item);
else else
normalInventory.RefreshItem(item); normalInventory.RefreshItem(owner, item);
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendEquipmentPackets(slot, item); SendEquipmentPackets(slot, item);
@ -180,7 +180,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
normalInventory.RefreshItem(list[slot]); normalInventory.RefreshItem(owner, list[slot]);
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendEquipmentPackets(slot, null); SendEquipmentPackets(slot, null);

View file

@ -1,10 +1,11 @@
 
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.actor.inventory; 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.Linq; using System.Linq;
namespace FFXIVClassic_Map_Server.actors.chara.player namespace FFXIVClassic_Map_Server.actors.chara.player
@ -20,38 +21,50 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public const ushort CURRENCY = 0x0063; //Max 0x140 public const ushort CURRENCY = 0x0063; //Max 0x140
public const ushort KEYITEMS = 0x0064; //Max 0x500 public const ushort KEYITEMS = 0x0064; //Max 0x500
public const ushort EQUIPMENT = 0x00FE; //Max 0x23 public const ushort EQUIPMENT = 0x00FE; //Max 0x23
public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23 public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23
private int endOfListIndex = 0;
private Player owner; private Character owner;
private ushort inventoryCapacity; private ushort inventoryCapacity;
private ushort inventoryCode; private ushort inventoryCode;
private List<InventoryItem> list; private InventoryItem[] list;
private bool[] isDirty;
public Inventory(Player ownerPlayer, ushort capacity, ushort code)
public Inventory(Character ownerPlayer, ushort capacity, ushort code)
{ {
owner = ownerPlayer; owner = ownerPlayer;
inventoryCapacity = capacity; inventoryCapacity = capacity;
inventoryCode = code; inventoryCode = code;
list = new InventoryItem[capacity];
isDirty = new bool[capacity];
} }
#region Inventory Management #region Inventory Management
public void InitList(List<InventoryItem> itemsFromDB) public void InitList(List<InventoryItem> itemsFromDB)
{ {
list = itemsFromDB; int i = 0;
foreach (InventoryItem item in itemsFromDB)
list[i++] = item;
endOfListIndex = i;
} }
public InventoryItem GetItemBySlot(ushort slot) public InventoryItem GetItemAtSlot(ushort slot)
{ {
if (slot < list.Count) if (slot < list.Length)
return list[slot]; return list[slot];
else else
return null; return null;
} }
public InventoryItem GetItemByUniqueId(ulong uniqueItemId) public InventoryItem GetItemByUniqueId(ulong uniqueItemId)
{ {
foreach (InventoryItem item in list) for (int i = 0; i < endOfListIndex; i++)
{ {
InventoryItem item = list[i];
Debug.Assert(item != null, "Item slot was null!!!");
if (item.uniqueId == uniqueItemId) if (item.uniqueId == uniqueItemId)
return item; return item;
} }
@ -60,54 +73,35 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public InventoryItem GetItemByCatelogId(ulong catelogId) public InventoryItem GetItemByCatelogId(ulong catelogId)
{ {
foreach (InventoryItem item in list) for (int i = 0; i < endOfListIndex; i++)
{ {
InventoryItem item = list[i];
Debug.Assert(item != null, "Item slot was null!!!");
if (item.itemId == catelogId) if (item.itemId == catelogId)
return item; return item;
} }
return null; return null;
} }
public void RefreshItem(InventoryItem item) public bool AddItem(uint itemId)
{ {
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); return AddItem(itemId, 1, 1);
SendInventoryPackets(item); }
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
} public bool AddItem(uint itemId, int quantity)
{
public void RefreshItem(params InventoryItem[] items) return AddItem(itemId, quantity, 1);
{
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(items.ToList());
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void RefreshItem(List<InventoryItem> items)
{
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(items);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void AddItem(uint itemId)
{
AddItem(itemId, 1, 1);
}
public void AddItem(uint itemId, int quantity)
{
AddItem(itemId, quantity, 1);
} }
public bool AddItem(uint itemId, int quantity, byte quality) public bool AddItem(uint itemId, int quantity, byte quality)
{ {
if (!IsSpaceForAdd(itemId, quantity)) if (!IsSpaceForAdd(itemId, quantity, quality))
return false; return false;
ItemData gItem = Server.GetItemGamedata(itemId); ItemData gItem = Server.GetItemGamedata(itemId);
List<ushort> slotsToUpdate = new List<ushort>();
List<SubPacket> addItemPackets = new List<SubPacket>();
if (gItem == null) if (gItem == null)
{ {
Program.Log.Error("Inventory.AddItem: unable to find item %u", itemId); Program.Log.Error("Inventory.AddItem: unable to find item %u", itemId);
@ -115,16 +109,25 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
} }
//Check if item id exists //Check if item id exists
int quantityCount = quantity; int quantityCount = quantity;
for (int i = 0; i < list.Count; i++) for (int i = 0; i < endOfListIndex; i++)
{ {
InventoryItem item = list[i]; InventoryItem item = list[i];
if (item.itemId == itemId && item.quantity < gItem.maxStack)
Debug.Assert(item != null, "Item slot was null!!!");
if (item.itemId == itemId && item.quality == quality && item.quantity < gItem.maxStack)
{ {
slotsToUpdate.Add(item.slot);
int oldQuantity = item.quantity; int oldQuantity = item.quantity;
item.quantity = Math.Min(item.quantity + quantityCount, gItem.maxStack); item.quantity = Math.Min(item.quantity + quantityCount, gItem.maxStack);
quantityCount -= (gItem.maxStack - oldQuantity); isDirty[i] = true;
quantityCount -= (gItem.maxStack - oldQuantity);
if (owner is Player)
{
Database.SetQuantity((Player)owner, item.uniqueId, item.quantity);
}
if (quantityCount <= 0) if (quantityCount <= 0)
break; break;
} }
@ -136,71 +139,44 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
//If Inventory is full //If Inventory is full
//if (quantityCount > 0 && isInventoryFull()) //if (quantityCount > 0 && isInventoryFull())
// return ITEMERROR_FULL; // return ITEMERROR_FULL;
//Update lists and db
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
//These had their quantities Changed
foreach (ushort slot in slotsToUpdate)
{
Database.SetQuantity(owner, slot, inventoryCode, list[slot].quantity);
if (inventoryCode != CURRENCY && inventoryCode != KEYITEMS)
SendInventoryPackets(list[slot]);
}
//New item that spilled over //New item that spilled over
while (quantityCount > 0) while (quantityCount > 0)
{ {
InventoryItem addedItem = Database.AddItem(owner, itemId, Math.Min(quantityCount, gItem.maxStack), quality, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability, inventoryCode); InventoryItem addedItem = Database.CreateItem(itemId, Math.Min(quantityCount, gItem.maxStack), quality, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability);
addedItem.slot = (ushort)endOfListIndex;
isDirty[endOfListIndex] = true;
list.Add(addedItem); list[endOfListIndex++] = addedItem;
if (inventoryCode != CURRENCY && inventoryCode != KEYITEMS)
SendInventoryPackets(addedItem);
quantityCount -= gItem.maxStack; quantityCount -= gItem.maxStack;
if (owner is Player)
{
Database.AddItem((Player)owner, addedItem, inventoryCode);
}
}
if (owner is Player)
{
SendUpdatePackets((Player)owner);
} }
if (inventoryCode == CURRENCY || inventoryCode == KEYITEMS)
SendFullInventory();
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
return true; return true;
} }
public void AddItem(uint[] itemId) public void RemoveItem(uint itemId)
{ {
if (!IsSpaceForAdd(itemId[0], itemId.Length)) RemoveItem(itemId, 1);
return; }
//Update lists and db public void RemoveItem(uint itemId, int quantity)
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); {
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); RemoveItem(itemId, quantity, 1);
int startPos = list.Count;
//New item that spilled over
for (int i = 0; i < itemId.Length; i++)
{
ItemData gItem = Server.GetItemGamedata(itemId[i]);
InventoryItem addedItem = Database.AddItem(owner, itemId[i], 1, (byte)1, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability, inventoryCode);
list.Add(addedItem);
}
SendInventoryPackets(startPos);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
} }
public void RemoveItem(uint itemId, int quantity) public void RemoveItem(uint itemId, int quantity, int quality)
{ {
if (!HasItem(itemId, quantity)) if (!HasItem(itemId, quantity, quality))
return; return;
List<ushort> slotsToUpdate = new List<ushort>(); List<ushort> slotsToUpdate = new List<ushort>();
@ -211,23 +187,31 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
//Remove as we go along //Remove as we go along
int quantityCount = quantity; int quantityCount = quantity;
ushort lowestSlot = 0; ushort lowestSlot = 0;
for (int i = list.Count - 1; i >= 0; i--) for (int i = endOfListIndex - 1; i >= 0; i--)
{ {
InventoryItem item = list[i]; InventoryItem item = list[i];
if (item.itemId == itemId)
Debug.Assert(item != null, "Item slot was null!!!");
if (item.itemId == itemId && item.quality == quality)
{ {
int oldQuantity = item.quantity; int oldQuantity = item.quantity;
//Stack nomnomed //Stack nomnomed
if (item.quantity - quantityCount <= 0) if (item.quantity - quantityCount <= 0)
{ {
itemsToRemove.Add(item); if (owner is Player)
slotsToRemove.Add(item.slot); Database.RemoveItem((Player)owner, list[i].uniqueId);
} list[i] = null;
else }
{ //Stack reduced
slotsToUpdate.Add(item.slot); else
item.quantity -= quantityCount; //Stack reduced {
} item.quantity -= quantityCount;
if (owner is Player)
Database.SetQuantity((Player)owner, list[i].uniqueId, list[i].quantity);
}
isDirty[i] = true;
quantityCount -= oldQuantity; quantityCount -= oldQuantity;
lowestSlot = item.slot; lowestSlot = item.slot;
@ -235,51 +219,23 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
if (quantityCount <= 0) if (quantityCount <= 0)
break; break;
} }
} }
for (int i = 0; i < slotsToUpdate.Count; i++) doRealign();
{ if (owner is Player)
Database.SetQuantity(owner, slotsToUpdate[i], inventoryCode, list[slotsToUpdate[i]].quantity); SendUpdatePackets((Player)owner);
}
int oldListSize = list.Count;
for (int i = 0; i < itemsToRemove.Count; i++)
{
Database.RemoveItem(owner, itemsToRemove[i].uniqueId, inventoryCode);
list.Remove(itemsToRemove[i]);
}
//Realign slots
for (int i = lowestSlot; i < list.Count; i++)
list[i].slot = (ushort)i;
//Added tail end items that need to be cleared for slot realignment
for (int i = oldListSize-1; i >= oldListSize - itemsToRemove.Count; i--)
{
if (!slotsToRemove.Contains((ushort)i))
slotsToRemove.Add((ushort)i);
}
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(lowestSlot);
SendInventoryRemovePackets(slotsToRemove);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
if (inventoryCode == NORMAL)
owner.GetEquipment().SendFullEquipment(false);
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
} }
public void RemoveItemByUniqueId(ulong itemDBId) public void RemoveItemByUniqueId(ulong itemDBId)
{ {
ushort slot = 0; ushort slot = 0;
InventoryItem toDelete = null; InventoryItem toDelete = null;
foreach (InventoryItem item in list) for (int i = endOfListIndex - 1; i >= 0; i--)
{ {
InventoryItem item = list[i];
Debug.Assert(item != null, "Item slot was null!!!");
if (item.uniqueId == itemDBId) if (item.uniqueId == itemDBId)
{ {
toDelete = item; toDelete = item;
@ -289,188 +245,248 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
} }
if (toDelete == null) if (toDelete == null)
return; return;
int oldListSize = list.Count; if (owner is Player)
list.RemoveAt(slot); Database.RemoveItem((Player)owner, toDelete.uniqueId);
Database.RemoveItem(owner, itemDBId, inventoryCode);
//Realign slots
for (int i = slot; i < list.Count; i++)
list[i].slot = (ushort)i;
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(slot);
SendInventoryRemovePackets(slot);
if (slot != oldListSize - 1)
SendInventoryRemovePackets((ushort)(oldListSize - 1));
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
if (inventoryCode == NORMAL)
owner.GetEquipment().SendFullEquipment(false);
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
list[slot] = null;
isDirty[slot] = true;
doRealign();
if (owner is Player)
SendUpdatePackets((Player)owner);
} }
public void RemoveItemAtSlot(ushort slot) public void RemoveItemAtSlot(ushort slot)
{ {
if (slot >= list.Count) if (slot >= endOfListIndex)
return; return;
int oldListSize = list.Count; if (owner is Player)
list.RemoveAt((int)slot); Database.RemoveItem((Player)owner, list[slot].uniqueId);
Database.RemoveItem(owner, slot, inventoryCode);
list[slot] = null;
//Realign slots isDirty[slot] = true;
for (int i = slot; i < list.Count; i++)
list[i].slot = (ushort)i; doRealign();
if (owner is Player)
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); SendUpdatePackets((Player)owner);
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); }
SendInventoryPackets(slot); public void RemoveItemAtSlot(ushort slot, int quantity)
SendInventoryRemovePackets(slot); {
if (slot != oldListSize - 1) if (slot >= endOfListIndex)
SendInventoryRemovePackets((ushort)(oldListSize - 1)); return;
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); if (list[slot] != null)
{
if (inventoryCode == NORMAL) list[slot].quantity -= quantity;
owner.GetEquipment().SendFullEquipment(false);
if (list[slot].quantity <= 0)
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); {
if (owner is Player)
Database.RemoveItem((Player)owner, list[slot].uniqueId);
list[slot] = null;
doRealign();
}
else
{
if (owner is Player)
Database.SetQuantity((Player)owner, list[slot].uniqueId, list[slot].quantity);
}
isDirty[slot] = true;
if (owner is Player)
SendUpdatePackets((Player)owner);
}
} }
public void ChangeDurability(uint slot, uint durabilityChange) public void ChangeDurability(uint slot, uint durabilityChange)
{ {
isDirty[slot] = true;
} }
public void ChangeSpiritBind(uint slot, uint spiritBindChange) public void ChangeSpiritBind(uint slot, uint spiritBindChange)
{ {
isDirty[slot] = true;
} }
public void ChangeMateria(uint slot, byte materiaSlot, byte materiaId) public void ChangeMateria(uint slot, byte materiaSlot, byte materiaId)
{ {
isDirty[slot] = true;
} }
#endregion #endregion
#region Packet Functions #region Packet Functions
public void SendFullInventory() public void SendFullInventory(Player player)
{ {
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(0); SendInventoryPackets(player, 0);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
} }
private void SendInventoryPackets(InventoryItem item) private void SendInventoryPackets(Player player, InventoryItem item)
{ {
owner.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, item)); player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, item));
} }
private void SendInventoryPackets(List<InventoryItem> items) private void SendInventoryPackets(Player player, List<InventoryItem> items)
{ {
int currentIndex = 0; int currentIndex = 0;
while (true) while (true)
{ {
if (items.Count - currentIndex >= 64) if (items.Count - currentIndex >= 64)
owner.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, items, ref currentIndex)); player.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex >= 32) else if (items.Count - currentIndex >= 32)
owner.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, items, ref currentIndex)); player.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex >= 16) else if (items.Count - currentIndex >= 16)
owner.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, items, ref currentIndex)); player.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex > 1) else if (items.Count - currentIndex > 1)
owner.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, items, ref currentIndex)); player.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex == 1) else if (items.Count - currentIndex == 1)
{ {
owner.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, items[currentIndex])); player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, items[currentIndex]));
currentIndex++; currentIndex++;
} }
else else
break; break;
} }
} }
private void SendInventoryPackets(int startOffset) private void SendInventoryPackets(Player player, int startOffset)
{ {
int currentIndex = startOffset; int currentIndex = startOffset;
while (true) List<InventoryItem> lst = new List<InventoryItem>();
{ for (int i = 0; i < endOfListIndex; i++)
if (list.Count - currentIndex >= 64) lst.Add(list[i]);
owner.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, list, ref currentIndex));
else if (list.Count - currentIndex >= 32) while (true)
owner.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, list, ref currentIndex)); {
else if (list.Count - currentIndex >= 16) if (endOfListIndex - currentIndex >= 64)
owner.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, list, ref currentIndex)); player.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, lst, ref currentIndex));
else if (list.Count - currentIndex > 1) else if (endOfListIndex - currentIndex >= 32)
owner.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, list, ref currentIndex)); player.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, lst, ref currentIndex));
else if (list.Count - currentIndex == 1) else if (endOfListIndex - currentIndex >= 16)
{ player.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, lst, ref currentIndex));
owner.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, list[currentIndex])); else if (endOfListIndex - currentIndex > 1)
currentIndex++; player.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, lst, ref currentIndex));
} else if (endOfListIndex - currentIndex == 1)
else {
break; player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, list[currentIndex]));
currentIndex++;
}
else
break;
} }
} }
private void SendInventoryRemovePackets(ushort index) private void SendInventoryRemovePackets(Player player, ushort index)
{ {
owner.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, index)); player.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, index));
} }
private void SendInventoryRemovePackets(List<ushort> indexes) private void SendInventoryRemovePackets(Player player, List<ushort> indexes)
{ {
int currentIndex = 0; int currentIndex = 0;
while (true) while (true)
{ {
if (indexes.Count - currentIndex >= 64) if (indexes.Count - currentIndex >= 64)
owner.QueuePacket(InventoryRemoveX64Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); player.QueuePacket(InventoryRemoveX64Packet.BuildPacket(owner.actorId, indexes, ref currentIndex));
else if (indexes.Count - currentIndex >= 32) else if (indexes.Count - currentIndex >= 32)
owner.QueuePacket(InventoryRemoveX32Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); player.QueuePacket(InventoryRemoveX32Packet.BuildPacket(owner.actorId, indexes, ref currentIndex));
else if (indexes.Count - currentIndex >= 16) else if (indexes.Count - currentIndex >= 16)
owner.QueuePacket(InventoryRemoveX16Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); player.QueuePacket(InventoryRemoveX16Packet.BuildPacket(owner.actorId, indexes, ref currentIndex));
else if (indexes.Count - currentIndex > 1) else if (indexes.Count - currentIndex > 1)
owner.QueuePacket(InventoryRemoveX08Packet.BuildPacket(owner.actorId, indexes, ref currentIndex)); player.QueuePacket(InventoryRemoveX08Packet.BuildPacket(owner.actorId, indexes, ref currentIndex));
else if (indexes.Count - currentIndex == 1) else if (indexes.Count - currentIndex == 1)
{ {
owner.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, indexes[currentIndex])); player.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, indexes[currentIndex]));
currentIndex++; currentIndex++;
} }
else else
break; break;
} }
}
public void RefreshItem(Player player, InventoryItem item)
{
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(player, item);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void RefreshItem(Player player, params InventoryItem[] items)
{
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(player, items.ToList());
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void RefreshItem(Player player, List<InventoryItem> items)
{
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(player, items);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
} }
#endregion #endregion
#region Inventory Utils #region Client Updating
private 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);
}
Array.Clear(isDirty, 0, isDirty.Length);
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
//Send Updated Slots
SendInventoryPackets(player, items);
//Send Remove packets for tail end
SendInventoryRemovePackets(player, slotsToRemove);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
player.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
#endregion
#region Inventory Utils
public bool IsFull() public bool IsFull()
{ {
return list.Count >= inventoryCapacity; return endOfListIndex >= inventoryCapacity;
} }
public bool IsSpaceForAdd(uint itemId, int quantity) public bool IsSpaceForAdd(uint itemId, int quantity, int quality)
{ {
int quantityCount = quantity; int quantityCount = quantity;
for (int i = 0; i < list.Count; i++) for (int i = 0; i < endOfListIndex; i++)
{ {
InventoryItem item = list[i]; InventoryItem item = list[i];
ItemData gItem = Server.GetItemGamedata(item.itemId); ItemData gItem = Server.GetItemGamedata(item.itemId);
if (item.itemId == itemId && item.quantity < gItem.maxStack) if (item.itemId == itemId && item.quality == quality && item.quantity < gItem.maxStack)
{ {
quantityCount -= (gItem.maxStack - item.quantity); quantityCount -= (gItem.maxStack - item.quantity);
if (quantityCount <= 0) if (quantityCount <= 0)
@ -484,27 +500,61 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public bool HasItem(uint itemId) public bool HasItem(uint itemId)
{ {
return HasItem(itemId, 1); return HasItem(itemId, 1);
}
public bool HasItem(uint itemId, int minQuantity)
{
return HasItem(itemId, minQuantity, 1);
} }
public bool HasItem(uint itemId, int minQuantity) public bool HasItem(uint itemId, int minQuantity, int quality)
{ {
int count = 0; int count = 0;
foreach (InventoryItem item in list) for (int i = endOfListIndex - 1; i >= 0; i--)
{ {
if (item.itemId == itemId) InventoryItem item = list[i];
count += item.quantity;
Debug.Assert(item != null, "Item slot was null!!!");
if (count >= minQuantity)
return true; if (item.itemId == itemId && item.quality == quality)
count += item.quantity;
if (count >= minQuantity)
return true;
} }
return false; return false;
} }
public int GetNextEmptySlot() public int GetNextEmptySlot()
{ {
return list.Count == 0 ? 0 : list.Count(); return endOfListIndex;
}
private void doRealign()
{
int lastNullSlot = -1;
for (int i = 0; i < endOfListIndex; i++)
{
if (list[i] == null && lastNullSlot == -1)
{
lastNullSlot = i;
continue;
}
else if (list[i] != null && lastNullSlot != -1)
{
list[lastNullSlot] = list[i];
list[lastNullSlot].slot = (ushort)lastNullSlot;
list[i] = null;
isDirty[lastNullSlot] = true;
isDirty[i] = true;
lastNullSlot++;
}
}
endOfListIndex = lastNullSlot;
} }
#endregion #endregion

View file

@ -135,7 +135,8 @@ namespace FFXIVClassic_Map_Server.Actors
public uint homepoint = 0; public uint homepoint = 0;
public byte homepointInn = 0; public byte homepointInn = 0;
//Instancing //Retainer
RetainerMeetingRelationGroup retainerMeetingGroup = null;
public Retainer currentSpawnedRetainer = null; public Retainer currentSpawnedRetainer = null;
public bool sentRetainerSpawn = false; public bool sentRetainerSpawn = false;
@ -533,12 +534,12 @@ namespace FFXIVClassic_Map_Server.Actors
#region Inventory & Equipment #region Inventory & Equipment
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId)); QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
inventories[Inventory.NORMAL].SendFullInventory(); inventories[Inventory.NORMAL].SendFullInventory(this);
inventories[Inventory.CURRENCY].SendFullInventory(); inventories[Inventory.CURRENCY].SendFullInventory(this);
inventories[Inventory.KEYITEMS].SendFullInventory(); inventories[Inventory.KEYITEMS].SendFullInventory(this);
inventories[Inventory.BAZAAR].SendFullInventory(); inventories[Inventory.BAZAAR].SendFullInventory(this);
inventories[Inventory.MELDREQUEST].SendFullInventory(); inventories[Inventory.MELDREQUEST].SendFullInventory(this);
inventories[Inventory.LOOT].SendFullInventory(); inventories[Inventory.LOOT].SendFullInventory(this);
equipment.SendFullEquipment(false); equipment.SendFullEquipment(false);
playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId)); playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
#endregion #endregion
@ -1742,30 +1743,30 @@ namespace FFXIVClassic_Map_Server.Actors
chocoboAppearance = appearanceId; chocoboAppearance = appearanceId;
} }
public bool SpawnMyRetainer(Npc bell, int retainerIndex) public Retainer SpawnMyRetainer(Npc bell, int retainerIndex)
{ {
Tuple<uint, uint, string> retainerData = Database.GetRetainer(this, retainerIndex); Tuple<uint, uint, string> retainerData = Database.GetRetainer(this, retainerIndex);
ActorClass actorClass = Server.GetWorldManager().GetActorClass(retainerData.Item2); ActorClass actorClass = Server.GetWorldManager().GetActorClass(retainerData.Item2);
if (actorClass == null) if (actorClass == null)
return false; return null;
float distance = (float)Math.Sqrt(((positionX - bell.positionX) * (positionX - bell.positionX)) + ((positionZ - bell.positionZ) * (positionZ - bell.positionZ))); float distance = (float)Math.Sqrt(((positionX - bell.positionX) * (positionX - bell.positionX)) + ((positionZ - bell.positionZ) * (positionZ - bell.positionZ)));
float posX = bell.positionX - ((-1.0f * (bell.positionX - positionX)) / distance); float posX = bell.positionX - ((-1.0f * (bell.positionX - positionX)) / distance);
float posZ = bell.positionZ - ((-1.0f * (bell.positionZ - positionZ)) / distance); float posZ = bell.positionZ - ((-1.0f * (bell.positionZ - positionZ)) / distance);
Retainer retainer = new Retainer(retainerData.Item1, retainerData.Item3, actorClass, this, posX, bell.positionY, positionZ, (float)Math.Atan2(positionX - posX, positionZ - posZ)); Retainer retainer = new Retainer(retainerData.Item3, actorClass, this, posX, bell.positionY, positionZ, (float)Math.Atan2(positionX - posX, positionZ - posZ));
retainer.LoadEventConditions(actorClass.eventConditions); retainer.LoadEventConditions(actorClass.eventConditions);
//RetainerMeetingRelationGroup group = new RetainerMeetingRelationGroup(5555, this, retainer); retainerMeetingGroup = new RetainerMeetingRelationGroup(5555, this, retainer);
//group.SendGroupPackets(playerSession); retainerMeetingGroup.SendGroupPackets(playerSession);
currentSpawnedRetainer = retainer; currentSpawnedRetainer = retainer;
sentRetainerSpawn = false; sentRetainerSpawn = false;
return true; return retainer;
} }
public void DespawnMyRetainer() public void DespawnMyRetainer()
@ -1773,6 +1774,8 @@ namespace FFXIVClassic_Map_Server.Actors
if (currentSpawnedRetainer != null) if (currentSpawnedRetainer != null)
{ {
currentSpawnedRetainer = null; currentSpawnedRetainer = null;
retainerMeetingGroup.SendDeletePacket(playerSession);
retainerMeetingGroup = null;
} }
} }

View file

@ -23,12 +23,11 @@ namespace FFXIVClassic_Map_Server.dataobjects
public byte materia5 = 0; public byte materia5 = 0;
//Bare Minimum //Bare Minimum
public InventoryItem(uint id, uint itemId, ushort slot) public InventoryItem(uint id, uint itemId)
{ {
this.uniqueId = id; this.uniqueId = id;
this.itemId = itemId; this.itemId = itemId;
this.quantity = 1; this.quantity = 1;
this.slot = slot;
ItemData gItem = Server.GetItemGamedata(itemId); ItemData gItem = Server.GetItemGamedata(itemId);
itemType = gItem.isExclusive ? (byte)0x3 : (byte)0x0; itemType = gItem.isExclusive ? (byte)0x3 : (byte)0x0;
@ -55,12 +54,11 @@ namespace FFXIVClassic_Map_Server.dataobjects
this.materia5 = item.materia5; this.materia5 = item.materia5;
} }
public InventoryItem(uint uniqueId, uint itemId, int quantity, ushort slot, byte itemType, byte qualityNumber, int durability, ushort spiritbind, byte materia1, byte materia2, byte materia3, byte materia4, byte materia5) public InventoryItem(uint uniqueId, uint itemId, int quantity, byte itemType, byte qualityNumber, int durability, ushort spiritbind, byte materia1, byte materia2, byte materia3, byte materia4, byte materia5)
{ {
this.uniqueId = uniqueId; this.uniqueId = uniqueId;
this.itemId = itemId; this.itemId = itemId;
this.quantity = quantity; this.quantity = quantity;
this.slot = slot;
this.itemType = itemType; this.itemType = itemType;
this.quality = qualityNumber; this.quality = qualityNumber;
this.durability = durability; this.durability = durability;

View file

@ -169,7 +169,9 @@ namespace FFXIVClassic_World_Server
{ {
uint sessionId = subpacket.header.targetId; uint sessionId = subpacket.header.targetId;
Session session = GetSession(sessionId); Session session = GetSession(sessionId);
subpacket.DebugPrintSubPacket();
if (subpacket.gameMessage.opcode != 0x1 && subpacket.gameMessage.opcode != 0xca)
subpacket.DebugPrintSubPacket();
if (subpacket.gameMessage.opcode >= 0x1000) if (subpacket.gameMessage.opcode >= 0x1000)
{ {
//subpacket.DebugPrintSubPacket(); //subpacket.DebugPrintSubPacket();