Core/SAI: Added support for StringIds to creature and gameobject targets (#29910)

Co-authored-by: Shauren <shauren.trinity@gmail.com>
(cherry picked from commit 2ce4068459)
This commit is contained in:
Meji
2024-04-11 10:15:46 +02:00
committed by Ovahlord
parent 125b6d2ed7
commit 2c56ee9ce1
6 changed files with 157 additions and 108 deletions
+63 -85
View File
@@ -1656,7 +1656,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
ObjectVector casters;
GetTargets(casters, CreateSmartEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0, 0), unit);
GetTargets(casters, CreateSmartEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, e.action.crossCast.targetParam4, e.action.param_string, 0), unit);
CastSpellExtraArgs args;
if (e.action.crossCast.castFlags & SMARTCAST_TRIGGERED)
@@ -2537,7 +2537,7 @@ void SmartScript::ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, ui
RecalcTimer(e, std::min<uint32>(min, 5000), std::min<uint32>(min, 5000));
}
SmartScriptHolder SmartScript::CreateSmartEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, uint32 action_param7, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 target_param4, uint32 phaseMask)
SmartScriptHolder SmartScript::CreateSmartEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, uint32 action_param7, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 target_param4, std::string_view targetParamString, uint32 phaseMask)
{
SmartScriptHolder script;
script.event.type = e;
@@ -2564,6 +2564,7 @@ SmartScriptHolder SmartScript::CreateSmartEvent(SMART_EVENT e, uint32 event_flag
script.target.raw.param2 = target_param2;
script.target.raw.param3 = target_param3;
script.target.raw.param4 = target_param4;
script.target.param_string = targetParamString;
script.source_type = SMART_SCRIPT_TYPE_CREATURE;
InitTimer(script);
@@ -2686,20 +2687,13 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
break;
}
ObjectVector units;
GetWorldObjectsInDist(units, static_cast<float>(e.target.unitRange.maxDist));
std::vector<Creature*> creatures;
ref->GetCreatureListWithOptionsInGrid(creatures, static_cast<float>(e.target.unitRange.maxDist), {
.CreatureId = e.target.unitRange.creature ? Optional<uint32>(e.target.unitRange.creature) : Optional<uint32>(),
.StringId = !e.target.param_string.empty() ? Optional<std::string_view>(e.target.param_string) : Optional<std::string_view>(),
});
for (WorldObject* unit : units)
{
if (!IsCreature(unit))
continue;
if (me && me->GetGUID() == unit->GetGUID())
continue;
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);
}
std::ranges::copy_if(creatures, std::back_inserter(targets), [&](Creature const* target) { return !ref->IsWithinDist(target, static_cast<float>(e.target.unitRange.minDist)); });
if (e.target.unitRange.maxSize)
Trinity::Containers::RandomResize(targets, e.target.unitRange.maxSize);
@@ -2707,46 +2701,21 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
}
case SMART_TARGET_CREATURE_DISTANCE:
{
ObjectVector units;
GetWorldObjectsInDist(units, static_cast<float>(e.target.unitDistance.dist));
if (!baseObject)
break;
for (WorldObject* unit : units)
{
if (!IsCreature(unit))
continue;
std::vector<Creature*> creatures;
baseObject->GetCreatureListWithOptionsInGrid(creatures, static_cast<float>(e.target.unitDistance.dist), {
.CreatureId = e.target.unitDistance.creature ? Optional<uint32>(e.target.unitDistance.creature) : Optional<uint32>(),
.StringId = !e.target.param_string.empty() ? Optional<std::string_view>(e.target.param_string) : Optional<std::string_view>(),
});
if (me && me->GetGUID() == unit->GetGUID())
continue;
if (!e.target.unitDistance.creature || unit->ToCreature()->GetEntry() == e.target.unitDistance.creature)
targets.push_back(unit);
}
targets = { creatures.begin(), creatures.end() };
if (e.target.unitDistance.maxSize)
Trinity::Containers::RandomResize(targets, e.target.unitDistance.maxSize);
break;
}
case SMART_TARGET_GAMEOBJECT_DISTANCE:
{
ObjectVector units;
GetWorldObjectsInDist(units, static_cast<float>(e.target.goDistance.dist));
for (WorldObject* unit : units)
{
if (!IsGameObject(unit))
continue;
if (go && go->GetGUID() == unit->GetGUID())
continue;
if (!e.target.goDistance.entry || unit->ToGameObject()->GetEntry() == e.target.goDistance.entry)
targets.push_back(unit);
}
if (e.target.goDistance.maxSize)
Trinity::Containers::RandomResize(targets, e.target.goDistance.maxSize);
break;
}
case SMART_TARGET_GAMEOBJECT_RANGE:
{
WorldObject* ref = baseObject;
@@ -2760,25 +2729,35 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
break;
}
ObjectVector units;
GetWorldObjectsInDist(units, static_cast<float>(e.target.goRange.maxDist));
std::vector<GameObject*> gameObjects;
ref->GetGameObjectListWithOptionsInGrid(gameObjects, static_cast<float>(e.target.goRange.maxDist), {
.GameObjectId = e.target.goRange.entry ? Optional<uint32>(e.target.goRange.entry) : Optional<uint32>(),
.StringId = !e.target.param_string.empty() ? Optional<std::string_view>(e.target.param_string) : Optional<std::string_view>(),
});
for (WorldObject* unit : units)
{
if (!IsGameObject(unit))
continue;
if (go && go->GetGUID() == unit->GetGUID())
continue;
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);
}
std::ranges::copy_if(gameObjects, std::back_inserter(targets), [&](GameObject const* target) { return !ref->IsWithinDist(target, static_cast<float>(e.target.goRange.minDist)); });
if (e.target.goRange.maxSize)
Trinity::Containers::RandomResize(targets, e.target.goRange.maxSize);
break;
}
case SMART_TARGET_GAMEOBJECT_DISTANCE:
{
if (!baseObject)
break;
std::vector<GameObject*> gameObjects;
baseObject->GetGameObjectListWithOptionsInGrid(gameObjects, static_cast<float>(e.target.goDistance.dist), {
.GameObjectId = e.target.goDistance.entry ? Optional<uint32>(e.target.goDistance.entry) : Optional<uint32>(),
.StringId = !e.target.param_string.empty() ? Optional<std::string_view>(e.target.param_string) : Optional<std::string_view>(),
});
targets = { gameObjects.begin(), gameObjects.end() };
if (e.target.goDistance.maxSize)
Trinity::Containers::RandomResize(targets, e.target.goDistance.maxSize);
break;
}
case SMART_TARGET_CREATURE_GUID:
{
if (!scriptTrigger && !baseObject)
@@ -2809,23 +2788,22 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
}
case SMART_TARGET_PLAYER_RANGE:
{
ObjectVector units;
GetWorldObjectsInDist(units, static_cast<float>(e.target.playerRange.maxDist));
if (!baseObject)
break;
if (!units.empty() && baseObject)
for (WorldObject* unit : units)
if (IsPlayer(unit) && baseObject->IsInRange(unit, float(e.target.playerRange.minDist), float(e.target.playerRange.maxDist)))
targets.push_back(unit);
std::vector<Player*> players;
baseObject->GetPlayerListInGrid(players, static_cast<float>(e.target.playerRange.maxDist));
std::ranges::copy_if(players, std::back_inserter(targets), [&](Player const* target) { return !baseObject->IsWithinDist(target, static_cast<float>(e.target.playerRange.minDist)); });
break;
}
case SMART_TARGET_PLAYER_DISTANCE:
{
ObjectVector units;
GetWorldObjectsInDist(units, static_cast<float>(e.target.playerDistance.dist));
if (!baseObject)
break;
for (WorldObject* unit : units)
if (IsPlayer(unit))
targets.push_back(unit);
std::vector<Player*> players;
baseObject->GetPlayerListInGrid(players, static_cast<float>(e.target.playerDistance.dist));
targets = { players.begin(), players.end() };
break;
}
case SMART_TARGET_STORED:
@@ -2858,7 +2836,13 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
break;
}
if (Creature* target = ref->FindNearestCreature(e.target.unitClosest.entry, float(e.target.unitClosest.dist ? e.target.unitClosest.dist : 100), !e.target.unitClosest.dead))
Creature* target = ref->FindNearestCreatureWithOptions(float(e.target.unitClosest.dist ? e.target.unitClosest.dist : 100), {
.CreatureId = e.target.unitClosest.entry,
.StringId = !e.target.param_string.empty() ? Optional<std::string_view>(e.target.param_string) : Optional<std::string_view>(),
.IsAlive = !e.target.unitClosest.dead
});
if (target)
targets.push_back(target);
break;
}
@@ -2875,7 +2859,12 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
break;
}
if (GameObject* target = ref->FindNearestGameObject(e.target.goClosest.entry, float(e.target.goClosest.dist ? e.target.goClosest.dist : 100)))
GameObject* target = ref->FindNearestGameObjectWithOptions(float(e.target.goClosest.dist ? e.target.goClosest.dist : 100), {
.GameObjectId = e.target.goClosest.entry,
.StringId = !e.target.param_string.empty() ? Optional<std::string_view>(e.target.param_string) : Optional<std::string_view>()
});
if (target)
targets.push_back(target);
break;
}
@@ -2983,17 +2972,6 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
}
}
void SmartScript::GetWorldObjectsInDist(ObjectVector& targets, float dist) const
{
WorldObject* obj = GetBaseObject();
if (!obj)
return;
Trinity::AllWorldObjectsInRange u_check(obj, dist);
Trinity::WorldObjectListSearcher<Trinity::AllWorldObjectsInRange> searcher(obj, targets, u_check);
Cell::VisitAllObjects(obj, searcher, dist);
}
void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob, std::string const& varString)
{
if (!e.active && e.GetEventType() != SMART_EVENT_LINK)