VanguardReMaster/client/Assets/Vanguard/Runtime/UI/Overlays/ZoneBlockStripView.cs

184 lines
6.0 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 ZoneBlockStripView
{
private static readonly BoardZone[] Zones =
{
BoardZone.Hand,
BoardZone.Deck,
BoardZone.Drop,
BoardZone.Soul,
BoardZone.Damage,
BoardZone.Guardian,
BoardZone.Trigger,
};
private readonly Dictionary<BoardZone, Text> _labels =
new Dictionary<BoardZone, Text>();
private Text _header;
public RectTransform Root { get; private set; }
public event Action<BoardZone> ZoneClicked;
public void Build(
Transform parent,
string name,
Vector2 anchor,
Vector2 pivot,
Vector2 position,
Vector2 size)
{
var prefabRoot = OverlayPrefabs.Instantiate("ZoneBlockStrip", parent);
if (prefabRoot != null)
{
Root = prefabRoot;
Root.name = name;
ApplyLayout(anchor, pivot, position, size);
WireButtons();
return;
}
Root = UiKit.CreatePanel(parent, name, new Color(0.02f, 0.035f, 0.055f, 0.82f));
ApplyLayout(anchor, pivot, position, size);
UiKit.AddVerticalLayout(Root, 8, 4);
_header = UiKit.CreateText(
Root,
"Header",
string.Empty,
14,
new Color(0.86f, 0.91f, 1f),
TextAnchor.MiddleLeft);
_header.fontStyle = FontStyle.Bold;
UiKit.MakeLiteral(_header);
UiKit.SetPreferredHeight(_header, 20f);
CreateRow("Row1");
CreateRow("Row2");
CreateZoneButtons();
WireButtons();
}
private void CreateZoneButtons()
{
for (var i = 0; i < Zones.Length; i++)
{
var zone = Zones[i];
var row = Root.Find(i < 4 ? "Row1" : "Row2");
UiKit.CreateButton(
row,
"Zone_" + zone,
string.Empty,
null,
13);
}
}
private void ApplyLayout(
Vector2 anchor,
Vector2 pivot,
Vector2 position,
Vector2 size)
{
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;
}
private void WireButtons()
{
_header = Root.Find("Header")?.GetComponent<Text>();
if (_header != null)
{
_header.fontStyle = FontStyle.Bold;
UiKit.MakeLiteral(_header);
}
for (var i = 0; i < Zones.Length; i++)
{
var zone = Zones[i];
var row = i < 4 ? "Row1" : "Row2";
var button = Root.Find(row + "/Zone_" + zone)?.GetComponent<Button>();
if (button == null)
continue;
var element = button.GetComponent<LayoutElement>();
if (element == null)
element = button.gameObject.AddComponent<LayoutElement>();
element.preferredHeight = 32f;
element.preferredWidth = i < 4 ? 80f : 108f;
_labels[zone] = button.GetComponentInChildren<Text>();
if (_labels[zone] != null)
UiKit.MakeLiteral(_labels[zone]);
button.onClick.AddListener(() => ZoneClicked?.Invoke(zone));
}
}
public void Update(PlayerView player, bool self)
{
if (Root == null)
return;
_header.text = Loc.Translate(self ? "ВЫ" : "ПРОТИВНИК")
+ (player != null && !string.IsNullOrEmpty(player.Name)
? " · " + player.Name
: string.Empty);
var hand = player != null
? Mathf.Max(player.HandCount, player.Hand?.Count ?? 0)
: 0;
var deck = player?.DeckCount ?? 0;
var drop = player?.Drop?.Count ?? 0;
var soul = player?.Soul?.Count ?? 0;
var damage = player != null
? player.FaceDownDamage + (player.FaceUpDamage?.Count ?? 0)
: 0;
var guardian = player?.Guardian?.Count ?? 0;
var trigger = player?.Trigger?.Count ?? 0;
Set(BoardZone.Hand, "Рука", hand);
Set(BoardZone.Deck, "Колода", deck);
Set(BoardZone.Drop, "Дроп", drop);
Set(BoardZone.Soul, "Душа", soul);
Set(BoardZone.Damage, "Урон", damage);
Set(BoardZone.Guardian, "Защита", guardian);
Set(BoardZone.Trigger, "Триг.", trigger);
}
private RectTransform CreateRow(string name)
{
var row = UiKit.CreatePanel(Root, name, Color.clear);
var element = row.gameObject.AddComponent<LayoutElement>();
element.preferredHeight = 32f;
UiKit.AddHorizontalLayout(row, 0, 4);
return row;
}
private void Set(BoardZone zone, string label, int count)
{
if (_labels.TryGetValue(zone, out var text) && text != null)
text.text = Loc.Translate(label) + " " + count;
}
}
}