258 lines
9.4 KiB
C#
258 lines
9.4 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
using VOID.Generic.Dict;
|
|
using VOID.Generic.Objects.Abstract.Events;
|
|
using VOID.Generic.Objects.Unit;
|
|
using VOID.Generic.Objects.Unit.Actions;
|
|
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
|
using VOID.Generic.Objects.Unit.Events;
|
|
using VOID.Generic.Player;
|
|
using VOID.Generic.Turn;
|
|
|
|
namespace VOID.UserInterface.Game
|
|
{
|
|
/// <summary>
|
|
/// Manages ActionBar's Turn elements for current player only:<br/>
|
|
/// - Turn resources of <see cref="UnitObject"/><br/>
|
|
/// - Button to start new <see cref="TurnManager"/><br/>
|
|
/// - Buttons to <see cref="LeaveTurnAction"/> and <see cref="EndTurnAction"/> when in combat
|
|
/// </summary>
|
|
public class ActionBarTurnInfoUI : MonoBehaviour
|
|
{
|
|
public static ActionBarTurnInfoUI current { get; private set; }
|
|
|
|
// ActionBar for this unit
|
|
private UnitObject _unit;
|
|
private UnitObjectActionBar _actionBar;
|
|
|
|
// Visual Elements - Turn Info
|
|
private VisualElement _turnInfoElement;
|
|
private VisualElement _actionPointsElement;
|
|
private readonly List<VisualElement> _actionPointsElements = new();
|
|
private ProgressBar _moveBar;
|
|
private Button _nextTurnButton;
|
|
private Button _startTurnButton;
|
|
private Button _endTurnButton;
|
|
|
|
// References
|
|
private PlayerController _playerController;
|
|
|
|
private void Awake()
|
|
{
|
|
current = this;
|
|
|
|
var uiDocument = gameObject.GetComponent<UIDocument>();
|
|
var templateElement = uiDocument.rootVisualElement;
|
|
|
|
// Find all important elements
|
|
_turnInfoElement = templateElement.Q("turn-info");
|
|
_actionPointsElement = templateElement.Q("action-points");
|
|
_moveBar = templateElement.Q<ProgressBar>("move-bar");
|
|
_nextTurnButton = templateElement.Q<Button>("next-turn");
|
|
_startTurnButton = templateElement.Q<Button>("start-turn");
|
|
_endTurnButton = templateElement.Q<Button>("end-turn");
|
|
|
|
// Remove placeholders from action points
|
|
_actionPointsElement.Clear();
|
|
|
|
_turnInfoElement.dataSource = this;
|
|
_turnInfoElement.pickingMode = PickingMode.Position;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_playerController = PlayerController.current;
|
|
_playerController.OnActiveUnitChange += OnActiveUnitChange;
|
|
_nextTurnButton.clicked += NextTurn;
|
|
_startTurnButton.clicked += StartTurn;
|
|
_endTurnButton.clicked += EndTurn;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Player order active unit to end its turn.
|
|
/// </summary>
|
|
private void NextTurn()
|
|
{
|
|
if (!_unit) return;
|
|
|
|
_unit.OrderStop();
|
|
_unit.Order(new EndTurnAction(_unit));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts new turn manager - also nearby units will also join
|
|
/// </summary>
|
|
private void StartTurn()
|
|
{
|
|
if (!_unit) return;
|
|
if (_unit.basicState.turnManager) return;
|
|
TurnManager.BuildGameObject(_unit);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Player order active unit to try end turn.<br/>
|
|
/// - If combat is FORCED then try to escape (if possible)
|
|
/// - If combat is NOT FORCED then end whole turn manager
|
|
/// </summary>
|
|
private void EndTurn()
|
|
{
|
|
if (!_unit) return;
|
|
if (!_unit.basicState.turnManager) return;
|
|
|
|
// if fight is forced when try leave with current unit
|
|
// else end whole turn combat
|
|
if (_unit.basicState.turnManager.isForcedFight)
|
|
_unit.OrderInstantly(new LeaveTurnAction(_unit));
|
|
else
|
|
_unit.basicState.turnManager.EndTurnManager();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Depending on unit turn state it hide or show player's buttons for turn.
|
|
/// </summary>
|
|
private void UpdateTurnButtonsVisibility()
|
|
{
|
|
if (_unit.basicState.turnManager)
|
|
{
|
|
_nextTurnButton.style.display = DisplayStyle.Flex;
|
|
_endTurnButton.style.display = DisplayStyle.Flex;
|
|
_startTurnButton.style.display = DisplayStyle.None;
|
|
}
|
|
else
|
|
{
|
|
_nextTurnButton.style.display = DisplayStyle.None;
|
|
_endTurnButton.style.display = DisplayStyle.None;
|
|
_startTurnButton.style.display = DisplayStyle.Flex;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 1. Stops listening to changes for previous unit
|
|
/// 2. Start listening to changes in new active unit
|
|
/// 3. Updates whole UI
|
|
/// </summary>
|
|
private void OnActiveUnitChange(UnitObject unit)
|
|
{
|
|
if (_unit)
|
|
{
|
|
_unit.basicEvents.onTurnQueueEnter.RemoveListener(OnTurnEnter);
|
|
_unit.basicEvents.onTurnQueueLeave.RemoveListener(OnTurnLeave);
|
|
_unit.basicEvents.onTurnSelfStart.RemoveListener(OnTurnSelfStart);
|
|
_unit.basicEvents.onTurnSelfEnd.RemoveListener(OnTurnSelfEnd);
|
|
_unit.unitEvents.onCurrentResourceChange.RemoveListener(OnResourceChange);
|
|
_unit.unitEvents.onMaxResourceChange.RemoveListener(OnResourceChange);
|
|
}
|
|
|
|
_unit = unit;
|
|
UpdateActionPoints();
|
|
UpdateMovePoints();
|
|
UpdateTurnButtonsVisibility();
|
|
UpdateWaitingForTurn();
|
|
|
|
_unit.basicEvents.onTurnQueueEnter.AddListener(OnTurnEnter);
|
|
_unit.basicEvents.onTurnQueueLeave.AddListener(OnTurnLeave);
|
|
_unit.basicEvents.onTurnSelfStart.AddListener(OnTurnSelfStart);
|
|
_unit.basicEvents.onTurnSelfEnd.AddListener(OnTurnSelfEnd);
|
|
_unit.unitEvents.onCurrentResourceChange.AddListener(OnResourceChange);
|
|
_unit.unitEvents.onMaxResourceChange.AddListener(OnResourceChange);
|
|
}
|
|
|
|
private void OnTurnEnter(TurnEvent turnEvent)
|
|
{
|
|
UpdateTurnButtonsVisibility();
|
|
UpdateWaitingForTurn();
|
|
}
|
|
|
|
private void OnTurnLeave(TurnEvent turnEvent)
|
|
{
|
|
UpdateTurnButtonsVisibility();
|
|
UpdateWaitingForTurn();
|
|
}
|
|
|
|
private void OnTurnSelfStart(TurnEvent turnEvent)
|
|
{
|
|
UpdateWaitingForTurn();
|
|
}
|
|
|
|
private void OnTurnSelfEnd(TurnEvent turnEvent)
|
|
{
|
|
UpdateWaitingForTurn();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Makes ActionBar's turn elements inactive if currently active unit is waiting for its turn.
|
|
/// </summary>
|
|
private void UpdateWaitingForTurn()
|
|
{
|
|
var isWaiting = _unit.basicState.turnManager && _unit.basicState.turnManager.currentUnitTurn != _unit;
|
|
_turnInfoElement.EnableInClassList("inactive", isWaiting);
|
|
}
|
|
|
|
private void OnResourceChange(UnitResourceChangeEvent resourceChangeEvent)
|
|
{
|
|
switch (resourceChangeEvent.type)
|
|
{
|
|
case UnitResourceType.ActionPoints:
|
|
UpdateActionPoints();
|
|
break;
|
|
case UnitResourceType.MovePoints:
|
|
UpdateMovePoints();
|
|
break;
|
|
default: return;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates current and max action points to correspond these from UnitData.
|
|
/// </summary>
|
|
private void UpdateActionPoints()
|
|
{
|
|
var maxActionPoints = (int)_unit.unitData.maxResources.actionPoints;
|
|
var currentActionPoints = (int)_unit.unitData.currentResources.actionPoints;
|
|
|
|
// Add/Remove visual elements if needed
|
|
for (var i = 0; i < maxActionPoints - _actionPointsElements.Count;) AddActionPointElement();
|
|
for (var i = 0; i < _actionPointsElements.Count - maxActionPoints;) RemoveActionPointElement();
|
|
|
|
// Activate/Disable action points
|
|
for (var i = 0; i < _actionPointsElements.Count; i++)
|
|
{
|
|
var actionPointElement = _actionPointsElements[i];
|
|
actionPointElement.EnableInClassList("active-action-point", i < currentActionPoints);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds new action point element to UI.
|
|
/// </summary>
|
|
private void AddActionPointElement()
|
|
{
|
|
var actionPointElement = new VisualElement();
|
|
actionPointElement.AddToClassList("action-point");
|
|
_actionPointsElement.Add(actionPointElement);
|
|
_actionPointsElements.Add(actionPointElement);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes one action point element from UI.
|
|
/// </summary>
|
|
private void RemoveActionPointElement()
|
|
{
|
|
_actionPointsElement.Remove(_actionPointsElements.Last());
|
|
_actionPointsElements.Remove(_actionPointsElements.Last());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates current and max move points to correspond these from UnitData.
|
|
/// </summary>
|
|
private void UpdateMovePoints()
|
|
{
|
|
_moveBar.highValue = _unit.unitData.maxResources.movePoints;
|
|
_moveBar.value = _unit.unitData.currentResources.movePoints;
|
|
_moveBar.title = $"{_moveBar.value:F1} / {_moveBar.highValue:F1}";
|
|
}
|
|
}
|
|
}
|