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 HappyHoarders v1.0.0
LC_HoardingBugSnacks.dll
Decompiled 2 years agousing 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; } } }