Skip to content

Commit ee806af

Browse files
Merge branch 'challenges-ui-api-old' into challenges-ui-api
2 parents 49f6a64 + 5dad2f1 commit ee806af

12 files changed

Lines changed: 1290 additions & 0 deletions

InscryptionAPI/AscensionScreens/AscensionRunSetupScreenBase.cs

Lines changed: 437 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
using DiskCardGame;
2+
using HarmonyLib;
3+
using System;
4+
using UnityEngine;
5+
using System.Linq;
6+
using APIPlugin;
7+
using System.Collections.Generic;
8+
using GBC;
9+
using System.Collections;
10+
11+
namespace InscryptionAPI.AscensionScreens
12+
{
13+
[HarmonyPatch]
14+
public static class AscensionScreenManager
15+
{
16+
internal static List<Type> registeredScreens = new List<Type>();
17+
18+
internal static Dictionary<AscensionMenuScreens.Screen, AscensionRunSetupScreenBase> screens;
19+
20+
internal static AscensionMenuScreens.Screen initialScreen = AscensionMenuScreens.Screen.JournalSummary;
21+
22+
internal const int CUSTOM_SCREEN_START = 100;
23+
24+
private static string challengeScreenHoverText = "START RUN";
25+
26+
public static void AdvanceScreenQueue(bool forward=true)
27+
{
28+
29+
}
30+
31+
public static void RegisterScreen<T>() where T : AscensionRunSetupScreenBase
32+
{
33+
registeredScreens.Add(typeof(T));
34+
}
35+
36+
private static AscensionScreenSort.Direction GetPreferredDirection(Type t)
37+
{
38+
AscensionScreenSort sortAttr = Attribute.GetCustomAttribute(t, typeof(AscensionScreenSort)) as AscensionScreenSort;
39+
if (sortAttr == null)
40+
return AscensionScreenSort.Direction.NoPreference;
41+
else
42+
return sortAttr.preferredDirection;
43+
}
44+
45+
public static void InitializeAllScreens()
46+
{
47+
// Sort the screens
48+
registeredScreens.Sort((a, b) => (int)GetPreferredDirection(a) - (int)GetPreferredDirection(b));
49+
50+
// Build screens
51+
screens = new Dictionary<AscensionMenuScreens.Screen, AscensionRunSetupScreenBase>();
52+
53+
AscensionMenuScreens.Screen previousScreen = AscensionMenuScreens.Screen.SelectChallenges;
54+
AscensionMenuScreens.Screen currentScreen = (AscensionMenuScreens.Screen)CUSTOM_SCREEN_START;
55+
AscensionMenuScreens.Screen nextScreen = (AscensionMenuScreens.Screen)(CUSTOM_SCREEN_START + 1);
56+
initialScreen = currentScreen;
57+
for (int i = 0; i < registeredScreens.Count; i++)
58+
{
59+
Type screenType = registeredScreens[i];
60+
61+
if (i == registeredScreens.Count - 1) // the last one
62+
nextScreen = AscensionMenuScreens.Screen.SelectChallengesConfirm;
63+
64+
try
65+
{
66+
AscensionRunSetupScreenBase screen = AscensionRunSetupScreenBase.BuildScreen(screenType, previousScreen, nextScreen);
67+
68+
screens.Add(currentScreen, screen);
69+
70+
previousScreen = currentScreen;
71+
currentScreen = nextScreen;
72+
nextScreen = (AscensionMenuScreens.Screen)((int)nextScreen + 1);
73+
} catch (Exception ex)
74+
{
75+
Plugin.Log.LogError(ex);
76+
}
77+
}
78+
79+
if (screens.Count == 0)
80+
return;
81+
82+
// Now make another pass through the screens and set the behavior of hovering over the continue and back buttons
83+
84+
previousScreen = AscensionMenuScreens.Screen.SelectChallenges;
85+
currentScreen = (AscensionMenuScreens.Screen)CUSTOM_SCREEN_START;
86+
nextScreen = (AscensionMenuScreens.Screen)(CUSTOM_SCREEN_START + 1);
87+
88+
// Set the hover text of the challenge screen to be the title of the first custom screen
89+
challengeScreenHoverText = screens[currentScreen].headerText;
90+
91+
for (int i = 0; i < screens.Count; i++)
92+
{
93+
AscensionRunSetupScreenBase cur = screens[currentScreen];
94+
95+
string prevText = screens.ContainsKey(previousScreen) ? screens[previousScreen].headerText : "SELECT CHALLENGES";
96+
string nextText = screens.ContainsKey(nextScreen) ? screens[nextScreen].headerText : "START RUN";
97+
98+
Action<MainInputInteractable> prevHoverAction = (MainInputInteractable i) => cur.DisplayMessage(Localization.ToUpper(Localization.Translate(prevText)));
99+
Action<MainInputInteractable> nextHoverAction = (MainInputInteractable i) => cur.DisplayMessage(Localization.ToUpper(Localization.Translate(nextText)));
100+
Action<MainInputInteractable> unHoverAction = (MainInputInteractable i) => cur.ClearMessage();
101+
102+
cur.backButton.CursorEntered = (Action<MainInputInteractable>)Delegate.Combine(cur.backButton.CursorEntered, prevHoverAction);
103+
cur.backButton.CursorExited = (Action<MainInputInteractable>)Delegate.Combine(cur.backButton.CursorExited, unHoverAction);
104+
cur.continueButton.CursorEntered = (Action<MainInputInteractable>)Delegate.Combine(cur.continueButton.CursorEntered, nextHoverAction);
105+
cur.continueButton.CursorExited = (Action<MainInputInteractable>)Delegate.Combine(cur.continueButton.CursorExited, unHoverAction);
106+
107+
previousScreen = currentScreen;
108+
currentScreen = nextScreen;
109+
nextScreen = (AscensionMenuScreens.Screen)((int)nextScreen + 1);
110+
}
111+
}
112+
113+
// This patches the confirmation button of the challenge screen to ensure it starts the queue
114+
[HarmonyPatch(typeof(AscensionChallengeScreen), "OnContinuePressed")]
115+
[HarmonyPrefix]
116+
public static bool TransitionToSideDeckScreen(ref AscensionChallengeScreen __instance)
117+
{
118+
if (screens == null || screens.Count == 0)
119+
return true; // No custom screens; execute the original method
120+
121+
AscensionMenuScreens.Instance.SwitchToScreen(initialScreen);
122+
return false;
123+
}
124+
125+
[HarmonyPatch(typeof(AscensionMenuScreens), "ScreenSwitchSequence")]
126+
[HarmonyPostfix]
127+
public static IEnumerator SwitchToScreen(IEnumerator sequenceEvent, AscensionMenuScreens.Screen screen)
128+
{
129+
while (sequenceEvent.MoveNext())
130+
yield return sequenceEvent.Current;
131+
132+
yield return new WaitForSeconds(0.05f);
133+
134+
if (AscensionScreenManager.screens.ContainsKey(screen))
135+
AscensionScreenManager.screens[screen].gameObject.SetActive(true);
136+
137+
yield break;
138+
}
139+
140+
[HarmonyPatch(typeof(AscensionMenuScreens), "ConfigurePostGameScreens")]
141+
[HarmonyPostfix]
142+
public static void InitializeScreensOnStart()
143+
{
144+
InitializeAllScreens();
145+
}
146+
147+
[HarmonyPatch(typeof(AscensionMenuScreens), "DeactivateAllScreens")]
148+
[HarmonyPostfix]
149+
public static void DeactivateAllCustomScreens()
150+
{
151+
if (screens != null && screens.Count > 0)
152+
foreach (AscensionRunSetupScreenBase screenbase in screens.Values)
153+
if (screenbase != null && screenbase.gameObject != null)
154+
screenbase.gameObject.SetActive(false);
155+
}
156+
157+
[HarmonyPatch(typeof(AscensionChallengeScreen), "OnContinueCursorEnter")]
158+
[HarmonyPrefix]
159+
public static bool HoverTextFirstCustomScreen(ref AscensionChallengeScreen __instance)
160+
{
161+
string line = Localization.Translate(challengeScreenHoverText);
162+
__instance.challengeDisplayer.DisplayText("", line, "", false);
163+
return false;
164+
}
165+
}
166+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace InscryptionAPI.AscensionScreens
2+
{
3+
// Decorates a custom screen and marks how it should be sorted
4+
public class AscensionScreenSort : System.Attribute
5+
{
6+
public enum Direction : int
7+
{
8+
RequiresStart = 1,
9+
PrefersStart = 2,
10+
NoPreference = 3,
11+
PrefersEnd = 4,
12+
RequiresEnd = 5,
13+
}
14+
15+
public Direction preferredDirection;
16+
17+
public AscensionScreenSort(Direction preferredDirection = Direction.NoPreference)
18+
{
19+
this.preferredDirection = preferredDirection;
20+
}
21+
}
22+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using DiskCardGame;
2+
using System.Linq;
3+
using UnityEngine;
4+
using System.Collections.Generic;
5+
6+
namespace InscryptionAPI.Challenges
7+
{
8+
public class AscensionChallengePaginator : MonoBehaviour
9+
{
10+
public int challengePageIndex = 0;
11+
12+
public readonly static int CHALLENGES_PER_ROW = 7;
13+
14+
public List<AscensionChallengeInfo> availableChallenges;
15+
16+
public List<AscensionIconInteractable> topRow;
17+
18+
public List<AscensionIconInteractable> bottomRow;
19+
20+
public List<List<AscensionChallengeInfo>> pages = new();
21+
22+
public List<List<bool>> pageStates = new();
23+
24+
private void PageBuilder(List<AscensionChallengeInfo> challenges, int startIdx)
25+
{
26+
List<AscensionChallengeInfo> curPage = new List<AscensionChallengeInfo>();
27+
for (int i = startIdx; i < challenges.Count; i++)
28+
{
29+
// Check to see if we need a new page
30+
if (curPage.Count == 14)
31+
{
32+
pages.Add(curPage);
33+
curPage = new List<AscensionChallengeInfo>();
34+
}
35+
36+
// Check to see if we need a blank buffer
37+
// This happens if the next icon is the same as the current, and the
38+
// current icon would be on the bottom row
39+
if (i < challenges.Count - 1 && challenges[i + 1].challengeType == challenges[i].challengeType && curPage.Count % 2 == 1)
40+
curPage.Add(null);
41+
42+
curPage.Add(challenges[i]);
43+
}
44+
pages.Add(curPage);
45+
}
46+
47+
public void GeneratePages()
48+
{
49+
// The first page is nice and easy
50+
List<AscensionChallengeInfo> pageOne = new List<AscensionChallengeInfo>();
51+
pageOne.AddRange(availableChallenges.GetRange(0, 14));
52+
pages.Add(pageOne);
53+
54+
// Do the challenges first:
55+
List<AscensionChallengeInfo> challenges = availableChallenges.Where(i => i.pointValue > 0).ToList();
56+
List<AscensionChallengeInfo> assists = availableChallenges.Where(i => i.pointValue < 0).ToList();
57+
58+
// Do the challenges
59+
if (challenges.Count > 14)
60+
PageBuilder(challenges, 14);
61+
62+
if (assists.Count > 0)
63+
PageBuilder(assists, 0);
64+
65+
while (pageStates.Count < pages.Count)
66+
{
67+
pageStates.Add(new List<bool>());
68+
for (int i = 0; i < 14; i++)
69+
pageStates[pageStates.Count - 1].Add(false);
70+
}
71+
}
72+
73+
private void SavePageState()
74+
{
75+
for (int i = 0; i < 7; i++)
76+
{
77+
pageStates[challengePageIndex][i * 2] = topRow[i].activatedRenderer.enabled;
78+
pageStates[challengePageIndex][i * 2 + 1] = bottomRow[i].activatedRenderer.enabled;
79+
}
80+
}
81+
82+
public void ShowVisibleChallenges()
83+
{
84+
// Sort out which list of challenges are the visible ones
85+
List<AscensionChallengeInfo> visibleChallenges = pages[challengePageIndex];
86+
List<bool> selectedChallenges = pageStates[challengePageIndex];
87+
88+
// Make all challenge icons inactive
89+
foreach (AscensionIconInteractable icon in topRow.Concat(bottomRow))
90+
icon.gameObject.SetActive(false);
91+
92+
// Start going through and setting the icons
93+
for (int i = 0; i < visibleChallenges.Count; i++)
94+
{
95+
if (visibleChallenges[i] == null) // this is a spacer
96+
continue;
97+
AscensionIconInteractable targetIcon = (i % 2 == 0) ? this.topRow[i / 2] : this.bottomRow[i / 2];
98+
targetIcon.AssignInfo(visibleChallenges[i]);
99+
targetIcon.activatedRenderer.enabled = selectedChallenges[i];
100+
targetIcon.gameObject.SetActive(true);
101+
}
102+
}
103+
104+
public void ChallengePageLeft(MainInputInteractable button)
105+
{
106+
if (!AscensionMenuScreens.Instance.selectChallengesScreen.activeSelf)
107+
return;
108+
109+
if (challengePageIndex > 0)
110+
{
111+
SavePageState();
112+
challengePageIndex -= 1;
113+
ShowVisibleChallenges();
114+
}
115+
}
116+
117+
public void ChallengePageRight(MainInputInteractable button)
118+
{
119+
if (!AscensionMenuScreens.Instance.selectChallengesScreen.activeSelf)
120+
return;
121+
122+
if (challengePageIndex < pages.Count - 1)
123+
{
124+
SavePageState();
125+
challengePageIndex += 1;
126+
ShowVisibleChallenges();
127+
}
128+
}
129+
}
130+
}

0 commit comments

Comments
 (0)