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

Refactoring Equipment class. Fixed inital inventory setup due to missing addItem() (now addItems) function. Added Jorge's refactored Retainer manager script.

This commit is contained in:
Filip Maj 2019-05-12 15:03:34 -04:00
parent d673670604
commit 267961233f
4 changed files with 229 additions and 155 deletions

View file

@ -26,11 +26,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public const int SLOT_RIGHTFINGER = 21; public const int SLOT_RIGHTFINGER = 21;
public const int SLOT_LEFTFINGER = 22; public const int SLOT_LEFTFINGER = 22;
private Player owner; readonly private Player owner;
private ushort inventoryCapacity; readonly private ushort inventoryCapacity;
private ushort inventoryCode; readonly private ushort inventoryCode;
private InventoryItem[] list; private InventoryItem[] list;
private ItemPackage normalInventory; readonly private ItemPackage normalInventory;
private bool writeToDB = true; private bool writeToDB = true;
@ -43,62 +43,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
this.normalInventory = normalInventory; this.normalInventory = normalInventory;
} }
public InventoryItem GetItemAtSlot(ushort slot)
{
if (slot < list.Length)
return list[slot];
else
return null;
}
public void SendCheckEquipmentToPlayer(Player toPlayer)
{
List<InventoryItem> items = new List<InventoryItem>();
for (ushort i = 0; i < list.Length; i++)
{
if (list[i] != null)
{
InventoryItem equipItem = new InventoryItem(list[i], i);
items.Add(equipItem);
}
}
toPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, 0x23, ItemPackage.EQUIPMENT_OTHERPLAYER));
int currentIndex = 0;
while (true)
{
if (items.Count - currentIndex >= 16)
toPlayer.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex > 1)
toPlayer.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex == 1)
{
toPlayer.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, items[currentIndex]));
currentIndex++;
}
else
break;
}
toPlayer.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void SendFullEquipment(bool DoClear)
{
List<ushort> slotsToUpdate = new List<ushort>();
for (ushort i = 0; i < list.Length; i++)
{
if (list[i] == null && DoClear)
slotsToUpdate.Add(0);
else if (list[i] != null)
slotsToUpdate.Add(i);
}
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendEquipmentPackets(slotsToUpdate);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void SetEquipment(ushort[] slots, ushort[] itemSlots) public void SetEquipment(ushort[] slots, ushort[] itemSlots)
{ {
if (slots.Length != itemSlots.Length) if (slots.Length != itemSlots.Length)
@ -116,7 +60,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
} }
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendFullEquipment(false); SendFullEquipment(owner);
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
} }
@ -157,7 +101,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
normalInventory.RefreshItem(owner, item); normalInventory.RefreshItem(owner, item);
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendEquipmentPackets(slot, item); SendSingleEquipmentUpdatePacket(slot, item);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
@ -179,52 +123,23 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
if (writeToDB) if (writeToDB)
Database.UnequipItem(owner, slot); Database.UnequipItem(owner, slot);
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
normalInventory.RefreshItem(owner, list[slot]); normalInventory.RefreshItem(owner, list[slot]);
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendEquipmentPackets(slot, null); SendSingleEquipmentUpdatePacket(slot, null);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
list[slot] = null; list[slot] = null;
owner.RecalculateStats(); owner.RecalculateStats();
} }
private void SendEquipmentPackets(ushort equipSlot, InventoryItem item) public InventoryItem GetItemAtSlot(ushort slot)
{ {
if (item == null) if (slot < list.Length)
owner.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, equipSlot)); return list[slot];
else else
owner.QueuePacket(EquipmentListX01Packet.BuildPacket(owner.actorId, equipSlot, item.slot)); return null;
}
private void SendEquipmentPackets(List<ushort> slotsToUpdate)
{
int currentIndex = 0;
while (true)
{
if (slotsToUpdate.Count - currentIndex >= 64)
owner.QueuePacket(EquipmentListX64Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex >= 32)
owner.QueuePacket(EquipmentListX32Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex >= 16)
owner.QueuePacket(EquipmentListX16Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex > 1)
owner.QueuePacket(EquipmentListX08Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex == 1)
{
owner.QueuePacket(EquipmentListX01Packet.BuildPacket(owner.actorId, slotsToUpdate[currentIndex], list[slotsToUpdate[currentIndex]].slot));
currentIndex++;
}
else
break;
}
} }
public int GetCapacity() public int GetCapacity()
@ -232,5 +147,66 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
return list.Length; return list.Length;
} }
#region Packet Functions
private void SendSingleEquipmentUpdatePacket(ushort equipSlot, InventoryItem item)
{
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
if (item == null)
owner.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, equipSlot));
else
owner.QueuePacket(EquipmentListX01Packet.BuildPacket(owner.actorId, equipSlot, item.slot));
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
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;
}
}
public void SendFullEquipment()
{
SendFullEquipment(owner);
}
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, inventoryCapacity, inventoryCode));
else
targetPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, 0x23, ItemPackage.EQUIPMENT_OTHERPLAYER));
SendEquipmentPackets(slotsToUpdate, targetPlayer);
targetPlayer.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
#endregion
} }
} }

