using UnityEngine; using TMPro; // АРЕНА: бои с другими "игроками" (пока боты) за рейтинг. Билеты: 5 штук, 1 восстанавливается за 20 минут. // Вкладка "Рейтинг" -- таблица лидеров и ваше место. Лиги: Бронза -> Серебро -> Золото -> Платина -> Алмаз. public class ArenaPanel : BasePanel { int tab; TextMeshProUGUI ticketsText; protected override void Build(RectTransform root) { var col = UIKit.Card(root, new Color(0, 0, 0, 0), 0, 12); UIKit.Stretch(col); UIKit.Tabs(col, new[] { "Бой", "Рейтинг" }, tab, i => { tab = i; RequestRebuild(); }); var holder = UIKit.Make("ListHolder", col); UIKit.Size(holder, -1, -1).flexibleHeight = 1; var list = ScrollList(holder); ticketsText = null; if (tab == 0) BuildFights(list); else BuildRating(list); } void BuildFights(RectTransform list) { var d = GP.Data; int mine = GP.ArmyPower; var head = UIKit.Card(list, new Color(0.15f, 0.2f, 0.35f)); UIKit.Text(head, "Рейтинг: " + d.arenaRating + " • Лига: " + GameData.ArenaLeague(d.arenaRating), 32, UIKit.Theme.Gold, TextAlignmentOptions.Center).fontStyle = FontStyles.Bold; UIKit.Text(head, "Ваша сила: " + mine.ToString("N0") + " • Побед: " + d.arenaWins + " из " + d.arenaFights, 24, UIKit.Theme.TextDim, TextAlignmentOptions.Center); ticketsText = UIKit.Text(head, "", 28, UIKit.Theme.Text, TextAlignmentOptions.Center); Tick(); if (GP.TotalTroops == 0) { UIKit.Text(list, "Для боёв на арене нужны войска.", 28, UIKit.Theme.Red, TextAlignmentOptions.Center, 60); UIKit.Button(list, "Перейти к войскам", UIKit.Theme.Blue, () => OpenPanel("Troops"), -1, 90); } var opps = GP.ArenaOpponents; string[] tags = { "Лёгкий", "Равный", "Сильный" }; for (int i = 0; i < opps.Count; i++) { int idx = i; var o = opps[i]; float chance = GameProgress.WinChance(mine, o.power); var card = UIKit.Card(list); var row = UIKit.Row(card, 120, 16); UIKit.Icon(row, ProfilePanel.AvatarColors[(o.name.Length + i) % ProfilePanel.AvatarColors.Length], o.name.Substring(0, 1), 110); var info = UIKit.Card(row, new Color(0, 0, 0, 0), 0, 2); UIKit.Size(info, -1, -1, 1); UIKit.Text(info, o.name + " " + (i < tags.Length ? tags[i] : "") + "", 30).fontStyle = FontStyles.Bold; UIKit.Text(info, "Сила " + o.power.ToString("N0") + " • рейтинг " + o.rating, 24, UIKit.Theme.TextDim); Color cc = chance >= 0.7f ? UIKit.Theme.Green : (chance >= 0.4f ? UIKit.Theme.Gold : UIKit.Theme.Red); UIKit.Text(info, "Шанс победы " + Mathf.RoundToInt(chance * 100) + "%", 24, cc); bool can = GP.TotalTroops > 0 && GP.ArenaTickets > 0; var b = UIKit.Button(row, "Атаковать", can ? UIKit.Theme.Red : UIKit.Theme.Gray, () => Fight(idx), 200, 90); b.interactable = can; } UIKit.Button(list, "Обновить соперников", UIKit.Theme.Gray, () => GP.GenerateOpponents(), -1, 80); UIKit.Text(list, "Победа: +15..35 рейтинга, 150 золота, 5 кристаллов. Поражение: -8..14 рейтинга.", 22, UIKit.Theme.TextDim, TextAlignmentOptions.Center); } void BuildRating(RectTransform list) { var board = GP.Leaderboard(); int myRank = board.FindIndex(e => e.power == -1) + 1; UIKit.Text(list, "Ваше место: " + myRank + " из " + board.Count, 32, UIKit.Theme.Gold, TextAlignmentOptions.Center, 60) .fontStyle = FontStyles.Bold; for (int i = 0; i < board.Count; i++) { var e = board[i]; bool me = e.power == -1; var row = UIKit.Row(list, 70, 14, me ? new Color(0.45f, 0.36f, 0.12f) : (i % 2 == 0 ? UIKit.Theme.Card : UIKit.Theme.CardDark), 10); Color place = i == 0 ? UIKit.Theme.Gold : (i == 1 ? new Color(0.8f, 0.8f, 0.85f) : (i == 2 ? new Color(0.8f, 0.5f, 0.3f) : UIKit.Theme.TextDim)); UIKit.Size(UIKit.Text(row, (i + 1).ToString(), 30, place, TextAlignmentOptions.Center), 70); var n = UIKit.Text(row, e.name, 28, me ? UIKit.Theme.Gold : UIKit.Theme.Text); UIKit.Size(n, -1, -1, 1); UIKit.Size(UIKit.Text(row, GameData.ArenaLeague(e.rating), 24, UIKit.Theme.TextDim, TextAlignmentOptions.Right), 140); UIKit.Size(UIKit.Text(row, e.rating.ToString(), 28, UIKit.Theme.Text, TextAlignmentOptions.Right), 100); } } void Fight(int index) { var r = GP.FightArena(index); if (r == null) return; if (r.win) UIKit.Message("ПОБЕДА!", "Вы победили игрока " + r.opponent + "!\n\nРейтинг: +" + r.ratingChange + "\nНаграда: " + GameData.RewardsText(r.rewards) + ", 15 опыта", "Отлично"); else UIKit.Message("Поражение", r.opponent + " оказался сильнее.\n\nРейтинг: " + r.ratingChange, "Понятно"); } protected override void Tick() { if (ticketsText == null) return; int t = GP.ArenaTickets; string next = t < GameData.ArenaMaxTickets ? " • +1 через " + GameData.FormatTime(GP.SecondsToNextTicket) : ""; ticketsText.text = "Билеты: " + t + " / " + GameData.ArenaMaxTickets + next; } }