Армия: заказы, сроки по часам игры, завершение один раз (TroopsTrainedEvent), сохранение train=. Население отдаёт жителей и принимает новобранцев через свой контракт. GameProgress (код Вальдемара, с разрешения команды): только цена, Казармы, окна и статистика; старая очередь из progress.json переносится один раз с тем же оставшимся временем. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
96 lines
4.1 KiB
C#
96 lines
4.1 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using TMPro;
|
||
|
||
// КАЗАРМЫ -- здание для найма войск.
|
||
// - Без казарм нанимать войска нельзя.
|
||
// - Каждые казармы дают +1 место в очереди обучения (1 казармы = 3 места, максимум 5).
|
||
// - Уровень Казарм открывает новые типы войск (вместе с уровнем Ратуши; числа -- EconomyConfig, раздел "Солдат", ТЕСТ).
|
||
// Считаются самые прокачанные Казармы. Уровень сохраняет модуль Поселения (ILeveledBuilding).
|
||
// - Тап по казармам открывает окно Казарм (App/BuildingWindow): очередь, войска, улучшение, кнопка "Нанять войска".
|
||
// - Подписи над зданием больше нет -- всё в окне (вернуть: ShowLabel = true).
|
||
// Вешается на префаб Barracks (его создаёт Tools -> Build HUD Panels).
|
||
public class Barracks : MonoBehaviour, ILeveledBuilding
|
||
{
|
||
public static readonly List<Barracks> All = new List<Barracks>();
|
||
public static int Count { get { return All.Count; } }
|
||
public static bool ShowLabel = false;
|
||
|
||
public int level = 1;
|
||
public int Level { get => level; set => level = Mathf.Max(1, value); }
|
||
|
||
// Уровень самых прокачанных Казарм в городе (0 -- казарм нет)
|
||
public static int MaxLevel
|
||
{
|
||
get { int m = 0; foreach (var b in All) if (b != null && b.level > m) m = b.level; return m; }
|
||
}
|
||
|
||
// Размер очереди обучения в зависимости от числа казарм
|
||
public static int QueueSize { get { return Count == 0 ? 0 : Mathf.Min(5, 2 + Count); } }
|
||
|
||
TextMeshPro label;
|
||
float next;
|
||
|
||
void OnEnable() { if (!All.Contains(this)) All.Add(this); }
|
||
void OnDisable() { All.Remove(this); }
|
||
|
||
void Start()
|
||
{
|
||
if (!ShowLabel) return;
|
||
// подпись над зданием (обычный 3D-текст, не UI)
|
||
var go = new GameObject("BarracksLabel");
|
||
go.transform.SetParent(transform, false);
|
||
var sr = GetComponent<SpriteRenderer>();
|
||
float top = sr != null && sr.sprite != null ? sr.sprite.bounds.max.y : 1f;
|
||
go.transform.localPosition = new Vector3(0, top + 0.15f, 0);
|
||
label = go.AddComponent<TextMeshPro>();
|
||
label.fontSize = 3f;
|
||
label.alignment = TextAlignmentOptions.Center;
|
||
label.rectTransform.sizeDelta = new Vector2(6f, 1.2f);
|
||
label.color = Color.white;
|
||
label.outlineWidth = 0.2f;
|
||
label.outlineColor = Color.black;
|
||
var r = label.GetComponent<MeshRenderer>();
|
||
if (r != null) r.sortingOrder = (sr != null ? sr.sortingOrder : 0) + 10;
|
||
Refresh();
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
if (label == null) return;
|
||
if (Time.unscaledTime < next) return;
|
||
next = Time.unscaledTime + 0.5f;
|
||
Refresh();
|
||
}
|
||
|
||
void Refresh()
|
||
{
|
||
if (label == null) return;
|
||
var training = GameProgress.Instance.Training;
|
||
if (training.Count == 0)
|
||
{
|
||
label.text = "Казармы\n<size=70%>нажмите, чтобы нанять</size>";
|
||
return;
|
||
}
|
||
var o = training[0];
|
||
label.text = "Казармы\n<size=70%>" + GameData.Troops[o.Type].name + " ×" + o.Count + " " +
|
||
GameData.FormatTime(GameProgress.Instance.TrainingSecondsLeft(o)) +
|
||
(training.Count > 1 ? " (+" + (training.Count - 1) + ")" : "") + "</size>";
|
||
}
|
||
|
||
Vector3 downPos;
|
||
|
||
void OnMouseDown()
|
||
{
|
||
downPos = Input.mousePosition;
|
||
}
|
||
|
||
// Тап (а не перетаскивание камеры) -- окно Казарм
|
||
void OnMouseUpAsButton()
|
||
{
|
||
if (UIBlocker.IsPointerOverUI()) return;
|
||
if ((Input.mousePosition - downPos).magnitude > 25f) return;
|
||
BuildingWindow.Open(gameObject);
|
||
}
|
||
}
|