From cc07e1f4537abe7ae5c9c5d10135e53e29b008b8 Mon Sep 17 00:00:00 2001 From: Yogurt Date: Mon, 27 May 2019 17:31:25 -0700 Subject: [PATCH] Pass BattleCommand to combat functions to prepare for passing BattleCommand to scripts. Add CommandResultContainer to status update to handle death from dots. --- .../actors/chara/Character.cs | 34 +++++++++++------- .../actors/chara/ai/StatusEffectContainer.cs | 36 +++++++++++-------- .../actors/chara/ai/utils/BattleUtils.cs | 19 +++++----- 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/FFXIVClassic Map Server/actors/chara/Character.cs index d6bdb623..bba5324d 100644 --- a/FFXIVClassic Map Server/actors/chara/Character.cs +++ b/FFXIVClassic Map Server/actors/chara/Character.cs @@ -842,15 +842,19 @@ namespace FFXIVClassic_Map_Server.Actors } - public virtual void OnDamageDealt(Character defender, CommandResult action, CommandResultContainer actionContainer = null) + public virtual void OnDamageDealt(Character defender, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) { switch (action.hitType) { case (HitType.Miss): - OnMiss(this, action, actionContainer); + OnMiss(defender, skill, action, actionContainer); + break; + case (HitType.Crit): + OnCrit(defender, skill, action, actionContainer); + OnHit(defender, skill, action, actionContainer); break; default: - OnHit(defender, action, actionContainer); + OnHit(defender, skill, action, actionContainer); break; } @@ -865,18 +869,18 @@ namespace FFXIVClassic_Map_Server.Actors } } - public virtual void OnDamageTaken(Character attacker, CommandResult action, CommandResultContainer actionContainer = null) + public virtual void OnDamageTaken(Character attacker, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) { switch (action.hitType) { case (HitType.Miss): - OnEvade(attacker, action, actionContainer); + OnEvade(attacker, skill, action, actionContainer); break; case (HitType.Parry): - OnParry(attacker, action, actionContainer); + OnParry(attacker, skill, action, actionContainer); break; case (HitType.Block): - OnBlock(attacker, action, actionContainer); + OnBlock(attacker, skill, action, actionContainer); break; } @@ -1030,38 +1034,42 @@ namespace FFXIVClassic_Map_Server.Actors } //Called when this character evades attacker's action - public void OnEvade(Character attacker, CommandResult action, CommandResultContainer actionContainer = null) + public void OnEvade(Character attacker, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) { SetProc((ushort)HitType.Evade); statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnEvade, "onEvade", attacker, this, action, actionContainer); } //Called when this character blocks attacker's action - public void OnBlock(Character attacker, CommandResult action, CommandResultContainer actionContainer = null) + public void OnBlock(Character attacker, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) { SetProc((ushort)HitType.Block); statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnBlock, "onBlock", attacker, this, action, actionContainer); } //Called when this character parries attacker's action - public void OnParry(Character attacker, CommandResult action, CommandResultContainer actionContainer = null) + public void OnParry(Character attacker, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) { SetProc((ushort)HitType.Parry); statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnParry, "onParry", attacker, this, action, actionContainer); } //Called when this character misses - public void OnMiss(Character defender, CommandResult action, CommandResultContainer actionContainer = null) + public void OnMiss(Character defender, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) { SetProc((ushort)HitType.Miss); statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnMiss, "onMiss", this, defender, action, actionContainer); } - public void OnHit(Character defender, CommandResult action, CommandResultContainer actionContainer = null) + public void OnHit(Character defender, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) { statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnHit, "onHit", this, defender, action, actionContainer); } + public void OnCrit(Character defender, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) + { + 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... ") @@ -1073,7 +1081,7 @@ namespace FFXIVClassic_Map_Server.Actors //5. The hit itself. For single hit commands this message is "Your [command] hits [target] for x damage" for multi hits it's "[Target] takes x points of damage" //6. Stoneskin falling off //6. Buffs that activate after a command hits, like Aegis Boon and Divine Veil - + //After all hits //7. If it's a multi-hit command there's a "{numhits]fold attack..." message or if all hits miss an "All attacks missed" message //8. Buffs that fall off after the skill ends, like Excruciate diff --git a/FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs b/FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs index 09742e6d..465c7a48 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs @@ -35,15 +35,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai public void Update(DateTime tick) { + CommandResultContainer resultContainer = new CommandResultContainer(); + //Regen/Refresh/Regain effects tick every 3 seconds if ((DateTime.Now - lastTick).Seconds >= 3) { - RegenTick(tick); + RegenTick(tick, resultContainer); lastTick = DateTime.Now; } - // list of effects to remove - // if (owner is Player) UpdateTimeAtIndex(4, 4294967295); + // list of effects to remove var removeEffects = new List(); for (int i = 0; i < effects.Values.Count; i++) { @@ -59,15 +60,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai RemoveStatusEffect(effect); } - if (sendUpdate) + resultContainer.CombineLists(); + + if (resultContainer.GetList().Count > 0) { - owner.zone.BroadcastPacketsAroundActor(owner, owner.GetActorStatusPackets()); - sendUpdate = false; + owner.DoBattleAction(0, 0x7c000062, resultContainer.GetList()); } } //regen/refresh/regain - public void RegenTick(DateTime tick) + public void RegenTick(DateTime tick, CommandResultContainer resultContainer) { ushort dotTick = (ushort) owner.GetMod(Modifier.RegenDown); ushort regenTick = (ushort) owner.GetMod(Modifier.Regen); @@ -77,18 +79,24 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai //DoTs tick before regen and the full dot damage is displayed, even if some or all of it is nullified by regen. Only effects like stoneskin actually alter the number shown if (dotTick > 0) { - CommandResult action = new CommandResult(owner.actorId, 30331, (uint)(HitEffect.HitEffectType | HitEffect.Hit), dotTick); + //Unsure why 10105 is the textId used + //Also unsure why magicshield is used + CommandResult action = new CommandResult(owner.actorId, 10105, (uint)(HitEffect.MagicEffectType | HitEffect.MagicShield | HitEffect.NoResist), dotTick); utils.BattleUtils.HandleStoneskin(owner, action); // todo: figure out how to make red numbers appear for enemies getting hurt by dots - //owner.DelHP(action.amount); - utils.BattleUtils.DamageTarget(owner, owner, action, null); - owner.DoBattleAction(0, 0, action); + resultContainer.AddAction(action); + owner.DelHP(action.amount, resultContainer); } //DoTs are the only effect to show numbers, so that doesnt need to be handled for these - owner.AddHP(regenTick); - owner.AddMP(refreshtick); - owner.AddTP(regainTick); + if (regenTick != 0) + owner.AddHP(regenTick); + + if (refreshtick != 0) + owner.AddMP(refreshtick); + + if (regainTick != 0) + owner.AddTP(regainTick); } public bool HasStatusEffect(uint id) diff --git a/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs b/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs index 8c40cd3d..f4770c53 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs @@ -241,7 +241,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils defender.SubtractMod((uint)Modifier.Stoneskin, mitigation); } - public static void DamageTarget(Character attacker, Character defender, CommandResult action, CommandResultContainer actionContainer= null) + public static void DamageTarget(Character attacker, Character defender, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer= null) { if (defender != null) { @@ -254,9 +254,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils bnpc.lastAttacker = attacker; } - defender.DelHP((short)action.amount); - attacker.OnDamageDealt(defender, action, actionContainer); - defender.OnDamageTaken(attacker, action, actionContainer); + defender.DelHP((short)action.amount, actionContainer); + attacker.OnDamageDealt(defender, skill, action, actionContainer); + defender.OnDamageTaken(attacker, skill, action, actionContainer); // todo: other stuff too if (defender is BattleNpc) @@ -272,11 +272,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils } } - public static void HealTarget(Character caster, Character target, CommandResult action, CommandResultContainer actionContainer = null) + public static void HealTarget(Character caster, Character target, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) { if (target != null) { - target.AddHP(action.amount); + target.AddHP(action.amount, actionContainer); target.statusEffects.CallLuaFunctionByFlag((uint) StatusEffectFlags.ActivateOnHealed, "onHealed", caster, target, action, actionContainer); } @@ -512,8 +512,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils actionContainer.AddAction(action); action.enmity = (ushort) (action.enmity * (skill != null ? skill.enmityModifier : 1)); + //Damage the target - DamageTarget(attacker, defender, action, actionContainer); + DamageTarget(attacker, defender, skill, action, actionContainer); } public static void FinishActionSpell(Character attacker, Character defender, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) @@ -542,7 +543,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils actionContainer.AddAction(action); - DamageTarget(attacker, defender, action, actionContainer); + DamageTarget(attacker, defender, skill, action, actionContainer); } public static void FinishActionHeal(Character attacker, Character defender, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null) @@ -552,7 +553,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils actionContainer.AddAction(action); - HealTarget(attacker, defender, action, actionContainer); + HealTarget(attacker, defender, skill, action, actionContainer); } public static void FinishActionStatus(Character attacker, Character defender, BattleCommand skill, CommandResult action, CommandResultContainer actionContainer = null)