Fix scrolling reports and duplicate Sarka status
continuous-integration/drone/push Build is passing

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;
+5 -5
View File
@@ -325,12 +325,12 @@ ScrollLayoutWidgetClass {
{
VerticalLayoutWidgetClass {
Name "JournalContent" Slot AlignableSlot {
HorizontalAlign 3 VerticalAlign 3 Padding 8 4 14 4
HorizontalAlign 3 VerticalAlign 0 Padding 8 4 14 4
}
{
TextWidgetClass {
Name "JournalText" Slot LayoutSlot {
HorizontalAlign 3 Padding 0 0 0 8 SizeMode Fill
HorizontalAlign 3 Padding 0 0 0 8 SizeMode Auto
}
Clipping Ancestor Color 0.9 0.92 0.94 1 Text "Waiting for the first HQ event..." "Font Size" 18 "Min Font Size" 18 Wrap 1 FontProperties FontProperties {
Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt"
@@ -748,7 +748,7 @@ TextWidgetClass {
FrameWidgetClass { "Is Visible" 0 Name "StatusPage" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 220 OffsetLeft 220 PositionY 160 OffsetTop 160 SizeX 1000 OffsetRight -1220 SizeY 486 OffsetBottom -646 } {
TextWidgetClass {
Name "StatusHelp" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 6 OffsetTop 6 SizeX 936 OffsetRight -964 SizeY 50 OffsetBottom -56 }
Color 0.9 0.92 0.94 1 Text "Live server state. Mortar counts mean operational / deployed; UAZ allowances include past losses." "Font Size" 19 "Min Font Size" 19 Wrap 1
Color 0.9 0.92 0.94 1 Text "Live mission status. Scroll for more. Mortars: operational / deployed. UAZ allowances include past losses." "Font Size" 19 "Min Font Size" 19 Wrap 1
FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" }
}
ScrollLayoutWidgetClass {
@@ -760,12 +760,12 @@ ScrollLayoutWidgetClass {
{
VerticalLayoutWidgetClass {
Name "StatusContent" Slot AlignableSlot {
HorizontalAlign 3 VerticalAlign 3 Padding 8 4 14 4
HorizontalAlign 3 VerticalAlign 0 Padding 8 4 14 4
}
{
TextWidgetClass {
Name "Status" Slot LayoutSlot {
HorizontalAlign 3 Padding 0 0 0 8 SizeMode Fill
HorizontalAlign 3 Padding 0 0 0 8 SizeMode Auto
}
Clipping Ancestor Color 0.9 0.92 0.94 1 Text "Waiting for mission status..." "Font Size" 18 "Min Font Size" 18 Wrap 1 FontProperties FontProperties {
Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt"