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 ScavengerBeforeLoop v1.0.0
plugins/ScavengerBeforeLoop/ScavengerBeforeLoop.dll
Decompiled a day 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 BepInEx; using BepInEx.Configuration; using HarmonyLib; using LocalTweaks; using Microsoft.CodeAnalysis; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using UnityEngine; using UnityEngine.Networking; [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("ScavengerBeforeLoop")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ScavengerBeforeLoop")] [assembly: AssemblyTitle("ScavengerBeforeLoop")] [assembly: AssemblyVersion("1.0.0.0")] [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 ScavengerBeforeLoop { [BepInPlugin("com.youssef.ScavengerBeforeLoop", "Scavenger Before Loop", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "com.youssef.ScavengerBeforeLoop"; public const string Name = "Scavenger Before Loop"; private static Plugin instance; private ConfigEntry<bool> onePerStage; private readonly Harmony harmony = new Harmony("com.youssef.ScavengerBeforeLoop"); private SceneInfo trackedScene; private SceneInfo populatedScene; private CharacterSpawnCard scavenger; private Xoroshiro128Plus rng; private int spawned; private int failedAttempts; private bool spawning; private float nextSpawn; private float nextAttempt; private const float SpawnInterval = 90f; private void Awake() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_0093: Expected O, but got Unknown //IL_0093: Expected O, but got Unknown instance = this; onePerStage = TweakSettings.Checkbox(((BaseUnityPlugin)this).Config, "Scavengers", "Maximum one per stage", value: true, "Limit stage 5 to one Scavenger in total, even after it dies. Uncheck for another every 90 seconds until the teleporter finishes. Changes apply immediately; existing enemies are never removed.", "com.youssef.ScavengerBeforeLoop", "Scavenger Before Loop"); try { harmony.Patch((MethodBase)AccessTools.Method(typeof(SpawnCard), "DoSpawn", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "BeforeSpawn", (Type[])null), new HarmonyMethod(typeof(Plugin), "AfterSpawn", (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "FinishSpawn", (Type[])null), (HarmonyMethod)null); SceneDirector.onPostPopulateSceneServer += ScenePopulated; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Stage 5 Scavengers loaded."); } catch (Exception arg) { harmony.UnpatchSelf(); ((BaseUnityPlugin)this).Logger.LogError((object)$"Stage 5 Scavengers were not applied.\n{arg}"); ((Behaviour)this).enabled = false; } } private void OnDestroy() { SceneDirector.onPostPopulateSceneServer -= ScenePopulated; harmony.UnpatchSelf(); if ((Object)(object)instance == (Object)(object)this) { instance = null; } } private void ScenePopulated(SceneDirector director) { populatedScene = SceneInfo.instance; } private bool IsTargetStage() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown Run val = Run.instance; SceneDef mostRecentSceneDef = SceneCatalog.mostRecentSceneDef; if (!NetworkServer.active || !Object.op_Implicit((Object)(object)val) || val.stageClearCount != 4 || !Object.op_Implicit((Object)(object)SceneInfo.instance) || !Object.op_Implicit((Object)(object)mostRecentSceneDef) || (int)mostRecentSceneDef.sceneType != 1 || mostRecentSceneDef.isFinalStage || !mostRecentSceneDef.validForRandomSelection) { return false; } if ((Object)(object)trackedScene != (Object)(object)SceneInfo.instance) { trackedScene = SceneInfo.instance; spawned = 0; failedAttempts = 0; spawning = false; nextSpawn = 0f; nextAttempt = 0f; rng = new Xoroshiro128Plus(val.seed ^ 0x53434156); } return true; } private void FixedUpdate() { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) if (!IsTargetStage() || (Object)(object)populatedScene != (Object)(object)trackedScene || Time.fixedTime < nextSpawn || Time.fixedTime < nextAttempt || (spawned > 0 && (onePerStage.Value || TeleporterFinished()))) { return; } nextAttempt = Time.fixedTime + 1f; CharacterBody val = null; foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances) && readOnlyInstances.isPlayerControlled && Object.op_Implicit((Object)(object)readOnlyInstances.healthComponent) && readOnlyInstances.healthComponent.alive) { val = readOnlyInstances; break; } } if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)DirectorCore.instance)) { return; } if (!Object.op_Implicit((Object)(object)scavenger)) { scavenger = LegacyResourcesAPI.Load<CharacterSpawnCard>("SpawnCards/CharacterSpawnCards/cscScav"); } if (!Object.op_Implicit((Object)(object)scavenger)) { ((BaseUnityPlugin)this).Logger.LogError((object)"The original cscScav spawn card could not be loaded."); ((Behaviour)this).enabled = false; return; } DirectorPlacementRule val2 = new DirectorPlacementRule { placementMode = (PlacementMode)1, position = val.corePosition, minDistance = 30f, maxDistance = 80f, preventOverhead = true }; DirectorSpawnRequest val3 = new DirectorSpawnRequest((SpawnCard)(object)scavenger, val2, rng) { teamIndexOverride = (TeamIndex)2, ignoreTeamMemberLimit = (spawned == 0) }; GameObject val4 = DirectorCore.instance.TrySpawnObject(val3); if (!Object.op_Implicit((Object)(object)val4)) { val2.placementMode = (PlacementMode)4; val4 = DirectorCore.instance.TrySpawnObject(val3); } if (!Object.op_Implicit((Object)(object)val4) && ++failedAttempts == 30) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Still looking for a valid Scavenger spawn point on this stage."); } } private static bool TeleporterFinished() { if (Object.op_Implicit((Object)(object)TeleporterInteraction.instance)) { return TeleporterInteraction.instance.isCharged; } return false; } private static bool IsScavenger(SpawnCard card, DirectorSpawnRequest request) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Invalid comparison between Unknown and I4 if (!Object.op_Implicit((Object)(object)card) || !Object.op_Implicit((Object)(object)card.prefab) || request.teamIndexOverride == (TeamIndex?)1) { return false; } CharacterMaster component = card.prefab.GetComponent<CharacterMaster>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.bodyPrefab) && ((Object)component.bodyPrefab).name == "ScavBody") { return (int)(((??)request.teamIndexOverride) ?? component.teamIndex) == 2; } return false; } private static bool BeforeSpawn(SpawnCard __instance, Vector3 position, Quaternion rotation, DirectorSpawnRequest spawnRequest, ref SpawnResult __result, out bool __state) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0085: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) __state = false; if (!Object.op_Implicit((Object)(object)instance) || !instance.IsTargetStage() || !IsScavenger(__instance, spawnRequest)) { return true; } if (instance.spawning || (instance.spawned > 0 && (instance.onePerStage.Value || Time.fixedTime < instance.nextSpawn || TeleporterFinished()))) { __result = new SpawnResult { spawnRequest = spawnRequest, position = position, rotation = rotation, success = false }; return false; } instance.spawning = true; __state = true; return true; } private static void AfterSpawn(SpawnResult __result, bool __state) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)instance) && __state && __result.success && Object.op_Implicit((Object)(object)__result.spawnedInstance)) { instance.spawned++; instance.failedAttempts = 0; instance.nextSpawn = Time.fixedTime + 90f; } } private static void FinishSpawn(bool __state) { if (Object.op_Implicit((Object)(object)instance) && __state) { instance.spawning = false; } } } } namespace LocalTweaks { internal static class PatchTools { internal static MethodInfo Method(string type, string name) { Type type2 = AccessTools.TypeByName(type); if (!(type2 == null)) { return AccessTools.DeclaredMethod(type2, name, (Type[])null, (Type[])null) ?? throw new MissingMethodException(type, name); } throw new TypeLoadException(type); } internal static IEnumerable<CodeInstruction> ReplaceFloat(IEnumerable<CodeInstruction> source, float value, MethodInfo replacement) { List<CodeInstruction> list = source.ToList(); List<CodeInstruction> list2 = list.Where((CodeInstruction x) => x.opcode == OpCodes.Ldc_R4 && x.operand is float num && Math.Abs(num - value) < 1E-06f).ToList(); if (list2.Count != 1) { throw new InvalidOperationException($"Expected one {value} constant, found {list2.Count}."); } list2[0].opcode = OpCodes.Call; list2[0].operand = replacement; return list; } } internal static class TweakSettings { internal static ConfigEntry<int> Slider(ConfigFile file, string section, string name, int value, int min, int max, string description, string guid, string modName) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown ConfigEntry<int> obj = file.Bind<int>(section, name, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(min, max), Array.Empty<object>())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(obj, new IntSliderConfig { min = min, max = max }), guid, modName); return obj; } internal static ConfigEntry<bool> Checkbox(ConfigFile file, string section, string name, bool value, string description, string guid, string modName) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown ConfigEntry<bool> obj = file.Bind<bool>(section, name, value, description); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(obj), guid, modName); return obj; } } }