diff options
author | Meji <alvaromegias_46@hotmail.com> | 2021-12-04 20:40:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-04 20:40:06 +0100 |
commit | 198d18bef5d3480cb30c80e4a4946327f401a6d4 (patch) | |
tree | e8879143817db34d8e0923582b1d96f3d0da61ea | |
parent | 0d0f9784a92245879c1e98b011dc112b1b8bb76b (diff) |
Core/SAI: Fixed crash when using SMART_TARGET_CLOSEST_* in areatrigger smart script (#27336)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 88 |
1 files changed, 75 insertions, 13 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 0a3ed95a6dc..28b4f008b5b 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2723,6 +2723,17 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, break; case SMART_TARGET_CREATURE_RANGE: { + WorldObject* ref = baseObject; + if (!ref) + ref = scriptTrigger; + + if (!ref) + { + TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_RANGE: Entry " SI64FMTD " SourceType %u Event %u Action %u Target %u 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)); @@ -2734,7 +2745,7 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, if (me && me->GetGUID() == unit->GetGUID()) continue; - if ((!e.target.unitRange.creature || unit->ToCreature()->GetEntry() == 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) && ref->IsInRange(unit, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist))) targets.push_back(unit); } @@ -2786,6 +2797,17 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, } case SMART_TARGET_GAMEOBJECT_RANGE: { + WorldObject* ref = baseObject; + if (!ref) + ref = scriptTrigger; + + if (!ref) + { + TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_RANGE: Entry " SI64FMTD " SourceType %u Event %u Action %u Target %u 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)); @@ -2797,7 +2819,7 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, if (go && go->GetGUID() == unit->GetGUID()) continue; - if ((!e.target.goRange.entry && unit->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(unit, float(e.target.goRange.minDist), float(e.target.goRange.maxDist))) + if ((!e.target.goRange.entry && unit->ToGameObject()->GetEntry() == e.target.goRange.entry) && ref->IsInRange(unit, float(e.target.goRange.minDist), float(e.target.goRange.maxDist))) targets.push_back(unit); } @@ -2809,7 +2831,8 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, { if (!scriptTrigger && !baseObject) { - TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID can not be used without invoker"); + TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID: Entry " SI64FMTD " SourceType %u Event %u Action %u Target %u is missing base object or invoker.", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType()); break; } @@ -2822,7 +2845,8 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, { if (!scriptTrigger && !baseObject) { - TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker"); + TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID: Entry " SI64FMTD " SourceType %u Event %u Action %u Target %u is missing base object or invoker.", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType()); break; } @@ -2854,32 +2878,70 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, } case SMART_TARGET_STORED: { - WorldObject* ref = GetBaseObject(); + WorldObject* ref = baseObject; if (!ref) ref = scriptTrigger; - if (ref) - if (ObjectVector const* stored = GetStoredTargetVector(e.target.stored.id, *ref)) - targets.assign(stored->begin(), stored->end()); + if (!ref) + { + TC_LOG_ERROR("sql.sql", "SMART_TARGET_STORED: Entry " SI64FMTD " SourceType %u Event %u Action %u Target %u 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: { - if (Creature* target = baseObject->FindNearestCreature(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead)) + WorldObject* ref = baseObject; + if (!ref) + ref = scriptTrigger; + + if (!ref) + { + TC_LOG_ERROR("sql.sql", "SMART_TARGET_CLOSEST_CREATURE: Entry " SI64FMTD " SourceType %u Event %u Action %u Target %u is missing base object or invoker.", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType()); + break; + } + + if (Creature* target = ref->FindNearestCreature(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead)) targets.push_back(target); break; } case SMART_TARGET_CLOSEST_GAMEOBJECT: { - if (GameObject* target = baseObject->FindNearestGameObject(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100))) + WorldObject* ref = baseObject; + if (!ref) + ref = scriptTrigger; + + if (!ref) + { + TC_LOG_ERROR("sql.sql", "SMART_TARGET_CLOSEST_GAMEOBJECT: Entry " SI64FMTD " SourceType %u Event %u Action %u Target %u is missing base object or invoker.", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType()); + break; + } + + if (GameObject* target = ref->FindNearestGameObject(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100))) targets.push_back(target); break; } case SMART_TARGET_CLOSEST_PLAYER: { - if (WorldObject* obj = GetBaseObject()) - if (Player* target = obj->SelectNearestPlayer(float(e.target.playerDistance.dist))) - targets.push_back(target); + WorldObject* ref = baseObject; + if (!ref) + ref = scriptTrigger; + + if (!ref) + { + TC_LOG_ERROR("sql.sql", "SMART_TARGET_CLOSEST_PLAYER: Entry " SI64FMTD " SourceType %u Event %u Action %u Target %u 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: |