Decompiled source of HappyHoarders v1.0.0

LC_HoardingBugSnacks.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LC_HoardingBugSnacks.Patches;
using LethalLib.Modules;
using RuntimeNetcodeRPCValidator;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LC_HoardingBugSnacks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Aca")]
[assembly: AssemblyProduct("LC_HoardingBugSnacks")]
[assembly: AssemblyCopyright("Copyright © Aca 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("8a19c370-df01-4355-878e-94a5f517f97b")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LC_HoardingBugSnacks
{
	[BepInPlugin("Mellowdy.HoardingBugSnacks", "HoardingBugSnacks", "1.0.1")]
	[BepInDependency("NicholaScott.BepInEx.RuntimeNetcodeRPCValidator", "0.2.5")]
	public class HoardingBugSnacksMod : BaseUnityPlugin
	{
		private const string modGUID = "Mellowdy.HoardingBugSnacks";

		private const string modName = "HoardingBugSnacks";

		private const string modVersion = "1.0.1";

		private const string assetName = "bug.snack";

		private const string gameObjectName = "BugSnacks.prefab";

		private readonly Harmony harmony = new Harmony("Mellowdy.HoardingBugSnacks");

		private NetcodeValidator validator = new NetcodeValidator("Mellowdy.HoardingBugSnacks");

		public static ManualLogSource mls;

		public static HoardingBugSnacksMod instance;

		private static string Name = "Hoarding Bug Snacks";

		private static string Description = "Use to sedate the common hoarding bug by means of peace offering.";

		private static ConfigEntry<int> price;

		public static ConfigEntry<int> friendlyTime;

		public static ConfigEntry<int> danceTime;

		public static ConfigEntry<int> bugsToSpawn;

		public static ConfigEntry<int> randomBugsToSpawn;

		public static ConfigEntry<int> shotgunChance;

		public static Item shotgunItem;

		public static EnemyType hoarderType;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			mls = Logger.CreateLogSource("Mellowdy.HoardingBugSnacks");
			harmony.PatchAll(typeof(SpawnPatch));
			harmony.PatchAll();
			validator.PatchAll();
			price = ((BaseUnityPlugin)this).Config.Bind<int>("Item", "Price", 10, "");
			friendlyTime = ((BaseUnityPlugin)this).Config.Bind<int>("Item", "Friendliness", 60, "How long are the bugs friendly for? (in seconds)");
			danceTime = ((BaseUnityPlugin)this).Config.Bind<int>("Item", "Dance", 10, "How long should the bugs dance for? (in seconds)");
			bugsToSpawn = ((BaseUnityPlugin)this).Config.Bind<int>("Bugs", "Spawn Always", 1, "How many bugs should always spawn at the start of a round");
			randomBugsToSpawn = ((BaseUnityPlugin)this).Config.Bind<int>("Bugs", "Spawn Random", 3, "How many bugs extra bugs CAN randomly spawn in addition to the guaranteed bugs");
			shotgunChance = ((BaseUnityPlugin)this).Config.Bind<int>("Bugs", "Shotgun chance", 10, "Chance for bug to spawn with a shotgun (100 = 100%) (they found the US constitution and really liked the second part)");
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = Path.Combine(directoryName, "bug.snack").Replace("\\", "/");
			mls.LogMessage((object)text);
			AssetBundle val = AssetBundle.LoadFromFile(text);
			Item val2 = val.LoadAsset<Item>("BugSnacks.asset");
			GameObject val3 = val.LoadAsset<GameObject>("BugSnacks.prefab");
			BugSnacks bugSnacks = val3.AddComponent<BugSnacks>();
			((GrabbableObject)bugSnacks).useCooldown = 1f;
			((GrabbableObject)bugSnacks).itemProperties = val2;
			((GrabbableObject)bugSnacks).grabbable = true;
			((GrabbableObject)bugSnacks).grabbableToEnemies = true;
			bugSnacks.shake = val.LoadAsset<AudioClip>("shake.wav");
			Items.RegisterItem(val2);
			Items.RegisterShopItem(val2, (TerminalNode)null, (TerminalNode)null, CreateInfoNode(Name, Description), price.Value);
			mls.LogInfo((object)"HoardingBugSnacks is active");
		}

		private TerminalNode CreateInfoNode(string name, string description)
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			val.clearPreviousText = true;
			((Object)val).name = name + "InfoNode";
			val.displayText = description + "\n\n";
			return val;
		}
	}
}
namespace LC_HoardingBugSnacks.Patches
{
	public class BugSnacks : GrabbableObject
	{
		public static float BugHappiness;

		private AudioSource audio;

		public AudioClip shake;

		public override void Start()
		{
			((GrabbableObject)this).Start();
			audio = ((Component)this).GetComponent<AudioSource>();
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (buttonDown)
			{
				audio.PlayOneShot(shake);
				base.playerHeldBy.playerBodyAnimator.SetTrigger("shakeItem");
				MakeBugsDanceServerRpc(((Component)this).transform, 1, 5f);
			}
		}

