Разведка М2: целенаправленная разведка поселений, замка и лагерей с отчётами II и III

Отряд идёт маршем, наблюдает 2/4 (поселение, лагерь) или 3/6 (замок) игровых часов, отчёт на конец наблюдения,
потом домой. Уровень II -- точные войска, герой, стены; III -- плюс защита и ресурсы ±15%. Один отчёт на операцию,
сохранение. Карта: кнопки «Разведка II/III», окно отчёта, «Отчёты», прогноз по отчёту вне обзора.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alexander
2026-11-04 15:21:54 +01:00
co-authored by Claude Opus 5.5
parent 6c39c8b102
commit 61ba46947c
16 changed files with 552 additions and 27 deletions
@@ -30,6 +30,8 @@ namespace Bogatyri.World
public bool gather; // поход на ресурсную точку: сбор вместо боя
public bool patrol; // патруль-заглушка соседа (Разведка М1): без боя и добычи, Армии игрока не касается
public bool scout; // поход «Разведка» (решения 31.10, п. 2): дойти до цели и вернуться, без боя и сбора
public int reconLevel; // Разведка М2: 0 -- просто дойти и вернуться; 2 / 3 -- наблюдать reconHoldMs и составить отчёт
public long reconHoldMs; // сколько наблюдать цель (мс часов игры): время уровня из модуля Разведки
public long gatherEndMs; // когда сбор закончится (груз полон, точка истощена или исчезла)
public int cargo; // сколько ресурса несёт войско (известно с начала сбора)
public int defenders; // гарнизон цели в момент боя
@@ -147,7 +149,8 @@ namespace Bogatyri.World
MarchReturned, // войско вернулось домой
GatherStarted, // войско дошло до ресурсной точки и начало сбор (или точка исчезла -- targetEmpty)
GatherFinished, // сбор закончен, войско идёт домой с грузом
ScoutArrived // разведка дошла до цели и повернула домой (targetEmpty -- цели уже нет)
ScoutArrived, // разведка дошла до цели: повернула домой или (М2) начала наблюдение (targetEmpty -- цели уже нет)
ReconCompleted // М2: наблюдение закончено -- пора составить отчёт, разведчики идут домой
}
public struct WorldEvent
@@ -373,6 +376,11 @@ namespace Bogatyri.World
ArriveScout(next);
events.Add(new WorldEvent { Type = WorldEventType.ScoutArrived, March = next, TimeMs = nextMs });
}
else if (nextKind == 1)
{
next.state = MarchState.Returning; // наблюдение закончено, обратный путь уже рассчитан
events.Add(new WorldEvent { Type = WorldEventType.ReconCompleted, March = next, TimeMs = nextMs });
}
else
{
next.state = MarchState.Finished;
@@ -487,6 +495,23 @@ namespace Bogatyri.World
m.loot = new List<RewardEntry>();
ResourcePoint p = target.type == MapNodeType.ResourcePoint ? GetPoint(target.id) : null;
m.targetEmpty = target.type == MapNodeType.ResourcePoint && (p == null || !p.active);
// М2: разведчики стоят у цели время наблюдения, потом идут домой (обратный путь -- от конца наблюдения)
if (m.reconLevel > 0 && m.reconHoldMs > 0 && !m.targetEmpty)
{
m.state = MarchState.Gathering;
m.gatherEndMs = m.arriveMs + m.reconHoldMs;
m.returnMs = m.gatherEndMs + TravelTimeMs(target, from, units);
}
}
// Разведка с отчётом (М2): уровень и время наблюдения. Только пока разведчики ещё в пути к цели
public bool SetRecon(MarchData m, int level, long holdMs)
{
if (m == null || !m.scout || m.state != MarchState.Outbound || !marches.Contains(m)) return false;
m.reconLevel = level;
m.reconHoldMs = Math.Max(0, holdMs);
return true;
}
// Название цели похода: запомненное при выступлении (старые походы -- с карты)
@@ -542,7 +567,7 @@ namespace Bogatyri.World
{
segmentFrom = target;
segmentTo = home;
start = m.gather ? m.gatherEndMs : m.arriveMs; // после сбора -- обратно от конца сбора
start = m.gather || m.reconLevel > 0 && m.gatherEndMs > 0 ? m.gatherEndMs : m.arriveMs; // после сбора / наблюдения -- от его конца
end = m.returnMs;
}