Skip to content

Commit f8a8021

Browse files
Initial codebase commit (v1.0.0.0)
Initial codebase commit with original working goal for the mod: * Support for changing Workshop LevelSet. * Remove or change level limit. * Optionally filter out levels in personal playlists. * Up to 3 layers of sorting methods with option to reverse individual methods.
1 parent 10e25ec commit f8a8021

File tree

19 files changed

+1122
-197
lines changed

19 files changed

+1122
-197
lines changed

.env

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
SOLUTION=Mod.Template.sln
2-
ARTIFACTS=Build/Distance Mod Template.zip
3-
RELEASE_BODY=This release was automatically generated as part of a GitHub workflow. Please read the repository README for more info.
1+
SOLUTION=Distance.LevelSelectAdditions.sln
2+
ARTIFACTS=Build/Distance Level Select Additions.zip
3+
RELEASE_BODY=This release was automatically generated as part of a GitHub workflow. Please read the repository README for more info.
4+
5+

Mod.Template.Content/Mod.Template.Content.projitems renamed to Distance.LevelSelectAdditions.Content/Distance.LevelSelectAdditions.Content.projitems

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<SharedGUID>4e7d37c7-8afe-4f79-baf6-4ce82d05e091</SharedGUID>
77
</PropertyGroup>
88
<PropertyGroup Label="Configuration">
9-
<Import_RootNamespace>Mod.Template.Content</Import_RootNamespace>
9+
<Import_RootNamespace>Distance.LevelSelectAdditions.Content</Import_RootNamespace>
1010
</PropertyGroup>
1111
<ItemGroup>
1212
<Content Include="$(MSBuildThisFileDirectory)Mod\mod.json">
@@ -16,4 +16,6 @@
1616
<ItemGroup>
1717
<Folder Include="$(MSBuildThisFileDirectory)Mod\" />
1818
</ItemGroup>
19-
</Project>
19+
</Project>
20+
21+

