144 lines
5.4 KiB
C#
144 lines
5.4 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 BattleActionPositionDecider : BattleActionDecider
|
|
{
|
|
private CameraStateMachine _cameraStateMachine;
|
|
private IInputService _inputService;
|
|
|
|
private Vector3 _targetPosition;
|
|
private LayerMask _navMeshMask;
|
|
|
|
private const float StoppingDistance = 0.15f;
|
|
|
|
public BattleActionPositionDecider(
|
|
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.Position;
|
|
|
|
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 PositionBattleActionDeciderResult()
|
|
{
|
|
ResultCode = _decisionResultCode,
|
|
Position = _targetPosition
|
|
};
|
|
}
|
|
|
|
public override void UnmountDecider()
|
|
{
|
|
if (!IsMounted) return;
|
|
|
|
_playerDecisionMarker.Toggle(false);
|
|
_markerManager.ReleaseMarkerInstance(_playerDecisionMarker);
|
|
_markerManager.ReleaseMarkerInstance(_playerLockedDecisionMarker);
|
|
|
|
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
|
|
SelectPosition);
|
|
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
|
|
ConfirmPosition);
|
|
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
|
|
CancelPosition);
|
|
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Watchment,
|
|
MarkPosition);
|
|
|
|
IsMounted = false;
|
|
}
|
|
|
|
public override void MountDecider()
|
|
{
|
|
if (IsMounted) return;
|
|
|
|
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
|
|
SelectPosition);
|
|
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
|
|
ConfirmPosition);
|
|
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
|
|
CancelPosition);
|
|
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Watchment,
|
|
MarkPosition);
|
|
|
|
_playerLockedDecisionMarker = _markerManager.GetMarkerInstance();
|
|
_playerDecisionMarker = _markerManager.GetMarkerInstance();
|
|
_playerDecisionMarker.Toggle(true);
|
|
|
|
IsMounted = true;
|
|
}
|
|
|
|
private MarkerManager _markerManager;
|
|
|
|
private void CancelPosition(InputAction.CallbackContext obj)
|
|
{
|
|
_decisionResultCode = BattleActionDecisionResultCode.CancelDecision;
|
|
_waitForEnterTokenSource?.Cancel();
|
|
}
|
|
|
|
private void ConfirmPosition(InputAction.CallbackContext input)
|
|
{
|
|
_decisionResultCode = BattleActionDecisionResultCode.Decided;
|
|
|
|
_waitForEnterTokenSource?.Cancel();
|
|
}
|
|
|
|
private RaycastHit[] _hitBuffer = new RaycastHit[1];
|
|
private Vector3 _lastViewedPosition;
|
|
private PlayerDecisionMarker _playerDecisionMarker;
|
|
private PlayerDecisionMarker _playerLockedDecisionMarker;
|
|
|
|
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) return;
|
|
|
|
var hit = _hitBuffer[0];
|
|
|
|
_playerDecisionMarker.MoveMarker(hit.point);
|
|
|
|
_lastViewedPosition = hit.point;
|
|
}
|
|
|
|
private void SelectPosition(InputAction.CallbackContext input)
|
|
{
|
|
_targetPosition = _lastViewedPosition;
|
|
|
|
_playerLockedDecisionMarker.MoveMarker(_targetPosition);
|
|
_playerLockedDecisionMarker.Toggle(true);
|
|
|
|
_waitForEnterTokenSource?.Cancel();
|
|
}
|
|
}
|
|
} |