using 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.1.7")]
[assembly: AssemblyInformationalVersion("1.1.0+5158d60ca4ab440b630656cb306358c3386758c6")]
[assembly: AssemblyProduct("Player Scaling")]
[assembly: AssemblyTitle("PlayerScaling")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.7.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))]
[HarmonyPatch("RunGetDifficultyMultiplier")]
public static class DifficultyPatch
{
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 = Plugin.PlayerScaling(ScalingType.Enemy);
float num2 = SemiFunc.RunGetDifficultyMultiplier() / Mathf.Sqrt(Plugin.PlayerScaling(ScalingType.Difficulty));
___amountCurve1Value = (int)(__instance.amountCurve1.Evaluate(num2) * num);
___amountCurve2Value = (int)(__instance.amountCurve2.Evaluate(num2) * num);
___amountCurve3Value = (int)(__instance.amountCurve3.Evaluate(num2) * num);
}
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.1.0")]
public class Plugin : BaseUnityPlugin
{
public const string modGUID = "dev.redfops.repo.playerscaling";
public const string modName = "Player Scaling";
public const string modVersion = "1.1.0";
public static ConfigEntry<bool> mapScalingEnabled;
public static ConfigEntry<bool> enemyScalingEnabled;
public static ConfigEntry<bool> valuableScalingEnabled;
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> valuableScalingOffset;
public static ConfigEntry<float> difficultyScalingOffset;
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_01a3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Expected O, but got Unknown
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Expected O, but got Unknown
//IL_021d: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Expected O, but got Unknown
//IL_0248: Unknown result type (might be due to invalid IL or missing references)
//IL_0252: Expected O, but got Unknown
//IL_0285: Unknown result type (might be due to invalid IL or missing references)
//IL_028f: Expected O, but got Unknown
//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: 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>()));
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", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 10f), Array.Empty<object>()));
enemyScalingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies Scaling", "Enemies Scaling Enabled", true, new ConfigDescription("Whether or not the number of enemies will be scaled to the number of players", (AcceptableValueBase)null, 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", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 10f), Array.Empty<object>()));
valuableScalingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Valuables Scaling", "Valuables Scaling Enabled", true, new ConfigDescription("Whether or not the amount of valuables will be scaled to the number of players", (AcceptableValueBase)null, 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>()));
valuableScalingOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Valuables Scaling", "Valuables Scaling Offset", 0.1f, new ConfigDescription("Offsets the difficulty of the Valuable spawner", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), 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(ValuablePatchTrans));
harmony.PatchAll(typeof(ValuablePatch));
Logger.LogInfo((object)"Plugin PlayerScaling is loaded!");
}
public static float PlayerScaling(ScalingType scalingType)
{
return scalingType switch
{
ScalingType.Valuable => valuableScalingMultiplier.Value * (valuableScalingEnabled.Value ? PlayerScaling(ScalingType.Global) : 1f),
ScalingType.Enemy => enemyScalingMultiplier.Value * (enemyScalingEnabled.Value ? PlayerScaling(ScalingType.Global) : 1f),
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) ? 1f : ((float)GameDirector.instance.PlayerList.Count / playerDivisor.Value)),
};
}
}
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)
{
float num = Plugin.PlayerScaling(ScalingType.Map);
___ExtractionAmount = 0;
if (num == 1f)
{
if (___ModuleAmount > 4)
{
___ModuleAmount = Mathf.Min(5 + RunManager.instance.levelsCompleted, 10);
if (___ModuleAmount >= 10)
{
___ExtractionAmount = 3;
}
else if (___ModuleAmount >= 8)
{
___ExtractionAmount = 2;
}
else if (___ModuleAmount >= 6)
{
___ExtractionAmount = 1;
}
else
{
___ExtractionAmount = 0;
}
}
__instance.LevelHeight = 3;
__instance.LevelWidth = 3;
}
else
{
__instance.LevelHeight = (int)(3f * Mathf.Sqrt(num + 2f));
__instance.LevelWidth = __instance.LevelHeight;
if (___ModuleAmount > 4)
{
___ModuleAmount = Mathf.Min((int)(num * (float)(5 + RunManager.instance.levelsCompleted)), __instance.LevelHeight * __instance.LevelWidth);
___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;
}
}
continue;
}
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 && 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")]
public static class ValuablePatch
{
private static void Prefix(ref int ___totalMaxAmount, ref int ___tinyMaxAmount, ref int ___smallMaxAmount, ref int ___mediumMaxAmount, ref int ___bigMaxAmount, ref int ___wideMaxAmount, ref int ___tallMaxAmount, ref int ___veryTallMaxAmount, ValuableDirector __instance)
{
float num = Plugin.PlayerScaling(ScalingType.Valuable);
float num2 = SemiFunc.RunGetDifficultyMultiplier() / Mathf.Sqrt(Plugin.PlayerScaling(ScalingType.Difficulty)) + Plugin.valuableScalingOffset.Value;
___totalMaxAmount = Mathf.RoundToInt(__instance.totalMaxAmountCurve.Evaluate(num2) * num);
___tinyMaxAmount = Mathf.RoundToInt(__instance.tinyMaxAmountCurve.Evaluate(num2) * num);
___smallMaxAmount = Mathf.RoundToInt(__instance.smallMaxAmountCurve.Evaluate(num2) * num);
___mediumMaxAmount = Mathf.RoundToInt(__instance.mediumMaxAmountCurve.Evaluate(num2) * num);
___bigMaxAmount = Mathf.RoundToInt(__instance.bigMaxAmountCurve.Evaluate(num2) * num);
___wideMaxAmount = Mathf.RoundToInt(__instance.wideMaxAmountCurve.Evaluate(num2) * num);
___tallMaxAmount = Mathf.RoundToInt(__instance.tallMaxAmountCurve.Evaluate(num2) * num);
___veryTallMaxAmount = Mathf.RoundToInt(__instance.veryTallMaxAmountCurve.Evaluate(num2) * num);
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
public static class ValuablePatchTrans
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
int num = -1;
int num2 = -1;
Label label = generator.DefineLabel();
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
for (int i = 0; i < list.Count; i++)
{
if (CodeInstructionExtensions.StoresField(list[i], typeof(ValuableDirector).GetField("totalMaxAmount", BindingFlags.Instance | BindingFlags.NonPublic)))
{
for (int num3 = i; num3 > 0; num3--)
{
if (list[num3].opcode == OpCodes.Ldc_R4)
{
num = num3 + 2;
}
if (list[num3].opcode == OpCodes.Brfalse)
{
list[num3].operand = label;
break;
}
}
}
else if (CodeInstructionExtensions.StoresField(list[i], typeof(ValuableDirector).GetField("veryTallMaxAmount", BindingFlags.Instance | BindingFlags.NonPublic)))
{
num2 = i + 1;
list[i + 1].labels.Add(label);
break;
}
}
if (num > -1 && num2 > -1)
{
list.RemoveRange(num, num2 - num);
}
else
{
Plugin.Logger.LogError((object)"Cannot find <Stdfld totalMaxAmount> in ValuableDirector.SetupHost");
}
return list.AsEnumerable();
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "PlayerScaling";
public const string PLUGIN_NAME = "Player Scaling";
public const string PLUGIN_VERSION = "1.1.0";
}
}