Mod.Template.Content/Mod.Template.Content.shproj renamed to Distance.LevelSelectAdditions.Content/Distance.LevelSelectAdditions.Content.shproj

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="UTF-8"?>
1+
<?xml version="1.0" encoding="UTF-8"?>
22
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
33
<PropertyGroup Label="Globals">
44
<ProjectGuid>4e7d37c7-8afe-4f79-baf6-4ce82d05e091</ProjectGuid>
@@ -8,6 +8,8 @@
88
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
99
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
1010
<PropertyGroup />
11-
<Import Project="Mod.Template.Content.projitems" Label="Shared" />
11+
<Import Project="Distance.LevelSelectAdditions.Content.projitems" Label="Shared" />
1212
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
13-
</Project>
13+
</Project>
14+
15+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"FriendlyName": "Level Select Additions",
3+
"Description": "Extends the level selection UI by adding more options.",
4+
"Author": "trigger_segfault",
5+
"Contact": "Github: @trigger-segfault; Discord: trigger_segfault#7281",
6+
"ModuleFileName": "Distance.LevelSelectAdditions.dll",
7+
"RequiredGSLs": [
8+
"com.github.reherc/Centrifuge.Distance"
9+
],
10+
"SkipLoad": false,
11+
"Priority": 10
12+
}
13+
14+
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 16
44
VisualStudioVersion = 16.0.31515.178
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Mod.Template.Content", "Mod.Template.Content\Mod.Template.Content.shproj", "{4E7D37C7-8AFE-4F79-BAF6-4CE82D05E091}"
6+
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Distance.LevelSelectAdditions.Content", "Distance.LevelSelectAdditions.Content\Distance.LevelSelectAdditions.Content.shproj", "{4E7D37C7-8AFE-4F79-BAF6-4CE82D05E091}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mod.Template", "Mod.Template\Mod.Template.csproj", "{7BCB2908-B003-45D9-BE68-50CBA5217603}"
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Distance.LevelSelectAdditions", "Distance.LevelSelectAdditions\Distance.LevelSelectAdditions.csproj", "{7BCB2908-B003-45D9-BE68-50CBA5217603}"
99
EndProject
1010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{08A1C9FA-7DC2-4A60-B9A6-AC0EB7132893}"
1111
ProjectSection(SolutionItems) = preProject
@@ -17,7 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1717
EndProject
1818
Global
1919
GlobalSection(SharedMSBuildProjectFiles) = preSolution
20-
Mod.Template.Content\Mod.Template.Content.projitems*{4e7d37c7-8afe-4f79-baf6-4ce82d05e091}*SharedItemsImports = 13
20+
Distance.LevelSelectAdditions.Content\Distance.LevelSelectAdditions.Content.projitems*{4e7d37c7-8afe-4f79-baf6-4ce82d05e091}*SharedItemsImports = 13
2121
EndGlobalSection
2222
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2323
Debug|Any CPU = Debug|Any CPU
@@ -36,3 +36,6 @@ Global
3636
SolutionGuid = {E6970D48-CD23-4427-951B-448B144F30DA}
3737
EndGlobalSection
3838
EndGlobal
39+
40+
41+
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
using Reactor.API.Configuration;
2+
using System;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using UnityEngine;
6+
7+
using SortingMethod = LevelSelectMenuLogic.SortingMethod;
8+
9+
namespace Distance.LevelSelectAdditions
10+
{
11+
public class ConfigurationLogic : MonoBehaviour
12+
{
13+
#region Properties
14+
15+
private const string HideWorkshopLevelsInPlaylists_ID = "workshop.hide_levels_in_playlists";
16+
public bool HideWorkshopLevelsInPlaylists
17+
{
18+
get => Get<bool>(HideWorkshopLevelsInPlaylists_ID);
19+
set => Set(HideWorkshopLevelsInPlaylists_ID, value);
20+
}
21+
22+
private const string WorkshopLevelLimit_ID = "workshop.level_limit";
23+
public int WorkshopLevelLimit
24+
{
25+
get => Get<int>(WorkshopLevelLimit_ID);
26+
set => Set(WorkshopLevelLimit_ID, value);
27+
}
28+
29+
private const string WorkshopSortingMethod_ID = "workshop.sorting_method";
30+
public SortingMethod WorkshopSortingMethod
31+
{
32+
get => Get<SortingMethod>(WorkshopSortingMethod_ID);
33+
set => Set(WorkshopSortingMethod_ID, value);
34+
}
35+
36+
private const string WorkshopSortingMethod2_ID = "workshop.sorting_method2";
37+
public SortingMethod WorkshopSortingMethod2
38+
{
39+
get => Get<SortingMethod>(WorkshopSortingMethod2_ID);
40+
set => Set(WorkshopSortingMethod2_ID, value);
41+
}
42+
43+
private const string WorkshopSortingMethod3_ID = "workshop.sorting_method3";
44+
public SortingMethod WorkshopSortingMethod3
45+
{
46+
get => Get<SortingMethod>(WorkshopSortingMethod3_ID);
47+
set => Set(WorkshopSortingMethod3_ID, value);
48+
}
49+
50+
private const string WorkshopReverseSortingMethod_ID = "workshop.reverse_sorting_method";
51+
public bool WorkshopReverseSortingMethod
52+
{
53+
get => Get<bool>(WorkshopReverseSortingMethod_ID);
54+
set => Set(WorkshopReverseSortingMethod_ID, value);
55+
}
56+
57+
private const string WorkshopReverseSortingMethod2_ID = "workshop.reverse_sorting_method2";
58+
public bool WorkshopReverseSortingMethod2
59+
{
60+
get => Get<bool>(WorkshopReverseSortingMethod2_ID);
61+
set => Set(WorkshopReverseSortingMethod2_ID, value);
62+
}
63+
64+
private const string WorkshopReverseSortingMethod3_ID = "workshop.reverse_sorting_method3";
65+
public bool WorkshopReverseSortingMethod3
66+
{
67+
get => Get<bool>(WorkshopReverseSortingMethod3_ID);
68+
set => Set(WorkshopReverseSortingMethod3_ID, value);
69+
}
70+
71+
// Future plans:
72+
/*private const string EnableRecentlDownloadsLevelSet_ID = "recentdownloads.enable";
73+
public bool EnableRecentlDownloadsLevelSet
74+
{
75+
get => Get<bool>(EnableRecentlDownloadsLevelSet_ID);
76+
set => Set(EnableRecentlDownloadsLevelSet_ID, value);
77+
}
78+
79+
private const string RecentDownloadedsTimeInDays_ID = "recentdownloads.time_in_days";
80+
public double RecentDownloadedsTimeInDays
81+
{
82+
get => Get<double>(RecentDownloadedsTimeInDays_ID);
83+
set => Set(RecentDownloadedsTimeInDays_ID, value);
84+
}
85+
86+
private const string HideRecentDownloadsLevelsInPlaylists_ID = "recentdownloads.hide_levels_in_playlists";
87+
public bool HideRecentDownloadsLevelsInPlaylists
88+
{
89+
get => Get<bool>(HideRecentDownloadsLevelsInPlaylists_ID);
90+
set => Set(HideRecentDownloadsLevelsInPlaylists_ID, value);
91+
}
92+
93+
private const string RecentDownloadsLevelLimit_ID = "recentdownloads.level_limit";
94+
public int RecentDownloadsLevelLimit
95+
{
96+
get => Get<int>(RecentDownloadsLevelLimit_ID);
97+
set => Set(RecentDownloadsLevelLimit_ID, value);
98+
}*/
99+
100+
#endregion
101+
102+
#region Helpers
103+
104+
public SortingMethod[] GetWorkshopSortingMethods()
105+
{
106+
return new SortingMethod[]
107+
{
108+
WorkshopSortingMethod,
109+
WorkshopSortingMethod2,
110+
WorkshopSortingMethod3,
111+
};
112+
}
113+
public bool[] GetWorkshopReverseSortingMethods()
114+
{
115+
return new bool[]
116+
{
117+
WorkshopReverseSortingMethod,
118+
WorkshopReverseSortingMethod2,
119+
WorkshopReverseSortingMethod3,
120+
};
121+
}
122+
123+
#endregion
124+
125+
internal Settings Config;
126+
127+
public event Action<ConfigurationLogic> OnChanged;
128+
129+
private void Load()
130+
{
131+
Config = new Settings("Config");// Mod.FullName);
132+
}
133+
134+
public void Awake()
135+
{
136+
Load();
137+
138+
// Assign default settings (if not already assigned).
139+
Get(HideWorkshopLevelsInPlaylists_ID, false);
140+
Get(WorkshopLevelLimit_ID, 1000);
141+
Get(WorkshopSortingMethod_ID, LevelSort.Recently_Downloaded);
142+
Get(WorkshopSortingMethod2_ID, LevelSort.None);
143+
Get(WorkshopSortingMethod3_ID, LevelSort.None);
144+
Get(WorkshopReverseSortingMethod_ID, false);
145+
Get(WorkshopReverseSortingMethod2_ID, false);
146+
Get(WorkshopReverseSortingMethod3_ID, false);
147+
148+
// Save settings, and any defaults that may have been added.
149+
Save();
150+
}
151+
152+
public T Get<T>(string key, T @default = default)
153+
{
154+
return Config.GetOrCreate(key, @default);
155+
}
156+
157+
public void Set<T>(string key, T value)
158+
{
159+
Config[key] = value;
160+
Save();
161+
}
162+
163+
public void Save()
164+
{
165+
Config?.Save();
166+
OnChanged?.Invoke(this);
167+
}
168+
}
169+
}

