223 lines
7.5 KiB
C#
223 lines
7.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using VOID.Generic.Objects.Item;
|
|
using VOID.Generic.Player.DraggingOperation;
|
|
using VOID.Generic.Player.Input;
|
|
using VOID.Generic.Player.Util;
|
|
using VOID.UserInterface;
|
|
using VOID.UserInterface.Game;
|
|
using VOID.Generic.Util;
|
|
using VOID.ScriptableObjects.Abilities;
|
|
|
|
namespace VOID.Generic.Player
|
|
{
|
|
[DefaultExecutionOrder(-1)]
|
|
public class DraggingManager : MonoBehaviour
|
|
{
|
|
public static DraggingManager current {get; private set;}
|
|
|
|
// References
|
|
private PlayerController _playerController;
|
|
private PlayerInputManager _playerInputManager;
|
|
private GameUI _gameUI;
|
|
private DraggingUI _draggingUI;
|
|
|
|
// Configuration
|
|
[SerializeField] private float startDraggingAfter = 0.2f;
|
|
|
|
// Private properties
|
|
private List<AbstractDraggingOperation> _draggingOperations;
|
|
private SelectUtilResult _sourceSelect;
|
|
private SelectUtilResult _targetSelect;
|
|
private bool _isDragging;
|
|
private bool _isPreparing;
|
|
|
|
// Submodule that visualize player's dragging
|
|
private DraggingVisualizer _draggingVisualizer;
|
|
|
|
// Transform from those GameObjects used as start and end for trajectory
|
|
private GameObject _draggingFrom;
|
|
private GameObject _draggingTo;
|
|
|
|
private void Awake()
|
|
{
|
|
current = this;
|
|
var thisTransform = transform;
|
|
_draggingFrom = new GameObject("Dragging From");
|
|
_draggingFrom.transform.parent = thisTransform;
|
|
_draggingTo = new GameObject("Dragging To");
|
|
_draggingTo.transform.parent = thisTransform;
|
|
|
|
_draggingOperations = AppDomain.CurrentDomain.GetAssemblies()
|
|
.SelectMany(assembly => assembly.GetTypes())
|
|
.Where(type => type.IsSubclassOf(typeof(AbstractDraggingOperation)) && type.IsClass)
|
|
.Select(Activator.CreateInstance)
|
|
.Cast<AbstractDraggingOperation>()
|
|
.ToList();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_playerInputManager = PlayerInputManager.current;
|
|
_playerInputManager.OnDraggingPrepare += PrepareDragging;
|
|
_playerInputManager.OnDraggingStart += StartDragging;
|
|
_playerInputManager.OnDraggingEnd += EndDragging;
|
|
_playerController = PlayerController.current;
|
|
_gameUI = GameUI.current;
|
|
_draggingUI = DraggingUI.current;
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
Dragging();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks that the operation can be performed and prepares the data for use
|
|
/// </summary>
|
|
private void PrepareDragging()
|
|
{
|
|
if (_isPreparing || _isDragging) Clean();
|
|
var sourceSelect = SelectUtil.Select();
|
|
|
|
// Dragging only when ability or item selected (and can be dragged)
|
|
if (!sourceSelect.selectObject && !sourceSelect.selectAbility) return;
|
|
if (sourceSelect.selectObject is not null and not ItemObject) return;
|
|
var selectItem = (ItemObject)sourceSelect.selectObject;
|
|
if (selectItem && !selectItem.itemData.canBeMoved) return;
|
|
|
|
_draggingFrom.transform.position = sourceSelect.position;
|
|
_draggingTo.transform.position = sourceSelect.position;
|
|
_sourceSelect = sourceSelect;
|
|
|
|
_isPreparing = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initiate draging visualisation
|
|
/// Requied: PrepapreDragging to be done before
|
|
/// </summary>
|
|
private void StartDragging()
|
|
{
|
|
if(!_isPreparing) return;
|
|
_isDragging = true;
|
|
|
|
if(_sourceSelect.selectObject is ItemObject) StartDraggingItem((ItemObject)_sourceSelect.selectObject);
|
|
else if(_sourceSelect.selectAbility) StartDraggingAbility(_sourceSelect.selectAbility);
|
|
}
|
|
|
|
private void StartDraggingItem(ItemObject item)
|
|
{
|
|
// Prepare for Scene dragging
|
|
_draggingVisualizer = DraggingVisualizer.Create(_draggingFrom.transform, _draggingTo.transform, item);
|
|
|
|
// Prepare for UI dragging
|
|
_draggingUI.Set(item);
|
|
}
|
|
|
|
private void StartDraggingAbility(BasicAbility ability)
|
|
{
|
|
_draggingUI.Set(ability);
|
|
_draggingUI.Show();
|
|
}
|
|
|
|
private void Dragging()
|
|
{
|
|
if (!_isDragging) return;
|
|
if (_sourceSelect.selectObject && !_gameUI.isCursorOverUI) DraggingItemOnScene();
|
|
else if (_sourceSelect.selectObject && _gameUI.isCursorOverUI) DraggingItemOnUI();
|
|
else if (_sourceSelect.selectAbility) DraggingAbility();
|
|
}
|
|
|
|
private void DraggingItemOnScene()
|
|
{
|
|
_draggingUI.Hide();
|
|
var hit = SelectUtil.SelectHit();
|
|
_draggingTo.transform.position = hit.point;
|
|
|
|
// Dragging only onto STATIC objects (like floor)
|
|
if (hit.collider.gameObject.layer is not LayerManager.StaticIndex)
|
|
{
|
|
_draggingVisualizer.Hide();
|
|
return;
|
|
}
|
|
|
|
var isInRange = RangeUtil.IsInRange(
|
|
_draggingFrom.transform.position,
|
|
_draggingTo.transform.position,
|
|
_playerController.activeUnit.unitData.takeRange*2,
|
|
false
|
|
);
|
|
|
|
// Dragging only when in player's unit range (2 * take range)
|
|
if (!isInRange)
|
|
{
|
|
_draggingVisualizer.Hide();
|
|
return;
|
|
}
|
|
|
|
_draggingVisualizer.Show();
|
|
}
|
|
|
|
private void DraggingItemOnUI()
|
|
{
|
|
_draggingUI.Show();
|
|
_draggingVisualizer.Hide();
|
|
}
|
|
|
|
private void DraggingAbility()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// This function completes the transfer process. It contains the main logic responsible for moving an object from one place to another
|
|
/// Required: StartDragging to be done before
|
|
/// </summary>
|
|
private void EndDragging()
|
|
{
|
|
if (!_isDragging)
|
|
{
|
|
Clean();
|
|
return;
|
|
}
|
|
|
|
_targetSelect = SelectUtil.Select();
|
|
|
|
if (_gameUI.isCursorOverUI && _targetSelect.slotUI?.slotType == null)
|
|
{
|
|
Debug.LogWarning("Dragged into invalid place over UI");
|
|
Clean();
|
|
return;
|
|
}
|
|
|
|
var operation = _draggingOperations.FirstOrDefault(op => op.Check(_sourceSelect, _targetSelect));
|
|
if (operation != null)
|
|
{
|
|
operation.Perform(_playerController.activeUnit, _sourceSelect, _targetSelect);
|
|
Clean();
|
|
return;
|
|
}
|
|
|
|
Debug.LogWarning("Dragging between unsupported places: " +
|
|
$"'{_sourceSelect.slotUI?.slotType}' -> '{_targetSelect.slotUI?.slotType}'");
|
|
Clean();
|
|
}
|
|
|
|
private void Clean()
|
|
{
|
|
if (_draggingVisualizer)
|
|
{
|
|
Destroy(_draggingVisualizer.gameObject);
|
|
_draggingVisualizer = null;
|
|
}
|
|
_isDragging = false;
|
|
_isPreparing = false;
|
|
_sourceSelect = null;
|
|
_targetSelect = null;
|
|
_draggingUI.Hide();
|
|
}
|
|
}
|
|
} |