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 96b289cadbf304e427ddbd281d1a6f592af612a7)
This commit is contained in:
@@ -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)
|
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
|
// 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))
|
if (!roll_chance_i(e.event.event_chance))
|
||||||
return;
|
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)
|
if (unit)
|
||||||
mLastInvoker = unit->GetGUID();
|
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 there is at least 1 failed cast and no successful casts at all, retry again on next loop
|
||||||
if (failedSpellCast && !successfulSpellCast)
|
if (failedSpellCast && !successfulSpellCast)
|
||||||
RaisePriority(e);
|
{
|
||||||
|
RetryLater(e, true);
|
||||||
|
// Don't execute linked events
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMART_ACTION_SELF_CAST:
|
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)
|
void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* quest)
|
||||||
{
|
{
|
||||||
if (e.empty())
|
if (e.empty())
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ class TC_GAME_API SmartScript
|
|||||||
|
|
||||||
void SortEvents(SmartAIEventList& events);
|
void SortEvents(SmartAIEventList& events);
|
||||||
void RaisePriority(SmartScriptHolder& e);
|
void RaisePriority(SmartScriptHolder& e);
|
||||||
|
void RetryLater(SmartScriptHolder& e, bool ignoreChanceRoll = false);
|
||||||
|
|
||||||
SmartAIEventList mEvents;
|
SmartAIEventList mEvents;
|
||||||
SmartAIEventList mInstallEvents;
|
SmartAIEventList mInstallEvents;
|
||||||
|
|||||||
@@ -1619,7 +1619,10 @@ enum SmartEventFlags
|
|||||||
SMART_EVENT_FLAG_WHILE_CHARMED = 0x200, //Event occurs even if AI owner is charmed
|
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_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
|
enum SmartCastFlags
|
||||||
|
|||||||
Reference in New Issue
Block a user