using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MMBiomeGeneration; using MMRoomGeneration; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ClassLibrary4")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ClassLibrary4")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d7f3cd4f-957c-4fa6-a4ae-1b1904889467")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 COTLMultiplayerRoomSizeScaling { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.cotlmp.roomsizescaling", "COTL Multiplayer Room Size Scaling", "0.1.1")] public sealed class RoomSizeScalingPlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotlmp.roomsizescaling"; public const string PluginName = "COTL Multiplayer Room Size Scaling"; public const string PluginVersion = "0.1.1"; internal ConfigEntry Enabled; internal ConfigEntry BiasStrength; internal ConfigEntry KeepVanillaChance; internal ConfigEntry BiasStrength3P; internal ConfigEntry KeepVanillaChance3P; internal ConfigEntry BiasStrength4P; internal ConfigEntry KeepVanillaChance4P; internal ConfigEntry MinAreaGainPct; internal ConfigEntry DebugLogging; private Harmony _harmony; internal static RoomSizeScalingPlugin Instance { get; private set; } internal static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger; private void Awake() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Expected O, but got Unknown Instance = this; Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable generated room size scaling."); BiasStrength = ((BaseUnityPlugin)this).Config.Bind("General", "BiasStrength", 0.7f, new ConfigDescription("Chance to attempt an upsize roll each generated room (0..1).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); KeepVanillaChance = ((BaseUnityPlugin)this).Config.Bind("General", "KeepVanillaChance", 0.35f, new ConfigDescription("Chance to keep vanilla selection for room-flow variety (0..1).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); BiasStrength3P = ((BaseUnityPlugin)this).Config.Bind("Multiplayer", "BiasStrength3P", 0.85f, new ConfigDescription("Upsize roll chance when 3 players are active.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); KeepVanillaChance3P = ((BaseUnityPlugin)this).Config.Bind("Multiplayer", "KeepVanillaChance3P", 0.25f, new ConfigDescription("Chance to keep vanilla room size when 3 players are active.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); BiasStrength4P = ((BaseUnityPlugin)this).Config.Bind("Multiplayer", "BiasStrength4P", 0.9f, new ConfigDescription("Upsize roll chance when 4+ players are active.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); KeepVanillaChance4P = ((BaseUnityPlugin)this).Config.Bind("Multiplayer", "KeepVanillaChance4P", 0.12f, new ConfigDescription("Chance to keep vanilla room size when 4+ players are active.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); MinAreaGainPct = ((BaseUnityPlugin)this).Config.Bind("General", "MinAreaGainPct", 0.15f, new ConfigDescription("Minimum area gain required to swap to a larger generated room piece.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); DebugLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugLogging", false, "Verbose room-size selection logs."); _harmony = new Harmony("com.cotlmp.roomsizescaling"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"COTL Multiplayer Room Size Scaling v0.1.1 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch] internal static class GenerateRoomGetRandomEncounterIslandPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(GenerateRoom), "GetRandomEncounterIsland", (Type[])null, (Type[])null); } private static void Postfix(GenerateRoom __instance, ref IslandPiece __result) { RoomSizeScalingPlugin instance = RoomSizeScalingPlugin.Instance; if ((Object)(object)instance == (Object)null || !instance.Enabled.Value || (Object)(object)__instance == (Object)null || (Object)(object)__result == (Object)null) { return; } BiomeRoom val = (((Object)(object)BiomeGenerator.Instance != (Object)null) ? BiomeGenerator.Instance.CurrentRoom : null); if (val != null && !string.IsNullOrEmpty(val.GameObjectPath)) { return; } List startPieces = __instance.StartPieces; if (startPieces == null || startPieces.Count == 0) { return; } int num = Mathf.Max(1, PlayerFarming.playersCount); float value = instance.KeepVanillaChance.Value; float value2 = instance.BiasStrength.Value; if (num >= 4) { value = instance.KeepVanillaChance4P.Value; value2 = instance.BiasStrength4P.Value; } else if (num >= 3) { value = instance.KeepVanillaChance3P.Value; value2 = instance.BiasStrength3P.Value; } if (Random.value < value || Random.value > value2) { return; } List list = CollectAvailableCandidates(startPieces); if (list.Count == 0) { return; } float area = GetArea(__result); IslandPiece val2 = __result; float num2 = area; for (int i = 0; i < list.Count; i++) { IslandPiece val3 = list[i]; float area2 = GetArea(val3); if (area2 > num2) { num2 = area2; val2 = val3; } } if ((Object)(object)val2 == (Object)null || val2 == __result) { return; } float num3 = area * (1f + instance.MinAreaGainPct.Value); if (!(num2 < num3)) { if (instance.DebugLogging.Value) { RoomSizeScalingPlugin.Log.LogInfo((object)$"[RoomSizeScale] Up-sized generated room piece area {area:0.00} -> {num2:0.00} (players={num}, keep={value:0.00}, bias={value2:0.00})"); } __result = val2; } } private static List CollectAvailableCandidates(List source) { List list = new List(); for (int i = 0; i < source.Count; i++) { IslandPiece val = source[i]; if ((Object)(object)val == (Object)null || val.Encounters == null || val.Encounters.ObjectList == null) { continue; } int num = 0; int num2 = 0; for (int j = 0; j < val.Encounters.ObjectList.Count; j++) { GameObjectAndProbability val2 = val.Encounters.ObjectList[j]; if (val2 != null && IsAvailableOnCurrentLayer(val2)) { num++; if (!string.IsNullOrEmpty(val2.GameObjectPath) && BiomeGenerator.EncounterAlreadyUsed(val2.GameObjectPath)) { num2++; } } } if (num > 0 && num2 < num) { list.Add(val); } } if (list.Count == 0) { for (int k = 0; k < source.Count; k++) { if ((Object)(object)source[k] != (Object)null) { list.Add(source[k]); } } } return list; } private static float GetArea(IslandPiece piece) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null) { return 0f; } PolygonCollider2D collider = piece.Collider; if ((Object)(object)collider == (Object)null) { return 0f; } Vector2[] points = collider.points; Bounds bounds; if (points == null || points.Length < 3) { bounds = ((Collider2D)collider).bounds; float x = ((Bounds)(ref bounds)).size.x; bounds = ((Collider2D)collider).bounds; return x * ((Bounds)(ref bounds)).size.y; } double num = 0.0; for (int i = 0; i < points.Length; i++) { Vector2 val = points[i]; Vector2 val2 = points[(i + 1) % points.Length]; num += (double)(val.x * val2.y - val2.x * val.y); } float num2 = Mathf.Abs((float)(num * 0.5)); if (!(num2 > 0f)) { bounds = ((Collider2D)collider).bounds; float x2 = ((Bounds)(ref bounds)).size.x; bounds = ((Collider2D)collider).bounds; return x2 * ((Bounds)(ref bounds)).size.y; } return num2; } private static bool IsAvailableOnCurrentLayer(GameObjectAndProbability encounter) { if (GameManager.DungeonUseAllLayers) { return true; } return GameManager.CurrentDungeonLayer switch { 1 => encounter.LayerOne, 2 => encounter.LayerTwo, 3 => encounter.LayerThree, 4 => encounter.LayerFour, _ => false, }; } } }