Decompiled source of Shisha v1.0.0

plugins/shisha/LethalCompanyShisha.dll

Decompiled 3 days 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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Imperium.API;
using LethalCompanyShisha.Core;
using LethalCompanyShisha.Core.AI;
using LethalCompanyShisha.Core.AI.StateMachine;
using LethalCompanyShisha.Core.Integration;
using LethalCompanyShisha.Core.StateMachine;
using LethalCompanyShisha.Enemies;
using LethalCompanyShisha.Enemies.CustomStateMachineBehaviours;
using LethalCompanyShisha.Enemies.Transitions;
using LethalCompanyShisha.NetcodePatcher;
using LethalCompanyShisha.Util;
using LethalCompanyShisha.Util.Types;
using LethalLib;
using LethalLib.Modules;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Pool;
using UnityEngine.SceneManagement;
using UnityEngine.Scripting;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("LethalLib")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("Louis")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Lethal Company Shisha")]
[assembly: AssemblyFileVersion("2.0.1.0")]
[assembly: AssemblyInformationalVersion("2.0.1+f15435f59532252ee7fe93d189251bfc0d43049c")]
[assembly: AssemblyProduct("Shisha")]
[assembly: AssemblyTitle("LethalCompanyShisha")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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 LethalCompanyShisha
{
	[BepInPlugin("LethalCompanyShisha", "Shisha", "2.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ShishaPlugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		internal static CachedList<Assembly> CachedAssemblies;

		internal EnemyType ShishaEnemyType;

		public static Item ShishaRedPoopItem;

		public static Item ShishaGreenPoopItem;

		public static Item ShishaBluePoopItem;

		public static ShishaPlugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static ShishaConfig Config { get; private set; }

		private void Awake()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			Stopwatch stopwatch = Stopwatch.StartNew();
			Logger = Logger.CreateLogSource("Shisha|2.0.1");
			Instance = this;
			CachedAssemblies = new CachedList<Assembly>(() => AppDomain.CurrentDomain.GetAssemblies().ToList());
			if (LobbyCompatibilityChecker.Enabled)
			{
				LobbyCompatibilityChecker.Init();
			}
			Logger.LogDebug((object)"Creating Shisha config.");
			Config = new ShishaConfig(((BaseUnityPlugin)this).Config);
			LogVerbose("Creating Harmony instance...");
			_harmony = new Harmony("LethalCompanyShisha");
			_harmony.PatchAll();
			if (!Config.ShishaEnabled)
			{
				Logger.LogInfo((object)"Shisha is disabled, not loading asset bundle.");
				return;
			}
			_harmony.PatchAll(typeof(ShishaPlugin));
			_harmony.PatchAll(typeof(ShishaPoopBehaviour));
			NetcodePatcher();
			Assets.LoadAssetBundle("shishabundle");
			if (!Object.op_Implicit((Object)(object)Assets.MainAssetBundle))
			{
				Logger.LogError((object)"MainAssetBundle is null");
				return;
			}
			SetupShisha();
			ShishaRedPoopItem = SetupShishaPoop("Red");
			ShishaGreenPoopItem = SetupShishaPoop("Green");
			ShishaBluePoopItem = SetupShishaPoop("Blue");
			stopwatch.Stop();
			Logger.LogInfo((object)string.Format("{0}:{1} has setup in {2}ms.", "LethalCompanyShisha", "2.0.1", stopwatch.ElapsedMilliseconds));
		}

		private void SetupShisha()
		{
			ShishaEnemyType = Assets.MainAssetBundle.LoadAsset<EnemyType>("ShishaEnemyType");
			ShishaEnemyType.MaxCount = Config.MaxAmount;
			ShishaEnemyType.PowerLevel = Config.PowerLevel;
			ShishaEnemyType.normalizedTimeInDayToLeave = (Config.TimeInDayLeaveEnabled ? 0.6f : 1f);
			ShishaEnemyType.canDie = Config.Killable;
			TerminalNode terminalNode = Assets.MainAssetBundle.LoadAsset<TerminalNode>("ShishaTerminalNode");
			TerminalKeyword terminalKeyword = Assets.MainAssetBundle.LoadAsset<TerminalKeyword>("ShishaTerminalKeyword");
			NetworkPrefabs.RegisterNetworkPrefab(ShishaEnemyType.enemyPrefab);
			Utilities.FixMixerGroups(ShishaEnemyType.enemyPrefab);
			RegisterEnemyWithConfig(Config.ShishaEnabled, Config.Rarity, ShishaEnemyType, terminalNode, terminalKeyword);
		}

		private static Item SetupShishaPoop(string colour)
		{
			Item val = Assets.MainAssetBundle.LoadAsset<Item>("Shisha" + colour + "PoopItemData");
			switch (colour)
			{
			case "Red":
				val.minValue = Config.CommonCrystalMinValue;
				val.maxValue = Config.CommonCrystalMaxValue;
				break;
			case "Green":
				val.minValue = Config.UncommonCrystalMinValue;
				val.maxValue = Config.UncommonCrystalMaxValue;
				break;
			case "Blue":
				val.minValue = Config.RareCrystalMinValue;
				val.maxValue = Config.RareCrystalMaxValue;
				break;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
			Utilities.FixMixerGroups(val.spawnPrefab);
			Items.RegisterScrap(val, 0, (LevelTypes)(-1));
			return val;
		}

		private static void RegisterEnemyWithConfig(bool enemyEnabled, string configMoonRarity, EnemyType enemy, TerminalNode terminalNode, TerminalKeyword terminalKeyword)
		{
			if (enemyEnabled)
			{
				var (dictionary, dictionary2) = ConfigParsing(configMoonRarity);
				Enemies.RegisterEnemy(enemy, dictionary, dictionary2, terminalNode, terminalKeyword);
			}
			else
			{
				Enemies.RegisterEnemy(enemy, 0, (LevelTypes)(-1), terminalNode, terminalKeyword);
			}
		}

		private static (Dictionary<LevelTypes, int> spawnRateByLevelType, Dictionary<string, int> spawnRateByCustomLevelType) ConfigParsing(string configMoonRarity)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<LevelTypes, int> dictionary = new Dictionary<LevelTypes, int>();
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
			foreach (string item in from s in configMoonRarity.Split(',')
				select s.Trim())
			{
				string[] array = item.Split(':');
				if (array.Length != 2)
				{
					continue;
				}
				string text = array[0];
				if (!int.TryParse(array[1], out var result))
				{
					continue;
				}
				if (Enum.TryParse<LevelTypes>(text, ignoreCase: true, out LevelTypes result2))
				{
					dictionary[result2] = result;
					LogVerbose($"Registered spawn rate for level type {result2} to {result}");
					continue;
				}
				string value = text + "Level";
				if (Enum.TryParse<LevelTypes>(value, ignoreCase: true, out result2))
				{
					dictionary[result2] = result;
					LogVerbose($"Registered spawn rate for level type {result2} to {result}");
				}
				else
				{
					dictionary2[text] = result;
					LogVerbose($"Registered spawn rate for custom level type {text} to {result}");
				}
			}
			return (dictionary, dictionary2);
		}

		private static void NetcodePatcher()
		{
			try
			{
				IEnumerable<Type> loadableTypes = Assembly.GetExecutingAssembly().GetLoadableTypes();
				foreach (Type item in loadableTypes)
				{
					MethodInfo[] methods = item.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] array = methods;
					foreach (MethodInfo methodInfo in array)
					{
						if (!Attribute.IsDefined(methodInfo, typeof(RuntimeInitializeOnLoadMethodAttribute)))
						{
							continue;
						}
						if (methodInfo.ContainsGenericParameters)
						{
							Logger.LogDebug((object)("[NetcodePatcher] Skipping generic method " + item.FullName + "." + methodInfo.Name + " with [RuntimeInitializeOnLoadMethod] attribute."));
						}
						else
						{
							try
							{
								methodInfo.Invoke(null, null);
							}
							catch (Exception arg)
							{
								Logger.LogError((object)$"Error invoking method {item.FullName}.{methodInfo.Name}: {arg}");
							}
						}
					}
				}
			}
			catch (ReflectionTypeLoadException ex)
			{
				Logger.LogError((object)$"[NetcodePatcher] Error loading types from assembly: {ex}");
				for (int j = 0; j < ex.LoaderExceptions.Length; j++)
				{
					Exception ex2 = ex.LoaderExceptions[j];
					if (ex2 != null)
					{
						Logger.LogError((object)("[NetcodePatcher] Loader Exception: " + ex2.Message));
					}
				}
			}
		}

		internal static void LogVerbose(object message)
		{
			if (Config.VerboseLoggingEnabled)
			{
				Logger.LogDebug(message);
			}
		}
	}
	internal static class LobbyCompatibilityChecker
	{
		internal static bool Enabled => Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility");

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void Init()
		{
			PluginHelper.RegisterPlugin("LethalCompanyShisha", Version.Parse("2.0.1"), (CompatibilityLevel)2, (VersionStrictness)3);
		}
	}
	public class ShishaPoopBehaviour : PhysicsProp
	{
		public enum PoopType
		{
			Common,
			Uncommon,
			Rare
		}

		private bool _networkEventsSubscribed;

		private readonly NetworkVariable<bool> _isPartOfShisha = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private void OnEnable()
		{
			SubscribeToNetworkEvents();
		}

		private void OnDisable()
		{
			UnsubscribeFromNetworkEvents();
		}

		public override void Start()
		{
			((GrabbableObject)this).Start();
			SubscribeToNetworkEvents();
		}

		public override void Update()
		{
			if (((GrabbableObject)this).isHeld)
			{
				EvaluateIsPartOfShisha();
			}
			if (!_isPartOfShisha.Value)
			{
				((GrabbableObject)this).Update();
			}
		}

		public override void LateUpdate()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (_isPartOfShisha.Value)
			{
				if (Object.op_Implicit((Object)(object)((Component)this).transform.parent))
				{
					((Component)this).transform.position = ((Component)this).transform.parent.position;
					((Component)this).transform.rotation = ((Component)this).transform.parent.rotation;
				}
			}
			else
			{
				((GrabbableObject)this).LateUpdate();
			}
		}

		public override void EquipItem()
		{
			((PhysicsProp)this).EquipItem();
			EvaluateIsPartOfShisha();
		}

		public override void GrabItem()
		{
			((GrabbableObject)this).GrabItem();
			EvaluateIsPartOfShisha();
		}

		[ServerRpc(RequireOwnership = false)]
		internal void SetIsPartOfShishaServerRpc(bool value)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4263262004u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref value, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4263262004u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
					_isPartOfShisha.Value = value;
				}
			}
		}

		private void EvaluateIsPartOfShisha()
		{
			if (_isPartOfShisha.Value)
			{
				if (((NetworkBehaviour)this).IsServer)
				{
					_isPartOfShisha.Value = false;
				}
				else
				{
					SetIsPartOfShishaServerRpc(value: false);
				}
			}
		}

		[HarmonyPatch(typeof(BeltBagItem), "PutObjectInBagLocalClient")]
		[HarmonyPostfix]
		private static void TriggerHeldActions(BeltBagItem __instance, GrabbableObject gObject)
		{
			if (gObject is ShishaPoopBehaviour shishaPoopBehaviour)
			{
				((GrabbableObject)shishaPoopBehaviour).EquipItem();
			}
		}

		private void OnIsPartOfShishaChanged(bool oldValue, bool newValue)
		{
			((GrabbableObject)this).grabbableToEnemies = !newValue;
			((GrabbableObject)this).grabbable = !newValue;
			((GrabbableObject)this).fallTime = ((!newValue) ? 1f : 0f);
		}

		private void SubscribeToNetworkEvents()
		{
			if (!_networkEventsSubscribed)
			{
				NetworkVariable<bool> isPartOfShisha = _isPartOfShisha;
				isPartOfShisha.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Combine((Delegate?)(object)isPartOfShisha.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnIsPartOfShishaChanged));
				_networkEventsSubscribed = true;
			}
		}

		private void UnsubscribeFromNetworkEvents()
		{
			if (_networkEventsSubscribed)
			{
				NetworkVariable<bool> isPartOfShisha = _isPartOfShisha;
				isPartOfShisha.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Remove((Delegate?)(object)isPartOfShisha.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnIsPartOfShishaChanged));
				_networkEventsSubscribed = false;
			}
		}

		protected override void __initializeVariables()
		{
			if (_isPartOfShisha == null)
			{
				throw new Exception("ShishaPoopBehaviour._isPartOfShisha cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)_isPartOfShisha).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_isPartOfShisha, "_isPartOfShisha");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_isPartOfShisha);
			((PhysicsProp)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(4263262004u, new RpcReceiveHandler(__rpc_handler_4263262004), "SetIsPartOfShishaServerRpc");
			((PhysicsProp)this).__initializeRpcs();
		}

		private static void __rpc_handler_4263262004(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool isPartOfShishaServerRpc = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref isPartOfShishaServerRpc, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ShishaPoopBehaviour)(object)target).SetIsPartOfShishaServerRpc(isPartOfShishaServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "ShishaPoopBehaviour";
		}
	}
	[Serializable]
	public class ShishaConfig : ConfigLoader<ShishaConfig>
	{
		[field: Tooltip("Whether to log more debug information to the console. 99% of people do NOT need to touch this.")]
		public bool VerboseLoggingEnabled { get; private set; }

		[field: Header("Shisha Spawn Settings")]
		[field: Tooltip("Whether the Shisha will spawn in games.")]
		public bool ShishaEnabled { get; private set; } = true;


		[field: Tooltip("Spawn weight of the Shisha on all moons. You can to add to it any moon, just follow the format (also needs LLL installed for LE moons to work with this config).")]
		public string Rarity { get; private set; } = "All:30";


		[field: Tooltip("The power level of the Shisha.")]
		[field: Range(0f, 100f)]
		public float PowerLevel { get; private set; } = 0.5f;


		[field: Tooltip("The max amount of Shishas that can spawn in the map.")]
		[field: Range(0f, 500f)]
		public int MaxAmount { get; private set; } = 20;


		[field: Header("Shisha Poop Settings")]
		[field: Tooltip("Toggles whether the Shisha can poop when idle.")]
		public bool PoopBehaviourEnabled { get; private set; } = true;


		[field: Tooltip("The chance of the Shisha pooping while idle. The setting PoopBehaviourEnabled must be set to true for this to work.")]
		[field: Range(0f, 1f)]
		public float PoopChance { get; private set; } = 0.05f;


		[field: Tooltip("")]
		[field: Range(0f, 999999f)]
		public float CommonCrystalSpawnWeight { get; private set; } = 65f;


		[field: Tooltip("")]
		[field: Range(0f, 999999f)]
		public float UncommonCrystalSpawnWeight { get; private set; } = 25f;


		[field: Tooltip("")]
		[field: Range(0f, 999999f)]
		public float RareCrystalSpawnWeight { get; private set; } = 10f;


		[field: Tooltip("The minimum value that the common crystal can spawn with.")]
		[field: Range(0f, 999999f)]
		public int CommonCrystalMinValue { get; private set; } = 20;


		[field: Tooltip("The maximum value that the common crystal can spawn with.")]
		[field: Range(0f, 999999f)]
		public int CommonCrystalMaxValue { get; private set; } = 35;


		[field: Tooltip("The minimum value that the uncommon crystal can spawn with.")]
		[field: Range(0f, 999999f)]
		public int UncommonCrystalMinValue { get; private set; } = 40;


		[field: Tooltip("The maximum value that the uncommon crystal can spawn with.")]
		[field: Range(0f, 999999f)]
		public int UncommonCrystalMaxValue { get; private set; } = 75;


		[field: Tooltip("The minimum value that the rare crystal can spawn with.")]
		[field: Range(0f, 999999f)]
		public int RareCrystalMinValue { get; private set; } = 80;


		[field: Tooltip("The maximum value that the rare crystal can spawn with.")]
		[field: Range(0f, 999999f)]
		public int RareCrystalMaxValue { get; private set; } = 100;


		[field: Header("General Settings")]
		[field: Tooltip("Whether the Shisha can be killed.")]
		public bool Killable { get; private set; } = true;


		[field: Tooltip("The amount of health the Shisha has.")]
		[field: Range(1f, 999999f)]
		public int Health { get; private set; } = 3;


		[field: Tooltip("Toggles whether the Shisha will leave the map when it gets dark (like other vanilla daytime entities).")]
		public bool TimeInDayLeaveEnabled { get; private set; } = true;


		[field: Header("Movement Settings")]
		[field: Tooltip("When enabled, the Shisha will wander around the map.")]
		public bool Wander { get; private set; } = true;


		[field: Tooltip("The maximum distance from the Shisha's current position within which it can wander.")]
		[field: Range(0f, 999999f)]
		public float WanderRadius { get; private set; } = 50f;


		[field: Tooltip("When enabled, the Shisha will only wander around its spawn point within the radius defined by the Wander Radius setting. If disabled, the Shisha can wander from any point within the Wander Radius.")]
		public bool AnchoredWandering { get; private set; } = true;


		[field: Tooltip("The minimum time that the Shisha will wander for.")]
		public float WanderTimeMin { get; private set; } = 5f;


		[field: Tooltip("The maximum time that the Shisha will wander for.")]
		public float WanderTimeMax { get; private set; } = 45f;


		[field: Tooltip("The maximum speed of the Shisha.")]
		[field: Range(0f, 500f)]
		public float MaxSpeed { get; private set; } = 4f;


		[field: Tooltip("The acceleration of the Shisha.")]
		[field: Range(0f, 500f)]
		public float Acceleration { get; private set; } = 1f;


		[field: Tooltip("The maximum speed of the Shisha when running away from something.")]
		[field: Range(0f, 500f)]
		public float RunningAwayMaxSpeed { get; private set; } = 7f;


		[field: Header("Audio Settings")]
		[field: Tooltip("The minimum time gap between any given ambient sound effect.")]
		[field: Range(0f, 50f)]
		public float AmbientSfxTimerMin { get; private set; } = 7.5f;


		[field: Tooltip("The maximum time gap between any given ambient sound effect.")]
		[field: Range(0f, 500f)]
		public float AmbientSfxTimerMax { get; private set; } = 30f;


		[field: Tooltip("The volume of the ambient sounds of the Shisha.")]
		[field: Range(0f, 1f)]
		public float AmbientSfxVolume { get; private set; } = 0.4f;


		[field: Tooltip("The volume of the footstep sounds of the Shisha.")]
		[field: Range(0f, 1f)]
		public float FootstepSfxVolume { get; private set; } = 0.7f;


		public ShishaConfig(ConfigFile cfg)
			: base(cfg)
		{
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LethalCompanyShisha";

		public const string PLUGIN_NAME = "Shisha";

		public const string PLUGIN_VERSION = "2.0.1";
	}
}
namespace LethalCompanyShisha.Util
{
	internal static class ExtensionMethods
	{
		public static void SafeSet<T>(this NetworkVariable<T> networkVariable, T newValue) where T : IEquatable<T>
		{
			if (!EqualityComparer<T>.Default.Equals(networkVariable.Value, newValue))
			{
				networkVariable.Value = newValue;
			}
		}

		internal static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
		{
			if (assembly == null)
			{
				throw new ArgumentNullException("assembly");
			}
			try
			{
				return assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type t) => t != null);
			}
		}
	}
	public static class LineOfSightUtil
	{
		internal static bool HasLineOfSight(Vector3 targetPosition, Transform eyeTransform, float viewWidth = 45f, float viewRange = 60f, float proximityAwareness = -1f, bool isFoggy = false)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)eyeTransform))
			{
				return false;
			}
			Vector3 position = eyeTransform.position;
			Vector3 val = targetPosition - position;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			if (sqrMagnitude <= 0.0001f)
			{
				return true;
			}
			float num = viewRange;
			if (isFoggy)
			{
				num = Mathf.Clamp(viewRange, 0f, 30f);
			}
			float num2 = num * num;
			if (sqrMagnitude > num2)
			{
				return false;
			}
			float num3 = Mathf.Sqrt(sqrMagnitude);
			if (!(proximityAwareness >= 0f) || !(num3 <= proximityAwareness))
			{
				float num4 = Mathf.Clamp(viewWidth, 0f, 180f) * 0.5f * (MathF.PI / 180f);
				float num5 = Mathf.Cos(num4);
				float num6 = Vector3.Dot(eyeTransform.forward, val / num3);
				if (num6 < num5)
				{
					return false;
				}
			}
			if (Physics.Linecast(position, targetPosition, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
			{
				return false;
			}
			return true;
		}
	}
	internal static class PlayerUtil
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static PlayerControllerB GetPlayerFromClientId(ulong playerClientId)
		{
			return StartOfRound.Instance.allPlayerScripts[playerClientId];
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static PlayerControllerB GetPlayerFromClientId(int playerClientId)
		{
			return StartOfRound.Instance.allPlayerScripts[playerClientId];
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static ulong GetClientIdFromPlayer(PlayerControllerB player)
		{
			return player.playerClientId;
		}

		internal static bool IsPlayerDead(PlayerControllerB player)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return true;
			}
			if (!player.isPlayerDead)
			{
				return !player.isPlayerControlled;
			}
			return true;
		}
	}
	public class WeightedPicker<T>
	{
		private readonly List<(T item, float cumulativeWeight)> _processedItems;

		private readonly float _totalWeight;

		public WeightedPicker(IEnumerable<(T item, float weight)> weightedItems)
		{
			List<(T, float)> list = weightedItems.ToList();
			if (list.Count == 0)
			{
				throw new ArgumentException("Item list cannot be null or empty.");
			}
			_processedItems = new List<(T, float)>(list.Count);
			float num = 0f;
			foreach (var (item, num2) in list)
			{
				if (num2 < 0f)
				{
					throw new ArgumentException("Weights must be non-negative.");
				}
				num += num2;
				_processedItems.Add((item, num));
			}
			_totalWeight = num;
			if (_totalWeight <= 0f)
			{
				throw new ArgumentException("Total weight of all items must be greater than 0.");
			}
		}

		public T PickOne()
		{
			float num = Random.Range(0f, _totalWeight);
			foreach (var (result, num2) in _processedItems)
			{
				if (num < num2)
				{
					return result;
				}
			}
			return _processedItems[_processedItems.Count - 1].item;
		}
	}
}
namespace LethalCompanyShisha.Util.Types
{
	public class CachedList<T> : IEnumerable<T>, IEnumerable
	{
		private readonly Func<List<T>> _computeListFunction;

