153 lines
4.8 KiB
C#
153 lines
4.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using Vanguard.Board3D;
|
||
using Vanguard.Shared.Protocol;
|
||
|
||
namespace Vanguard.UI.Overlays
|
||
{
|
||
/// <summary>
|
||
/// Компактная панель игрока: Колода, Душа, Рука, Сброс.
|
||
/// Все блоки одинаковые; кликабельны только Душа и Сброс.
|
||
/// </summary>
|
||
public sealed class PlayerStatsPanelView
|
||
{
|
||
private sealed class StatEntry
|
||
{
|
||
public BoardZone Zone;
|
||
public Text Value;
|
||
}
|
||
|
||
private readonly List<StatEntry> _stats = new List<StatEntry>();
|
||
private RectTransform _root;
|
||
private Text _header;
|
||
|
||
public RectTransform Root => _root;
|
||
public event Action<BoardZone> ZoneClicked;
|
||
|
||
public void Build(
|
||
Transform parent,
|
||
string name,
|
||
bool self,
|
||
Vector2 anchor,
|
||
Vector2 pivot,
|
||
Vector2 position,
|
||
Vector2 size)
|
||
{
|
||
_root = UiKit.CreatePanel(
|
||
parent,
|
||
name,
|
||
new Color(0.02f, 0.035f, 0.055f, 0.9f));
|
||
_root.anchorMin = anchor;
|
||
_root.anchorMax = anchor;
|
||
_root.pivot = pivot;
|
||
_root.anchoredPosition = position;
|
||
_root.sizeDelta = size;
|
||
|
||
var image = _root.GetComponent<Image>();
|
||
if (image != null)
|
||
image.raycastTarget = false;
|
||
|
||
UiKit.AddVerticalLayout(_root, 8, 4);
|
||
|
||
_header = UiKit.CreateText(
|
||
_root,
|
||
"Header",
|
||
self ? "ВЫ" : "ПРОТИВНИК",
|
||
13,
|
||
new Color(0.86f, 0.91f, 1f),
|
||
TextAnchor.MiddleLeft);
|
||
_header.fontStyle = FontStyle.Bold;
|
||
UiKit.MakeLiteral(_header);
|
||
UiKit.SetPreferredHeight(_header, 20f);
|
||
|
||
var stats = UiKit.CreatePanel(_root, "Stats", Color.clear);
|
||
UiKit.AddHorizontalLayout(stats, 0, 4);
|
||
UiKit.SetPreferredHeight(stats, 42f);
|
||
|
||
AddStat(stats, BoardZone.Deck, "Колода");
|
||
AddStat(stats, BoardZone.Soul, "Душа", clickable: true);
|
||
AddStat(stats, BoardZone.Hand, "Рука");
|
||
AddStat(stats, BoardZone.Drop, "Сброс", clickable: true);
|
||
}
|
||
|
||
private void AddStat(
|
||
RectTransform parent,
|
||
BoardZone zone,
|
||
string label,
|
||
bool clickable = false)
|
||
{
|
||
var block = UiKit.CreatePanel(
|
||
parent,
|
||
"Stat_" + zone,
|
||
new Color(0.06f, 0.09f, 0.14f, 0.85f));
|
||
var image = block.GetComponent<Image>();
|
||
if (image != null)
|
||
image.raycastTarget = clickable;
|
||
|
||
UiKit.AddVerticalLayout(block, 2, 0);
|
||
UiKit.SetPreferredHeight(block, 40f);
|
||
|
||
var caption = UiKit.CreateText(
|
||
block,
|
||
"Caption",
|
||
label,
|
||
9,
|
||
new Color(0.62f, 0.70f, 0.86f));
|
||
UiKit.MakeLiteral(caption);
|
||
UiKit.SetPreferredHeight(caption, 12f);
|
||
|
||
var value = UiKit.CreateText(
|
||
block,
|
||
"Value",
|
||
"0",
|
||
15,
|
||
Color.white);
|
||
value.fontStyle = FontStyle.Bold;
|
||
UiKit.SetPreferredHeight(value, 18f);
|
||
|
||
if (clickable)
|
||
{
|
||
var button = block.gameObject.AddComponent<Button>();
|
||
button.targetGraphic = image;
|
||
button.onClick.AddListener(() => ZoneClicked?.Invoke(zone));
|
||
}
|
||
|
||
_stats.Add(new StatEntry { Zone = zone, Value = value });
|
||
}
|
||
|
||
public void Update(PlayerView player, bool self)
|
||
{
|
||
if (_root == null)
|
||
return;
|
||
|
||
_header.text = (self ? "ВЫ" : "ПРОТИВНИК")
|
||
+ (player != null && !string.IsNullOrEmpty(player.Name)
|
||
? " · " + player.Name
|
||
: string.Empty);
|
||
|
||
var hand = player != null
|
||
? Mathf.Max(player.HandCount, player.Hand?.Count ?? 0)
|
||
: 0;
|
||
|
||
Set(BoardZone.Deck, player?.DeckCount ?? 0);
|
||
Set(BoardZone.Soul, player?.Soul?.Count ?? 0);
|
||
Set(BoardZone.Hand, hand);
|
||
Set(BoardZone.Drop, player?.Drop?.Count ?? 0);
|
||
}
|
||
|
||
private void Set(BoardZone zone, int value)
|
||
{
|
||
foreach (var stat in _stats)
|
||
{
|
||
if (stat.Zone == zone && stat.Value != null)
|
||
{
|
||
stat.Value.text = value.ToString();
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|