using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; // ВОЙСКА: армия, очередь обучения (идёт и когда игра закрыта), найм воинов за ресурсы, // ускорение за кристаллы. Новые типы войск открываются уровнем Ратуши. public class TroopsPanel : BasePanel { readonly List queueBars = new List(); readonly List queueTimes = new List(); Button speedUp; static readonly int[] Amounts = { 1, 10, 50 }; protected override void Build(RectTransform root) { var d = GP.Data; queueBars.Clear(); queueTimes.Clear(); speedUp = null; var list = ScrollList(root); // --- Армия --- var army = UIKit.Card(list, UIKit.Theme.CardDark); ProfilePanel.Header(army, "Армия"); ProfilePanel.KV(army, "Всего воинов в городе", GP.TotalTroops.ToString("N0")); ProfilePanel.KV(army, "В походе на карте мира", GameServices.Get().TroopsInMarches.ToString("N0")); ProfilePanel.KV(army, "Сила войск", GP.TroopsPower.ToString("N0")); ProfilePanel.KV(army, "Сила армии с героем", GP.ArmyPower.ToString("N0")); UIKit.Button(army, "Отправить армию на карте мира", UIKit.Theme.Green, () => OpenPanel("World"), -1, 80, 26); // --- Гарнизон: часть воинов охраняет город и в походы не уходит --- IArmy troopsArmy = GameServices.Get(); var garrison = UIKit.Card(list, UIKit.Theme.CardDark); ProfilePanel.Header(garrison, "Гарнизон города"); ProfilePanel.KV(garrison, "В гарнизоне", troopsArmy.GarrisonTotal.ToString("N0") + " из " + troopsArmy.SoldiersAtHome.ToString("N0")); ProfilePanel.KV(garrison, "Свободны для походов", troopsArmy.AvailableForMarch.ToString("N0")); UIKit.Text(garrison, "Гарнизон защищает город и не уходит в походы. Воины в нём не пропадают: всего воинов столько же.", 22, UIKit.Theme.TextDim); var gRow = UIKit.Row(garrison, 80, 10); GarrisonButton(gRow, troopsArmy, "0", 0); GarrisonButton(gRow, troopsArmy, "-10", troopsArmy.GarrisonTotal - 10); GarrisonButton(gRow, troopsArmy, "-1", troopsArmy.GarrisonTotal - 1); GarrisonButton(gRow, troopsArmy, "+1", troopsArmy.GarrisonTotal + 1); GarrisonButton(gRow, troopsArmy, "+10", troopsArmy.GarrisonTotal + 10); GarrisonButton(gRow, troopsArmy, "Все", troopsArmy.SoldiersAtHome); // --- Нет казарм -- нанимать негде --- if (Barracks.Count == 0) { var warn = UIKit.Card(list, new Color(0.35f, 0.18f, 0.12f)); UIKit.Text(warn, "Нанимать войска можно только в Казармах. Постройте их на свободном участке.", 28, UIKit.Theme.Text); UIKit.Button(warn, "ПОСТРОИТЬ КАЗАРМЫ", UIKit.Theme.Green, () => { if (BuildModeController.Instance != null) BuildModeController.Instance.SetMode(true); else UIKit.Toast("Нажмите кнопку СТРОЙКА"); }, -1, 96, 32); } // --- Очередь обучения --- var queue = UIKit.Card(list); ProfilePanel.Header(queue, "Обучение (" + d.training.Count + " / " + Barracks.QueueSize + ") • казарм: " + Barracks.Count); if (d.training.Count == 0) { UIKit.Text(queue, "Никто не обучается. Выберите войска ниже.", 26, UIKit.Theme.TextDim); } else { foreach (var o in d.training) { var def = GameData.Troops[o.troopIndex]; var r = UIKit.Row(queue, 44, 10); var n = UIKit.Text(r, def.name + " × " + o.count, 28); UIKit.Size(n, -1, -1, 1); var t = UIKit.Text(r, "", 26, UIKit.Theme.Gold, TextAlignmentOptions.Right); UIKit.Size(t, 180); queueTimes.Add(t); queueBars.Add(UIKit.Bar(queue, 0, def.color, 20)); } speedUp = UIKit.Button(queue, "", UIKit.Theme.Blue, () => GP.SpeedUpTraining(), -1, 80); } Tick(); // --- Типы войск --- for (int i = 0; i < GameData.Troops.Count; i++) { int idx = i; var def = GameData.Troops[i]; bool unlocked = GP.TroopUnlocked(i); var card = UIKit.Card(list, unlocked ? UIKit.Theme.Card : UIKit.Theme.CardDark); var top = UIKit.Row(card, 120, 16); UIKit.Icon(top, unlocked ? def.color : UIKit.Theme.Gray, def.name.Substring(0, 1), 110); var info = UIKit.Card(top, new Color(0, 0, 0, 0), 0, 2); UIKit.Size(info, -1, -1, 1); UIKit.Text(info, def.name + " в армии: " + GP.TroopCount(i).ToString("N0") + "", 32).fontStyle = FontStyles.Bold; UIKit.Text(info, def.description, 22, UIKit.Theme.TextDim); UIKit.Text(info, "Сила " + def.power + " • " + def.secondsPerUnit + " сек/воин • " + GameData.RewardsText(def.cost), 22, UIKit.Theme.TextDim); if (!unlocked) { UIKit.Text(card, "Откроется на Ратуше " + def.requiredTownHall + " уровня", 26, UIKit.Theme.Gold, TextAlignmentOptions.Center); continue; } var btns = UIKit.Row(card, 80, 10); foreach (int amount in Amounts) { int a = amount; bool can = Barracks.Count > 0 && GP.CanAfford(def.cost, a) && d.training.Count < Barracks.QueueSize; var b = UIKit.Button(btns, "+" + a, can ? UIKit.Theme.Green : UIKit.Theme.Gray, () => GP.Train(idx, a), -1, 80, 30); UIKit.Size(b, -1, 80, 1); } } } // Окно перестраивается само: Армия публикует TroopsChangedEvent, GameProgress сообщает об изменении static void GarrisonButton(Transform row, IArmy army, string label, int target) { target = Mathf.Clamp(target, 0, army.SoldiersAtHome); bool can = target != army.GarrisonTotal; var b = UIKit.Button(row, label, can ? UIKit.Theme.Blue : UIKit.Theme.Gray, () => { if (can) army.SetGarrison(target); }, -1, 80, 28); UIKit.Size(b, -1, 80, 1); } protected override void Tick() { var d = GP.Data; for (int i = 0; i < queueBars.Count && i < d.training.Count; i++) { var o = d.training[i]; UIKit.SetBar(queueBars[i], GP.TrainingProgress(o)); queueTimes[i].text = GameData.FormatTime(GP.TrainingSecondsLeft(o)); } if (speedUp != null && d.training.Count > 0) UIKit.SetButton(speedUp, "Ускорить всё за " + GP.SpeedUpCost + " кристаллов", true); } }