using System.Collections.Generic; using UnityEngine; using Vanguard.App; using Vanguard.Shared.Protocol; using Vanguard.UI; namespace Vanguard.Board3D { /// /// Демо-сцена 3D-поля: раскладывает карты без сервера, чтобы проверять /// геометрию, drag&drop, rest, закрытые карты и общий круг защиты. /// public sealed class PlaymatSandbox : MonoBehaviour { public PlaymatLayoutConfig config; public bool showHints = true; private GameBoard3D _board; private int _clicks; private void Start() { SceneEnvironment.Build(SceneTheme.Battle); _board = GameBoard3D.Create(null, config != null ? config : PlaymatLayoutConfig.Default); _board.ArtProvider = SandboxArt; _board.SetVisible(true); _board.CardClicked += OnCardClicked; _board.SlotClicked += OnSlotClicked; _board.CardDropped += OnCardDropped; _board.PileClicked += OnPileClicked; _board.Render(BuildDemo(), BuildState()); } private void OnCardClicked(BoardCardRef card) { _clicks++; Debug.Log("SANDBOX card " + card); } private void OnSlotClicked(BoardCardRef slot) { Debug.Log("SANDBOX slot " + slot); } private void OnCardDropped(BoardCardRef source, BoardCardRef target) { Debug.Log("SANDBOX drop " + source + " -> " + target); // В песочнице нет сервера: возвращаем карту на место. _board.Render(BuildDemo(), BuildState()); } private void OnPileClicked(BoardCardRef pile) { Debug.Log("SANDBOX pile " + pile + " count=" + pile.Index); } private static BoardArt SandboxArt(string printingId) { var texture = LoadSandboxTexture(printingId); if (texture != null) return new BoardArt(texture, Color.white, printingId); var clan = printingId != null && printingId.Contains("002") ? "Kagero" : "RoyalPaladin"; var sprite = CardArt.ForCard(printingId ?? "sandbox", clan); return new BoardArt( sprite != null ? sprite.texture : null, CardArt.ClanColor(clan), printingId); } private static Texture2D LoadSandboxTexture(string printingId) { if (string.IsNullOrEmpty(printingId)) return null; var slash = printingId.IndexOf('/'); if (slash <= 0 || slash >= printingId.Length - 1) return null; var set = printingId.Substring(0, slash).ToLowerInvariant(); var tail = printingId.Substring(slash + 1); var number = string.Empty; for (var i = 0; i < tail.Length; i++) { var c = tail[i]; if (char.IsDigit(c) || (i == 0 && (c == 'S' || c == 's'))) { number += char.ToLowerInvariant(c); continue; } break; } if (number.Length == 0) return null; return Resources.Load("CardArt/" + set + "_" + number); } private static BoardRenderState BuildState() { var state = new BoardRenderState(); state.Highlights.Add(new BoardSlotKey(0, -1)); state.Highlights.Add(new BoardSlotKey(1, -1)); state.SelectedHandInstanceIds.Add(12); state.DropTargets.Add(new BoardSlotKey(0, -1)); for (var slot = 0; slot < PlaymatLayout.RearGuardCount; slot++) state.DropTargets.Add(new BoardSlotKey(0, slot)); state.GuardianDropAllowed = true; return state; } private static MatchView BuildDemo() { CardView Card(string id, int instance, bool rested = false, bool faceUp = true) => new CardView { PrintingId = id, InstanceId = instance, Rested = rested, FaceUp = faceUp, BasePower = 8000, Power = rested ? 5000 : 8000, BaseCritical = 1, Critical = 1, }; var self = new PlayerView { Index = 0, Name = "Sandbox", Vanguard = Card("BT01/001EN", 1), RearGuards = new CardView[5], Hand = new List { Card("BT01/002EN", 11), Card("BT01/003EN", 12), Card("BT01/004EN", 13), Card("BT01/005EN", 14), Card("BT01/006EN", 15), }, Guardian = new List { Card("BT01/007EN", 21), Card("BT01/008EN", 22), }, Soul = new List { Card("BT01/009EN", 31), Card("BT01/010EN", 32), }, FaceDownDamage = 2, FaceUpDamage = new List { Card("BT01/011EN", 41), Card("BT01/012EN", 42), }, Trigger = new List { Card("BT01/090EN", 61) }, DeckCount = 38, Drop = new List { Card("BT01/013EN", 51) }, }; self.RearGuards[0] = Card("BT01/014EN", 2); self.RearGuards[3] = Card("BT01/015EN", 3, rested: true); self.RearGuards[4] = Card("BT01/016EN", 4); var opponent = new PlayerView { Index = 1, Name = "Opponent", Vanguard = Card("BT01/020EN", 101), RearGuards = new CardView[5], Hand = new List(), Guardian = new List(), Soul = new List { Card("BT01/021EN", 131) }, FaceDownDamage = 1, FaceUpDamage = new List { Card("BT01/022EN", 141) }, Trigger = new List { Card("BT01/091EN", 161) }, DeckCount = 40, Drop = new List(), }; opponent.RearGuards[4] = Card("BT01/023EN", 102); opponent.RearGuards[2] = Card("BT01/024EN", 103, rested: true); return new MatchView { MatchId = "sandbox", You = 0, ActivePlayer = 0, TurnNumber = 4, Phase = GamePhase.Main, Players = new List { self, opponent }, Clock = new ClockView(), LegalIntents = new List(), }; } } }