View file

@ -122,6 +122,31 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
return AddItem(itemId, quantity, 1); return AddItem(itemId, quantity, 1);
} }
public bool AddItems(uint[] itemIds)
{
bool canAdd = GetFreeSlots() - itemIds.Length >= 0;
if (canAdd)
{
foreach (uint id in itemIds)
{
ItemData gItem = Server.GetItemGamedata(id);
InventoryItem.ItemModifier modifiers = null;
if (gItem.durability != 0)
{
modifiers = new InventoryItem.ItemModifier();
modifiers.durability = (uint)gItem.durability;
}
InventoryItem addedItem = Database.CreateItem(id, Math.Min(1, gItem.maxStack), 0, modifiers);
addedItem.RefreshPositioning(owner, itemPackageCode, (ushort)endOfListIndex);
isDirty[endOfListIndex] = true;
list[endOfListIndex++] = addedItem;
DoDatabaseAdd(addedItem);
}
}
return canAdd;
}
public INV_ERROR AddItem(InventoryItem itemRef) public INV_ERROR AddItem(InventoryItem itemRef)
{ {
//If it isn't a single item (ie: armor) just add like normal (not valid for BAZAAR) //If it isn't a single item (ie: armor) just add like normal (not valid for BAZAAR)
@ -600,7 +625,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
//If player is updating their normal inventory, we need to send //If player is updating their normal inventory, we need to send
//an equip update as well to resync the slots. //an equip update as well to resync the slots.
if (player.Equals(owner) && itemPackageCode == NORMAL) if (player.Equals(owner) && itemPackageCode == NORMAL)
player.GetEquipment().SendFullEquipment(true); player.GetEquipment().SendFullEquipment();
player.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); player.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
} }
@ -625,6 +650,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
return endOfListIndex >= itemPackageCapacity; return endOfListIndex >= itemPackageCapacity;
} }
public int GetFreeSlots()
{
return itemPackageCapacity - endOfListIndex;
}
public bool IsSpaceForAdd(uint itemId, int quantity, int quality) public bool IsSpaceForAdd(uint itemId, int quantity, int quality)
{ {
int quantityCount = quantity; int quantityCount = quantity;

View file

@ -537,7 +537,7 @@ namespace FFXIVClassic_Map_Server.Actors
itemPackages[ItemPackage.BAZAAR].SendFullInventory(this); itemPackages[ItemPackage.BAZAAR].SendFullInventory(this);
itemPackages[ItemPackage.MELDREQUEST].SendFullInventory(this); itemPackages[ItemPackage.MELDREQUEST].SendFullInventory(this);
itemPackages[ItemPackage.LOOT].SendFullInventory(this); itemPackages[ItemPackage.LOOT].SendFullInventory(this);
equipment.SendFullEquipment(false); equipment.SendFullEquipment();
playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId)); playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
#endregion #endregion
@ -1675,7 +1675,7 @@ namespace FFXIVClassic_Map_Server.Actors
return; return;
QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId)); QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId));
toBeExamined.GetEquipment().SendCheckEquipmentToPlayer(this); toBeExamined.GetEquipment().SendFullEquipment(this);
QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId)); QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId));
} }

View file

