Skip to content

Commit

Permalink
Main Menu Playlist Mode & Rate this level button (v1.1.3.0)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
trigger-segfault committed Jul 21, 2022
1 parent e9d0922 commit bec5a5c
Show file tree
Hide file tree
Showing 23 changed files with 873 additions and 111 deletions.
60 changes: 50 additions & 10 deletions Distance.LevelSelectAdditions/ConfigurationLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Distance.LevelSelectAdditions.Sorting;
using Reactor.API.Configuration;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

Expand Down Expand Up @@ -108,6 +107,49 @@ public bool EnableTheOtherSideSprintCampaign
set => Set(EnableTheOtherSideSprintCampaign_ID, value);
}


private const string EnableLevelSetOptionsMenu_ID = "levelsets.enable_levelsets_options_menu";
public bool EnableLevelSetOptionsMenu
{
get => Get<bool>(EnableLevelSetOptionsMenu_ID);
set => Set(EnableLevelSetOptionsMenu_ID, value);
}

private const string EnableChooseMainMenuQuickPlaylist_ID = "levelsets.enable_choose_mainmenu_quick_playlist";
public bool EnableChooseMainMenuQuickPlaylist
{
get => Get<bool>(EnableChooseMainMenuQuickPlaylist_ID);
set => Set(EnableChooseMainMenuQuickPlaylist_ID, value);
}

private const string EnableChooseMainMenuVisitWorkshopButton_ID = "gui.enable_choose_mainmenu_workshop_button";
public bool EnableChooseMainMenuVisitWorkshopButton
{
get => Get<bool>(EnableChooseMainMenuVisitWorkshopButton_ID);
set => Set(EnableChooseMainMenuVisitWorkshopButton_ID, value);
}

private const string EnableRateWorkshopLevelButton_ID = "gui.enable_rate_workshop_level_button";
public bool EnableRateWorkshopLevelButton
{
get => Get<bool>(EnableRateWorkshopLevelButton_ID);
set => Set(EnableRateWorkshopLevelButton_ID, value);
}

private const string HideChooseMainMenuUnusedButtons_ID = "gui.hide_choose_mainmenu_unused_buttons";
public bool HideChooseMainMenuUnusedButtons
{
get => Get<bool>(HideChooseMainMenuUnusedButtons_ID);
set => Set(HideChooseMainMenuUnusedButtons_ID, value);
}

/*private const string FixLevelSelectScrollBug_ID = "gui.fix_level_select_scroll_bug";
public bool FixLevelSelectScrollBug
{
get => Get<bool>(FixLevelSelectScrollBug_ID);
set => Set(FixLevelSelectScrollBug_ID, value);
}*/

/*private const string LevelSetSettingsTable_ID = "levelsets.options";
public Dictionary<LevelSelectMenuAbstract.DisplayType, Dictionary<GameModeID, string>> LevelSetSettingsTable
{
Expand All @@ -122,15 +164,6 @@ public bool EnableTheOtherSideSprintCampaign
set => Set(State_LastLevelSets_ID, value);
}

// No config option for these yet
public bool EnableLevelSetOptionsMenu => true;

public bool FixLevelSelectScrollBug => true;

public bool EnableChooseMainMenuVisitWorkshopButton => true;

public bool HideChooseMainMenuUnusedButtons => true;

#endregion

#region Helpers
Expand Down Expand Up @@ -244,6 +277,13 @@ public void Awake()
Get(WorkshopReverseSortingMethod3_ID, false);
Get(EnableTheOtherSideSprintCampaign_ID, false);

Get(EnableLevelSetOptionsMenu_ID, true);
Get(EnableChooseMainMenuQuickPlaylist_ID, true);
Get(EnableChooseMainMenuVisitWorkshopButton_ID, true);
Get(EnableRateWorkshopLevelButton_ID, true);
Get(HideChooseMainMenuUnusedButtons_ID, true);
//Get(FixLevelSelectScrollBug_ID, true); // Always enable this fix

// Save settings, and any defaults that may have been added.
Save();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
<Compile Include="Events\PlaylistFileDeleted.cs" />
<Compile Include="Events\PlaylistFileRenamed.cs" />
<Compile Include="Extensions\Assembly-CSharp\LevelPlaylist.cs" />
<Compile Include="Extensions\Assembly-CSharp\LevelSelectMenuLogic.cs" />
<Compile Include="Extensions\Assembly-CSharp\NGUIExtensions.cs" />
<Compile Include="Extensions\mscorlib\System\String.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelGridGrid\PushGrid.cs" />
Expand All @@ -106,15 +107,21 @@
<Compile Include="Harmony\Assembly-CSharp\LevelPlaylist\Save.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\ClearTempPlaylist.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\Initialize.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OnLevelButtonClicked.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OnLevelPlaylistMenuClickLoad.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OnLevelPlaylistMenuClickSave.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OnRateLevelPanelPop.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\OpenLevelPlaylistMenu.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\SetDisplayedInfoForSelectedLevel.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\SetupLevelPlaylistVisuals.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\Start.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\StartPlaylist.cs" />
<Compile Include="Harmony\Assembly-CSharp\LevelSelectMenuLogic\UpdateInput.cs" />
<Compile Include="Harmony\Assembly-CSharp\OptionsMenuLogic\GetSubmenus.cs" />
<Compile Include="Helpers\Sanitizer.cs" />
<Compile Include="Mod.cs" />
<Compile Include="Scripts\LevelPlaylistEntryUpdateLogic.cs" />
<Compile Include="Scripts\LevelSelectWorkshopRateButtonLogic.cs" />
<Compile Include="Scripts\Menus\LevelSetMenuType.cs" />
<Compile Include="Sorting\LevelFilter.cs" />
<Compile Include="Sorting\LevelSort.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public Data(string oldFilePath, string oldLevelSetID, string name)
{
this.filePath = oldFilePath;
this.levelSetID = oldLevelSetID;
this.name = oldLevelSetID;
this.name = name;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ namespace Distance.LevelSelectAdditions.Extensions
{
public static class LevelPlaylistExtensions
{
#region Constants

public static readonly Color BasePersonalColor = GConstants.myLevelColor_;

#endregion

#region Playlist Attributes

public static bool IsResourcesPlaylist(this LevelPlaylist playlist)
Expand Down Expand Up @@ -136,7 +142,7 @@ public static string GetLevelSetIDPrefix(string levelSetID)

#endregion

#region Display Name
#region Personal Display Name

public static string GetUncoloredName(this LevelPlaylist playlist)
{
Expand All @@ -150,7 +156,7 @@ public static bool GetColor(this LevelPlaylist playlist, out bool colorTag, out
bool hasColor = playlist.Name_.DecodeNGUIColor(out _, out colorTag, out color);
if (multiplyBaseColor && hasColor && !colorTag)
{
color *= GConstants.myLevelColor_;
color *= BasePersonalColor;
}
return hasColor;
}
Expand All @@ -161,7 +167,25 @@ public static bool GetNameAndColor(this LevelPlaylist playlist, out string name,
bool hasColor = playlist.Name_.DecodeNGUIColor(out name, out colorTag, out color);
if (multiplyBaseColor && hasColor && !colorTag)
{
color *= GConstants.myLevelColor_;
color *= BasePersonalColor;
}
return hasColor;
}

// 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).
// If alwaysUseBaseColor is true, then the base playlist color is always returned, even if the name is uncolored.
// (AKA `BasePersonalColor` will always be output if the `[c][/c]` tag is not used.)
// Returns true if the playlist name is colored.
public static bool GetBaseColor(this LevelPlaylist playlist, out Color baseColor, bool alwaysUseBaseColor)
{
bool hasColor = playlist.GetColor(out bool colorTag, out _, false);
if ((hasColor || alwaysUseBaseColor) && !colorTag)
{
baseColor = BasePersonalColor;
}
else
{
baseColor = Color.white; // Default color with `[c][/c]` tag, or when no color is used.
}
return hasColor;
}
Expand Down Expand Up @@ -230,11 +254,11 @@ public static bool Rename(this LevelPlaylist playlist, string newName, bool auto

if (hasColor && colorTag)
{
/*if (!hasSymbols && color.Color32Equals(GConstants.myLevelColor_))
/*if (!hasSymbols && color.Color32Equals(BasePersonalColor))
{
playlist.Name_ = newName;//.EncodeNGUIColorHex(Color.white); // [FFFFFF]{newName}[-]
}
else if (color.TryGetBaseColorFromMultiplier(GConstants.myLevelColor_, out Color baseColor))
else if (color.TryGetBaseColorFromMultiplier(BasePersonalColor, out Color baseColor))
{
// We can lose the color tag, because the current name color naturally supports the myLevelColor_ multiplier.
playlist.Name_ = newName.EncodeNGUIColorHex(baseColor); // [RRGGBB(AA)]{newName}[-]
Expand Down Expand Up @@ -295,22 +319,22 @@ public static bool Recolor(this LevelPlaylist playlist, Color? optNewColor, bool

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

Color newColor = (optNewColor ?? GConstants.myLevelColor_);
Color newColor = (optNewColor ?? BasePersonalColor);


// These bools state whether the new and old colors can support *not* using the [c] color tag.
Color oldBaseColor = oldColor;
bool useOldBase = !colorTag;
if (colorTag) // If color tag is used, then oldColor is not the baseColor
{
useOldBase = oldColor.TryGetBaseColorFromMultiplier(GConstants.myLevelColor_, out oldBaseColor);
useOldBase = oldColor.TryGetBaseColorFromMultiplier(BasePersonalColor, out oldBaseColor);
}
else
{
oldColor *= GConstants.myLevelColor_;
oldColor *= BasePersonalColor;
}
//bool useOldBase = oldColor.TryGetBaseColorFromMultiplier(GConstants.myLevelColor_, out Color oldBaseColor);
bool useNewBase = newColor.TryGetBaseColorFromMultiplier(GConstants.myLevelColor_, out Color newBaseColor);
//bool useOldBase = oldColor.TryGetBaseColorFromMultiplier(BasePersonalColor, out Color oldBaseColor);
bool useNewBase = newColor.TryGetBaseColorFromMultiplier(BasePersonalColor, out Color newBaseColor);


// If the user has put other formatting/color symbols inside the name,
Expand All @@ -327,7 +351,7 @@ public static bool Recolor(this LevelPlaylist playlist, Color? optNewColor, bool
// The above comparison needs to check `colorTag`, because the extracted color would be a base color otherwise.
// Normal color is the same, don't change anything.
}
else if (!optNewColor.HasValue || newColor.Color32Equals(GConstants.myLevelColor_))
else if (!optNewColor.HasValue || newColor.Color32Equals(BasePersonalColor))
{
if (hasSymbols && colorTag)
{
Expand Down Expand Up @@ -545,11 +569,11 @@ public static void PromptRecolor(this LevelPlaylist playlist, Action<bool> onSub
{
if (!playlist.GetColor(out bool colorTag, out Color color, true))
{
color = GConstants.myLevelColor_;
color = BasePersonalColor;
}
/*else if (!colorTag) // handled by true parameter
{
color *= GConstants.myLevelColor_;
color *= BasePersonalColor;
}*/

