1+ using DiskCardGame ;
2+ using HarmonyLib ;
3+ using UnityEngine ;
4+ using System . Collections ;
5+
6+ namespace InscryptionAPI . AscensionScreens
7+ {
8+ [ HarmonyPatch ]
9+ public static class AscensionScreenManager
10+ {
11+ internal static List < Type > registeredScreens = new List < Type > ( ) ;
12+
13+ internal static Dictionary < AscensionMenuScreens . Screen , AscensionRunSetupScreenBase > screens ;
14+
15+ internal static AscensionMenuScreens . Screen initialScreen = AscensionMenuScreens . Screen . JournalSummary ;
16+
17+ internal const int CUSTOM_SCREEN_START = 100 ;
18+
19+ private static string challengeScreenHoverText = "START RUN" ;
20+
21+ public static void RegisterScreen < T > ( ) where T : AscensionRunSetupScreenBase
22+ {
23+ registeredScreens . Add ( typeof ( T ) ) ;
24+ }
25+
26+ private static AscensionScreenSort . Direction GetPreferredDirection ( Type t )
27+ {
28+ AscensionScreenSort sortAttr = Attribute . GetCustomAttribute ( t , typeof ( AscensionScreenSort ) ) as AscensionScreenSort ;
29+ if ( sortAttr == null )
30+ return AscensionScreenSort . Direction . NoPreference ;
31+ else
32+ return sortAttr . preferredDirection ;
33+ }
34+
35+ public static void InitializeAllScreens ( )
36+ {
37+ // Sort the screens
38+ registeredScreens . Sort ( ( a , b ) => ( int ) GetPreferredDirection ( a ) - ( int ) GetPreferredDirection ( b ) ) ;
39+
40+ // Build screens
41+ screens = new Dictionary < AscensionMenuScreens . Screen , AscensionRunSetupScreenBase > ( ) ;
42+
43+ AscensionMenuScreens . Screen previousScreen = AscensionMenuScreens . Screen . SelectChallenges ;
44+ AscensionMenuScreens . Screen currentScreen = ( AscensionMenuScreens . Screen ) CUSTOM_SCREEN_START ;
45+ AscensionMenuScreens . Screen nextScreen = ( AscensionMenuScreens . Screen ) ( CUSTOM_SCREEN_START + 1 ) ;
46+ initialScreen = currentScreen ;
47+ for ( int i = 0 ; i < registeredScreens . Count ; i ++ )
48+ {
49+ Type screenType = registeredScreens [ i ] ;
50+
51+ if ( i == registeredScreens . Count - 1 ) // the last one
52+ nextScreen = AscensionMenuScreens . Screen . SelectChallengesConfirm ;
53+
54+ try
55+ {
56+ AscensionRunSetupScreenBase screen = AscensionRunSetupScreenBase . BuildScreen ( screenType , previousScreen , nextScreen ) ;
57+
58+ screens . Add ( currentScreen , screen ) ;
59+
60+ previousScreen = currentScreen ;
61+ currentScreen = nextScreen ;
62+ nextScreen = ( AscensionMenuScreens . Screen ) ( ( int ) nextScreen + 1 ) ;
63+ } catch ( Exception ex )
64+ {
65+ InscryptionAPIPlugin . Log . LogError ( ex ) ;
66+ }
67+ }
68+
69+ if ( screens . Count == 0 )
70+ return ;
71+
72+ // Now make another pass through the screens and set the behavior of hovering over the continue and back buttons
73+
74+ previousScreen = AscensionMenuScreens . Screen . SelectChallenges ;
75+ currentScreen = ( AscensionMenuScreens . Screen ) CUSTOM_SCREEN_START ;
76+ nextScreen = ( AscensionMenuScreens . Screen ) ( CUSTOM_SCREEN_START + 1 ) ;
77+
78+ // Set the hover text of the challenge screen to be the title of the first custom screen
79+ challengeScreenHoverText = screens [ currentScreen ] . headerText ;
80+
81+ for ( int i = 0 ; i < screens . Count ; i ++ )
82+ {
83+ AscensionRunSetupScreenBase cur = screens [ currentScreen ] ;
84+
85+ string prevText = screens . ContainsKey ( previousScreen ) ? screens [ previousScreen ] . headerText : "SELECT CHALLENGES" ;
86+ string nextText = screens . ContainsKey ( nextScreen ) ? screens [ nextScreen ] . headerText : "START RUN" ;
87+
88+ Action < MainInputInteractable > prevHoverAction = ( MainInputInteractable i ) => cur . DisplayMessage ( Localization . ToUpper ( Localization . Translate ( prevText ) ) ) ;
89+ Action < MainInputInteractable > nextHoverAction = ( MainInputInteractable i ) => cur . DisplayMessage ( Localization . ToUpper ( Localization . Translate ( nextText ) ) ) ;
90+ Action < MainInputInteractable > unHoverAction = ( MainInputInteractable i ) => cur . ClearMessage ( ) ;
91+
92+ cur . backButton . CursorEntered = ( Action < MainInputInteractable > ) Delegate . Combine ( cur . backButton . CursorEntered , prevHoverAction ) ;
93+ cur . backButton . CursorExited = ( Action < MainInputInteractable > ) Delegate . Combine ( cur . backButton . CursorExited , unHoverAction ) ;
94+ cur . continueButton . CursorEntered = ( Action < MainInputInteractable > ) Delegate . Combine ( cur . continueButton . CursorEntered , nextHoverAction ) ;
95+ cur . continueButton . CursorExited = ( Action < MainInputInteractable > ) Delegate . Combine ( cur . continueButton . CursorExited , unHoverAction ) ;
96+
97+ previousScreen = currentScreen ;
98+ currentScreen = nextScreen ;
99+ nextScreen = ( AscensionMenuScreens . Screen ) ( ( int ) nextScreen + 1 ) ;
100+ }
101+ }
102+
103+ // This patches the confirmation button of the challenge screen to ensure it starts the queue
104+ [ HarmonyPatch ( typeof ( AscensionChallengeScreen ) , "OnContinuePressed" ) ]
105+ [ HarmonyPrefix ]
106+ public static bool TransitionToSideDeckScreen ( ref AscensionChallengeScreen __instance )
107+ {
108+ if ( screens == null || screens . Count == 0 )
109+ return true ; // No custom screens; execute the original method
110+
111+ AscensionMenuScreens . Instance . SwitchToScreen ( initialScreen ) ;
112+ return false ;
113+ }
114+
115+ [ HarmonyPatch ( typeof ( AscensionMenuScreens ) , "ScreenSwitchSequence" ) ]
116+ [ HarmonyPostfix ]
117+ public static IEnumerator SwitchToScreen ( IEnumerator sequenceEvent , AscensionMenuScreens . Screen screen )
118+ {
119+ while ( sequenceEvent . MoveNext ( ) )
120+ yield return sequenceEvent . Current ;
121+
122+ yield return new WaitForSeconds ( 0.05f ) ;
123+
124+ if ( AscensionScreenManager . screens . ContainsKey ( screen ) )
125+ AscensionScreenManager . screens [ screen ] . gameObject . SetActive ( true ) ;
126+
127+ yield break ;
128+ }
129+
130+ [ HarmonyPatch ( typeof ( AscensionMenuScreens ) , "ConfigurePostGameScreens" ) ]
131+ [ HarmonyPostfix ]
132+ public static void InitializeScreensOnStart ( )
133+ {
134+ InitializeAllScreens ( ) ;
135+ }
136+
137+ [ HarmonyPatch ( typeof ( AscensionMenuScreens ) , "DeactivateAllScreens" ) ]
138+ [ HarmonyPostfix ]
139+ public static void DeactivateAllCustomScreens ( )
140+ {
141+ if ( screens != null && screens . Count > 0 )
142+ foreach ( AscensionRunSetupScreenBase screenbase in screens . Values )
143+ if ( screenbase != null && screenbase . gameObject != null )
144+ screenbase . gameObject . SetActive ( false ) ;
145+ }
146+
147+ [ HarmonyPatch ( typeof ( AscensionChallengeScreen ) , "OnContinueCursorEnter" ) ]
148+ [ HarmonyPrefix ]
149+ public static bool HoverTextFirstCustomScreen ( ref AscensionChallengeScreen __instance )
150+ {
151+ string line = Localization . Translate ( challengeScreenHoverText ) ;
152+ __instance . challengeDisplayer . DisplayText ( "" , line , "" , false ) ;
153+ return false ;
154+ }
155+ }
156+ }
0 commit comments