Разведка М3 (ядро): тайные операции -- группа до 10 пехоты/лучников, до 2 операций, проверки обнаружения, прерывание и возврат

- Разведка: CheckCovertGroup, StartCovert, CheckCovertUntil (15/25/35%, при входе и каждые 5 реальных минут, максимум при пересечении, 5-75%, детерминированно по одной сетке), EndCovert; сохранение covert=
- Армия: AvailableUnits, TakeUnitsForMarch -- поход точного состава
- Мир: AbortMission -- домой от места обнаружения, без отчёта; охраняемые области и позиция армии через IWorldMap
- Карта: «Тайно» в окне атаки и окне чужой армии, окно «РАЗВЕДЧИКОВ ЗАМЕТИЛИ»
- «Шпион» -- переключатель IntelligenceConfig (ТЕСТ); 5 тестов

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alexander
2026-11-06 17:15:22 +01:00
co-authored by Claude Opus 5.5
parent 56a5a82a8c
commit 2835c514d8
18 changed files with 622 additions and 14 deletions
@@ -158,6 +158,10 @@ public interface IArmy
// Забрать свободных воинов в поход (запоминает состав похода).
// false -- ничего не взято: не хватает воинов, нет свободного слота или поход с таким номером уже есть.
bool TakeForMarch(int marchId, int count);
// Свободные воины по типам (в городе минус гарнизон) и поход точного состава -- тайная группа (Разведка М3):
// только пехота и лучники. false -- столько таких воинов нет или слоты заняты
int[] AvailableUnits { get; }
bool TakeUnitsForMarch(int marchId, int[] units);
// Вернуть выживших из похода по тем же типам войск.
// Зачисляет только по известному походу и только один раз; false -- такого похода нет, никто не добавлен.
bool ReturnFromMarch(int marchId, int survivors);
@@ -255,6 +259,29 @@ public interface IWorldMap
void GetArmies(long timeMs, List<ArmyOnMap> result);
// Цель разведки: замок, поселение, лагерь (Разведка М2). false -- такой цели нет или её нельзя разведать
bool TryGetReconTarget(string targetId, out ReconTarget target);
// Разведка М3: охраняемые области (чужие поселения, башни, замок Круга) и где армия в момент t
void GetGuardedZones(List<GuardedZone> result);
bool TryGetArmyPosition(string armyId, long timeMs, out int x, out int y);
}
// Охраняемая область (Разведка М3, ТЗ разведки, раздел 8): тайный отряд в ней проверяется на обнаружение.
// Радиус и шанс по виду области -- правила Разведки
public enum GuardedZoneKind { Settlement, Tower, CircleCastle }
public struct GuardedZone
{
public string Id;
public int X, Y; // милли-единицы карты
public GuardedZoneKind Kind;
}
// Тайный отряд обнаружен (Разведка М3): миссия прервана, Мир разворачивает отряд домой с этого момента
public struct CovertDetection
{
public string OpId; // "covert_<номер похода>"
public string ArmyId; // "march_<номер похода>"
public long TimeMs;
public int Check; // номер проверки, на которой заметили
}
// ---------------- Разведка (Bogatyri.Intelligence): туман войны, наблюдение ----------------
@@ -301,6 +328,18 @@ public interface IIntelligence
IReadOnlyList<KnownContact> Contacts { get; }
void ObserveUntil(long nowMs); // досчитать наблюдение до момента (в том числе офлайн)
// ---- М3, тайные операции (ТЗ разведки, разделы 7-8) ----
bool CovertEnabled { get; } // технология «Шпион» (пока -- переключатель IntelligenceConfig)
int CovertMaxSoldiers { get; } // 10 пехотинцев / лучников (с героем-шпионом 20 -- позже)
int ActiveCovertOps { get; } // идут сейчас (не больше CovertMaxOps)
// Можно ли отправить тайно такой состав (по типам войск); null -- можно, иначе причина для игрока
string CheckCovertGroup(int[] units, int activeCovertOps);
void StartCovert(string opId, string armyId, long startMs);
// Проверки обнаружения до момента: при входе в охраняемую область и каждые 5 реальных минут в ней.
// Каждая проверка -- один раз (детерминированно по id операции и номеру проверки). Возвращает новые обнаружения
List<CovertDetection> CheckCovertUntil(long nowMs);
void EndCovert(string opId); // отряд вернулся домой
// ---- М2: целенаправленная разведка ----
// Сколько разведчики наблюдают цель (мс часов игры): поселение 2 / 4, замок 3 / 6 игровых часов (уровень II / III).
// 0 -- цель нельзя разведать с отчётом