Added UnequipAbility function, made EquipAbility work with zero indexed hotbar database, added new checks to EquipAbilityCommand.lua

This commit is contained in:
yogurt 2017-08-29 09:00:09 -05:00
parent 91afda04ca
commit c3fd8f917e
3 changed files with 124 additions and 89 deletions

View File

@ -1259,6 +1259,8 @@ namespace FFXIVClassic_Map_Server
} }
} }
} }
else
UnequipAbility(player, hotbarSlot);
} }
//Unequipping is done by sending an equip packet with 2700083200 as the ability and the hotbar slot of the action being unequipped //Unequipping is done by sending an equip packet with 2700083200 as the ability and the hotbar slot of the action being unequipped

View File

@ -975,6 +975,11 @@ namespace FFXIVClassic_Map_Server.Actors
charaWork.parameterSave.state_mainSkill[0] = classId; charaWork.parameterSave.state_mainSkill[0] = classId;
charaWork.parameterSave.state_mainSkillLevel = charaWork.battleSave.skillLevel[classId-1]; charaWork.parameterSave.state_mainSkillLevel = charaWork.battleSave.skillLevel[classId-1];
playerWork.restBonusExpRate = 0.0f; playerWork.restBonusExpRate = 0.0f;
for(int i = charaWork.commandBorder; i < charaWork.command.Length; i++)
{
charaWork.command[i] = 0;
charaWork.commandCategory[i] = 0;
}
ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("charaWork/stateForAll", this); ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("charaWork/stateForAll", this);
@ -1847,95 +1852,89 @@ namespace FFXIVClassic_Map_Server.Actors
public void EquipAbility(ushort hotbarSlot, ushort commandId) public void EquipAbility(ushort hotbarSlot, ushort commandId)
{ {
//if (charaWork.commandAcquired[commandId]) var ability = Server.GetWorldManager().GetBattleCommand(commandId);
uint trueCommandId = commandId | 0xA0F00000;
ushort trueHotbarSlot = (ushort)(hotbarSlot + charaWork.commandBorder - 1);
ushort endOfHotbar = (ushort)(charaWork.commandBorder + 30);
List<ushort> slotsToUpdate = new List<ushort>();
bool canEquip = true;
//If the ability is already equipped we need this so we can move its recast timer to the new slot
uint oldRecast = 0;
//Check if the command is already on the hotbar
ushort oldSlot = FindFirstCommandSlotById(trueCommandId);
bool isAlreadyEquipped = oldSlot < endOfHotbar;
//New ability being added to the hotbar, set truehotbarslot to the first open slot.
if (hotbarSlot == 0)
{ {
uint trueCommandId = 0xA0F00000 | commandId; //If the ability is already equipped, we can't add it to the hotbar again.
ushort trueHotbarSlot = (ushort)(hotbarSlot + charaWork.commandBorder - 1); if (isAlreadyEquipped)
ushort endOfHotbar = (ushort)(charaWork.commandBorder + 30); canEquip = false;
List<ushort> slotsToUpdate = new List<ushort>(); else
if (trueCommandId != 2700083200) trueHotbarSlot = FindFirstCommandSlotById(0);
{
bool canEquip = true;
bool isAlreadyEquipped = false;
//If hotbar slot is 0, look for the first open slot
if (hotbarSlot == 0)
{
trueHotbarSlot = FindFirstCommandSlotById(0);
ushort equippedSlot = FindFirstCommandSlotById(trueCommandId);
//We can only equip a command if there is an open hotbar slot and if the command was not found in the hotbar.
canEquip = trueHotbarSlot < endOfHotbar && equippedSlot >= endOfHotbar;
//If the command was found in the hotbar, mark it as already equipped
isAlreadyEquipped = equippedSlot < endOfHotbar;
}
//If the slot the command is being moved to is occupied, move that command to the slot currently occupied by the command being placed.
else if (charaWork.command[trueHotbarSlot] != trueCommandId)
{
//Search for where the ability we're equipping is already equipped
ushort oldSlot = FindFirstCommandSlotById(trueCommandId);
//If the command was found, update the old slot, otherwise it will just be overwritten
if (oldSlot < endOfHotbar)
{
charaWork.command[oldSlot] = charaWork.command[trueHotbarSlot];
slotsToUpdate.Add(oldSlot);
//Need to update the old slot's recast timer as well
charaWork.parameterTemp.maxCommandRecastTime[oldSlot - charaWork.commandBorder] = charaWork.parameterTemp.maxCommandRecastTime[trueHotbarSlot - charaWork.commandBorder];
//I don't know how the game handled moving abilities in terms of cooldowns.
//I'm assuming they just keep whatever their current cooldown was instead of being reset to their max but SE were dicks in 1.0 so who knows
charaWork.parameterSave.commandSlot_recastTime[oldSlot - charaWork.commandBorder] = charaWork.parameterSave.commandSlot_recastTime[trueHotbarSlot - charaWork.commandBorder];
Database.EquipAbility(this, oldSlot, charaWork.command[trueHotbarSlot], charaWork.parameterSave.commandSlot_recastTime[oldSlot - charaWork.commandBorder]);
}
}
if (canEquip)
{
charaWork.command[trueHotbarSlot] = trueCommandId;
charaWork.commandCategory[trueHotbarSlot] = 1;
//Set recast time
ushort maxRecastTime = (ushort)Server.GetWorldManager().GetBattleCommand(commandId).recastTimeSeconds;
uint recastEnd = Utils.UnixTimeStampUTC() + maxRecastTime;
charaWork.parameterTemp.maxCommandRecastTime[trueHotbarSlot - charaWork.commandBorder] = maxRecastTime;
charaWork.parameterSave.commandSlot_recastTime[trueHotbarSlot - charaWork.commandBorder] = recastEnd;
slotsToUpdate.Add(trueHotbarSlot);
Database.EquipAbility(this, trueHotbarSlot, trueCommandId, recastEnd);
//"[Command] set."
SendGameMessage(Server.GetWorldManager().GetActor(), 30603, 0x20, 0, (int)commandId);
}
//Ability is already equipped
else if (isAlreadyEquipped)
{
//"That action is already set to an action slot."
SendGameMessage(Server.GetWorldManager().GetActor(), 30719, 0x20, 0);
}
//Hotbar full
else
{
//"You cannot set any more actions."
SendGameMessage(Server.GetWorldManager().GetActor(), 30720, 0x20, 0);
}
}
//Unequip command
else if (trueCommandId == 2700083200 && charaWork.command[trueHotbarSlot] != 0)
{
//Need to get the commandId this way because when unequipping an ability the commandId is 0.
SendGameMessage(Server.GetWorldManager().GetActor(), 30604, 0x20, 0, charaWork.command[trueHotbarSlot] ^ 2700083200);
Database.UnequipAbility(this, trueHotbarSlot);
charaWork.command[trueHotbarSlot] = 0;
slotsToUpdate.Add(trueHotbarSlot);
}
UpdateHotbar(slotsToUpdate);
} }
//action not acquired //If the slot we're moving an command to already has an command there, move that command to the new command's old slot.
// else //Only need to do this if the new command is already equipped, otherwise we just write over the command there
else if (charaWork.command[trueHotbarSlot] != trueCommandId && isAlreadyEquipped)
{ {
//"You have not yet acquired that action." //Move the command to oldslot
//SendGameMessage(Server.GetWorldManager().GetActor(), 30742, 0x20, 0, 0); charaWork.command[oldSlot] = charaWork.command[trueHotbarSlot];
//Move recast timers to old slot as well and store the old recast timer
oldRecast = charaWork.parameterSave.commandSlot_recastTime[oldSlot - charaWork.commandBorder];
charaWork.parameterTemp.maxCommandRecastTime[oldSlot - charaWork.commandBorder] = charaWork.parameterTemp.maxCommandRecastTime[trueHotbarSlot - charaWork.commandBorder];
charaWork.parameterSave.commandSlot_recastTime[oldSlot - charaWork.commandBorder] = charaWork.parameterSave.commandSlot_recastTime[trueHotbarSlot - charaWork.commandBorder];
//Save changes
Database.EquipAbility(this, (ushort)(oldSlot - charaWork.commandBorder), charaWork.command[oldSlot], charaWork.parameterSave.commandSlot_recastTime[oldSlot - charaWork.commandBorder]);
slotsToUpdate.Add(oldSlot);
} }
if (canEquip)
{
charaWork.command[trueHotbarSlot] = trueCommandId;
charaWork.commandCategory[trueHotbarSlot] = 1;
//Set recast time. If the ability was already equipped, then we use the previous recast timer instead of setting a new one
ushort maxRecastTime = (ushort)ability.recastTimeSeconds;
uint recastEnd = isAlreadyEquipped ? oldRecast : Utils.UnixTimeStampUTC() + maxRecastTime;
charaWork.parameterTemp.maxCommandRecastTime[trueHotbarSlot - charaWork.commandBorder] = maxRecastTime;
charaWork.parameterSave.commandSlot_recastTime[trueHotbarSlot - charaWork.commandBorder] = recastEnd;
slotsToUpdate.Add(trueHotbarSlot);
Database.EquipAbility(this, (ushort) (trueHotbarSlot - charaWork.commandBorder), trueCommandId, recastEnd);
//"[Command] set."
if (!isAlreadyEquipped)
SendGameMessage(Server.GetWorldManager().GetActor(), 30603, 0x20, 0, commandId);
}
//Ability is already equipped
else if (isAlreadyEquipped)
{
//"That action is already set to an action slot."
SendGameMessage(Server.GetWorldManager().GetActor(), 30719, 0x20, 0);
}
//Hotbar full
else
{
//"You cannot set any more actions."
SendGameMessage(Server.GetWorldManager().GetActor(), 30720, 0x20, 0);
}
UpdateHotbar(slotsToUpdate);
}
public void UnequipAbility(ushort hotbarSlot)
{
List<ushort> slotsToUpdate = new List<ushort>();
ushort trueHotbarSlot = (ushort)(hotbarSlot + charaWork.commandBorder - 1);
uint commandId = charaWork.command[trueHotbarSlot];
Database.UnequipAbility(this, (ushort)(trueHotbarSlot - charaWork.commandBorder));
charaWork.command[trueHotbarSlot] = 0;
slotsToUpdate.Add(trueHotbarSlot);
SendGameMessage(Server.GetWorldManager().GetActor(), 30604, 0x20, 0, commandId ^ 0xA0F00000);
UpdateHotbar(slotsToUpdate);
} }
//Finds the first hotbar slot with a given commandId. //Finds the first hotbar slot with a given commandId.