		private readonly object _lock = new object();

		private List<T> _cachedList;

		private bool _hasValue;

		public List<T> Value
		{
			get
			{
				if (!_hasValue)
				{
					lock (_lock)
					{
						if (!_hasValue)
						{
							ComputeAndCacheListInternal();
						}
					}
				}
				return _cachedList ?? Enumerable.Empty<T>().ToList();
			}
		}

		public bool HasValue
		{
			get
			{
				lock (_lock)
				{
					return _hasValue;
				}
			}
		}

		public CachedList(Func<List<T>> computeListFunction)
		{
			_computeListFunction = computeListFunction ?? throw new ArgumentNullException("computeListFunction");
			_cachedList = null;
			_hasValue = false;
		}

		public void Reset()
		{
			lock (_lock)
			{
				_cachedList = null;
				_hasValue = false;
			}
		}

		private void ComputeAndCacheListInternal()
		{
			try
			{
				_cachedList = _computeListFunction();
				_hasValue = true;
			}
			catch
			{
				_hasValue = false;
				throw;
			}
		}

		public IEnumerator<T> GetEnumerator()
		{
			return Value.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public struct CachedUnityObject<T> : IEquatable<CachedUnityObject<T>> where T : Object
	{
		private T _value;

		private bool _hasValue;

		public bool HasValue
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return _hasValue;
			}
		}

		public T Value
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return _value;
			}
		}

		public CachedUnityObject(T value)
		{
			_value = value;
			_hasValue = (Object)(object)value != (Object)null;
		}

		public void Set(T newValue)
		{
			_value = newValue;
			_hasValue = (Object)(object)newValue != (Object)null;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Reset()
		{
			_value = default(T);
			_hasValue = false;
		}

		public override string ToString()
		{
			if (!_hasValue)
			{
				return "No Value";
			}
			return ((object)_value).ToString() ?? "null";
		}

		public override bool Equals(object obj)
		{
			if (obj is CachedUnityObject<T> other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(CachedUnityObject<T> other)
		{
			return (Object)(object)_value == (Object)(object)other._value;
		}

		public override int GetHashCode()
		{
			if (!_hasValue)
			{
				return 0;
			}
			return ((Object)_value).GetInstanceID();
		}

		public static bool operator ==(CachedUnityObject<T> left, CachedUnityObject<T> right)
		{
			return (Object)(object)left._value == (Object)(object)right._value;
		}

		public static bool operator !=(CachedUnityObject<T> left, CachedUnityObject<T> right)
		{
			return (Object)(object)left._value != (Object)(object)right._value;
		}
	}
	public class CachedValue<T>
	{
		private readonly Func<T> _computeValueFunction;

		private readonly object _lock = new object();

		private T _cachedValue;

		private bool _hasValue;

		public T Value
		{
			get
			{
				if (!_hasValue)
				{
					lock (_lock)
					{
						if (!_hasValue)
						{
							ComputeAndCacheValueInternal();
						}
					}
				}
				return _cachedValue;
			}
		}

		public bool HasValue
		{
			get
			{
				lock (_lock)
				{
					return _hasValue;
				}
			}
		}

		public CachedValue(Func<T> computeValueFunction, bool eager = false)
		{
			_computeValueFunction = computeValueFunction ?? throw new ArgumentNullException("computeValueFunction");
			_cachedValue = default(T);
			_hasValue = false;
			if (eager)
			{
				ComputeAndCacheValueInternal();
			}
		}

		public void Reset()
		{
			lock (_lock)
			{
				_cachedValue = default(T);
				_hasValue = false;
			}
		}

		private void ComputeAndCacheValueInternal()
		{
			try
			{
				_cachedValue = _computeValueFunction();
				_hasValue = true;
			}
			catch
			{
				_hasValue = false;
				throw;
			}
		}
	}
	[Serializable]
	public struct NetworkPositionalSyncFidelity
	{
		[Tooltip("Controls how aggressively the client's model catches up to the server's actual position. A smaller value is faster and snappier, but can appear jittery on laggy connections.")]
		public float InterpolationAggressiveness;

		[Tooltip("The distance the enemy must move from its last synced position before the server sends a new network update. A smaller value means more frequent, accurate updates at the cost of higher bandwidth.")]
		public float UpdateDistanceThreshold;
	}
}
namespace LethalCompanyShisha.Enemies
{
	public class ShishaAdapter : IEnemyAdapter
	{
		[CompilerGenerated]
		private EnemyAI <instance>P;

		private float _targetSpeed;

		[Tooltip("Low-accuracy, low-bandwidth setting.")]
		public NetworkPositionalSyncFidelity ShishaFidelityProfile;

		public NavMeshAgent Agent => <instance>P.agent;

		public Animator Animator => <instance>P.creatureAnimator;

		public Transform Transform => ((Component)<instance>P).transform;

		public Transform EyeTransform => <instance>P.eye;

		public GameObject[] AssignedAINodes
		{
			get
			{
				return <instance>P.allAINodes;
			}
			set
			{
				<instance>P.allAINodes = value;
			}
		}

		public PlayerControllerB TargetPlayer
		{
			get
			{
				return <instance>P.targetPlayer;
			}
			set
			{
				<instance>P.targetPlayer = value;
			}
		}

		public bool IsDead => <instance>P.isEnemyDead;

		public float StunNormalizedTimer => <instance>P.stunNormalizedTimer;

		public float OpenDoorSpeedMultiplier
		{
			get
			{
				return <instance>P.openDoorSpeedMultiplier;
			}
			set
			{
				<instance>P.openDoorSpeedMultiplier = value;
			}
		}

		public float AIIntervalLength
		{
			get
			{
				return <instance>P.AIIntervalTime;
			}
			set
			{
				<instance>P.AIIntervalTime = value;
			}
		}

		public int Health
		{
			get
			{
				return <instance>P.enemyHP;
			}
			set
			{
				<instance>P.enemyHP = value;
			}
		}

		public float AgentSpeedChangeRate { get; set; }

		public float NetworkPositionInterpolationAggressiveness
		{
			get
			{
				return <instance>P.syncMovementSpeed;
			}
			set
			{
				<instance>P.syncMovementSpeed = value;
			}
		}

		public float NetworkPositionUpdateDistanceTheshold
		{
			get
			{
				return <instance>P.updatePositionThreshold;
			}
			set
			{
				<instance>P.updatePositionThreshold = value;
			}
		}

		public ShishaAdapter(EnemyAI instance)
		{
			<instance>P = instance;
			AgentSpeedChangeRate = 10f;
			ShishaFidelityProfile = new NetworkPositionalSyncFidelity
			{
				InterpolationAggressiveness = 0.25f,
				UpdateDistanceThreshold = 1f
			};
			base..ctor();
		}

		public bool ApplyDamage(int damage)
		{
			Health -= damage;
			return Health <= 0;
		}

		internal void MoveAgent()
		{
			Agent.speed = Mathf.MoveTowards(Agent.speed, _targetSpeed, AgentSpeedChangeRate * Time.deltaTime);
		}

		internal void SetMovementProfile(float maxSpeed, float acceleration)
		{
			_targetSpeed = maxSpeed;
			Agent.acceleration = acceleration;
		}

		internal void BeginGracefulStop()
		{
			SetMovementProfile(0f, 100f);
		}

		internal void KillAllSpeed()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Agent.speed = 0f;
			Agent.velocity = Vector3.zero;
			_targetSpeed = 0f;
		}

		public void StopAllPathing()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			<instance>P.StopSearch(<instance>P.currentSearch, true);
			<instance>P.destination = RoundManager.Instance.GetNavMeshPosition(((Component)<instance>P).transform.position, RoundManager.Instance.navHit, -1f, -1);
			<instance>P.movingTowardsTargetPlayer = false;
			<instance>P.moveTowardsDestination = false;
		}

		public void MoveToDestination(Vector3 destination)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			<instance>P.SetDestinationToPosition(destination, false);
		}

		public void MoveToPlayer(PlayerControllerB player)
		{
			<instance>P.SetMovingTowardsTargetPlayer(player);
			<instance>P.moveTowardsDestination = true;
		}

		public bool HasReachedDestination()
		{
			//IL_0049: 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)
			if (!<instance>P.moveTowardsDestination)
			{
				return true;
			}
			if (Agent.pathPending)
			{
				return false;
			}
			if (Agent.remainingDistance <= Agent.stoppingDistance)
			{
				if (Agent.hasPath)
				{
					Vector3 velocity = Agent.velocity;
					if (!(((Vector3)(ref velocity)).sqrMagnitude < 0.05f))
					{
						goto IL_005f;
					}
				}
				return true;
			}
			goto IL_005f;
			IL_005f:
			return false;
		}

		public void SetNetworkFidelityProfile(NetworkPositionalSyncFidelity profile)
		{
			NetworkPositionInterpolationAggressiveness = profile.InterpolationAggressiveness;
			NetworkPositionUpdateDistanceTheshold = profile.UpdateDistanceThreshold;
		}
	}
	public class ShishaBlackboard : IEnemyBlackboard
	{
		public WeightedPicker<ShishaPoopBehaviour.PoopType> PoopPicker;

		public bool IsKillable { get; set; }

		public bool IsWanderEnabled { get; set; }

		public bool IsAnchoredWanderEnabled { get; set; }

		public bool IsPoopBehaviourEnabled { get; set; }

		public bool IsTimeInDayLeaveEnabled { get; set; }

		public double WanderCycleEndTime { get; set; }

		public float PoopProbability { get; set; } = 0.05f;


		public ShishaServer PartnerShisha { get; set; }

		public ShishaServer.Gender Gender { get; set; }

		public Vector3 SpawnPosition { get; set; }

		public Vector3 RunAwayPosition { get; set; }

		public Transform PoopPlaceholder { get; set; }

		public ShishaNetcodeController NetcodeController { get; set; }
	}
	public class ShishaClient : MonoBehaviour
	{
		public enum SkinType : byte
		{
			Default,
			Spooky,
			Hell,
			Snow
		}

		public static readonly int ForceWalk = Animator.StringToHash("ForceWalk");

		public static readonly int OnHit = Animator.StringToHash("OnHit");

		public static readonly int IsDead = Animator.StringToHash("IsDead");

		public static readonly int DoPoop = Animator.StringToHash("DoPoop");

		public static readonly int IsBowing = Animator.StringToHash("IsBowing");

		public static readonly int IsGrazing = Animator.StringToHash("IsGrazing");

		public static readonly int DoLieDown = Animator.StringToHash("DoLieDown");

		private static readonly int Speed = Animator.StringToHash("Speed");

		[Header("Audio")]
		[SerializeField]
		private AudioSource creatureVoice;

		[SerializeField]
		public AudioSource creatureSfx;

		[Tooltip("An array of audio clips that can be played randomly at intervals while the creature is wandering.")]
		[SerializeField]
		public AudioClip[] ambientSfx;

		[SerializeField]
		public AudioClip[] footstepSfx;

		[Header("Renderers")]
		[SerializeField]
		private SkinnedMeshRenderer mainBodyRenderer;

		[SerializeField]
		private SkinnedMeshRenderer hornsRenderer;

		[SerializeField]
		private GameObject rootRenderer;

		[SerializeField]
		private Material[] skinMaterials;

		[SerializeField]
		private Material[] hornSkinMaterials;

		[Header("Particle Effects")]
		[SerializeField]
		private ParticleSystem poofParticleSystem;

		[Header("Misc Objects")]
		[SerializeField]
		private Transform poopPlaceholder;

		[SerializeField]
		private GameObject scanNode;

		[Header("Controllers")]
		[Space(5f)]
		[SerializeField]
		private ShishaNetcodeController netcodeController;

		[SerializeField]
		private Animator animator;

		private ShishaPoopBehaviour _currentPoop;

		private Vector3 _agentLastPosition;

		private bool _networkEventsSubscribed;

		private float _agentCurrentSpeed;

		private void Awake()
		{
			if (!Object.op_Implicit((Object)(object)netcodeController))
			{
				netcodeController = ((Component)this).GetComponent<ShishaNetcodeController>();
			}
		}

		private void OnEnable()
		{
			SubscribeToNetworkEvents();
		}

		private void OnDisable()
		{
			UnsubscribeFromNetworkEvents();
		}

		private void Start()
		{
			if (!Object.op_Implicit((Object)(object)animator))
			{
				animator = ((Component)this).GetComponent<Animator>();
			}
			SubscribeToNetworkEvents();
			InitializeConfigValues();
			AddStateMachineBehaviours(animator);
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position;
			float agentCurrentSpeed = _agentCurrentSpeed;
			Vector3 val = position - _agentLastPosition;
			_agentCurrentSpeed = Mathf.Lerp(agentCurrentSpeed, ((Vector3)(ref val)).magnitude / Time.deltaTime, 0.75f);
			_agentLastPosition = position;
			animator.SetFloat(Speed, _agentCurrentSpeed);
		}

		private void HandlePlayAmbientSfx(int clipIndex)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			AudioClip val = ambientSfx[clipIndex];
			creatureVoice.PlayOneShot(val);
			WalkieTalkie.TransmitOneShotAudio(creatureVoice, val, 1f);
			RoundManager.Instance.PlayAudibleNoise(((Component)creatureVoice).gameObject.transform.position, 10f, 0.5f, 0, false, 0);
		}

		private void HandleSpawnShishaPoop(NetworkObjectReference poopNetworkObjectReference, int scrapValue)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			NetworkObject val = default(NetworkObject);
			if (((NetworkObjectReference)(ref poopNetworkObjectReference)).TryGet(ref val, (NetworkManager)null))
			{
				ShishaPlugin.LogVerbose("Poop network object was not null!");
				_currentPoop = ((Component)val).GetComponent<ShishaPoopBehaviour>();
				((Component)_currentPoop).transform.position = ((Component)poopPlaceholder).transform.position;
				((Component)_currentPoop).transform.rotation = ((Component)poopPlaceholder).transform.rotation;
				((Component)_currentPoop).transform.SetParent(poopPlaceholder, false);
				((GrabbableObject)_currentPoop).SetScrapValue(scrapValue);
				ShishaPlugin.LogVerbose("Shisha poop spawned.");
			}
		}

		private void HandleSetGender(ShishaServer.Gender gender)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			ShishaPlugin.LogVerbose($"[ShishaClient] Setting gender of this Shisha to {gender}.");
			bool enabled = ((Renderer)hornsRenderer).enabled;
			Vector3 localScale = rootRenderer.transform.localScale;
			switch (gender)
			{
			case ShishaServer.Gender.Male:
				enabled = true;
				((Vector3)(ref localScale))..ctor(0.9f, 0.9f, 0.9f);
				break;
			case ShishaServer.Gender.Female:
				enabled = false;
				((Vector3)(ref localScale))..ctor(0.8f, 0.8f, 0.8f);
				break;
			}
			((Renderer)hornsRenderer).enabled = enabled;
			((Component)this).gameObject.transform.localScale = localScale;
		}

		private void HandleSetSkinType(SkinType skinType)
		{
			ShishaPlugin.LogVerbose($"[ShishaClient] Setting the skin type of this Shisha to {skinType}.");
			((Renderer)mainBodyRenderer).material = skinMaterials[(uint)skinType];
			((Renderer)hornsRenderer).material = hornSkinMaterials[(uint)skinType];
		}

		public void DropPoop()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_currentPoop))
			{
				((GrabbableObject)_currentPoop).parentObject = null;
				((Component)_currentPoop).transform.SetParent(StartOfRound.Instance.propsContainer, true);
				((GrabbableObject)_currentPoop).EnablePhysics(true);
				((GrabbableObject)_currentPoop).FallToGround(true, false, default(Vector3));
				((Component)_currentPoop).transform.SetParent(RoundManager.Instance.spawnedScrapContainer, true);
				((GrabbableObject)_currentPoop).isHeld = false;
				((GrabbableObject)_currentPoop).grabbable = true;
				((GrabbableObject)_currentPoop).grabbableToEnemies = true;
				_currentPoop = null;
			}
		}

		public IEnumerator CompleteDeathSequence()
		{
			ShishaPlugin.LogVerbose("In CompleteDeathSequence");
			yield return (object)new WaitForSeconds(1f);
			poofParticleSystem.Play();
			rootRenderer.gameObject.SetActive(false);
			creatureSfx.Stop(true);
			Object.Destroy((Object)(object)scanNode.gameObject);
			yield return (object)new WaitForSeconds(0.1f);
			Object.Destroy((Object)(object)rootRenderer);
			if (((NetworkBehaviour)netcodeController).IsServer)
			{
				SpawnDeathPoopsServerRpc();
				yield return (object)new WaitForSeconds(0.5f);
			}
		}

		[ServerRpc]
		private void SpawnDeathPoopsServerRpc()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0067: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			List<Item> list = new List<Item>(3)
			{
				ShishaPlugin.ShishaRedPoopItem,
				ShishaPlugin.ShishaGreenPoopItem,
				ShishaPlugin.ShishaBluePoopItem
			};
			foreach (Item item in list)
			{
				Vector3 randomNavMeshPositionInRadiusSpherical = RoundManager.Instance.GetRandomNavMeshPositionInRadiusSpherical(((Component)this).transform.position, 2f, default(NavMeshHit));
				GameObject val = Object.Instantiate<GameObject>(item.spawnPrefab, randomNavMeshPositionInRadiusSpherical, Quaternion.identity, StartOfRound.Instance.propsContainer);
				ShishaPoopBehaviour component = val.GetComponent<ShishaPoopBehaviour>();
				((GrabbableObject)component).EnablePhysics(true);
				((GrabbableObject)component).FallToGround(true, false, default(Vector3));
				((Component)component).transform.SetParent(RoundManager.Instance.spawnedScrapContainer, true);
				NetworkObject component2 = val.GetComponent<NetworkObject>();
				component2.Spawn(false);
			}
		}

		private void InitializeConfigValues()
		{
			creatureVoice.volume = ShishaPlugin.Config.AmbientSfxVolume * 2f;
			creatureSfx.volume = ShishaPlugin.Config.FootstepSfxVolume;
		}

		private void AddStateMachineBehaviours(Animator receivedAnimator)
		{
			StateMachineBehaviour[] behaviours = receivedAnimator.GetBehaviours<StateMachineBehaviour>();
			StateMachineBehaviour[] array = behaviours;
			foreach (StateMachineBehaviour val in array)
			{
				if (val is BaseStateMachineBehaviour baseStateMachineBehaviour)
				{
					baseStateMachineBehaviour.Initialize(netcodeController);
				}
			}
		}

		private void HandleSetAnimationTrigger(int animationId)
		{
			animator.SetTrigger(animationId);
		}

		private void HandleSetAnimationBool(int animationId, bool value)
		{
			animator.SetBool(animationId, value);
		}

		private void SubscribeToNetworkEvents()
		{
			if (!_networkEventsSubscribed && Object.op_Implicit((Object)(object)netcodeController))
			{
				ShishaPlugin.LogVerbose("[ShishaClient] Subscribed to network events.");
				netcodeController.OnSetAnimationTrigger += HandleSetAnimationTrigger;
				netcodeController.OnSpawnShishaPoop += HandleSpawnShishaPoop;
				netcodeController.OnPlayAmbientSfx += HandlePlayAmbientSfx;
				netcodeController.OnSetAnimationBool += HandleSetAnimationBool;
				netcodeController.OnSetGender += HandleSetGender;
				netcodeController.OnSetSkinType += HandleSetSkinType;
				_networkEventsSubscribed = true;
			}
		}

		private void UnsubscribeFromNetworkEvents()
		{
			if (_networkEventsSubscribed && Object.op_Implicit((Object)(object)netcodeController))
			{
				ShishaPlugin.LogVerbose("[ShishaClient] Unsubscribed from network events.");
				netcodeController.OnSetAnimationTrigger -= HandleSetAnimationTrigger;
				netcodeController.OnSpawnShishaPoop -= HandleSpawnShishaPoop;
				netcodeController.OnPlayAmbientSfx -= HandlePlayAmbientSfx;
				netcodeController.OnSetAnimationBool -= HandleSetAnimationBool;
				netcodeController.OnSetGender -= HandleSetGender;
				netcodeController.OnSetSkinType -= HandleSetSkinType;
				_networkEventsSubscribed = false;
			}
		}
	}
	public class ShishaNetcodeController : NetworkBehaviour
	{
		internal event Action OnOneShotIdleAnimationComplete;

		internal event Action<int> OnSetAnimationTrigger;

		internal event Action<NetworkObjectReference, int> OnSpawnShishaPoop;

		internal event Action<int> OnPlayAmbientSfx;

		internal event Action<int, bool> OnSetAnimationBool;

		internal event Action<ShishaServer.Gender> OnSetGender;

		internal event Action<ShishaClient.SkinType> OnSetSkinType;

		[ClientRpc]
		internal void SetSkinTypeClientRpc(ShishaClient.SkinType skinType)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(13225499u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<ShishaClient.SkinType>(ref skinType, default(ForEnums));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 13225499u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					this.OnSetSkinType?.Invoke(skinType);
				}
			}
		}

		[ClientRpc]
		internal void SetGenderClientRpc(ShishaServer.Gender gender)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(93014574u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<ShishaServer.Gender>(ref gender, default(ForEnums));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 93014574u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					this.OnSetGender?.Invoke(gender);
				}
			}
		}

		[ClientRpc]
		internal void PlayAmbientSfxClientRpc(int clipIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3128063444u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, clipIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3128063444u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					this.OnPlayAmbientSfx?.Invoke(clipIndex);
				}
			}
		}

		[ClientRpc]
		internal void SpawnShishaPoopClientRpc(NetworkObjectReference poopNetworkObjectReference, int scrapValue)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2931340248u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref poopNetworkObjectReference, default(ForNetworkSerializable));
					BytePacker.WriteValueBitPacked(val2, scrapValue);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2931340248u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					this.OnSpawnShishaPoop?.Invoke(poopNetworkObjectReference, scrapValue);
				}
			}
		}

		[ClientRpc]
		internal void SetAnimationTriggerClientRpc(int animationId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3391285696u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, animationId);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3391285696u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					this.OnSetAnimationTrigger?.Invoke(animationId);
				}
			}
		}

		[ClientRpc]
		internal void SetAnimationBoolClientRpc(int animationId, bool value)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3260505482u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, animationId);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref value, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3260505482u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					this.OnSetAnimationBool?.Invoke(animationId, value);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		internal void OneShotIdleAnimationCompleteServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2685241602u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2685241602u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					this.OnOneShotIdleAnimationComplete?.Invoke();
				}
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(13225499u, new RpcReceiveHandler(__rpc_handler_13225499), "SetSkinTypeClientRpc");
			((NetworkBehaviour)this).__registerRpc(93014574u, new RpcReceiveHandler(__rpc_handler_93014574), "SetGenderClientRpc");
			((NetworkBehaviour)this).__registerRpc(3128063444u, new RpcReceiveHandler(__rpc_handler_3128063444), "PlayAmbientSfxClientRpc");
			((NetworkBehaviour)this).__registerRpc(2931340248u, new RpcReceiveHandler(__rpc_handler_2931340248), "SpawnShishaPoopClientRpc");
			((NetworkBehaviour)this).__registerRpc(3391285696u, new RpcReceiveHandler(__rpc_handler_3391285696), "SetAnimationTriggerClientRpc");
			((NetworkBehaviour)this).__registerRpc(3260505482u, new RpcReceiveHandler(__rpc_handler_3260505482), "SetAnimationBoolClientRpc");
			((NetworkBehaviour)this).__registerRpc(2685241602u, new RpcReceiveHandler(__rpc_handler_2685241602), "OneShotIdleAnimationCompleteServerRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_13225499(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ShishaClient.SkinType skinTypeClientRpc = default(ShishaClient.SkinType);
				((FastBufferReader)(ref reader)).ReadValueSafe<ShishaClient.SkinType>(ref skinTypeClientRpc, default(ForEnums));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ShishaNetcodeController)(object)target).SetSkinTypeClientRpc(skinTypeClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_93014574(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ShishaServer.Gender genderClientRpc = default(ShishaServer.Gender);
				((FastBufferReader)(ref reader)).ReadValueSafe<ShishaServer.Gender>(ref genderClientRpc, default(ForEnums));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ShishaNetcodeController)(object)target).SetGenderClientRpc(genderClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3128063444(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int clipIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref clipIndex);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ShishaNetcodeController)(object)target).PlayAmbientSfxClientRpc(clipIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2931340248(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkObjectReference poopNetworkObjectReference = default(NetworkObjectReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref poopNetworkObjectReference, default(ForNetworkSerializable));
				int scrapValue = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref scrapValue);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ShishaNetcodeController)(object)target).SpawnShishaPoopClientRpc(poopNetworkObjectReference, scrapValue);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3391285696(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int animationTriggerClientRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref animationTriggerClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ShishaNetcodeController)(object)target).SetAnimationTriggerClientRpc(animationTriggerClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3260505482(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int animationId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref animationId);
				bool value = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref value, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ShishaNetcodeController)(object)target).SetAnimationBoolClientRpc(animationId, value);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2685241602(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ShishaNetcodeController)(object)target).OneShotIdleAnimationCompleteServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "ShishaNetcodeController";
		}
	}
	public class ShishaServer : StateManagedAI<ShishaServer.States, ShishaServer>
	{
		public enum States
		{
			Spawning,
			Roaming,
			ArrivingAtIdlePosition,
			Idle,
			RunningAway,
			Dead
		}

		public enum Gender
		{
			Male,
			Female
		}

		[SerializeField]
		public AISearchRoutine RoamSearchRoutine;

		[SerializeField]
		private Transform poopPlaceholder;

		[SerializeField]
		public ShishaNetcodeController netcodeController;

		private static SeichiAltMapIntegration snowichiIntegration;

		private static SeichiAltMapIntegration scorchiIntegration;

		private static SeichiAltMapIntegration spookichiIntegration;

		private float _ambientAudioTimer;

		private float _lastHitTime;

		private int _numberOfAmbientAudioClips;

		private bool _networkEventsSubscribed;

		private static bool _hasRegisteredImperiumInsights;

		public AIContext<ShishaBlackboard, ShishaAdapter> Context { get; private set; }

		private ShishaBlackboard _blackboard => Context.Blackboard;

		private ShishaAdapter _adapter => Context.Adapter;

		private void Awake()
		{
			ShishaBlackboard blackboard = new ShishaBlackboard();
			ShishaAdapter adapter = new ShishaAdapter((EnemyAI)(object)this);
			Context = new AIContext<ShishaBlackboard, ShishaAdapter>(blackboard, adapter);
			_blackboard.PoopPicker = new WeightedPicker<ShishaPoopBehaviour.PoopType>(new List<(ShishaPoopBehaviour.PoopType, float)>
			{
				(ShishaPoopBehaviour.PoopType.Common, ShishaPlugin.Config.CommonCrystalSpawnWeight),
				(ShishaPoopBehaviour.PoopType.Uncommon, ShishaPlugin.Config.UncommonCrystalSpawnWeight),
				(ShishaPoopBehaviour.PoopType.Rare, ShishaPlugin.Config.RareCrystalSpawnWeight)
			});
		}

		private void OnEnable()
		{
			SubscribeToNetworkEvents();
			snowichiIntegration?.AddTrackedShisha(this);
			scorchiIntegration?.AddTrackedShisha(this);
			spookichiIntegration?.AddTrackedShisha(this);
		}

		private void OnDisable()
		{
			UnsubscribeFromNetworkEvents();
			snowichiIntegration?.RemoveTrackedShisha(this);
			scorchiIntegration?.RemoveTrackedShisha(this);
			spookichiIntegration?.RemoveTrackedShisha(this);
		}

		public override void Start()
		{
			InitializeConfigValues();
			CollectAudioClipsAndSources<ShishaClient>();
			base.Start();
			if (((NetworkBehaviour)this).IsServer)
			{
				SubscribeToNetworkEvents();
				RegisterImperiumInsights();
				CheckIfSceneIsSeichi();
				_numberOfAmbientAudioClips = ((Component)this).GetComponent<ShishaClient>().ambientSfx.Length;
			}
		}

		private void RegisterImperiumInsights()
		{
			bool isAgentNull = !Object.op_Implicit((Object)(object)_adapter.Agent);
			if (ImperiumIntegration.IsLoaded && !_hasRegisteredImperiumInsights)
			{
				Visualization.InsightsFor<ShishaServer>().SetPersonalNameGenerator((Func<ShishaServer, string>)((ShishaServer entity) => entity.Id)).RegisterInsight("Behaviour State", (Func<ShishaServer, string>)((ShishaServer entity) => entity.CurrentState.GetStateType().ToString()))
					.RegisterInsight("Acceleration", (Func<ShishaServer, string>)((ShishaServer entity) => isAgentNull ? "0" : $"{entity._adapter.Agent.acceleration:0.0}"))
					.RegisterInsight("Gender", (Func<ShishaServer, string>)((ShishaServer entity) => entity._blackboard.Gender.ToString()));
			}
			_hasRegisteredImperiumInsights = true;
		}

		private void CheckIfSceneIsSeichi()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)snowichiIntegration) && Object.op_Implicit((Object)(object)scorchiIntegration) && Object.op_Implicit((Object)(object)spookichiIntegration))
			{
				return;
			}
			Scene sceneByName = SceneManager.GetSceneByName("Seichi");
			if (((Scene)(ref sceneByName)).IsValid() && ((Scene)(ref sceneByName)).isLoaded)
			{
				GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
				Transform val = null;
				GameObject[] array = rootGameObjects;
				foreach (GameObject val2 in array)
				{
					if (((Object)val2).name == "Environment")
					{
						val = val2.transform;
					}
				}
				if (!Object.op_Implicit((Object)(object)val))
				{
					LogVerbose("Couldn't find the Environment transform.");
					return;
				}
				if (!Object.op_Implicit((Object)(object)snowichiIntegration))
				{
					GameObject gameObject = ((Component)val.Find("v0xxManager/Snowichi")).gameObject;
					if (Object.op_Implicit((Object)(object)gameObject))
					{
						snowichiIntegration = gameObject.GetComponent<SeichiAltMapIntegration>();
						if (!Object.op_Implicit((Object)(object)snowichiIntegration))
						{
							snowichiIntegration = gameObject.AddComponent<SeichiAltMapIntegration>();
						}
					}
				}
				if (!Object.op_Implicit((Object)(object)scorchiIntegration))
				{
					GameObject gameObject2 = ((Component)val.Find("WebleyManager/Scorchi")).gameObject;
					if (Object.op_Implicit((Object)(object)gameObject2))
					{
						scorchiIntegration = gameObject2.GetComponent<SeichiAltMapIntegration>();
						if (!Object.op_Implicit((Object)(object)scorchiIntegration))
						{
							scorchiIntegration = gameObject2.AddComponent<SeichiAltMapIntegration>();
						}
					}
				}
				if (!Object.op_Implicit((Object)(object)spookichiIntegration))
				{
					GameObject gameObject3 = ((Component)val.Find("Halloween/Spookichi")).gameObject;
					if (Object.op_Implicit((Object)(object)gameObject3))
					{
						spookichiIntegration = gameObject3.GetComponent<SeichiAltMapIntegration>();
						if (!Object.op_Implicit((Object)(object)spookichiIntegration))
						{
							spookichiIntegration = gameObject3.AddComponent<SeichiAltMapIntegration>();
						}
					}
				}
				snowichiIntegration.AddTrackedShisha(this);
				scorchiIntegration.AddTrackedShisha(this);
				spookichiIntegration.AddTrackedShisha(this);
				snowichiIntegration.skinTypeWhenEnabled = ShishaClient.SkinType.Snow;
				scorchiIntegration.skinTypeWhenEnabled = ShishaClient.SkinType.Hell;
				spookichiIntegration.skinTypeWhenEnabled = ShishaClient.SkinType.Spooky;
				if (!((Component)snowichiIntegration).gameObject.activeSelf && !((Component)scorchiIntegration).gameObject.activeSelf)
				{
					_blackboard.NetcodeController.SetSkinTypeClientRpc(ShishaClient.SkinType.Default);
				}
				else if (((Component)snowichiIntegration).gameObject.activeSelf)
				{
					_blackboard.NetcodeController.SetSkinTypeClientRpc(ShishaClient.SkinType.Snow);
				}
				else if (((Component)scorchiIntegration).gameObject.activeSelf)
				{
					_blackboard.NetcodeController.SetSkinTypeClientRpc(ShishaClient.SkinType.Hell);
				}
				else if (((Component)spookichiIntegration).gameObject.activeSelf)
				{
					_blackboard.NetcodeController.SetSkinTypeClientRpc(ShishaClient.SkinType.Spooky);
				}
			}
			else
			{
				snowichiIntegration = null;
				scorchiIntegration = null;
				spookichiIntegration = null;
			}
		}

		public void ManageAmbientSfx()
		{
			if (!_blackboard.IsWanderEnabled)
			{
				return;
			}
			_ambientAudioTimer -= Time.deltaTime;
			if (_ambientAudioTimer <= 0f)
			{
				_ambientAudioTimer = Random.Range(ShishaPlugin.Config.AmbientSfxTimerMin, ShishaPlugin.Config.AmbientSfxTimerMax);
				if (_numberOfAmbientAudioClips != 0)
				{
					netcodeController.PlayAmbientSfxClientRpc(Random.Range(0, _numberOfAmbientAudioClips));
				}
			}
		}

		protected override bool ShouldRunUpdate()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				return !_adapter.IsDead;
			}
			return false;
		}

		protected override bool ShouldRunAiInterval()
		{
			return ShouldRunUpdate();
		}

		protected override States DetermineInitialState()
		{
			return States.Spawning;
		}

		public override void DaytimeEnemyLeave()
		{
			if (((NetworkBehaviour)this).IsServer && _blackboard.IsTimeInDayLeaveEnabled)
			{
				((MonoBehaviour)this).StartCoroutine(LeaveWhenNoOneIsLooking(Random.Range(5f, 12f)));
				((EnemyAI)this).DaytimeEnemyLeave();
			}
		}

		private IEnumerator LeaveWhenNoOneIsLooking(float checkIntervalTimer)
		{
			if (!((NetworkBehaviour)this).IsServer)
			{
				yield break;
			}
			while (!_adapter.IsDead)
			{
				if (!IsPlayerLookingAtShisha(120f, 80))
				{
					((EnemyAI)this).KillEnemyServerRpc(false);
					Object.Destroy((Object)(object)((Component)this).gameObject);
					break;
				}
				yield return (object)new WaitForSeconds(checkIntervalTimer);
			}
		}

		private bool IsPlayerLookingAtShisha(float playerViewWidth = 30f, int playerViewRange = 60, float playerProximityAwareness = 3f)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!PlayerUtil.IsPlayerDead(val) && val.HasLineOfSightToPosition(((EnemyAI)this).eye.position, playerViewWidth, playerViewRange, playerProximityAwareness))
				{
					return true;
				}
			}
			return false;
		}

		private void HandleOneShotIdleAnimationComplete()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				TriggerCustomEvent("OneShotIdleAnimationComplete");
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitId = -1)
		{
			((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitId);
			if (!((NetworkBehaviour)this).IsServer || _adapter.IsDead || !_blackboard.IsKillable || Time.time - _lastHitTime < 0.02f)
			{
				return;
			}
			_lastHitTime = Time.time;
			_adapter.TargetPlayer = playerWhoHit;
			if (_adapter.ApplyDamage(force))
			{
				SwitchBehaviourState(States.Dead);
				return;
			}
			_blackboard.NetcodeController.SetAnimationTriggerClientRpc(ShishaClient.OnHit);
			if (CurrentState.GetStateType() != States.RunningAway)
			{
				SwitchBehaviourState(States.RunningAway);
			}
		}

		private void InitializeConfigValues()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				LogVerbose("Initializing config values...");
				ShishaConfig config = ShishaPlugin.Config;
				RoamSearchRoutine.loopSearch = true;
				RoamSearchRoutine.searchWidth = config.WanderRadius;
				((EnemyAI)this).creatureVoice.volume = config.AmbientSfxVolume * 2f;
				((EnemyAI)this).creatureSFX.volume = config.FootstepSfxVolume;
				_adapter.Health = Mathf.Max(config.Health, 1);
				_blackboard.IsKillable = config.Killable;
				_blackboard.IsWanderEnabled = config.Wander;
				_blackboard.IsAnchoredWanderEnabled = config.AnchoredWandering;
				_blackboard.IsTimeInDayLeaveEnabled = config.TimeInDayLeaveEnabled;
				_blackboard.IsPoopBehaviourEnabled = config.PoopBehaviourEnabled;
				_blackboard.PoopProbability = config.PoopChance;
				_blackboard.PoopPlaceholder = poopPlaceholder;
				_blackboard.Gender = Gender.Male;
				_blackboard.NetcodeController = netcodeController;
			}
		}

		private void SubscribeToNetworkEvents()
		{
			if (((NetworkBehaviour)this).IsServer && !_networkEventsSubscribed)
			{
				netcodeController.OnOneShotIdleAnimationComplete += HandleOneShotIdleAnimationComplete;
				_networkEventsSubscribed = true;
			}
		}

		private void UnsubscribeFromNetworkEvents()
		{
			if (((NetworkBehaviour)this).IsServer && _networkEventsSubscribed)
			{
				netcodeController.OnOneShotIdleAnimationComplete -= HandleOneShotIdleAnimationComplete;
				_networkEventsSubscribed = false;
			}
		}

		protected override string GetLogPrefix()
		{
			return "[ShishaServerAI " + base.Id + "]";
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			base.__initializeRpcs();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "ShishaServer";
		}
	}
}
namespace LethalCompanyShisha.Enemies.Transitions
{
	internal class TransitionFromRunningAway : StateTransition<ShishaServer.States, ShishaServer>
	{
		public TransitionFromRunningAway(ShishaServer enemyAIInstance)
			: base(enemyAIInstance)
		{
		}

