Fix scrolling reports and duplicate Sarka status
This commit is contained in:
+6
-1
@@ -1,6 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
Latest published Workshop version: **0.0.111**
|
Latest published Workshop version: **0.0.112**
|
||||||
|
|
||||||
|
## 2026-10-17 — Mission status readability
|
||||||
|
|
||||||
|
- Fixed clipped status and journal text so long reports can be scrolled.
|
||||||
|
- Fixed duplicated Šárka wave details and restored the hunting-patrol summary.
|
||||||
|
|
||||||
## 2026-10-17 — Mission menu navigation
|
## 2026-10-17 — Mission menu navigation
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,36 @@ modded class ERR_AdminMenu
|
|||||||
}
|
}
|
||||||
ERR_ProbePage(0); return true;
|
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()
|
bool ERR_ProbeJournalVisible()
|
||||||
{
|
{
|
||||||
TextWidget text = TextWidget.Cast(GetRootWidget().FindAnyWidget("JournalText"));
|
TextWidget text = TextWidget.Cast(GetRootWidget().FindAnyWidget("JournalText"));
|
||||||
|
|||||||
@@ -79,6 +79,13 @@ modded class ERR_GameMode
|
|||||||
{
|
{
|
||||||
ERR_AdminMenu menu = ERR_AdminMenu.GetOpenMenu();
|
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 (!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());
|
System.MakeScreenshot("$logs:err-menu-sidebar-" + m_ERRSarkaMenuPage.ToString());
|
||||||
m_ERRSarkaStage = 91; return;
|
m_ERRSarkaStage = 91; return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ class ERR_HunterService : ERR_ConvoyService
|
|||||||
}
|
}
|
||||||
string SarkaStatus()
|
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.
|
// HQ maintenance runs even while tactical ticks pause in an empty round.
|
||||||
void PauseSarkaIfEmpty()
|
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));
|
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;
|
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)
|
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;
|
if ((!m_PendingReserve && Deployed() >= m_Target + m_ReserveSpent) || Deployed() >= 15 || m_Mode.Forces().Count() >= 250) return false;
|
||||||
|
|||||||
@@ -325,12 +325,12 @@ ScrollLayoutWidgetClass {
|
|||||||
{
|
{
|
||||||
VerticalLayoutWidgetClass {
|
VerticalLayoutWidgetClass {
|
||||||
Name "JournalContent" Slot AlignableSlot {
|
Name "JournalContent" Slot AlignableSlot {
|
||||||
HorizontalAlign 3 VerticalAlign 3 Padding 8 4 14 4
|
HorizontalAlign 3 VerticalAlign 0 Padding 8 4 14 4
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TextWidgetClass {
|
TextWidgetClass {
|
||||||
Name "JournalText" Slot LayoutSlot {
|
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 {
|
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"
|
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 } {
|
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 {
|
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 }
|
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" }
|
FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" }
|
||||||
}
|
}
|
||||||
ScrollLayoutWidgetClass {
|
ScrollLayoutWidgetClass {
|
||||||
@@ -760,12 +760,12 @@ ScrollLayoutWidgetClass {
|
|||||||
{
|
{
|
||||||
VerticalLayoutWidgetClass {
|
VerticalLayoutWidgetClass {
|
||||||
Name "StatusContent" Slot AlignableSlot {
|
Name "StatusContent" Slot AlignableSlot {
|
||||||
HorizontalAlign 3 VerticalAlign 3 Padding 8 4 14 4
|
HorizontalAlign 3 VerticalAlign 0 Padding 8 4 14 4
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TextWidgetClass {
|
TextWidgetClass {
|
||||||
Name "Status" Slot LayoutSlot {
|
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 {
|
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"
|
Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt"
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ ScrollLayoutWidgetClass {
|
|||||||
{
|
{
|
||||||
VerticalLayoutWidgetClass {
|
VerticalLayoutWidgetClass {
|
||||||
Name "JournalContent" Slot AlignableSlot {
|
Name "JournalContent" Slot AlignableSlot {
|
||||||
HorizontalAlign 3 VerticalAlign 3 Padding 8 4 14 4
|
HorizontalAlign 3 VerticalAlign 0 Padding 8 4 14 4
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TextWidgetClass {
|
TextWidgetClass {
|
||||||
Name "JournalText" Slot LayoutSlot {
|
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 {{COLOR_TEXT}} Text "Waiting for the first HQ event..." "Font Size" {{SIZE_BODY}} "Min Font Size" {{SIZE_BODY}} Wrap 1 FontProperties FontProperties {
|
Clipping Ancestor Color {{COLOR_TEXT}} Text "Waiting for the first HQ event..." "Font Size" {{SIZE_BODY}} "Min Font Size" {{SIZE_BODY}} Wrap 1 FontProperties FontProperties {
|
||||||
Font "{{FONT}}"
|
Font "{{FONT}}"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
FrameWidgetClass { "Is Visible" {{VISIBLE_StatusPage}} 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 } {
|
FrameWidgetClass { "Is Visible" {{VISIBLE_StatusPage}} 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 {
|
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 }
|
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 {{COLOR_TEXT}} Text "Live server state. Mortar counts mean operational / deployed; UAZ allowances include past losses." "Font Size" {{SIZE_INTRO}} "Min Font Size" {{SIZE_INTRO}} Wrap 1
|
Color {{COLOR_TEXT}} Text "Live mission status. Scroll for more. Mortars: operational / deployed. UAZ allowances include past losses." "Font Size" {{SIZE_INTRO}} "Min Font Size" {{SIZE_INTRO}} Wrap 1
|
||||||
FontProperties FontProperties { Font "{{FONT}}" }
|
FontProperties FontProperties { Font "{{FONT}}" }
|
||||||
}
|
}
|
||||||
ScrollLayoutWidgetClass {
|
ScrollLayoutWidgetClass {
|
||||||
@@ -13,12 +13,12 @@ ScrollLayoutWidgetClass {
|
|||||||
{
|
{
|
||||||
VerticalLayoutWidgetClass {
|
VerticalLayoutWidgetClass {
|
||||||
Name "StatusContent" Slot AlignableSlot {
|
Name "StatusContent" Slot AlignableSlot {
|
||||||
HorizontalAlign 3 VerticalAlign 3 Padding 8 4 14 4
|
HorizontalAlign 3 VerticalAlign 0 Padding 8 4 14 4
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TextWidgetClass {
|
TextWidgetClass {
|
||||||
Name "Status" Slot LayoutSlot {
|
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 {{COLOR_TEXT}} Text "Waiting for mission status..." "Font Size" {{SIZE_BODY}} "Min Font Size" {{SIZE_BODY}} Wrap 1 FontProperties FontProperties {
|
Clipping Ancestor Color {{COLOR_TEXT}} Text "Waiting for mission status..." "Font Size" {{SIZE_BODY}} "Min Font Size" {{SIZE_BODY}} Wrap 1 FontProperties FontProperties {
|
||||||
Font "{{FONT}}"
|
Font "{{FONT}}"
|
||||||
|
|||||||
Reference in New Issue
Block a user