chore: add AI state diagnostics for animation investigation
Added diagnostic functions to inspect proxy actor AI state: - DiagnosticProxyAIState(): logs AIProcess presence, current package, pathfinding state - EnableProxyAIAnimationMode(): placeholder for AI animation enablement - Called on proxy spawn to gather evidence about AI setup This is part of the AI approach investigation - we need to verify if proxies already have active AIProcess instances and what packages they have assigned. If the animation issue is just about calling Move() naturally (which happens when the AI runs), we can potentially enable this by assigning proper packages to the proxy and letting the game loop drive movement. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -481,6 +481,74 @@ namespace
|
||||
a_proxy.SetHeading(a_heading);
|
||||
}
|
||||
|
||||
// NEW: Enable AI-driven animation mode
|
||||
// This function attempts to make the proxy a "real" AI actor that plays animations
|
||||
// Strategy: Let the AI system drive movement via Move(), which triggers animations
|
||||
// Override position with SetPosition() to keep network sync accurate
|
||||
void EnableProxyAIAnimationMode(
|
||||
RE::Actor& a_proxy,
|
||||
const RE::PlayerCharacter& a_player)
|
||||
{
|
||||
(void)a_player;
|
||||
|
||||
// Ensure the proxy has an AIProcess (normally should have one by default)
|
||||
if (!a_proxy.currentProcess) {
|
||||
// If no AI process exists, we can't enable animation mode
|
||||
LogWarningWithLocalPlayerPrefix(std::format(
|
||||
"EnableProxyAIAnimationMode: Proxy {:08X} has no AIProcess; cannot enable animation mode.",
|
||||
a_proxy.GetFormID()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the proxy is already set up for movement
|
||||
auto* process = a_proxy.currentProcess;
|
||||
|
||||
// Key insight: We want the proxy to think it's following the player
|
||||
// But we DON'T want actual pathfinding (Creation Engine path bugs)
|
||||
// Solution: The proxy will idle, and we'll move it via our network updates
|
||||
// While the animation system still gets velocity updates from game loop
|
||||
|
||||
// For now, just document that this mode is available
|
||||
LogInfoWithLocalPlayerPrefix(std::format(
|
||||
"Proxy {:08X} has active AIProcess; AI animation mode is available.",
|
||||
a_proxy.GetFormID()));
|
||||
}
|
||||
|
||||
// Diagnostic: Log proxy's AI state
|
||||
void DiagnosticProxyAIState(
|
||||
RE::Actor& a_proxy,
|
||||
std::string_view a_label)
|
||||
{
|
||||
if (!a_proxy.currentProcess) {
|
||||
LogInfoWithLocalPlayerPrefix(std::format(
|
||||
"[{}] Proxy {:08X}: NO AIProcess",
|
||||
a_label,
|
||||
a_proxy.GetFormID()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get package info
|
||||
std::string packageInfo = "NO_PACKAGE";
|
||||
if (a_proxy.currentProcess->currentPackage.package) {
|
||||
packageInfo = std::format("PACKAGE_EXISTS");
|
||||
}
|
||||
|
||||
// Get locomotion state
|
||||
bool isPathing = a_proxy.IsPathing();
|
||||
bool isPathValid = a_proxy.IsPathValid();
|
||||
bool isPathComplete = a_proxy.IsPathingComplete();
|
||||
|
||||
LogInfoWithLocalPlayerPrefix(std::format(
|
||||
"[{}] Proxy {:08X}: AIProcess={}, {}, isPathing={}, pathValid={}, pathComplete={}",
|
||||
a_label,
|
||||
a_proxy.GetFormID(),
|
||||
(void*)a_proxy.currentProcess,
|
||||
packageInfo,
|
||||
isPathing,
|
||||
isPathValid,
|
||||
isPathComplete));
|
||||
}
|
||||
|
||||
bool IsProxyMovementPackageType(RE::PTYPE a_type)
|
||||
{
|
||||
switch (a_type) {
|
||||
@@ -3479,10 +3547,14 @@ namespace
|
||||
}
|
||||
const auto finalSpawnPosition = spawnedActor->GetPosition();
|
||||
|
||||
g_runtimeProxySpawnSucceeded = true;
|
||||
g_runtimeProxySpawnAttemptInProgress = false;
|
||||
StartRuntimeProxyVisibilityHoldIfNeeded();
|
||||
LogInfoWithLocalPlayerPrefix(std::format(
|
||||
g_runtimeProxySpawnSucceeded = true;
|
||||
g_runtimeProxySpawnAttemptInProgress = false;
|
||||
StartRuntimeProxyVisibilityHoldIfNeeded();
|
||||
|
||||
// NEW: Log AI state for animation investigation
|
||||
DiagnosticProxyAIState(*spawnedActor, "ProxySpawnSuccess");
|
||||
|
||||
LogInfoWithLocalPlayerPrefix(std::format(
|
||||
"Runtime proxy spawn succeeded: actorBase={:08X}, actorBaseSource={}, handle={:08X}, createdRef={:08X}, resolvedAsActor=true, parentCell={:08X}, position={}. Stage 3 will prefer this actor for the single active remote representation while keeping the placed fallback available.",
|
||||
a_baseActor->GetFormID(),
|
||||
GetRuntimeActorBaseSourceLabel(a_actorBaseSource),
|
||||
|
||||
Reference in New Issue
Block a user