Decompiled source of PeakCats v1.9.0
plugins/PeakCats.dll
Decompiled 3 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; 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 class CatBrain : ItemComponent { private enum Social : byte { None, Sniff, Groom, Play, Chase, Cuddle } private enum Block { None, Wall, Ledge, Cliff, Steep, Water } public static readonly string[] RoleNames = new string[5] { "None", "Hunter", "Medic", "Scout", "Cozy" }; public static readonly string[] RoleBlurbs = new string[5] { "No job - just a very good cat.", "Catches you something to eat every few minutes.", "Stay close and it slowly heals your injuries and poison.", "Sniffs out unopened luggage nearby and leads you to it.", "Stay close and it keeps you warm in the cold." }; public static readonly string[] RoleClanNames = new string[5] { "None", "Hunter", "Medicine cat", "Pathfinder", "Den-mother" }; public int role; private float nextHunt = -1f; private float nextMedic; private float nextScout; private float nextCozy; private float scoutUntil; private Vector3 scoutTarget; private bool scoutAnnounced; private static readonly HashSet<int> s_scoutedLuggage = new HashSet<int>(); private static List<Item> s_safeFood; public bool inWater; public bool windGrip; private float envSpeedMul = 1f; private float lastLavaHit; private float hazardScan; private float lavaFleeCooldown; private Vector3 windCounter; public CatCommand command; private Vector3 stayAt; private bool goingTo; private CatBrain socialWith; private Social socialKind; private float nextSocial; private float nextCuddle; 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; private static int s_solidMask; 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; 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 float lastGroundContact = -99f; private Vector3 contactNormal = Vector3.up; private static int s_characterLayer = -2; private bool ownerWasDown; private Vector3 vigilPos; private float reunitedUntil; private float morningUntil; private bool wasNight; public static readonly string[] WarriorSuffixes = new string[16] { "heart", "storm", "fur", "pelt", "claw", "tail", "whisker", "flight", "song", "frost", "leaf", "stripe", "fang", "shade", "breeze", "wing" }; public const int StarSuffix = 16; public int warriorName; private string dnCache; private string dnFor; private int dnType = -2; private int dnWarrior = -1; private int dnStage = -2; private float nextNameSync; private float nextClanSave; private string lastShownName; private int lastShownWarrior; private float nextCeremonyCheck; private string lastNameFor; private float clanRoleAt = -1f; private float nextStar; 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 bool toyChasing; private Vector3 toyTarget; private CatToy toyYarn; private float yarnSince; private float lastSwat; private float nextYarnSwat; private float nextPounce; private float yarnBoredUntil; private ClimbTrail trail; private int trailIdx; private float trailStuck; private float trailEndWait; private Vector3 strayHome; private bool strayHomeSet; private float strayFleeUntil; private float nextStraySpot; public bool Staying { get { if (command != CatCommand.Stay && command != CatCommand.Sit) { return command == CatCommand.GoTo; } return true; } } public float Size => Mathf.Lerp(1f, 1.3f, age) * Type.Scale; 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 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 int NameStage => CatWarrior.Stage(age); public string DisplayName { get { int num = ((warriorName == 0) ? (-1) : NameStage); if (dnCache == null || (object)dnFor != catName || dnType != typeId || dnWarrior != warriorName || dnStage != num) { dnFor = catName; dnType = typeId; dnWarrior = warriorName; dnStage = num; string text = (string.IsNullOrEmpty(catName) ? Type.Name : catName); dnCache = ((num < 0) ? text : WarriorForm(text, num, warriorName - 1)); } return dnCache; } } 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; } } public bool IsStray { get { if ((Object)(object)base.item != (Object)null && base.item.data != null) { return CatData.Stray(base.item.data); } return false; } } public static string RoleName(int r) { if (!CatWarrior.On(CatWarrior.ClanSpeak)) { return RoleNames[Mathf.Clamp(r, 0, 4)]; } return RoleClanNames[Mathf.Clamp(r, 0, 4)]; } public void RequestRole(int r) { Player val = ((MonoBehaviourPun)this).photonView.Controller ?? PhotonNetwork.MasterClient; if (PhotonNetwork.InRoom && val != null) { if (!val.IsLocal && CatNet.FeatureOf(val) < 180) { CatNet.Notice(val.NickName + " needs PeakCats 1.8.0 or newer for cat jobs."); return; } ((MonoBehaviourPun)this).photonView.RPC("RPC_SetRole", val, new object[1] { (byte)r }); } } [PunRPC] private void RPC_SetRole(byte r, PhotonMessageInfo info) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (((MonoBehaviourPun)this).photonView.IsMine && base.item.data != null && info.Sender != null && !soul && r <= 4 && info.Sender.ActorNumber == ownerActor) { CatData.SetRole(base.item.data, r); SaveState(); ((MonoBehaviourPun)this).photonView.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { base.item.data }); } } private void AbilityTick() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0273: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_03de: 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_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) if (role == 0 || soul || passedOut || IsStray) { return; } Character val = OwnerCharacter(); if ((Object)(object)val == (Object)null || val.data.dead) { return; } float num = Vector3.Distance(val.Center, ((Component)this).transform.position); float time = Time.time; switch (role) { case 1: { if (nextHunt < 0f) { nextHunt = time + Random.Range(60f, 100f); } if (time < nextHunt || sleeping || num > 14f || (int)base.item.itemState != 0 || !grounded || climbing || Perched) { break; } nextHunt = time + Random.Range(120f, 180f); Item val2 = RandomSafeFood(); if (!((Object)(object)val2 == (Object)null)) { Vector3 val3 = ((Component)this).transform.position + ((Component)this).transform.forward * 0.35f + Vector3.up * 0.35f; GameObject val4 = PhotonNetwork.InstantiateItemRoom(((Object)((Component)val2).gameObject).name, val3, Quaternion.identity, true); PhotonView val5 = (((Object)(object)val4 != (Object)null) ? val4.GetComponent<PhotonView>() : null); if ((Object)(object)val5 != (Object)null) { val5.RPC("SetKinematicRPC", (RpcTarget)3, new object[3] { false, val3, Quaternion.identity }); } Voice(CatSound.Chirp); CatNet.SendNoticeTo(ownerActor, DisplayName + " caught you a " + val2.GetItemName((ItemInstanceData)null) + "!"); } break; } case 2: if (!(time < nextMedic) && !sleeping && !(num > 4f)) { nextMedic = time + 6f; CatNet.SendAbility(ownerActor, 1, 0.025f); CatNet.SendAbility(ownerActor, 2, 0.02f); ((Component)this).GetComponent<CatFx>()?.Emit(CatFx.Kind.Heart, ((Component)this).transform.position + Vector3.up * 0.35f * Size, 0.05f, 1.2f, Vector3.up * 0.2f); } break; case 3: { if (!(time > nextScout) || sleeping || Staying || Perched || (int)base.item.itemState != 0 || !(num < 20f)) { break; } nextScout = time + 45f; Luggage val6 = null; float num2 = 35f; foreach (Luggage item in Luggage.ALL_LUGGAGE) { if (!((Object)(object)item == (Object)null) && ((Component)item).gameObject.activeInHierarchy && !s_scoutedLuggage.Contains(((Object)item).GetInstanceID()) && !(item is LuggageCursed) && !(item is RespawnChest) && !item.IsOpen) { float num3 = Vector3.Distance(((Component)item).transform.position, val.Center); if (num3 < num2 && Mathf.Abs(((Component)item).transform.position.y - val.Center.y) < 12f) { num2 = num3; val6 = item; } } } if ((Object)(object)val6 != (Object)null && num2 > 5f) { s_scoutedLuggage.Add(((Object)val6).GetInstanceID()); scoutTarget = ((Component)val6).transform.position; scoutUntil = time + 14f; scoutAnnounced = false; } break; } case 4: if (!(time < nextCozy) && !(num > 3.5f)) { nextCozy = time + 5f; CatNet.SendAbility(ownerActor, 3, 0.035f); } break; } } private bool ThinkScout(float dt) { //IL_002c: 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_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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (role != 3 || Time.time > scoutUntil || sleeping || Staying || (int)base.item.itemState != 0) { return false; } Vector3 val = scoutTarget - ((Component)this).transform.position; val.y = 0f; if (((Vector3)(ref val)).magnitude > 1.1f) { ChaseToy(scoutTarget, 1f, pounce: false); return true; } moveSpeed = 0f; if (mode != CatMode.Sit) { SetMode(CatMode.Sit, 3f); } if (!scoutAnnounced) { scoutAnnounced = true; Voice(CatSound.Meow); CatNet.SendNoticeTo(ownerActor, DisplayName + " found some luggage!"); scoutUntil = Time.time + 4f; } return true; } private static Item RandomSafeFood() { if (s_safeFood == null) { s_safeFood = new List<Item>(); ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance; if ((Object)(object)instance == (Object)null) { return null; } foreach (Item value in instance.itemLookup.Values) { if ((Object)(object)value == (Object)null || value is CatItem || value is CatToyItem || !CatFood.IsEdible(value)) { continue; } FoodEffects foodEffects = CatFood.For(value); if (foodEffects.instant[1] > -0.05f) { continue; } bool flag = false; for (int i = 0; i < foodEffects.instant.Length; i++) { if (i != 1 && foodEffects.instant[i] > 0f) { flag = true; } } if (!flag && foodEffects.timed.Count <= 0 && !foodEffects.chaos && !foodEffects.clearAll && !foodEffects.cureAll && PlainFood(value)) { s_safeFood.Add(value); } } Plugin.Log.LogInfo((object)$"Hunter cats can catch {s_safeFood.Count} kinds of food."); } if (s_safeFood.Count <= 0) { return null; } return s_safeFood[Random.Range(0, s_safeFood.Count)]; } private static bool PlainFood(Item it) { ItemAction[] components = ((Component)it).GetComponents<ItemAction>(); foreach (ItemAction val in components) { if (!((Object)(object)val == (Object)null) && CatFood.Fires(val) && !(val is Action_Consume) && !(val is Action_ConsumeAndSpawn) && !(val is Action_ReduceUses) && !(val is Action_RestoreHunger) && !(val is Action_GiveExtraStamina) && !(val is Action_PlayAnimation) && !(val is Action_PlayItemAnimation) && !(val is Action_IncrementSteamStat) && !(val is Action_TryHotDogAchievement)) { Action_ModifyStatus val2 = (Action_ModifyStatus)(object)((val is Action_ModifyStatus) ? val : null); if (val2 == null || !(val2.changeAmount <= 0f)) { return false; } } } return true; } public static void ApplyAbilityToMe(int kind, float amount) { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && !localCharacter.data.dead && !(amount <= 0f) && !(amount > 0.2f)) { CharacterAfflictions afflictions = localCharacter.refs.afflictions; switch (kind) { case 1: afflictions.SubtractStatus((STATUSTYPE)0, amount, false, false); break; case 2: afflictions.SubtractStatus((STATUSTYPE)3, amount, false, false); break; case 3: afflictions.SubtractStatus((STATUSTYPE)2, amount, false, false); break; } } } 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 void RequestCommand(CatCommand c, Vector3 point) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) Player val = ((MonoBehaviourPun)this).photonView.Controller ?? PhotonNetwork.MasterClient; if (PhotonNetwork.InRoom && val != null) { if (!val.IsLocal && CatNet.FeatureOf(val) < 160) { CatNet.Notice(val.NickName + " needs PeakCats 1.6.0 or newer for cat commands."); return; } ((MonoBehaviourPun)this).photonView.RPC("RPC_Command", val, new object[2] { (byte)c, point }); } } [PunRPC] private void RPC_Command(byte c, Vector3 point, PhotonMessageInfo info) { //IL_000d: 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_003e: 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) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: 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_0180: 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_01ab: 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) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0235: 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_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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) if (!((MonoBehaviourPun)this).photonView.IsMine || info.Sender == null || info.Sender.ActorNumber != ownerActor || soul || c > 6) { return; } CatCommand catCommand = (CatCommand)c; if ((int)base.item.itemState != 0 || Perched || (climbing && catCommand != CatCommand.Come && catCommand != CatCommand.Follow)) { return; } Character val = OwnerCharacter(); goingTo = false; socialWith = null; switch (catCommand) { case CatCommand.Come: case CatCommand.Follow: command = CatCommand.None; if (sleeping) { WakeUp(CatSound.Chirp); } if (!((Object)(object)val == (Object)null) && !val.data.dead) { if (catCommand == CatCommand.Come && Vector3.Distance(val.Center, ((Component)this).transform.position) > 25f && TryRescueTo(val, null)) { Voice(CatSound.Chirp); break; } StartFollowingOwner(val); Voice(CatSound.Chirp); } break; case CatCommand.Stay: case CatCommand.Sit: command = catCommand; stayAt = ((Component)this).transform.position; StopClimbing(); if (!sleeping) { SetMode((catCommand == CatCommand.Sit) ? CatMode.Sit : CatMode.Loaf, (catCommand == CatCommand.Sit) ? 9999f : Random.Range(4f, 8f)); } if ((Object)(object)val != (Object)null) { Vector3 val3 = val.Center - ((Component)this).transform.position; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude > 0.01f) { faceDir = ((Vector3)(ref val3)).normalized; } } break; case CatCommand.Nap: command = CatCommand.None; if (!sleeping) { FallAsleep(); } break; case CatCommand.GoTo: { if (float.IsNaN(point.x) || Vector3.Distance(point, ((Component)this).transform.position) > 80f) { return; } if (sleeping) { WakeUp(CatSound.Yawn); } command = CatCommand.GoTo; stayAt = point; goingTo = true; StopClimbing(); fireSpot = point; Vector3 val2 = point - ((Component)this).transform.position; firePos = point + ((Vector3)(ref val2)).normalized; fireNap = false; SetMode(CatMode.ToFire, 40f); Voice(CatSound.Chirp); break; } } SendState(); } private void ClearCommand() { command = CatCommand.None; goingTo = false; } private void ArrivedAtGoTo() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) goingTo = false; stayAt = ((Component)this).transform.position; SetMode(CatMode.Sit, Random.Range(4f, 8f)); } private bool ChooseWhileStaying() { //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_0042: 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_0057: 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_0079: 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_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_0091: Unknown result type (might be due to invalid IL or missing references) if (!Staying) { return false; } if (goingTo) { goingTo = false; stayAt = ((Component)this).transform.position; } if (command == CatCommand.Sit) { SetMode(CatMode.Sit, 9999f); return true; } Vector3 val = stayAt - ((Component)this).transform.position; val.y = 0f; if (((Vector3)(ref val)).magnitude > 1.6f) { fireSpot = stayAt; firePos = stayAt + ((Vector3)(ref val)).normalized; goingTo = true; SetMode(CatMode.ToFire, 15f); return true; } float value = Random.value; if (value < 0.35f) { SetMode(CatMode.Loaf, Random.Range(6f, 14f)); } else if (value < 0.6f) { SetMode(CatMode.Groom, Random.Range(3f, 6f)); } else { SetMode(CatMode.Sit, Random.Range(4f, 9f)); } return true; } private bool TrySocialize() { if (Time.time < nextSocial || !Plugin.CatsSocialize.Value) { return false; } nextSocial = Time.time + Random.Range(18f, 40f); CatBrain catBrain = NearbyCat(5f, awake: true); if ((Object)(object)catBrain == (Object)null) { return false; } float value = Random.value; Social social = ((value < 0.35f) ? Social.Sniff : ((value < 0.6f) ? Social.Groom : ((value < 0.82f) ? Social.Play : Social.Chase))); if (Staying && social == Social.Chase) { social = Social.Sniff; } if (Staying) { catBrain.JoinSocial(this, social); return false; } socialWith = catBrain; socialKind = social; SetMode(CatMode.Follow, 10f); if (social == Social.Chase) { catBrain.RunFrom(this); } if (Random.value < 0.5f) { Voice((social == Social.Play || social == Social.Chase) ? CatSound.Chirp : CatSound.Trill); } return true; } private bool TryCuddleUp() { //IL_004a: 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) if (!Plugin.CatsSocialize.Value || Time.time < nextCuddle) { return false; } nextCuddle = Time.time + 30f; CatBrain catBrain = NearbyCat(7f, awake: false); if ((Object)(object)catBrain == (Object)null) { return false; } if (Vector3.Distance(((Component)catBrain).transform.position, ((Component)this).transform.position) < 0.8f) { return false; } socialWith = catBrain; socialKind = Social.Cuddle; SetMode(CatMode.Follow, 10f); return true; } private CatBrain NearbyCat(float range, bool awake) { //IL_005a: 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_00b0: Unknown result type (might be due to invalid IL or missing references) CatBrain result = null; float num = range; foreach (CatBrain item in All) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)this) && ((MonoBehaviourPun)item).photonView.IsMine && !item.soul && !item.passedOut && (int)((ItemComponent)item).item.itemState == 0 && !item.Perched && !item.climbing && awake != item.sleeping && (!awake || (item.mode != CatMode.Eat && item.mode != CatMode.ToFire && !((Object)(object)item.socialWith != (Object)null)))) { float num2 = Vector3.Distance(((Component)item).transform.position, ((Component)this).transform.position); if (num2 < num) { num = num2; result = item; } } } return result; } private bool SocialTarget(out Vector3 target) { //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) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0091: Unknown result type (might be due to invalid IL or missing references) target = Vector3.zero; if ((Object)(object)socialWith == (Object)null) { return false; } if (socialWith.soul || (int)((ItemComponent)socialWith).item.itemState != 0 || (socialKind != Social.Cuddle && socialWith.sleeping)) { socialWith = null; SetMode(CatMode.Idle, 1f); return true; } target = ((Component)socialWith).transform.position; Vector3 val = target - ((Component)this).transform.position; val.y = 0f; float num = ((socialKind == Social.Cuddle) ? 0.5f : ((socialKind == Social.Chase) ? 0.45f : 0.62f)); if (((Vector3)(ref val)).magnitude < num) { StartSocial(); return true; } return true; } private float SocialSpeed(float d) { if (socialKind != Social.Chase) { return Mathf.Clamp(d * 1.2f, 0.6f, 1.6f); } return Mathf.Clamp(d * 1.5f, 1.5f, 3.6f); } private void StartSocial() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) CatBrain catBrain = socialWith; Social social = socialKind; socialWith = null; if (!((Object)(object)catBrain == (Object)null)) { Vector3 val = ((Component)catBrain).transform.position - ((Component)this).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.001f) { faceDir = ((Vector3)(ref val)).normalized; } switch (social) { case Social.Cuddle: SetMode(CatMode.Loaf, 1.5f); break; case Social.Sniff: SetMode(CatMode.Sit, Random.Range(2.5f, 4f)); catBrain.JoinSocial(this, Social.Sniff); break; case Social.Groom: SetMode(CatMode.Groom, Random.Range(3f, 5f)); catBrain.JoinSocial(this, Social.Sniff); break; case Social.Play: case Social.Chase: SetMode(CatMode.Bat, Random.Range(2.5f, 4f)); catBrain.JoinSocial(this, Social.Play); break; } } } private void JoinSocial(CatBrain from, Social kind) { //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_0044: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (((MonoBehaviourPun)this).photonView.IsMine && !sleeping && mode != CatMode.Eat && !((Object)(object)socialWith != (Object)null)) { Vector3 val = ((Component)from).transform.position - ((Component)this).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.001f) { faceDir = ((Vector3)(ref val)).normalized; } nextSocial = Time.time + Random.Range(18f, 40f); SetMode(kind switch { Social.Groom => CatMode.Groom, Social.Play => CatMode.Bat, _ => CatMode.Sit, }, Random.Range(2.5f, 4f)); SendState(); } } private void RunFrom(CatBrain chaser) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_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_0091: 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) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (((MonoBehaviourPun)this).photonView.IsMine && !sleeping && !Staying) { Vector3 val = ((Component)this).transform.position - ((Component)chaser).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Random.insideUnitSphere; } val.y = 0f; moveDir = Quaternion.Euler(0f, Random.Range(-30f, 30f), 0f) * ((Vector3)(ref val)).normalized; nextSocial = Time.time + Random.Range(18f, 40f); SetMode(CatMode.Trot, Random.Range(2f, 3.2f)); SendState(); } } 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" }); } if (s_characterLayer == -2) { s_characterLayer = LayerMask.NameToLayer("Character"); } if (s_solidMask == 0) { s_solidMask = -1 & ~LayerMask.GetMask(new string[5] { "Character", "Ignore Raycast", "UI", "TransparentFX", "Water" }); } 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_01b