Introduce a puppet vtable hook to preserve networked locomotion Speed and fix proxy cadence. Added F4TProxyPuppet (header + impl) which installs an Actor::Update hook that writes the desired graph Speed and calls UpdateNoAI for proxy actors so the engine does not recompute/zero Speed from controller velocity. Publish active proxy FormIDs and per-proxy desired speeds so the hook targets only proxy actors. Wire animationGraphSpeed through networking: parse/send a new "animationGraphSpeed" field and store it on RemotePlayerState. Proxy animation sync now prefers the authoritative animationGraphSpeed when present, otherwise maps movementSpeed ~1:1 to graph Speed (with sprint floor and clamping). Added graph variables speedSampled/speedDamped alongside Speed and updated snapshot population and diagnostics. Removed character-controller velocity injection (was causing physics/animation conflicts) and adjusted proxy movement logic to rely on graph variables plus kinematic SetPosition. Also: Publish puppet diagnostics from the controller, add sender-side local graph speed read diagnostic, update fake_player to compute and send animationGraphSpeed, and append detailed dev-log entries describing the root cause, diagnostics, and fixes. Build and runtime diagnostics added to verify hook behavior and cadence changes.
60 lines
1.7 KiB
C++
60 lines
1.7 KiB
C++
#pragma once
|
|
|
|
#include "F4TRemotePlayerState.h"
|
|
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <string_view>
|
|
|
|
namespace RE
|
|
{
|
|
class Actor;
|
|
}
|
|
|
|
namespace F4T::ProxyAnimationSync
|
|
{
|
|
// Confirmed via local read-by-name graph debug (Fallout4Together.log):
|
|
// - float "Speed" reads/writes while in-game (walk ~47-105)
|
|
// - bool "IsSprinting" reads while in-game
|
|
// - bIsMoving, bIsSneaking, bSprint, bInJumpState, bWeaponDrawn, Direction: unavailable by name
|
|
namespace GraphVar
|
|
{
|
|
inline constexpr const char* kSpeed = "Speed";
|
|
inline constexpr const char* kSpeedLower = "speed";
|
|
inline constexpr const char* kSpeedSampled = "speedSampled";
|
|
inline constexpr const char* kSpeedDamped = "speedDamped";
|
|
inline constexpr const char* kIsSprinting = "IsSprinting";
|
|
}
|
|
|
|
// Maps network movementSpeed (units/sec) to graph Speed (~0-105). Used when the sender
|
|
// does not provide animationGraphSpeed.
|
|
float MapMovementSpeedToGraphSpeed(float a_movementSpeed, bool a_isSprinting);
|
|
|
|
struct ProxyAppliedAnimationState
|
|
{
|
|
bool hasAppliedGraphState{ false };
|
|
bool lastIsMoving{ false };
|
|
bool lastIsSprinting{ false };
|
|
bool lastIsSneaking{ false };
|
|
bool lastIsJumping{ false };
|
|
bool lastWeaponDrawn{ false };
|
|
float lastGraphSpeed{ 0.0F };
|
|
float lastDirection{ 0.0F };
|
|
std::chrono::steady_clock::time_point movingHoldUntil{};
|
|
};
|
|
|
|
void ResetAppliedAnimationState(ProxyAppliedAnimationState& a_state);
|
|
|
|
void ApplyProxyAnimationFromRemoteState(
|
|
ProxyAppliedAnimationState& a_state,
|
|
RE::Actor& a_proxy,
|
|
const RemotePlayerState::RemotePlayerState& a_remotePlayer);
|
|
|
|
void ClearProxyAnimationState(
|
|
ProxyAppliedAnimationState& a_state,
|
|
RE::Actor& a_proxy,
|
|
std::uint32_t a_remotePlayerId,
|
|
std::string_view a_reason);
|
|
}
|