Add [AltFollow] diagnostics to the companion follow loop

Throttled (5s) log lines give the exact gate when a spawned altbot does
not follow: different_map / no_intents skip, combat skip, and the
formation decision (formed slot_dist vs owner_dist vs rad) that decides
move_to_slot vs follow_intent vs hold-in-place.
This commit is contained in:
devbox
2026-08-13 21:53:51 +10:00
parent fb0723b653
commit 20f590ccb1
+42 -2
View File
@@ -1289,7 +1289,21 @@ void Module::OnWorldUpdate(std::chrono::milliseconds diff)
if (bot->GetMapId() != owner->GetMapId() ||
!Services::HasIntents(botId))
{
static std::unordered_map<uint32, uint32> s_skipDbg;
uint32 const now_dbg = getMSTime();
if (now_dbg - s_skipDbg[botId] >= 5000)
{
s_skipDbg[botId] = now_dbg;
TC_LOG_ERROR("playerbot.v2",
"[AltFollow] {} skip reason={} map_bot={} map_owner={} has_intents={}",
bot->GetName(),
(bot->GetMapId() != owner->GetMapId()) ? "different_map" : "no_intents",
bot->GetMapId(), owner->GetMapId(),
Services::HasIntents(botId));
}
continue;
}
// Emergency heal on owner
if (owner->GetHealth() > 0 &&
@@ -1377,7 +1391,19 @@ void Module::OnWorldUpdate(std::chrono::milliseconds diff)
// Formation / follow — never while fighting
if (botFighting || ownerHasFight || bot->IsNonMeleeSpellCast(false))
{
static std::unordered_map<uint32, uint32> s_combatDbg;
uint32 const now_dbg = getMSTime();
if (now_dbg - s_combatDbg[botId] >= 5000)
{
s_combatDbg[botId] = now_dbg;
TC_LOG_ERROR("playerbot.v2",
"[AltFollow] {} skip reason=combat bot_fight={} owner_fight={} casting={}",
bot->GetName(), botFighting, ownerHasFight,
bot->IsNonMeleeSpellCast(false));
}
continue;
}
constexpr float kFormDist = 2.0f;
constexpr float kSlotOkSq = 4.0f * 4.0f;
@@ -1387,14 +1413,15 @@ void Module::OnWorldUpdate(std::chrono::milliseconds diff)
float followDist = kFormDist;
float followAngle = 0.f;
FormationType ft = FormationType::Free;
uint8 ai_slot = 0;
if (BotAI* ai = Services::Registry().ai(botId))
{
ft = ai->effective_formation_type(false);
if (ft != FormationType::Free)
{
uint8 const slot = ai->formation_slot();
ai_slot = ai->formation_slot();
FormationOffset const off =
ComputeFormationOffset(ft, slot, kFormDist);
ComputeFormationOffset(ft, ai_slot, kFormDist);
followDist = off.distance;
followAngle = off.angle_radians;
}
@@ -1443,6 +1470,19 @@ void Module::OnWorldUpdate(std::chrono::milliseconds diff)
owner->GetGUID(), followDist, followAngle};
Services::Intents(botId).push(std::move(it));
}
static std::unordered_map<uint32, uint32> s_followDbg;
uint32 const now_dbg = getMSTime();
if (now_dbg - s_followDbg[botId] >= 5000)
{
s_followDbg[botId] = now_dbg;
TC_LOG_ERROR("playerbot.v2",
"[AltFollow] {} decision={} ft={} slot={} slot_dist={:.1f} owner_dist={:.1f} rad={:.1f}",
bot->GetName(),
(ft == FormationType::Free) ? "free" : "formed",
int(ft), uint32(ai_slot),
std::sqrt(slotDistSq), std::sqrt(odSq), rad);
}
}
}
}