mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/SAI: Added support for StringIds to creature and gameobject targets (#29910)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
This commit is contained in:
3
sql/updates/world/master/2024_04_11_00_world.sql
Normal file
3
sql/updates/world/master/2024_04_11_00_world.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `smart_scripts`
|
||||
ADD `action_param_string` VARCHAR(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL AFTER `action_param7`,
|
||||
ADD `target_param_string` VARCHAR(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL AFTER `target_param4`;
|
||||
@@ -27,7 +27,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(WORLD_DEL_LINKED_RESPAWN_MASTER, "DELETE FROM linked_respawn WHERE linkedGuid = ? AND linkType = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_REP_LINKED_RESPAWN, "REPLACE INTO linked_respawn (guid, linkedGuid, linkType) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEXT, "SELECT CreatureID, GroupID, ID, Text, Type, Language, Probability, Emote, Duration, Sound, SoundPlayType, BroadcastTextId, TextRange FROM creature_text", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, Difficulties, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, event_param5, event_param_string, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, action_param7, target_type, target_param1, target_param2, target_param3, target_param4, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, Difficulties, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, event_param5, event_param_string, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, action_param7, action_param_string, target_type, target_param1, target_param2, target_param3, target_param4, target_param_string, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_DEL_GAMEOBJECT, "DELETE FROM gameobject WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_DEL_EVENT_GAMEOBJECT, "DELETE FROM game_event_gameobject WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_INS_GRAVEYARD_ZONE, "INSERT INTO graveyard_zone (ID, GhostZone) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -51,8 +51,7 @@ class TC_GAME_API SmartScript
|
||||
void ProcessAction(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
|
||||
void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
|
||||
void GetTargets(ObjectVector& targets, SmartScriptHolder const& e, WorldObject* invoker = nullptr) const;
|
||||
void GetWorldObjectsInDist(ObjectVector& objects, float dist) const;
|
||||
static SmartScriptHolder 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);
|
||||
static SmartScriptHolder 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);
|
||||
void SetPathId(uint32 id) { mPathId = id; }
|
||||
uint32 GetPathId() const { return mPathId; }
|
||||
WorldObject* GetBaseObject() const;
|
||||
|
||||
@@ -298,16 +298,18 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
||||
temp.action.raw.param5 = fields[20].GetUInt32();
|
||||
temp.action.raw.param6 = fields[21].GetUInt32();
|
||||
temp.action.raw.param7 = fields[22].GetUInt32();
|
||||
temp.action.param_string = fields[23].GetString();
|
||||
|
||||
temp.target.type = (SMARTAI_TARGETS)fields[23].GetUInt8();
|
||||
temp.target.raw.param1 = fields[24].GetUInt32();
|
||||
temp.target.raw.param2 = fields[25].GetUInt32();
|
||||
temp.target.raw.param3 = fields[26].GetUInt32();
|
||||
temp.target.raw.param4 = fields[27].GetUInt32();
|
||||
temp.target.x = fields[28].GetFloat();
|
||||
temp.target.y = fields[29].GetFloat();
|
||||
temp.target.z = fields[30].GetFloat();
|
||||
temp.target.o = fields[31].GetFloat();
|
||||
temp.target.type = (SMARTAI_TARGETS)fields[24].GetUInt8();
|
||||
temp.target.raw.param1 = fields[25].GetUInt32();
|
||||
temp.target.raw.param2 = fields[26].GetUInt32();
|
||||
temp.target.raw.param3 = fields[27].GetUInt32();
|
||||
temp.target.raw.param4 = fields[28].GetUInt32();
|
||||
temp.target.param_string = fields[29].GetString();
|
||||
temp.target.x = fields[30].GetFloat();
|
||||
temp.target.y = fields[31].GetFloat();
|
||||
temp.target.z = fields[32].GetFloat();
|
||||
temp.target.o = fields[33].GetFloat();
|
||||
|
||||
//check target
|
||||
if (!IsTargetValid(temp))
|
||||
@@ -851,7 +853,7 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e)
|
||||
}
|
||||
}();
|
||||
|
||||
static size_t rawCount = sizeof(SmartEvent::raw) / sizeof(uint32);
|
||||
constexpr size_t rawCount = sizeof(SmartEvent::raw) / sizeof(uint32);
|
||||
size_t paramsCount = paramsStructSize / sizeof(uint32);
|
||||
|
||||
for (size_t index = paramsCount; index < rawCount; index++)
|
||||
@@ -864,6 +866,25 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e)
|
||||
}
|
||||
}
|
||||
|
||||
bool eventUsesStringParam = [&]
|
||||
{
|
||||
switch (e.GetEventType())
|
||||
{
|
||||
case SMART_EVENT_SCENE_TRIGGER:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (!eventUsesStringParam && !e.event.param_string.empty())
|
||||
{
|
||||
TC_LOG_WARN("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has unused event_param_string with value {}, it should be NULL.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.param_string);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1014,7 +1035,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
||||
}
|
||||
}();
|
||||
|
||||
static size_t rawCount = sizeof(SmartAction::raw) / sizeof(uint32);
|
||||
constexpr size_t rawCount = sizeof(SmartAction::raw) / sizeof(uint32);
|
||||
size_t paramsCount = paramsStructSize / sizeof(uint32);
|
||||
|
||||
for (size_t index = paramsCount; index < rawCount; index++)
|
||||
@@ -1027,6 +1048,25 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
||||
}
|
||||
}
|
||||
|
||||
bool actionUsesStringParam = [&]
|
||||
{
|
||||
switch (e.GetActionType())
|
||||
{
|
||||
case SMART_ACTION_CROSS_CAST:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (!actionUsesStringParam && !e.action.param_string.empty())
|
||||
{
|
||||
TC_LOG_WARN("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has unused action_param_string with value {}, it should be NULL.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.param_string);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1075,7 +1115,7 @@ bool SmartAIMgr::CheckUnusedTargetParams(SmartScriptHolder const& e)
|
||||
}
|
||||
}();
|
||||
|
||||
static size_t rawCount = sizeof(SmartTarget::raw) / sizeof(uint32);
|
||||
constexpr size_t rawCount = sizeof(SmartTarget::raw) / sizeof(uint32);
|
||||
size_t paramsCount = paramsStructSize / sizeof(uint32);
|
||||
|
||||
for (size_t index = paramsCount; index < rawCount; index++)
|
||||
@@ -1088,6 +1128,30 @@ bool SmartAIMgr::CheckUnusedTargetParams(SmartScriptHolder const& e)
|
||||
}
|
||||
}
|
||||
|
||||
bool targetUsesStringParam = [&]
|
||||
{
|
||||
switch (e.GetTargetType())
|
||||
{
|
||||
case SMART_TARGET_CREATURE_RANGE:
|
||||
case SMART_TARGET_CREATURE_DISTANCE:
|
||||
case SMART_TARGET_GAMEOBJECT_RANGE:
|
||||
case SMART_TARGET_GAMEOBJECT_DISTANCE:
|
||||
case SMART_TARGET_CLOSEST_CREATURE:
|
||||
case SMART_TARGET_CLOSEST_GAMEOBJECT:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (!targetUsesStringParam && !e.target.param_string.empty())
|
||||
{
|
||||
TC_LOG_WARN("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has unused target_param_string with value {}, it should be NULL.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.target.param_string);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ typedef uint32 SAIBool;
|
||||
|
||||
enum eSmartAI
|
||||
{
|
||||
SMART_EVENT_PARAM_COUNT = 4,
|
||||
SMART_EVENT_PARAM_COUNT = 5,
|
||||
SMART_ACTION_PARAM_COUNT = 7,
|
||||
SMART_SUMMON_COUNTER = 0xFFFFFF,
|
||||
SMART_ESCORT_LAST_OOC_POINT = 0xFFFFFF,
|
||||
@@ -543,7 +543,7 @@ enum SMART_ACTION
|
||||
SMART_ACTION_REMOVE_NPC_FLAG = 83, // Flags
|
||||
SMART_ACTION_SIMPLE_TALK = 84, // groupID, can be used to make players say groupID, Text_over event is not triggered, whisper can not be used (Target units will say the text)
|
||||
SMART_ACTION_SELF_CAST = 85, // spellID, castFlags
|
||||
SMART_ACTION_CROSS_CAST = 86, // spellID, castFlags, CasterTargetType, CasterTarget param1, CasterTarget param2, CasterTarget param3, ( + the origonal target fields as Destination target), CasterTargets will cast spellID on all Targets (use with caution if targeting multiple * multiple units)
|
||||
SMART_ACTION_CROSS_CAST = 86, // spellID, castFlags, CasterTargetType, CasterTarget param1, CasterTarget param2, CasterTarget param3, CasterTarget param4, CasterTarget ParamString ( + the original target fields as Destination target), CasterTargets will cast spellID on all Targets (use with caution if targeting multiple * multiple units)
|
||||
SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST = 87, // script9 ids 1-9
|
||||
SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST = 88, // script9 id min, max
|
||||
SMART_ACTION_RANDOM_MOVE = 89, // maxDist
|
||||
@@ -703,6 +703,7 @@ struct SmartAction
|
||||
uint32 targetParam1;
|
||||
uint32 targetParam2;
|
||||
uint32 targetParam3;
|
||||
uint32 targetParam4;
|
||||
} crossCast;
|
||||
|
||||
struct
|
||||
@@ -1257,6 +1258,8 @@ struct SmartAction
|
||||
uint32 param7;
|
||||
} raw;
|
||||
};
|
||||
|
||||
std::string param_string;
|
||||
};
|
||||
|
||||
enum SMARTAI_SPAWN_FLAGS
|
||||
@@ -1278,18 +1281,18 @@ enum SMARTAI_TARGETS
|
||||
SMART_TARGET_HOSTILE_RANDOM_NOT_TOP = 6, // Any random target except top threat, maxdist, playerOnly, powerType + 1
|
||||
SMART_TARGET_ACTION_INVOKER = 7, // Unit who caused this Event to occur
|
||||
SMART_TARGET_POSITION = 8, // use xyz from event params
|
||||
SMART_TARGET_CREATURE_RANGE = 9, // CreatureEntry(0any), minDist, maxDist
|
||||
SMART_TARGET_CREATURE_RANGE = 9, // CreatureEntry(0any), minDist, maxDist, maxSize, StringId
|
||||
SMART_TARGET_CREATURE_GUID = 10, // guid, entry
|
||||
SMART_TARGET_CREATURE_DISTANCE = 11, // CreatureEntry(0any), maxDist
|
||||
SMART_TARGET_CREATURE_DISTANCE = 11, // CreatureEntry(0any), maxDist, maxSize, StringId
|
||||
SMART_TARGET_STORED = 12, // id, uses pre-stored target(list)
|
||||
SMART_TARGET_GAMEOBJECT_RANGE = 13, // entry(0any), min, max
|
||||
SMART_TARGET_GAMEOBJECT_RANGE = 13, // entry(0any), minDist, maxDist, StringId
|
||||
SMART_TARGET_GAMEOBJECT_GUID = 14, // guid, entry
|
||||
SMART_TARGET_GAMEOBJECT_DISTANCE = 15, // entry(0any), maxDist
|
||||
SMART_TARGET_GAMEOBJECT_DISTANCE = 15, // entry(0any), maxDist, StringId
|
||||
SMART_TARGET_INVOKER_PARTY = 16, // invoker's party members
|
||||
SMART_TARGET_PLAYER_RANGE = 17, // min, max
|
||||
SMART_TARGET_PLAYER_DISTANCE = 18, // maxDist
|
||||
SMART_TARGET_CLOSEST_CREATURE = 19, // CreatureEntry(0any), maxDist, dead?
|
||||
SMART_TARGET_CLOSEST_GAMEOBJECT = 20, // entry(0any), maxDist
|
||||
SMART_TARGET_CLOSEST_CREATURE = 19, // CreatureEntry(0any), maxDist, dead?, StringId
|
||||
SMART_TARGET_CLOSEST_GAMEOBJECT = 20, // entry(0any), maxDist, StringId
|
||||
SMART_TARGET_CLOSEST_PLAYER = 21, // maxDist
|
||||
SMART_TARGET_ACTION_INVOKER_VEHICLE = 22, // Unit's vehicle who caused this Event to occur
|
||||
SMART_TARGET_OWNER_OR_SUMMONER = 23, // Unit's owner or summoner, Use Owner/Charmer of this unit
|
||||
@@ -1442,6 +1445,8 @@ struct SmartTarget
|
||||
uint32 param4;
|
||||
} raw;
|
||||
};
|
||||
|
||||
std::string param_string;
|
||||
};
|
||||
|
||||
enum SmartScriptType
|
||||
|
||||
Reference in New Issue
Block a user