Decompiled source of EnemySpawner v1.1.0

EnemySpawnerPlugin.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EnemySpawnerPlugin")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+f02a22e5a94ef60757c181ae25f6280ed6af8194")]
[assembly: AssemblyProduct("EnemySpawnerPlugin")]
[assembly: AssemblyTitle("EnemySpawnerPlugin")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace EnemySpawnerPlugin;

[BepInPlugin("TitaniumTurbine.EnemySpawner", "EnemySpawner.Plugin", "1.0.0")]
public class EnemySpawnerPlugin : BaseUnityPlugin
{
	private static int outsideMinCount;

	private static int outsideMaxCount;

	private static List<string> outsideNames;

	private static float outsideSpawnChance;

	private static int insideMinCount;

	private static int insideMaxCount;

	private static List<string> insideNames;

	private static float insideSpawnChance;

	private static bool insideSpawned;

	private static float playerCountScaling;

	private static bool onlyScaleMax;

	private void Awake()
	{
		ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("Outside Enemies", "OutsideMinCount", 1, "Minimum enemies to spawn outside when you land");
		ConfigEntry<int> val2 = ((BaseUnityPlugin)this).Config.Bind<int>("Outside Enemies", "OutsideMaxCount", 1, "Maximum enemies to spawn outside when you land");
		ConfigEntry<string> val3 = ((BaseUnityPlugin)this).Config.Bind<string>("Outside Enemies", "OutsideNames", "", "The IDs of the enemy types to spawn outside, separated by commas. Leave blank to select all enemies. All enemy IDs will be printed to the BepInEx console when loading a moon.\nExample: Flowerman,Crawler,MouthDog");
		ConfigEntry<float> val4 = ((BaseUnityPlugin)this).Config.Bind<float>("Outside Enemies", "OutsideSpawnChance", 1f, "Chance of spawning enemies outside when you land");
		ConfigEntry<int> val5 = ((BaseUnityPlugin)this).Config.Bind<int>("Inside Enemies", "InsideMinCount", 0, "Minimum enemies to spawn inside when you land");
		ConfigEntry<int> val6 = ((BaseUnityPlugin)this).Config.Bind<int>("Inside Enemies", "InsideMaxCount", 0, "Maximum enemies to spawn inside when you land");
		ConfigEntry<string> val7 = ((BaseUnityPlugin)this).Config.Bind<string>("Inside Enemies", "InsideNames", "", "The IDs of the enemy types to spawn outside, separated by commas. Leave blank to select all enemies. All enemy IDs will be printed to the BepInEx console when loading a moon.\nExample: Flowerman,Crawler,MouthDog");
		ConfigEntry<float> val8 = ((BaseUnityPlugin)this).Config.Bind<float>("Inside Enemies", "InsideSpawnChance", 0f, "Chance of spawning enemies inside when you land");
		ConfigEntry<float> val9 = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PlayerCountScaling", 0f, "Multiplier for the min and max counts to scale with number of players.\ncount = count * playerCountScaling * numberOfPlayers\nSet to 0 to disable scaling with player count.");
		ConfigEntry<bool> val10 = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OnlyScaleMax", false, "Only apply player count scaling to the max enemy counts");
		outsideMinCount = val.Value;
		outsideMaxCount = val2.Value;
		outsideSpawnChance = val4.Value;
		insideMinCount = val5.Value;
		insideMaxCount = val6.Value;
		insideSpawnChance = val8.Value;
		playerCountScaling = val9.Value;
		onlyScaleMax = val10.Value;
		outsideNames = val3.Value.Split(",").ToList();
		insideNames = val7.Value.Split(",").ToList();
		Harmony.CreateAndPatchAll(typeof(EnemySpawnerPlugin), (string)null);
	}

	private static List<SpawnableEnemyWithRarity> GetEnemies()
	{
		Debug.Log((object)"GETTING ENEMIES");
		List<SpawnableEnemyWithRarity> list = new List<SpawnableEnemyWithRarity>();
		list = (from x in GameObject.Find("Terminal").GetComponentInChildren<Terminal>().moonsCatalogueList.SelectMany((SelectableLevel x) => x.Enemies.Concat(x.DaytimeEnemies).Concat(x.OutsideEnemies))
			where x != null && (Object)(object)x.enemyType != (Object)null && ((Object)x.enemyType).name != null
			select x).GroupBy((SpawnableEnemyWithRarity x) => ((Object)x.enemyType).name, (string k, IEnumerable<SpawnableEnemyWithRarity> v) => v.First()).ToList();
		Debug.Log((object)$"Enemy types: {list.Count}");
		return list;
	}

	[HarmonyPatch(typeof(EnemyAI), "PlayerIsTargetable")]
	[HarmonyPrefix]
	private static bool PatchTargetable(object[] __args, ref bool __result, ref EnemyAI __instance)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		PlayerControllerB val = (PlayerControllerB)__args[0];
		bool flag = (bool)__args[1];
		bool flag2 = true;
		if (flag && val.isInHangarShipRoom)
		{
			__result = false;
			return false;
		}
		if (val.isPlayerControlled && !val.isPlayerDead && (Object)(object)val.inAnimationWithEnemy == (Object)null && (flag2 || val.isInsideFactory != __instance.isOutside) && val.sinkingValue < 0.73f)
		{
			if (__instance.isOutside && StartOfRound.Instance.hangarDoorsClosed)
			{
				__result = val.isInHangarShipRoom == __instance.isInsidePlayerShip;
				return false;
			}
			__result = true;
			return false;
		}
		__result = false;
		return false;
	}

	[HarmonyPatch(typeof(EnemyVent), "Start")]
	[HarmonyPostfix]
	private static void SpawnInsideEnemies()
	{
		Random random = new Random();
		RoundManager instance = RoundManager.Instance;
		int connectedPlayers = GameNetworkManager.Instance.connectedPlayers;
		float num = ((playerCountScaling > 0f) ? ((float)connectedPlayers * playerCountScaling) : 1f);
		if (!insideSpawned && random.NextDouble() < (double)insideSpawnChance && (((NetworkBehaviour)instance).NetworkManager.IsServer || ((NetworkBehaviour)instance).NetworkManager.IsHost))
		{
			GameObject[] array = GameObject.FindGameObjectsWithTag("EnemySpawn");
			List<SpawnableEnemyWithRarity> enemies = GetEnemies();
			List<string> list = enemies.Select((SpawnableEnemyWithRarity x) => ((Object)x.enemyType).name).ToList();
			int minValue = (onlyScaleMax ? insideMinCount : ((int)((float)insideMinCount * num)));
			int maxValue = (int)((float)insideMaxCount * num);
			IEnumerable<string> source = insideNames.Intersect(list);
			List<string> source2 = ((source.Count() > 0) ? insideNames : list);
			for (int i = 0; i < random.Next(minValue, maxValue); i++)
			{
				string text = source2.ElementAt(random.Next(insideNames.Count()));
				Debug.Log((object)("Spawning a " + text + " inside"));
				SpawnEnemyFromVent(array[i % array.Length].GetComponent<EnemyVent>(), instance, text);
			}
			insideSpawned = true;
		}
	}

	[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
	[HarmonyPostfix]
	private static void SpawnOutsideEnemies()
	{
		Random random = new Random();
		RoundManager instance = RoundManager.Instance;
		int connectedPlayers = GameNetworkManager.Instance.connectedPlayers;
		float num = ((playerCountScaling > 0f) ? ((float)connectedPlayers * playerCountScaling) : 1f);
		if (!(random.NextDouble() < (double)outsideSpawnChance) || (!((NetworkBehaviour)instance).NetworkManager.IsServer && !((NetworkBehaviour)instance).NetworkManager.IsHost))
		{
			return;
		}
		List<SpawnableEnemyWithRarity> enemies = GetEnemies();
		List<string> list = enemies.Select((SpawnableEnemyWithRarity x) => ((Object)x.enemyType).name).ToList();
		foreach (string item in list)
		{
			Debug.Log((object)item);
		}
		int minValue = (onlyScaleMax ? outsideMinCount : ((int)((float)outsideMinCount * num)));
		int maxValue = (int)((float)outsideMaxCount * num);
		IEnumerable<string> source = outsideNames.Intersect(list);
		List<string> source2 = ((source.Count() > 0) ? outsideNames : list);
		for (int i = 0; i < random.Next(minValue, maxValue); i++)
		{
			string text = source2.ElementAt(random.Next(source2.Count()));
			Debug.Log((object)("Spawning a " + text + " outside"));
			SpawnEnemyOutside(instance, text);
		}
	}

	private static void SpawnEnemyFromVent(EnemyVent vent, RoundManager rm, string enemyName)
	{
		//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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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)
		Debug.Log((object)"SpawnEnemyFromVent");
		Vector3 position = vent.floorNode.position;
		float y = vent.floorNode.eulerAngles.y;
		EnemyType enemyType = GetEnemies().Find((SpawnableEnemyWithRarity x) => ((Object)x.enemyType).name == enemyName).enemyType;
		enemyType.isOutsideEnemy = false;
		NetworkObjectReference val = rm.SpawnEnemyGameObject(position, y, vent.enemyTypeIndex, enemyType);
	}

	private static void SpawnEnemyOutside(RoundManager rm, string enemyName)
	{
		//IL_003a: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: 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_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)"SpawnEnemyOutside");
		GameObject[] array = GameObject.FindGameObjectsWithTag("OutsideAINode");
		Vector3 position = array[rm.AnomalyRandom.Next(0, array.Length)].transform.position;
		position = rm.GetRandomNavMeshPositionInRadius(position, 4f, default(NavMeshHit));
		Debug.Log((object)$"Anomaly random 4: {position.x}, {position.y}, {position.z}");
		EnemyType enemyType = GetEnemies().Find((SpawnableEnemyWithRarity x) => ((Object)x.enemyType).name == enemyName).enemyType;
		enemyType.isOutsideEnemy = true;
		NetworkObjectReference val = rm.SpawnEnemyGameObject(position, 0f, 0, enemyType);
	}
}