Skip to content

Commit bec5a5c

Browse files
Main Menu Playlist Mode & Rate this level button (v1.1.3.0)
Refactors: * Moved some common duplicate code to new extensions class for LevelSelectMenuLogic. * Cleaned up base color handling for Personal playlists to reference a single readonly field. Also added `GetBaseColor` for use outside of the extensions class. * Moved where LevelPlaylistCompoundData was created for LevelSelectMenuLogic's tempPlaylist, so that it's done right after the tempPlaylist is created. Fixes: * Fixed PlaylistFileDeleted event assigning wrong value to name field (field is currently unused, so no functional difference). * Fixed LevelSelectMenuLogic's tempPlaylist state so that it'll always be reset when entering the Playlist Mode menu. * Also fixed the file name input field for saving/loading in Playlist Mode, so that the field doesn't remember *echoes of a past playlsit*. New Options: * Finally added options for previously always-on settings: * Enable Playlist Options menu * Enable *Visit Workshop page* button for Main Menus * Enable Playlist Mode when in the Choose Main Menu display type. * Re-introduce the *Rate this level* button in the Advanced level select menu. * Hide unused buttons in the Advanced level select menu for the Choose Main Menu display type.
1 parent e9d0922 commit bec5a5c

23 files changed

+873
-111
lines changed

Distance.LevelSelectAdditions/ConfigurationLogic.cs

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using Distance.LevelSelectAdditions.Sorting;
33
using Reactor.API.Configuration;
44
using System;
5-
using System.Collections;
65
using System.Collections.Generic;
76
using UnityEngine;
87

@@ -108,6 +107,49 @@ public bool EnableTheOtherSideSprintCampaign
108107
set => Set(EnableTheOtherSideSprintCampaign_ID, value);
109108
}
110109