@ -13,65 +13,133 @@ eventTalkStepFinalAnswer(actorClassId) - Confirm Dialog
eventTalkStepError(errorCode) - Error dialog, 1: No Extra Retainers, 2: Server Busy. eventTalkStepError(errorCode) - Error dialog, 1: No Extra Retainers, 2: Server Busy.
eventTalkStepFinish() eventTalkStepFinish()
--]] --]]
require ("global") require ("global")
function init(npc) function init(npc)
return false, false, 0, 0; return false, false, 0, 0;
end end
function onEventStarted(player, npc, triggerName) function onEventStarted(player, npc, triggerName)
introChoice = callClientFunction(player, "newEventTalkStep1", false); local npcActorClass = npc:GetActorClassId()
local retainerIndex = 3001100;
local cutscene = "rtn0l010" -- Defaulting to Limsa for now for testing
if (introChoice == 1) then if npcActorClass == 1000166 then
cutscene = "rtn0l010";
retainerIndex = 3001101;
elseif npcActorClass == 1000865 then
cutscene = "rtn0u010";
retainerIndex = 3002101;
elseif npcActorClass == 1001184 then
cutscene = "rtn0g010";
retainerIndex = 3003101;
else
return;
end
raceChoice = callClientFunction(player, "eventTalkStep2");
while (true) do introChoice = callClientFunction(player, "newEventTalkStep1", false);
if (retainerChoice == 0) then if (introChoice == 1) then
raceChoice = callClientFunction(player, "eventTalkStep22");
end
if (raceChoice == 0) then -- Choose Retainer or Random
--Choose random actorId raceChoice = callClientFunction(player, "eventTalkStep2");
elseif (raceChoice > 0) then
--Choose 5 random but correct actor ids
retainerChoice = callClientFunction(player, "eventTaklSelectCutSeane", "rtn0g010", 0x2DCB1A, 0x2DCB1A, 0x2DCB1A, 0x2DCB1A, 0x2DCB1A);
if (retainerChoice == -1) then while (true) do
player:EndEvent();
return;
elseif (retainerChoice > 0) then
--Retainer chosen, choose name
retainerName = callClientFunction(player, "eventTalkStep4", 0x2DCB1A);
if (retainerName ~= "") then
confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", 0x2DCB1A);
if (confirmChoice == 1) then if (retainerChoice == 0) then
callClientFunction(player, "eventTalkStepFinish"); raceChoice = callClientFunction(player, "eventTalkStep22");
player:EndEvent(); end
return;
elseif (confirmChoice == 3) then
raceChoice = 0;
else
player:EndEvent();
return;
end
end
end if (raceChoice == 0) then
else --Choose random actorId from a valid set for the city
break;
end
end math.randomseed(os.time());
local randomRetainer = math.random(retainerIndex, (retainerIndex+74));
end retainerName = callClientFunction(player, "eventTalkStep4", randomRetainer);
player:EndEvent(); if (retainerName ~= "") then
confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", randomRetainer);
if (confirmChoice == 1) then
callClientFunction(player, "eventTalkStepFinish");
player:EndEvent();
return;
elseif (confirmChoice == 3) then
raceChoice = 0;
else
player:EndEvent();
return;
end
else
callClientFunction(player, "eventTalkStepBreak");
raceChoice = -1;
end
elseif (raceChoice > 0) and (raceChoice < 16) then
--Choose 5 random but correct actor ids for the city and race/tribe
local retainerRace = ((retainerIndex) + (5*(raceChoice-1)));
local retainerRaceChoices = {retainerRace, retainerRace+1, retainerRace+2, retainerRace+3, retainerRace+4};
-- Randomize the appearance order of the available five
shuffle(retainerRaceChoices);
retainerChoice = callClientFunction(player, "eventTaklSelectCutSeane", cutscene, retainerRaceChoices[1], retainerRaceChoices[2], retainerRaceChoices[3], retainerRaceChoices[4], retainerRaceChoices[5]);
if (retainerChoice == -1) then
player:EndEvent();
return;
elseif (retainerChoice > 0) then
--Retainer chosen, choose name
retainerName = callClientFunction(player, "eventTalkStep4", retainerRaceChoices[retainerChoice]);
if (retainerName ~= "") then
confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", retainerRaceChoices[retainerChoice]);
if (confirmChoice == 1) then
callClientFunction(player, "eventTalkStepFinish");
player:EndEvent();
return;
elseif (confirmChoice == 3) then
retainerChoice = 0;
else
player:EndEvent();
return;
end
else
callClientFunction(player, "eventTalkStepBreak");
raceChoice = -1;
end
end
else
break;
end
end
end
player:EndEvent();
end
function shuffle(tbl)
for i = #tbl, 2, -1 do
local j = math.random(i)
tbl[i], tbl[j] = tbl[j], tbl[i]
end
return tbl
end end