Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of PlayerScaling v1.2.4
PlayerScaling.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PlayerScaling")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.4")] [assembly: AssemblyInformationalVersion("1.2.4+194ad588f4355dafd402bbf7c37064017e0908d1")] [assembly: AssemblyProduct("Player Scaling")] [assembly: AssemblyTitle("PlayerScaling")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PlayerScaling { [HarmonyPatch(typeof(SemiFunc))] public static class DifficultyPatch { private static IEnumerable<MethodBase> TargetMethods() { return Plugin.GetNumberedMethodInfos(typeof(SemiFunc), "RunGetDifficultyMultiplier", Array.Empty<Type>(), 10); } private static void Postfix(ref float __result) { float num = Plugin.PlayerScaling(ScalingType.Difficulty); if (num != 1f) { __result += Plugin.difficultyScalingOffset.Value; __result *= Mathf.Sqrt(num); } } } [HarmonyPatch(typeof(EnemyDirector))] [HarmonyPatch("AmountSetup")] public static class EnemyAmountPatch { private static void Prefix(ref int ___amountCurve1Value, ref int ___amountCurve2Value, ref int ___amountCurve3Value, EnemyDirector __instance) { float num = (float)RunManager.instance.levelsCompleted * Plugin.enemyScalingMultiplier.Value; float num2 = Mathf.FloorToInt(Mathf.Max(1f, Mathf.Min(2f, (num + 4f) / 5f))); float num3 = Mathf.FloorToInt(Mathf.Max(0f, Mathf.Min(2f, num / 3f))); float num4 = Mathf.FloorToInt(Mathf.Max(1f, Mathf.Min(2f, (num + 4f) / 5f))); float num5 = Mathf.Min(10f, 5f + num); float num6 = num2 / num5; float num7 = num3 / num5; float num8 = num4 / num5; float num9 = num6 + num7 + num8; float num10 = 1f; if (num9 > Plugin.maxEnemyDensity.Value) { num10 = Plugin.maxEnemyDensity.Value / num9; } if ((double)Plugin.maxEnemyDensity.Value > 0.8 && num > 11f) { num10 = (0.25f + 0.05f * num) / num9; } num6 *= num10; num7 *= num10; num8 *= num10; ___amountCurve1Value = Mathf.Max(1, Mathf.RoundToInt(num6 * (float)Plugin.curModuleAmount)); ___amountCurve2Value = Mathf.Max(0, Mathf.RoundToInt(num7 * (float)Plugin.curModuleAmount)); ___amountCurve3Value = Mathf.Max(1, Mathf.RoundToInt(num8 * (float)Plugin.curModuleAmount)); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { int num = -1; List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.StoresField(list[i], typeof(EnemyDirector).GetField("amountCurve1Value", BindingFlags.Instance | BindingFlags.NonPublic))) { num = i + 1; } } if (num > -1) { list.RemoveRange(0, num); } else { Plugin.Logger.LogError((object)"Cannot find <Stdfld amountCurve1Value> in EnemyDirector.AmountSetup"); } return list.AsEnumerable(); } } [BepInPlugin("dev.redfops.repo.playerscaling", "Player Scaling", "1.2.4")] public class Plugin : BaseUnityPlugin { public delegate float DifficultyDelegate(); public const string modGUID = "dev.redfops.repo.playerscaling"; public const string modName = "Player Scaling"; public const string modVersion = "1.2.4"; public static int curModuleAmount = 5; public static ConfigEntry<bool> mapScalingEnabled; public static ConfigEntry<bool> downScalingEnabled; public static ConfigEntry<bool> difficultyScalingEnabled; public static ConfigEntry<float> mapScalingMultiplier; public static ConfigEntry<float> enemyScalingMultiplier; public static ConfigEntry<float> valuableScalingMultiplier; public static ConfigEntry<float> difficultyScalingMultiplier; public static ConfigEntry<float> difficultyScalingOffset; public static ConfigEntry<int> defaultMaxMapSize; public static ConfigEntry<float> maxEnemyDensity; public static ConfigEntry<float> downScalingMin; public static ConfigEntry<float> globalScalingMultiplier; public static ConfigEntry<int> numPlayersStartScaling; public static ConfigEntry<float> playerDivisor; internal static ManualLogSource Logger; private readonly Harmony harmony = new Harmony("dev.redfops.repo.playerscaling"); private void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Expected O, but got Unknown //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; globalScalingMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General Scaling", "Global Scaling Multiplier", 1f, new ConfigDescription("Multiplies player scaling by this number", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 10f), Array.Empty<object>())); numPlayersStartScaling = ((BaseUnityPlugin)this).Config.Bind<int>("General Scaling", "Player Scaling Minimum", 4, new ConfigDescription("Scaling only happens after the player count passes this number", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 16), Array.Empty<object>())); playerDivisor = ((BaseUnityPlugin)this).Config.Bind<float>("General Scaling", "Player Scaling Divisor", 4f, new ConfigDescription("Number of players divided by this is the scaling factor", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 12f), Array.Empty<object>())); downScalingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General Scaling", "Down Scaling Enabled", false, new ConfigDescription("Whether or not the map will be scaled down if less players than minimum", (AcceptableValueBase)null, Array.Empty<object>())); downScalingMin = ((BaseUnityPlugin)this).Config.Bind<float>("General Scaling", "Minimum Downscaling Multiplier", 0.5f, new ConfigDescription("The lowest the downscaling factor will go, not recommended below 0.5", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); mapScalingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Map Scaling", "Map Scaling Enabled", true, new ConfigDescription("Whether or not the map will be scaled to the number of players", (AcceptableValueBase)null, Array.Empty<object>())); mapScalingMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Map Scaling", "Map Scaling Multiplier", 1f, new ConfigDescription("Multiplies the map size by this number (including max size)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 10f), Array.Empty<object>())); defaultMaxMapSize = ((BaseUnityPlugin)this).Config.Bind<int>("Map Scaling", "Default Max Map Size", 10, new ConfigDescription("Max map size before scaling", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 60), Array.Empty<object>())); enemyScalingMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Enemies Scaling", "Enemies Scaling Multiplier", 1f, new ConfigDescription("Multiplies the number of enemies by this number (not including max)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 10f), Array.Empty<object>())); maxEnemyDensity = ((BaseUnityPlugin)this).Config.Bind<float>("Enemies Scaling", "Max Enemy Density", 0.8f, new ConfigDescription("Caps number of enemies per map module", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 5f), Array.Empty<object>())); valuableScalingMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Valuables Scaling", "Valuables Scaling Multiplier", 1f, new ConfigDescription("Multiplies the amount of valuables by this number", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 10f), Array.Empty<object>())); difficultyScalingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Difficulty Scaling", "Difficulty Scaling Enabled", true, new ConfigDescription("Whether or not the difficulty will be scaled to the number of players", (AcceptableValueBase)null, Array.Empty<object>())); difficultyScalingMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty Scaling", "Difficulty Scaling Multiplier", 1f, new ConfigDescription("Multiplies the difficulty by this number", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 4f), Array.Empty<object>())); difficultyScalingOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty Scaling", "Difficulty Scaling Offset", 0.085f, new ConfigDescription("Offsets the general difficulty", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); harmony.PatchAll(typeof(TileGenerationPatchTrans)); harmony.PatchAll(typeof(TileGenerationPatch)); harmony.PatchAll(typeof(DifficultyPatch)); harmony.PatchAll(typeof(EnemyAmountPatch)); harmony.PatchAll(typeof(ValuablePatch)); Logger.LogInfo((object)"Plugin PlayerScaling is loaded!"); } public static float PlayerScaling(ScalingType scalingType) { return scalingType switch { ScalingType.Valuable => valuableScalingMultiplier.Value, ScalingType.Enemy => enemyScalingMultiplier.Value, ScalingType.Map => mapScalingMultiplier.Value * (mapScalingEnabled.Value ? PlayerScaling(ScalingType.Global) : 1f), ScalingType.Difficulty => difficultyScalingMultiplier.Value * (difficultyScalingEnabled.Value ? PlayerScaling(ScalingType.Global) : 1f), _ => globalScalingMultiplier.Value * ((GameDirector.instance.PlayerList.Count < numPlayersStartScaling.Value || downScalingEnabled.Value) ? 1f : Mathf.Max((float)GameDirector.instance.PlayerList.Count / playerDivisor.Value, downScalingMin.Value)), }; } public static List<MethodBase> GetNumberedMethodInfos(Type source, string expectedBaseName, Type[] parameters, int checkMax, int checkMin = 0) { List<MethodBase> list = new List<MethodBase>(); if (Traverse.Create(source).Method(expectedBaseName, parameters, (object[])null).MethodExists()) { list.Add(AccessTools.Method(source, expectedBaseName, parameters, (Type[])null)); } for (int i = checkMin; i < checkMax; i++) { if (Traverse.Create(source).Method(expectedBaseName + i, parameters, (object[])null).MethodExists()) { list.Add(AccessTools.Method(source, expectedBaseName + i, parameters, (Type[])null)); } } return list; } } public enum ScalingType { Global, Enemy, Map, Valuable, Difficulty } [HarmonyPatch(typeof(LevelGenerator))] [HarmonyPatch("TileGeneration")] public static class TileGenerationPatch { private static void Prefix(LevelGenerator __instance, ref int ___ModuleAmount, ref int ___ExtractionAmount, ref float ___DebugLevelSize) { float num = Plugin.PlayerScaling(ScalingType.Map); ___ExtractionAmount = 0; if (___ModuleAmount > 4) { int num2 = Mathf.Min(Mathf.CeilToInt((float)Plugin.defaultMaxMapSize.Value * num), 2000); if (num2 > 200) { __instance.LevelHeight = 50; __instance.LevelWidth = 50; } ___ModuleAmount = Mathf.Min((int)(num * (float)(5 + RunManager.instance.levelsCompleted)), num2); Plugin.curModuleAmount = ___ModuleAmount; ___DebugLevelSize = num; ___ExtractionAmount = (___ModuleAmount - 4) / 2; } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static class TileGenerationPatchTrans { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { bool flag = false; int num = -1; int num2 = -1; List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (!CodeInstructionExtensions.StoresField(list[i], typeof(LevelGenerator).GetField("ModuleAmount", BindingFlags.Instance | BindingFlags.NonPublic))) { continue; } if (!flag) { flag = true; for (int num3 = i; num3 > 0; num3--) { if (list[num3].opcode == OpCodes.Ble) { num = num3 + 1; break; } } } else if (!(list[i - 1].opcode == OpCodes.Add)) { num2 = i + 1; break; } } if (num > -1 && num2 > -1) { list.RemoveRange(num, num2 - num); } else { Plugin.Logger.LogError((object)"Cannot find <Stdfld ModuleAmount> in LevelGenerator.TileGeneration"); } num = -1; num2 = -1; for (int j = 0; j < list.Count; j++) { if (CodeInstructionExtensions.StoresField(list[j], typeof(LevelGenerator).GetField("ExtractionAmount", BindingFlags.Instance | BindingFlags.NonPublic)) && list[j - 1].opcode == OpCodes.Ldc_I4_0) { num = j - 2; num2 = j + 1; break; } } if (num > -1 && num2 > -1) { list.RemoveRange(num, num2 - num); } else { Plugin.Logger.LogError((object)"Cannot find <Stdfld ExtractionAmount> in LevelGenerator.TileGeneration"); } flag = false; num = -1; num2 = -1; for (int k = 0; k < list.Count; k++) { if (CodeInstructionExtensions.LoadsField(list[k], typeof(LevelGenerator).GetField("ModuleAmount", BindingFlags.Instance | BindingFlags.NonPublic), false) && !flag) { if (list[k + 1].opcode == OpCodes.Ldc_I4_S && (Convert.ToInt32(list[k + 1].operand) == 10 || Convert.ToInt32(list[k + 1].operand) == 15) && list[k + 2].opcode == OpCodes.Blt) { flag = true; num = k - 1; } } else if (flag && CodeInstructionExtensions.StoresField(list[k], typeof(LevelGenerator).GetField("ExtractionAmount", BindingFlags.Instance | BindingFlags.NonPublic)) && list[k - 1].opcode == OpCodes.Ldc_I4_0) { num2 = k + 1; break; } } if (num > -1 && num2 > -1) { list.RemoveRange(num, num2 - num); } else { Plugin.Logger.LogError((object)"Cannot find <Stdfld ExtractionAmount> in LevelGenerator.TileGeneration"); } return list.AsEnumerable(); } } [HarmonyPatch(typeof(ValuableDirector))] [HarmonyPatch("SetupHost")] [HarmonyWrapSafe] public static class ValuablePatch { private static AnimationCurve[] TotalMaxAmountCurves { get; set; } private static AnimationCurve[] TotalMaxValueCurves { get; set; } private static AnimationCurve[] TinyCurves { get; set; } private static AnimationCurve[] SmallCurves { get; set; } private static AnimationCurve[] MediumCurves { get; set; } private static AnimationCurve[] BigCurves { get; set; } private static AnimationCurve[] WideCurves { get; set; } private static AnimationCurve[] TallCurves { get; set; } private static AnimationCurve[] VeryTallCurves { get; set; } private static void Prefix(ValuableDirector __instance) { if ((Object)(object)__instance == (Object)null) { return; } FieldRef<ValuableDirector, int> val = AccessTools.FieldRefAccess<ValuableDirector, int>("totalMaxAmount"); Plugin.Logger.LogInfo((object)"Player scaling runs HERE"); List<Plugin.DifficultyDelegate> staticNumberedMethodDelegates = GetStaticNumberedMethodDelegates<Plugin.DifficultyDelegate>(typeof(SemiFunc), "RunGetDifficultyMultiplier", Array.Empty<Type>(), 10); int num = Mathf.Min(10, 5 + RunManager.instance.levelsCompleted); if (RunManager.instance.levelsCompleted >= 10) { num += Mathf.Min(RunManager.instance.levelsCompleted - 9, 5); } float mapScalingFactor = (float)Plugin.curModuleAmount / (float)num; mapScalingFactor *= Plugin.valuableScalingMultiplier.Value; List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "totalMaxAmountCurve", 10); if (numberedFieldRefs.Count != 0) { if (TotalMaxAmountCurves == null) { TotalMaxAmountCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item in (from tuple in numberedFieldRefs.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>) where tuple.Item1 != null && tuple.Item2 != null select tuple).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2))) { item.Item2.Invoke(__instance) = ReplaceCurve(ref TotalMaxAmountCurves[item.Item1], item.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } } else { val.Invoke(__instance) = (int)Math.Ceiling((float)val.Invoke(__instance) * mapScalingFactor); } List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs2 = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "totalMaxValueCurve", 10); if (numberedFieldRefs2.Count != 0) { if (TotalMaxValueCurves == null) { TotalMaxValueCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs2.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item2 in from value in numberedFieldRefs2.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2)) where value.Item2 != null && value.Item3 != null select value) { item2.Item2.Invoke(__instance) = ReplaceCurve(ref TotalMaxValueCurves[item2.Item1], item2.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } } List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs3 = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "tinyMaxAmountCurve", 10); if (TinyCurves == null) { TinyCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs3.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item3 in from value in numberedFieldRefs3.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2)) where value.Item2 != null && value.Item3 != null select value) { item3.Item2.Invoke(__instance) = ReplaceCurve(ref TinyCurves[item3.Item1], item3.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs4 = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "smallMaxAmountCurve", 10); if (SmallCurves == null) { SmallCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs4.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item4 in from value in numberedFieldRefs4.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2)) where value.Item2 != null && value.Item3 != null select value) { item4.Item2.Invoke(__instance) = ReplaceCurve(ref SmallCurves[item4.Item1], item4.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs5 = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "mediumMaxAmountCurve", 10); if (MediumCurves == null) { MediumCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs5.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item5 in from value in numberedFieldRefs5.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2)) where value.Item2 != null && value.Item3 != null select value) { item5.Item2.Invoke(__instance) = ReplaceCurve(ref MediumCurves[item5.Item1], item5.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs6 = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "bigMaxAmountCurve", 10); if (BigCurves == null) { BigCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs6.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item6 in from value in numberedFieldRefs6.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2)) where value.Item2 != null && value.Item3 != null select value) { item6.Item2.Invoke(__instance) = ReplaceCurve(ref BigCurves[item6.Item1], item6.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs7 = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "wideMaxAmountCurve", 10); if (WideCurves == null) { WideCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs7.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item7 in from value in numberedFieldRefs7.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2)) where value.Item2 != null && value.Item3 != null select value) { item7.Item2.Invoke(__instance) = ReplaceCurve(ref WideCurves[item7.Item1], item7.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs8 = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "tallMaxAmountCurve", 10); if (TallCurves == null) { TallCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs8.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item8 in from value in numberedFieldRefs8.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2)) where value.Item2 != null && value.Item3 != null select value) { item8.Item2.Invoke(__instance) = ReplaceCurve(ref TallCurves[item8.Item1], item8.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } List<FieldRef<ValuableDirector, AnimationCurve>> numberedFieldRefs9 = GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(__instance, "veryTallMaxAmountCurve", 10); if (VeryTallCurves == null) { VeryTallCurves = (AnimationCurve[])(object)new AnimationCurve[numberedFieldRefs9.Count]; } foreach (Tuple<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> item9 in from value in numberedFieldRefs9.Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate> value, int index) => Tuple.Create<int, FieldRef<ValuableDirector, AnimationCurve>, Plugin.DifficultyDelegate>(index, value.Item1, value.Item2)) where value.Item2 != null && value.Item3 != null select value) { item9.Item2.Invoke(__instance) = ReplaceCurve(ref VeryTallCurves[item9.Item1], item9.Item2.Invoke(__instance), (float value) => value * mapScalingFactor); } } private static AnimationCurve ReplaceCurve(ref AnimationCurve target, AnimationCurve source, Func<float, float> calculate) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Plugin.Logger.LogInfo((object)("Player scaling will replace a curve with a factor of " + calculate(1f))); if (target == source) { return target; } target = new AnimationCurve(); Plugin.Logger.LogInfo((object)"Player scaling will copy a curve for scaling"); target.CopyFrom(source); target.ClearKeys(); Keyframe[] keys = source.GetKeys(); for (int i = 0; i < keys.Length; i++) { Keyframe val = keys[i]; Keyframe val2 = val; ((Keyframe)(ref val2)).value = calculate(((Keyframe)(ref val)).value); Keyframe val3 = val2; target.AddKey(val3); } return target; } private static List<FieldRef<S, T>> GetNumberedFieldRefs<S, T>(S source, string expectedBaseName, int checkMax, int checkMin = 0) { List<FieldRef<S, T>> list = new List<FieldRef<S, T>>(); if (Traverse.Create((object)source).Field(expectedBaseName).FieldExists()) { list.Add(AccessTools.FieldRefAccess<S, T>(expectedBaseName)); } for (int i = checkMin; i < checkMax; i++) { if (Traverse.Create((object)source).Field(expectedBaseName + i).FieldExists()) { list.Add(AccessTools.FieldRefAccess<S, T>(expectedBaseName + i)); } } return list; } private static List<T> GetStaticNumberedMethodDelegates<T>(Type source, string expectedBaseName, Type[] parameters, int checkMax, int checkMin = 0) where T : Delegate { List<T> list = new List<T>(); if (Traverse.Create(source).Method(expectedBaseName, parameters, (object[])null).MethodExists()) { list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(source, expectedBaseName, parameters, (Type[])null), (object)source, true)); } for (int i = checkMin; i < checkMax; i++) { if (Traverse.Create(source).Method(expectedBaseName + i, parameters, (object[])null).MethodExists()) { list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(source, expectedBaseName + i, parameters, (Type[])null), (object)source, true)); } } return list; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "PlayerScaling"; public const string PLUGIN_NAME = "Player Scaling"; public const string PLUGIN_VERSION = "1.2.4"; } }