		internal override bool ShouldTransitionBeTaken()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			NavMeshAgent agent = EnemyAIInstance.Context.Adapter.Agent;
			if (agent.pathPending)
			{
				return false;
			}
			if (agent.remainingDistance <= agent.stoppingDistance)
			{
				Vector3 val = EnemyAIInstance.Context.Adapter.Transform.position - EnemyAIInstance.Context.Blackboard.RunAwayPosition;
				return ((Vector3)(ref val)).sqrMagnitude <= 6f;
			}
			return false;
		}

		internal override ShishaServer.States NextState()
		{
			if (!EnemyAIInstance.Context.Blackboard.IsWanderEnabled)
			{
				return ShishaServer.States.ArrivingAtIdlePosition;
			}
			if (Random.Range(0, 2) != 0)
			{
				return ShishaServer.States.ArrivingAtIdlePosition;
			}
			return ShishaServer.States.Roaming;
		}
	}
	internal class TransitionToArrivingAtIdlePosition : StateTransition<ShishaServer.States, ShishaServer>
	{
		public TransitionToArrivingAtIdlePosition(ShishaServer enemyAIInstance)
			: base(enemyAIInstance)
		{
		}

		internal override bool ShouldTransitionBeTaken()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			NetworkTime serverTime = NetworkManager.Singleton.ServerTime;
			return ((NetworkTime)(ref serverTime)).Time >= EnemyAIInstance.Context.Blackboard.WanderCycleEndTime;
		}

		internal override ShishaServer.States NextState()
		{
			return ShishaServer.States.ArrivingAtIdlePosition;
		}
	}
	internal class TransitionToIdle : StateTransition<ShishaServer.States, ShishaServer>
	{
		public TransitionToIdle(ShishaServer enemyAIInstance)
			: base(enemyAIInstance)
		{
		}

		internal override bool ShouldTransitionBeTaken()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = EnemyAIInstance.Context.Adapter.Agent.velocity;
			return ((Vector3)(ref velocity)).sqrMagnitude < 0.01f;
		}

		internal override ShishaServer.States NextState()
		{
			return ShishaServer.States.Idle;
		}
	}
}
namespace LethalCompanyShisha.Enemies.BehaviourStates
{
	[Preserve]
	[State(ShishaServer.States.ArrivingAtIdlePosition)]
	internal class ArrivingAtIdlePositionState : BehaviourState<ShishaServer.States, ShishaServer>
	{
		public ArrivingAtIdlePositionState(ShishaServer enemyAiInstance)
			: base(enemyAiInstance)
		{
			base.Transitions = new List<StateTransition<ShishaServer.States, ShishaServer>>(1)
			{
				new TransitionToIdle(EnemyAIInstance)
			};
		}

