114 lines
4.1 KiB
C
114 lines
4.1 KiB
C
#ifdef WORKBENCH
|
|
class ERR_PreparationExitProbe
|
|
{
|
|
static int s_Pauses, s_ExitAt;
|
|
static bool s_Armed, s_Clean, s_Ended, s_Complete;
|
|
static void Finish()
|
|
{
|
|
if (!s_Armed || !s_Clean || !s_Ended || s_Complete || System.GetTickCount() - s_ExitAt >= 5000) return;
|
|
s_Complete = true;
|
|
Check(true, "native gameplay end after exit click and menu-listener cleanup observed");
|
|
Print("ERR SMOKE COMPLETE: preparation-exit native gameplay-end transition");
|
|
}
|
|
static bool Enabled()
|
|
{
|
|
string outcome;
|
|
return System.GetCLIParam("errSmokeOutcome", outcome) && outcome == "preparation-exit";
|
|
}
|
|
static bool Check(bool ok, string detail)
|
|
{
|
|
if (ok) Print("ERR SMOKE PASS: preparation exit " + detail);
|
|
else Print("ERR SMOKE FAIL: preparation exit " + detail, LogLevel.ERROR);
|
|
return ok;
|
|
}
|
|
}
|
|
modded class ERR_GameMode
|
|
{
|
|
override protected void StartScenario()
|
|
{
|
|
if (ERR_PreparationExitProbe.Enabled())
|
|
{
|
|
FailPreparation("Fixture: no safe navigable prison. Checks: water=120; uneven ground=30");
|
|
return;
|
|
}
|
|
super.StartScenario();
|
|
}
|
|
}
|
|
modded class SCR_RespawnSystemComponent
|
|
{
|
|
bool ERR_TestUnderlayHidden() { return m_wLoadingPlaceholder && !m_wLoadingPlaceholder.IsVisible(); }
|
|
}
|
|
modded class PauseMenuUI
|
|
{
|
|
protected bool m_ERRExitTestClosed;
|
|
override void OnMenuUpdate(float tDelta)
|
|
{
|
|
super.OnMenuUpdate(tDelta);
|
|
if (!ERR_PreparationExitProbe.Enabled() || m_ERRExitTestClosed) return;
|
|
m_ERRExitTestClosed = true;
|
|
SCR_RespawnSystemComponent respawn = SCR_RespawnSystemComponent.GetInstance();
|
|
if (!ERR_PreparationExitProbe.Check(IsFocused() && respawn && respawn.ERR_TestUnderlayHidden(), "native pause has focus and black underlay remains hidden")) return;
|
|
ERR_PreparationExitProbe.s_Pauses++;
|
|
Close();
|
|
}
|
|
}
|
|
modded class ERR_PreparationFailureMenu
|
|
{
|
|
protected float m_ERRExitTestAge;
|
|
protected int m_ERRExitTestStage;
|
|
override void OnMenuUpdate(float tDelta)
|
|
{
|
|
super.OnMenuUpdate(tDelta);
|
|
if (!ERR_PreparationExitProbe.Enabled() || !IsFocused() || m_ERRExitTestStage < 0) return;
|
|
m_ERRExitTestAge += tDelta;
|
|
if (m_ERRExitTestAge < 1) return;
|
|
m_ERRExitTestAge = 0;
|
|
if (m_ERRExitTestStage == 0)
|
|
{
|
|
SCR_RespawnSystemComponent respawn = SCR_RespawnSystemComponent.GetInstance();
|
|
if (!ERR_PreparationExitProbe.Check(Visible(m_Mode) && m_Bound && respawn && respawn.ERR_TestUnderlayHidden(), "real focused error menu has both bound buttons, exact error and hidden loading layer")) { m_ERRExitTestStage = -1; return; }
|
|
m_ERRExitTestStage = 1;
|
|
m_PauseButton.m_OnClicked.Invoke(m_PauseButton);
|
|
return;
|
|
}
|
|
if (m_ERRExitTestStage == 1)
|
|
{
|
|
if (!ERR_PreparationExitProbe.Check(ERR_PreparationExitProbe.s_Pauses == 1 && Failed(m_Mode), "pause button returns to the same failed round without admitting a player")) { m_ERRExitTestStage = -1; return; }
|
|
m_ERRExitTestStage = 2;
|
|
OnBack(); // Actual handler bound to MenuBack; no physical key-input claim.
|
|
return;
|
|
}
|
|
if (m_ERRExitTestStage == 2)
|
|
{
|
|
if (!ERR_PreparationExitProbe.Check(ERR_PreparationExitProbe.s_Pauses == 2, "bound Back handler opens native pause and restores failure-menu focus")) { m_ERRExitTestStage = -1; return; }
|
|
m_ERRExitTestStage = 3;
|
|
ERR_PreparationExitProbe.s_Armed = true;
|
|
ERR_PreparationExitProbe.s_ExitAt = System.GetTickCount();
|
|
m_ReturnButton.m_OnClicked.Invoke(m_ReturnButton);
|
|
}
|
|
}
|
|
override void OnMenuClose()
|
|
{
|
|
super.OnMenuClose();
|
|
if (ERR_PreparationExitProbe.s_Armed)
|
|
{
|
|
ERR_PreparationExitProbe.s_Clean = !m_Bound && !m_Mode && !m_ReturnButton && !m_PauseButton;
|
|
PrintFormat("ERR EXIT TEST: menu closed; cleaned=%1", ERR_PreparationExitProbe.s_Clean);
|
|
ERR_PreparationExitProbe.Finish();
|
|
}
|
|
}
|
|
}
|
|
modded class ArmaReforgerScripted
|
|
{
|
|
override void OnGameEnd()
|
|
{
|
|
bool expected = ERR_PreparationExitProbe.Enabled() && ERR_PreparationExitProbe.s_Armed && System.GetTickCount() - ERR_PreparationExitProbe.s_ExitAt < 5000;
|
|
super.OnGameEnd();
|
|
if (!expected) return; // Runner shutdown cannot qualify the exit button.
|
|
ERR_PreparationExitProbe.s_Ended = true;
|
|
Print("ERR EXIT TEST: native gameplay ended after the real exit button");
|
|
ERR_PreparationExitProbe.Finish();
|
|
}
|
|
}
|
|
#endif
|