60 lines
2.5 KiB
Plaintext
60 lines
2.5 KiB
Plaintext
// PHASE 5D: Thread-safe validation - handle both GameObjects and Creatures
|
|
WorldObject* targetObject = nullptr;
|
|
bool isCreature = targetGuid.IsCreature();
|
|
|
|
if (isCreature)
|
|
{
|
|
// Target is a Creature (e.g., invisible fire trigger)
|
|
Creature* creature = ObjectAccessor::GetCreature(*bot, targetGuid);
|
|
if (creature && creature->IsAlive())
|
|
{
|
|
targetObject = creature;
|
|
TC_LOG_ERROR("module.playerbot.quest", "Found nearest valid Creature {} at ({:.1f}, {:.1f}, {:.1f}) - distance {:.1f}yd ({} valid nearby)",
|
|
creature->GetEntry(),
|
|
creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(),
|
|
nearestDistance, validObjectsFound);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Target is a GameObject
|
|
auto snapshot = SpatialGridQueryHelpers::FindGameObjectByGuid(bot, targetGuid);
|
|
if (snapshot)
|
|
{
|
|
GameObject* gameObject = ObjectAccessor::GetGameObject(*bot, targetGuid);
|
|
if (gameObject)
|
|
{
|
|
targetObject = gameObject;
|
|
TC_LOG_ERROR("module.playerbot.quest", "Found nearest valid GameObject {} at ({:.1f}, {:.1f}, {:.1f}) - distance {:.1f}yd ({} valid nearby)",
|
|
gameObject->GetEntry(),
|
|
gameObject->GetPositionX(), gameObject->GetPositionY(), gameObject->GetPositionZ(),
|
|
nearestDistance, validObjectsFound);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!targetObject)
|
|
{
|
|
TC_LOG_ERROR("module.playerbot.quest", "UseQuestItemOnTarget: No valid target (GameObject or Creature) {} found (scanned {} nearby objects, {} were valid but GUID resolution failed)",
|
|
targetObjectId, nearbyObjects.size(), validObjectsFound);
|
|
|
|
// All targets might be despawned/used - navigate to objective area to wait for respawn
|
|
NavigateToObjective(ai, objective);
|
|
return;
|
|
}
|
|
|
|
// CRITICAL: Calculate SAFE distance from target based on type and damage radius
|
|
float damageRadius = 0.0f;
|
|
bool causesDamage = false;
|
|
float safeDistance = 10.0f; // Default safe distance
|
|
|
|
// For GameObjects, detect damage-causing types and their radius
|
|
GameObject* gameObject = targetObject->ToGameObject();
|
|
if (gameObject)
|
|
{
|
|
GameObjectTemplate const* goInfo = gameObject->GetGOInfo();
|
|
if (goInfo)
|
|
{
|
|
switch (goInfo->type)
|
|
{
|