Decompiled source of LoudParrots v1.2.5

UpdatedLethalCompanyMod.dll

Decompiled 3 months 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 HarmonyLib;
using LethalLib.Modules;
using UnityEngine;
using UpdatedLethalCompanyMod.Behaviours;
using UpdatedLethalCompanyMod.birds;
using UpdatedLethalCompanyMod.models;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("UpdatedLethalCompanyMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UpdatedLethalCompanyMod")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a7a9aa61-5974-475c-8eba-9495fb670e2b")]
[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 UpdatedLethalCompanyMod
{
	public enum BirdSpecies
	{
		Parrot,
		GoldFinch,
		Crow,
		Robin,
		Cardinal,
		LittleBird,
		BlueJayBird,
		Sparrow
	}
	public class MyConfig
	{
		public static ConfigEntry<string> configGreeting;

		public static ConfigEntry<bool> configDisplayGreeting;

		public static Dictionary<BirdSpecies, ConfigEntry<int>> spawnChancePerSpecies = new Dictionary<BirdSpecies, ConfigEntry<int>>();

		public static Dictionary<BirdSpecies, ConfigEntry<float>> monsterDetectionRangePerSpecies = new Dictionary<BirdSpecies, ConfigEntry<float>>();

		public static Dictionary<BirdSpecies, ConfigEntry<float>> monsterDetectionFrequencyPerSpecies = new Dictionary<BirdSpecies, ConfigEntry<float>>();

		public static Dictionary<BirdSpecies, ConfigEntry<float>> chirpVolumePerSpecies = new Dictionary<BirdSpecies, ConfigEntry<float>>();

		public static Dictionary<BirdSpecies, ConfigEntry<int>> peckRarityPerSpecies = new Dictionary<BirdSpecies, ConfigEntry<int>>();

		public MyConfig(ConfigFile cfg)
		{
			foreach (BirdSpecies value in Enum.GetValues(typeof(BirdSpecies)))
			{
				spawnChancePerSpecies[value] = cfg.Bind<int>("Birds." + value, "SpawnChance", 6, "Spawn chance for " + value.ToString() + " (0-1000) Recommended to keep between 0 and 100. Higher value means higher amount spawning");
				chirpVolumePerSpecies[value] = cfg.Bind<float>("Birds." + value, "ChirpVolume", 1f, "Chirp volume for " + value.ToString() + " (1 is just normal)");
			}
		}
	}
	public class ModInfo
	{
		public struct BirdInfo
		{
			public BirdSpecies species;

			public int peckDamage;

			public int peckChance;

			public List<string> peckMessages;

			public List<AudioClip> idleChirps;

			public List<AudioClip> warningChirps;

			public BirdInfo(BirdSpecies species, int peckDamage, int peckChance, List<string> peckMessages, List<AudioClip> idleChirps, List<AudioClip> warningChirps)
			{
				this.species = species;
				this.peckDamage = peckDamage;
				this.peckChance = peckChance;
				this.peckMessages = peckMessages;
				this.idleChirps = idleChirps;
				this.warningChirps = warningChirps;
			}
		}

		public const string modGUID = "Cas.LoudParrots";

		public const string modName = "Loud parrots";

		public const string modVersion = "1.2.5";

		public List<AudioClip> warningchirpsAudio = new List<AudioClip>();

		public Dictionary<BirdSpecies, List<AudioClip>> birdAudiosIdle = new Dictionary<BirdSpecies, List<AudioClip>>();

		public Dictionary<BirdSpecies, BirdInfo> birdInfos = new Dictionary<BirdSpecies, BirdInfo>();

		public static ModInfo Instance { get; private set; }

		public static List<string> GetPeckMessages(BirdSpecies species)
		{
			string text = species.ToString().ToLower();
			string[] source = new string[10]
			{
				"You were pecked by the " + text + "!",
				"The " + text + " gave you a little peck!",
				"You got a friendly peck from the " + text + "!",
				"The " + text + " decided to give you a peck!",
				"You received a gentle peck from the " + text + "!",
				"The " + text + " playfully pecked you!",
				"A peck from the " + text + " just landed on you!",
				"You felt the " + text + "'s beak with a light peck!",
				"The " + text + " greeted you with a quick peck!",
				"You were surprised by a sudden " + text + " peck!"
			};
			return source.ToList();
		}

		public ModInfo(List<AudioClip> warningchirpsAudio, Dictionary<BirdSpecies, List<AudioClip>> birdIdles, Dictionary<BirdSpecies, BirdInfo> birdInfos)
		{
			Instance = this;
			this.warningchirpsAudio = warningchirpsAudio;
			birdAudiosIdle = birdIdles;
			this.birdInfos = birdInfos;
		}

		public float GetRandomIntervalMax(float normal)
		{
			if (normal < 1f)
			{
				return Random.Range(1f, 1.5f);
			}
			return Random.Range(normal - 0.3f, normal + 0.5f);
		}

		public AudioClip GetRandomIdleChirpForBird(BirdSpecies species)
		{
			BirdInfo birdInfo = birdInfos[species];
			return birdInfo.idleChirps[Random.Range(0, birdInfo.idleChirps.Count)];
		}

		public AudioClip GetRandomWarningChirpForBird(BirdSpecies species)
		{
			if (Random.Range(0, 10) > 5)
			{
				return birdInfos[BirdSpecies.Parrot].warningChirps[Random.Range(0, birdInfos[BirdSpecies.Parrot].warningChirps.Count)];
			}
			BirdInfo birdInfo = birdInfos[species];
			return birdInfo.warningChirps[Random.Range(0, birdInfo.warningChirps.Count)];
		}

		public string GetPeckMessageForBird(BirdSpecies species)
		{
			BirdInfo birdInfo = birdInfos[species];
			return birdInfo.peckMessages[Random.Range(0, birdInfo.peckMessages.Count)];
		}
	}
	[BepInPlugin("Cas.LoudParrots", "Loud parrots", "1.2.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MyCustomLethalCompanyMod : BaseUnityPlugin
	{
		public static AssetBundle MyCustomAssets;

		private readonly Harmony harmony = new Harmony("Cas.LoudParrots");

		public static MyConfig MyConfig { get; internal set; }

		private void Awake()
		{
			try
			{
				ManualLogSource val = Logger.CreateLogSource("Cas.LoudParrots");
				LoadConfig();
				string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				MyCustomAssets = AssetBundle.LoadFromFile(Path.Combine(directoryName, "goodparrotbundle"));
				if ((Object)(object)MyCustomAssets == (Object)null)
				{
					val.LogError((object)"Failed to load custom assets.");
					return;
				}
				Dictionary<BirdSpecies, string> dictionary = new Dictionary<BirdSpecies, string>();
				dictionary.Add(BirdSpecies.Parrot, "Assets/Customscrap/ParrotData.asset");
				dictionary.Add(BirdSpecies.GoldFinch, "Assets/Customscrap/othervariants/GoldFinchData.asset");
				dictionary.Add(BirdSpecies.Crow, "Assets/Customscrap/othervariants/CrowData.asset");
				dictionary.Add(BirdSpecies.Robin, "Assets/Customscrap/othervariants/RobinData.asset");
				dictionary.Add(BirdSpecies.Cardinal, "Assets/Customscrap/othervariants/Cardinaldata.asset");
				dictionary.Add(BirdSpecies.LittleBird, "Assets/Customscrap/othervariants/LittleBirdData.asset");
				dictionary.Add(BirdSpecies.BlueJayBird, "Assets/Customscrap/othervariants/BlueJayBirdData.asset");
				dictionary.Add(BirdSpecies.Sparrow, "Assets/Customscrap/othervariants/SparrowData.asset");
				foreach (KeyValuePair<BirdSpecies, string> item in dictionary)
				{
					LoadBirds(MyCustomAssets, item.Value, GetBirdRarity(item.Key), item.Key);
					val.LogMessage((object)("Loaded bird: " + item.Key.ToString() + " with rarity " + GetBirdRarity(item.Key)));
				}
				AudioClip val2 = MyCustomAssets.LoadAsset<AudioClip>("Assets/Customscrap/ckacka.mp3");
				AudioClip val3 = MyCustomAssets.LoadAsset<AudioClip>("Assets/Customscrap/ckacka2.mp3");
				AudioClip val4 = MyCustomAssets.LoadAsset<AudioClip>("Assets/Customscrap/ckacka3.mp3");
				if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
				{
					val.LogError((object)"Failed to load bird audio sources.");
					return;
				}
				Dictionary<BirdSpecies, List<AudioClip>> dictionary2 = new Dictionary<BirdSpecies, List<AudioClip>>();
				dictionary2.Add(BirdSpecies.Parrot, new List<AudioClip> { val2, val3, val4 });
				AudioClip val5 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/cardinal2.wav");
				AudioClip val6 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/cardinal.wav");
				dictionary2.Add(BirdSpecies.Cardinal, new List<AudioClip> { val5, val6 });
				AudioClip val7 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/robin2.wav");
				AudioClip val8 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/robin.wav");
				dictionary2.Add(BirdSpecies.Robin, new List<AudioClip> { val7, val8 });
				AudioClip val9 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/blueJay2.wav");
				AudioClip val10 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/blueJay.wav");
				dictionary2.Add(BirdSpecies.BlueJayBird, new List<AudioClip> { val9, val10 });
				AudioClip val11 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/finch2.wav");
				AudioClip val12 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/finch.wav");
				dictionary2.Add(BirdSpecies.GoldFinch, new List<AudioClip> { val11, val12 });
				AudioClip val13 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/sparrow2.wav");
				AudioClip val14 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/sparrow.wav");
				dictionary2.Add(BirdSpecies.Sparrow, new List<AudioClip> { val13, val14 });
				AudioClip val15 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/crow1.wav");
				AudioClip val16 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/crow2.wav");
				dictionary2.Add(BirdSpecies.Crow, new List<AudioClip> { val15, val16 });
				AudioClip val17 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/chickadee2.wav");
				AudioClip val18 = MyCustomAssets.LoadAsset<AudioClip>("Assets/living birds/sounds/chickadee.wav");
				dictionary2.Add(BirdSpecies.LittleBird, new List<AudioClip> { val17, val18 });
				if ((Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null || (Object)(object)val7 == (Object)null || (Object)(object)val8 == (Object)null || (Object)(object)val9 == (Object)null || (Object)(object)val10 == (Object)null || (Object)(object)val11 == (Object)null || (Object)(object)val12 == (Object)null || (Object)(object)val13 == (Object)null || (Object)(object)val14 == (Object)null || (Object)(object)val15 == (Object)null || (Object)(object)val16 == (Object)null || (Object)(object)val17 == (Object)null || (Object)(object)val18 == (Object)null)
				{
					val.LogError((object)"Failed to load bird noises.");
					return;
				}
				Dictionary<BirdSpecies, ModInfo.BirdInfo> dictionary3 = new Dictionary<BirdSpecies, ModInfo.BirdInfo>();
				foreach (BirdSpecies value2 in Enum.GetValues(typeof(BirdSpecies)))
				{
					List<AudioClip> list = new List<AudioClip>();
					list.AddRange(dictionary2[value2]);
					ModInfo.BirdInfo value = new ModInfo.BirdInfo(value2, 1, 125, ModInfo.GetPeckMessages(value2), dictionary2[value2], list);
					dictionary3.Add(value2, value);
				}
				ModInfo modInfo = new ModInfo(new List<AudioClip> { val2, val3, val4 }, dictionary2, dictionary3);
				val.LogMessage((object)"Loaded birds succesfully..");
			}
			catch (Exception ex)
			{
				Logger.CreateLogSource("Cas.LoudParrots").LogError((object)ex);
			}
		}

		private void LoadConfig()
		{
			try
			{
				MyConfig = new MyConfig(((BaseUnityPlugin)this).Config);
			}
			catch (Exception ex)
			{
				Logger.CreateLogSource("Cas.LoudParrots").LogError((object)ex);
				Logger.CreateLogSource("Cas.LoudParrots").LogError((object)"Could not load config....");
			}
		}

		private int GetBirdRarity(BirdSpecies species)
		{
			int num = 8;
			return MyConfig.spawnChancePerSpecies.ContainsKey(species) ? MyConfig.spawnChancePerSpecies[species].Value : num;
		}

		private void LoadBirds(AssetBundle bundle, string path, int rarity, BirdSpecies species)
		{
			Item val = bundle.LoadAsset<Item>(path);
			if ((Object)(object)val == (Object)null)
			{
				Logger.CreateLogSource("Cas.LoudParrots").LogError((object)"Failed to load bird prefab.");
				return;
			}
			ParrotItem parrotItem = AddScriptBasedOnType(species, val);
			((GrabbableObject)parrotItem).grabbable = true;
			((GrabbableObject)parrotItem).grabbableToEnemies = true;
			((GrabbableObject)parrotItem).itemProperties = val;
			parrotItem.BirdSpecies = species;
			Utilities.FixMixerGroups(val.spawnPrefab);
			NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
			Items.RegisterScrap(val, rarity, (LevelTypes)(-1));
		}

		private ParrotItem AddScriptBasedOnType(BirdSpecies species, Item newbird)
		{
			return species switch
			{
				BirdSpecies.Parrot => newbird.spawnPrefab.AddComponent<Parrot>(), 
				BirdSpecies.GoldFinch => newbird.spawnPrefab.AddComponent<GoldFinch>(), 
				BirdSpecies.Crow => newbird.spawnPrefab.AddComponent<Crow>(), 
				BirdSpecies.Robin => newbird.spawnPrefab.AddComponent<Robin>(), 
				BirdSpecies.Cardinal => newbird.spawnPrefab.AddComponent<Cardinal>(), 
				BirdSpecies.LittleBird => newbird.spawnPrefab.AddComponent<LittleBird>(), 
				BirdSpecies.BlueJayBird => newbird.spawnPrefab.AddComponent<BlueJayBird>(), 
				BirdSpecies.Sparrow => newbird.spawnPrefab.AddComponent<Sparrow>(), 
				_ => newbird.spawnPrefab.AddComponent<ParrotItem>(), 
			};
		}
	}
}
namespace UpdatedLethalCompanyMod.models
{
	public class DangerInfo
	{
		public List<NearEnemy> EnemiesDistance { get; set; }

		public int DangerLevel { get; set; }

		public DangerInfo(List<NearEnemy> enemiesDistances, int dangerLevel)
		{
			EnemiesDistance = enemiesDistances;
			DangerLevel = dangerLevel;
		}

		public DangerInfo()
		{
			EnemiesDistance = new List<NearEnemy>();
			DangerLevel = 0;
		}

		public void SetDangerLevel(int dangerLevel)
		{
			if (DangerLevel < dangerLevel)
			{
				DangerLevel = dangerLevel;
			}
		}

		public void AddEnemyToList(EnemyAI enemy, float distance)
		{
			EnemiesDistance.Add(new NearEnemy(enemy, distance));
			if (distance < 20f)
			{
				SetDangerLevel(4);
			}
			if (distance < 40f)
			{
				SetDangerLevel(3);
			}
			SetDangerLevel(1);
		}
	}
	public struct NearEnemy
	{
		public EnemyAI Enemy { get; set; }

		public float Distance { get; set; }

		public NearEnemy(EnemyAI enemy, float distance)
		{
			Enemy = enemy;
			Distance = distance;
		}
	}
}
namespace UpdatedLethalCompanyMod.birds
{
	public class BlueJayBird : ParrotItem
	{
		public new void Awake()
		{
			BirdSpecies key = (base.BirdSpecies = BirdSpecies.BlueJayBird);
			peckDamage = ModInfo.Instance.birdInfos[key].peckDamage;
			base.BirdPecksPlayerChanceWhenHeld = ModInfo.Instance.birdInfos[key].peckChance;
			base.Checkintervalmax = ModInfo.Instance.GetRandomIntervalMax(3f);
			base.SearchRadius = 55f;
			base.Awake();
		}
	}
	public class Cardinal : ParrotItem
	{
		public new void Awake()
		{
			BirdSpecies key = (base.BirdSpecies = BirdSpecies.Cardinal);
			peckDamage = ModInfo.Instance.birdInfos[key].peckDamage;
			base.BirdPecksPlayerChanceWhenHeld = ModInfo.Instance.birdInfos[key].peckChance;
			base.Checkintervalmax = ModInfo.Instance.GetRandomIntervalMax(3f);
			base.SearchRadius = 50f;
			base.Awake();
		}
	}
	public class Crow : ParrotItem
	{
		public new void Awake()
		{
			BirdSpecies key = (base.BirdSpecies = BirdSpecies.Crow);
			peckDamage = ModInfo.Instance.birdInfos[key].peckDamage;
			base.BirdPecksPlayerChanceWhenHeld = ModInfo.Instance.birdInfos[key].peckChance;
			base.Checkintervalmax = ModInfo.Instance.GetRandomIntervalMax(3f);
			base.SearchRadius = 60f;
			base.Awake();
		}
	}
	public class GoldFinch : ParrotItem
	{
		public new void Awake()
		{
			BirdSpecies key = (base.BirdSpecies = BirdSpecies.GoldFinch);
			peckDamage = ModInfo.Instance.birdInfos[key].peckDamage;
			base.BirdPecksPlayerChanceWhenHeld = ModInfo.Instance.birdInfos[key].peckChance;
			base.Checkintervalmax = ModInfo.Instance.GetRandomIntervalMax(3f);
			base.SearchRadius = 30f;
			base.Awake();
		}
	}
	public class LittleBird : ParrotItem
	{
		public new void Awake()
		{
			BirdSpecies key = (base.BirdSpecies = BirdSpecies.LittleBird);
			peckDamage = ModInfo.Instance.birdInfos[key].peckDamage;
			base.BirdPecksPlayerChanceWhenHeld = ModInfo.Instance.birdInfos[key].peckChance;
			base.Checkintervalmax = ModInfo.Instance.GetRandomIntervalMax(3f);
			base.SearchRadius = 30f;
			base.Awake();
		}
	}
	public class Parrot : ParrotItem
	{
		private Dictionary<int, float> previousDistances;

		private float distanceCutOff = 90f;

		public new void Awake()
		{
			previousDistances = new Dictionary<int, float>();
			BirdSpecies key = (base.BirdSpecies = BirdSpecies.Parrot);
			peckDamage = ModInfo.Instance.birdInfos[key].peckDamage;
			base.BirdPecksPlayerChanceWhenHeld = ModInfo.Instance.birdInfos[key].peckChance;
			base.Checkintervalmax = ModInfo.Instance.GetRandomIntervalMax(3f);
			base.SearchRadius = 120f;
			base.Awake();
		}

		public override void DoParrotChecks()
		{
			if ((Object)(object)((GrabbableObject)this).playerHeldBy == (Object)null)
			{
				bepLogger.LogInfo((object)"PlayerHeldBy is null (this shouldn't happen?)");
				return;
			}
			if ((Object)(object)RoundManager.Instance == (Object)null && RoundManager.Instance.SpawnedEnemies == null)
			{
				bepLogger.LogInfo((object)"RoundManager or SpawnedEnemies is null");
				return;
			}
			dangerLevel = 0;
			DangerInfo dangerInfo = GetDangerInfo();
			foreach (NearEnemy item in dangerInfo.EnemiesDistance)
			{
				if (!previousDistances.ContainsKey(((Object)item.Enemy).GetInstanceID()))
				{
					previousDistances.Add(((Object)item.Enemy).GetInstanceID(), item.Distance);
				}
				if (item.Distance < previousDistances[((Object)item.Enemy).GetInstanceID()] && item.Distance < 70f)
				{
					dangerLevel++;
				}
				previousDistances[((Object)item.Enemy).GetInstanceID()] = item.Distance;
				if (item.Distance > distanceCutOff)
				{
					previousDistances.Remove(((Object)item.Enemy).GetInstanceID());
				}
				if (item.Enemy.movingTowardsTargetPlayer && item.Distance < 70f)
				{
					dangerLevel += 2;
				}
				if (item.Distance < 30f)
				{
					dangerLevel++;
				}
				if (item.Distance < 15f)
				{
					dangerLevel++;
				}
			}
			ChirpBasedOnDangerLevel();
		}
	}
	public class Robin : ParrotItem
	{
		public new void Awake()
		{
			BirdSpecies key = (base.BirdSpecies = BirdSpecies.Robin);
			peckDamage = ModInfo.Instance.birdInfos[key].peckDamage;
			base.BirdPecksPlayerChanceWhenHeld = ModInfo.Instance.birdInfos[key].peckChance;
			base.Checkintervalmax = ModInfo.Instance.GetRandomIntervalMax(3f);
			base.SearchRadius = 40f;
			base.Awake();
		}
	}
	public class Sparrow : ParrotItem
	{
		public new void Awake()
		{
			BirdSpecies key = (base.BirdSpecies = BirdSpecies.Sparrow);
			peckDamage = ModInfo.Instance.birdInfos[key].peckDamage;
			base.BirdPecksPlayerChanceWhenHeld = ModInfo.Instance.birdInfos[key].peckChance;
			base.Checkintervalmax = ModInfo.Instance.GetRandomIntervalMax(3f);
			base.SearchRadius = 40f;
			base.Awake();
		}
	}
}
namespace UpdatedLethalCompanyMod.Behaviours
{
	public class ParrotItem : PhysicsProp
	{
		protected const string enemyTag = "Enemy";

		private float checkinterval = 0f;

		private float checkFlyingIntervalMax = 1f;

		private float checkFlyingInterval = 0f;

		protected int dangerLevel;

		private Coroutine chirpCoroutine;

		public int peckDamage = 2;

		private Animator childAnimator;

		private bool isFallingAnimationPlaying = false;

		protected ManualLogSource bepLogger;

		protected RoundManager roundManager;

		public float Checkintervalmax { get; set; } = 3.5f;


		private float CheckMonstersIntervalMax { get; set; } = 3f;


		private float CheckMonstersIntervalCurrent { get; set; } = 0f;


		public int BirdPecksPlayerChanceWhenHeld { get; set; } = 100;


		public string BirdName { get; set; }

		public BirdSpecies BirdSpecies { get; set; }

		private AudioSource ChirpSource { get; set; }

		public float Volume { get; set; } = 1f;


		public float SearchRadius { get; set; } = 50f;


		public void Awake()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			bepLogger = Logger.CreateLogSource("Cas.LoudParrots");
			ChirpSource = ((Component)this).gameObject.GetComponent<AudioSource>();
			if ((Object)(object)ChirpSource == (Object)null)
			{
				bepLogger.LogInfo((object)"CHirpsource is null (this shouldn't happen?)");
			}
			float randomScale = GetRandomScale();
			((Component)this).transform.localScale = new Vector3(randomScale, randomScale, randomScale);
			childAnimator = ((Component)this).GetComponentInChildren<Animator>();
			Volume = (MyConfig.chirpVolumePerSpecies.ContainsKey(BirdSpecies) ? MyConfig.chirpVolumePerSpecies[BirdSpecies].Value : 1f);
			roundManager = Object.FindObjectOfType<RoundManager>();
			if ((Object)(object)roundManager == (Object)null)
			{
				bepLogger.LogError((object)"RoundManager is null, could not find a roundmanager! This will not negatively impact the workings of this mod or break the game signficantly.");
			}
		}

		private float GetRandomScale()
		{
			float num = Random.Range(0.05f, 1f);
			float num2 = Random.Range(0f, 1f);
			if (num > 0.5f && num2 > 0.5f)
			{
				num = Random.Range(0.05f, 0.5f);
			}
			return num;
		}

		public override void Update()
		{
			((GrabbableObject)this).Update();
			CheckFlight();
			if (checkinterval < Checkintervalmax)
			{
				checkinterval += Time.deltaTime;
				return;
			}
			checkinterval = 0f;
			if (!((GrabbableObject)this).isPocketed)
			{
				DoIdleChirp();
			}
			if (!((Object)(object)((GrabbableObject)this).playerHeldBy == (Object)null) && !((GrabbableObject)this).isPocketed)
			{
				TryToPeckPlayer();
				DoParrotChecks();
			}
		}

		private void CheckFlight()
		{
			if (checkFlyingInterval < checkFlyingIntervalMax)
			{
				checkFlyingInterval += Time.deltaTime;
				return;
			}
			checkFlyingInterval = 0f;
			bool flag = !((GrabbableObject)this).hasHitGround && !((GrabbableObject)this).isHeld && !((GrabbableObject)this).isHeldByEnemy;
			if (flag && !isFallingAnimationPlaying)
			{
				Animator obj = childAnimator;
				if (obj != null)
				{
					obj.SetBool("flying", true);
				}
				isFallingAnimationPlaying = true;
			}
			if (!flag && isFallingAnimationPlaying)
			{
				Animator obj2 = childAnimator;
				if (obj2 != null)
				{
					obj2.SetBool("flying", false);
				}
				isFallingAnimationPlaying = false;
			}
		}

		public override void FallWithCurve()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			float num = ((GrabbableObject)this).startFallingPosition.y - ((GrabbableObject)this).targetFloorPosition.y;
			if (((GrabbableObject)this).floorYRot == -1)
			{
				((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, Quaternion.Euler(((GrabbableObject)this).itemProperties.restingRotation.x, ((Component)this).transform.eulerAngles.y, ((GrabbableObject)this).itemProperties.restingRotation.z), Mathf.Clamp(14f * Time.deltaTime / num, 0f, 1f));
			}
			else
			{
				((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, Quaternion.Euler(((GrabbableObject)this).itemProperties.restingRotation.x, (float)(((GrabbableObject)this).floorYRot + ((GrabbableObject)this).itemProperties.floorYOffset) + 90f, ((GrabbableObject)this).itemProperties.restingRotation.z), Mathf.Clamp(14f * Time.deltaTime / num, 0f, 1f));
			}
			if (num > 5f)
			{
				((Component)this).transform.localPosition = Vector3.Lerp(((GrabbableObject)this).startFallingPosition, ((GrabbableObject)this).targetFloorPosition, StartOfRound.Instance.objectFallToGroundCurveNoBounce.Evaluate(((GrabbableObject)this).fallTime));
			}
			else
			{
				((Component)this).transform.localPosition = Vector3.Lerp(((GrabbableObject)this).startFallingPosition, ((GrabbableObject)this).targetFloorPosition, StartOfRound.Instance.objectFallToGroundCurve.Evaluate(((GrabbableObject)this).fallTime));
			}
			((GrabbableObject)this).fallTime = ((GrabbableObject)this).fallTime + Mathf.Abs(Time.deltaTime * 1.1f / num);
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (!buttonDown)
			{
				return;
			}
			((GrabbableObject)this).playerHeldBy.DamagePlayer(2, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
			try
			{
				if ((Object)(object)ChirpSource == (Object)null)
				{
					bepLogger.LogError((object)"Chirpy thing is null");
				}
				Animator obj = childAnimator;
				if (obj != null)
				{
					obj.SetBool("peck", true);
				}
				((Component)this).gameObject.GetComponent<AudioSource>().PlayOneShot(ModInfo.Instance.GetRandomIdleChirpForBird(BirdSpecies), Volume);
			}
			catch (Exception ex)
			{
				bepLogger.LogError((object)ex);
			}
		}

		public virtual void DoParrotChecks()
		{
			if ((Object)(object)((GrabbableObject)this).playerHeldBy == (Object)null)
			{
				bepLogger.LogInfo((object)"PlayerHeldBy is null (this shouldn't happen?)");
				return;
			}
			if ((Object)(object)RoundManager.Instance == (Object)null && RoundManager.Instance.SpawnedEnemies == null)
			{
				bepLogger.LogInfo((object)"RoundManager or SpawnedEnemies is null");
				return;
			}
			dangerLevel = 0;
			DangerInfo dangerInfo = GetDangerInfo();
			dangerLevel = dangerInfo.DangerLevel;
			ChirpBasedOnDangerLevel();
		}

		protected DangerInfo GetDangerInfo()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			DangerInfo dangerInfo = new DangerInfo();
			if ((Object)(object)roundManager != (Object)null && roundManager.SpawnedEnemies.Count > 0)
			{
				foreach (EnemyAI spawnedEnemy in roundManager.SpawnedEnemies)
				{
					float num = Vector3.Distance(((Component)spawnedEnemy).transform.position, ((Component)this).transform.position);
					if (num < SearchRadius)
					{
						dangerInfo.AddEnemyToList(spawnedEnemy, num);
					}
				}
				return dangerInfo;
			}
			EnemyAI[] array = Object.FindObjectsOfType<EnemyAI>();
			if (array == null)
			{
				return dangerInfo;
			}
			if (array.Length == 0)
			{
				return dangerInfo;
			}
			EnemyAI[] array2 = array;
			foreach (EnemyAI val in array2)
			{
				float num2 = Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position);
				if (num2 < SearchRadius)
				{
					dangerInfo.AddEnemyToList(val, num2);
				}
			}
			return dangerInfo;
		}

		protected void ChirpBasedOnDangerLevel()
		{
			if (dangerLevel <= 0)
			{
				if (chirpCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(chirpCoroutine);
					chirpCoroutine = null;
				}
			}
			else if (chirpCoroutine == null)
			{
				chirpCoroutine = ((MonoBehaviour)this).StartCoroutine(ChirpCoroutine());
			}
		}

		private IEnumerator ChirpCoroutine()
		{
			Animator obj = childAnimator;
			if (obj != null)
			{
				obj.SetBool("worried", true);
			}
			while (dangerLevel > 0)
			{
				PlayChirp();
				dangerLevel--;
				float waitTime = Random.Range(0.3f, 1.3f);
				yield return (object)new WaitForSeconds(waitTime);
				if (dangerLevel <= 0)
				{
					((MonoBehaviour)this).StopCoroutine(chirpCoroutine);
					chirpCoroutine = null;
					Animator obj2 = childAnimator;
					if (obj2 != null)
					{
						obj2.SetBool("worried", false);
					}
				}
			}
		}

		private void PlayChirp()
		{
			if ((Object)(object)ChirpSource == (Object)null)
			{
				bepLogger.LogError((object)"Chirpy thing is null");
				return;
			}
			ChirpSource = ((Component)this).gameObject.GetComponent<AudioSource>();
			if (!ChirpSource.isPlaying)
			{
				if (dangerLevel > 7)
				{
					ChirpSource.PlayOneShot(ModInfo.Instance.GetRandomWarningChirpForBird(BirdSpecies), Volume + 0.5f);
				}
				else
				{
					ChirpSource.PlayOneShot(ModInfo.Instance.GetRandomWarningChirpForBird(BirdSpecies), Volume);
				}
			}
		}

		private void TryToPeckPlayer()
		{
			//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)
			if (!((Object)(object)((GrabbableObject)this).playerHeldBy == (Object)null) && Random.Range(0, BirdPecksPlayerChanceWhenHeld + 40) == 1)
			{
				Animator obj = childAnimator;
				if (obj != null)
				{
					obj.SetBool("peck", true);
				}
				((GrabbableObject)this).playerHeldBy.DamagePlayer(peckDamage, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
				HUDManager.Instance.DisplayTip("Warning", ModInfo.Instance.GetPeckMessageForBird(BirdSpecies), true, false, "LC_Tip1");
			}
		}

		private void DoIdleChirp()
		{
			if (Random.Range(0, 100) > 90)
			{
				if ((Object)(object)ChirpSource == (Object)null)
				{
					bepLogger.LogError((object)"Audio source is null when playing bird idle noise");
				}
				else
				{
					Animator obj = childAnimator;
					if (obj != null)
					{
						obj.SetBool("sing", true);
					}
					ChirpSource.PlayOneShot(ModInfo.Instance.GetRandomIdleChirpForBird(BirdSpecies), Volume);
				}
			}
			if (!((Object)(object)childAnimator == (Object)null) && Random.Range(0, 100) > 65)
			{
				childAnimator.SetBool("ruffle", true);
			}
		}
	}
}