string hex = (color.a < 1f) ? NGUIText.EncodeColor32(color) : NGUIText.EncodeColor24(color);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Distance.LevelSelectAdditions.Scripts;
using System;
using UnityEngine;

namespace Distance.LevelSelectAdditions.Extensions
{
public static class LevelSelectMenuLogicExtensions
{
public static void UpdateQuickPlaylistText(this LevelSelectMenuLogic levelSelectMenu)
{
if (!levelSelectMenu.tempPlaylist_.Name_.IsEmptyPlaylistName())
{
levelSelectMenu.quickPlaylistLabel_.text = levelSelectMenu.tempPlaylist_.Name_; // Update the label showing the playlist name
}

// Preserve playlist name color (when not using `[c][/c] tag).
levelSelectMenu.tempPlaylist_.GetBaseColor(out Color baseColor, false);
levelSelectMenu.quickPlaylistLabel_.color = baseColor;
}

public static void UpdateBottomLeftButtonVisibility(this LevelSelectMenuLogic levelSelectMenu)
{
// Make sure to always display these buttons when in Playlist Mode.
if (Mod.Instance.Config.HideChooseMainMenuUnusedButtons && !levelSelectMenu.showingLevelPlaylist_)
{
// Hide unused buttons when in the Choose Main Menu display type.
bool isMainMenu = levelSelectMenu.displayType_ == LevelSelectMenuAbstract.DisplayType.ChooseMainMenuLevel;
levelSelectMenu.createPlaylistButton_.SetActive(!isMainMenu || Mod.Instance.Config.EnableChooseMainMenuQuickPlaylist);
levelSelectMenu.showLeaderboardsButton_.SetActive(!isMainMenu);
}
else
{
levelSelectMenu.createPlaylistButton_.SetActive(true);
levelSelectMenu.showLeaderboardsButton_.SetActive(true);
}
}

public static void ResetTempPlaylistState(this LevelSelectMenuLogic levelSelectMenu)
{
levelSelectMenu.tempPlaylist_.Name_ = nameof(LevelPlaylist); // restore default uninitialized name

var playlistData = levelSelectMenu.tempPlaylist_.GetComponent<LevelPlaylistCompoundData>();
if (playlistData)
{
playlistData.FilePath = null;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,9 @@ internal static void Postfix(LevelGridMenu.PlaylistEntry __instance, ref Color _
{
if (__instance.type_ == LevelGridMenu.PlaylistEntry.Type.Personal)
{
if (__instance.playlist_.GetColor(out bool colorTag, out _, false))
if (__instance.playlist_.GetBaseColor(out Color baseColor, false))
{
if (colorTag)
{
// Otherwise we'll return the normal color, which is multiplied against the base color tags.
// This will keep color tags used without this mod consistent.
__result = Color.white;
}
else
{
// Color functions in vanilla by multiplying against the personal playlist color.
__result = GConstants.myLevelColor_;
}
__result = baseColor;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
using Distance.LevelSelectAdditions.Scripts;
using Distance.LevelSelectAdditions.Extensions;
using HarmonyLib;

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

var playlistData = __instance.tempPlaylist_.GetComponent<LevelPlaylistCompoundData>();
if (playlistData)
{
playlistData.FilePath = null;
}
// We're exiting Playlist Mode, so we need to re-evaluate bottom left button visibility.
__instance.UpdateBottomLeftButtonVisibility();
}
}
}
Loading

0 comments on commit bec5a5c

Please sign in to comment.