Skip to content

Commit

Permalink
Scripts: Fix interaction of SCRIPT_FLAG_BUDDY_BY_STRING_ID and SCRIPT…
Browse files Browse the repository at this point in the history
…_COMMAND_TERMINATE_SCRIPT
  • Loading branch information
killerwife committed Dec 15, 2023
1 parent b2c589c commit 4a04b34
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 35 deletions.
80 changes: 47 additions & 33 deletions src/game/DBScripts/ScriptMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1326,7 +1326,7 @@ bool ScriptAction::GetScriptCommandObject(const ObjectGuid guid, bool includeIte

/// Select source and target for a script command
/// Returns false if an error happened
bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObject* originalTarget, std::vector<WorldObject*>& finalSources, std::vector<WorldObject*>& finalTargets) const
std::pair<bool, bool> ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObject* originalTarget, std::vector<WorldObject*>& finalSources, std::vector<WorldObject*>& finalTargets) const
{
std::vector<WorldObject*> buddies;

Expand All @@ -1344,7 +1344,7 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObj
if (m_script->command != SCRIPT_COMMAND_TERMINATE_SCRIPT)
{
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u has buddy %u by guid %u but buddy is dead, skipping.", m_table, m_script->id, m_script->command, buddy->GetEntry(), m_script->searchRadiusOrGuid);
return false;
return { false, false };
}
}
}
Expand All @@ -1355,10 +1355,11 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObj
if (!buddy && m_script->command != SCRIPT_COMMAND_TERMINATE_SCRIPT)
{
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, " DB-SCRIPTS: Process table `%s` id %u, command %u has buddy by guid %u not loaded in map %u (data-flags %u), skipping.", m_table, m_script->id, m_script->command, m_script->searchRadiusOrGuid, m_map->GetId(), m_script->data_flags);
return false;
return { false, false };
}
// this type can only have one buddy result
buddies.push_back(buddy);
if (buddy)
// this type can only have one buddy result
buddies.push_back(buddy);
}
else if (m_script->data_flags & SCRIPT_FLAG_BUDDY_BY_POOL)
{
Expand Down Expand Up @@ -1398,13 +1399,14 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObj
}
}

if (!buddy)
if (!buddy && m_script->command != SCRIPT_COMMAND_TERMINATE_SCRIPT)
{
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u has buddy %u by pool id %u and no creature found in map %u (data-flags %u), skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry, m_script->searchRadiusOrGuid, m_map->GetId(), m_script->data_flags);
return false;
return { false, false };
}
// this type can only have one buddy result
buddies.push_back(buddy);
if (buddy)
// this type can only have one buddy result
buddies.push_back(buddy);
}
else if (m_script->data_flags & SCRIPT_FLAG_BUDDY_BY_SPAWN_GROUP) // Buddy by group
{
Expand Down Expand Up @@ -1464,7 +1466,7 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObj
origin = originalTarget;
auto worldObjects = m_map->GetWorldObjects(m_script->buddyEntry);
if (worldObjects == nullptr)
return false;
return { false, false };
if ((m_script->data_flags & SCRIPT_FLAG_ALL_ELIGIBLE_BUDDIES) != 0)
{
for (WorldObject* wo : *worldObjects)
Expand All @@ -1485,15 +1487,21 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObj
}
if (m_script->searchRadiusOrGuid > 0)
for (WorldObject* buddy : buddies)
if (buddy->IsWithinDist(origin, m_script->searchRadiusOrGuid))
if (!buddy->IsWithinDist(origin, m_script->searchRadiusOrGuid))
buddies.erase(std::remove(buddies.begin(), buddies.end(), buddy), buddies.end());

if (buddies.empty() && m_script->command != SCRIPT_COMMAND_TERMINATE_SCRIPT)
{
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u has buddy %u by pool id %u and no creature found in map %u (data-flags %u), skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry, m_script->searchRadiusOrGuid, m_map->GetId(), m_script->data_flags);
return { false, false };
}
}
else // Buddy by entry
{
if (!originalSource && !originalTarget)
{
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u called without buddy %u, but no source for search available, skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry);
return false;
return { false, false };
}

// Prefer non-players as searcher
Expand Down Expand Up @@ -1575,7 +1583,7 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObj
if (buddies.empty() && m_script->command != SCRIPT_COMMAND_TERMINATE_SCRIPT)
{
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u has buddy %u not found in range %u of searcher %s (data-flags %u), skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry, m_script->searchRadiusOrGuid, origin->GetGuidStr().c_str(), m_script->data_flags);
return false;
return { false, false };
}
}
}
Expand All @@ -1596,7 +1604,7 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObj
if (m_script->data_flags & SCRIPT_FLAG_SOURCE_TARGETS_SELF)
finalTargets = finalSources;

return true;
return { true, buddies.size() };
}

/// Helper to log error information
Expand Down Expand Up @@ -1663,6 +1671,7 @@ bool ScriptAction::HandleScriptStep()
std::vector<WorldObject*> targets;

Object* itemSource = nullptr;
bool buddyFound;

