generated from Distance-Modding/Template.CSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add missing Adv. level select levels (v1.1.4.2)
Vanilla Fixes: * Fixed vanilla bug where in the Advanced level select menu. Two instances of levels in level sets wouldn't show up in the list: * Sprite: Zenith * Reverse Tag: Stuntware 2051 Refactors: * Switch to more uses of constants for WorkshopVoteIndex and "Unknown" default username.
- Loading branch information
1 parent
8dc455c
commit 881de7e
Showing
7 changed files
with
194 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
Distance.LevelSelectAdditions/Harmony/Assembly-CSharp/LevelSet/Initialize.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
using HarmonyLib; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Distance.LevelSelectAdditions.Harmony | ||
{ | ||
/// <summary> | ||
/// Patch to fix missing levels in the Advanced level select menu. The following levels are missing: | ||
/// <list type="bullet"> | ||
/// <item>Sprint: Zenith</item> | ||
/// <item>ReverseTag: Stuntware 2051</item> | ||
/// </list> | ||
/// </summary> | ||
[HarmonyPatch(typeof(LevelSet), nameof(LevelSet.Initialize))] | ||
internal static class LevelSet__Initialize | ||
{ | ||
[HarmonyPrefix] | ||
internal static void Prefix(LevelSet __instance) | ||
{ | ||
if (__instance.resourcesLevelNameAndPathPairsInSet_.Count > 0) | ||
{ | ||
return; // Already initialized | ||
} | ||
|
||
// Re-add levels that are missing in the Advanced level select menu (this setting requires a restart). | ||
// All official (but not community) levels are loaded from the `resourcesLevelFileNamesInSet_` field. | ||
// This is likely initialized by UnityEngine at some point outside of our view of the code. | ||
// This field stores file names without extension or relative path. | ||
List<string> knownMissingFileNames = new List<string>(); | ||
switch (__instance.gameModeID_) | ||
{ | ||
case GameModeID.Sprint: | ||
//Mod.Instance.Logger.Debug("GameModeID.Sprint"); | ||
knownMissingFileNames.Add("Zenith"); | ||
break; | ||
|
||
case GameModeID.ReverseTag: | ||
//Mod.Instance.Logger.Debug("GameModeID.ReverseTag"); | ||
knownMissingFileNames.Add("Stuntware 2051"); | ||
|
||
// The following are neither in the Advanced level select menu, or any level set grids. | ||
// However they still have ReverseTag as a supported mode - which is likely a mistake, | ||
// as the Stunt map (Refraction) that was removed in the Radical Update had its mode properly removed. | ||
|
||
// Unsure when this was removed, but probably for the same reason as below. | ||
//knownMissingFileNames.Add("Quantum Core"); | ||
|
||
// These were intentionally removed as noted in the Radical Update changelog. | ||
//knownMissingFileNames.Add("Space Skate"); | ||
//knownMissingFileNames.Add("Stunt Playground"); | ||
break; | ||
} | ||
|
||
if (knownMissingFileNames.Count > 0) | ||
{ | ||
// Double-check to make sure these levels haven't already been added by another mod, or game update. | ||
List<string> newResourceLevelFileNamesInSet = __instance.resourcesLevelFileNamesInSet_.ToList(); | ||
foreach (string fileName in knownMissingFileNames) | ||
{ | ||
if (Array.IndexOf(__instance.resourcesLevelFileNamesInSet_, fileName) == -1) | ||
{ | ||
newResourceLevelFileNamesInSet.Add(fileName); | ||
} | ||
} | ||
|
||
int added = newResourceLevelFileNamesInSet.Count - __instance.resourcesLevelFileNamesInSet_.Length; | ||
if (added > 0) | ||
{ | ||
// Update the array with the added missing levels. | ||
__instance.resourcesLevelFileNamesInSet_ = newResourceLevelFileNamesInSet.ToArray(); | ||
|
||
string header = $"{nameof(GameModeID)}.{__instance.gameModeID_}: "; | ||
Mod.Instance.Logger.Info($"{header}Added {added} missing {GUtils.GetPlural("level", added)} to the Advanced level select menu."); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.Linq.Expressions; | ||
|
||
namespace Distance.LevelSelectAdditions.Helpers | ||
{ | ||
/// <summary> | ||
/// Optimized and organized reflection for use with Steamworks, | ||
/// which is needed due to the lack of <c>Assembly-CSharp-firstpass.dll</c> dependency. | ||
/// <para/> | ||
/// <see cref="SteamworksHelper.Init()"/> must be called before using. | ||
/// </summary> | ||
public static class SteamworksHelper | ||
{ | ||
public const int VoteIndex_For = 0; | ||
public const int VoteIndex_Against = 1; | ||
public const int VoteIndex_None = 2; | ||
|
||
|
||
//private static Assembly assembly_FirstPass; | ||
|
||
public static void Init() | ||
{ | ||
// Nothing here yet... | ||
|
||
//assembly_FirstPass = typeof(SteamworksLeaderboard.Leaderboard).GetField("steamHandle_").FieldType.Assembly; | ||
} | ||
|
||
// WIP: | ||
/*private static Expression ParseMethodAccessor(Expression body, string member) | ||
{ | ||
string method = member.Substring(0, member.Length - 2); // Remove "()" | ||
int sepIndex = method.LastIndexOf("::"); | ||
if (sepIndex != -1) | ||
{ | ||
string classPath = method.Substring(0, sepIndex); | ||
method = method.Substring(sepIndex + 2); | ||
classPath = classPath.Replace("::", "."); | ||
Type staticType = typeof(GameManager).Assembly.GetType(classPath, false); | ||
if (staticType == null) | ||
{ | ||
staticType = assembly_FirstPass.GetType(classPath, false); | ||
} | ||
if (staticType == null) | ||
{ | ||
throw new ArgumentException($"Could not find declaring type for \"{member}\""); | ||
} | ||
return Expression.Call(staticType, method, null, body); | ||
} | ||
else | ||
{ | ||
return Expression.Call(body, method, null); | ||
} | ||
}*/ | ||
|
||
// Using this allows for compiling expressions that may need to access non-public fields or properties. | ||
// see: <https://stackoverflow.com/a/16208620/7517185> | ||
private static Delegate CreateAccessor(Type type, string accessorPath) | ||
{ | ||
Mod.Instance.Logger.Debug($"CreateAccessor: {type.Name}.{accessorPath}"); | ||
Stopwatch watch = Stopwatch.StartNew(); | ||
|
||
ParameterExpression param = Expression.Parameter(type, "x"); | ||
Expression body = param; | ||
foreach (string member in accessorPath.Split('.')) | ||
{ | ||
// WIP: | ||
//if (member.EndsWith("()")) | ||
//{ | ||
// body = ParseMethodAccessor(body, member); | ||
//} | ||
//else | ||
//{ | ||
body = Expression.PropertyOrField(body, member); | ||
//} | ||
} | ||
Delegate compiled = Expression.Lambda(body, param).Compile(); | ||
|
||
watch.Stop(); | ||
Mod.Instance.Logger.Debug($"CreateAccessor: {watch.ElapsedMilliseconds}ms"); | ||
return compiled; | ||
} | ||
|
||
private static Func<T, R> CreateAccessor<T, R>(string accessorPath) | ||
{ | ||
return (Func<T, R>)CreateAccessor(typeof(T), accessorPath); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters