115 lines
4.2 KiB
C#
115 lines
4.2 KiB
C#
using System.Collections.Generic;
|
|
using Sirenix.OdinInspector;
|
|
using Sirenix.Utilities;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
using VOID.Generic.Objects.Abstract.Events;
|
|
using VOID.Generic.Objects.Unit;
|
|
using VOID.UserInterface.Game.Util;
|
|
using VOID.ScriptableObjects;
|
|
|
|
namespace VOID.UserInterface.Game.Party
|
|
{
|
|
/// <summary>
|
|
/// Manages all visual elements for one <see cref="UnitObject"/> in <see cref="PartyUI"/>, including: portrait and statuses
|
|
/// </summary>
|
|
public class PartyUnitUI : MonoBehaviour
|
|
{
|
|
[ShowInInspector, ReadOnly] public UnitObject unit { get; private set; }
|
|
|
|
// Visual Elements
|
|
private VisualElement _templateElement;
|
|
private VisualElement _statusRow;
|
|
private UnitPortraitUI _unitPortraitUI;
|
|
private Dictionary<BasicStatus, StatusUI> _statuses = new();
|
|
|
|
/// <summary>
|
|
/// Initializes whole <see cref="PartyUnitUI"/>, should be executed from <see cref="PartyUI"/>.
|
|
/// </summary>
|
|
/// <param name="partyUnitTemplate">visual element which already exists and will be used.</param>
|
|
public void Init(VisualElement partyUnitTemplate)
|
|
{
|
|
// Find all important elements
|
|
_templateElement = partyUnitTemplate;
|
|
_statusRow = _templateElement.Q("status-row");
|
|
_unitPortraitUI = new UnitPortraitUI();
|
|
_unitPortraitUI.Init(_templateElement.Q("unit-portrait"));
|
|
_templateElement.style.display = DisplayStyle.None;
|
|
|
|
// Clear all placeholder statuses
|
|
_statusRow.Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Given <see cref="UnitObject"/> will be used in this visual element.
|
|
/// Which means its portrait, statuses and health will be displayed.
|
|
/// </summary>
|
|
public void SetUnit(UnitObject unit)
|
|
{
|
|
// Remove everything about previous Unit
|
|
UnsetUnit();
|
|
|
|
// New Unit assigned - start listeners and wait
|
|
this.unit = unit;
|
|
this.unit.basicEvents.onStatusStart.AddListener(OnUnitStatusStart);
|
|
this.unit.basicEvents.onStatusEnd.AddListener(OnUnitStatusEnd);
|
|
|
|
// Make UI visible and set Unit's portrait
|
|
_templateElement.style.display = DisplayStyle.Flex;
|
|
|
|
// For all statuses that already exists we need to initialize them manually
|
|
this.unit.statusManager.GetStatuses().ForEach(status => OnUnitStatusStart(new StatusEvent { obj = unit, status = status }));
|
|
|
|
_unitPortraitUI.SetUnit(unit);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears and hides this element.
|
|
/// </summary>
|
|
public void UnsetUnit()
|
|
{
|
|
// There is no unit currently
|
|
if (!unit) return;
|
|
|
|
// Remove all listeners, then remove assigned Unit
|
|
unit.basicEvents.onStatusStart.RemoveListener(OnUnitStatusStart);
|
|
unit.basicEvents.onStatusEnd.RemoveListener(OnUnitStatusEnd);
|
|
unit = null;
|
|
|
|
// Make UI invisible and unset portrait
|
|
_templateElement.style.display = DisplayStyle.None;
|
|
|
|
// Remove mapping
|
|
_statuses = null;
|
|
|
|
// Clear all statuses
|
|
_statusRow.Clear();
|
|
|
|
_unitPortraitUI.UnsetUnit();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds class "active" which usually will be used, by portret of player's currently active <see cref="UnitObject"/>
|
|
/// </summary>
|
|
public void SetActive(bool active = true)
|
|
{
|
|
_templateElement.EnableInClassList("active", active);
|
|
}
|
|
|
|
private void OnUnitStatusStart(StatusEvent statusEvent)
|
|
{
|
|
if (statusEvent.status.hidden) return;
|
|
var statusUI = new StatusUI();
|
|
statusUI.InitNew(_statusRow, statusEvent.status);
|
|
_statuses.Add(statusEvent.status, statusUI);
|
|
}
|
|
|
|
private void OnUnitStatusEnd(StatusEvent statusEvent)
|
|
{
|
|
if (statusEvent.status.hidden) return;
|
|
_statuses.GetValueOrDefault(statusEvent.status)?.Destroy();
|
|
_statuses.Remove(statusEvent.status);
|
|
}
|
|
}
|
|
}
|