using System.Numerics; using AcDream.App.Interaction; using AcDream.Core.Combat; using AcDream.Core.Selection; namespace AcDream.App.Combat; internal interface ICombatCameraTargetSource { Vector3? GetTrackedTargetPoint(); } /// /// Resolves retail's combat-camera target from canonical combat, selection, /// gameplay-option, and world-selection owners. /// /// /// ClientCombatSystem::UpdateTargetTracking @ 0x0056A950 enables /// CameraSet::TrackTarget only for melee/missile combat with the option /// enabled and a valid attack target. TrackTarget applies target-local offset /// (0, 0, 0.5). /// 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); } }