diff options
author | Giacomo Pozzoni <giacomopoz@gmail.com> | 2020-12-30 21:18:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-30 21:18:00 +0100 |
commit | 96b289cadbf304e427ddbd281d1a6f592af612a7 (patch) | |
tree | 1eaf6114ae071a252cbbb30345dcfcae7b216359 /src | |
parent | f8afcec9f3efc58ce8a38a6c63e2ebfc24d2e01d (diff) |
Core/SAI: Fix SMART_EVENT_FLAG_NOT_REPEATABLE flag being ignored when specifying a chance (and other SMART_ACTION_CAST fixes) (#25778)
* Core/SAI: Fix SMART_EVENT_FLAG_NOT_REPEATABLE flag being ignored when specifying a chance
Fix SMART_EVENT_FLAG_NOT_REPEATABLE flag being ignored when specifying a chance, always making the action trigger.
* Fix SMART_ACTION_CAST with SMART_EVENT_FLAG_NOT_REPEATABLE not casting the spell at all if rolled chance was successful but creature couldn't cast the spell
* Prevent linked actions if SMART_ACTION_CAST couldn't be completed and will be retried later
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 25 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 1 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 5 |
3 files changed, 27 insertions, 4 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index a6945a804a7..261a73d4bd9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -246,13 +246,17 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3 void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob) { + e.runOnce = true; //used for repeat check + // calc random - if (e.GetEventType() != SMART_EVENT_LINK && e.event.event_chance < 100 && e.event.event_chance) + if (e.GetEventType() != SMART_EVENT_LINK && e.event.event_chance < 100 && e.event.event_chance && !(e.event.event_flags & SMART_EVENT_FLAG_TEMP_IGNORE_CHANCE_ROLL)) { if (!roll_chance_i(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 &= ~SMART_EVENT_FLAG_TEMP_IGNORE_CHANCE_ROLL; if (unit) mLastInvoker = unit->GetGUID(); @@ -601,7 +605,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u // 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; } case SMART_ACTION_SELF_CAST: @@ -3782,6 +3790,17 @@ void SmartScript::RaisePriority(SmartScriptHolder& e) } } +void SmartScript::RetryLater(SmartScriptHolder& e, bool ignoreChanceRoll) +{ + 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 |= SMART_EVENT_FLAG_TEMP_IGNORE_CHANCE_ROLL; + + e.runOnce = false; +} + void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at) { if (e.empty()) diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index e028acbec1b..a2237ff2562 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -103,6 +103,7 @@ class TC_GAME_API SmartScript void SortEvents(SmartAIEventList& events); void RaisePriority(SmartScriptHolder& e); + void RetryLater(SmartScriptHolder& e, bool ignoreChanceRoll = false); SmartAIEventList mEvents; SmartAIEventList mInstallEvents; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index a8bb90700fd..f2c387de5f2 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1539,7 +1539,10 @@ enum SmartEventFlags SMART_EVENT_FLAG_WHILE_CHARMED = 0x200, //Event occurs even if AI owner is charmed SMART_EVENT_FLAG_DIFFICULTY_ALL = (SMART_EVENT_FLAG_DIFFICULTY_0|SMART_EVENT_FLAG_DIFFICULTY_1|SMART_EVENT_FLAG_DIFFICULTY_2|SMART_EVENT_FLAG_DIFFICULTY_3), - SMART_EVENT_FLAGS_ALL = (SMART_EVENT_FLAG_NOT_REPEATABLE|SMART_EVENT_FLAG_DIFFICULTY_ALL|SMART_EVENT_FLAG_RESERVED_5|SMART_EVENT_FLAG_RESERVED_6|SMART_EVENT_FLAG_DEBUG_ONLY|SMART_EVENT_FLAG_DONT_RESET|SMART_EVENT_FLAG_WHILE_CHARMED) + SMART_EVENT_FLAGS_ALL = (SMART_EVENT_FLAG_NOT_REPEATABLE|SMART_EVENT_FLAG_DIFFICULTY_ALL|SMART_EVENT_FLAG_RESERVED_5|SMART_EVENT_FLAG_RESERVED_6|SMART_EVENT_FLAG_DEBUG_ONLY|SMART_EVENT_FLAG_DONT_RESET|SMART_EVENT_FLAG_WHILE_CHARMED), + + // Temp flags, used only at runtime, never stored in DB + SMART_EVENT_FLAG_TEMP_IGNORE_CHANCE_ROLL = 0x40000000, //Event occurs no matter what roll_chance_i(e.event.event_chance) returns. }; enum SmartCastFlags |