Mod.Template/Mod.Template.csproj renamed to Distance.LevelSelectAdditions/Distance.LevelSelectAdditions.csproj

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<ProjectGuid>{7BCB2908-B003-45D9-BE68-50CBA5217603}</ProjectGuid>
88
<OutputType>Library</OutputType>
99
<AppDesignerFolder>Properties</AppDesignerFolder>
10-
<RootNamespace>Mod.Template</RootNamespace>
11-
<AssemblyName>Mod.Template</AssemblyName>
10+
<RootNamespace>Distance.LevelSelectAdditions</RootNamespace>
11+
<AssemblyName>Distance.LevelSelectAdditions</AssemblyName>
1212
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
1313
<FileAlignment>512</FileAlignment>
1414
<Deterministic>true</Deterministic>
@@ -86,13 +86,18 @@
8686
</Reference>
8787
</ItemGroup>
8888
<ItemGroup>
89+
<Compile Include="ConfigurationLogic.cs" />
90+
<Compile Include="Harmony\Assembly-CSharp\LevelGridMenu\CreateAndAddLevelSet.cs" />
8991
<Compile Include="Mod.cs" />
92+
<Compile Include="LevelFilter.cs" />
93+
<Compile Include="LevelSort.cs" />
9094
<Compile Include="Properties\AssemblyInfo.cs" />
9195
</ItemGroup>
9296
<ItemGroup>
93-
<None Include="Mod.Template.targets" />
97+
<None Include="Distance.LevelSelectAdditions.targets" />
9498
<None Include="packages.config" />
9599
</ItemGroup>
100+
<ItemGroup />
96101
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
97102
<PropertyGroup>
98103
<!-- 15.0 is for VS2017, adjust if necessary -->