		internal override void OnStateEnter(ref StateData initData)
		{
			base.OnStateEnter(ref initData);
			EnemyAIInstance.Context.Adapter.StopAllPathing();
			EnemyAIInstance.Context.Adapter.BeginGracefulStop();
		}

		internal override void UpdateBehaviour()
		{
			base.UpdateBehaviour();
			EnemyAIInstance.ManageAmbientSfx();
		}
	}
	[Preserve]
	[State(ShishaServer.States.Dead)]
	internal class DeadState : BehaviourState<ShishaServer.States, ShishaServer>
	{
		public DeadState(ShishaServer enemyAiInstance)
			: base(enemyAiInstance)
		{
			base.Transitions = new List<StateTransition<ShishaServer.States, ShishaServer>>();
		}

		internal override void OnStateEnter(ref StateData initData)
		{
			base.OnStateEnter(ref initData);
			EnemyAIInstance.Context.Adapter.StopAllPathing();
			EnemyAIInstance.Context.Adapter.KillAllSpeed();
			EnemyAIInstance.Context.Blackboard.NetcodeController.SetAnimationBoolClientRpc(ShishaClient.IsDead, value: true);
			((EnemyAI)EnemyAIInstance).KillEnemyServerRpc(false);
		}
	}
	[Preserve]
	[State(ShishaServer.States.Idle)]
	internal class IdleState : BehaviourState<ShishaServer.States, ShishaServer>
	{
		private int _currentIdleAnimation;

