refactor(camera): extract the update frame

Move fly/chase publication, combat target tracking, and local player projection behind typed runtime owners. Preserve the inbound-created projection/reconcile barrier while removing GameWindow callbacks and duplicate shadow helpers.
This commit is contained in:
Erik 2026-07-22 03:08:58 +02:00
parent eeb0f6b45c
commit 947c61d2d7
19 changed files with 988 additions and 356 deletions

View file

@ -0,0 +1,53 @@
using System.Numerics;
using AcDream.App.Interaction;
using AcDream.Core.Combat;
using AcDream.Core.Selection;
namespace AcDream.App.Combat;
internal interface ICombatCameraTargetSource
{
Vector3? GetTrackedTargetPoint();
}
/// <summary>
/// Resolves retail's combat-camera target from canonical combat, selection,
/// gameplay-option, and world-selection owners.
/// </summary>
/// <remarks>
/// <c>ClientCombatSystem::UpdateTargetTracking @ 0x0056A950</c> enables
/// <c>CameraSet::TrackTarget</c> only for melee/missile combat with the option
/// enabled and a valid attack target. TrackTarget applies target-local offset
/// (0, 0, 0.5).
/// </remarks>
internal sealed class CombatCameraTargetSource : ICombatCameraTargetSource
{
private readonly ICombatGameplaySettingsSource _settings;
private readonly CombatState _combat;
private readonly SelectionState _selection;
private readonly IWorldSelectionQuery _world;
public CombatCameraTargetSource(
ICombatGameplaySettingsSource settings,
CombatState combat,
SelectionState selection,
IWorldSelectionQuery world)
{
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
_combat = combat ?? throw new ArgumentNullException(nameof(combat));
_selection = selection ?? throw new ArgumentNullException(nameof(selection));
_world = world ?? throw new ArgumentNullException(nameof(world));
}
public Vector3? GetTrackedTargetPoint()
{
if (!_settings.ViewCombatTarget
|| !CombatInputPlanner.SupportsTargetedAttack(_combat.CurrentMode)
|| _selection.SelectedObjectId is not uint selected)
{
return null;
}
return _world.GetCombatCameraTargetPoint(selected);
}
}

View file

@ -15,6 +15,7 @@ internal interface ICombatGameplaySettingsSource
{
bool AutoTarget { get; }
bool AutoRepeatAttack { get; }
bool ViewCombatTarget { get; }
}
internal sealed class GameplaySettingsState : ICombatGameplaySettingsSource
@ -22,6 +23,7 @@ internal sealed class GameplaySettingsState : ICombatGameplaySettingsSource
public GameplaySettings Value { get; set; } = GameplaySettings.Default;
public bool AutoTarget => Value.AutoTarget;
public bool AutoRepeatAttack => Value.AutoRepeatAttack;
public bool ViewCombatTarget => Value.ViewCombatTarget;
}
internal interface ICombatFeedbackSink