From 972bcc31132147614f0c5a35aa55770bc217236e Mon Sep 17 00:00:00 2001 From: Malcrom Date: Mon, 19 Sep 2022 16:35:34 -0300 Subject: [PATCH] Feature(Smart Scripts/SMART_EVENT_RANGE): Proper fix to prevent Initial timer (#13059) * Feature(Smart Scripts/SMART_EVENT_RANGE): Proper fix to prevent Initial timer * Update SmartScript.cpp --- .../game/AI/SmartScripts/SmartScript.cpp | 23 ++++++++++++++----- .../game/AI/SmartScripts/SmartScriptMgr.cpp | 18 ++++++++++++--- .../game/AI/SmartScripts/SmartScriptMgr.h | 10 +++++++- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 69da11bac..0f1e187fb 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3428,15 +3428,19 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if (!me || !me->IsEngaged() || !me->GetVictim()) return; - if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max)) - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim()); - else + if (me->IsInRange(me->GetVictim(), (float)e.event.rangeRepeat.minRange, (float)e.event.rangeRepeat.maxRange)) { - if (!e.event.minMaxRepeat.controller) - RecalcTimer(e, 500, 500); // xinef: make it predictable "Malcrom: This seems to be done to standardize min, max start rather than using the range values for the timer." + if (e.event.rangeRepeat.onlyFireOnRepeat == 2) + { + e.event.rangeRepeat.onlyFireOnRepeat = 1; + RecalcTimer(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax); + } else - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); // Malcrom: if param5 value is greater than 0 first action will not happen until after repeat timer fires. + ProcessTimedAction(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax, me->GetVictim()); } + else + RecalcTimer(e, 500, 500); // make it predictable + break; } case SMART_EVENT_VICTIM_CASTING: @@ -4000,6 +4004,13 @@ void SmartScript::InitTimer(SmartScriptHolder& e) switch (e.GetEventType()) { //set only events which have initial timers + case SMART_EVENT_RANGE: + // If onlyFireOnRepeat is true set to 2 before entering combat. Will be set back to 1 after entering combat to ignore initial firing. + if (e.event.rangeRepeat.onlyFireOnRepeat == 1) + e.event.rangeRepeat.onlyFireOnRepeat = 2; + // make it predictable + RecalcTimer(e, 500, 500); + break; case SMART_EVENT_NEAR_PLAYERS: case SMART_EVENT_NEAR_PLAYERS_NEGATION: RecalcTimer(e, e.event.nearPlayer.firstTimer, e.event.nearPlayer.firstTimer); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 80c2eb221..3da4072b2 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -260,7 +260,6 @@ void SmartAIMgr::LoadSmartAIFromDB() case SMART_EVENT_TARGET_HEALTH_PCT: case SMART_EVENT_MANA_PCT: case SMART_EVENT_TARGET_MANA_PCT: - case SMART_EVENT_RANGE: case SMART_EVENT_FRIENDLY_HEALTH: case SMART_EVENT_FRIENDLY_HEALTH_PCT: case SMART_EVENT_FRIENDLY_MISSING_BUFF: @@ -269,6 +268,13 @@ void SmartAIMgr::LoadSmartAIFromDB() if (temp.event.minMaxRepeat.repeatMin == 0 && temp.event.minMaxRepeat.repeatMax == 0) temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; break; + case SMART_EVENT_RANGE: + if (temp.event.rangeRepeat.repeatMin == 0 && temp.event.rangeRepeat.repeatMax == 0) + temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; + // Will only work properly if value is 0 or 1 + if (temp.event.rangeRepeat.onlyFireOnRepeat > 1) + temp.event.rangeRepeat.onlyFireOnRepeat = 1; + break; case SMART_EVENT_VICTIM_CASTING: case SMART_EVENT_IS_BEHIND_TARGET: if (temp.event.minMaxRepeat.min == 0 && temp.event.minMaxRepeat.max == 0) @@ -472,7 +478,7 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e) case SMART_EVENT_DEATH: return NO_PARAMS; case SMART_EVENT_EVADE: return NO_PARAMS; case SMART_EVENT_SPELLHIT: return sizeof(SmartEvent::spellHit); - case SMART_EVENT_RANGE: return sizeof(SmartEvent::minMaxRepeat); + case SMART_EVENT_RANGE: return sizeof(SmartEvent::rangeRepeat); case SMART_EVENT_OOC_LOS: return sizeof(SmartEvent::los); case SMART_EVENT_RESPAWN: return sizeof(SmartEvent::respawn); case SMART_EVENT_TARGET_HEALTH_PCT: return sizeof(SmartEvent::minMaxRepeat); @@ -911,7 +917,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_EVENT_MANA_PCT: case SMART_EVENT_TARGET_HEALTH_PCT: case SMART_EVENT_TARGET_MANA_PCT: - case SMART_EVENT_RANGE: case SMART_EVENT_DAMAGED: case SMART_EVENT_DAMAGED_TARGET: case SMART_EVENT_RECEIVE_HEAL: @@ -921,6 +926,13 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) if (!IsMinMaxValid(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax)) return false; break; + case SMART_EVENT_RANGE: + if (!IsMinMaxValid(e, e.event.rangeRepeat.minRange, e.event.rangeRepeat.maxRange)) + return false; + + if (!IsMinMaxValid(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax)) + return false; + break; case SMART_EVENT_SPELLHIT: case SMART_EVENT_SPELLHIT_TARGET: if (e.event.spellHit.spell) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 74e9c9199..e7a1bcd32 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -221,9 +221,17 @@ struct SmartEvent uint32 max; uint32 repeatMin; uint32 repeatMax; - uint32 controller; } minMaxRepeat; + struct + { + uint32 minRange; + uint32 maxRange; + uint32 repeatMin; + uint32 repeatMax; + uint32 onlyFireOnRepeat; + } rangeRepeat; + struct { uint32 cooldownMin;