		private double _idleCycleEndTime;

		private bool _isIdleAnimationLooping;

		private readonly WeightedPicker<int> _idleAnimationPicker;

		public IdleState(ShishaServer enemyAiInstance)
			: base(enemyAiInstance)
		{
			base.Transitions = new List<StateTransition<ShishaServer.States, ShishaServer>>();
			float item = (EnemyAIInstance.Context.Blackboard.IsPoopBehaviourEnabled ? EnemyAIInstance.Context.Blackboard.PoopProbability : 0f);
			_idleAnimationPicker = new WeightedPicker<int>(new List<(int, float)>
			{
				(ShishaClient.DoPoop, item),
				(ShishaClient.IsGrazing, 0.7f),
				(ShishaClient.DoLieDown, 0.25f)
			});
		}

		internal override void OnStateEnter(ref StateData initData)
		{
			//IL_00fe: 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)
			base.OnStateEnter(ref initData);
			EnemyAIInstance.Context.Adapter.StopAllPathing();
			EnemyAIInstance.Context.Adapter.KillAllSpeed();
			EnemyAIInstance.Context.Adapter.Agent.isStopped = true;
			_currentIdleAnimation = (EnemyAIInstance.Context.Blackboard.IsWanderEnabled ? _idleAnimationPicker.PickOne() : ShishaClient.DoLieDown);
			if (_currentIdleAnimation == ShishaClient.DoPoop || _currentIdleAnimation == ShishaClient.DoLieDown)
			{
				if (_currentIdleAnimation == ShishaClient.DoPoop)
				{
					SpawnShishaPoop();
				}
				EnemyAIInstance.Context.Blackboard.NetcodeController.SetAnimationTriggerClientRpc(_currentIdleAnimation);
				_isIdleAnimationLooping = false;
			}
			else
			{
				EnemyAIInstance.Context.Blackboard.NetcodeController.SetAnimationBoolClientRpc(_currentIdleAnimation, value: true);
				_isIdleAnimationLooping = true;
				NetworkTime serverTime = NetworkManager.Singleton.ServerTime;
				_idleCycleEndTime = ((NetworkTime)(ref serverTime)).Time + (double)Random.Range(10f, 60f);
			}
		}