		public override void Update()
		{
			((GrabbableObject)this).Update();
		}

		public override void GrabItemFromEnemy(EnemyAI enemy)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			((GrabbableObject)this).GrabItemFromEnemy(enemy);
			if ((Object)(object)enemy != (Object)null && enemy is HoarderBugAI)
			{
				HoarderBugAI val = (HoarderBugAI)enemy;
				MakeBugsDanceServerRpc(((Component)val).transform, HoardingBugSnacksMod.danceTime.Value, 100f);
				BecomeFriends(val, HoardingBugSnacksMod.friendlyTime.Value, allBugs: true, (GrabbableObject)(object)this, base.playerHeldBy);
			}
		}

		public static void BecomeFriends(HoarderBugAI mainBug, float friendAmount, bool allBugs = true, GrabbableObject held = null, PlayerControllerB player = null)
		{
			mainBug.BecomeFriends(friendAmount, held, player);
			if (allBugs)
			{
				HoarderBugAI[] array = Object.FindObjectsOfType<HoarderBugAI>();
				foreach (HoarderBugAI original in array)
				{
					original.BecomeFriends(friendAmount, held, player);
				}
			}
		}

		[ServerRpc]
		public static void MakeBugsDanceServerRpc(Transform pos, int time, float range)
		{
			MakeBugsDanceClientRpc(pos, time, range);
		}

		[ClientRpc]
		public static void MakeBugsDanceClientRpc(Transform pos, int time, float range)
		{
			MakeBugsDance(pos, time, range);
		}