110+
111+
private const string EnableLevelSetOptionsMenu_ID = "levelsets.enable_levelsets_options_menu";
112+
public bool EnableLevelSetOptionsMenu
113+
{
114+
get => Get<bool>(EnableLevelSetOptionsMenu_ID);
115+
set => Set(EnableLevelSetOptionsMenu_ID, value);
116+
}
117+
118+
private const string EnableChooseMainMenuQuickPlaylist_ID = "levelsets.enable_choose_mainmenu_quick_playlist";
119+
public bool EnableChooseMainMenuQuickPlaylist
120+
{
121+
get => Get<bool>(EnableChooseMainMenuQuickPlaylist_ID);
122+
set => Set(EnableChooseMainMenuQuickPlaylist_ID, value);
123+
}
124+
125+
private const string EnableChooseMainMenuVisitWorkshopButton_ID = "gui.enable_choose_mainmenu_workshop_button";
126+
public bool EnableChooseMainMenuVisitWorkshopButton
127+
{
128+
get => Get<bool>(EnableChooseMainMenuVisitWorkshopButton_ID);
129+
set => Set(EnableChooseMainMenuVisitWorkshopButton_ID, value);
130+
}
131+
132+
private const string EnableRateWorkshopLevelButton_ID = "gui.enable_rate_workshop_level_button";
133+
public bool EnableRateWorkshopLevelButton
134+
{
135+
get => Get<bool>(EnableRateWorkshopLevelButton_ID);
136+
set => Set(EnableRateWorkshopLevelButton_ID, value);
137+
}
138+
139+
private const string HideChooseMainMenuUnusedButtons_ID = "gui.hide_choose_mainmenu_unused_buttons";
140+
public bool HideChooseMainMenuUnusedButtons
141+
{
142+
get => Get<bool>(HideChooseMainMenuUnusedButtons_ID);
143+
set => Set(HideChooseMainMenuUnusedButtons_ID, value);
144+
}
145+
146+
/*private const string FixLevelSelectScrollBug_ID = "gui.fix_level_select_scroll_bug";
147+
public bool FixLevelSelectScrollBug
148+
{
149+
get => Get<bool>(FixLevelSelectScrollBug_ID);
150+
set => Set(FixLevelSelectScrollBug_ID, value);
151+
}*/
152+
111153
/*private const string LevelSetSettingsTable_ID = "levelsets.options";
112154
public Dictionary<LevelSelectMenuAbstract.DisplayType, Dictionary<GameModeID, string>> LevelSetSettingsTable
113155
{
@@ -122,15 +164,6 @@ public bool EnableTheOtherSideSprintCampaign
122164
set => Set(State_LastLevelSets_ID, value);
123165
}
124166

125-
// No config option for these yet
126-
public bool EnableLevelSetOptionsMenu => true;
127-
128-
public bool FixLevelSelectScrollBug => true;
129-
130-
public bool EnableChooseMainMenuVisitWorkshopButton => true;
131-
132-
public bool HideChooseMainMenuUnusedButtons => true;
133-
134167
#endregion
135168

136169
#region Helpers
@@ -244,6 +277,13 @@ public void Awake()
244277
Get(WorkshopReverseSortingMethod3_ID, false);
245278
Get(EnableTheOtherSideSprintCampaign_ID, false);
246279

280+
Get(EnableLevelSetOptionsMenu_ID, true);
281+
Get(EnableChooseMainMenuQuickPlaylist_ID, true);
282+
Get(EnableChooseMainMenuVisitWorkshopButton_ID, true);
283+
Get(EnableRateWorkshopLevelButton_ID, true);
284+
Get(HideChooseMainMenuUnusedButtons_ID, true);
285+
//Get(FixLevelSelectScrollBug_ID, true); // Always enable this fix
286+
247287
// Save settings, and any defaults that may have been added.
248288
Save();
249289
}

Distance.LevelSelectAdditions/Distance.LevelSelectAdditions.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
<Compile Include="Events\PlaylistFileDeleted.cs" />
9393
<Compile Include="Events\PlaylistFileRenamed.cs" />
9494
<Compile Include="Extensions\Assembly-CSharp\LevelPlaylist.cs" />
95+
<Compile Include="Extensions\Assembly-CSharp\LevelSelectMenuLogic.cs" />
9596
<Compile Include="Extensions\Assembly-CSharp\NGUIExtensions.cs" />
9697
<Compile Include="Extensions\mscorlib\System\String.cs" />
9798
<Compile Include="Harmony\Assembly-CSharp\LevelGridGrid\PushGrid.cs" />
@@ -106,15 +107,21 @@
106107
<Compile Include="Harmony\Assembly-CSharp\LevelPlaylist\Save.cs" />
107108
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\ClearTempPlaylist.cs" />
108109
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\Initialize.cs" />
110+
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OnLevelButtonClicked.cs" />
109111
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OnLevelPlaylistMenuClickLoad.cs" />
110112
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OnLevelPlaylistMenuClickSave.cs" />
113+
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OnRateLevelPanelPop.cs" />
114+
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OpenLevelPlaylistMenu.cs" />
111115
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\SetDisplayedInfoForSelectedLevel.cs" />
112116
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\SetupLevelPlaylistVisuals.cs" />
113117
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\Start.cs" />
118+
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\StartPlaylist.cs" />
119+
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\UpdateInput.cs" />
114120
<Compile Include="Harmony\Assembly-CSharp\OptionsMenuLogic\GetSubmenus.cs" />
115121
<Compile Include="Helpers\Sanitizer.cs" />
116122
<Compile Include="Mod.cs" />
117123
<Compile Include="Scripts\LevelPlaylistEntryUpdateLogic.cs" />
124+
<Compile Include="Scripts\LevelSelectWorkshopRateButtonLogic.cs" />
118125
<Compile Include="Scripts\Menus\LevelSetMenuType.cs" />
119126
<Compile Include="Sorting\LevelFilter.cs" />
120127
<Compile Include="Sorting\LevelSort.cs" />

Distance.LevelSelectAdditions/Events/PlaylistFileDeleted.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public Data(string oldFilePath, string oldLevelSetID, string name)
1616
{
1717
this.filePath = oldFilePath;
1818
this.levelSetID = oldLevelSetID;
19-
this.name = oldLevelSetID;
19+
this.name = name;
2020
}
2121
}
2222
}

Distance.LevelSelectAdditions/Extensions/Assembly-CSharp/LevelPlaylist.cs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ namespace Distance.LevelSelectAdditions.Extensions
1212
{
1313
public static class LevelPlaylistExtensions
1414
{
15+
#region Constants
16+
17+
public static readonly Color BasePersonalColor = GConstants.myLevelColor_;
18+
19+
#endregion
20+
1521
#region Playlist Attributes
1622

1723
public static bool IsResourcesPlaylist(this LevelPlaylist playlist)
@@ -136,7 +142,7 @@ public static string GetLevelSetIDPrefix(string levelSetID)
136142

137143
#endregion
138144

139-
#region Display Name
145+
#region Personal Display Name
140146

141147
public static string GetUncoloredName(this LevelPlaylist playlist)
142148
{
@@ -150,7 +156,7 @@ public static bool GetColor(this LevelPlaylist playlist, out bool colorTag, out
150156
bool hasColor = playlist.Name_.DecodeNGUIColor(out _, out colorTag, out color);
151157
if (multiplyBaseColor && hasColor && !colorTag)
152158
{
153-
color *= GConstants.myLevelColor_;
159+
color *= BasePersonalColor;
154160
}
155161
return hasColor;
156162
}
@@ -161,7 +167,25 @@ public static bool GetNameAndColor(this LevelPlaylist playlist, out string name,
161167
bool hasColor = playlist.Name_.DecodeNGUIColor(out name, out colorTag, out color);
162168
if (multiplyBaseColor && hasColor && !colorTag)
163169
{
164-
color *= GConstants.myLevelColor_;
170+
color *= BasePersonalColor;
171+
}
172+
return hasColor;
173+
}
174+
175+
// Gets the base color to use for the label (this base color is used to preserve vanilla playlist colors that don't use the `[c][/c]` tag).
176+
// If alwaysUseBaseColor is true, then the base playlist color is always returned, even if the name is uncolored.
177+
// (AKA `BasePersonalColor` will always be output if the `[c][/c]` tag is not used.)
178+
// Returns true if the playlist name is colored.
179+
public static bool GetBaseColor(this LevelPlaylist playlist, out Color baseColor, bool alwaysUseBaseColor)
180+
{
181+
bool hasColor = playlist.GetColor(out bool colorTag, out _, false);
182+
if ((hasColor || alwaysUseBaseColor) && !colorTag)
183+
{
184+
baseColor = BasePersonalColor;
185+
}
186+
else
187+
{
188+
baseColor = Color.white; // Default color with `[c][/c]` tag, or when no color is used.
165189
}
166190
return hasColor;
167191
}
@@ -230,11 +254,11 @@ public static bool Rename(this LevelPlaylist playlist, string newName, bool auto
230254

231255
if (hasColor && colorTag)
232256
{
233-
/*if (!hasSymbols && color.Color32Equals(GConstants.myLevelColor_))
257+
/*if (!hasSymbols && color.Color32Equals(BasePersonalColor))
234258
{
235259
playlist.Name_ = newName;//.EncodeNGUIColorHex(Color.white); // [FFFFFF]{newName}[-]
236260
}
237-
else if (color.TryGetBaseColorFromMultiplier(GConstants.myLevelColor_, out Color baseColor))
261+
else if (color.TryGetBaseColorFromMultiplier(BasePersonalColor, out Color baseColor))
238262
{
239263
// We can lose the color tag, because the current name color naturally supports the myLevelColor_ multiplier.
240264
playlist.Name_ = newName.EncodeNGUIColorHex(baseColor); // [RRGGBB(AA)]{newName}[-]
@@ -295,22 +319,22 @@ public static bool Recolor(this LevelPlaylist playlist, Color? optNewColor, bool
295319

296320
bool hasColor = playlist.GetNameAndColor(out string name, out bool colorTag, out Color oldColor, false);
297321

298-
Color newColor = (optNewColor ?? GConstants.myLevelColor_);
322+
Color newColor = (optNewColor ?? BasePersonalColor);
299323

300324

301325
// These bools state whether the new and old colors can support *not* using the [c] color tag.
302326
Color oldBaseColor = oldColor;
303327
bool useOldBase = !colorTag;
304328
if (colorTag) // If color tag is used, then oldColor is not the baseColor
305329
{
306-
useOldBase = oldColor.TryGetBaseColorFromMultiplier(GConstants.myLevelColor_, out oldBaseColor);
330+
useOldBase = oldColor.TryGetBaseColorFromMultiplier(BasePersonalColor, out oldBaseColor);
307331
}
308332
else
309333
{
310-
oldColor *= GConstants.myLevelColor_;
334+
oldColor *= BasePersonalColor;
311335
}
312-
//bool useOldBase = oldColor.TryGetBaseColorFromMultiplier(GConstants.myLevelColor_, out Color oldBaseColor);
313-
bool useNewBase = newColor.TryGetBaseColorFromMultiplier(GConstants.myLevelColor_, out Color newBaseColor);
336+
//bool useOldBase = oldColor.TryGetBaseColorFromMultiplier(BasePersonalColor, out Color oldBaseColor);
337+
bool useNewBase = newColor.TryGetBaseColorFromMultiplier(BasePersonalColor, out Color newBaseColor);
314338

315339

316340
// If the user has put other formatting/color symbols inside the name,
@@ -327,7 +351,7 @@ public static bool Recolor(this LevelPlaylist playlist, Color? optNewColor, bool
327351
// The above comparison needs to check `colorTag`, because the extracted color would be a base color otherwise.
328352
// Normal color is the same, don't change anything.
329353
}
330-
else if (!optNewColor.HasValue || newColor.Color32Equals(GConstants.myLevelColor_))
354+
else if (!optNewColor.HasValue || newColor.Color32Equals(BasePersonalColor))
331355
{
332356
if (hasSymbols && colorTag)
333357
{
@@ -545,11 +569,11 @@ public static void PromptRecolor(this LevelPlaylist playlist, Action<bool> onSub
545569
{
546570
if (!playlist.GetColor(out bool colorTag, out Color color, true))
547571
{
548-
color = GConstants.myLevelColor_;
572+
color = BasePersonalColor;
549573
}
550574
/*else if (!colorTag) // handled by true parameter
551575
{
552-
color *= GConstants.myLevelColor_;
576+
color *= BasePersonalColor;
553577
}*/
554578

