fix(Core/AI): validate stored targets (#12489)

Co-authored-by: Meji <meji46@users.noreply.github.com>
Co-authored-by: Ariel Silva <ariel-@users.noreply.github.com>
Co-authored-by: Shauren <shauren.trinity@gmail.com>

Co-authored-by: Meji <meji46@users.noreply.github.com>
Co-authored-by: Ariel Silva <ariel-@users.noreply.github.com>
Co-authored-by: Shauren <shauren.trinity@gmail.com>
This commit is contained in:
Nefertumm
2022-07-24 13:06:11 -03:00
committed by GitHub
parent 5bcc54a617
commit f0777d1fd3
4 changed files with 98 additions and 23 deletions

View File

@@ -2051,7 +2051,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_SEND_TARGET_TO_TARGET:
{
ObjectVector const* storedTargets = GetStoredTargetVector(e.action.sendTargetToTarget.id);
WorldObject* ref = GetBaseObject();
if (!ref)
ref = unit;
if (!ref)
break;
ObjectVector const* storedTargets = GetStoredTargetVector(e.action.sendTargetToTarget.id, *ref);
if (!storedTargets)
break;
@@ -2919,6 +2927,17 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
break;
case SMART_TARGET_CREATURE_RANGE:
{
WorldObject* ref = baseObject;
if (!ref)
ref = scriptTrigger;
if (!ref)
{
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_CREATURE_RANGE: Entry {} SourceType {} Event {} Action {} Target {} is missing base object or invoker",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
break;
}
ObjectVector units;
GetWorldObjectsInDist(units, static_cast<float>(e.target.unitRange.maxDist));
@@ -2939,7 +2958,7 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
continue;
}
if (((e.target.unitRange.creature && unit->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(unit, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist))
if (((e.target.unitRange.creature && unit->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && ref->IsInRange(unit, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist))
targets.push_back(unit);
}
@@ -2994,6 +3013,18 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
}
case SMART_TARGET_GAMEOBJECT_RANGE:
{
WorldObject* ref = baseObject;
if (!ref)
ref = scriptTrigger;
if (!ref)
{
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_GAMEOBJECT_RANGE: Entry: {} SourceType {} Event {} Action {} Target {} is missing base object or invoker.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
break;
}
ObjectVector units;
GetWorldObjectsInDist(units, static_cast<float>(e.target.goRange.maxDist));
@@ -3005,7 +3036,7 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
if (go && go->GetGUID() == unit->GetGUID())
continue;
if (((e.target.goRange.entry && IsGameObject(unit) && unit->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((unit), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist))
if (((e.target.goRange.entry && IsGameObject(unit) && unit->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && ref->IsInRange((unit), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist))
targets.push_back(unit);
}
@@ -3015,7 +3046,8 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
{
if (!scriptTrigger && !baseObject)
{
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_CREATURE_GUID can not be used without invoker");
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_CREATURE_GUID: Entry {} SourceType {} Event {} Action {} Target {} is missing base object or invoker.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
break;
}
@@ -3028,7 +3060,8 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
{
if (!scriptTrigger && !GetBaseObject())
{
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker");
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_GAMEOBJECT_GUID: Entry {} SourceType {} Event {} Action {} Target {} is missing base object or invoker.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
break;
}
@@ -3060,32 +3093,75 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
}
case SMART_TARGET_STORED:
{
if (ObjectVector const* stored = GetStoredTargetVector(e.target.stored.id))
WorldObject* ref = baseObject;
if (!ref)
ref = scriptTrigger;
if (!ref)
{
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_STORED: Entry {} SourceType {} Event {} Action {} Target {} is missing base object or invoker.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
break;
}
if (ObjectVector const* stored = GetStoredTargetVector(e.target.stored.id, *ref))
targets.assign(stored->begin(), stored->end());
break;
}
case SMART_TARGET_CLOSEST_CREATURE:
{
Creature* target = GetClosestCreatureWithEntry(GetBaseObject(), e.target.unitClosest.entry, (float)(e.target.unitClosest.dist ? e.target.unitClosest.dist : 100), !e.target.unitClosest.dead);
WorldObject* ref = baseObject;
if (!ref)
ref = scriptTrigger;
if (!ref)
{
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_CLOSEST_CREATURE: Entry {} SourceType {} Event {} Action {} Target {} is missing base object or invoker.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
break;
}
Creature* target = GetClosestCreatureWithEntry(ref, e.target.unitClosest.entry, (float)(e.target.unitClosest.dist ? e.target.unitClosest.dist : 100), !e.target.unitClosest.dead);
if (target)
targets.push_back(target);
break;
}
case SMART_TARGET_CLOSEST_GAMEOBJECT:
{
GameObject* target = GetClosestGameObjectWithEntry(GetBaseObject(), e.target.goClosest.entry, (float)(e.target.goClosest.dist ? e.target.goClosest.dist : 100), e.target.goClosest.onlySpawned);
WorldObject* ref = baseObject;
if (!ref)
ref = scriptTrigger;
if (!ref)
{
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_CLOSEST_GAMEOBJECT: Entry {} SourceType {} Event {} Action {} Target {} is missing base object or invoker.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
break;
}
GameObject* target = GetClosestGameObjectWithEntry(ref, e.target.goClosest.entry, (float)(e.target.goClosest.dist ? e.target.goClosest.dist : 100), e.target.goClosest.onlySpawned);
if (target)
targets.push_back(target);
break;
}
case SMART_TARGET_CLOSEST_PLAYER:
{
if (WorldObject* obj = GetBaseObject())
WorldObject* ref = baseObject;
if (!ref)
ref = scriptTrigger;
if (!ref)
{
Player* target = obj->SelectNearestPlayer((float)e.target.playerDistance.dist);
if (target)
targets.push_back(target);
LOG_ERROR("scripts.ai.sai", "SMART_TARGET_CLOSEST_PLAYER: Entry {} SourceType {} Event {} Action {} Target {} is missing base object or invoker.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
break;
}
if (Player* target = ref->SelectNearestPlayer((float)e.target.playerDistance.dist))
targets.push_back(target);
break;
}
case SMART_TARGET_OWNER_OR_SUMMONER: