Files
Hasebe/Assets/Code/OfficeGame/BattleMode/Actions/Deciders/RotationBattleActionDecider.cs
T
2026-11-10 00:28:25 +03:00

156 lines
6.0 KiB
C#

using System;
using System.Threading;
using Code.Infrastructure.Camera;
using Code.Infrastructure.Input;
using Code.OfficeGame.BattleMode.Actions.Player;
using Code.OfficeGame.BattleMode.Marker;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.InputSystem;
namespace Code.OfficeGame.BattleMode.Actions.Deciders
{
public class RotationBattleActionDecider: BattleActionDecider
{
private CameraStateMachine _cameraStateMachine;
private IInputService _inputService;
private Quaternion _targetRotation;
private LayerMask _navMeshMask;
public RotationBattleActionDecider(
CameraStateMachine cameraStateMachine,
IInputService inputService,
MarkerManager markerManager)
{
_markerManager = markerManager;
_cameraStateMachine = cameraStateMachine;
_inputService = inputService;
_navMeshMask = LayerMask.GetMask("Environment");
}
private CancellationTokenSource _waitForEnterTokenSource;
private BattleActionDecisionResultCode _decisionResultCode;
public override DeciderType DeciderType => DeciderType.Rotation;
public override async UniTask<BattleActionDecisionResult> GetDecision()
{
if (!IsMounted) throw new Exception("Decider is not mounted"); // А почему бы и нет?
_waitForEnterTokenSource = new CancellationTokenSource();
_decisionResultCode = BattleActionDecisionResultCode.Deciding;
await UniTask.WaitUntilCanceled(_waitForEnterTokenSource.Token).SuppressCancellationThrow();
_waitForEnterTokenSource.Dispose();
_waitForEnterTokenSource = null;
return new RotationBattleActionDeciderResult()
{
ResultCode = _decisionResultCode,
Rotation = _targetRotation
};
}
public override void UnmountDecider()
{
if (!IsMounted) return;
_playerDecisionMarker.Toggle(false);
_markerManager.ReleaseMarkerInstance(_playerDecisionMarker);
_playerLockedDecisionMarker.Toggle(false);
_markerManager.ReleaseMarkerInstance(_playerLockedDecisionMarker);
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
SelectRotation);
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
ConfirmRotation);
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
CancelRotation);
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Watchment,
MarkPosition);
IsMounted = false;
}
public override void MountDecider(EntityProperties entityProperties)
{
if (IsMounted) return;
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
SelectRotation);
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
ConfirmRotation);
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
CancelRotation);
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Watchment,
MarkPosition);
_playerLockedDecisionMarker = _markerManager.GetMarkerInstance();
_playerDecisionMarker = _markerManager.GetMarkerInstance();
_playerDecisionMarker.Toggle(true);
_targetRotation = entityProperties.KinematicCharacterMotor.TransientRotation;
_entityPosition = entityProperties.KinematicCharacterMotor.TransientPosition;
IsMounted = true;
}
private MarkerManager _markerManager;
private void CancelRotation(InputAction.CallbackContext obj)
{
_decisionResultCode = BattleActionDecisionResultCode.CancelDecision;
_waitForEnterTokenSource?.Cancel();
}
private void ConfirmRotation(InputAction.CallbackContext input)
{
_decisionResultCode = BattleActionDecisionResultCode.Decided;
_waitForEnterTokenSource?.Cancel();
}
private RaycastHit[] _hitBuffer = new RaycastHit[1];
private PlayerDecisionMarker _playerDecisionMarker;
private PlayerDecisionMarker _playerLockedDecisionMarker;
private Vector3 _entityPosition;
private void MarkPosition(InputAction.CallbackContext input)
{
var position = _cameraStateMachine.Camera.transform.position;
var direction = _cameraStateMachine.Camera.transform.forward;
var hitCount = Physics.RaycastNonAlloc(
position,
direction,
_hitBuffer,
Mathf.Infinity,
_navMeshMask);
if (hitCount == 0
|| _entityPosition == Vector3.zero) return;
var hit = _hitBuffer[0];
var lookDirection = hit.point - _entityPosition;
_targetRotation = Quaternion.LookRotation(lookDirection.normalized, Vector3.up);
_playerDecisionMarker.transform.rotation = _targetRotation;
_playerDecisionMarker.transform.position = hit.point;
}
private void SelectRotation(InputAction.CallbackContext input)
{
_playerLockedDecisionMarker.MoveMarker(_entityPosition);
_playerLockedDecisionMarker.transform.rotation = _targetRotation;
_playerLockedDecisionMarker.Toggle(true);
_waitForEnterTokenSource?.Cancel();
}
}
}