555579
string hex = (color.a < 1f) ? NGUIText.EncodeColor32(color) : NGUIText.EncodeColor24(color);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Distance.LevelSelectAdditions.Scripts;
2+
using System;
3+
using UnityEngine;
4+
5+
namespace Distance.LevelSelectAdditions.Extensions
6+
{
7+
public static class LevelSelectMenuLogicExtensions
8+
{
9+
public static void UpdateQuickPlaylistText(this LevelSelectMenuLogic levelSelectMenu)
10+
{
11+
if (!levelSelectMenu.tempPlaylist_.Name_.IsEmptyPlaylistName())
12+
{
13+
levelSelectMenu.quickPlaylistLabel_.text = levelSelectMenu.tempPlaylist_.Name_; // Update the label showing the playlist name
14+
}
15+
16+
// Preserve playlist name color (when not using `[c][/c] tag).
17+
levelSelectMenu.tempPlaylist_.GetBaseColor(out Color baseColor, false);
18+
levelSelectMenu.quickPlaylistLabel_.color = baseColor;
19+
}
20+
21+
public static void UpdateBottomLeftButtonVisibility(this LevelSelectMenuLogic levelSelectMenu)
22+
{
23+
// Make sure to always display these buttons when in Playlist Mode.
24+
if (Mod.Instance.Config.HideChooseMainMenuUnusedButtons && !levelSelectMenu.showingLevelPlaylist_)
25+
{
26+
// Hide unused buttons when in the Choose Main Menu display type.
27+
bool isMainMenu = levelSelectMenu.displayType_ == LevelSelectMenuAbstract.DisplayType.ChooseMainMenuLevel;
28+
levelSelectMenu.createPlaylistButton_.SetActive(!isMainMenu || Mod.Instance.Config.EnableChooseMainMenuQuickPlaylist);
29+
levelSelectMenu.showLeaderboardsButton_.SetActive(!isMainMenu);
30+
}
31+
else
32+
{
33+
levelSelectMenu.createPlaylistButton_.SetActive(true);
34+
levelSelectMenu.showLeaderboardsButton_.SetActive(true);
35+
}
36+
}
37+
38+
public static void ResetTempPlaylistState(this LevelSelectMenuLogic levelSelectMenu)
39+
{
40+
levelSelectMenu.tempPlaylist_.Name_ = nameof(LevelPlaylist); // restore default uninitialized name
41+
42+
var playlistData = levelSelectMenu.tempPlaylist_.GetComponent<LevelPlaylistCompoundData>();
43+
if (playlistData)
44+
{
45+
playlistData.FilePath = null;
46+
}
47+
}
48+
}
49+
}

Distance.LevelSelectAdditions/Harmony/Assembly-CSharp/LevelGridMenu/PlaylistEntry/get_Color_.cs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,9 @@ internal static void Postfix(LevelGridMenu.PlaylistEntry __instance, ref Color _
2121
{
2222
if (__instance.type_ == LevelGridMenu.PlaylistEntry.Type.Personal)
2323
{
24-
if (__instance.playlist_.GetColor(out bool colorTag, out _, false))
24+
if (__instance.playlist_.GetBaseColor(out Color baseColor, false))
2525
{
26-
if (colorTag)
27-
{
28-
// Otherwise we'll return the normal color, which is multiplied against the base color tags.
29-
// This will keep color tags used without this mod consistent.
30-
__result = Color.white;
31-
}
32-
else
33-
{
34-
// Color functions in vanilla by multiplying against the personal playlist color.
35-
__result = GConstants.myLevelColor_;
36-
}
26+
__result = baseColor;
3727
}
3828
}
3929
}
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1-
using Distance.LevelSelectAdditions.Scripts;
1+
using Distance.LevelSelectAdditions.Extensions;
22
using HarmonyLib;
33

44
namespace Distance.LevelSelectAdditions.Harmony
55
{
66
/// <summary>
77
/// Patch to stop tempPlaylist_ from preserving its previous name. This can effect using the Rename button,
88
/// as well as the initial "QUICK PLAYLIST..." text due to the SetupLevelPlaylistVisuals patch.
9+
/// <para/>
10+
/// Also includes patch to hide unused Leaderboards (and optionally Playlist Mode) buttons when in the Choose Main Menu display type.
911
/// </summary>
1012
[HarmonyPatch(typeof(LevelSelectMenuLogic), nameof(LevelSelectMenuLogic.ClearTempPlaylist))]
1113
internal static class LevelSelectMenuLogic__ClearTempPlaylist
1214
{
1315
[HarmonyPostfix]
1416
internal static void Postfix(LevelSelectMenuLogic __instance)
1517
{
16-
__instance.tempPlaylist_.Name_ = nameof(LevelPlaylist); // restore default uninitialized name
18+
__instance.ResetTempPlaylistState();
1719

18-
var playlistData = __instance.tempPlaylist_.GetComponent<LevelPlaylistCompoundData>();
19-
if (playlistData)
20-
{
21-
playlistData.FilePath = null;
22-
}
20+
// We're exiting Playlist Mode, so we need to re-evaluate bottom left button visibility.
21+
__instance.UpdateBottomLeftButtonVisibility();
2322
}
2423
}
2524
}

0 commit comments

Comments
 (0)