Очередь обучения -- у Армии (решения 31.10, п. 8); окно «Разведка вернулась» на карте

Армия: заказы, сроки по часам игры, завершение один раз (TroopsTrainedEvent), сохранение train=.
Население отдаёт жителей и принимает новобранцев через свой контракт.
GameProgress (код Вальдемара, с разрешения команды): только цена, Казармы, окна и статистика;
старая очередь из progress.json переносится один раз с тем же оставшимся временем.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alexander
2026-11-01 13:19:34 +01:00
co-authored by Claude Opus 5.5
parent 33db41002e
commit 482721a704
16 changed files with 413 additions and 70 deletions
+25 -1
View File
@@ -24,9 +24,29 @@
| `ReturnFromMarch(marchId, survivors)` | Вернуть выживших по тем же типам (пропорционально). `false` — поход неизвестен, никто не добавлен. |
| `GetMarchUnits(marchId)` | Состав похода по типам — для боя с типами войск. |
| `ReturnUnits(marchId, survivorUnits)` | Вернуть выживших точно по типам, как посчитал бой. Больше, чем ушло, не вернётся. `false` — поход неизвестен. |
| `Training` | Очередь обучения: заказы (`TrainingOrderInfo`: номер, тип, сколько, начало и конец в мс часов игры). |
| `CanQueueTraining(type, count, queueSize, out error)` | Можно ли поставить заказ: очередь не заполнена, жителей хватает (Население). Ничего не меняет. |
| `TryQueueTraining(type, count, durationMs, queueSize, nowMs, out error)` | Поставить заказ в конец очереди; люди уходят из жителей в Казармы (`IPopulation.TryRecruit`). `false` — ничего не изменилось. |
| `ProcessTraining(nowMs)` | Закончить заказы, срок которых наступил (и офлайн): воины переходят в Армию через `IPopulation.CompleteTraining`, каждый заказ — один раз. |
| `FinishAllTraining(nowMs)` | Ускорение: все заказы готовы сейчас. |
Получить: `GameServices.Get<IArmy>()`. Регистрирует `App/GameModules`. `GameProgress` (обучение, кампания, арена, сила армии) и панели работают с войсками только через этот контракт.
## Очередь обучения
Решения по 8 вопросам Саши от 31.10, п. 8: **единственный владелец очереди — Армия.** Раньше её вёл `GameProgress` (`progress.json`, время по настоящим часам) — перенесено.
| Кто | Что делает |
| --- | --- |
| Армия | Заказы по порядку (новый начинается, когда закончится последний), сроки, завершение — один раз на заказ (`TroopsTrainedEvent`), сохранение. |
| Население | Свободные жители и резерв (`Recruitable`, `CivilianReserve`), уход людей в Казармы (`TryRecruit`) и переход в воины (`CompleteTraining`). |
| Слой приложения (`GameProgress`) | Есть ли Казармы и открыт ли тип войск, длина очереди (`Barracks.QueueSize`), цена — через Экономику (если заказ не встал — цена возвращается), окна, статистика заданий по `TroopsTrainedEvent`. |
- Время — часы игры (`GameClock.UnixNowMs`): перемотка «DEV +1 час» и офлайн досчитывают обучение так же, как марши. Раньше обучение шло по настоящим часам и перемотки не замечало.
- Повторный расчёт или загрузка не обучают заказ второй раз: он удаляется из очереди в момент завершения.
- Население не нашло новобранцев заказа (испорченное сохранение) — заказ снимается без воинов: люди не появляются из ниоткуда, очередь не встаёт.
- **Перенос старой очереди:** после загрузки `App/GameModules` один раз переносит заказы из `progress.json` (`Data.training`) в Армию с тем же оставшимся временем и признаком «люди взяты». Из `progress.json` они удаляются только после записи `save.json`.
## Правило «один солдат в одном месте»
Воин либо в городе, либо в походе. Поход забирает воинов из города и запоминает состав, возвращение раздаёт выживших по тем же типам. Тест `ArmyService_MarchNeverCreatesOrLosesSoldiers` проверяет, что «дома + в походах» всегда равно общему числу.
@@ -51,6 +71,7 @@
## События
- **Публикует:** `TroopsChangedEvent` (воинов в городе, из них в гарнизоне, и в походах) — при обучении, потерях, походе, возвращении, загрузке, сбросе. По нему `App/GameModules` перерисовывает панели HUD.
- **Публикует:** `TroopsTrainedEvent` (номер заказа, тип, сколько, когда были готовы) — один раз на заказ. По нему `GameProgress` ведёт статистику заданий и показывает «Обучено».
- **Слушает:** ничего.
## Сохранение
@@ -61,11 +82,13 @@
troops=<пехота>,<лучники>,<кавалерия>,<осадные>
garrison=<пехота>,<лучники>,<кавалерия>,<осадные> (часть troops)
march=<id похода>:<пехота>,<лучники>,<кавалерия>,<осадные>
train=<номер>|<тип>|<сколько>|<начало, мс>|<конец, мс>|<люди взяты 1/0> (по порядку очереди)
trainNext=<номер следующего заказа>
```
Старое сохранение без строки `garrison` читается: гарнизона нет.
Сброс (`ResetState`): войск, гарнизона и походов нет.
Сброс (`ResetState`): войск, гарнизона, походов и заказов обучения нет.
**Перенос из старых сохранений:**
- Раньше войска лежали в `progress.json`: `troops` хранил `GameProgress`, `sashaMarchUnits` — мост `ArmyBridge`.
@@ -96,6 +119,7 @@ march=<id похода>:<пехота>,<лучники>,<кавалерия>,<о
| Дата | Кто | Что |
| --- | --- | --- |
| 01.11.2026 | Claude | Решения 31.10, п. 8: очередь обучения перенесена из `GameProgress` в Армию (`Training`, `CanQueueTraining`, `TryQueueTraining`, `ProcessTraining`, `FinishAllTraining`, `TroopsTrainedEvent`, строки `train=` в сохранении), время — часы игры, перенос старой очереди из `progress.json`. Изменены `GameProgress`, `TroopsPanel`, `Barracks`, `BuildingWindow` (код Вальдемара, с разрешения команды). Тесты: порядок и однократность, лимит и ускорение, люди из Населения и обратно, сохранение и перенос. |
| 31.10.2026 | Claude | Слоты похода: `MarchSlots`, `ActiveMarches`; `ArmyService(baseMarchSlots)`, база 2 из таблицы `MarchConfig`; `TakeForMarch` отказывает при занятых слотах. Тест `ArmyService_MarchSlots`. |
| 28.10.2026 | Claude | По ревью 27.10.2026 (п. 2.1–2.2): `ReturnFromMarch` и `ReturnUnits` возвращают `bool` и зачисляют только по известному походу и только один раз; `TakeForMarch` отклоняет повторный номер похода; дубликаты походов в сохранении пропускаются. Тесты: неизвестный поход, повторное возвращение, повторный номер. |
| 27.10.2026 | Claude | Гарнизон города: `GarrisonTotal`, `GetGarrison`, `AvailableForMarch`, `SetGarrison`; в поход уходят только свободные; строка `garrison=` в сохранении; поле `Garrison` в `TroopsChangedEvent`; карточка «Гарнизон города» в окне «Войска». Тест «один солдат в одном месте» с гарнизоном. |
+1
View File
@@ -60,6 +60,7 @@
| Дата | Кто | Что |
| --- | --- | --- |
| 01.11.2026 | Claude | `IArmy`: очередь обучения (`Training`, `CanQueueTraining`, `TryQueueTraining`, `ProcessTraining`, `FinishAllTraining`), `TrainingOrderInfo`, событие `TroopsTrainedEvent`; `GameClock.UnixNowMs` (решения 31.10, п. 8). |
| 01.11.2026 | Claude | `IWorld.TryStartScout`; `IsScout` у `MarchStartedEvent` и `MarchReturnedEvent` (решения 31.10, п. 2). |
| 31.10.2026 | Claude | Разведка М1: контракты `IWorldMap`, `IIntelligence` (`ArmyOnMap`, `MapVisibility`, `KnownContact`), события `WorldAdvancingEvent`, `ArmySpottedEvent`, `ArmyIdentifiedEvent`, `ArmyLostContactEvent`. |
| 31.10.2026 | Claude | `IPopulation.CompleteTraining(type, n)` — передача новобранцев в Армию одним действием. |
+2 -1
View File
@@ -106,12 +106,13 @@
- п. 8, норма еды на солдата -- сейчас 0.2 еды в час реального времени, игрового календаря нет. Предложение: не вводить; если нужен «игровой месяц» -- 1 месяц = 1 сутки, норма ≈ 5 еды. Решает Дима.
- **Этап 5:** найм воина забирает человека из жителей (гражданский резерв — решение от 19.10.2026) — сделано 28.10.2026. Цену воина в ресурсах (`EconomyConfig`, раздел «Солдат»: 15 еды, 5 металла, 5 золота) Казармы пока не используют — у них своя цена в `GameData.Troops`.
- **Схема модулей:** Население — самостоятельный модуль (регламент 28.10 и 31.10.2026). Перенос внутрь Поселения от 28.10 был ошибкой и откатан 31.10.
- **Открыто (регламент 31.10, ждёт решения):** нормы еды для четырёх групп (гражданские и рабочие, новобранцы, солдаты, раненые); переход экономики на игровое время (1 игровой час = 5 реальных минут) и единицы офлайна (48 ч) и истории голода; кто считает предел жилья и рабочие места (по регламенту — Поселение); недоступен ли резерв и для работы; перенос очереди найма из `GameProgress` в Армию (с Сашей).
- **Открыто (регламент 31.10, ждёт решения):** нормы еды для четырёх групп (гражданские и рабочие, новобранцы, солдаты, раненые); переход экономики на игровое время (1 игровой час = 5 реальных минут) и единицы офлайна (48 ч) и истории голода; кто считает предел жилья и рабочие места (по регламенту — Поселение); недоступен ли резерв и для работы.
## Журнал изменений
| Дата | Кто | Что |
| --- | --- | --- |
| 01.11.2026 | Claude (Саша) | Очередь обучения перенесена в Армию (решения 31.10, п. 8). Население по-прежнему отдаёт жителей (`TryRecruit`) и принимает новобранцев в воины (`CompleteTraining`) — его код не менялся, зовёт их теперь Армия. `RecruitsTrained` больше никто не вызывает. |
| 31.10.2026 | Claude | `CompleteTraining`: новобранцы переходят в Армию одним действием с откатом, если Армия не приняла. Заказ обучения помечает, брали ли под него людей (`TrainingOrder.recruited`); старые заказы — по-старому. Интеграционные тесты с настоящей Армией: переход без потерь, отказ Армии, повтор, нет Армии, часть заказа. |
| 31.10.2026 | Claude | Автозаполнение новых мест убрано (`AutoFill` удалён, `App/CitySync` больше не ставит рабочих после стройки и улучшения), осталась только стартовая расстановка один раз. При загрузке рабочих не больше, чем жителей. Тесты: группы людей не пересекаются и в сумме дают всех, рабочих не больше свободных, новые места пустые, стартовая расстановка один раз. |
| 31.10.2026 | Claude | По регламенту 31.10: Население снова самостоятельный модуль (`Modules/Population`, сборка `Bogatyri.Population`); убрано ограничение «40% всех людей» — работать может любой житель, первая расстановка — 120 рабочих; резерв по уровню Ратуши 10/20/30 (ТЕСТ, `civilianReserveByTownHallLevel` вместо `civilianReserve`); при голоде добыча кроме еды ×0.5 (ТЕСТ). Тесты. |
+1
View File
@@ -105,6 +105,7 @@ EditMode-тесты: `Assets/Scripts/Modules/Tests/ModuleTests.cs`. Запуск
| Дата | Кто | Что |
| --- | --- | --- |
| 01.11.2026 | Claude | Решения 31.10, п. 8: очередь обучения — у Армии. Обновлены Army, Core, Population. |
| 01.11.2026 | Claude | Решения 31.10, п. 2: поход «Разведка». Обновлены World, Core, Intelligence. |
| 01.11.2026 | Claude | Решения 31.10, п. 6: 24 ресурсные точки. Обновлён World. |
| 01.11.2026 | Claude | Решения 31.10, п. 5: разгром дальше 5:1 (92% / 95% / до 99%). Обновлён Battle. |