Разведка М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
@@ -35,6 +35,9 @@ namespace Bogatyri.World
public int targetMarchId; // Разведка М2: цель -- движущаяся армия (номер её похода); 0 -- цель -- узел карты
public int meetX, meetY; // где отряд перехватит армию (милли-единицы карты)
public int leaveX, leaveY; // где наблюдение кончится -- отсюда домой
public bool covert; // Разведка М3: тайная операция (группа до 10 пехоты / лучников)
public bool aborted; // миссию прервали (тайный отряд обнаружен): с abortMs идут домой от leaveX/leaveY
public long abortMs;
public long gatherEndMs; // когда сбор закончится (груз полон, точка истощена или исчезла)
public int cargo; // сколько ресурса несёт войско (известно с начала сбора)
public int defenders; // гарнизон цели в момент боя
@@ -548,6 +551,14 @@ namespace Bogatyri.World
// Где сейчас войско (для отрисовки). Возвращает долю пути 0..1 и точки начала/конца отрезка.
public void GetMarchSegment(MarchData m, long nowMs, out MapNode segmentFrom, out MapNode segmentTo, out double progress)
{
if (m.aborted && nowMs >= m.abortMs)
{
// миссия прервана -- идут домой от места, где их заметили
segmentFrom = Point(m.leaveX, m.leaveY);
segmentTo = GetNode(m.fromNodeId);
progress = m.returnMs > m.abortMs ? Math.Min(1.0, Math.Max(0.0, (nowMs - m.abortMs) / (double)(m.returnMs - m.abortMs))) : 1.0;
return;
}
if (IsArmyRecon(m)) { GetArmyReconSegment(m, nowMs, out segmentFrom, out segmentTo, out progress); return; }
MapNode home = GetNode(m.fromNodeId);
MapNode target = GetNode(m.targetNodeId);