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;
}
}
}