From 9e60c7c09dc760ff60262b2f71ed3be104301165 Mon Sep 17 00:00:00 2001 From: tegstewart Date: Mon, 28 Oct 2024 14:58:55 -0600 Subject: [PATCH 1/3] Fix ProtectEffect not Working Corrected ProtectEffect not working as the wrong Start() method was being called. --- GameServer/ai/brain/ControlledNpcBrain.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GameServer/ai/brain/ControlledNpcBrain.cs b/GameServer/ai/brain/ControlledNpcBrain.cs index 89ef50062f..e8347dd600 100644 --- a/GameServer/ai/brain/ControlledNpcBrain.cs +++ b/GameServer/ai/brain/ControlledNpcBrain.cs @@ -464,7 +464,7 @@ public override void CheckAbilities() case Abilities.Protect: { if (GetPlayerOwner() is GamePlayer player) - new ProtectEffect().Start(player); + new ProtectEffect().Start(Body, player); break; } case Abilities.ChargeAbility: From 7fe5fdff07cf4984ada53e7a318fa3f7d7337bfe Mon Sep 17 00:00:00 2001 From: tegstewart Date: Mon, 28 Oct 2024 15:00:49 -0600 Subject: [PATCH 2/3] Fix Null Exception for NPC Protect Effect Remedied protect effect code assuming the source was a player and causing a null exception when that is not the case. --- GameServer/ai/brain/StandardMobBrain.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GameServer/ai/brain/StandardMobBrain.cs b/GameServer/ai/brain/StandardMobBrain.cs index 4f589e0a91..4ec56b4776 100644 --- a/GameServer/ai/brain/StandardMobBrain.cs +++ b/GameServer/ai/brain/StandardMobBrain.cs @@ -523,9 +523,9 @@ public virtual void AddToAggroList(GameLiving living, int aggroamount, bool Chec if (protectAmount > 0) { aggroamount -= protectAmount; - protect.ProtectSource.Out.SendMessage(LanguageMgr.GetTranslation(protect.ProtectSource.Client.Account.Language, "AI.Brain.StandardMobBrain.YouProtDist", player.GetName(0, false), - Body.GetName(0, false, protect.ProtectSource.Client.Account.Language, Body)), eChatType.CT_System, eChatLoc.CL_SystemWindow); - //player.Out.SendMessage("You are protected by " + protect.ProtectSource.GetName(0, false) + " from " + Body.GetName(0, false) + ".", eChatType.CT_System, eChatLoc.CL_SystemWindow); + if (protect.ProtectSource is GamePlayer playerSource) + playerSource.Out.SendMessage(LanguageMgr.GetTranslation(playerSource.Client.Account.Language, "AI.Brain.StandardMobBrain.YouProtDist", player.GetName(0, false), + Body.GetName(0, false, playerSource.Client.Account.Language, Body)), eChatType.CT_System, eChatLoc.CL_SystemWindow); lock ((m_aggroTable as ICollection).SyncRoot) { From e5f19ef0a6b74a32fb3ab7608a534f92f2045d9a Mon Sep 17 00:00:00 2001 From: tegstewart Date: Mon, 28 Oct 2024 15:52:26 -0600 Subject: [PATCH 3/3] Allow NPC Protect Effects ProtectEffect no longer assumes both the source and target are players, allowing the effect to work and no longer throw exceptions when the effect is being applied by and/or to NPCs. Removed a superfluous player group check, as that is already done in ProtectAbilityHandler.Execute(). I'm specifically using this for custom pets that protect their owner, but it could in theory be used in other contexts. Somebody could create a group vs group fight between NPCs, and have tank NPCs apply protect to healing NPCs, for example. While I was there, I cleaned up the code and addressed compiler warnings. --- GameServer/effects/ProtectEffect.cs | 121 +++++++++++++--------------- 1 file changed, 58 insertions(+), 63 deletions(-) diff --git a/GameServer/effects/ProtectEffect.cs b/GameServer/effects/ProtectEffect.cs index 0fa8ed400b..1b63bb7b27 100644 --- a/GameServer/effects/ProtectEffect.cs +++ b/GameServer/effects/ProtectEffect.cs @@ -32,34 +32,16 @@ namespace DOL.GS.Effects public class ProtectEffect : StaticEffect, IGameEffect { /// - /// The player protecting the target + /// The individual protecting the target /// - GamePlayer m_protectSource; + public GameLiving ProtectSource { get; private set; } /// - /// Gets the player protecting the target + /// The individual being protected /// - public GamePlayer ProtectSource - { - get { return m_protectSource; } - set { m_protectSource = value; } - } - - /// - /// Reference to gameplayer that is protecting this player - /// - GamePlayer m_protectTarget = null; - - /// - /// Gets the protected player - /// - public GamePlayer ProtectTarget - { - get { return m_protectTarget; } - set { m_protectTarget = value; } - } + public GameLiving ProtectTarget { get; private set; } - private Group m_playerGroup; + private Group m_playerGroup = null; /// /// Creates a new protect effect @@ -71,34 +53,37 @@ public ProtectEffect() /// /// Start the guarding on player /// - public void Start(GamePlayer protectSource, GamePlayer protectTarget) + public void Start(GameLiving source, GameLiving target) { - if (protectSource == null || protectTarget == null) + if (source == null || target == null) return; - m_owner = protectSource; - m_playerGroup = protectSource.Group; + m_owner = source; + ProtectSource = source; + ProtectTarget = target; - if (m_playerGroup != protectTarget.Group) - return; - - m_protectSource = protectSource; - m_protectTarget = protectTarget; - - GameEventMgr.AddHandler(m_playerGroup, GroupEvent.MemberDisbanded, new DOLEventHandler(GroupDisbandCallback)); + if (target.Group != null && target.Group == source.Group) + { + m_playerGroup = source.Group; + GameEventMgr.AddHandler(m_playerGroup, GroupEvent.MemberDisbanded, new DOLEventHandler(GroupDisbandCallback)); + } - m_protectSource.EffectList.Add(this); - m_protectTarget.EffectList.Add(this); + source.EffectList.Add(this); + target.EffectList.Add(this); - if (!protectSource.IsWithinRadius(protectTarget, ProtectAbilityHandler.PROTECT_DISTANCE)) + if (!source.IsWithinRadius(target, ProtectAbilityHandler.PROTECT_DISTANCE)) { - protectSource.Out.SendMessage(LanguageMgr.GetTranslation(protectSource.Client, "Effects.ProtectEffect.YouProtectingYBut", protectTarget.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); - protectTarget.Out.SendMessage(LanguageMgr.GetTranslation(protectTarget.Client, "Effects.ProtectEffect.XProtectingYouBut", protectSource.GetName(0, true)), eChatType.CT_System, eChatLoc.CL_SystemWindow); + if (source is GamePlayer playerSource) + playerSource.Out.SendMessage(LanguageMgr.GetTranslation(playerSource.Client, "Effects.ProtectEffect.YouProtectingYBut", target.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); + if (target is GamePlayer playerTarget) + playerTarget.Out.SendMessage(LanguageMgr.GetTranslation(playerTarget.Client, "Effects.ProtectEffect.XProtectingYouBut", source.GetName(0, true)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } else { - protectSource.Out.SendMessage(LanguageMgr.GetTranslation(protectSource.Client, "Effects.ProtectEffect.YouProtectingY", protectTarget.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); - protectTarget.Out.SendMessage(LanguageMgr.GetTranslation(protectTarget.Client, "Effects.ProtectEffect.XProtectingYou", protectSource.GetName(0, true)), eChatType.CT_System, eChatLoc.CL_SystemWindow); + if (source is GamePlayer playerSource) + playerSource.Out.SendMessage(LanguageMgr.GetTranslation(playerSource.Client, "Effects.ProtectEffect.YouProtectingY", target.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); + if (target is GamePlayer playerTarget) + playerTarget.Out.SendMessage(LanguageMgr.GetTranslation(playerTarget.Client, "Effects.ProtectEffect.XProtectingYou", source.GetName(0, true)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } } @@ -110,12 +95,8 @@ public void Start(GamePlayer protectSource, GamePlayer protectTarget) /// protected void GroupDisbandCallback(DOLEvent e, object sender, EventArgs args) { - MemberDisbandedEventArgs eArgs = args as MemberDisbandedEventArgs; - if (eArgs == null) return; - if (eArgs.Member == ProtectTarget || eArgs.Member == ProtectSource) - { + if (args is MemberDisbandedEventArgs eArgs && (eArgs.Member == ProtectTarget || eArgs.Member == ProtectSource)) Cancel(false); - } } /// @@ -123,15 +104,17 @@ protected void GroupDisbandCallback(DOLEvent e, object sender, EventArgs args) /// public override void Cancel(bool playerCancel) { - GameEventMgr.RemoveHandler(m_playerGroup, GroupEvent.MemberDisbanded, new DOLEventHandler(GroupDisbandCallback)); + if (m_playerGroup != null) + GameEventMgr.RemoveHandler(m_playerGroup, GroupEvent.MemberDisbanded, new DOLEventHandler(GroupDisbandCallback)); + // intercept handling is done by the active part - m_protectSource.EffectList.Remove(this); - m_protectTarget.EffectList.Remove(this); - - m_protectSource.Out.SendMessage(LanguageMgr.GetTranslation(m_protectSource.Client, "Effects.ProtectEffect.YouNoProtectY", m_protectTarget.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); - m_protectTarget.Out.SendMessage(LanguageMgr.GetTranslation(m_protectTarget.Client, "Effects.ProtectEffect.XNoProtectYou", m_protectSource.GetName(0, true)), eChatType.CT_System, eChatLoc.CL_SystemWindow); + ProtectSource.EffectList.Remove(this); + ProtectTarget.EffectList.Remove(this); - m_playerGroup = null; + if (ProtectSource is GamePlayer playerSource) + playerSource.Out.SendMessage(LanguageMgr.GetTranslation(playerSource.Client, "Effects.ProtectEffect.YouNoProtectY", ProtectTarget.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); + if (ProtectTarget is GamePlayer playerTarget) + playerTarget.Out.SendMessage(LanguageMgr.GetTranslation(playerTarget.Client, "Effects.ProtectEffect.XNoProtectYou", ProtectSource.GetName(0, true)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } /// @@ -139,12 +122,16 @@ public override void Cancel(bool playerCancel) /// public override string Name { - get { - if (m_protectSource != null && m_protectTarget != null) - return LanguageMgr.GetTranslation(((GamePlayer)Owner).Client, "Effects.ProtectEffect.ProtectByName", m_protectTarget.GetName(0, false), m_protectSource.GetName(0, false)); - return LanguageMgr.GetTranslation(((GamePlayer)Owner).Client, "Effects.ProtectEffect.Name"); + string language; + if (ProtectTarget is GamePlayer playerTarget) + language = playerTarget.Client.Account.Language; + else if (ProtectSource is GamePlayer playerSource) + language = playerSource.Client.Account.Language; + else + language = LanguageMgr.DefaultLanguage; + return LanguageMgr.GetTranslation(language, "Effects.ProtectEffect.ProtectByName", ProtectTarget.GetName(0, false), ProtectSource.GetName(0, false)); } } @@ -171,12 +158,20 @@ public override IList DelveInfo { get { - var delveInfoList = new List(4); - delveInfoList.Add(LanguageMgr.GetTranslation(((GamePlayer)Owner).Client, "Effects.ProtectEffect.InfoEffect")); - delveInfoList.Add(" "); - delveInfoList.Add(LanguageMgr.GetTranslation(((GamePlayer)Owner).Client, "Effects.ProtectEffect.XProtectingY", ProtectSource.GetName(0, true), ProtectTarget.GetName(0, false))); - - return delveInfoList; + string language; + if (ProtectTarget is GamePlayer playerTarget) + language = playerTarget.Client.Account.Language; + else if (ProtectSource is GamePlayer playerSource) + language = playerSource.Client.Account.Language; + else + language = LanguageMgr.DefaultLanguage; + + return new List(4) + { + LanguageMgr.GetTranslation(language, "Effects.ProtectEffect.InfoEffect"), + " ", + LanguageMgr.GetTranslation(language, "Effects.ProtectEffect.XProtectingY", ProtectSource.GetName(0, true), ProtectTarget.GetName(0, false)) + }; } } }