		internal override void UpdateBehaviour()
		{
			base.UpdateBehaviour();
			EnemyAIInstance.ManageAmbientSfx();
		}

		internal override void AIIntervalBehaviour()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			base.AIIntervalBehaviour();
			if (EnemyAIInstance.Context.Blackboard.IsWanderEnabled && _isIdleAnimationLooping)
			{
				NetworkTime serverTime = NetworkManager.Singleton.ServerTime;
				if (((NetworkTime)(ref serverTime)).Time >= _idleCycleEndTime)
				{
					EnemyAIInstance.SwitchBehaviourState(ShishaServer.States.Roaming);
				}
			}
		}

		internal override void OnStateExit(StateTransition<ShishaServer.States, ShishaServer> transition)
		{
			base.OnStateExit(transition);
			if (_isIdleAnimationLooping)
			{
				EnemyAIInstance.Context.Blackboard.NetcodeController.SetAnimationBoolClientRpc(_currentIdleAnimation, value: false);
			}
			EnemyAIInstance.Context.Adapter.Agent.isStopped = false;
		}

		internal override void OnCustomEvent(string eventName, StateData eventData)
		{
			base.OnCustomEvent(eventName, eventData);
			if (eventName == "OneShotIdleAnimationComplete")
			{
				if (_isIdleAnimationLooping)
				{
					EnemyAIInstance.LogVerbose("The event " + eventName + " was invoked even though this idle animation is a looping one.");
					return;
				}
				EnemyAIInstance.Context.Blackboard.NetcodeController.SetAnimationTriggerClientRpc(ShishaClient.ForceWalk);
				EnemyAIInstance.SwitchBehaviourState(ShishaServer.States.Roaming);
			}
		}

