Merge branch 'inventory_refactor' into develop

# Conflicts:
#	FFXIVClassic Map Server/Database.cs
#	FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
#	FFXIVClassic Map Server/WorldManager.cs
#	FFXIVClassic Map Server/actors/area/Area.cs
#	FFXIVClassic Map Server/actors/area/Zone.cs
#	FFXIVClassic Map Server/actors/chara/Character.cs
#	FFXIVClassic Map Server/actors/chara/npc/Npc.cs
#	FFXIVClassic Map Server/actors/chara/player/Inventory.cs
#	FFXIVClassic Map Server/actors/chara/player/Player.cs
#	FFXIVClassic Map Server/dataobjects/ZoneConnection.cs
#	FFXIVClassic Map Server/lua/LuaEngine.cs
#	FFXIVClassic Map Server/packets/send/Actor/AddActorPacket.cs
#	FFXIVClassic Map Server/packets/send/Actor/DeleteAllActorsPacket.cs
#	FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs
#	FFXIVClassic Map Server/packets/send/Actor/SetActorStatePacket.cs
#	FFXIVClassic Map Server/packets/send/Actor/SetActorStatusAllPacket.cs
#	FFXIVClassic Map Server/packets/send/Actor/SetActorStatusPacket.cs
#	FFXIVClassic Map Server/packets/send/Actor/_0x132Packet.cs
#	FFXIVClassic Map Server/packets/send/Actor/battle/BattleAction.cs
#	FFXIVClassic Map Server/packets/send/Actor/battle/BattleActionX10Packet.cs
#	FFXIVClassic Map Server/packets/send/Actor/battle/BattleActionX18Packet.cs
#	FFXIVClassic Map Server/packets/send/Actor/battle/CommandResultX00Packet.cs
#	FFXIVClassic Map Server/packets/send/Actor/events/SetEmoteEventCondition.cs
#	FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX08Packet.cs
#	data/scripts/commands/gm/giveitem.lua
This commit is contained in:
Filip Maj
2019-05-06 15:59:09 -04:00
202 changed files with 2713 additions and 1040 deletions

View File

