Decompiled source of PeakCats v1.4.0

plugins/PeakCats.dll

Decompiled 9 hours 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.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using PEAKLib.Items;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.UI;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.Core.Serizalization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("Zorro.Core.Runtime")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 PeakCats
{
	internal class CatAccount : MonoBehaviourPunCallbacks
	{
		public static CatAccount I;

		public const string PropTier = "PeakCatsTier";

		public const string PropPrefix = "PeakCatsPrefix";

		public static readonly Color DefaultPrefix = Color32.op_Implicit(new Color32((byte)232, (byte)176, (byte)74, byte.MaxValue));

		private ConfigFile file;

		private ConfigEntry<int> bestEntry;

		private ConfigEntry<string> colorEntry;

		private ConfigEntry<string> sealEntry;

		private string steamId = "";

		private int best;

		private Color prefix = DefaultPrefix;

		public static int Best
		{
			get
			{
				if (!((Object)(object)I != (Object)null))
				{
					return 0;
				}
				return Mathf.Clamp(I.best, 0, 3);
			}
		}

		public static Color PrefixColor
		{
			get
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)I != (Object)null))
				{
					return DefaultPrefix;
				}
				return I.prefix;
			}
		}

		public static bool IsWarrior => Best >= 3;

		private void Awake()
		{
			I = this;
		}

		private void Start()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			steamId = LocalSteamId();
			string text = "Account " + (string.IsNullOrEmpty(steamId) ? "local" : steamId);
			file = new ConfigFile(Path.Combine(Paths.ConfigPath, "com.attackstudioyt.peakcats.progress.cfg"), true);
			bestEntry = file.Bind<int>(text, "BestSummit", 0, "Most of your own cats you've taken to the Peak together (unlocks 10 / 20 / 30 customizations).\nSealed to your Steam account - edited values stop counting. r2modman's \"Export profile as code\" takes it to another PC.");
			colorEntry = file.Bind<string>(text, "WarriorColour", "#e8b04a", "Colour of your [Warrior] name prefix (set it in the cat panel settings).");
			sealEntry = file.Bind<string>(text, "Seal", "", "Ties this progress to your Steam account. Don't edit.");
			best = Mathf.Clamp(bestEntry.Value, 0, 3);
			if (best > 0 && sealEntry.Value != Seal(best, colorEntry.Value))
			{
				Plugin.Log.LogWarning((object)"PeakCats progress seal doesn't match this Steam account (or the file was edited) - starting from 0.");
				best = 0;
			}
			if (!ColorUtility.TryParseHtmlString(colorEntry.Value, ref prefix))
			{
				prefix = DefaultPrefix;
			}
			Publish();
		}

		private void Save()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			bestEntry.Value = best;
			colorEntry.Value = "#" + ColorUtility.ToHtmlStringRGB(prefix).ToLowerInvariant();
			sealEntry.Value = Seal(best, colorEntry.Value);
			file.Save();
		}

		private string Seal(int b, string color)
		{
			using HMACSHA256 hMACSHA = new HMACSHA256(Encoding.UTF8.GetBytes("PeakCats|summit-seal|v1|AttackStudioYT"));
			byte[] array = hMACSHA.ComputeHash(Encoding.UTF8.GetBytes($"{steamId}|{b}|{color.ToLowerInvariant()}"));
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < 16; i++)
			{
				stringBuilder.Append(array[i].ToString("x2"));
			}
			return stringBuilder.ToString();
		}

		public static string LocalSteamId()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return SteamUser.GetSteamID().m_SteamID.ToString();
			}
			catch
			{
				return "";
			}
		}

		public override void OnJoinedRoom()
		{
			Publish();
		}

		private void Publish()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0038: Expected O, but got Unknown
			if (PhotonNetwork.LocalPlayer != null)
			{
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"PeakCatsTier", (object)Best);
				((Dictionary<object, object>)val).Add((object)"PeakCatsPrefix", (object)ColorUtility.ToHtmlStringRGB(PrefixColor));
				Hashtable val2 = val;
				PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
			}
		}

		public static int TierOf(Player p)
		{
			if (p == null || p.CustomProperties == null || !((Dictionary<object, object>)(object)p.CustomProperties).TryGetValue((object)"PeakCatsTier", out object value) || !(value is int num))
			{
				return 0;
			}
			return Mathf.Clamp(num, 0, 3);
		}

		public static object PrefixProp(Player p)
		{
			if (p == null || p.CustomProperties == null || !((Dictionary<object, object>)(object)p.CustomProperties).TryGetValue((object)"PeakCatsPrefix", out object value))
			{
				return null;
			}
			return value;
		}

		public static bool WarriorOf(Player p, out Color c)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			c = DefaultPrefix;
			if (TierOf(p) < 3)
			{
				return false;
			}
			if (((Dictionary<object, object>)(object)p.CustomProperties).TryGetValue((object)"PeakCatsPrefix", out object value) && value is string text)
			{
				ColorUtility.TryParseHtmlString("#" + text, ref c);
			}
			return true;
		}

		public static void RecordSummit(int cats)
		{
			if (!((Object)(object)I == (Object)null) && cats > 0)
			{
				cats = Mathf.Clamp(cats, 1, 3);
				if (cats > I.best)
				{
					int num = I.best;
					I.best = cats;
					I.Save();
					I.Publish();
					CatNet.Notice((cats >= 3 && num < 3) ? "You brought 3 cats to the Peak! All 30 cat customizations and the [Warrior] prefix are yours!" : $"Cat customizations unlocked: {CatCosmetics.UnlockedCount(cats)} / 30  (open the cat panel)");
				}
			}
		}

		public static void SetPrefixColor(Color c)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)I == (Object)null))
			{
				I.prefix = c;
				I.Save();
				I.Publish();
			}
		}
	}
	internal class CatAnimator : MonoBehaviour
	{
		private static readonly string[] Names = new string[25]
		{
			"hips", "spine", "chest", "neck", "head", "ear_L", "ear_R", "arm_L", "fore_L", "hand_L",
			"thigh_L", "shin_L", "foot_L", "arm_R", "fore_R", "hand_R", "thigh_R", "shin_R", "foot_R", "tail0",
			"tail1", "tail2", "tail3", "tail4", "tail5"
		};

		private const int Hips = 0;

		private const int Spine = 1;

		private const int Chest = 2;

		private const int Neck = 3;

		private const int Head = 4;

		private const int EarL = 5;

		private const int EarR = 6;

		private const int ArmL = 7;

		private const int ForeL = 8;

		private const int HandL = 9;

		private const int ThighL = 10;

		private const int ShinL = 11;

		private const int FootL = 12;

		private const int ArmR = 13;

		private const int ForeR = 14;

		private const int HandR = 15;

		private const int ThighR = 16;

		private const int ShinR = 17;

		private const int FootR = 18;

		private const int Tail0 = 19;

		private const int N = 25;

		private CatBrain brain;

		private Item item;

		private Rigidbody rig;

		private Transform rigRoot;

		private readonly Transform[] bones = (Transform[])(object)new Transform[25];

		private Vector3 hipsRest;

		private CatMesh.Eye eyeL;

		private CatMesh.Eye eyeR;

		private SkinnedMeshRenderer body;

		private readonly Vector3[] target = (Vector3[])(object)new Vector3[25];

		private readonly Quaternion[] current = (Quaternion[])(object)new Quaternion[25];

		private Vector3 hipsOffset;

		private Vector3 hipsOffsetCur;

		private Quaternion rootRotCur = Quaternion.identity;

		private Vector3 rootPosCur;

		private float gait;

		private float speedSm;

		private float t0;

		private float blink;

		private float blinkTarget;

		private float nextBlink;

		private float blinkHold;

		private float slowBlinkUntil;

		private float happy;

		private float sleepLid;

		private float earTwitchL;

		private float earTwitchR;

		private float nextEarTwitch;

		private Vector3 lookPoint;

		private float nextSaccade;

		private bool hasLookPoint;

		private Vector3 eyeLookPoint;

		private float nextEyeDart;

		private float pupil;

		private float lastVoice;

		private CatSound lastVoiceKind;

		private float updateAccum;

		private CatEmote emote;

		private float emoteStart;

		private float emoteEnd;

		private bool rootSnap;

		public bool Ready => (Object)(object)rigRoot != (Object)null;

		public Transform HeadBone => bones[4];

		private bool EmoteActive
		{
			get
			{
				if (emote != CatEmote.None)
				{
					return Time.time < emoteEnd;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			brain = ((Component)this).GetComponent<CatBrain>();
			item = ((Component)this).GetComponent<Item>();
			rigRoot = ((Component)this).transform.Find("Visual/CatRig");
			if ((Object)(object)rigRoot == (Object)null)
			{
				Plugin.Log.LogError((object)"Cat has no rig!");
				((Behaviour)this).enabled = false;
				return;
			}
			for (int i = 0; i < 25; i++)
			{
				bones[i] = FindDeep(rigRoot, Names[i]);
			}
			hipsRest = bones[0].localPosition;
			for (int j = 0; j < 25; j++)
			{
				current[j] = Quaternion.identity;
			}
			body = ((Component)rigRoot).GetComponentInChildren<SkinnedMeshRenderer>(true);
			eyeL = FindEye(bones[4], "Eye_L");
			eyeR = FindEye(bones[4], "Eye_R");
			t0 = Random.value * 100f;
			nextBlink = Time.time + Random.Range(1f, 4f);
		}

		private void Start()
		{
			rig = item.rig;
		}

		private static Transform FindDeep(Transform t, string n)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if (((Object)t).name == n)
			{
				return t;
			}
			foreach (Transform item in t)
			{
				Transform val = FindDeep(item, n);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static CatMesh.Eye FindEye(Transform head, string name)
		{
			Transform val = head.Find(name);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return new CatMesh.Eye
			{
				ball = val.Find("Ball"),
				pupil = val.Find("Ball/Pupil"),
				lidUpper = val.Find("LidUpper"),
				lidLower = val.Find("LidLower")
			};
		}

		public void OnIdentity()
		{
			Transform val = ((Component)this).transform.Find("Visual/CatRig");
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponentInChildren<SkinnedMeshRenderer>(true) == (Object)null))
			{
				CatMesh.SetCoatOnInstance(val, brain.typeId);
				pupil = brain.Type.PupilSize;
			}
		}

		public void OnVoice(CatSound s)
		{
			lastVoice = Time.time;
			lastVoiceKind = s;
		}

		public void OnPetChanged(bool on)
		{
		}

		public void PlayEmote(CatEmote kind, float seconds)
		{
			emote = kind;
			emoteStart = Time.time;
			emoteEnd = Time.time + seconds;
			if (kind == CatEmote.ThumbsUp || kind == CatEmote.Sassy || kind == CatEmote.Cheer || kind == CatEmote.Wave)
			{
				slowBlinkUntil = Time.time + 1.2f;
			}
		}

		private void LateUpdate()
		{
			//IL_0052: 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)
			if ((Object)(object)rigRoot == (Object)null || (Object)(object)brain == (Object)null)
			{
				return;
			}
			Camera val = (((Object)(object)MainCamera.instance != (Object)null) ? MainCamera.instance.cam : Camera.main);
			float num = (((Object)(object)val != (Object)null) ? Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) : 0f);
			float num2 = ((num > 90f) ? (-1f) : ((num > 35f || ((Object)(object)body != (Object)null && !((Renderer)body).isVisible)) ? 0.1f : 0f));
			if (!(num2 < 0f))
			{
				updateAccum += Time.deltaTime;
				if (!(updateAccum < num2))
				{
					float dt = Mathf.Min(updateAccum, 0.1f);
					updateAccum = 0f;
					Animate(dt);
				}
			}
		}

		private void Animate(float dt)
		{
			//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_0031: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			//IL_0055: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Invalid comparison between Unknown and I4
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			float t = Time.time + t0;
			for (int i = 0; i < 25; i++)
			{
				target[i] = Vector3.zero;
			}
			hipsOffset = Vector3.zero;
			Vector3 rootPos = Vector3.zero;
			Quaternion rootRot = Quaternion.identity;
			Vector3 val = (((Object)(object)rig != (Object)null) ? rig.linearVelocity : Vector3.zero);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(val.x, 0f, val.z);
			float num = (((int)item.itemState == 0 && brain.grounded) ? ((Vector3)(ref val2)).magnitude : 0f);
			speedSm = Mathf.Lerp(speedSm, num, 1f - Mathf.Exp((0f - dt) * 8f));
			bool flag = (int)item.itemState == 1;
			bool sleeping = brain.sleeping;
			bool passedOut = brain.passedOut;
			CatMode mode = brain.mode;
			bool flag2 = EmoteActive && !sleeping && !passedOut && !brain.soul;
			bool flag3 = false;
			if (brain.soul)
			{
				PoseLoaf(t);
			}
			else if (passedOut)
			{
				PosePassedOut(t);
			}
			else if (flag)
			{
				PoseHeld(t, sleeping);
				rootRot = Quaternion.Euler(0f, Plugin.HoldYaw.Value, 0f);
				rootPos = CatPrefabBuilder.HeldVisualOffset * brain.Size;
				if (flag2)
				{
					PawWave(t);
				}
			}
			else if (brain.Perched)
			{
				PosePerch(t, sleeping);
				rootRot = Quaternion.Euler(-42f, 0f, 0f);
				rootPos = new Vector3(0f, -0.02f, 0.06f) * brain.Size;
				if (flag2)
				{
					PawWave(t);
				}
			}
			else if (flag2 && brain.grounded && !brain.climbing && speedSm < 0.35f)
			{
				float et = Time.time - emoteStart;
				flag3 = emote == CatEmote.PlayDead;
				PoseEmote(emote, t, et, ref rootRot, ref rootPos);
			}
			else if (brain.climbing)
			{
				PoseClimb(t);
			}
			else if (!brain.grounded && brain.airTime > 0.15f)
			{
				PoseAir(t);
			}
			else if (sleeping)
			{
				PoseSleep(t);
			}
			else if (brain.windGrip && speedSm < 0.08f && mode != CatMode.Eat)
			{
				PoseSphinx(t);
			}
			else
			{
				switch (mode)
				{
				case CatMode.Sit:
					PoseSit(t);
					break;
				case CatMode.Groom:
					PoseSit(t);
					PoseGroom(t);
					break;
				case CatMode.Stretch:
				case CatMode.Wake:
					PoseStretch(t);
					break;
				case CatMode.Loaf:
					if (brain.seed % 2 == 0)
					{
						PoseSphinx(t);
					}
					else
					{
						PoseLoaf(t);
					}
					break;
				case CatMode.Bat:
					PoseSit(t);
					PoseBat(t);
					break;
				case CatMode.Eat:
					PoseEat(t);
					break;
				case CatMode.Vigil:
					if (speedSm < 0.08f)
					{
						PoseLoaf(t);
					}
					else
					{
						PoseStand(t);
					}
					break;
				default:
					PoseStand(t);
					break;
				}
				if (speedSm > 0.08f)
				{
					PoseGait(t, dt);
				}
			}
			Overlays(t, dt, flag, sleeping || passedOut || flag3);
			Apply(dt, rootRot, rootPos);
			Face(t, dt, flag, sleeping || passedOut || flag3);
		}

		private void Set(int b, float x, float y = 0f, float z = 0f)
		{
			//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)
			target[b] = new Vector3(x, y, z);
		}

		private void Add(int b, float x, float y = 0f, float z = 0f)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			ref Vector3 reference = ref target[b];
			reference += new Vector3(x, y, z);
		}

		private void Legs(int arm, float a, float f, float h, int thigh, float th, float sh, float ft)
		{
			Set(arm, a);
			Set(arm + 1, f);
			Set(arm + 2, h);
			Set(thigh, th);
			Set(thigh + 1, sh);
			Set(thigh + 2, ft);
		}

		private void TailCurve(float basePitch, float segPitch, float baseYaw = 0f, float segYaw = 0f)
		{
			Set(19, basePitch, baseYaw);
			for (int i = 1; i < 6; i++)
			{
				Set(19 + i, segPitch, segYaw);
			}
		}

		private void PawWave(float t)
		{
			Set(13, -135f, 0f, 45f + Mathf.Sin(t * 9f) * 18f);
			Set(14, -20f);
			Set(15, -20f);
		}

		private void PoseBeg()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			PoseSit(0f);
			hipsOffset = new Vector3(0f, -0.07f, -0.04f);
			Set(0, -44f);
			Set(1, -12f);
			Set(2, -6f);
			Set(3, 26f);
			Set(4, 26f);
			Legs(7, -35f, -70f, -20f, 10, -30f, 150f, -75f);
			Legs(13, -35f, -70f, -20f, 16, -30f, 150f, -75f);
		}

		private void PoseEmote(CatEmote e, float t, float et, ref Quaternion rootRot, ref Vector3 rootPos)
		{
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_0639: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0506: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			switch (e)
			{
			case CatEmote.Wave:
				PoseSit(t);
				PawWave(t);
				Set(4, 20f, -8f, 10f);
				break;
			case CatEmote.Salute:
				PoseSit(t);
				Set(13, -150f, 0f, 48f);
				Set(14, -100f);
				Set(15, -30f);
				Set(4, 14f);
				Set(3, 10f);
				break;
			case CatEmote.Dance:
			{
				PoseStand(t);
				float num7 = Mathf.Sin(et * 6.3f);
				Set(0, 0f, 0f, num7 * 10f);
				Set(1, 0f, 0f, (0f - num7) * 6f);
				Set(2, 0f, num7 * 8f, (0f - num7) * 4f);
				Set(4, 4f + Mathf.Sin(et * 12.6f) * 8f, (0f - num7) * 10f, num7 * 8f);
				Legs(7, -35f * Mathf.Max(0f, num7), -30f * Mathf.Max(0f, num7), 0f, 10, 0f, 0f, 0f);
				Legs(13, -35f * Mathf.Max(0f, 0f - num7), -30f * Mathf.Max(0f, 0f - num7), 0f, 16, 0f, 0f, 0f);
				TailCurve(40f, 8f, num7 * 35f, num7 * 10f);
				hipsOffset = new Vector3(0f, Mathf.Abs(num7) * 0.018f, 0f);
				break;
			}
			case CatEmote.BegDance:
			{
				PoseBeg();
				float num6 = Mathf.Sin(et * 5f);
				Set(0, -44f, 0f, num6 * 12f);
				Set(2, -6f, 0f, (0f - num6) * 8f);
				Set(4, 26f, 0f, num6 * 14f);
				Set(7, -35f + num6 * 25f);
				Set(13, -35f - num6 * 25f);
				break;
			}
			case CatEmote.Clap:
			{
				PoseBeg();
				float num5 = (Mathf.Sin(et * 14f) + 1f) * 0.5f;
				Set(7, -100f, 0f, 0f - (8f + num5 * 30f));
				Set(13, -100f, 0f, 8f + num5 * 30f);
				Set(8, -50f);
				Set(14, -50f);
				break;
			}
			case CatEmote.Flex:
				PoseBeg();
				Set(7, -100f, 0f, -50f);
				Set(13, -100f, 0f, 50f);
				Set(8, -120f);
				Set(14, -120f);
				Set(2, -16f);
				Set(4, 18f);
				break;
			case CatEmote.ThumbsUp:
				PoseSit(t);
				Set(13, -85f, 0f, 42f);
				Set(14, -30f);
				Set(15, -40f);
				Set(4, 24f, 0f, 12f);
				break;
			case CatEmote.Backflip:
			{
				float num3 = Mathf.Clamp01(et / 0.8f);
				float num4 = num3 * num3 * (3f - 2f * num3);
				PoseAir(t);
				Legs(7, -80f, -60f, 0f, 10, 70f, 60f, 0f);
				Legs(13, -80f, -60f, 0f, 16, 70f, 60f, 0f);
				if (num3 >= 1f)
				{
					PoseStand(t);
					break;
				}
				Vector3 val = new Vector3(0f, 0.18f, 0f) * brain.Size;
				rootRot = Quaternion.Euler(-360f * num4, 0f, 0f);
				rootSnap = true;
				rootPos = val - rootRot * val + Vector3.up * (4f * num3 * (1f - num3) * 0.32f * brain.Size);
				break;
			}
			case CatEmote.Sit:
				PoseSit(t);
				break;
			case CatEmote.PlayDead:
				PosePassedOut(t);
				break;
			case CatEmote.Panic:
				PoseStand(t);
				TailCurve(85f, 2f);
				Set(4, -8f, Mathf.Sin(et * 14f) * 35f);
				Set(3, -14f);
				Set(5, -40f, 0f, 30f);
				Set(6, -40f, 0f, -30f);
				hipsOffset = new Vector3(0f, Mathf.Abs(Mathf.Sin(et * 12f)) * 0.025f, 0f);
				break;
			case CatEmote.Sad:
				PoseSphinx(t);
				Set(3, 22f);
				Set(4, 28f);
				Set(5, -35f, 0f, 40f);
				Set(6, -35f, 0f, -40f);
				TailCurve(-14f, -1f, 10f, 3f);
				break;
			case CatEmote.Shrug:
				PoseSit(t);
				Set(4, 26f, 0f, 22f);
				Set(7, 20f);
				Set(13, 20f);
				Set(5, 0f, 0f, 25f);
				Set(6, 0f, 0f, 25f);
				break;
			case CatEmote.Think:
				PoseSit(t);
				Set(13, -125f, 0f, 28f);
				Set(14, -105f);
				Set(15, -20f);
				Set(4, 30f, 12f, 14f);
				break;
			case CatEmote.No:
				PoseSit(t);
				Set(4, 24f, Mathf.Sin(et * 9f) * 28f);
				break;
			case CatEmote.Sassy:
				PoseLoaf(t);
				Set(4, 4f, 70f);
				Set(3, -8f, 10f);
				TailCurve(20f, 12f, 40f, 10f);
				break;
			case CatEmote.Punch:
			{
				PoseBeg();
				float num2 = Mathf.Sin(et * 11f);
				Set(7, -90f - Mathf.Max(0f, num2) * 40f, 0f, -20f);
				Set(13, -90f - Mathf.Max(0f, 0f - num2) * 40f, 0f, 20f);
				Set(8, -20f + Mathf.Max(0f, num2) * 20f);
				Set(14, -20f + Mathf.Max(0f, 0f - num2) * 20f);
				break;
			}
			case CatEmote.Cheer:
			{
				PoseBeg();
				float num = Mathf.Sin(et * 10f) * 12f;
				Set(7, -150f, 0f, 0f - (45f + num));
				Set(13, -150f, 0f, 45f + num);
				Set(8, -10f);
				Set(14, -10f);
				Set(4, 10f);
				break;
			}
			default:
				PoseStand(t);
				break;
			}
		}

		private void PoseStand(float t)
		{
			TailCurve(38f, 9f);
			Set(3, -6f);
			Set(4, 4f);
		}

		private void PoseSit(float t)
		{
			//IL_0010: 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)
			hipsOffset = new Vector3(0f, -0.075f, -0.03f);
			Set(0, -30f);
			Set(1, -10f);
			Set(2, -4f);
			Set(3, 18f);
			Set(4, 26f);
			Legs(7, 44f, 0f, 0f, 10, -50f, 138f, -58f);
			Legs(13, 44f, 0f, 0f, 16, -50f, 138f, -58f);
			TailCurve(-10f, -2f, 50f, 24f);
		}

		private void PoseSphinx(float t)
		{
			//IL_0010: 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)
			hipsOffset = new Vector3(0f, -0.098f, 0f);
			Set(3, -8f);
			Set(4, 10f);
			Legs(7, -72f, -12f, 8f, 10, -78f, 118f, -40f);
			Legs(13, -72f, -12f, 8f, 16, -78f, 118f, -40f);
			TailCurve(-12f, -1f, 58f, 22f);
		}

		private void PoseLoaf(float t)
		{
			//IL_0010: 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)
			hipsOffset = new Vector3(0f, -0.1f, 0f);
			Set(3, -2f);
			Set(4, 12f);
			Legs(7, 70f, -140f, 30f, 10, -78f, 118f, -40f);
			Legs(13, 70f, -140f, 30f, 16, -78f, 118f, -40f);
			TailCurve(-10f, 0f, 70f, 28f);
		}

		private void PoseSleep(float t)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			PoseLoaf(t);
			hipsOffset = new Vector3(0f, -0.108f, 0f);
			Set(0, 0f, 0f, 10f);
			Set(1, 0f, 14f, 4f);
			Set(2, 0f, 16f, 4f);
			Set(3, 28f, 34f, -8f);
			Set(4, 26f, 26f, -22f);
			TailCurve(-8f, 0f, 88f, 34f);
		}

		private void PoseStretch(float t)
		{
			//IL_0010: 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)
			hipsOffset = new Vector3(0f, -0.01f, -0.015f);
			Set(1, 14f);
			Set(2, 12f);
			Set(3, -26f);
			Set(4, -30f);
			Legs(7, -66f, -18f, 10f, 10, 6f, 6f, 0f);
			Legs(13, -66f, -18f, 10f, 16, 6f, 6f, 0f);
			TailCurve(62f, 6f);
		}

		private void PoseGroom(float t)
		{
			float num = Mathf.Sin(t * 9f);
			Set(13, -95f, 0f, 8f);
			Set(14, -70f + num * 6f);
			Set(15, -30f);
			Add(3, 18f, -8f);
			Add(4, 22f + num * 7f, -14f, 6f);
		}

		private void PoseBat(float t)
		{
			float num = Mathf.Sin(t * 13f);
			float num2 = Mathf.Max(0f, num) * Mathf.Max(0f, Mathf.Sin(t * 2.3f));
			Set(13, -40f - num2 * 70f, 0f, (0f - num2) * 18f);
			Set(14, -10f - num2 * 40f);
			Add(4, 8f);
		}

		private void PoseEat(float t)
		{
			//IL_0085: 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)
			PoseStand(t);
			float num = Mathf.Sin(t * 10f);
			Set(3, 28f);
			Set(4, 38f + num * 5f);
			Set(7, -8f);
			Set(13, -8f);
			hipsOffset = new Vector3(0f, -0.01f, 0f);
		}

		private void PoseAir(float t)
		{
			Legs(7, -40f, -10f, 0f, 10, 38f, 10f, 0f);
			Legs(13, -40f, -10f, 0f, 16, 38f, 10f, 0f);
			TailCurve(48f, 6f);
			Set(3, -10f);
		}

		private void PoseClimb(float t)
		{
			float num = Mathf.Sin(t * 7f) * Mathf.Clamp01(brain.climbSpeed * 3f);
			Legs(7, -60f + num * 25f, -20f, 10f, 10, 25f - num * 20f, 20f, 0f);
			Legs(13, -60f - num * 25f, -20f, 10f, 16, 25f + num * 20f, 20f, 0f);
			TailCurve(-30f, -4f);
			Set(3, -20f);
			Set(4, -10f);
		}

		private void PosePerch(float t, bool asleep)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			hipsOffset = Vector3.zero;
			Set(0, 0f);
			Set(1, 20f);
			Set(2, 22f);
			Legs(7, -30f, -38f, 20f, 10, 48f, 12f, 8f);
			Legs(13, -24f, -44f, 22f, 16, 42f, 16f, 8f);
			float num = Mathf.Sin(t * 2.1f);
			Set(19, -34f, num * 26f);
			for (int i = 1; i < 6; i++)
			{
				Set(19 + i, -6f, Mathf.Sin(t * 2.1f - (float)i * 0.45f) * 9f);
			}
			if (asleep)
			{
				Set(3, 18f, 10f);
				Set(4, 22f, 14f, -10f);
			}
			else
			{
				Set(3, -14f);
				Set(4, -2f);
			}
		}

		private void PoseHeld(float t, bool asleep)
		{
			//IL_0010: 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)
			hipsOffset = new Vector3(0f, -0.06f, 0f);
			Legs(7, -48f, -28f, 12f, 10, -50f, 70f, -20f);
			Legs(13, -48f, -28f, 12f, 16, -50f, 70f, -20f);
			TailCurve(-55f, -8f, 20f, 4f);
			if (asleep)
			{
				Set(3, 25f, 20f);
				Set(4, 30f, 18f, -15f);
			}
			else
			{
				Set(3, -6f);
				Set(4, 4f);
			}
		}

		private void PosePassedOut(float t)
		{
			//IL_0010: 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)
			hipsOffset = new Vector3(0f, -0.1f, 0f);
			Set(0, 0f, 0f, 78f);
			Legs(7, -25f, -10f, 0f, 10, 15f, 10f, 0f);
			Legs(13, -35f, -10f, 0f, 16, 25f, 10f, 0f);
			Set(3, 10f, 0f, -10f);
			Set(4, 15f, 0f, -20f);
			TailCurve(-10f, -2f, 25f, 6f);
		}

		private void PoseGait(float t, float dt)
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			float num = ((speedSm > 2.2f) ? 0.42f : ((speedSm > 1f) ? 0.3f : 0.2f));
			gait += dt * speedSm / num * MathF.PI;
			float A = ((speedSm > 2.2f) ? 42f : ((speedSm > 1f) ? 32f : 22f));
			float B = ((speedSm > 1f) ? 55f : 40f);
			Leg(7, gait, front: true);
			Leg(16, gait + 0.2f, front: false);
			Leg(13, gait + MathF.PI, front: true);
			Leg(10, gait + MathF.PI + 0.2f, front: false);
			hipsOffset += new Vector3(0f, Mathf.Abs(Mathf.Sin(gait)) * 0.006f, 0f);
			Add(4, Mathf.Sin(gait * 2f) * 2f);
			Add(19, 6f, Mathf.Sin(gait) * 6f);
			void Leg(int upper, float ph, bool front)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: 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_0051: 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_0088: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: 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)
				float num2 = Mathf.Sin(ph);
				float num3 = Mathf.Cos(ph);
				ref Vector3 reference = ref target[upper];
				reference += new Vector3(num2 * A, 0f, 0f);
				ref Vector3 reference2 = ref target[upper + 1];
				reference2 += new Vector3((front ? 1f : 0.8f) * Mathf.Max(0f, num3) * B, 0f, 0f);
				ref Vector3 reference3 = ref target[upper + 2];
				reference3 += new Vector3((0f - Mathf.Max(0f, num3)) * B * 0.4f, 0f, 0f);
			}
		}

		private void Overlays(float t, float dt, bool held, bool eyesShut)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			float num = (eyesShut ? Mathf.Sin(t * 1.6f) : Mathf.Sin(t * 3.4f));
			Add(1, num * 1.2f);
			Add(2, (0f - num) * 1.6f);
			hipsOffset += new Vector3(0f, num * (eyesShut ? 0.0025f : 0.0012f), 0f);
			float num2 = (brain.sleeping ? 2.5f : ((brain.mode == CatMode.Bat) ? 22f : (brain.petting ? 12f : 9f)));
			float num3 = ((brain.mode == CatMode.Bat) ? 5f : 1.6f);
			for (int i = 0; i < 6; i++)
			{
				Add(19 + i, 0f, Mathf.Sin(t * num3 - (float)i * 0.65f) * num2 * (0.4f + (float)i * 0.14f));
			}
			if (brain.sleeping)
			{
				Add(24, 0f, Mathf.Pow(Mathf.Max(0f, Mathf.Sin(t * 0.7f)), 20f) * 30f);
			}
			if (Time.time > nextEarTwitch)
			{
				nextEarTwitch = Time.time + Random.Range(1.5f, 6f);
				if (Random.value < 0.5f)
				{
					earTwitchL = 1f;
				}
				else
				{
					earTwitchR = 1f;
				}
			}
			earTwitchL = Mathf.MoveTowards(earTwitchL, 0f, dt * 6f);
			earTwitchR = Mathf.MoveTowards(earTwitchR, 0f, dt * 6f);
			float num4 = (brain.petting ? 18f : ((!brain.grounded && !held && brain.airTime > 0.2f) ? 45f : 0f));
			Add(5, num4 + earTwitchL * 20f, 0f, earTwitchL * 18f);
			Add(6, num4 + earTwitchR * 20f, 0f, (0f - earTwitchR) * 18f);
			if (brain.petting && !brain.sleeping)
			{
				float num5 = Mathf.Sin(t * 7f);
				Add(7, num5 * 14f);
				Add(13, (0f - num5) * 14f);
				Add(8, Mathf.Max(0f, num5) * 18f);
				Add(14, Mathf.Max(0f, 0f - num5) * 18f);
				Add(4, -8f, 0f, Mathf.Sin(t * 2.5f) * 10f);
			}
			if (!eyesShut && brain.mode != CatMode.Groom && brain.mode != CatMode.Eat)
			{
				UpdateLookPoint(held);
				if (hasLookPoint)
				{
					Vector3 val = rigRoot.InverseTransformDirection(lookPoint - bones[4].position);
					float num6 = Mathf.Clamp(Mathf.Atan2(val.x, val.z) * 57.29578f, -70f, 70f);
					float y = val.y;
					Vector2 val2 = new Vector2(val.x, val.z);
					float num7 = Mathf.Clamp((0f - Mathf.Atan2(y, ((Vector2)(ref val2)).magnitude)) * 57.29578f, -40f, 35f);
					Add(3, num7 * 0.35f, num6 * 0.4f);
					Add(4, num7 * 0.55f, num6 * 0.6f, (0f - num6) * 0.12f);
				}
			}
			float num8 = Time.time - lastVoice;
			if (num8 < 0.6f && !brain.sleeping)
			{
				Add(4, -12f * Mathf.Sin(num8 / 0.6f * MathF.PI));
			}
		}

		private void UpdateLookPoint(bool held)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			Character lookCharacter = brain.LookCharacter;
			if ((Object)(object)lookCharacter != (Object)null)
			{
				lookPoint = lookCharacter.Head;
				hasLookPoint = true;
			}
			else if (held && (Object)(object)item.holderCharacter != (Object)null && item.holderCharacter.IsLocal && (Object)(object)MainCamera.instance != (Object)null && Time.time % 9f < 5f)
			{
				lookPoint = ((Component)MainCamera.instance.cam).transform.position;
				hasLookPoint = true;
			}
			else if (Time.time > nextSaccade)
			{
				nextSaccade = Time.time + Random.Range(1.2f, 4f);
				Vector3 forward = rigRoot.forward;
				lookPoint = bones[4].position + Quaternion.Euler(Random.Range(-25f, 15f), Random.Range(-60f, 60f), 0f) * forward * 3f;
				hasLookPoint = true;
			}
		}

		private void Apply(float dt, Quaternion rootRot, Vector3 rootPos)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_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)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			float num = 1f - Mathf.Exp((0f - dt) * 10f);
			for (int i = 0; i < 25; i++)
			{
				if (!((Object)(object)bones[i] == (Object)null))
				{
					current[i] = Quaternion.Slerp(current[i], Quaternion.Euler(target[i]), num);
					bones[i].localRotation = current[i];
				}
			}
			hipsOffsetCur = Vector3.Lerp(hipsOffsetCur, hipsOffset, num);
			bones[0].localPosition = hipsRest + hipsOffsetCur;
			float num2 = (rootSnap ? 1f : (1f - Mathf.Exp((0f - dt) * 8f)));
			rootSnap = false;
			rootRotCur = Quaternion.Slerp(rootRotCur, rootRot, num2);
			rootPosCur = Vector3.Lerp(rootPosCur, rootPos, num2);
			rigRoot.localRotation = rootRotCur;
			rigRoot.localPosition = rootPosCur;
			rigRoot.localScale = Vector3.one * brain.Size;
			bones[4].localScale = Vector3.one * Mathf.Lerp(1.1f, 1f, brain.age);
		}

		private void Face(float t, float dt, bool held, bool eyesShut)
		{
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			if (eyeL == null || eyeR == null)
			{
				return;
			}
			if (Time.time > nextBlink)
			{
				nextBlink = Time.time + Random.Range(2f, 6f);
				blinkHold = 0.08f;
				if ((Object)(object)brain.LookCharacter != (Object)null && Random.value < 0.35f)
				{
					slowBlinkUntil = Time.time + 1.4f;
					blinkHold = 0.9f;
				}
			}
			bool flag = Time.time < slowBlinkUntil;
			blinkHold -= dt;
			blinkTarget = ((!(blinkHold > 0f)) ? 0f : (flag ? 0.8f : 1f));
			blink = Mathf.MoveTowards(blink, blinkTarget, dt * (flag ? 2.5f : 14f));
			float num = ((brain.petting && !eyesShut) ? 1f : 0f);
			happy = Mathf.MoveTowards(happy, num, dt * 4f);
			sleepLid = Mathf.MoveTowards(sleepLid, eyesShut ? 1f : 0f, dt * 1.5f);
			float num2 = Mathf.Max(blink, sleepLid);
			float upper = Mathf.Lerp(-75f, 90f, Mathf.Max(num2, happy * 0.72f));
			float lower = Mathf.Lerp(-75f, 52f, happy * (1f - sleepLid));
			float num3 = brain.Type.PupilSize;
			if (brain.mode == CatMode.Bat || brain.mode == CatMode.Air || brain.mode == CatMode.Follow)
			{
				num3 += 0.18f;
			}
			if ((Object)(object)DayNightManager.instance != (Object)null && DayNightManager.instance.isDay < 0.5f)
			{
				num3 += 0.15f;
			}
			if (brain.petting)
			{
				num3 -= 0.08f;
			}
			pupil = Mathf.Lerp(pupil, Mathf.Clamp(num3, 0.3f, 0.9f), 1f - Mathf.Exp((0f - dt) * 3f));
			if (Time.time > nextEyeDart)
			{
				nextEyeDart = Time.time + Random.Range(0.25f, 1.2f);
				eyeLookPoint = (hasLookPoint ? (lookPoint + Random.insideUnitSphere * 0.25f) : (bones[4].position + bones[4].forward * 2f));
			}
			bool hide = num2 > 0.8f;
			ApplyEye(eyeL, upper, lower, hide, eyesShut, dt);
			ApplyEye(eyeR, upper, lower, hide, eyesShut, dt);
		}

		private void ApplyEye(CatMesh.Eye e, float upper, float lower, bool hide, bool eyesShut, float dt)
		{
			//IL_0023: 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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			if (e == null)
			{
				return;
			}
			if ((Object)(object)e.lidUpper != (Object)null)
			{
				e.lidUpper.localRotation = Quaternion.Euler(upper, 0f, 0f);
			}
			if ((Object)(object)e.lidLower != (Object)null)
			{
				e.lidLower.localRotation = Quaternion.Euler(0f, 0f, 180f) * Quaternion.Euler(lower, 0f, 0f);
			}
			if ((Object)(object)e.pupil != (Object)null)
			{
				e.pupil.localScale = new Vector3(pupil, Mathf.Lerp(0.72f, 0.85f, pupil), 1f);
			}
			if (e.renderers != null)
			{
				Renderer[] renderers = e.renderers;
				foreach (Renderer val in renderers)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					switch (((Object)val).name)
					{
					case "Ball":
					case "Pupil":
					case "Shine":
					case "Shine2":
						if (val.enabled == hide)
						{
							val.enabled = !hide;
						}
						break;
					}
				}
			}
			if (!((Object)(object)e.ball == (Object)null))
			{
				if (hide)
				{
					e.ball.localRotation = Quaternion.identity;
				}
				else if (!eyesShut)
				{
					Vector3 val2 = e.ball.parent.InverseTransformPoint(eyeLookPoint);
					Quaternion val3 = Quaternion.LookRotation((((Vector3)(ref val2)).sqrMagnitude > 1E-06f) ? val2 : Vector3.forward);
					val3 = Quaternion.RotateTowards(Quaternion.identity, val3, 28f);
					e.ball.localRotation = Quaternion.Slerp(e.ball.localRotation, val3, 1f - Mathf.Exp((0f - dt) * 18f));
				}
			}
		}
	}
	internal class CatAudio : MonoBehaviour
	{
		private static readonly Dictionary<string, List<AudioClip>> s_clips = new Dictionary<string, List<AudioClip>>();

		private AudioSource voice;

		private AudioSource purr;

		private CatBrain brain;

		private float purrVol;

		private float nextFireCheck;

		private bool nearFire;

		public static void LoadAll(string pluginDir)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(pluginDir, "sounds");
			if (!Directory.Exists(text))
			{
				Plugin.Log.LogWarning((object)("No sounds folder at " + text));
				return;
			}
			int num = 0;
			string[] files = Directory.GetFiles(text);
			foreach (string path in files)
			{
				string text2 = Path.GetExtension(path).ToLowerInvariant();
				AudioType val = (AudioType)((text2 == ".ogg") ? 14 : ((text2 == ".wav") ? 20 : 0));
				if ((int)val == 0)
				{
					continue;
				}
				AudioClip val2 = LoadClip(path, val);
				if (!((Object)(object)val2 == (Object)null))
				{
					string key = Path.GetFileNameWithoutExtension(path).Split('_')[0];
					if (!s_clips.TryGetValue(key, out var value))
					{
						value = (s_clips[key] = new List<AudioClip>());
					}
					value.Add(val2);
					num++;
				}
			}
			Plugin.Log.LogInfo((object)string.Format("Loaded {0} cat sounds ({1}).", num, string.Join(", ", s_clips.Keys)));
		}

		private static AudioClip LoadClip(string path, AudioType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)type != 20)
			{
				Plugin.Log.LogWarning((object)("Only .wav is supported: " + path));
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(path);
				int num = 1;
				int num2 = 44100;
				int num3 = 16;
				int num4 = -1;
				int num5 = 0;
				int num6;
				for (int i = 12; i + 8 <= array.Length; i += 8 + num6 + (num6 & 1))
				{
					string text = Encoding.ASCII.GetString(array, i, 4);
					num6 = BitConverter.ToInt32(array, i + 4);
					if (text == "fmt ")
					{
						num = BitConverter.ToInt16(array, i + 10);
						num2 = BitConverter.ToInt32(array, i + 12);
						num3 = BitConverter.ToInt16(array, i + 22);
					}
					else if (text == "data")
					{
						num4 = i + 8;
						num5 = Math.Min(num6, array.Length - num4);
						break;
					}
				}
				if (num4 < 0 || num3 != 16)
				{
					Plugin.Log.LogWarning((object)("Unsupported wav " + path));
					return null;
				}
				int num7 = num5 / 2;
				float[] array2 = new float[num7];
				for (int j = 0; j < num7; j++)
				{
					array2[j] = (float)BitConverter.ToInt16(array, num4 + j * 2) / 32768f;
				}
				AudioClip obj = AudioClip.Create(Path.GetFileNameWithoutExtension(path), num7 / num, num, num2, false);
				obj.SetData(array2, 0);
				return obj;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Couldn't load " + path + ": " + ex.Message));
				return null;
			}
		}

		private static AudioClip Pick(string kind, byte variant)
		{
			if (!s_clips.TryGetValue(kind, out var value) || value.Count == 0)
			{
				return null;
			}
			return value[variant % value.Count];
		}

		private void Awake()
		{
			brain = ((Component)this).GetComponent<CatBrain>();
			voice = MakeSource(loop: false);
			purr = MakeSource(loop: true);
		}

		private AudioSource MakeSource(bool loop)
		{
			AudioSource val = ((Component)this).gameObject.AddComponent<AudioSource>();
			val.playOnAwake = false;
			val.loop = loop;
			val.spatialBlend = 1f;
			val.rolloffMode = (AudioRolloffMode)0;
			val.minDistance = (loop ? 0.6f : 1.5f);
			val.maxDistance = (loop ? 8f : 30f);
			val.dopplerLevel = 0f;
			if ((Object)(object)SFX_Player.instance != (Object)null)
			{
				val.outputAudioMixerGroup = SFX_Player.instance.defaultMixerGroup;
			}
			return val;
		}

		public void PlayVoice(CatSound s, byte variant)
		{
			if (!((Object)(object)voice == (Object)null))
			{
				if ((Object)(object)voice.outputAudioMixerGroup == (Object)null && (Object)(object)SFX_Player.instance != (Object)null)
				{
					voice.outputAudioMixerGroup = SFX_Player.instance.defaultMixerGroup;
					purr.outputAudioMixerGroup = SFX_Player.instance.defaultMixerGroup;
				}
				float num = 1f;
				float num2 = 1f;
				string kind;
				switch (s)
				{
				case CatSound.Chirp:
					kind = "chirp";
					break;
				case CatSound.Trill:
					kind = "chirp";
					num2 = 1.08f;
					break;
				case CatSound.SleepyMrrp:
					kind = "sleepy";
					num = 0.55f;
					break;
				case CatSound.Yawn:
					kind = "yawn";
					break;
				case CatSound.Surprised:
					kind = "surprised";
					num = 1.1f;
					break;
				case CatSound.LeftBehind:
					kind = "meow";
					num = 1.3f;
					num2 = 1.05f;
					break;
				case CatSound.Hungry:
					kind = "meow";
					num2 = 0.95f;
					break;
				default:
					kind = "meow";
					break;
				}
				AudioClip val = Pick(kind, variant) ?? Pick("meow", variant);
				if (!((Object)(object)val == (Object)null))
				{
					float num3 = (((Object)(object)brain != (Object)null) ? (brain.Type.Pitch * Mathf.Lerp(1.22f, 1f, brain.age)) : 1f);
					voice.pitch = num2 * num3 * (0.95f + (float)(variant % 11) * 0.01f);
					voice.PlayOneShot(val, Mathf.Clamp01(num * Plugin.Volume.Value));
				}
			}
		}

		private void Update()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Invalid comparison between Unknown and I4
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)brain == (Object)null || (Object)(object)purr == (Object)null)
			{
				return;
			}
			if (Time.time > nextFireCheck)
			{
				nextFireCheck = Time.time + 2f;
				nearFire = brain.sleeping && (int)((ItemComponent)brain).item.itemState == 0 && (Object)(object)CatBrain.NearestLitFire(((Component)this).transform.position, 3f) != (Object)null;
			}
			float num = (brain.petting ? 0.9f : ((brain.sleeping && (int)((ItemComponent)brain).item.itemState == 1) ? 0.35f : (nearFire ? 0.25f : 0f)));
			purrVol = Mathf.MoveTowards(purrVol, num, Time.deltaTime * 0.8f);
			if (purrVol > 0.001f)
			{
				if (!purr.isPlaying)
				{
					purr.clip = Pick("purr", (byte)Random.Range(0, 255));
					if ((Object)(object)purr.clip == (Object)null)
					{
						return;
					}
					purr.time = Random.Range(0f, Mathf.Max(0f, purr.clip.length - 1f));
					purr.Play();
				}
				purr.volume = purrVol * Plugin.Volume.Value;
			}
			else if (purr.isPlaying)
			{
				purr.Stop();
			}
		}
	}
	internal static class CatHazards
	{
		private static Lava[] s_lava = (Lava[])(object)new Lava[0];

		private static WaterZone[] s_water = (WaterZone[])(object)new WaterZone[0];

		private static WindChillZone[] s_wind = (WindChillZone[])(object)new WindChillZone[0];

		private static float s_scan;

		public static IEnumerable<Lava> Lavas
		{
			get
			{
				Scan();
				return s_lava;
			}
		}

		private static void Scan()
		{
			if (!(Time.time < s_scan))
			{
				s_scan = Time.time + 10f;
				s_lava = Object.FindObjectsByType<Lava>((FindObjectsSortMode)0);
				s_water = Object.FindObjectsByType<WaterZone>((FindObjectsSortMode)0);
				s_wind = Object.FindObjectsByType<WindChillZone>((FindObjectsSortMode)0);
			}
		}

		public static bool InWater(Vector3 p)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Scan();
			WaterZone[] array = s_water;
			foreach (WaterZone val in array)
			{
				if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled && ((Bounds)(ref val.zoneBounds)).Contains(p))
				{
					return true;
				}
			}
			return false;
		}

		public static bool Wind(Vector3 p, out Vector3 itemAccel)
		{
			//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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_009d: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			Scan();
			itemAccel = Vector3.zero;
			bool result = false;
			WindChillZone[] array = s_wind;
			foreach (WindChillZone val in array)
			{
				if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled && ((Bounds)(ref val.windZoneBounds)).Contains(p))
				{
					if (val.windActive)
					{
						result = true;
					}
					if (val.windMovesItems)
					{
						float num = (val.useIntensityCurve ? (Mathf.Clamp01(val.windIntensity - 0.5f) * 2f) : 1f);
						itemAccel += val.currentWindDirection * val.windForce * val.windItemFactor * num;
					}
				}
			}
			return result;
		}

		public static bool LavaRisingBelow(Vector3 p, float range)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			foreach (LavaRising item in LavaRising.ALL_LAVA)
			{
				if (!((Object)(object)item == (Object)null) && item.started && !item.ended && !((Object)(object)item.lava == (Object)null))
				{
					float num = p.y - item.lava.position.y;
					if (num > -2f && num < range)
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	internal class CatBrain : ItemComponent
	{
		private enum Block
		{
			None,
			Wall,
			Ledge,
			Cliff,
			Steep,
			Water
		}

		public bool inWater;

		public bool windGrip;

		private float envSpeedMul = 1f;

		private float lastLavaHit;

		private float hazardScan;

		private float lavaFleeCooldown;

		private Vector3 windCounter;

		public static readonly List<CatBrain> All = new List<CatBrain>();

		public CatMode mode;

		public byte seed;

		public bool sleeping;

		public bool petting;

		public bool climbing;

		public int lookViewId = -1;

		public float energy = 1f;

		public float age = 1f;

		public int typeId = -1;

		public string catName = "";

		public int ownerActor = -1;

		public int carriedWeight;

		public int collar;

		private float modeUntil;

		private float thinkTimer;

		private float nextVoice;

		private float heldStill;

		private float stuckTime;

		private float sleptAt;

		private Character followTarget;

		private float lastLeftBehindMeow;

		private Item foodTarget;

		private float nextFoodScan;

		private float saveTimer;

		private Rigidbody rig;

		public Vector3 moveDir;

		public float moveSpeed;

		public Vector3 faceDir;

		public bool grounded = true;

		public float airTime;

		public float climbSpeed;

		private Vector3 wallNormal;

		private float climbStart;

		private Vector3 lastSafePos;

		private float lastSafeTime;

		private BoxCollider box;

		private static readonly RaycastHit[] s_hits = (RaycastHit[])(object)new RaycastHit[8];

		private static int s_groundMask;

		public CatAnimator anim;

		public CatAudio audio;

		public CatVitals vitals;

		public float lastModeChange;

		private int[] appliedCos;

		private int[] appliedMarks;

		private int appliedCollar = -1;

		private bool dataLoaded;

		private int highlightDirtyFrame = -1;

		private float nextRebindCheck;

		private float sizedAge = -1f;

		[PunRPC]
		public float emoteUntil;

		public CatEmote emote;

		public bool fireNap;

		private Vector3 fireSpot;

		private Vector3 firePos;

		private float nextFireCheck;

		private float fireNapCooldown;

		private static Campfire[] s_fires = (Campfire[])(object)new Campfire[0];

		private static float s_fireScan;

		private readonly Dictionary<Item, float> foodIgnoredUntil = new Dictionary<Item, float>();

		public bool nearLava;

		private float lastLedgeHeight;

		private Vector3 lastHopPos;

		private float lastHopTime;

		private int hopFails;

		private float followBest = float.MaxValue;

		private float followBestTime;

		private ClimbTrail viaTrail;

		private float waterWaitUntil;

		private float climbProgressBest = float.MaxValue;

		private float climbProgressTime;

		private float climbCooldown;

		private float lostWall;

		private float pulledUntil;

		private Vector3 groundNormal = Vector3.up;

		private float nearCheckTime;

		private bool nearCached = true;

		private bool ownerWasDown;

		private Vector3 vigilPos;

		private float reunitedUntil;

		private float morningUntil;

		private bool wasNight;

		public int perchActor = -1;

		private bool perchPhysics;

		private Vector3 perchFwd;

		private float leftBehindFor;

		private bool frozenForRescue;

		public bool soul;

		private Vector3 deathPos;

		private Vector3 soulFrom;

		private Vector3 soulSeat;

		private float soulStart;

		private bool soulHasSeat;

		private GameObject skeleton;

		private Light soulLight;

		private readonly Dictionary<Renderer, (Material[] mats, ShadowCastingMode shadows)> soulSaved = new Dictionary<Renderer, (Material[], ShadowCastingMode)>();

		private const float SoulSpeed = 3f;

		private static readonly Dictionary<RespawnChest, Bounds> s_statueBounds = new Dictionary<RespawnChest, Bounds>();

		private static RespawnChest s_statue;

		private static float s_statueCheck;

		private static Material s_ghostMat;

		private static Material s_boneMat;

		private static Material s_socketMat;

		private ClimbTrail trail;

		private int trailIdx;

		private float trailStuck;

		private float trailEndWait;

		public float Size => Mathf.Lerp(1f, 1.3f, age);

		public bool IsKitten => age < 0.999f;

		public bool passedOut
		{
			get
			{
				if ((Object)(object)vitals != (Object)null)
				{
					return vitals.passedOut;
				}
				return false;
			}
		}

		public CatType Type => CatTypes.Get((typeId >= 0) ? typeId : 0);

		public Vector3 HeadPosition
		{
			get
			{
				//IL_0034: 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)
				//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)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)anim != (Object)null) || !anim.Ready || !((Object)(object)anim.HeadBone != (Object)null))
				{
					return ((Component)this).transform.position + ((Component)this).transform.up * 0.3f;
				}
				return anim.HeadBone.position;
			}
		}

		public string DisplayName
		{
			get
			{
				if (!string.IsNullOrEmpty(catName))
				{
					return catName;
				}
				return Type.Name;
			}
		}

		public Character LookCharacter
		{
			get
			{
				if (lookViewId < 0)
				{
					return null;
				}
				PhotonView val = PhotonView.Find(lookViewId);
				if (!((Object)(object)val != (Object)null))
				{
					return null;
				}
				return ((Component)val).GetComponent<Character>();
			}
		}

		public bool Emoting => Time.time < emoteUntil;

		private static float IsDayValue
		{
			get
			{
				if (!((Object)(object)DayNightManager.instance != (Object)null))
				{
					return 1f;
				}
				return DayNightManager.instance.isDay;
			}
		}

		public static bool IsNight => IsDayValue < 0.45f;

		private bool IsMorning => Time.time < morningUntil;

		private static float NightDrain
		{
			get
			{
				if (!IsNight)
				{
					return 0.45f;
				}
				return 2.4f;
			}
		}

		private float LeftBehindDistance
		{
			get
			{
				if (!(Time.time < reunitedUntil))
				{
					return 70f;
				}
				return 25f;
			}
		}

		public bool Perched
		{
			get
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Invalid comparison between Unknown and I4
				if (perchActor >= 0 && (Object)(object)base.item != (Object)null)
				{
					return (int)base.item.itemState == 0;
				}
				return false;
			}
		}

		public int PerchWeight => 2 + Mathf.RoundToInt(age) + carriedWeight;

		public Character Rider => CharacterByActor(perchActor);

		public bool onTrail
		{
			get
			{
				if (trail != null)
				{
					return climbing;
				}
				return false;
			}
		}

		private bool ThinkHazards(float dt)
		{
			//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_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_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)this).transform.position + Vector3.up * 0.15f;
			envSpeedMul = 1f;
			nearLava = false;
			foreach (Lava lava in CatHazards.Lavas)
			{
				if ((Object)(object)lava == (Object)null || !((Behaviour)lava).isActiveAndEnabled || lava.OutsideBounds(val))
				{
					continue;
				}
				float num = val.y - ((Component)lava).transform.position.y;
				if (num < 0.35f)
				{
					LavaBurn();
					return true;
				}
				if (!(num < 5f))
				{
					continue;
				}
				nearLava = true;
				if (sleeping)
				{
					WakeUp(CatSound.Surprised);
				}
				fireNap = false;
				if (num < 1.5f && Time.time > lavaFleeCooldown && !passedOut && mode != CatMode.Trot && mode != CatMode.Air && mode != CatMode.Follow && mode != CatMode.Climb && mode != CatMode.Vigil && grounded)
				{
					Vector3 val2 = ((Component)this).transform.position - ((Bounds)(ref lava.bounds)).center;
					val2.y = 0f;
					if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
					{
						val2 = ((Component)this).transform.position - ((Component)lava).transform.position;
					}
					val2.y = 0f;
					moveDir = ((((Vector3)(ref val2)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val2)).normalized : (-((Component)this).transform.forward));
					SetMode(CatMode.Trot, 2f);
					lavaFleeCooldown = Time.time + 6f;
				}
			}
			if (CatHazards.LavaRisingBelow(((Component)this).transform.position, 25f))
			{
				nearLava = true;
				envSpeedMul = 1.35f;
				if (sleeping)
				{
					WakeUp(CatSound.Surprised);
				}
				fireNap = false;
			}
			bool flag = CatHazards.InWater(val);
			if (flag != inWater)
			{
				inWater = flag;
				if (flag)
				{
					Voice(CatSound.Surprised);
					if (sleeping)
					{
						WakeUp(null);
					}
					fireNap = false;
				}
				else if (grounded && !passedOut)
				{
					SetMode(CatMode.Groom, 3.5f);
					vitals.Add((STATUSTYPE)2, 0.04f);
					Voice(CatSound.Meow);
				}
			}
			if (inWater)
			{
				envSpeedMul *= 0.7f;
				if (!passedOut && mode != CatMode.Trot && mode != CatMode.Follow && mode != CatMode.Vigil && mode != CatMode.Climb && grounded)
				{
					Vector3 val3 = lastSafePos - ((Component)this).transform.position;
					val3.y = 0f;
					if (((Vector3)(ref val3)).sqrMagnitude > 0.25f)
					{
						moveDir = ((Vector3)(ref val3)).normalized;
						SetMode(CatMode.Trot, 2f);
					}
				}
			}
			windGrip = CatHazards.Wind(val, out var itemAccel);
			windCounter = -itemAccel * 0.9f;
			if (windGrip)
			{
				envSpeedMul *= 0.65f;
			}
			return false;
		}

		private void LavaBurn()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			if (!(Time.time - lastLavaHit < 1f))
			{
				lastLavaHit = Time.time;
				vitals.Add((STATUSTYPE)8, 0.25f);
				vitals.Add((STATUSTYPE)0, 0.25f);
				Voice(CatSound.Surprised);
				StopClimbing();
				if (sleeping)
				{
					sleeping = false;
					SaveState();
				}
				Character val = OwnerCharacter();
				Vector3 val2 = (((Object)(object)val != (Object)null && !val.data.dead) ? val.Center : lastSafePos) - ((Component)this).transform.position;
				val2.y = 0f;
				rig.linearVelocity = ((((Vector3)(ref val2)).sqrMagnitude > 0.01f) ? (((Vector3)(ref val2)).normalized * Mathf.Min(6f, ((Vector3)(ref val2)).magnitude)) : Vector3.zero) + Vector3.up * 11f;
				base.item.ForceSyncForFrames(10);
				SetMode(CatMode.Air, 3f);
				Plugin.D("Cat '" + DisplayName + "' touched lava - leaps out");
			}
		}

		private void UpdateWindPose()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!((MonoBehaviourPun)this).photonView.IsMine && !(Time.time < hazardScan))
			{
				hazardScan = Time.time + 0.5f;
				windGrip = (int)base.item.itemState == 0 && CatHazards.Wind(((Component)this).transform.position + Vector3.up * 0.15f, out var _);
			}
		}

		public override void Awake()
		{
			((ItemComponent)this).Awake();
			anim = ((Component)this).GetComponent<CatAnimator>();
			audio = ((Component)this).GetComponent<CatAudio>();
			vitals = ((Component)this).GetComponent<CatVitals>();
			box = ((Component)this).GetComponent<BoxCollider>();
			if (s_groundMask == 0)
			{
				s_groundMask = LayerMask.GetMask(new string[3] { "Terrain", "Map", "Default" });
			}
			Item item = base.item;
			item.OnStateChange = (Action<ItemState>)Delegate.Combine(item.OnStateChange, new Action<ItemState>(OnItemStateChanged));
		}

		public override void OnEnable()
		{
			((MonoBehaviourPunCallbacks)this).OnEnable();
			All.Add(this);
		}

		public override void OnDisable()
		{
			((MonoBehaviourPunCallbacks)this).OnDisable();
			All.Remove(this);
		}

		private void Start()
		{
			//IL_0026: 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)
			//IL_004c: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
			rig = base.item.rig;
			rig.centerOfMass = new Vector3(0f, 0.1f, 0f);
			rig.maxAngularVelocity = 12f;
			lastSafePos = ((Component)this).transform.position;
			OnItemStateChanged(base.item.itemState);
			if (base.item.data != null && CatData.IsCat(base.item.data))
			{
				((ItemComponent)this).OnInstanceDataSet();
			}
			else if (typeId < 0)
			{
				ApplyIdentity(0, "", -1);
			}
			Item item = base.item;
			item.OnPrimaryFinishedCast = (Action)Delegate.Combine(item.OnPrimaryFinishedCast, new Action(OnPetCastFinished));
			Item item2 = base.item;
			item2.OnPrimaryCancelled = (Action)Delegate.Combine(item2.OnPrimaryCancelled, new Action(OnPetCancelled));
			Item item3 = base.item;
			item3.OnSecondaryFinishedCast = (Action)Delegate.Combine(item3.OnSecondaryFinishedCast, new Action(OnTakeBackFinished));
			thinkTimer = Random.value * 0.25f;
			nextVoice = Time.time + Random.Range(4f, 12f);
			if (((MonoBehaviourPun)this).photonView.IsMine && base.item.lastThrownTime > 0f && Time.time - base.item.lastThrownTime < 1f && base.item.lastThrownAmount > 0.1f)
			{
				WakeUp(CatSound.Surprised);
			}
			Plugin.D($"Cat {((MonoBehaviourPun)this).photonView.ViewID} start state={base.item.itemState} mine={((MonoBehaviourPun)this).photonView.IsMine}");
		}

		private void OnDestroy()
		{
			OnDestroySoul();
			if (!((Object)(object)base.item == (Object)null))
			{
				Item item = base.item;
				item.OnPrimaryFinishedCast = (Action)Delegate.Remove(item.OnPrimaryFinishedCast, new Action(OnPetCastFinished));
				Item item2 = base.item;
				item2.OnPrimaryCancelled = (Action)Delegate.Remove(item2.OnPrimaryCancelled, new Action(OnPetCancelled));
				Item item3 = base.item;
				item3.OnSecondaryFinishedCast = (Action)Delegate.Remove(item3.OnSecondaryFinishedCast, new Action(OnTakeBackFinished));
				Item item4 = base.item;
				item4.OnStateChange = (Action<ItemState>)Delegate.Remove(item4.OnStateChange, new Action<ItemState>(OnItemStateChanged));
			}
		}

		public override void OnInstanceDataSet()
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			ItemInstanceData data = base.item.data;
			if (!CatData.IsCat(data))
			{
				return;
			}
			ApplyIdentity(CatData.Type(data), CatData.Name(data) ?? "", CatData.Owner(data));
			int num = CatData.Collar(data);
			if (num != collar)
			{
				collar = num;
				Transform val = ((Component)this).transform.Find("Visual/CatRig");
				if ((Object)(object)val != (Object)null)
				{
					CatCollars.Apply(val, num);
				}
			}
			if (!((MonoBehaviourPun)this).photonView.IsMine || !dataLoaded)
			{
				energy = CatData.Energy(data);
				SetAgeLocal(CatData.Age(data));
				if ((Object)(object)vitals != (Object)null)
				{
					vitals.LoadFrom(data);
				}
				bool flag = CatData.Sleeping(data);
				if (flag != sleeping)
				{
					sleeping = flag;
					if (flag)
					{
						sleptAt = Time.time;
					}
				}
				if (sleeping && (int)base.item.itemState == 0)
				{
					mode = CatMode.Sleep;
				}
			}
			else
			{
				SaveState();
			}
			dataLoaded = true;
			KeepSlotDataInSync();
			((Component)this).GetComponent<CatCarry>()?.Refresh();
			highlightDirtyFrame = Time.frameCount;
			int[] array = CatData.Cosmetics(data);
			int[] array2 = CatData.Markings(data);
			if (appliedCos == null || !array.SequenceEqual(appliedCos) || num != appliedCollar)
			{
				appliedCos = array;
				appliedMarks = array2;
				appliedCollar = num;
				CatCosmetics.Apply(this, array, array2);
			}
			else if (appliedMarks == null || !array2.SequenceEqual(appliedMarks))
			{
				appliedMarks = array2;
				if (!soul)
				{
					CatMarkings.Apply(((Component)this).transform.Find("Visual/CatRig"), array2);
				}
			}
			ApplyPerch(CatData.Perch(data));
			ApplySoul(CatData.Soul(data), CatData.DeathPos(data));
			Plugin.D($"Cat {((MonoBehaviourPun)this).photonView.ViewID} data: type={typeId} name='{catName}' sleeping={sleeping} owner={ownerActor}");
		}

		private void ApplyIdentity(int type, string name, int owner)
		{
			bool num = type != typeId;
			if (num)
			{
				appliedCos = null;
			}
			typeId = type;
			catName = name;
			ownerActor = owner;
			if (num && (Object)(object)anim != (Object)null)
			{
				anim.OnIdentity();
			}
		}

		public void SaveNow()
		{
			SaveState();
		}

		public void KeepSlotDataInSync()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_006a: 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)
			Character val = (((int)base.item.itemState == 1) ? ((ItemComponent)this).holderCharacter : null);
			if ((Object)(object)val == (Object)null || !val.IsLocal || base.item.data == null || (Object)(object)val.refs?.items == (Object)null || (Object)(object)val.player == (Object)null)
			{
				return;
			}
			Optionable<byte> currentSelectedSlot = val.refs.items.currentSelectedSlot;
			if (!currentSelectedSlot.IsNone)
			{
				ItemSlot itemSlot = val.player.GetItemSlot(currentSelectedSlot.Value);
				if (itemSlot != null && !itemSlot.IsEmpty() && itemSlot.prefab is CatItem && itemSlot.data != base.item.data)
				{
					itemSlot.data = base.item.data;
				}
			}
		}

		private void SaveState()
		{
			ItemInstanceData data = base.item.data;
			if (data != null && CatData.IsCat(data))
			{
				CatData.SetSleeping(data, sleeping);
				CatData.SetEnergy(data, energy);
				CatData.SetAge(data, age);
				if ((Object)(object)vitals != (Object)null)
				{
					vitals.SaveTo(data);
				}
			}
		}

		private void SendState(Player to = null)
		{
			if (PhotonNetwork.InRoom)
			{
				object[] array = new object[8]
				{
					(byte)mode,
					seed,
					lookViewId,
					sleeping,
					energy,
					modeUntil - Time.time,
					climbing,
					age
				};
				if (to != null)
				{
					((MonoBehaviourPun)this).photonView.RPC("RPC_CatState", to, array);
				}
				else
				{
					((MonoBehaviourPun)this).photonView.RPC("RPC_CatState", (RpcTarget)1, array);
				}
			}
		}

		[PunRPC]
		private void RPC_CatState(byte m, byte s, int look, bool sl, float en, float remaining, bool climb, float ag)
		{
			SetAgeLocal(ag);
			if ((uint)m != (uint)mode)
			{
				lastModeChange = Time.time;
			}
			mode = (CatMode)m;
			seed = s;
			lookViewId = look;
			energy = en;
			climbing = climb;
			modeUntil = Time.time + remaining;
			if (sl != sleeping)
			{
				sleeping = sl;
				if (sl)
				{
					sleptAt = Time.time;
				}
			}
			SaveState();
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			((MonoBehaviourPunCallbacks)this).OnPlayerEnteredRoom(newPlayer);
			if (((MonoBehaviourPun)this).photonView.IsMine)
			{
				SaveState();
				SendState(newPlayer);
				if ((Object)(object)vitals != (Object)null)
				{
					vitals.SendTo(newPlayer);
				}
				if (petting)
				{
					((MonoBehaviourPun)this).photonView.RPC("RPC_Pet", newPlayer, new object[1] { true });
				}
			}
		}

		private Vector3 Spread(Vector3 fwd)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.AngleAxis((float)((((MonoBehaviourPun)this).photonView.ViewID & 0x7FFFFFFF) % 5) * 36f - 72f, Vector3.up) * fwd;
		}

		private void SetAgeLocal(float a)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			a = Mathf.Clamp01(a);
			if (a == age && sizedAge >= 0f)
			{
				return;
			}
			age = a;
			if (!(Mathf.Abs(age - sizedAge) < 0.004f) || (age >= 1f && sizedAge < 1f))
			{
				sizedAge = age;
				OnItemStateChanged(base.item.itemState);
				CatPrefabBuilder.PlaceHands(((Component)this).transform, Size);
				CatPetting component = ((Component)this).GetComponent<CatPetting>();
				if ((Object)(object)component != (Object)null && !petting)
				{
					component.CaptureGrip();
				}
			}
		}

		private void Grow(float dt, float bonusSeconds = 0f)
		{
			if (IsKitten)
			{
				float num = Mathf.Max(60f, Plugin.GrowMinutes.Value * 60f);
				float num2 = age;
				SetAgeLocal(age + (dt * (petting ? 2f : 1f) + bonusSeconds) / num);
				if (age >= 0.999f && num2 < 0.999f)
				{
					SetAgeLocal(1f);
					SaveState();
					SendState();
					((MonoBehaviourPun)this).photonView.RPC("RPC_GrownUp", (RpcTarget)0, Array.Empty<object>());
				}
				else if (Mathf.FloorToInt(num2 * 20f) != Mathf.FloorToInt(age * 20f))
				{
					SaveState();
					SendState();
				}
			}
		}

		[PunRPC]
		private void RPC_GrownUp()
		{
			((Component)this).GetComponent<CatFx>()?.Burst();
			if ((Object)(object)anim != (Object)null)
			{
				anim.OnVoice(CatSound.Trill);
			}
			CatNet.Notice(DisplayName + " is all grown up!");
			if (((MonoBehaviourPun)this).photonView.IsMine)
			{
				Voice(CatSound.Chirp);
			}
		}

		public void SetMode(CatMode m, float duration)
		{
			if (m != mode)
			{
				lastModeChange = Time.time;
			}
			mode = m;
			modeUntil = Time.time + duration;
			seed = (byte)Random.Range(0, 256);
			if (m != CatMode.Follow && m != CatMode.Climb)
			{
				followTarget = null;
			}
			if (m != CatMode.Eat && m != CatMode.Follow)
			{
				foodTarget = null;
			}
			SendState();
			Plugin.D($"Cat {((MonoBehaviourPun)this).photonView.ViewID} '{DisplayName}' -> {m} for {duration:F1}s (energy {energy:F2}, sleeping {sleeping})");
		}

		public void Voice(CatSound s)
		{
			if (!PhotonNetwork.InRoom)
			{
				RPC_Voice((byte)s, (byte)Random.Range(0, 256));
				return;
			}
			((MonoBehaviourPun)this).photonView.RPC("RPC_Voice", (RpcTarget)0, new object[2]
			{
				(byte)s,
				(byte)Random.Range(0, 256)
			});
		}

		public void OnOwnerEmote(CatEmote kind, float seconds)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			if (!soul && !passedOut && !sleeping && !climbing && ((int)base.item.itemState == 0 || (int)base.item.itemState == 1 || Perched))
			{
				emote = kind;
				emoteUntil = Time.time + seconds;
				if ((Object)(object)anim != (Object)null)
				{
					anim.PlayEmote(kind, seconds);
				}
				CatSound? catSound = kind switch
				{
					CatEmote.Wave => CatSound.Chirp, 
					CatEmote.Dance => CatSound.Trill, 
					CatEmote.BegDance => CatSound.Trill, 
					CatEmote.Cheer => CatSound.Meow, 
					CatEmote.Clap => CatSound.Trill, 
					CatEmote.Panic => CatSound.Surprised, 
					CatEmote.Sad => CatSound.SleepyMrrp, 
					CatEmote.Salute => CatSound.Chirp, 
					CatEmote.Backflip => CatSound.Chirp, 
					_ => null, 
				};
				if (catSound.HasValue)
				{
					RPC_Voice((byte)catSound.Value, (byte)Random.Range(0, 256));
				}
			}
		}

		private void RPC_Voice(byte s, byte variant)
		{
			if ((Object)(object)audio != (Object)null)
			{
				audio.PlayVoice((CatSound)s, variant);
			}
			if ((Object)(object)anim != (Object)null)
			{
				anim.OnVoice((CatSound)s);
			}
			((Component)this).GetComponent<CatFx>()?.OnVoice((CatSound)s);
		}

		public void FallAsleep()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (((MonoBehaviourPun)this).photonView.IsMine && !sleeping)
			{
				sleeping = true;
				sleptAt = Time.time;
				heldStill = 0f;
				if ((int)base.item.itemState == 0)
				{
					SetMode(CatMode.Sleep, Random.Range(40f, 90f));
				}
				else
				{
					SendState();
				}
				SaveState();
				Voice(CatSound.SleepyMrrp);
			}
		}

		public void WakeUp(CatSound? sound = CatSound.Yawn)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (!((MonoBehaviourPun)this).photonView.IsMine)
			{
				return;
			}
			if (!sleeping)
			{
				if (sound == CatSound.Surprised)
				{
					Voice(CatSound.Surprised);
				}
				return;
			}
			sleeping = false;
			heldStill = 0f;
			if (fireNap)
			{
				fireNap = false;
				fireNapCooldown = Time.time + 90f;
			}
			if ((int)base.item.itemState == 0)
			{
				SetMode(CatMode.Wake, 2.6f);
			}
			else
			{
				SendState();
			}
			SaveState();
			if (sound.HasValue)
			{
				Voice(sound.Value);
			}
		}

		public void OnPassedOut()
		{
			StopClimbing();
			if (((MonoBehaviourPun)this).photonView.IsMine)
			{
				SetMode(CatMode.Out, 9999f);
			}
		}

		public void OnRevived()
		{
			if (((MonoBehaviourPun)this).photonView.IsMine)
			{
				SetMode(CatMode.Wake, 2.6f);
				Voice(CatSound.Chirp);
			}
		}

		[PunRPC]
		private void RPC_Fed(int itemId, int feederView, PhotonMessageInfo info)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			PhotonView val = PhotonView.Find(feederView);
			if ((Object)(object)val == (Object)null || (info.Sender != null && val.Owner != info.Sender))
			{
				return;
			}
			if ((Object)(object)anim != (Object)null)
			{
				anim.OnVoice(CatSound.Trill);
			}
			((Component)this).GetComponent<CatFx>()?.Burst();
			Item val2 = default(Item);
			if (((MonoBehaviourPun)this).photonView.IsMine && ItemDatabase.TryGetItem((ushort)itemId, ref val2))
			{
				FoodEffects foodEffects = CatFood.For(val2);
				vitals.ApplyFood(foodEffects);
				Grow(0f, 30f);
				if ((Object)(object)PhotonView.Find(feederView) != (Object)null)
				{
					lookViewId = feederView;
				}
				if (sleeping && vitals.Wired)
				{
					WakeUp(CatSound.Chirp);
				}
				if ((int)base.item.itemState == 0 && !passedOut && !sleeping)
				{
					SetMode(CatMode.Eat, 2.5f);
				}
				else
				{
					SendState();
				}
				Voice(CatSound.Trill);
				Plugin.D($"Cat '{DisplayName}' was fed {val2.GetItemName((ItemInstanceData)null)} (hunger now {vitals.Get((STATUSTYPE)1):F2}, bar {vitals.DisplaySum:F2}, effects {foodEffects.timed.Count})");
			}
		}

		[PunRPC]
		private void RPC_SetCosmetic(byte slot, byte id, PhotonMessageInfo info)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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)
			if (!((MonoBehaviourPun)this).photonView.IsMine || base.item.data == null || info.Sender == null || soul || info.Sender.ActorNumber != ownerActor || slot >= 9)
			{
				return;
			}
			if (id != 0)
			{
				Cosmetic cosmetic = CatCosmetics.Get(id);
				if (cosmetic == null || (uint)cosmetic.Slot != slot || !CatCosmetics.Unlocked(cosmetic, CatAccount.TierOf(info.Sender)))
				{
					return;
				}
			}
			CatData.SetCosmetic(base.item.data, slot, id);
			SaveState();
			((MonoBehaviourPun)this).photonView.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { base.item.data });
		}

		[PunRPC]
		private void RPC_SetMarking(byte layer, int value, PhotonMessageInfo info)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (((MonoBehaviourPun)this).photonView.IsMine && base.item.data != null && info.Sender != null && !soul && info.Sender.ActorNumber == ownerActor && layer < 4 && CatData.Marking(base.item.data, layer) != CatMarkings.Sanitize(value))
			{
				CatData.SetMarking(base.item.data, layer, CatMarkings.Sanitize(value));
				SaveState();
				((MonoBehaviourPun)this).photonView.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { base.item.data });
			}
		}

		[PunRPC]
		private void RPC_GiveCarry(int itemId, ItemInstanceData data, int giverView, PhotonMessageInfo info)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			Item val = default(Item);
			if (!PhotonNetwork.IsMasterClient || !ItemDatabase.TryGetItem((ushort)itemId, ref val))
			{
				return;
			}
			PhotonView val2 = PhotonView.Find(giverView);
			Character val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Character>() : null);
			if ((Object)(object)val3 == (Object)null || val2.Owner != info.Sender || (Object)(object)val3.player == (Object)null || !HasItem(val3.player, (ushort)itemId))
			{
				return;
			}
			if (base.item.data == null || CatData.TryGetCarried(base.item.data, out var _, out var _))
			{
				GameObject val4 = PhotonNetwork.InstantiateItemRoom(((Object)((Component)val).gameObject).name, ((Component)this).transform.position + Vector3.up * 0.4f, Quaternion.identity, true);
				if (!((Object)(object)val4 == (Object)null))
				{
					PhotonView component = val4.GetComponent<PhotonView>();
					component.RPC("SetKinematicRPC", (RpcTarget)3, new object[3]
					{
						false,
						val4.transform.position,
						val4.transform.rotation
					});
					component.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { data });
					CatNet.SendGiveTaken(info.Sender, itemId);
				}
			}
			else
			{
				CatData.SetCarried(base.item.data, val, data);
				((MonoBehaviourPun)this).photonView.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { base.item.data });
				CatNet.SendGiveTaken(info.Sender, itemId);
				Plugin.D("Host: '" + DisplayName + "' now carries " + val.GetItemName((ItemInstanceData)null));
			}
		}

		private static bool HasItem(Player p, ushort id)
		{
			ItemSlot[] itemSlots = p.itemSlots;
			foreach (ItemSlot val in itemSlots)
			{
				if (val != null && !val.IsEmpty() && val.prefab.itemID == id)
				{
					return true;
				}
			}
			if (p.tempFullSlot != null && !p.tempFullSlot.IsEmpty())
			{
				return p.tempFullSlot.prefab.itemID == id;
			}
			return false;
		}

		private void RebindOwnerIfRejoined()
		{
			if (!PhotonNetwork.IsMasterClient || base.item.data == null || PhotonNetwork.CurrentRoom == null || (ownerActor >= 0 && PhotonNetwork.CurrentRoom.GetPlayer(ownerActor, false) != null))
			{
				return;
			}
			int num = CatData.OwnerUid(base.item.data);
			if (num == 0)
			{
				return;
			}
			Player[] playerList = PhotonNetwork.PlayerList;
			foreach (Player val in playerList)
			{
				if (CatData.Uid(val) == num)
				{
					CatData.SetOwner(base.item.data, val.ActorNumber);
					SaveState();
					((MonoBehaviourPun)this).photonView.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { base.item.data });
					Plugin.Log.LogInfo((object)("'" + DisplayName + "' found its owner again (" + val.NickName + " rejoined)."));
					break;
				}
			}
		}

		private void OnTakeBackFinished()
		{
			if (!((Object)(object)((ItemComponent)this).holderCharacter == (Object)null) && ((ItemComponent)this).holderCharacter.IsLocal)
			{
				if (!CatData.TryGetCarried(base.item.data, out var _, out var _))
				{
					RequestPerch();
					return;
				}
				((MonoBehaviourPun)this).photonView.RPC("RPC_TakeCarry", (RpcTarget)2, new object[1] { ((MonoBehaviourPun)((ItemComponent)this).holderCharacter).photonView.ViewID });
			}
		}

		[PunRPC]
		private void RPC_TakeCarry(int charView, PhotonMessageInfo info)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Invalid comparison between Unknown and I4
			//IL_00ce: 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)
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			PhotonView val = PhotonView.Find(charView);
			Character val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Character>() : null);
			if (!((Object)(object)val2 == (Object)null) && val.Owner == info.Sender && CatData.TryGetCarried(base.item.data, out var prefab, out var data) && (int)base.item.itemState == 1 && !((Object)(object)((ItemComponent)this).holderCharacter != (Object)(object)val2))
			{
				ItemSlot val3 = default(ItemSlot);
				if (!val2.player.AddItem(prefab.itemID, data, ref val3))
				{
					CatNet.SendNoticeTo(info.Sender.ActorNumber, "No room in your pockets for that.");
					return;
				}
				CatData.ClearCarried(base.item.data);
				((MonoBehaviourPun)this).photonView.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { base.item.data });
				CatNet.SendNoticeTo(info.Sender.ActorNumber, "Took the " + prefab.GetItemName((ItemInstanceData)null) + " off " + DisplayName + "'s back.");
			}
		}

		private void OnPetCastFinished()
		{
			if (!((Object)(object)((ItemComponent)this).holderCharacter == (Object)null) && ((ItemComponent)this).holderCharacter.IsLocal && !petting)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_Pet", (RpcTarget)0, new object[1] { true });
			}
		}

		private void OnPetCancelled()
		{
			if (petting)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_Pet", (RpcTarget)0, new object[1] { false });
			}
		}

		[PunRPC]
		private void RPC_Pet(bool on)
		{
			petting = on;
			Plugin.D($"Cat {((MonoBehaviourPun)this).photonView.ViewID} petting={on}");
			((Component)this).GetComponent<CatPetting>()?.OnPetChanged(on);
			if (on && ((MonoBehaviourPun)this).photonView.IsMine)
			{
				heldStill = Mathf.Max(heldStill, 12f);
			}
		}

		private void Update()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Invalid comparison between Unknown and I4
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Invalid comparison between Unknown and I4
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if (highlightDirtyFrame >= 0 && Time.frameCount > highlightDirtyFrame)
			{
				highlightDirtyFrame = -1;
				CatPrefabBuilder.RefreshHighlight(base.item);
			}
			UpdateWindPose();
			if (!((MonoBehaviourPun)this).photonView.IsMine || (Object)(object)rig == (Object)null)
			{
				return;
			}
			thinkTimer -= Time.deltaTime;
			if (thinkTimer > 0f)
			{
				return;
			}
			float num = (thinkTimer = 0.25f + Random.value * 0.05f);
			if (Time.time > nextRebindCheck)
			{
				nextRebindCheck = Time.time + 5f;
				RebindOwnerIfRejoined();
			}
			if ((int)base.item.itemState == 0)
			{
				LoyalTransitions();
			}
			if ((int)base.item.itemState == 0 && SafetyNet(num))
			{
				return;
			}
			if (!NearAnyPlayer(100f) && (int)base.item.itemState == 0 && !soul && perchActor < 0)
			{
				if (climbing)
				{
					StopClimbing();
					rig.linearVelocity = Vector3.zero;
				}
				return;
			}
			if ((Object)(object)vitals != (Object)null && !soul && (int)base.item.itemState != 2)
			{
				vitals.Tick(num);
			}
			if (!soul && ((int)base.item.itemState == 0 || (int)base.item.itemState == 1))
			{
				Grow(num);
			}
			saveTimer -= num;
			if (saveTimer <= 0f)
			{
				saveTimer = 2f;
				SaveState();
			}
			Think(num);
		}

		private bool NearAnyPlayer(float range)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			float num = range * range;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if ((Object)(object)allCharacter != (Object)null)
				{
					Vector3 val = allCharacter.Center - ((Component)this).transform.position;
					if (((Vector3)(ref val)).sqrMagnitude < num)
					{
						return true;
					}
				}
			}
			return false;
		}

		private void Think(float dt)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			CatType type = Type;
			float num = Mathf.Lerp(420f, 170f, type.Laziness) * Mathf.Lerp(0.7f, 1f, age);
			float num2 = Mathf.Lerp(50f, 110f, type.Laziness);
			LoyalTransitions();
			TrackDawn();
			if (soul)
			{
				if (mode != CatMode.Soul)
				{
					SetMode(CatMode.Soul, 9999f);
				}
			}
			else if ((int)base.item.itemState == 1)
			{
				ThinkHeld(dt, num, num2);
			}
			else if (Perched)
			{
				ThinkPerched(dt, num, nu