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
This commit is contained in:
Malcrom
2022-09-19 16:35:34 -03:00
committed by GitHub
parent 7dc598f364
commit 972bcc3113
3 changed files with 41 additions and 10 deletions
@@ -3428,15 +3428,19 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
if (!me || !me->IsEngaged() || !me->GetVictim()) if (!me || !me->IsEngaged() || !me->GetVictim())
return; return;
if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max)) if (me->IsInRange(me->GetVictim(), (float)e.event.rangeRepeat.minRange, (float)e.event.rangeRepeat.maxRange))
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim());
else
{ {
if (!e.event.minMaxRepeat.controller) if (e.event.rangeRepeat.onlyFireOnRepeat == 2)
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." {
e.event.rangeRepeat.onlyFireOnRepeat = 1;
RecalcTimer(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax);
}
else 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; break;
} }
case SMART_EVENT_VICTIM_CASTING: case SMART_EVENT_VICTIM_CASTING:
@@ -4000,6 +4004,13 @@ void SmartScript::InitTimer(SmartScriptHolder& e)
switch (e.GetEventType()) switch (e.GetEventType())
{ {
//set only events which have initial timers //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:
case SMART_EVENT_NEAR_PLAYERS_NEGATION: case SMART_EVENT_NEAR_PLAYERS_NEGATION:
RecalcTimer(e, e.event.nearPlayer.firstTimer, e.event.nearPlayer.firstTimer); RecalcTimer(e, e.event.nearPlayer.firstTimer, e.event.nearPlayer.firstTimer);
@@ -260,7 +260,6 @@ void SmartAIMgr::LoadSmartAIFromDB()
case SMART_EVENT_TARGET_HEALTH_PCT: case SMART_EVENT_TARGET_HEALTH_PCT:
case SMART_EVENT_MANA_PCT: case SMART_EVENT_MANA_PCT:
case SMART_EVENT_TARGET_MANA_PCT: case SMART_EVENT_TARGET_MANA_PCT:
case SMART_EVENT_RANGE:
case SMART_EVENT_FRIENDLY_HEALTH: case SMART_EVENT_FRIENDLY_HEALTH:
case SMART_EVENT_FRIENDLY_HEALTH_PCT: case SMART_EVENT_FRIENDLY_HEALTH_PCT:
case SMART_EVENT_FRIENDLY_MISSING_BUFF: case SMART_EVENT_FRIENDLY_MISSING_BUFF:
@@ -269,6 +268,13 @@ void SmartAIMgr::LoadSmartAIFromDB()
if (temp.event.minMaxRepeat.repeatMin == 0 && temp.event.minMaxRepeat.repeatMax == 0) if (temp.event.minMaxRepeat.repeatMin == 0 && temp.event.minMaxRepeat.repeatMax == 0)
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
break; 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_VICTIM_CASTING:
case SMART_EVENT_IS_BEHIND_TARGET: case SMART_EVENT_IS_BEHIND_TARGET:
if (temp.event.minMaxRepeat.min == 0 && temp.event.minMaxRepeat.max == 0) 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_DEATH: return NO_PARAMS;
case SMART_EVENT_EVADE: return NO_PARAMS; case SMART_EVENT_EVADE: return NO_PARAMS;
case SMART_EVENT_SPELLHIT: return sizeof(SmartEvent::spellHit); 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_OOC_LOS: return sizeof(SmartEvent::los);
case SMART_EVENT_RESPAWN: return sizeof(SmartEvent::respawn); case SMART_EVENT_RESPAWN: return sizeof(SmartEvent::respawn);
case SMART_EVENT_TARGET_HEALTH_PCT: return sizeof(SmartEvent::minMaxRepeat); 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_MANA_PCT:
case SMART_EVENT_TARGET_HEALTH_PCT: case SMART_EVENT_TARGET_HEALTH_PCT:
case SMART_EVENT_TARGET_MANA_PCT: case SMART_EVENT_TARGET_MANA_PCT:
case SMART_EVENT_RANGE:
case SMART_EVENT_DAMAGED: case SMART_EVENT_DAMAGED:
case SMART_EVENT_DAMAGED_TARGET: case SMART_EVENT_DAMAGED_TARGET:
case SMART_EVENT_RECEIVE_HEAL: 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)) if (!IsMinMaxValid(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax))
return false; return false;
break; 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:
case SMART_EVENT_SPELLHIT_TARGET: case SMART_EVENT_SPELLHIT_TARGET:
if (e.event.spellHit.spell) if (e.event.spellHit.spell)
@@ -221,9 +221,17 @@ struct SmartEvent
uint32 max; uint32 max;
uint32 repeatMin; uint32 repeatMin;
uint32 repeatMax; uint32 repeatMax;
uint32 controller;
} minMaxRepeat; } minMaxRepeat;
struct
{
uint32 minRange;
uint32 maxRange;
uint32 repeatMin;
uint32 repeatMax;
uint32 onlyFireOnRepeat;
} rangeRepeat;
struct struct
{ {
uint32 cooldownMin; uint32 cooldownMin;