@@ -23,6 +23,9 @@ using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.packets.receive.events;
using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
using FFXIVClassic_Map_Server.actors.chara.npc;
namespace FFXIVClassic_Map_Server.Actors
{
@@ -71,7 +74,6 @@ namespace FFXIVClassic_Map_Server.Actors
//Event Related
public uint currentEventOwner = 0;
public string currentEventName = "";
public Coroutine currentEventRunning;
//Player Info
@@ -84,9 +86,11 @@ namespace FFXIVClassic_Map_Server.Actors
public bool isGM = false;
public bool isZoneChanging = true;
//Inventory
private Dictionary<ushort, Inventory> inventories = new Dictionary<ushort, Inventory>();
private Equipment equipment;
//Trading
private Player otherTrader = null;
private ItemPackage myOfferings;
private bool isTradeAccepted = false;
private bool isTradeLocked = false;
//GC Related
public byte gcCurrent;
@@ -115,6 +119,10 @@ namespace FFXIVClassic_Map_Server.Actors
public uint homepoint = 0;
public byte homepointInn = 0;
//Nameplate Stuff
public uint currentLSPlate = 0;
public byte repairType = 0;
//Retainer
RetainerMeetingRelationGroup retainerMeetingGroup = null;
public Retainer currentSpawnedRetainer = null;
@@ -138,14 +146,14 @@ namespace FFXIVClassic_Map_Server.Actors
moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
inventories[Inventory.NORMAL] = new Inventory(this, MAXSIZE_INVENTORY_NORMAL, Inventory.NORMAL);
inventories[Inventory.KEYITEMS] = new Inventory(this, MAXSIZE_INVENTORY_KEYITEMS, Inventory.KEYITEMS);
inventories[Inventory.CURRENCY_CRYSTALS] = new Inventory(this, MAXSIZE_INVENTORY_CURRANCY, Inventory.CURRENCY_CRYSTALS);
inventories[Inventory.MELDREQUEST] = new Inventory(this, MAXSIZE_INVENTORY_MELDREQUEST, Inventory.MELDREQUEST);
inventories[Inventory.BAZAAR] = new Inventory(this, MAXSIZE_INVENTORY_BAZAAR, Inventory.BAZAAR);
inventories[Inventory.LOOT] = new Inventory(this, MAXSIZE_INVENTORY_LOOT, Inventory.LOOT);
itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, MAXSIZE_INVENTORY_NORMAL, ItemPackage.NORMAL);
itemPackages[ItemPackage.KEYITEMS] = new ItemPackage(this, MAXSIZE_INVENTORY_KEYITEMS, ItemPackage.KEYITEMS);
itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, MAXSIZE_INVENTORY_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
itemPackages[ItemPackage.MELDREQUEST] = new ItemPackage(this, MAXSIZE_INVENTORY_MELDREQUEST, ItemPackage.MELDREQUEST);
itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, MAXSIZE_INVENTORY_BAZAAR, ItemPackage.BAZAAR);
itemPackages[ItemPackage.LOOT] = new ItemPackage(this, MAXSIZE_INVENTORY_LOOT, ItemPackage.LOOT);
equipment = new Equipment(this, inventories[Inventory.NORMAL], MAXSIZE_INVENTORY_EQUIPMENT, Inventory.EQUIPMENT);
equipment = new Equipment(this, itemPackages[ItemPackage.NORMAL], MAXSIZE_INVENTORY_EQUIPMENT, ItemPackage.EQUIPMENT);
//Set the Skill level caps of all FFXIV (classes)skills to 50
for (int i = 0; i < charaWork.battleSave.skillLevelCap.Length; i++)
@@ -228,7 +236,7 @@ namespace FFXIVClassic_Map_Server.Actors
Database.LoadPlayerCharacter(this);
lastPlayTimeUpdate = Utils.UnixTimeStampUTC();
this.aiContainer = new AIContainer(this, new PlayerController(this), null, new TargetFind(this));
allegiance = CharacterTargetingAllegiance.Player;
CalculateBaseStats();
@@ -474,7 +482,18 @@ namespace FFXIVClassic_Map_Server.Actors
propPacketUtil.AddProperty(String.Format("work.guildleveChecked[{0}]", i));
}
//NPC Linkshell
//Bazaar
CheckBazaarFlags(true);
if (charaWork.eventSave.repairType != 0)
propPacketUtil.AddProperty("charaWork.eventSave.repairType");
if (charaWork.eventTemp.bazaarRetail)
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRetail");
if (charaWork.eventTemp.bazaarRepair)
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRepair");
if (charaWork.eventTemp.bazaarMateria)
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarMateria");
//NPC Linkshell
for (int i = 0; i < playerWork.npcLinkshellChatCalling.Length; i++)
{
if (playerWork.npcLinkshellChatCalling[i] != false)
@@ -514,13 +533,13 @@ namespace FFXIVClassic_Map_Server.Actors
//GetSpawnPackets(actorId, spawnType).DebugPrintPacket();
#region Inventory & Equipment
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
inventories[Inventory.NORMAL].SendFullInventory(this);
inventories[Inventory.CURRENCY_CRYSTALS].SendFullInventory(this);
inventories[Inventory.KEYITEMS].SendFullInventory(this);
inventories[Inventory.BAZAAR].SendFullInventory(this);
inventories[Inventory.MELDREQUEST].SendFullInventory(this);
inventories[Inventory.LOOT].SendFullInventory(this);
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
itemPackages[ItemPackage.NORMAL].SendFullInventory(this);
itemPackages[ItemPackage.CURRENCY_CRYSTALS].SendFullInventory(this);
itemPackages[ItemPackage.KEYITEMS].SendFullInventory(this);
itemPackages[ItemPackage.BAZAAR].SendFullInventory(this);
itemPackages[ItemPackage.MELDREQUEST].SendFullInventory(this);
itemPackages[ItemPackage.LOOT].SendFullInventory(this);
equipment.SendFullEquipment(false);
playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
#endregion
@@ -623,6 +642,33 @@ namespace FFXIVClassic_Map_Server.Actors
}
}
public void BroadcastPackets(List<SubPacket> packets, bool sendToSelf)
{
foreach (SubPacket packet in packets)
{
if (sendToSelf)
{
SubPacket clonedPacket = new SubPacket(packet, actorId);
QueuePacket(clonedPacket);
}
foreach (Actor a in playerSession.actorInstanceList)
{
if (a is Player)
{
Player p = (Player)a;
if (p.Equals(this))
continue;
SubPacket clonedPacket = new SubPacket(packet, a.actorId);
p.QueuePacket(clonedPacket);
}
}
}
}
public void BroadcastPacket(SubPacket packet, bool sendToSelf)
{
if (sendToSelf)
@@ -937,6 +983,8 @@ namespace FFXIVClassic_Map_Server.Actors
public void PrepareClassChange(byte classId)
{
//If new class, init abilties and level
if (charaWork.battleSave.skillLevel[classId - 1] <= 0)
UpdateClassLevel(classId, 1);
SendCharaExpInfo();
}
@@ -1003,6 +1051,16 @@ namespace FFXIVClassic_Map_Server.Actors
RecalculateStats();
}
public void UpdateClassLevel(byte classId, short level)
{
Database.PlayerCharacterUpdateClassLevel(this, classId, level);
charaWork.battleSave.skillLevel[classId - 1] = level;
ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("charaWork/exp", this);
propertyBuilder.AddProperty(String.Format("charaWork.battleSave.skillLevel[{0}]", classId-1));
List<SubPacket> packets = propertyBuilder.Done();
QueuePackets(packets);
}
public void GraphicChange(int slot, InventoryItem invItem)
{
if (invItem == null)
@@ -1048,18 +1106,68 @@ namespace FFXIVClassic_Map_Server.Actors
BroadcastPacket(CreateAppearancePacket(), true);
}
public Inventory GetInventory(ushort type)
public void SetRepairRequest(byte type)
{
if (inventories.ContainsKey(type))
return inventories[type];
else
return null;
charaWork.eventSave.repairType = type;
ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/bazaar", this);
propPacketUtil.AddProperty("charaWork.eventSave.repairType");
QueuePackets(propPacketUtil.Done());
}
public void CheckBazaarFlags(bool noUpdate = false)
{
bool isDealing = false, isRepairing = false, seekingItem = false;
lock (GetItemPackage(ItemPackage.BAZAAR))
{
foreach (InventoryItem item in GetItemPackage(ItemPackage.BAZAAR).GetRawList())
{
if (item == null)
break;
if (item.GetBazaarMode() == InventoryItem.TYPE_SINGLE || item.GetBazaarMode() == InventoryItem.TYPE_MULTI || item.GetBazaarMode() == InventoryItem.TYPE_STACK)
isDealing = true;
if (item.GetBazaarMode() == InventoryItem.TYPE_SEEK_REPAIR)
isRepairing = true;
if (item.GetBazaarMode() == InventoryItem.TYPE_SEEK_ITEM)
isDealing = true;
if (isDealing && isRepairing && seekingItem)
break;
}
}
bool doUpdate = false;
ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/bazaar", this);
if (charaWork.eventTemp.bazaarRetail != isDealing)
{
charaWork.eventTemp.bazaarRetail = isDealing;
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRetail");
doUpdate = true;
}
if (charaWork.eventTemp.bazaarRepair != isRepairing)
{
charaWork.eventTemp.bazaarRepair = isRepairing;
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRepair");
doUpdate = true;
}
if (charaWork.eventTemp.bazaarMateria != (GetItemPackage(ItemPackage.MELDREQUEST).GetCount() != 0))
{
charaWork.eventTemp.bazaarMateria = GetItemPackage(ItemPackage.MELDREQUEST).GetCount() != 0;
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarMateria");
doUpdate = true;
}
if (!noUpdate && doUpdate)
BroadcastPackets(propPacketUtil.Done(), true);
}
public int GetCurrentGil()
{
if (GetInventory(Inventory.CURRENCY_CRYSTALS).HasItem(1000001))
return GetInventory(Inventory.CURRENCY_CRYSTALS).GetItemByCatelogId(1000001).quantity;
if (HasItem(1000001))
return GetItemPackage(ItemPackage.CURRENCY_CRYSTALS).GetItemByCatelogId(1000001).quantity;
else
return 0;
}
@@ -1576,8 +1684,10 @@ namespace FFXIVClassic_Map_Server.Actors
public void SendMyTradeToPlayer(Player player)
{
Inventory tradeInventory = new Inventory(this, 4, Inventory.TRADE);
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)
@@ -1590,13 +1700,15 @@ namespace FFXIVClassic_Map_Server.Actors
public void StartEvent(Actor owner, EventStartPacket start)
{
currentEventOwner = start.scriptOwnerActorID;
currentEventName = start.triggerName;
LuaEngine.GetInstance().EventStarted(this, owner, start);
}
public void UpdateEvent(EventUpdatePacket update)
{
LuaEngine.GetInstance().OnEventUpdate(this, update.luaParams);
}
LuaEngine.GetInstance().OnEventUpdate(this, update.luaParams);
}
public void KickEvent(Actor actor, string conditionName, params object[] parameters)
{
@@ -1604,7 +1716,18 @@ namespace FFXIVClassic_Map_Server.Actors
return;
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, conditionName, lParams);
SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, 0x75dc1705, conditionName, lParams);
spacket.DebugPrintSubPacket();
QueuePacket(spacket);
}
public void KickEventSpecial(Actor actor, uint unknown, string conditionName, params object[] parameters)
{
if (actor == null)
return;
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, unknown, conditionName, lParams);
spacket.DebugPrintSubPacket();
QueuePacket(spacket);
}
@@ -1612,7 +1735,7 @@ namespace FFXIVClassic_Map_Server.Actors
public void SetEventStatus(Actor actor, string conditionName, bool enabled, byte unknown)
{
QueuePacket(packets.send.actor.events.SetEventStatus.BuildPacket(actor.actorId, enabled, unknown, conditionName));
}
}
public void RunEventFunction(string functionName, params object[] parameters)
{
@@ -2572,5 +2695,127 @@ namespace FFXIVClassic_Map_Server.Actors
return equippedItem != null && equippedItem.itemId == itemId;
}
public Retainer GetSpawnedRetainer()
{
return currentSpawnedRetainer;
}
public void StartTradeTransaction(Player otherPlayer)
{
myOfferings = new ItemPackage(this, 4, ItemPackage.TRADE, true);
ItemPackage otherPlayerOfferings = new ItemPackage(otherPlayer, 4, ItemPackage.TRADE, true);
myOfferings.StartSendUpdate();
myOfferings.SendUpdatePackets(this);
myOfferings.SendUpdatePackets(otherPlayer);
myOfferings.DoneSendUpdate();
otherTrader = otherPlayer;
isTradeAccepted = false;
}
public Player GetOtherTrader()
{
return otherTrader;
}
public ItemPackage GetTradeOfferings()
{
return myOfferings;
}
public bool IsTrading()
{
return otherTrader != null;
}
public bool IsTradeAccepted()
{
return isTradeAccepted;
}
public void AddTradeItem(ushort slot, ushort linkedSlot, int subquantity)
{
if (!IsTrading())
return;
InventoryItem mine = itemPackages[ItemPackage.NORMAL].GetItemAtSlot(linkedSlot);
InventoryItem tradeItem = new InventoryItem(mine, slot);
myOfferings.StartSendUpdate();
myOfferings.AddItem(mine.itemId, mine.quantity, mine.quality);
myOfferings.SendUpdatePackets(otherTrader);
myOfferings.DoneSendUpdate();
}
public void AddTradeGil(int quantity)
{
if (!IsTrading())
return;
myOfferings.StartSendUpdate();
myOfferings.AddItem(1000001, quantity, 1);
myOfferings.SendUpdatePackets(otherTrader);
myOfferings.DoneSendUpdate();
}
public void RemoveTradeItem(ushort slot)
{
if (!IsTrading())
return;
myOfferings.StartSendUpdate();
myOfferings.RemoveItemAtSlot(slot);
myOfferings.SendUpdatePackets(otherTrader);
myOfferings.DoneSendUpdate();
}
public void ClearTradeItems(ushort slot)
{
if (!IsTrading())
return;
myOfferings.StartSendUpdate();
myOfferings.Clear();
myOfferings.SendUpdatePackets(otherTrader);
myOfferings.DoneSendUpdate();
}
public void AcceptTrade(bool accepted)
{
if (!IsTrading())
return;
isTradeAccepted = accepted;
}
public void FinishTradeTransaction()
{
isTradeAccepted = false;
myOfferings = null;
otherTrader = null;
}
public void Test()
{
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
QueuePacket(InventorySetBeginPacket.BuildPacket(actorId, 4, ItemPackage.TRADE));
QueuePacket(InventoryRemoveX01Packet.BuildPacket(actorId, 1));
QueuePacket(InventorySetEndPacket.BuildPacket(actorId));
QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
public void Test2()
{
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
QueuePacket(InventorySetBeginPacket.BuildPacket(actorId, 4, ItemPackage.TRADE));
QueuePacket(EquipmentListX01Packet.BuildPacket(actorId, 1, 1));
QueuePacket(InventorySetEndPacket.BuildPacket(actorId));
QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
}
}