Decompiled source of YesFox v1.0.7

BepInEx/plugins/YesFox/YesFox.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using YesFox.Compatibility;

[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("YesFox")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.7.0")]
[assembly: AssemblyInformationalVersion("1.0.7+e2ffa9b6597cb7bea6bd4c54f62d30b942ffa117")]
[assembly: AssemblyProduct("YesFox")]
[assembly: AssemblyTitle("YesFox")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 YesFox
{
	[BepInPlugin("Dev1A3.YesFox", "YesFox", "1.0.0")]
	internal class Plugin : BaseUnityPlugin
	{
		internal const string modGUID = "Dev1A3.YesFox";

		internal const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("Dev1A3.YesFox");

		internal static ManualLogSource logSource;

		internal static List<GameObject> _networkPrefabs = new List<GameObject>();

		internal static ConfigEntry<bool> Shroud_AllMoons;

		internal static ConfigEntry<float> Shroud_SpawnChance_SameMoon;

		internal static ConfigEntry<float> Shroud_SpawnChance_OtherMoons;

		internal static ConfigEntry<int> Fox_MinimumWeeds;

		internal static ConfigEntry<int> Fox_SpawnChance;

		public static GameObject BushWolfAddonPrefab { get; internal set; }

		public static EnemyType BushWolfEnemyType { get; internal set; }

		private void Awake()
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			logSource = ((BaseUnityPlugin)this).Logger;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			harmony.PatchAll(executingAssembly);
			logSource.LogInfo((object)"Patches Loaded");
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "bush_wolf"));
			if ((Object)(object)val == (Object)null)
			{
				logSource.LogError((object)"[AssetBundle] Failed to load asset bundle: bush_wolf");
				return;
			}
			BushWolfAddonPrefab = val.LoadAsset<GameObject>("Assets/LethalCompany/Game/Prefabs/EnemyAI/BushWolfEnemy.prefab");
			if ((Object)(object)BushWolfAddonPrefab != (Object)null)
			{
				if (!_networkPrefabs.Contains(BushWolfAddonPrefab))
				{
					_networkPrefabs.Add(BushWolfAddonPrefab);
				}
				logSource.LogInfo((object)"[AssetBundle] Successfully loaded prefab: BushWolfEnemy");
			}
			else
			{
				logSource.LogError((object)"[AssetBundle] Failed to load prefab: BushWolfEnemy");
			}
			Shroud_AllMoons = ((BaseUnityPlugin)this).Config.Bind<bool>("Weed Spawning", "All Moons", false, "Should weeds be able to spawn on all moons excluding gordion?");
			Shroud_SpawnChance_SameMoon = ((BaseUnityPlugin)this).Config.Bind<float>("Weed Spawning", "Spawn Chance (Current Moon)", 8.5f, new ConfigDescription("What should the chance for them to initially spawn the moon you are routed to be? Weeds attempt to spawn on all moons when you go into orbit after each day.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			Shroud_SpawnChance_OtherMoons = ((BaseUnityPlugin)this).Config.Bind<float>("Weed Spawning", "Spawn Chance (Other Moons)", 4f, new ConfigDescription("What should the chance for them to initially spawn on other moons be? Weeds attempt to spawn on all moons when you go into orbit after each day.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			Fox_MinimumWeeds = ((BaseUnityPlugin)this).Config.Bind<int>("Fox Spawning", "Minimum Weeds", 30, "The minimum amount of weeds required to spawn");
			Fox_SpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("Fox Spawning", "Spawn Chance", -1, new ConfigDescription("What should the spawn chance be? If left as -1 then it will be the same as vanilla (a higher chance the more weeds there are)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 100), Array.Empty<object>()));
		}
	}
	[HarmonyPatch]
	internal static class HarmonyPatches
	{
		public static Random WeedEnemySpawnRandom;

		public static List<SpawnableEnemyWithRarity> WeedEnemies = new List<SpawnableEnemyWithRarity>();

		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void GameNetworkManager_Start(GameNetworkManager __instance)
		{
			if (__instance.gameVersionNum >= 64)
			{
				foreach (GameObject networkPrefab in Plugin._networkPrefabs)
				{
					if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(networkPrefab))
					{
						NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
					}
				}
			}
			else
			{
				foreach (GameObject networkPrefab2 in Plugin._networkPrefabs)
				{
					if (NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(networkPrefab2))
					{
						NetworkManager.Singleton.RemoveNetworkPrefab(networkPrefab2);
					}
				}
			}
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				LobbyCompatibility.Init(__instance.gameVersionNum);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "SetPlanetsMold")]
		[HarmonyPrefix]
		public static bool SetPlanetsMold(StartOfRound __instance)
		{
			if (!((NetworkBehaviour)__instance).IsOwner)
			{
				return false;
			}
			Random random = new Random(__instance.randomMapSeed + 32);
			Terminal val = Object.FindFirstObjectByType<Terminal>();
			for (int i = 0; i < __instance.levels.Length; i++)
			{
				if (i == 3 || (!__instance.levels[i].canSpawnMold && !Plugin.Shroud_AllMoons.Value))
				{
					Plugin.logSource.LogInfo((object)$"Skipping level #{i} {__instance.levels[i].PlanetName} mold iterations");
					continue;
				}
				if (__instance.levels[i].moldSpreadIterations > 0)
				{
					SelectableLevel obj = __instance.levels[i];
					obj.moldSpreadIterations++;
					Plugin.logSource.LogInfo((object)$"Increasing level #{i} {__instance.levels[i].PlanetName} mold iterations by 1; risen to {__instance.levels[i].moldSpreadIterations}");
					continue;
				}
				float num = (((Object)(object)__instance.levels[i] == (Object)(object)__instance.currentLevel) ? (Plugin.Shroud_SpawnChance_SameMoon.Value / 100f) : ((val.groupCredits < 200 && __instance.levels[i].levelID == 12) ? 0.05f : ((!((float)val.groupCredits < 500f) || (__instance.levels[i].levelID != 7 && __instance.levels[i].levelID != 6 && __instance.levels[i].levelID < 10) || (__instance.currentLevel.levelID != 5 && __instance.currentLevel.levelID != 8 && __instance.currentLevel.levelID != 4 && __instance.currentLevel.levelID > 2)) ? (Plugin.Shroud_SpawnChance_OtherMoons.Value / 100f) : 0.02f)));
				if (random.Next(0, 100) <= (int)(num * 100f))
				{
					SelectableLevel obj2 = __instance.levels[i];
					obj2.moldSpreadIterations += random.Next(1, 3);
					Plugin.logSource.LogInfo((object)$"Increasing level #{i} {__instance.levels[i].PlanetName} mold iterations for the first time; risen to {__instance.levels[i].moldSpreadIterations}");
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void StartOfRound_Start()
		{
			GenerateWeedEnemiesList();
		}

		public static void GenerateWeedEnemiesList()
		{
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			WeedEnemies.Clear();
			try
			{
				EnemyType val = ((IEnumerable<EnemyType>)Resources.FindObjectsOfTypeAll<EnemyType>()).FirstOrDefault((Func<EnemyType, bool>)((EnemyType x) => ((Object)x).name == "BushWolf" && (Object)(object)x.enemyPrefab != (Object)(object)Plugin.BushWolfAddonPrefab));
				EnemyType val2 = ((IEnumerable<EnemyType>)Resources.FindObjectsOfTypeAll<EnemyType>()).FirstOrDefault((Func<EnemyType, bool>)((EnemyType x) => ((Object)x).name == "BushWolf" && (Object)(object)x.enemyPrefab == (Object)(object)Plugin.BushWolfAddonPrefab));
				if (!((Object)(object)val != (Object)(object)val2))
				{
					return;
				}
				if ((Object)(object)val == (Object)null && (Object)(object)val2 != (Object)null)
				{
					val = val2;
					val2 = null;
				}
				if (!((Object)(object)val != (Object)null))
				{
					return;
				}
				if ((Object)(object)val2 != (Object)null)
				{
					if ((Object)(object)val2.enemyPrefab == (Object)(object)Plugin.BushWolfAddonPrefab)
					{
						Plugin.logSource.LogInfo((object)"[GenerateWeedEnemiesList] BushWolf: Renamed addon EnemyType name");
						((Object)val2).name = "BushWolfAddon";
					}
					GameObject enemyPrefab = val2.enemyPrefab;
					object obj;
					if (enemyPrefab == null)
					{
						obj = null;
					}
					else
					{
						GameObject gameObject = enemyPrefab.gameObject;
						obj = ((gameObject != null) ? gameObject.GetComponent<EnemyAI>() : null);
					}
					if (Object.op_Implicit((Object)obj))
					{
						val2.enemyPrefab.gameObject.GetComponent<EnemyAI>().enemyType = val;
						Plugin.logSource.LogInfo((object)"[GenerateWeedEnemiesList] BushWolf: Replaced addon EnemyAI enemyType");
					}
					if (GameNetworkManager.Instance.gameVersionNum >= 64)
					{
						GameObject enemyPrefab2 = val.enemyPrefab;
						SkinnedMeshRenderer[] array = ((enemyPrefab2 != null) ? enemyPrefab2.GetComponentsInChildren<SkinnedMeshRenderer>() : null);
						GameObject enemyPrefab3 = val2.enemyPrefab;
						SkinnedMeshRenderer[] array2 = ((enemyPrefab3 != null) ? enemyPrefab3.GetComponentsInChildren<SkinnedMeshRenderer>() : null);
						foreach (SkinnedMeshRenderer obj2 in array2)
						{
							((Renderer)obj2).material = ((Renderer)array[0]).material;
							((Renderer)obj2).materials = ((Renderer)array[0]).materials;
						}
						val.enemyPrefab = val2.enemyPrefab;
						Plugin.logSource.LogInfo((object)"[GenerateWeedEnemiesList] BushWolf: Replaced original EnemyType prefab");
					}
				}
				WeedEnemies.Add(new SpawnableEnemyWithRarity
				{
					enemyType = val,
					rarity = 100
				});
			}
			catch (Exception ex)
			{
				Plugin.logSource.LogError((object)ex);
			}
		}

		public static void SpawnWeedEnemies(int currentHour)
		{
			MoldSpreadManager val = Object.FindFirstObjectByType<MoldSpreadManager>();
			int num = 0;
			if ((Object)(object)val != (Object)null)
			{
				num = val.generatedMold.Count;
			}
			if (num <= Plugin.Fox_MinimumWeeds.Value)
			{
				Plugin.logSource.LogDebug((object)$"Weed enemies attempted to spawn but were denied. Reason: WeedCount | Amount: {num}");
				return;
			}
			if (Plugin.Fox_SpawnChance.Value >= 0)
			{
				int num2 = WeedEnemySpawnRandom.Next(1, 100);
				if (num2 > Plugin.Fox_SpawnChance.Value)
				{
					Plugin.logSource.LogDebug((object)$"Weed enemies attempted to spawn but were denied. Reason: SpawnChance | Amount: {num2}");
					return;
				}
			}
			else
			{
				int num3 = WeedEnemySpawnRandom.Next(0, 80);
				if (num3 > num)
				{
					Plugin.logSource.LogDebug((object)$"Weed enemies attempted to spawn but were denied. Reason: SpawnChance | Amount: {num3}");
					return;
				}
			}
			int num4 = WeedEnemySpawnRandom.Next(1, 3);
			GameObject[] spawnPoints = GameObject.FindGameObjectsWithTag("OutsideAINode");
			float timeUpToCurrentHour = TimeOfDay.Instance.lengthOfHours * (float)currentHour;
			if (WeedEnemies.Count == 0)
			{
				GenerateWeedEnemiesList();
				if (WeedEnemies.Count == 0)
				{
					Plugin.logSource.LogError((object)"Weed enemies attempted to spawn but were denied. Reason: ListEmpty");
					return;
				}
			}
			for (int i = 0; i < num4; i++)
			{
				if (!SpawnRandomWeedEnemy(spawnPoints, timeUpToCurrentHour, num))
				{
					break;
				}
			}
		}

		public static bool SpawnRandomWeedEnemy(GameObject[] spawnPoints, float timeUpToCurrentHour, int numberOfWeeds)
		{
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			RoundManager.Instance.SpawnProbabilities.Clear();
			int num = 0;
			for (int i = 0; i < WeedEnemies.Count; i++)
			{
				EnemyType enemyType = WeedEnemies[i].enemyType;
				if (RoundManager.Instance.firstTimeSpawningWeedEnemies)
				{
					enemyType.numberSpawned = 0;
				}
				if (enemyType.PowerLevel > RoundManager.Instance.currentMaxOutsidePower - RoundManager.Instance.currentOutsideEnemyPower || enemyType.numberSpawned >= enemyType.MaxCount || enemyType.spawningDisabled)
				{
					RoundManager.Instance.SpawnProbabilities.Add(0);
					Plugin.logSource.LogDebug((object)"A weed enemy attempted to spawn but was denied. Reason: Probability | Amount: 0");
					continue;
				}
				int num2 = ((RoundManager.Instance.increasedOutsideEnemySpawnRateIndex == i) ? 100 : ((!enemyType.useNumberSpawnedFalloff) ? ((int)((float)WeedEnemies[i].rarity * enemyType.probabilityCurve.Evaluate(timeUpToCurrentHour / RoundManager.Instance.timeScript.totalTime))) : ((int)((float)WeedEnemies[i].rarity * (enemyType.probabilityCurve.Evaluate(timeUpToCurrentHour / RoundManager.Instance.timeScript.totalTime) * enemyType.numberSpawnedFalloff.Evaluate((float)enemyType.numberSpawned / 10f))))));
				if (enemyType.spawnFromWeeds)
				{
					num2 = (int)Mathf.Clamp((float)num2 * ((float)numberOfWeeds / 60f), 0f, 200f);
				}
				RoundManager.Instance.SpawnProbabilities.Add(num2);
				num += num2;
			}
			RoundManager.Instance.firstTimeSpawningWeedEnemies = false;
			if (num <= 0)
			{
				Plugin.logSource.LogDebug((object)$"A weed enemy attempted to spawn but was denied. Reason: SpawnRate | Amount: {num}");
				return false;
			}
			bool result = false;
			int randomWeightedIndex = RoundManager.Instance.GetRandomWeightedIndex(RoundManager.Instance.SpawnProbabilities.ToArray(), WeedEnemySpawnRandom);
			EnemyType enemyType2 = WeedEnemies[randomWeightedIndex].enemyType;
			float num3 = Mathf.Max(enemyType2.spawnInGroupsOf, 1);
			for (int j = 0; (float)j < num3; j++)
			{
				float num4 = RoundManager.Instance.currentMaxOutsidePower - RoundManager.Instance.currentOutsideEnemyPower;
				if (enemyType2.PowerLevel > num4)
				{
					Plugin.logSource.LogDebug((object)$"A weed enemy attempted to spawn but was denied. Reason: PowerLevel | Amount: {num4}");
					break;
				}
				RoundManager instance = RoundManager.Instance;
				instance.currentOutsideEnemyPower += enemyType2.PowerLevel;
				Vector3 position = spawnPoints[RoundManager.Instance.AnomalyRandom.Next(0, spawnPoints.Length)].transform.position;
				position = RoundManager.Instance.GetRandomNavMeshPositionInBoxPredictable(position, 10f, default(NavMeshHit), RoundManager.Instance.AnomalyRandom, RoundManager.Instance.GetLayermaskForEnemySizeLimit(enemyType2));
				position = RoundManager.Instance.PositionWithDenialPointsChecked(position, spawnPoints, enemyType2);
				GameObject val = Object.Instantiate<GameObject>(enemyType2.enemyPrefab, position, Quaternion.Euler(Vector3.zero));
				val.GetComponentInChildren<NetworkObject>().Spawn(true);
				RoundManager.Instance.SpawnedEnemies.Add(val.GetComponent<EnemyAI>());
				EnemyType enemyType3 = val.GetComponent<EnemyAI>().enemyType;
				enemyType3.numberSpawned++;
				result = true;
			}
			Plugin.logSource.LogDebug((object)(enemyType2.enemyName + " attempted to spawn and was allowed"));
			return result;
		}

		[HarmonyPatch(typeof(RoundManager), "InitializeRandomNumberGenerators")]
		[HarmonyPostfix]
		public static void InitializeRandomNumberGenerators(RoundManager __instance)
		{
			WeedEnemySpawnRandom = new Random(__instance.playersManager.randomMapSeed + 42);
		}

		[HarmonyPatch(typeof(RoundManager), "AdvanceHourAndSpawnNewBatchOfEnemies")]
		[HarmonyPrefix]
		public static void AdvanceHourAndSpawnNewBatchOfEnemies(RoundManager __instance)
		{
			if (GameNetworkManager.Instance.gameVersionNum >= 64)
			{
				SpawnWeedEnemies(__instance.currentHour + __instance.hourTimeBetweenEnemySpawnBatches);
			}
		}

		[HarmonyPatch(typeof(BushWolfEnemy), "GetBiggestWeedPatch")]
		[HarmonyPostfix]
		public static void GetBiggestWeedPatch(BushWolfEnemy __instance, bool __result)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (__result && !Object.op_Implicit((Object)(object)GameObject.FindGameObjectWithTag("MoldAttractionPoint")))
			{
				__instance.aggressivePosition = __instance.mostHiddenPosition;
			}
		}
	}
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "YesFox";

		public const string PLUGIN_NAME = "YesFox";

		public const string PLUGIN_VERSION = "1.0.7";
	}
}
namespace YesFox.Compatibility
{
	internal class LobbyCompatibility
	{
		public static void Init(int versionNum)
		{
			Plugin.logSource.LogWarning((object)"LobbyCompatibility detected, registering plugin with LobbyCompatibility.");
			Version version = Version.Parse("1.0.7");
			PluginHelper.RegisterPlugin("YesFox", version, (CompatibilityLevel)((versionNum < 64) ? 1 : 2), (VersionStrictness)2);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}