Decompiled source of GuaranteedTurrets v1.0.0

GuaranteedTurrets.dll

Decompiled 12 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
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("GuaranteedTurrets")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GuaranteedTurrets")]
[assembly: AssemblyTitle("GuaranteedTurrets")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GuaranteedTurrets;

[BepInPlugin("Rei.GuaranteedTurrets", "GuaranteedTurrets", "1.0.0")]
public class GuaranteedTurretsPlugin : BaseUnityPlugin
{
	public const string PluginAuthor = "Rei";

	public const string PluginName = "GuaranteedTurrets";

	public const string PluginVersion = "1.0.0";

	public const string PluginGUID = "Rei.GuaranteedTurrets";

	private const string TurretSpawnCardKey = "RoR2/Base/Drones/iscBrokenTurret1.asset";

	private const int SpawnAttemptsPerTurret = 10;

	private ConfigEntry<int> minimumTurrets;

	private ConfigEntry<int> maximumTurrets;

	private ConfigEntry<bool> countNaturalTurrets;

	private InteractableSpawnCard turretCard;

	private bool turretCardLoadFailed;

	private void Awake()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		minimumTurrets = ((BaseUnityPlugin)this).Config.Bind<int>("Turrets", "Minimum", 2, new ConfigDescription("Every normal stage is guaranteed at least this many Gunner Turrets.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>()));
		maximumTurrets = ((BaseUnityPlugin)this).Config.Bind<int>("Turrets", "Maximum", 4, new ConfigDescription("Each stage rolls a random target between Minimum and Maximum (inclusive). Set it equal to Minimum for a fixed count. Values below Minimum are treated as Minimum.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>()));
		countNaturalTurrets = ((BaseUnityPlugin)this).Config.Bind<bool>("Turrets", "CountNaturalTurrets", true, "If true, turrets the game spawned on its own count toward the target, so only the missing ones are added. If false, the rolled amount is always added on top of natural spawns. Natural turrets are never removed.");
		SceneDirector.onPostPopulateSceneServer += OnPostPopulateSceneServer;
	}

	private void OnDestroy()
	{
		SceneDirector.onPostPopulateSceneServer -= OnPostPopulateSceneServer;
	}

	private void OnPostPopulateSceneServer(SceneDirector sceneDirector)
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Expected O, but got Unknown
		if (!NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance) || !Object.op_Implicit((Object)(object)DirectorCore.instance) || !IsNormalStage())
		{
			return;
		}
		InteractableSpawnCard val = GetTurretCard();
		if (!Object.op_Implicit((Object)(object)val))
		{
			return;
		}
		int value = minimumTurrets.Value;
		int num = Math.Max(value, maximumTurrets.Value);
		Xoroshiro128Plus val2 = new Xoroshiro128Plus(Run.instance.seed + (ulong)Run.instance.stageClearCount);
		int num2 = val2.RangeInt(value, num + 1);
		int num3 = CountTurrets(val);
		int num4 = (countNaturalTurrets.Value ? (num2 - num3) : num2);
		int num5 = 0;
		for (int i = 0; i < num4; i++)
		{
			if (TrySpawnTurret(val, val2))
			{
				num5++;
			}
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)($"{SceneCatalog.mostRecentSceneDef.cachedName}: rolled {num2} (range {value}-{num}), " + $"{num3} natural, spawned {num5}" + ((num5 < num4) ? $" of {num4} (no room for the rest)" : "")));
	}

	private static bool IsNormalStage()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Invalid comparison between Unknown and I4
		if (Run.instance is InfiniteTowerRun)
		{
			return false;
		}
		SceneDef mostRecentSceneDef = SceneCatalog.mostRecentSceneDef;
		if (Object.op_Implicit((Object)(object)mostRecentSceneDef) && (int)mostRecentSceneDef.sceneType == 1)
		{
			return !mostRecentSceneDef.isFinalStage;
		}
		return false;
	}

	private InteractableSpawnCard GetTurretCard()
	{
		//IL_001b: 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)
		if (!Object.op_Implicit((Object)(object)turretCard) && !turretCardLoadFailed)
		{
			try
			{
				turretCard = Addressables.LoadAssetAsync<InteractableSpawnCard>((object)"RoR2/Base/Drones/iscBrokenTurret1.asset").WaitForCompletion();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
			}
			if (!Object.op_Implicit((Object)(object)turretCard))
			{
				turretCardLoadFailed = true;
				((BaseUnityPlugin)this).Logger.LogError((object)"Could not load the Gunner Turret spawn card from 'RoR2/Base/Drones/iscBrokenTurret1.asset'. No turrets will be added.");
			}
		}
		return turretCard;
	}

	private static int CountTurrets(InteractableSpawnCard card)
	{
		string name = ((Object)((SpawnCard)card).prefab).name;
		int num = 0;
		PurchaseInteraction[] array = Object.FindObjectsOfType<PurchaseInteraction>();
		for (int i = 0; i < array.Length; i++)
		{
			if (((Object)((Component)array[i]).gameObject).name.StartsWith(name, StringComparison.Ordinal))
			{
				num++;
			}
		}
		return num;
	}

	private static bool TrySpawnTurret(InteractableSpawnCard card, Xoroshiro128Plus rng)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		DirectorPlacementRule val = new DirectorPlacementRule
		{
			placementMode = (PlacementMode)4
		};
		for (int i = 0; i < 10; i++)
		{
			if (Object.op_Implicit((Object)(object)DirectorCore.instance.TrySpawnObject(new DirectorSpawnRequest((SpawnCard)(object)card, val, rng))))
			{
				return true;
			}
		}
		return false;
	}
}