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

(cherry picked from commit 96b289cadb)
This commit is contained in:
Giacomo Pozzoni
2020-12-30 21:18:00 +01:00
committed by Shauren
parent a8d00ddd69
commit da0d9ee283
3 changed files with 27 additions and 4 deletions
@@ -258,13 +258,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, std::string const& varString)
{
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();
@@ -613,7 +617,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:
@@ -4076,6 +4084,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, SceneTemplate const* scene, Quest const* quest)
{
if (e.empty())