From fe78a4651c111382de57de15b5194cd968c13dc1 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 24 May 2022 14:31:16 -0400 Subject: [PATCH] Core/SAI: Fix SMART_EVENT_FLAG_NOT_REPEATABLE flag being ignored when specifying a chance Port From (https://github.com/TrinityCore/TrinityCore/commit/da0d9ee28349d1974cdacc0e3ad5b3707af04a36) --- Source/Framework/Constants/SmartAIConst.cs | 5 ++++- Source/Game/AI/SmartScripts/SmartScript.cs | 25 +++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Source/Framework/Constants/SmartAIConst.cs b/Source/Framework/Constants/SmartAIConst.cs index 5f89ed93b..9a29dc796 100644 --- a/Source/Framework/Constants/SmartAIConst.cs +++ b/Source/Framework/Constants/SmartAIConst.cs @@ -108,7 +108,10 @@ namespace Framework.Constants WhileCharmed = 0x200, //Event occurs even if AI owner is charmed DifficultyAll = (Difficulty0 | Difficulty1 | Difficulty2 | Difficulty3), - All = (NotRepeatable | DifficultyAll | Reserved5 | Reserved6 | DebugOnly | DontReset | WhileCharmed) + All = (NotRepeatable | DifficultyAll | Reserved5 | Reserved6 | DebugOnly | DontReset | WhileCharmed), + + // Temp flags, used only at runtime, never stored in DB + TempIgnoreChanceRoll = 0x40000000, //Event occurs no matter what roll_chance_i(e.event.event_chance) returns. } public enum SmartRespawnCondition diff --git a/Source/Game/AI/SmartScripts/SmartScript.cs b/Source/Game/AI/SmartScripts/SmartScript.cs index 609fb403f..e427c4c41 100644 --- a/Source/Game/AI/SmartScripts/SmartScript.cs +++ b/Source/Game/AI/SmartScripts/SmartScript.cs @@ -141,13 +141,17 @@ namespace Game.AI void ProcessAction(SmartScriptHolder e, Unit unit = null, uint var0 = 0, uint var1 = 0, bool bvar = false, SpellInfo spell = null, GameObject gob = null, string varString = "") { + e.RunOnce = true; //used for repeat check + //calc random - if (e.GetEventType() != SmartEvents.Link && e.Event.event_chance < 100 && e.Event.event_chance != 0) + if (e.GetEventType() != SmartEvents.Link && e.Event.event_chance < 100 && e.Event.event_chance != 0 && !e.Event.event_flags.HasFlag(SmartEventFlags.TempIgnoreChanceRoll)) { if (RandomHelper.randChance(e.Event.event_chance)) return; } - e.RunOnce = true;//used for repeat check + + // Remove SMART_EVENT_FLAG_TEMP_IGNORE_CHANCE_ROLL flag after processing roll chances as it's not needed anymore + e.Event.event_flags &= ~SmartEventFlags.TempIgnoreChanceRoll; if (unit != null) LastInvoker = unit.GetGUID(); @@ -500,7 +504,11 @@ namespace Game.AI // If there is at least 1 failed cast and no successful casts at all, retry again on next loop if (failedSpellCast && !successfulSpellCast) - RaisePriority(e); + { + RetryLater(e, true); + // Don't execute linked events + return; + } break; } @@ -4024,6 +4032,17 @@ namespace Game.AI } } + void RetryLater(SmartScriptHolder e, bool ignoreChanceRoll = false) + { + RaisePriority(e); + + // This allows to retry the action later without rolling again the chance roll (which might fail and end up not executing the action) + if (ignoreChanceRoll) + e.Event.event_flags |= SmartEventFlags.TempIgnoreChanceRoll; + + e.RunOnce = false; + } + void FillScript(List e, WorldObject obj, AreaTriggerRecord at, SceneTemplate scene, Quest quest) { if (e.Empty())