{
// Add scope for source & target variables so that they are not used below
Expand All @@ -1681,7 +1690,9 @@ bool ScriptAction::HandleScriptStep()
sources.push_back(static_cast<WorldObject*>(source));
if (target && target->isType(TYPEMASK_WORLDOBJECT))
targets.push_back(static_cast<WorldObject*>(target));
if (!GetScriptProcessTargets(dynamic_cast<WorldObject*>(source), dynamic_cast<WorldObject*>(target), sources, targets))
bool success;
std::tie(success, buddyFound) = GetScriptProcessTargets(dynamic_cast<WorldObject*>(source), dynamic_cast<WorldObject*>(target), sources, targets);
if (!success)
return false;

if (source && source->isType(TYPEMASK_ITEM))
Expand Down Expand Up @@ -1709,15 +1720,15 @@ bool ScriptAction::HandleScriptStep()
WorldObject* pTarget = data.second;
Object* pSourceOrItem = pSource ? pSource : itemSource;

bool result = ExecuteDbscriptCommand(pSource, pTarget, pSourceOrItem);
bool result = ExecuteDbscriptCommand(pSource, pTarget, pSourceOrItem, buddyFound);
if (result == true)
finalResult = true;
}

return finalResult;
}

bool ScriptAction::ExecuteDbscriptCommand(WorldObject* pSource, WorldObject* pTarget, Object* pSourceOrItem)
bool ScriptAction::ExecuteDbscriptCommand(WorldObject* pSource, WorldObject* pTarget, Object* pSourceOrItem, bool buddyFound)
{
if (m_script->condition_id && !sObjectMgr.IsConditionSatisfied(m_script->condition_id, pTarget, m_map, pSource, CONDITION_FROM_DBSCRIPTS))
return false;
Expand Down Expand Up @@ -2508,6 +2519,7 @@ bool ScriptAction::ExecuteDbscriptCommand(WorldObject* pSource, WorldObject* pTa
}

bool result = false;
bool terminationBuddyFound = false;
if (m_script->terminateScript.npcOrGOEntry || m_script->terminateScript.poolId || (m_script->data_flags & (SCRIPT_FLAG_BUDDY_BY_GUID)))
{
WorldObject* terminationBuddy = nullptr;
Expand Down Expand Up @@ -2598,25 +2610,27 @@ bool ScriptAction::ExecuteDbscriptCommand(WorldObject* pSource, WorldObject* pTa
}
}

if (!(m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL) && !terminationBuddy)
{
if (m_script->terminateScript.npcOrGOEntry)
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, "DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched npc entry(%u) was not found alive)", m_table, m_script->id, m_script->terminateScript.npcOrGOEntry);
else
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, "DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as no npc in pool id(%u) was found alive)", m_table, m_script->id, m_script->terminateScript.poolId);
result = true;
}
else if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL && terminationBuddy)
{
if (m_script->terminateScript.npcOrGOEntry)
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, "DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched npc entry(%u) was found alive)", m_table, m_script->id, m_script->terminateScript.npcOrGOEntry);
else
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, "DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched npc in pool id(%u) was found alive)", m_table, m_script->id, m_script->terminateScript.poolId);
result = true;
}
terminationBuddyFound = terminationBuddy;
}
else
terminationBuddyFound = buddyFound;

if (!(m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL) && !terminationBuddyFound)
{
if (m_script->terminateScript.npcOrGOEntry)
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, "DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched npc entry(%u) was not found alive)", m_table, m_script->id, m_script->terminateScript.npcOrGOEntry);
else
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, "DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as no npc in pool id(%u) was found alive)", m_table, m_script->id, m_script->terminateScript.poolId);
result = true;
}
else if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL && terminationBuddyFound)
{
if (m_script->terminateScript.npcOrGOEntry)
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, "DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched npc entry(%u) was found alive)", m_table, m_script->id, m_script->terminateScript.npcOrGOEntry);
else
DETAIL_FILTER_LOG(LOG_FILTER_DB_SCRIPT, "DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched npc in pool id(%u) was found alive)", m_table, m_script->id, m_script->terminateScript.poolId);
result = true;
}

if (result) // Terminate further steps of this script
{
Expand Down
4 changes: 2 additions & 2 deletions src/game/DBScripts/ScriptMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ class ScriptAction
ScriptAction(ScriptMapType scriptType, Map* _map, ObjectGuid _sourceGuid, ObjectGuid _targetGuid, ObjectGuid _ownerGuid, std::shared_ptr<ScriptInfo> _script);

bool HandleScriptStep(); // return true IF AND ONLY IF the script should be terminated
bool ExecuteDbscriptCommand(WorldObject* pSource, WorldObject* pTarget, Object* pSourceOrItem);
bool ExecuteDbscriptCommand(WorldObject* pSource, WorldObject* pTarget, Object* pSourceOrItem, bool buddyFound);

const char* GetTableName() const { return m_table; }
uint32 GetId() const { return m_script->id; }
Expand All @@ -627,7 +627,7 @@ class ScriptAction

// Helper functions
bool GetScriptCommandObject(const ObjectGuid guid, bool includeItem, Object*& resultObject) const;
bool GetScriptProcessTargets(WorldObject* originalSource, WorldObject* originalTarget, std::vector<WorldObject*>& finalSources, std::vector<WorldObject*>& finalTargets) const;
std::pair<bool, bool> GetScriptProcessTargets(WorldObject* originalSource, WorldObject* originalTarget, std::vector<WorldObject*>& finalSources, std::vector<WorldObject*>& finalTargets) const;
bool LogIfNotCreature(WorldObject* pWorldObject) const;
bool LogIfNotUnit(WorldObject* pWorldObject) const;
bool LogIfNotGameObject(WorldObject* pWorldObject) const;
Expand Down

0 comments on commit 4a04b34

Please sign in to comment.