From 289e4dc24befea39af51eff8279a6bd4c8947ecf Mon Sep 17 00:00:00 2001 From: Yogurt Date: Wed, 29 May 2019 19:46:29 -0700 Subject: [PATCH] More targeting changes Added CanUse instead of CanAttack/CanWeaponSkill/CanCast since they all check the same things anyway. Fixed some bugs like mp checking against hp in AddMP. --- .../actors/chara/Character.cs | 25 ++--- .../actors/chara/ai/state/MagicState.cs | 5 +- .../actors/chara/ai/state/WeaponSkillState.cs | 4 +- .../actors/chara/npc/BattleNpc.cs | 16 +--- .../actors/chara/player/Player.cs | 91 ++++++------------- 5 files changed, 41 insertions(+), 100 deletions(-) diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/FFXIVClassic Map Server/actors/chara/Character.cs index eb40c22e..17884323 100644 --- a/FFXIVClassic Map Server/actors/chara/Character.cs +++ b/FFXIVClassic Map Server/actors/chara/Character.cs @@ -232,8 +232,7 @@ namespace FFXIVClassic_Map_Server.Actors public void DoBattleAction(ushort commandId, uint animationId, CommandResult[] results) { int currentIndex = 0; - //AoE abilities only ever hit 16 people, so we probably won't need this loop anymore - //Apparently aoe are limited to 8? + while (true) { if (results.Length - currentIndex >= 10) @@ -247,9 +246,6 @@ namespace FFXIVClassic_Map_Server.Actors } else break; - - //I think aoe effects play on all hit enemies. Firaga does at least - //animationId = 0; //If more than one packet is sent out, only send the animation once to avoid double playing. } } @@ -446,20 +442,11 @@ namespace FFXIVClassic_Map_Server.Actors return true; } - public virtual bool CanCast(Character target, BattleCommand spell) + public virtual bool CanUse(Character target, BattleCommand skill, CommandResult error = null) { return false; } - public virtual bool CanWeaponSkill(Character target, BattleCommand skill) - { - return false; - } - - public virtual bool CanUseAbility(Character target, BattleCommand ability) - { - return false; - } public virtual uint GetAttackDelayMs() { @@ -628,7 +615,7 @@ namespace FFXIVClassic_Map_Server.Actors public void SetMP(uint mp) { charaWork.parameterSave.mpMax = (short)mp; - if (mp > charaWork.parameterSave.hpMax[0]) + if (mp > charaWork.parameterSave.mpMax) SetMaxMP(mp); updateFlags |= ActorUpdateFlags.HpTpMp; @@ -1070,6 +1057,7 @@ namespace FFXIVClassic_Map_Server.Actors { statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnHit, "onCrit", this, defender, action, actionContainer); } + //The order of messages that appears after using a command is: //1. Cast start messages. (ie "You begin casting... ") @@ -1146,13 +1134,14 @@ namespace FFXIVClassic_Map_Server.Actors { if (command.isCombo && hitTarget) ((Player)this).SetCombos(command.comboNextCommandId); - else + //Only reset combo if the command is a spell or weaponskill, since abilities can be used between combo skills + else if (command.commandType == CommandType.Spell || command.commandType == CommandType.WeaponSkill) ((Player)this).SetCombos(); } - CommandResult error = new CommandResult(actorId, 0, 0); DelMP(command.CalculateMpCost(this)); DelTP(command.CalculateTpCost(this)); + actions.CombineLists(); DoBattleAction(command.id, command.battleAnimation, actions.GetList()); } diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs index d424a3da..c44db21c 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs @@ -36,13 +36,12 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state this.target = target != null ? target : owner; - if (returnCode == 0 && owner.CanCast(this.target, spell)) + if (returnCode == 0 && owner.CanUse(this.target, spell, errorResult)) { OnStart(); } else { - errorResult = new CommandResult(owner.actorId, 32553, 0); interrupt = true; } } @@ -174,7 +173,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state private bool CanCast() { - return owner.CanCast(target, spell) && spell.IsValidMainTarget(owner, target) && !HasMoved(); + return owner.CanUse(target, spell); } private bool HasMoved() diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs index 57ca36f8..06210707 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs @@ -24,7 +24,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state this.skill = Server.GetWorldManager().GetBattleCommand(skillId); var returnCode = lua.LuaEngine.CallLuaBattleCommandFunction(owner, skill, "weaponskill", "onSkillPrepare", owner, target, skill); - if (returnCode == 0 && owner.CanWeaponSkill(target, skill)) + if (returnCode == 0 && owner.CanUse(this.target, skill, errorResult)) { OnStart(); } @@ -167,7 +167,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state private bool CanUse() { - return owner.CanWeaponSkill(target, skill) && skill.IsValidMainTarget(owner, target); + return owner.CanUse(target, skill); } public BattleCommand GetWeaponSkill() diff --git a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs b/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs index 9e90c645..156a6109 100644 --- a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs +++ b/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs @@ -188,7 +188,7 @@ namespace FFXIVClassic_Map_Server.Actors return true; } - public override bool CanCast(Character target, BattleCommand spell) + public override bool CanUse(Character target, BattleCommand spell, CommandResult error = null) { // todo: if (target == null) @@ -209,18 +209,6 @@ namespace FFXIVClassic_Map_Server.Actors return true; } - public override bool CanWeaponSkill(Character target, BattleCommand skill) - { - // todo: - return true; - } - - public override bool CanUseAbility(Character target, BattleCommand ability) - { - // todo: - return false; - } - public uint GetDespawnTime() { return despawnTime; @@ -264,7 +252,7 @@ namespace FFXIVClassic_Map_Server.Actors zone.BroadcastPacketsAroundActor(this, GetSpawnPackets(null, 0x01)); zone.BroadcastPacketsAroundActor(this, GetInitPackets()); charaWork.parameterSave.hp = charaWork.parameterSave.hpMax; - charaWork.parameterSave.mp = charaWork.parameterSave.mpMax; + charaWork.parameterSave.hp = (short[])charaWork.parameterSave.hpMax.Clone(); RecalculateStats(); OnSpawn(); diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 70eb955b..1815c890 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -2169,110 +2169,75 @@ namespace FFXIVClassic_Map_Server.Actors return true; } - public override bool CanCast(Character target, BattleCommand spell) + //Do we need separate functions? they check the same things + public override bool CanUse(Character target, BattleCommand skill, CommandResult error = null) { - //Might want to do these with a CommandResult instead to be consistent with the rest of command stuff - if (GetHotbarTimer(spell.id) > Utils.UnixTimeStampUTC()) - { - // todo: this needs confirming - // Please wait a moment and try again. - SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20, (uint)spell.id); - return false; - } - if (target == null) - { - // Target does not exist. - SendGameMessage(Server.GetWorldManager().GetActor(), 32511, 0x20, (uint)spell.id); - return false; - } - if (Utils.XZDistance(positionX, positionZ, target.positionX, target.positionZ) > spell.range) - { - // The target is too far away. - SendGameMessage(Server.GetWorldManager().GetActor(), 32539, 0x20, (uint)spell.id); - return false; - } - if (Utils.XZDistance(positionX, positionZ, target.positionX, target.positionZ) < spell.minRange) - { - // The target is too close. - SendGameMessage(Server.GetWorldManager().GetActor(), 32538, 0x20, (uint)spell.id); - return false; - } - if (target.positionY - positionY > (spell.rangeHeight / 2)) - { - // The target is too far above you. - SendGameMessage(Server.GetWorldManager().GetActor(), 32540, 0x20, (uint)spell.id); - return false; - } - if (positionY - target.positionY > (spell.rangeHeight / 2)) - { - // The target is too far below you. - SendGameMessage(Server.GetWorldManager().GetActor(), 32541, 0x20, (uint)spell.id); - return false; - } - if (!IsValidTarget(target, spell.mainTarget) || !spell.IsValidMainTarget(this, target)) + if (!skill.IsValidMainTarget(this, target, error) || !IsValidTarget(target, skill.mainTarget)) { // error packet is set in IsValidTarget return false; } - return true; - } - public override bool CanWeaponSkill(Character target, BattleCommand skill) - { - // todo: see worldmaster ids 32558~32557 for proper ko message and stuff + //Might want to do these with a BattleAction instead to be consistent with the rest of command stuff if (GetHotbarTimer(skill.id) > Utils.UnixTimeStampUTC()) { // todo: this needs confirming // Please wait a moment and try again. - SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20, (uint)skill.id); + error?.SetTextId(32535); return false; } - if (target == null) + if (Utils.XZDistance(positionX, positionZ, target.positionX, target.positionZ) > skill.range) { - // Target does not exist. - SendGameMessage(Server.GetWorldManager().GetActor(), 32511, 0x20, (uint)skill.id); + // The target is too far away. + error?.SetTextId(32539); + return false; + } + + if (Utils.XZDistance(positionX, positionZ, target.positionX, target.positionZ) < skill.minRange) + { + // The target is too close. + error?.SetTextId(32538); return false; } - //Original game checked height difference before horizontal distance if (target.positionY - positionY > (skill.rangeHeight / 2)) { // The target is too far above you. - SendGameMessage(Server.GetWorldManager().GetActor(), 32540, 0x20, (uint)skill.id); + error?.SetTextId(32540); return false; } if (positionY - target.positionY > (skill.rangeHeight / 2)) { // The target is too far below you. - SendGameMessage(Server.GetWorldManager().GetActor(), 32541, 0x20, (uint)skill.id); + error?.SetTextId(32541); return false; } - var targetDist = Utils.XZDistance(positionX, positionZ, target.positionX, target.positionZ); - - if (targetDist > skill.range) + if (skill.CalculateMpCost(this) > GetMP()) { - // The target is out of range. - SendGameMessage(Server.GetWorldManager().GetActor(), 32537, 0x20, (uint)skill.id); + // You do not have enough MP. + error?.SetTextId(32545); return false; } - if (targetDist < skill.minRange) + if (skill.CalculateTpCost(this) > GetTP()) { - // The target is too close. - SendGameMessage(Server.GetWorldManager().GetActor(), 32538, 0x20, (uint)skill.id); + // You do not have enough TP. + error?.SetTextId(32546); return false; } - - if (!IsValidTarget(target, skill.validTarget) || !skill.IsValidMainTarget(this, target)) + //Proc requirement + if (skill.procRequirement != BattleCommandProcRequirement.None && !charaWork.battleTemp.timingCommandFlag[(int)skill.procRequirement - 1]) { - // error packet is set in IsValidTarget + //Conditions for use are not met + error?.SetTextId(32556); return false; } + return true; }