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),
},
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) },
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(),
};
}
}
}