		private void SpawnShishaPoop()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)EnemyAIInstance).IsServer)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)EnemyAIInstance.Context.Blackboard.PoopPlaceholder))
			{
				ShishaPlugin.Logger.LogError((object)"The poop placeholder transform is null.");
				return;
			}
			ShishaPoopBehaviour.PoopType variant = EnemyAIInstance.Context.Blackboard.PoopPicker.PickOne();
			GameObject val = Object.Instantiate<GameObject>(GetPoopItemFromType(variant).spawnPrefab, EnemyAIInstance.Context.Blackboard.PoopPlaceholder.position, EnemyAIInstance.Context.Blackboard.PoopPlaceholder.rotation, EnemyAIInstance.Context.Blackboard.PoopPlaceholder);
			ShishaPoopBehaviour shishaPoopBehaviour = default(ShishaPoopBehaviour);
			if (!val.TryGetComponent<ShishaPoopBehaviour>(ref shishaPoopBehaviour))
			{
				EnemyAIInstance.LogError("The poop object has no ShishaPoopBehaviour. The prefab is probably broken.");
				Object.Destroy((Object)(object)val);
				return;
			}
			int scrapValue = CalculateScrapValue(variant);
			((GrabbableObject)shishaPoopBehaviour).SetScrapValue(scrapValue);
			val.GetComponent<NetworkObject>().Spawn(false);
			EnemyAIInstance.Context.Blackboard.NetcodeController.SpawnShishaPoopClientRpc(NetworkObjectReference.op_Implicit(val), scrapValue);
		}

		private static Item GetPoopItemFromType(ShishaPoopBehaviour.PoopType variant)
		{
			return (Item)(variant switch
			{
				ShishaPoopBehaviour.PoopType.Common => ShishaPlugin.ShishaRedPoopItem, 
				ShishaPoopBehaviour.PoopType.Uncommon => ShishaPlugin.ShishaGreenPoopItem, 
				ShishaPoopBehaviour.PoopType.Rare => ShishaPlugin.ShishaBluePoopItem, 
				_ => ShishaPlugin.ShishaRedPoopItem, 
			});
		}

		private static int CalculateScrapValue(ShishaPoopBehaviour.PoopType variant)
		{
			return variant switch
			{
				ShishaPoopBehaviour.PoopType.Common => Random.Range(ShishaPlugin.Config.CommonCrystalMinValue, ShishaPlugin.Config.CommonCrystalMaxValue + 1), 
				ShishaPoopBehaviour.PoopType.Uncommon => Random.Range(ShishaPlugin.Config.UncommonCrystalMinValue, ShishaPlugin.Config.UncommonCrystalMaxValue + 1), 
				ShishaPoopBehaviour.PoopType.Rare => Random.Range(ShishaPlugin.Config.RareCrystalMinValue, ShishaPlugin.Config.RareCrystalMaxValue + 1), 
				_ => 1, 
			};
		}
	}
	[Preserve]
	[State(ShishaServer.States.Roaming)]
	internal class RoamingState : BehaviourState<ShishaServer.States, ShishaServer>
	{
		public RoamingState(ShishaServer enemyAiInstance)
			: base(enemyAiInstance)
		{
			base.Transitions = new List<StateTransition<ShishaServer.States, ShishaServer>>(1)
			{
				new TransitionToArrivingAtIdlePosition(EnemyAIInstance)
			};
		}

		internal override void OnStateEnter(ref StateData initData)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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)
			base.OnStateEnter(ref initData);
			EnemyAIInstance.Context.Adapter.SetMovementProfile(ShishaPlugin.Config.MaxSpeed, ShishaPlugin.Config.Acceleration);
			ShishaBlackboard blackboard = EnemyAIInstance.Context.Blackboard;
			NetworkTime serverTime = NetworkManager.Singleton.ServerTime;
			blackboard.WanderCycleEndTime = ((NetworkTime)(ref serverTime)).Time + (double)Random.Range(ShishaPlugin.Config.WanderTimeMin, ShishaPlugin.Config.WanderTimeMax);
			((EnemyAI)EnemyAIInstance).StartSearch(EnemyAIInstance.Context.Blackboard.IsAnchoredWanderEnabled ? EnemyAIInstance.Context.Blackboard.SpawnPosition : EnemyAIInstance.Context.Adapter.Transform.position, EnemyAIInstance.RoamSearchRoutine);
		}

		internal override void UpdateBehaviour()
		{
			base.UpdateBehaviour();
			EnemyAIInstance.Context.Adapter.MoveAgent();
			EnemyAIInstance.ManageAmbientSfx();
		}

		internal override void OnStateExit(StateTransition<ShishaServer.States, ShishaServer> transition)
		{
			base.OnStateExit(transition);
			EnemyAIInstance.Context.Adapter.StopAllPathing();
		}
	}
	[Preserve]
	[State(ShishaServer.States.RunningAway)]
	internal class RunningAwayState : BehaviourState<ShishaServer.States, ShishaServer>
	{
		public RunningAwayState(ShishaServer enemyAiInstance)
			: base(enemyAiInstance)
		{
			base.Transitions = new List<StateTransition<ShishaServer.States, ShishaServer>>(1)
			{
				new TransitionFromRunningAway(EnemyAIInstance)
			};
		}

		internal override void OnStateEnter(ref StateData initData)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			base.OnStateEnter(ref initData);
			BaseAI.PathStatus pathStatus;
			Vector3 position = BaseAI.GetFarthestValidNodeFromPosition(out pathStatus, EnemyAIInstance.Context.Adapter.Agent, Object.op_Implicit((Object)(object)EnemyAIInstance.Context.Adapter.TargetPlayer) ? ((Component)EnemyAIInstance.Context.Adapter.TargetPlayer).transform.position : EnemyAIInstance.Context.Adapter.Transform.position, ((EnemyAI)EnemyAIInstance).allAINodes).position;
			if (pathStatus == BaseAI.PathStatus.Invalid)
			{
				EnemyAIInstance.LogWarning("Could not find a valid node to escape to.");
				EnemyAIInstance.SwitchBehaviourState(ShishaServer.States.Roaming);
			}
			else
			{
				EnemyAIInstance.Context.Blackboard.RunAwayPosition = position;
				EnemyAIInstance.Context.Adapter.MoveToDestination(position);
				EnemyAIInstance.Context.Adapter.SetMovementProfile(ShishaPlugin.Config.RunningAwayMaxSpeed, ShishaPlugin.Config.Acceleration);
			}
		}

		internal override void UpdateBehaviour()
		{
			base.UpdateBehaviour();
			EnemyAIInstance.Context.Adapter.MoveAgent();
			EnemyAIInstance.ManageAmbientSfx();
		}

		internal override void OnStateExit(StateTransition<ShishaServer.States, ShishaServer> transition)
		{
			base.OnStateExit(transition);
			EnemyAIInstance.Context.Adapter.StopAllPathing();
		}
	}
	[Preserve]
	[State(ShishaServer.States.Spawning)]
	internal class SpawningState : BehaviourState<ShishaServer.States, ShishaServer>
	{
		public SpawningState(ShishaServer enemyAiInstance)
			: base(enemyAiInstance)
		{
			base.Transitions = new List<StateTransition<ShishaServer.States, ShishaServer>>();
		}

		internal override void OnStateEnter(ref StateData initData)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			base.OnStateEnter(ref initData);
			EnemyAIInstance.Context.Adapter.StopAllPathing();
			EnemyAIInstance.Context.Ada