Mod.Template/Mod.Template.targets renamed to Distance.LevelSelectAdditions/Distance.LevelSelectAdditions.targets

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
22
<PropertyGroup>
3-
<ModName>Distance Mod Template</ModName>
3+
<ModName>Distance Level Select Additions</ModName>
44
</PropertyGroup>
5-
</Project>
5+
</Project>
6+
7+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using HarmonyLib;
2+
using System;
3+
using System.Collections.Generic;
4+
using UnityEngine;
5+
6+
//using SortingMethod = LevelSelectMenuLogic.SortingMethod;
7+
8+
namespace Distance.LevelSelectAdditions.Harmony
9+
{
10+
/// <summary>
11+
/// A patch applied to the method that handles preparing and adding LevelSets to the list.
12+
/// <para/>
13+
/// Here we need to add our own handling for Workshop LevelSets and remove the original <c>levelPlaylist.LimitCountTo(100)</c>.
14+
/// </summary>
15+
[HarmonyPatch(typeof(LevelGridMenu), nameof(LevelGridMenu.CreateAndAddLevelSet))]
16+
internal static class LevelGridMenu__CreateAndAddLevelSet
17+
{
18+
19+
internal static bool Prefix(LevelGridMenu __instance, LevelSet set, string name, LevelGridMenu.PlaylistEntry.Type type, LevelGroupFlags flags)
20+
{
21+
// Only perform special handling for Workshop LevelSets (since that's all that's currently supported).
22+
if (type == LevelGridMenu.PlaylistEntry.Type.Workshop)
23+
{
24+
LevelPlaylist levelPlaylist = LevelPlaylist.Create(set, name, flags);
25+
LevelGridMenu.PlaylistEntry.UnlockStyle unlockStyle = LevelGridMenu.PlaylistEntry.UnlockStyle.None;
26+
27+
// Filter out levels in personal playlists, if the user has specified this.
28+
if (Mod.Instance.Config.HideWorkshopLevelsInPlaylists)
29+
{
30+
LevelFilter.ExcludeLevelsInPersonalPlaylists(levelPlaylist, __instance.modeID_);
31+
}
32+
33+
// Apply custom sorting.
34+
{
35+
var sorter = new LevelSort(Mod.Instance.Config.GetWorkshopSortingMethods(),
36+
Mod.Instance.Config.GetWorkshopReverseSortingMethods());
37+
sorter.SortPlaylist(__instance, levelPlaylist);
38+
}
39+
40+
// Finally apply limit after sorting and potentially removing levels that were in playlists.
41+
if (Mod.Instance.Config.WorkshopLevelLimit != LevelFilter.Infinite)
42+
{
43+
LevelFilter.LimitLevels(levelPlaylist, Mod.Instance.Config.WorkshopLevelLimit);
44+
}
45+
46+
47+
// All done! Add the organized LevelPlaylist entry.
48+
__instance.CreateAndAddEntry(levelPlaylist, type, true, unlockStyle, string.Empty);
49+
50+
51+
// Skip the original method, since we've fully handled this level set.
52+
return false;
53+
}
54+
55+
// Fallback to the original method for anything that's not a Workshop LevelSet.
56+
return true;
57+
}
58+
59+
}
60+
}

0 commit comments

Comments
 (0)