		public static void MakeBugsDance(Transform pos, int time, float range)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!(range > 0.5f))
			{
				return;
			}
			HoarderBugAI[] array = Object.FindObjectsOfType<HoarderBugAI>();
			HoarderBugAI[] array2 = array;
			foreach (HoarderBugAI val in array2)
			{
				if (Vector3.Distance(((Component)val).transform.position, pos.position) < range)
				{
					val.StartDance(time);
				}
			}
		}
	}
	public static class ExtensionMethod
	{
		public static void BecomeFriends(this HoarderBugAI original, float amount, GrabbableObject held = null, PlayerControllerB player = null)
		{
			Type typeFromHandle = typeof(HoarderBugAI);
			FieldInfo field = typeFromHandle.GetField("annoyanceMeter", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field != null)
			{
				float num = (float)field.GetValue(original);
				field.SetValue(original, num - amount);
			}
			original.targetItem = held;
			original.angryAtPlayer = null;
			if ((Object)(object)player != (Object)null)
			{
				original.watchingPlayer = player;
			}
			BugSnacks.BugHappiness += amount;
		}

		public static void StartDance(this HoarderBugAI original, float duration)
		{
			float startY = 2f;
			((MonoBehaviour)original).StopAllCoroutines();
			original.BecomeFriends(0.5f);
			((MonoBehaviour)original).StartCoroutine((IEnumerator)original.Dance(duration, startY));
		}

		public static IEnumerator<WaitForEndOfFrame> Dance(this HoarderBugAI original, float duration, float startY)
		{
			float Amplitude = 0.4f;
			float Frequency = (float)Math.PI * 10f;
			Transform chestTrans = original.animationContainer.Find("Armature").Find("Abdomen").Find("Chest");
			float time = 0f;
			while (time < duration)
			{
				chestTrans.localPosition = new Vector3(chestTrans.localPosition.x, startY + Mathf.Sin(time * Frequency) * Amplitude, chestTrans.localPosition.z);
				time += Time.deltaTime;
				yield return new WaitForEndOfFrame();
			}
			chestTrans.localPosition = new Vector3(chestTrans.localPosition.x, startY, chestTrans.localPosition.z);
		}
	}
	internal class SpawnPatch
	{
		public static HoarderBugItem tempShotgun;

		[HarmonyPatch(typeof(RoundManager), "Awake")]
		[HarmonyPostfix]
		public static void FindShotgun()
		{
			List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
			HoardingBugSnacksMod.shotgunItem = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item i) => ((Object)i).name.Equals("Shotgun")));
		}

		[HarmonyPatch(typeof(RoundManager), "LoadNewLevelWait")]
		[HarmonyPostfix]
		public static void SpawnExtraHoardingBugs(RoundManager __instance)
		{
			int num = 2;
			if (((NetworkBehaviour)__instance).NetworkManager.IsHost || ((NetworkBehaviour)__instance).NetworkManager.IsServer)
			{
				((MonoBehaviour)__instance).StartCoroutine(FinishedLoading(__instance));
			}
		}

		public static IEnumerator FinishedLoading(RoundManager instance)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => instance.dungeonCompletedGenerating));
			yield return null;
			yield return (object)new WaitUntil((Func<bool>)(() => instance.playersFinishedGeneratingFloor.Count >= GameNetworkManager.Instance.connectedPlayers));
			yield return (object)new WaitForSeconds(5f);
			float x = Random.Range(-25f, 25f);
			float z = Random.Range(-25f, 25f);
			Vector3 spawnPos = new Vector3(-4.3f + Random.Range(-5f, 5f) + x, -219.5f, 66f + Random.Range(-5f, 5f) + z);
			Transform node;
			do
			{
				node = ChooseClosestNodeToPosition(spawnPos);
				yield return (object)new WaitForSeconds(1f);
			}
			while ((Object)(object)node == (Object)null);
			Vector3 realSpawnPos = node.position;
			int numToSpawn = HoardingBugSnacksMod.bugsToSpawn.Value + Random.Range(0, HoardingBugSnacksMod.randomBugsToSpawn.Value);
			for (int i = 0; i < numToSpawn; i++)
			{
				instance.SpawnEnemyOnServer(realSpawnPos, 0f, 2);
			}
		}

		public static Transform ChooseClosestNodeToPosition(Vector3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			GameObject[] source = GameObject.FindGameObjectsWithTag("AINode");
			GameObject[] source2 = source.OrderBy((GameObject x) => Vector3.Distance(pos, x.transform.position)).ToArray();
			return source2.First().transform;
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		private static void SetHoarderType(StartOfRound __instance)
		{
			SelectableLevel[] levels = __instance.levels;
			SelectableLevel[] array = levels;
			foreach (SelectableLevel val in array)
			{
				foreach (SpawnableEnemyWithRarity enemy in val.Enemies)
				{
					if (!(((Object)enemy.enemyType).name == "HoarderBug"))
					{
						continue;
					}
					if ((Object)(object)HoardingBugSnacksMod.hoarderType == (Object)null)
					{
						enemy.enemyType.isOutsideEnemy = false;
						HoardingBugSnacksMod.hoarderType = enemy.enemyType;
					}
					break;
				}
			}
		}

		[HarmonyPatch(typeof(HoarderBugAI), "Start")]
		[HarmonyPostfix]
		public static void SpawnWithShotgun(HoarderBugAI __instance)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)HoardingBugSnacksMod.shotgunChance.Value / 100f;
			if (num > Random.Range(0f, 1f))
			{
				GameObject val = Object.Instantiate<GameObject>(HoardingBugSnacksMod.shotgunItem.spawnPrefab, ((Component)__instance).transform.position, Quaternion.identity);
				NetworkObject component = val.GetComponent<NetworkObject>();
				ShotgunItem component2 = val.GetComponent<ShotgunItem>();
				Item itemProperties = ((GrabbableObject)component2).itemProperties;
				((GrabbableObject)component2).SetScrapValue(Random.Range(itemProperties.minValue, itemProperties.maxValue) / 4);
				component2.shellsLoaded = 2;
				component2.safetyOn = false;
				component.Spawn(false);
				((EnemyAI)__instance).SwitchToBehaviourStateOnLocalClient(1);
				__instance.GrabItemServerRpc(NetworkObjectReference.op_Implicit(component));
			}
		}

		[HarmonyPatch(typeof(HoarderBugAI), "DropItem")]
		[HarmonyPrefix]
		public static void DontDropIfShotgun(HoarderBugAI __instance)
		{
			if (__instance.heldItem != null && (__instance.heldItem.itemGrabbableObject is ShotgunItem || __instance.heldItem.itemGrabbableObject is BugSnacks))
			{
				tempShotgun = __instance.heldItem;
			}
		}

		[HarmonyPatch(typeof(HoarderBugAI), "DropItem")]
		[HarmonyPostfix]
		public static void PickBackUpIfShotgun(HoarderBugAI __instance)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.heldItem == null && tempShotgun != null)
			{
				__instance.GrabItemServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)tempShotgun.itemGrabbableObject).NetworkObject));
				tempShotgun = null;
			}
		}

		[HarmonyPatch(typeof(HoarderBugAI), "IsHoarderBugAngry")]
		[HarmonyPrefix]
		public static bool MakeNotAngryWhenSnacks(HoarderBugAI __instance)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Invalid comparison between Unknown and I4
			if (BugSnacks.BugHappiness > 0f)
			{
				BugSnacks.BugHappiness -= Time.deltaTime;
				return false;
			}
			if (((EnemyAI)__instance).stunNormalizedTimer > 0f)
			{
				__instance.angryTimer = 4f;
				if (Object.op_Implicit((Object)(object)((EnemyAI)__instance).stunnedByPlayer))
				{
					__instance.angryAtPlayer = ((EnemyAI)__instance).stunnedByPlayer;
				}
				return true;
			}
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < HoarderBugAI.HoarderBugItems.Count; i++)
			{
				if ((int)HoarderBugAI.HoarderBugItems[i].status == 1)
				{
					num2++;
				}
				else if ((int)HoarderBugAI.HoarderBugItems[i].status == 2)
				{
					num++;
				}
			}
			if (!(__instance.angryTimer > 0f))
			{
				return num2 > 0;
			}
			return true;
		}
	}
}