View File

@ -3,12 +3,46 @@ require ("global")
--equipAbilityWidget: Widget that calls this command --equipAbilityWidget: Widget that calls this command
--triggername: Event Starter ? --triggername: Event Starter ?
--slot: Which slot the ability will go into --slot: Which slot the ability will go into
--ability: Ability being equipped --commandid: command being equipped
function onEventStarted(player, equipAbilityWidget, triggername, slot, ability, unkown, arg1, arg2, arg3, arg4, arg5, arg6) function onEventStarted(player, equipAbilityWidget, triggername, slot, commandid, unkown, arg1, arg2, arg3, arg4, arg5, arg6)
if ability then local worldManager = GetWorldManager();
player:EquipAbility(slot, ability, 1); local ability = worldManager:GetBattleCommand(commandid);
--Equip
if (commandid > 0) then
--Can the player equip any more cross class actions
if (player.charaWork.parameterTemp.otherClassAbilityCount[0] >= player.charaWork.parameterTemp.otherClassAbilityCount[1]) then
--"You cannot set any more actions."
player:SendGameMessage(GetWorldMaster(), 30720, 0x20, 0, 0);
player:endEvent();
return;
end
--Is the player high enough level in that class to equip the ability
if (player.charaWork.battleSave.skillLevel[ability.job] < ability.level) then
--"You have not yet acquired that action"
player:SendGameMessage(GetWorldMaster(), 30742, 0x20, 0, 0);
player:endEvent();
return;
end
--Equip the ability
player:EquipAbility(slot, commandid);
--Unequip
elseif (commandid == 0) then
commandid = player.charaWork.command[slot + player.charaWork.commandBorder];
--Is the ability a part of the player's current class?
--This check isn't correct because of jobs having different ids
if(worldManager:GetBattleCommand(commandid).job == player.charaWork.parameterSave.state_mainSkill[0]) then
--"Actions of your current class or job cannot be removed."
player:SendGameMessage(GetWorldMaster(), 30745, 0x20, 0, 0);
elseif (commandid != 0) then
player:UnequipAbility(slot);
end
end end
player:endEvent(); player:endEvent();
end end