Fix scrolling reports and duplicate Sarka status

This commit is contained in:
2026-10-17 18:44:01 +02:00
parent d5464f7438
commit 82b52ae1fc
7 changed files with 61 additions and 13 deletions
@@ -180,6 +180,36 @@ modded class ERR_AdminMenu
}
ERR_ProbePage(0); return true;
}
bool ERR_ProbeReportOverflow(string textName, string scrollName)
{
TextWidget text = TextWidget.Cast(GetRootWidget().FindAnyWidget(textName));
ScrollLayoutWidget scroll = ScrollLayoutWidget.Cast(GetRootWidget().FindAnyWidget(scrollName));
if (!text || !scroll) return false;
string saved = text.GetText();
string report;
for (int i = 0; i < 80; i++) report += "Report line " + i.ToString() + ": a long mission report must remain readable.\n";
report += "FINAL REPORT LINE";
text.SetText(report); GetRootWidget().Update();
float width, height, textWidth, textHeight, viewWidth, viewHeight;
text.GetScreenSize(width, height); text.GetTextSize(textWidth, textHeight);
scroll.GetScreenSize(viewWidth, viewHeight);
bool fits = GetGame().GetWorkspace().DPIUnscale(height) >= textHeight - 2 && height > viewHeight;
scroll.SetSliderPos(0, 1); GetRootWidget().Update();
float x, y, viewX, viewY, sliderX, sliderY;
text.GetScreenPos(x, y); scroll.GetScreenPos(viewX, viewY); scroll.GetSliderPos(sliderX, sliderY);
bool reachable = sliderY >= 0.98 && y + height <= viewY + viewHeight + 2 && y + height > viewY;
PrintFormat("ERR REPORT OVERFLOW: widget=%1 height=%2 textHeight=%3 viewport=%4 slider=%5 fits=%6 reachable=%7", textName, height, textHeight, viewHeight, sliderY, fits, reachable);
text.SetText(saved); scroll.SetSliderPos(0, 0); GetRootWidget().Update();
return fits && reachable;
}
bool ERR_ProbeHunterSummary()
{
TextWidget text = TextWidget.Cast(GetRootWidget().FindAnyWidget("Status"));
if (!text) return false;
string report = text.GetText();
array<string> parts = {}; report.Split("Sarka waves:", parts, false);
return report.Contains("HQ hunting patrols:") && parts.Count() == 2 && report.Contains("cars per anger point");
}
bool ERR_ProbeJournalVisible()
{
TextWidget text = TextWidget.Cast(GetRootWidget().FindAnyWidget("JournalText"));
@@ -79,6 +79,13 @@ modded class ERR_GameMode
{
ERR_AdminMenu menu = ERR_AdminMenu.GetOpenMenu();
if (!ERR_SarkaProbeCheck(menu && menu.ERR_ProbeNavigation(m_ERRSarkaMenuPage), "top main tabs and left sidebar reach page " + m_ERRSarkaMenuPage.ToString())) return;
if (m_ERRSarkaMenuPage == ERR_AdminPage.STATUS)
{
if (!ERR_SarkaProbeCheck(menu.ERR_ProbeHunterSummary(), "patrol summary and exactly one Sarka wave summary")) return;
if (!ERR_SarkaProbeCheck(menu.ERR_ProbeReportOverflow("Status", "StatusScroll"), "long status grows and last line scrolls into view")) return;
}
if (m_ERRSarkaMenuPage == ERR_AdminPage.JOURNAL)
if (!ERR_SarkaProbeCheck(menu.ERR_ProbeReportOverflow("JournalText", "JournalScroll"), "long journal grows and last line scrolls into view")) return;
System.MakeScreenshot("$logs:err-menu-sidebar-" + m_ERRSarkaMenuPage.ToString());
m_ERRSarkaStage = 91; return;
}
@@ -149,7 +149,7 @@ class ERR_HunterService : ERR_ConvoyService
}
string SarkaStatus()
{
return string.Format(" Sarka waves: %1 deployed, %2/%3 pending in wave %4; %5.", m_SarkaWaves.Spawned, m_SarkaWaves.Pending, m_SarkaWaves.Target, m_SarkaWaves.Wave, m_SarkaStatus) + string.Format(" %1 cars per anger point (30 per wave maximum).", m_SarkaWaves.CarsPerAnger);
return string.Format("Sarka waves: %1 deployed, %2/%3 pending in wave %4; %5. %6 cars per anger point (30 per wave maximum).", m_SarkaWaves.Spawned, m_SarkaWaves.Pending, m_SarkaWaves.Target, m_SarkaWaves.Wave, m_SarkaStatus, m_SarkaWaves.CarsPerAnger);
}
// HQ maintenance runs even while tactical ticks pause in an empty round.
void PauseSarkaIfEmpty()
@@ -434,7 +434,13 @@ class ERR_HunterService : ERR_ConvoyService
ERR_HQ.Event("HUNTER RESERVE", string.Format("%1 replaces unavailable patrol %2; reserve=%3/3; next departure in at least 480s; silence is not a confirmed death", unit.Source, m_PendingReserve.Source, m_ReserveSpent));
m_PendingReserve = null;
}
override string Status() { return string.Format("HQ hunting patrols: %1 active including bikes and Sarkas; %2 UAZ/trucks deployed; aggression allowance %3, reserve used %4/3 (15 total maximum). Reserve departures at least eight minutes apart. Motorbikes have a separate allowance.", ActiveHunters(), Deployed(), m_Target, m_ReserveSpent) + SarkaStatus(); }
override string Status()
{
// Keep the formatted patrol summary before calling another formatting method.
string patrols = string.Format("HQ hunting patrols: %1 active including bikes and Sarkas; %2 UAZ/trucks deployed; aggression allowance %3, reserve used %4/3 (15 total maximum). Reserve departures at least eight minutes apart. Motorbikes have a separate allowance.", ActiveHunters(), Deployed(), m_Target, m_ReserveSpent);
string sarka = SarkaStatus();
return patrols + "\n" + sarka;
}
protected bool StartHunter(ERR_HQ hq, float now)
{
if ((!m_PendingReserve && Deployed() >= m_Target + m_ReserveSpent) || Deployed() >= 15 || m_Mode.Forces().Count() >= 250) return false;