refactor(Core/SmartScripts): Change invoker to be WorldObject (#19408)

* refactor(Core/SmartScripts): Change invoker to be WorldObject

* avoid dangling else

* womp womp

* check for null

* null check

* Update SmartScript.cpp

* Avarishd broke it for sure

* remove redundant check

* reduce more redundant code

* who doesnt love redundancy
This commit is contained in:
Kitzunu
2024-07-27 12:32:55 +02:00
committed by GitHub
parent e34ce755c8
commit 5da3e2e688
4 changed files with 85 additions and 36 deletions

View File

@@ -167,21 +167,29 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (unit)
mLastInvoker = unit->GetGUID();
else if (gob)
mLastInvoker = gob->GetGUID();
if (Unit* tempInvoker = GetLastInvoker())
if (WorldObject* tempInvoker = GetLastInvoker())
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction: Invoker: {} ({})", tempInvoker->GetName(), tempInvoker->GetGUID().ToString());
bool isControlled = e.action.moveToPos.controlled > 0;
ObjectVector targets;
GetTargets(targets, e, unit);
WorldObject* invoker = nullptr;
if (unit)
invoker = unit;
else if (gob)
invoker = gob;
GetTargets(targets, e, invoker);
switch (e.GetActionType())
{
case SMART_ACTION_TALK:
{
Creature* talker = e.target.type == 0 ? me : nullptr;
Unit* talkTarget = nullptr;
WorldObject* talkTarget = nullptr;
for (WorldObject* target : targets)
{
@@ -232,7 +240,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
sCreatureTextMgr->SendChat(target->ToCreature(), uint8(e.action.simpleTalk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
else if (IsPlayer(target) && me)
{
Unit* templastInvoker = GetLastInvoker();
WorldObject* templastInvoker = GetLastInvoker();
sCreatureTextMgr->SendChat(me, uint8(e.action.simpleTalk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_NEUTRAL, false, target->ToPlayer());
}
@@ -783,7 +791,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_INVOKER_CAST:
{
// Can be used for area trigger cast
Unit* tempLastInvoker = GetLastInvoker(unit);
WorldObject* tempLastInvoker = GetLastInvoker(unit);
if (!tempLastInvoker)
break;
@@ -798,11 +806,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsUnit(target))
continue;
if (!IsUnit(tempLastInvoker))
continue;
if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !target->ToUnit()->HasAura(e.action.cast.spell))
{
if (e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
{
tempLastInvoker->InterruptNonMeleeSpells(false);
tempLastInvoker->ToUnit()->InterruptNonMeleeSpells(false);
}
TriggerCastFlags triggerFlags = TRIGGERED_NONE;
@@ -818,7 +829,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
}
tempLastInvoker->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlags);
tempLastInvoker->ToUnit()->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlags);
LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker {} casts spell {} on target {} with castflags {}",
tempLastInvoker->GetGUID().ToString(), e.action.cast.spell, target->GetGUID().ToString(), e.action.cast.castFlags);
}
@@ -1397,16 +1408,28 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (Creature* cTarget = target->ToCreature())
{
CreatureAI* ai = cTarget->AI();
if (IsSmart(cTarget))
ENSURE_AI(SmartAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me);
// Make sure we check that the sender is either a creature or gameobject
if (IsSmart(cTarget, true) && (me || go))
{
if (me)
ENSURE_AI(SmartAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me);
else
ENSURE_AI(SmartAI, ai)->SetData(e.action.setData.field, e.action.setData.data, go);
}
else
ai->SetData(e.action.setData.field, e.action.setData.data);
}
else if (GameObject* oTarget = target->ToGameObject())
{
GameObjectAI* ai = oTarget->AI();
if (IsSmart(oTarget))
ENSURE_AI(SmartGameObjectAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me);
// Make sure we check that the sender is either a creature or gameobject
if (IsSmart(oTarget, true) && (me || go))
{
if (me)
ENSURE_AI(SmartGameObjectAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me);
else
ENSURE_AI(SmartGameObjectAI, ai)->SetData(e.action.setData.field, e.action.setData.data, go);
}
else
ai->SetData(e.action.setData.field, e.action.setData.data);
}
@@ -2900,7 +2923,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.action.setGuid.invokerGUID)
{
if (Unit* invoker = GetLastInvoker())
if (WorldObject* invoker = GetLastInvoker())
{
guidToSend = invoker->GetGUID();
}
@@ -3318,12 +3341,12 @@ SmartScriptHolder SmartScript::CreateSmartEvent(SMART_EVENT e, uint32 event_flag
return script;
}
void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, Unit* invoker /*= nullptr*/) const
void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, WorldObject* invoker /*= nullptr*/) const
{
Unit* scriptTrigger = nullptr;
WorldObject* scriptTrigger = nullptr;
if (invoker)
scriptTrigger = invoker;
else if (Unit* tempLastInvoker = GetLastInvoker())
else if (WorldObject* tempLastInvoker = GetLastInvoker())
scriptTrigger = tempLastInvoker;
WorldObject* baseObject = GetBaseObject();
@@ -3399,8 +3422,9 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
targets.push_back(scriptTrigger);
break;
case SMART_TARGET_ACTION_INVOKER_VEHICLE:
if (scriptTrigger && scriptTrigger->GetVehicle() && scriptTrigger->GetVehicle()->GetBase())
targets.push_back(scriptTrigger->GetVehicle()->GetBase());
if (scriptTrigger && IsUnit(scriptTrigger))
if (scriptTrigger->ToUnit()->GetVehicle() && scriptTrigger->ToUnit()->GetVehicle()->GetBase())
targets.push_back(scriptTrigger->ToUnit()->GetVehicle()->GetBase());
break;
case SMART_TARGET_INVOKER_PARTY:
if (scriptTrigger)
@@ -4323,7 +4347,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
if (e.event.dataSet.id != var0 || e.event.dataSet.value != var1)
return;
RecalcTimer(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax);
ProcessAction(e, unit, var0, var1);
ProcessAction(e, unit, var0, var1, false, nullptr, gob);
break;
}
case SMART_EVENT_PASSENGER_REMOVED:
@@ -4352,11 +4376,16 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
case SMART_EVENT_EVENT_PHASE_CHANGE:
{
if (!IsInPhase(e.event.eventPhaseChange.phasemask))
{
return;
}
ProcessAction(e, GetLastInvoker());
WorldObject* templastInvoker = GetLastInvoker();
if (!templastInvoker)
return;
if (!IsUnit(templastInvoker))
return;
ProcessAction(e, templastInvoker->ToUnit());
break;
}
case SMART_EVENT_GAME_EVENT_START:
@@ -5178,14 +5207,14 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
}
}
Unit* SmartScript::GetLastInvoker(Unit* invoker) const
WorldObject* SmartScript::GetLastInvoker(WorldObject* invoker) const
{
// Xinef: Look for invoker only on map of base object... Prevents multithreaded crashes
if (GetBaseObject())
return ObjectAccessor::GetUnit(*GetBaseObject(), mLastInvoker);
return ObjectAccessor::GetWorldObject(*GetBaseObject(), mLastInvoker);
// xinef: used for area triggers invoker cast
else if (invoker)
return ObjectAccessor::GetUnit(*invoker, mLastInvoker);
return ObjectAccessor::GetWorldObject(*invoker, mLastInvoker);
return nullptr;
}