using ADOFAIRenderer.Core;
using HarmonyLib;
namespace ADOFAIRenderer.Patch.Game;
///
/// Keeps the game controller (scrController) in uninterrupted play during a render: no pause, no failure,
/// no scene change after the clear, and no clear texts.
///
/// All patches are active while (stage >= OnScene). RenderManager also sets
/// noFail, noFailInfiniteMargin and disableCongratsMessage on the controller when the scene is ready.
///
///
[HarmonyPatch(typeof(scrController))]
// ReSharper disable once InconsistentNaming
public static class scrControllerPatch
{
///
/// Prefix of scrController.TogglePauseGame() (pause menu toggle; sets Time.timeScale to 0 or 1 and shows the
/// pause menu; also called from the pause button, the pause key and OnApplicationPauseCallback). Skipped while
/// rendering, so the level cannot be paused. The skipped call returns
/// false (Harmony default for the unset bool result).
///
/// True to run the original method (not rendering); false to skip it (rendering).
[HarmonyPrefix]
[HarmonyPatch("TogglePauseGame")]
public static bool PreventPause()
{
return !RenderManager.IsActive;
}
///
/// Prefix of scrController.PortalTravelAction(Portal), which leaves the level through a portal (next level,
/// level select, main menu, ...); the game calls it on entering the Won state for non-world levels and on input after a win.
/// Skipped while rendering, so the scene stays loaded for the delay after the level end.
///
/// True to run the original method (not rendering); false to skip it (rendering).
[HarmonyPrefix]
[HarmonyPatch("PortalTravelAction")]
public static bool PreventPortalTravel()
{
return !RenderManager.IsActive;
}
///
/// Prefix of scrController.FailAction(...), which enters the Fail state: stops the song and all sounds, pauses the
/// VFX video and shows the failure texts. Skipped while rendering.
///
/// True to run the original method (not rendering); false to skip it (rendering).
[HarmonyPrefix]
[HarmonyPatch("FailAction")]
public static bool PreventFailAction()
{
return !RenderManager.IsActive;
}
///
/// Prefix of scrController.Fail2Action(), which moves from Fail to Fail2 (accuracy calculation, saving of the
/// best result for boss/custom boss levels, death counter). Skipped while rendering.
///
/// True to run the original method (not rendering); false to skip it (rendering).
[HarmonyPrefix]
[HarmonyPatch("Fail2Action")]
public static bool PreventFail2Action()
{
return !RenderManager.IsActive;
}
///
/// Prefix of scrController.OnPlayerDied(...), which kills the remaining players and calls FailAction when no other
/// player is alive. Skipped while rendering.
///
/// True to run the original method (not rendering); false to skip it (rendering).
[HarmonyPrefix]
[HarmonyPatch("OnPlayerDied")]
public static bool PreventPlayerDied()
{
return !RenderManager.IsActive;
}
///
/// Postfix of scrController.OnLandOnPortal(...), the win handler on the last tile: it sets and activates
/// txtCongrats / txtAprilCongrats / txtAllStrictClear, may show the detailed results and end-screen
/// lanterns, saves the result and changes the state to Won.
///
/// While rendering, clears and deactivates the three clear texts and disables the detailed results panel after the
/// original has run, so they do not appear in the rendered video. The Won state itself is kept: the default render end
/// condition (RenderContext.EndCondition) waits for it.
///
///
/// The game controller.
[HarmonyPostfix]
[HarmonyPatch("OnLandOnPortal")]
public static void PreventWinTextsPostfix(scrController __instance)
{
if (!RenderManager.IsActive || __instance == null) return;
if (__instance.txtCongrats)
{
__instance.txtCongrats.text = string.Empty;
__instance.txtCongrats.gameObject.SetActive(false);
}
if (__instance.txtAprilCongrats)
{
__instance.txtAprilCongrats.text = string.Empty;
__instance.txtAprilCongrats.gameObject.SetActive(false);
}
if (__instance.txtAllStrictClear)
{
__instance.txtAllStrictClear.text = string.Empty;
__instance.txtAllStrictClear.gameObject.SetActive(false);
}
if (__instance.detailedResults)
{
__instance.detailedResults.enabled = false;
if (__instance.detailedResults.gameObject != null)
{
__instance.detailedResults.gameObject.SetActive(false);
}
}
}
}