Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HatHunt v6.4.2
HatHunt.dll
Decompiled 19 hours 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.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace HatHunt; public enum AnimeBase : byte { None, Headband, Maid, Hachimaki, Kasa, Kabuto } public enum BandStyle : byte { None, Thin, Thick, Double } public enum BrimStyle : byte { None, Flat, Wide, Upturned, Drooping, Visor, Tricorn, Rolled, Sloped } public class CharacterPuppet { public Transform Root; private PlayerControllerB player; private readonly List<Transform> src = new List<Transform>(); private readonly List<Transform> dst = new List<Transform>(); private readonly Dictionary<Transform, Transform> map = new Dictionary<Transform, Transform>(); private GameObject hatObj; private Hat hatShown; private int hatVersion = -1; public Vector3 HeadPoint { get { //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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_007b: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)player != (Object)null && (Object)(object)player.gameplayCamera != (Object)null) ? ((Component)player.gameplayCamera).transform.position : (((Object)(object)player != (Object)null) ? (((Component)player).transform.position + Vector3.up * 2f) : Vector3.zero)); return ((Object)(object)player != (Object)null) ? ((Component)player).transform.InverseTransformPoint(val) : (Vector3.up * 2f); } } public GameObject Hat => hatObj; public static CharacterPuppet Build(PlayerControllerB p, Transform parent) { //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: 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_0097: 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_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: 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) SkinnedMeshRenderer thisPlayerModel = p.thisPlayerModel; if ((Object)(object)thisPlayerModel == (Object)null || (Object)(object)thisPlayerModel.sharedMesh == (Object)null || thisPlayerModel.bones == null || thisPlayerModel.bones.Length == 0) { return null; } CharacterPuppet characterPuppet = new CharacterPuppet(); characterPuppet.player = p; CharacterPuppet characterPuppet2 = characterPuppet; characterPuppet2.Root = new GameObject("puppet").transform; characterPuppet2.Root.SetParent(parent, false); characterPuppet2.Root.localScale = ((Component)p).transform.lossyScale; HashSet<Transform> need = new HashSet<Transform>(); Action<Transform> action = delegate(Transform t) { while ((Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)((Component)p).transform && need.Add(t)) { t = t.parent; } }; Transform[] bones = thisPlayerModel.bones; foreach (Transform obj in bones) { action(obj); } action(thisPlayerModel.rootBone); action(p.headCostumeContainer); action(p.playerGlobalHead); action(((Component)thisPlayerModel).transform); List<Transform> list = new List<Transform>(need); list.Sort((Transform a, Transform b) => Depth(a, ((Component)p).transform).CompareTo(Depth(b, ((Component)p).transform))); foreach (Transform item in list) { if (item.IsChildOf(((Component)p).transform)) { Transform transform = new GameObject(((Object)item).name).transform; transform.SetParent(((Object)(object)item.parent == (Object)(object)((Component)p).transform || !characterPuppet2.map.TryGetValue(item.parent, out var value)) ? characterPuppet2.Root : value, false); transform.localPosition = item.localPosition; transform.localRotation = item.localRotation; transform.localScale = item.localScale; characterPuppet2.map[item] = transform; characterPuppet2.src.Add(item); characterPuppet2.dst.Add(transform); } } if (!characterPuppet2.map.TryGetValue(((Component)thisPlayerModel).transform, out var value2)) { value2 = characterPuppet2.Root; } GameObject val = new GameObject("body"); val.transform.SetParent(value2, false); SkinnedMeshRenderer val2 = val.AddComponent<SkinnedMeshRenderer>(); Transform[] array = (Transform[])(object)new Transform[thisPlayerModel.bones.Length]; for (int num2 = 0; num2 < array.Length; num2++) { array[num2] = (((Object)(object)thisPlayerModel.bones[num2] != (Object)null && characterPuppet2.map.TryGetValue(thisPlayerModel.bones[num2], out var value3)) ? value3 : null); } val2.sharedMesh = thisPlayerModel.sharedMesh; val2.bones = array; val2.rootBone = (((Object)(object)thisPlayerModel.rootBone != (Object)null && characterPuppet2.map.TryGetValue(thisPlayerModel.rootBone, out var value4)) ? value4 : null); ((Renderer)val2).sharedMaterials = ((Renderer)thisPlayerModel).sharedMaterials; ((Renderer)val2).localBounds = ((Renderer)thisPlayerModel).localBounds; val2.updateWhenOffscreen = true; val2.quality = (SkinQuality)0; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)val2).receiveShadows = true; try { for (int num3 = 0; num3 < thisPlayerModel.sharedMesh.blendShapeCount; num3++) { val2.SetBlendShapeWeight(num3, thisPlayerModel.GetBlendShapeWeight(num3)); } } catch { } if ((Object)(object)value2 != (Object)(object)characterPuppet2.Root) { val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; } return characterPuppet2; } private static int Depth(Transform t, Transform stop) { int num = 0; while ((Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)stop) { num++; t = t.parent; } return num; } public void Sync() { //IL_002f: 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_0047: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < src.Count; i++) { Transform val = src[i]; if (!((Object)(object)val == (Object)null)) { Transform val2 = dst[i]; val2.localPosition = val.localPosition; val2.localRotation = val.localRotation; val2.localScale = val.localScale; } } if (hatShown != null && hatVersion != HatManager.HeadVersion) { Pose(); } } public void SetHat(Hat hat) { if ((Object)(object)hatObj != (Object)null) { Object.Destroy((Object)(object)hatObj); } hatObj = null; hatShown = hat; hatVersion = HatManager.HeadVersion; if (hat == null || (Object)(object)player == (Object)null) { return; } try { hatObj = HatVisuals.Build(hat); Light[] componentsInChildren = hatObj.GetComponentsInChildren<Light>(true); foreach (Light val in componentsInChildren) { ((Behaviour)val).enabled = false; } Pose(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("puppet hat: " + ex.Message)); } } private void Pose() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) hatVersion = HatManager.HeadVersion; if (!((Object)(object)hatObj == (Object)null) && hatShown != null && !((Object)(object)player == (Object)null)) { HatManager.HatLocalPose(player, hatShown, out var parent, out var local); if (map.TryGetValue(parent, out var value)) { hatObj.transform.SetParent(value, false); HatManager.SetLocalMatrix(hatObj.transform, local); } else { hatObj.transform.SetParent(Root, false); HatManager.SetLocalMatrix(hatObj.transform, ((Component)player).transform.worldToLocalMatrix * parent.localToWorldMatrix * local); } } } public void Destroy() { if ((Object)(object)Root != (Object)null) { Object.Destroy((Object)(object)((Component)Root).gameObject); } Root = null; hatObj = null; } } public class CharacterStudio { public PreviewStage Stage; public CharacterPuppet Puppet; private Transform pivot; private float camDist = 1.4f; private float targetDist = 1.4f; public float Swing = 38f; private float nextReframe; private int framedVersion = -1; public RenderTexture Texture => Stage.Texture; public bool Active { set { Stage.Active = value; } } public static CharacterStudio Create(string name, Vector3 pos, int w, int h) { //IL_0008: 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) CharacterStudio characterStudio = new CharacterStudio(); characterStudio.Stage = PreviewStage.Create(name, pos, w, h, pedestal: false); characterStudio.pivot = HatVisuals.PropPivot(characterStudio.Stage.Turntable, "pivot", new Vector3(0f, 0.4f, 0f), Quaternion.identity); return characterStudio; } public bool Capture(PlayerControllerB p) { if (Puppet != null) { Puppet.Destroy(); } Puppet = CharacterPuppet.Build(p, pivot); if (Puppet == null) { return false; } Puppet.Sync(); Reframe(snap: true); return true; } public void SetHat(Hat hat) { if (Puppet != null) { Puppet.SetHat(hat); Reframe(snap: false); } } private void Reframe(bool snap) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (Puppet != null) { Vector3 headPoint = Puppet.HeadPoint; Bounds val = default(Bounds); ((Bounds)(ref val))..ctor(headPoint + Vector3.up * 0.05f, new Vector3(0.6f, 0.6f, 0.6f)); if ((Object)(object)Puppet.Hat != (Object)null && PreviewStage.LocalBounds(Puppet.Hat.transform, Puppet.Root, out var b)) { ((Bounds)(ref val)).Encapsulate(((Bounds)(ref b)).min); ((Bounds)(ref val)).Encapsulate(((Bounds)(ref b)).max); } Puppet.Root.localPosition = -((Bounds)(ref val)).center; float num = Mathf.Max(new float[3] { ((Bounds)(ref val)).size.x, ((Bounds)(ref val)).size.y, ((Bounds)(ref val)).size.z }) * 0.5f; targetDist = Mathf.Clamp(num / Mathf.Tan((float)Math.PI / 12f) * 1.25f, 1f, 3.5f); if (snap) { camDist = targetDist; } } } public void Tick() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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) if (Puppet != null) { Puppet.Sync(); if (Time.unscaledTime > nextReframe || framedVersion != HatManager.HeadVersion) { nextReframe = Time.unscaledTime + 0.25f; framedVersion = HatManager.HeadVersion; Reframe(snap: false); } pivot.localRotation = Quaternion.Euler(0f, Mathf.Sin(Time.unscaledTime * 0.8f) * Swing, 0f); camDist = Mathf.Lerp(camDist, targetDist, Mathf.Min(1f, Time.unscaledDeltaTime * 6f)); Transform transform = ((Component)Stage.Cam).transform; transform.localPosition = new Vector3(0f, 0.4f + camDist * 0.1f, camDist); transform.LookAt(pivot.position); } } public void Clear() { if (Puppet != null) { Puppet.Destroy(); } Puppet = null; } } public static class Collection { public static readonly List<HatKey> Hats = new List<HatKey>(); public static int EquippedIndex = -1; public static int Keys; public static int Version; public static readonly int[] Crates = new int[4]; private static string Dir => Path.Combine(Paths.ConfigPath, "HatHunt"); private static string FilePath => Path.Combine(Dir, "my_hats.txt"); public static HatKey? Equipped => (EquippedIndex >= 0 && EquippedIndex < Hats.Count) ? new HatKey?(Hats[EquippedIndex]) : ((HatKey?)null); public static void Load() { Version++; Hats.Clear(); EquippedIndex = -1; Keys = 0; for (int i = 0; i < Crates.Length; i++) { Crates[i] = 0; } try { if (!File.Exists(FilePath)) { return; } string text = null; string[] array = File.ReadAllLines(FilePath); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.Length == 0 || text3.StartsWith("#")) { continue; } HatKey key; if (text3.StartsWith("equipped=")) { text = text3.Substring(9); } else if (text3.StartsWith("keys=")) { int.TryParse(text3.Substring(5), out Keys); } else if (text3.StartsWith("crate=")) { string[] array2 = text3.Substring(6).Split(':'); if (array2.Length == 2 && int.TryParse(array2[0], out var result) && int.TryParse(array2[1], out var result2) && result >= 0 && result < Crates.Length) { Crates[result] = result2; } } else if (HatKey.TryParse(text3, out key) && !Hats.Contains(key)) { Hats.Add(key); } } if (text != null && HatKey.TryParse(text, out var key2)) { EquippedIndex = Hats.IndexOf(key2); } } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to load hat collection: " + ex)); } } public static void Save() { Version++; try { Directory.CreateDirectory(Dir); List<string> list = new List<string>(); list.Add("# HatHunt collection - seed,rarity,serial. Don't edit unless you like broken hats."); List<string> list2 = list; HatKey? equipped = Equipped; if (equipped.HasValue) { list2.Add("equipped=" + equipped.Value.Serialize()); } list2.Add("keys=" + Keys); for (int i = 0; i < Crates.Length; i++) { if (Crates[i] > 0) { list2.Add("crate=" + i + ":" + Crates[i]); } } foreach (HatKey hat in Hats) { list2.Add(hat.Serialize()); } File.WriteAllLines(FilePath, list2.ToArray()); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to save hat collection: " + ex)); } } public static void RemoveAll(IList<HatKey> keys) { HatKey? equipped = Equipped; foreach (HatKey key in keys) { Hats.Remove(key); } EquippedIndex = (equipped.HasValue ? Hats.IndexOf(equipped.Value) : (-1)); Save(); } public static bool Add(HatKey k) { if (Hats.Contains(k)) { return false; } Hats.Add(k); Save(); return true; } } public class CrateFx : MonoBehaviour { public const float HatRevealTime = 1.45f; private Transform lid; private Transform padlock; private Transform hatPivot; private GameObject hat; private Material inside; private Light glow; private Color rarityColor = Color.white; private AudioSource src; private float t; private float hatScale = 1f; private bool clunked; private bool creaked; private bool chimed; private bool padlockFalling; private Vector3 padlockVel; private readonly List<Transform> sparks = new List<Transform>(); private readonly List<Vector3> sparkVel = new List<Vector3>(); private Rarity rarity; public static void Play(Vector3 pos, Quaternion rot, CrateType type, HatKey? key) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("HatHunt_CrateFx"); val.transform.position = pos; val.transform.rotation = rot; CrateFx crateFx = val.AddComponent<CrateFx>(); crateFx.Setup(type, key); } catch (Exception ex) { Plugin.Log.LogWarning((object)("crate fx: " + ex.Message)); } } private void Setup(CrateType type, HatKey? key) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) GameObject val = HatVisuals.BuildCrate(type); val.transform.SetParent(((Component)this).transform, false); val.transform.localScale = Vector3.one * 1.75f; val.transform.localPosition = Vector3.down * (((Object)(object)NetPrefabs.CrateItemProps != (Object)null) ? NetPrefabs.CrateItemProps.verticalOffset : 0f); lid = val.transform.Find("lid"); padlock = val.transform.Find("padlock"); rarity = (key.HasValue ? key.Value.Rarity : Rarity.Common); rarityColor = HatGen.RarityColors[(uint)rarity]; inside = HatVisuals.NewGlowMaterial(rarityColor, 0.01f); HatVisuals.PropPart(val.transform, HatVisuals.CubeMesh, inside, new Vector3(0f, 0.255f, 0f), Quaternion.identity, new Vector3(0.38f, 0.002f, 0.26f)); glow = HatVisuals.CloneLight(((Component)this).transform, new Vector3(0f, 0.6f, 0f), rarityColor, 5f, 0f); if ((Object)(object)glow != (Object)null) { glow.shadows = (LightShadows)0; } hatPivot = new GameObject("hatPivot").transform; hatPivot.SetParent(((Component)this).transform, false); hatPivot.localPosition = new Vector3(0f, 0.25f, 0f); if (key.HasValue) { try { Hat hat = HatGen.Generate(key.Value); this.hat = HatVisuals.Build(hat); this.hat.transform.SetParent(hatPivot, false); hatScale = HatVisuals.ItemScale(hat); this.hat.transform.localScale = Vector3.zero; Light[] componentsInChildren = this.hat.GetComponentsInChildren<Light>(true); foreach (Light val2 in componentsInChildren) { ((Behaviour)val2).enabled = false; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("crate fx hat: " + ex.Message)); } } src = ((Component)this).gameObject.AddComponent<AudioSource>(); src.spatialBlend = 1f; src.rolloffMode = (AudioRolloffMode)1; src.minDistance = 1.5f; src.maxDistance = 28f; src.dopplerLevel = 0f; src.playOnAwake = false; try { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.ship3DAudio != (Object)null) { src.outputAudioMixerGroup = instance.ship3DAudio.outputAudioMixerGroup; } } catch { } src.PlayOneShot(CrateSfx.Click, 0.9f); } private static float EaseOutBack(float x) { return 1f + 2.70158f * Mathf.Pow(x - 1f, 3f) + 1.70158f * Mathf.Pow(x - 1f, 2f); } private void Update() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00e9: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: 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) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_059f: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) t += Time.deltaTime; if ((Object)(object)padlock != (Object)null) { if (t < 0.4f) { padlock.localRotation = Quaternion.Euler(0f, 0f, Mathf.Sin(t * 70f) * 22f * (1f - t / 0.4f)); } else { if (!padlockFalling) { padlockFalling = true; padlockVel = new Vector3(Random.Range(-0.2f, 0.2f), 0.35f, 0.5f); } padlockVel += Vector3.down * 3.5f * Time.deltaTime; Transform obj = padlock; obj.localPosition += padlockVel * Time.deltaTime; Transform obj2 = padlock; obj2.localRotation *= Quaternion.Euler(400f * Time.deltaTime, 0f, 250f * Time.deltaTime); float num = Mathf.Clamp01(1f - (t - 0.6f) / 0.4f); padlock.localScale = Vector3.one * num; } } if (!clunked && t > 0.4f) { clunked = true; src.PlayOneShot(CrateSfx.Clunk, 0.8f); } if (!creaked && t > 0.5f) { creaked = true; src.PlayOneShot(CrateSfx.Creak, 0.75f); } if ((Object)(object)lid != (Object)null && t > 0.55f) { float x = Mathf.Clamp01((t - 0.55f) / 0.45f); lid.localRotation = Quaternion.Euler(-108f * EaseOutBack(x), 0f, 0f); } float num2 = ((!(t >= 0.6f)) ? 0f : ((!(t >= 1f)) ? ((t - 0.6f) / 0.4f) : Mathf.Clamp01(1f - (t - 2.2f) / 1f))); if ((Object)(object)inside != (Object)null && inside.HasProperty("_EmissiveColor")) { inside.SetColor("_EmissiveColor", rarityColor * (6f * num2)); } if ((Object)(object)glow != (Object)null) { HDAdditionalLightData component = ((Component)glow).GetComponent<HDAdditionalLightData>(); float num3 = (300f + 250f * (float)(int)rarity) * num2; if ((Object)(object)component != (Object)null) { component.SetIntensity(num3, (LightUnit)0); } else { glow.intensity = num2 * 2f; } } if (!chimed && t > 0.62f) { chimed = true; src.PlayOneShot(CrateSfx.Chime(rarity), 0.85f); SpawnSparks(8 + 4 * (int)rarity); } for (int num4 = sparks.Count - 1; num4 >= 0; num4--) { Transform val = sparks[num4]; if (!((Object)(object)val == (Object)null)) { sparkVel[num4] += Vector3.down * 2.2f * Time.deltaTime; val.localPosition += sparkVel[num4] * Time.deltaTime; val.localScale *= Mathf.Max(0f, 1f - Time.deltaTime * 1.4f); val.Rotate(300f * Time.deltaTime, 200f * Time.deltaTime, 0f); } } if ((Object)(object)hat != (Object)null) { if (t > 0.7f && t < 1.5f) { float num5 = Mathf.Clamp01((t - 0.7f) / 0.75000006f); float num6 = 1f - (1f - num5) * (1f - num5); hat.transform.localScale = Vector3.one * hatScale * num6; hatPivot.localPosition = new Vector3(0f, 0.25f + 0.45f * num6, 0f); hatPivot.localRotation = Quaternion.Euler(0f, 540f * num6, 0f); } else if (t >= 1.5f) { float num7 = Mathf.Clamp01(1f - (t - 1.45f - 0.05f) / 0.12f); hat.transform.localScale = Vector3.one * hatScale * num7; if (num7 <= 0f) { Object.Destroy((Object)(object)hat); hat = null; } } } if (t > 3f) { ((Component)this).transform.localScale = Vector3.one * Mathf.Clamp01(1f - (t - 3f) / 0.5f); } if (t > 3.6f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { if ((Object)(object)inside != (Object)null) { Object.Destroy((Object)(object)inside); } } private void SpawnSparks(int n) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) Material m = HatVisuals.GlowMaterial(Color.Lerp(rarityColor, Color.white, 0.35f), 8f); for (int i = 0; i < n; i++) { Transform transform = HatVisuals.PropPart(((Component)this).transform, HatVisuals.CubeMesh, m, new Vector3(Random.Range(-0.15f, 0.15f), 0.45f, Random.Range(-0.1f, 0.1f)), Random.rotation, Vector3.one * Random.Range(0.015f, 0.03f)).transform; sparks.Add(transform); sparkVel.Add(new Vector3(Random.Range(-0.7f, 0.7f), Random.Range(1.4f, 2.6f), Random.Range(-0.7f, 0.7f))); } } } public class CrateItem : GrabbableObject { public const float ModelScale = 1.75f; public bool HasType; public CrateType Type; private GameObject model; private bool built; private ScanNodeProperties scan; public override void Start() { ((GrabbableObject)this).Start(); scan = ((Component)this).GetComponentInChildren<ScanNodeProperties>(true); TryResolve(); } private void TryResolve() { if (!HasType && !((Object)(object)((NetworkBehaviour)this).NetworkObject == (Object)null) && ((NetworkBehaviour)this).NetworkObject.IsSpawned && ItemData.ById.TryGetValue(((NetworkBehaviour)this).NetworkObjectId, out var value) && value.Kind == 2) { Type = value.Crate; HasType = true; } } public void SetType(CrateType t) { Type = t; HasType = true; built = false; } public override void Update() { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_0110: Unknown result type (might be due to invalid IL or missing references) ((GrabbableObject)this).Update(); if (!HasType) { TryResolve(); return; } if (((NetworkBehaviour)this).IsServer && (Object)(object)((NetworkBehaviour)this).NetworkObject != (Object)null && ((NetworkBehaviour)this).NetworkObject.IsSpawned && !ItemData.ById.ContainsKey(((NetworkBehaviour)this).NetworkObjectId)) { WorldLoot.Host_Register(this, Type); } if (!built) { built = true; if ((Object)(object)model != (Object)null) { Object.Destroy((Object)(object)model); } try { model = HatVisuals.BuildCrate(Type); model.transform.SetParent(((Component)this).transform, false); model.transform.localPosition = Vector3.down * (((Object)(object)base.itemProperties != (Object)null) ? base.itemProperties.verticalOffset : 0f); model.transform.localScale = Vector3.one * 1.75f; MeshRenderer componentInChildren = model.GetComponentInChildren<MeshRenderer>(); if ((Object)(object)componentInChildren != (Object)null) { base.mainObjectRenderer = componentInChildren; } if ((Object)(object)scan != (Object)null) { scan.headerText = Economy.CrateNames[(uint)Type]; scan.subText = "Locked - use a key on it"; } base.customGrabTooltip = "Grab crate : [E]"; } catch (Exception ex) { Plugin.Log.LogWarning((object)("crate build: " + ex.Message)); } } if ((Object)(object)model != (Object)null && model.activeSelf == base.isPocketed) { model.SetActive(!base.isPocketed); } } public override void SetControlTipsForItem() { try { if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.ChangeControlTipMultiple(new string[1] { "Locked: drop it, then use a key on it" }, true, base.itemProperties); } } catch { ((GrabbableObject)this).SetControlTipsForItem(); } } public override int GetItemDataToSave() { return (int)((!HasType) ? CrateType.Otaku : (Type + 1)); } public override void LoadItemSaveData(int saveData) { ((GrabbableObject)this).LoadItemSaveData(saveData); Type = (CrateType)Mathf.Clamp(saveData - 1, 0, 3); HasType = true; built = false; } } public static class CrateSfx { private static AudioClip click; private static AudioClip clunk; private static AudioClip creak; private static readonly AudioClip[] chimes = (AudioClip[])(object)new AudioClip[5]; private const int Rate = 44100; public static AudioClip Click { get { if ((Object)(object)click == (Object)null) { click = Make("hh_click", 0.18f, (float t) => (Mathf.Sin(t * 2f * (float)Math.PI * 2600f) * Mathf.Exp((0f - t) * 120f) + Noise(t, 9000f) * Mathf.Exp((0f - t) * 80f) * 0.6f + ((!(t <= 0.07f)) ? (Mathf.Sin((t - 0.07f) * 2f * (float)Math.PI * 3400f) * Mathf.Exp((0f - (t - 0.07f)) * 150f)) : 0f)) * 0.5f); } return click; } } public static AudioClip Clunk { get { if ((Object)(object)clunk == (Object)null) { clunk = Make("hh_clunk", 0.3f, (float t) => (Mathf.Sin(t * 2f * (float)Math.PI * (140f - 120f * t)) * 0.8f + Noise(t, 1500f) * 0.4f) * Mathf.Exp((0f - t) * 18f) * 0.8f); } return clunk; } } public static AudioClip Creak { get { if ((Object)(object)creak == (Object)null) { creak = Make("hh_creak", 0.55f, delegate(float t) { float num = 210f + 70f * Mathf.Sin(t * 9f) + 40f * t; float num2 = Mathf.Repeat(t * num, 1f) * 2f - 1f; float num3 = 0.6f + 0.4f * Mathf.Sin(t * 2f * (float)Math.PI * 23f); float num4 = Mathf.Clamp01(t / 0.05f) * Mathf.Clamp01((0.55f - t) / 0.15f); return num2 * num3 * num4 * 0.28f + Noise(t, 700f) * num4 * 0.08f; }); } return creak; } } private static AudioClip Make(string name, float seconds, Func<float, float> wave) { int num = (int)(44100f * seconds); float[] array = new float[num]; for (int i = 0; i < num; i++) { array[i] = Mathf.Clamp(wave((float)i / 44100f), -1f, 1f); } AudioClip val = AudioClip.Create(name, num, 1, 44100, false); val.SetData(array, 0); return val; } private static float Noise(float t, float f) { return Mathf.PerlinNoise(t * f, 0.37f) * 2f - 1f; } public static AudioClip Chime(Rarity r) { int ri = (int)r; if ((Object)(object)chimes[ri] != (Object)null) { return chimes[ri]; } float[] notes = new float[7] { 523.25f, 659.25f, 783.99f, 1046.5f, 1318.5f, 1568f, 2093f }; int count = 2 + ri; float step = 0.09f; float seconds = (float)count * step + 0.9f; chimes[ri] = Make("hh_chime" + ri, seconds, delegate(float t) { float num = 0f; for (int i = 0; i < count; i++) { float num2 = t - (float)i * step; if (num2 < 0f) { break; } float num3 = notes[Mathf.Min(i, notes.Length - 1)]; num += (Mathf.Sin(num2 * 2f * (float)Math.PI * num3) + 0.3f * Mathf.Sin(num2 * 2f * (float)Math.PI * num3 * 2.01f)) * Mathf.Exp((0f - num2) * 4.5f); } if (ri >= 3) { num += Noise(t, 12000f) * 0.25f * Mathf.Exp((0f - t) * 2.5f) * Mathf.Abs(Mathf.Sin(t * 60f)); } return num * 0.22f; }); return chimes[ri]; } } public enum CrateType : byte { Scavenger, Otaku, Wig, Golden } public enum CrownStyle : byte { Straight, Taper, Cone, Dome, Bell, Bulb, Tiered, Pinched, Flared } public struct Decor { public DecorType Type; public Color Color; public float Size; public float Angle; public int Count; public bool IsTop => (int)Type <= 5; public bool Glows => Type == DecorType.Halo || Type == DecorType.Orbiters || Type == DecorType.Flame || Type == DecorType.Antenna; } public enum DecorType : byte { Pompom, Antenna, Propeller, Star, Flame, Tassel, Feathers, Horns, Spikes, Gems, Ears, Bow, Buckle, Flower, Halo, Orbiters, GooglyEyes, Mohawk, Ribbons, BunnyEars, OniHorns, Headphones, BigBow, Ahoge, FoxMask, SweatDrop, AngerMark, Hearts, Sparkles, Crest, Tiara } public static class Economy { public class StoreItem { public HatKey Key; public HatKey? Shown; public int Price; public int ListPrice; public bool Sold; public bool Mystery; public bool Scam; public bool PreOwned; public HatKey Display => Shown.HasValue ? Shown.Value : Key; public bool Discounted => ListPrice > Price; } public enum BoothEvent : byte { None, FlashSale, Mystery, Deal, Haggle } private enum Pending { None, Trade, Open, Buy, Sell } public const int CrateTypeCount = 4; public static readonly string[] CrateNames = new string[4] { "Scavenger Crate", "Otaku Crate", "Wig Crate", "Golden Crate" }; private static readonly string[] CrateHex = new string[4] { "#C9A46B", "#FF7AB8", "#7FD6FF", "#FFD24A" }; private static readonly string[] CrateBlurb = new string[4] { "any hat or wig", "anime-inspired hats only", "wigs and hairstyles only", "Rare or better, guaranteed" }; private static readonly float[][] CrateWeights = new float[4][] { new float[5] { 45f, 30f, 16f, 7f, 2f }, new float[5] { 45f, 30f, 16f, 7f, 2f }, new float[5] { 45f, 30f, 16f, 7f, 2f }, new float[5] { 0f, 0f, 60f, 30f, 10f } }; public static BoothEvent Event = BoothEvent.None; public static int StockDay = -1; public static readonly List<StoreItem> Stock = new List<StoreItem>(); public static int KeyPrice = 60; private static Pending pending = Pending.None; private static float pendingSince; private static List<HatKey> pendingTrade = new List<HatKey>(); private static CrateType pendingCrate; private static readonly HashSet<HatKey> soldThisSession = new HashSet<HatKey>(); public static float LastStockAt = -100f; private static string noticeText; public static string LastResult; public static float LastResultTime; private static Terminal cachedTerminal; private static bool Busy { get { if (pending != Pending.None && Time.time - pendingSince > 10f) { pending = Pending.None; } return pending != Pending.None; } } public static bool IsBusy => Busy; public static void ResetSession() { soldThisSession.Clear(); StockDay = -1; Stock.Clear(); Event = BoothEvent.None; Vendors.Current = VendorId.Coat; pending = Pending.None; pendingTrade.Clear(); } private static void SetPending(Pending p) { pending = p; pendingSince = Time.time; } private static string Hex(Rarity r) { return HatGen.RarityHex(r); } private static string Tag(Rarity r) { return "<color=" + Hex(r) + ">" + r.ToString().ToUpper() + "</color>"; } public static bool AtCompany() { StartOfRound instance = StartOfRound.Instance; return !((Object)(object)instance == (Object)null) && !((Object)(object)instance.currentLevel == (Object)null) && (instance.currentLevel.sceneName == "CompanyBuilding" || instance.currentLevel.levelID == 3); } public static bool CanShop() { return AtCompany() || Encounters.VendorActive; } public static string EventTitle(BoothEvent e) { return e switch { BoothEvent.FlashSale => "FLASH SALE", BoothEvent.Mystery => "MYSTERY ITEM", BoothEvent.Deal => "DEAL OF THE CENTURY", BoothEvent.Haggle => "GOOD MOOD: 20% OFF", _ => null, }; } public static string EventColor(BoothEvent e) { return e switch { BoothEvent.FlashSale => "#FF5A4A", BoothEvent.Mystery => "#C58BFF", BoothEvent.Deal => "#FFB020", BoothEvent.Haggle => "#6CFF8E", _ => "#FFFFFF", }; } private static int CurrentDay() { StartOfRound instance = StartOfRound.Instance; return ((Object)(object)instance != (Object)null && instance.gameStats != null) ? instance.gameStats.daysSpent : 0; } private static Terminal FindTerminal() { return Object.FindObjectOfType<Terminal>(); } public static float[] Weights(CrateType t) { return CrateWeights[(uint)t]; } public static Func<Hat, bool> ThemeFilter(CrateType t) { return t switch { CrateType.Otaku => (Hat h) => h.Design.Anime != AnimeBase.None, CrateType.Wig => (Hat h) => h.Design.Wig != WigStyle.None, _ => null, }; } public static bool Host_TryDropExtra(int playerIdx, GrabbableObject item) { Random rng = HatManager.Instance.Rng; double num = rng.NextDouble() * 100.0; double num2 = Mathf.Max(0f, Plugin.CfgDropKey.Value); double num3 = Mathf.Max(0f, Plugin.CfgDropCrate.Value); if (num < num2) { Host_Grant(playerIdx, 0, 0, 1, 0); return true; } if (num < num2 + num3) { double num4 = rng.NextDouble() * 100.0; CrateType crate = ((!(num4 >= 5.0)) ? CrateType.Golden : ((!(num4 >= 25.0)) ? CrateType.Otaku : ((!(num4 >= 45.0)) ? CrateType.Wig : CrateType.Scavenger))); Host_Grant(playerIdx, 1, (byte)crate, 1, 0); return true; } return false; } private static void Host_Grant(int playerIdx, byte kind, byte crate, int count, byte how) { HatNet.ToAll("HatHunt.Grant", HatNet.Build(delegate(BinaryWriter w) { w.Write(playerIdx); w.Write(kind); w.Write(crate); w.Write(count); w.Write(how); })); } private static void Host_Notice(ulong client, string text) { HatNet.ToClient("HatHunt.Notice", client, HatNet.Build(delegate(BinaryWriter w) { w.Write(text); })); } public static void Host_OnTrade(ulong sender, byte[] data) { if (!HatNet.IsHost) { return; } List<HatKey> list = new List<HatKey>(); using (BinaryReader binaryReader = HatNet.Reader(data)) { int num = binaryReader.ReadInt32(); for (int i = 0; i < num && i < 20; i++) { HatKey? hatKey = HatNet.ReadKey(binaryReader); if (hatKey.HasValue) { list.Add(hatKey.Value); } } } int num2 = Mathf.Max(2, Plugin.CfgTradeCount.Value); int num3 = HatManager.PlayerIndexOf(sender); if (num3 < 0) { return; } if (list.Count != num2 || list.Distinct().Count() != num2) { Host_Notice(sender, "Trade-up needs exactly " + num2 + " different hats."); return; } Rarity rarity = list[0].Rarity; if (list.Any((HatKey k) => k.Rarity != rarity)) { Host_Notice(sender, "All hats in a trade-up must be the same rarity."); return; } if (rarity == Rarity.Legendary) { Host_Notice(sender, "Legendary is already the top rarity."); return; } List<Hat> source = list.Select((HatKey k) => HatGen.Generate(k)).ToList(); Func<Hat, bool> filter = null; if (source.Count((Hat h) => h.Design.Anime != AnimeBase.None) * 2 > num2) { filter = ThemeFilter(CrateType.Otaku); } else if (source.Count((Hat h) => h.Design.Wig != WigStyle.None) * 2 > num2) { filter = ThemeFilter(CrateType.Wig); } HatKey key = Registry.CreateUnique(HatManager.Instance.Rng, rarity + 1, filter); HatManager.Instance.Host_GiveHat(num3, key, FoundReason.TradeUp, ""); } public static void Host_OnOpen(ulong sender, byte[] data) { if (HatNet.IsHost) { CrateType crateType; using (BinaryReader binaryReader = HatNet.Reader(data)) { crateType = (CrateType)Mathf.Clamp((int)binaryReader.ReadByte(), 0, 3); } int num = HatManager.PlayerIndexOf(sender); if (num >= 0) { Random rng = HatManager.Instance.Rng; Rarity rarity = HatGen.RollRarity(rng, CrateWeights[(uint)crateType], HatManager.Instance.FortuneOf(num)); HatKey key = Registry.CreateUnique(rng, rarity, ThemeFilter(crateType)); HatManager.Instance.Host_GiveHat(num, key, FoundReason.Crate, CrateNames[(uint)crateType]); } } } public static void Host_PrepareStock() { if (HatNet.IsHost && !((Object)(object)HatManager.Instance == (Object)null) && Host_EnsureStock()) { HatNet.ToAll("HatHunt.Stock", StockPayload()); } } private static bool Host_EnsureStock() { int num = CurrentDay(); if (StockDay == num && Stock.Count > 0) { return false; } StockDay = num; Stock.Clear(); Event = BoothEvent.None; Random rng = HatManager.Instance.Rng; Vendors.Current = Vendors.HostPick(rng); VendorDef def = Vendors.Def; KeyPrice = Mathf.Max(1, Mathf.RoundToInt((float)Mathf.Max(1, Plugin.CfgKeyPrice.Value) * def.KeyMul)); int num2 = Mathf.Clamp(Plugin.CfgStoreSize.Value + def.ExtraStock, 1, 12); for (int i = 0; i < num2; i++) { Rarity rarity = HatGen.RollRarity(rng, def.Weights, 0f); Func<Hat, bool> filter; if (def.AnimeShare <= 0f && def.WigShare <= 0f) { filter = i switch { 1 => ThemeFilter(CrateType.Wig), 0 => ThemeFilter(CrateType.Otaku), _ => null, }; } else { double num3 = rng.NextDouble(); filter = ((!(num3 >= (double)def.AnimeShare)) ? ThemeFilter(CrateType.Otaku) : ((!(num3 >= (double)(def.AnimeShare + def.WigShare))) ? ThemeFilter(CrateType.Wig) : null)); } HatKey hatKey = Registry.CreateUnique(rng, rarity, filter); int num4 = VendorPrice(hatKey, rng); Stock.Add(new StoreItem { Key = hatKey, Price = num4, ListPrice = num4 }); } Stock.Sort((StoreItem a, StoreItem b) => a.Key.Rarity.CompareTo(b.Key.Rarity)); if (Plugin.CfgBoothEvents.Value || def.MysteryBias >= 1f) { Host_RollEvent(rng, def); } Plugin.Log.LogInfo((object)string.Concat("HatHunt: ", def.Name, " runs the booth on day ", num, " (", Stock.Count, " items, event ", Event, ")")); return true; } private static int Round5(float v) { return Mathf.Max(5, Mathf.RoundToInt(v / 5f) * 5); } private static int VendorPrice(HatKey k, Random rng) { VendorDef def = Vendors.Def; float num = 1f - def.PriceSpread * 0.5f + (float)rng.NextDouble() * def.PriceSpread; int[] array = new int[5] { Plugin.CfgPriceCommon.Value, Plugin.CfgPriceUncommon.Value, Plugin.CfgPriceRare.Value, Plugin.CfgPriceEpic.Value, Plugin.CfgPriceLegendary.Value }; return Mathf.Max(1, Mathf.RoundToInt((float)array[(uint)k.Rarity] * def.PriceMul * num / 5f) * 5); } private static void Host_RollEvent(Random rng, VendorDef v) { bool flag = false; if (v.MysteryBias >= 1f) { Host_AddMystery(rng, new float[5] { 0f, 0f, 38f, 38f, 24f }); flag = true; if (!Plugin.CfgBoothEvents.Value || rng.NextDouble() < 0.5) { return; } } double num = rng.NextDouble(); if (num < 1.0 - (double)v.EventChance) { return; } num = rng.NextDouble(); double num2 = 0.33; double num3 = 0.27 + (double)v.MysteryBias; double num4 = 0.2; double num5 = 0.2 + (double)v.HaggleBias; if (flag) { num3 = 0.0; } double num6 = num2 + num3 + num4 + num5; num *= num6; if (num < num2) { Event = BoothEvent.FlashSale; StoreItem storeItem = Stock[rng.Next(Stock.Count)]; storeItem.Price = Round5((float)storeItem.ListPrice * 0.5f); return; } if (num < num2 + num3) { Host_AddMystery(rng, new float[5] { 0f, 0f, 55f, 33f, 12f }); return; } if (num < num2 + num3 + num4) { Event = BoothEvent.Deal; int num7 = Mathf.Max(5, Mathf.RoundToInt((float)Plugin.CfgPriceLegendary.Value * v.PriceMul)); StoreItem storeItem2 = new StoreItem(); storeItem2.Price = Round5((float)num7 * 0.55f); storeItem2.ListPrice = num7; StoreItem storeItem3 = storeItem2; if (rng.NextDouble() < (double)v.DealReal) { storeItem3.Key = Registry.CreateUnique(rng, Rarity.Legendary); } else { storeItem3.Scam = true; storeItem3.Key = Registry.CreateUnique(rng, (rng.NextDouble() >= 0.7) ? Rarity.Uncommon : Rarity.Common); storeItem3.Shown = new HatKey(rng.Next(int.MinValue, int.MaxValue), Rarity.Legendary, Registry.NextSerial + rng.Next(0, 3)); } Stock.Add(storeItem3); return; } Event = BoothEvent.Haggle; foreach (StoreItem item in Stock) { item.Price = Round5((float)item.ListPrice * 0.8f); } } private static void Host_AddMystery(Random rng, float[] weights) { Event = BoothEvent.Mystery; Rarity rarity = HatGen.RollRarity(rng, weights, 0f); HatKey key = Registry.CreateUnique(rng, rarity); int num = Round5((240f + (float)rng.NextDouble() * 60f) * Vendors.Def.PriceMul); Stock.Add(new StoreItem { Key = key, Price = num, ListPrice = num, Mystery = true }); } private static int PriceOf(HatKey k, Random rng) { int[] array = new int[5] { Plugin.CfgPriceCommon.Value, Plugin.CfgPriceUncommon.Value, Plugin.CfgPriceRare.Value, Plugin.CfgPriceEpic.Value, Plugin.CfgPriceLegendary.Value }; float num = 0.85f + (float)rng.NextDouble() * 0.3f; return Mathf.Max(1, Mathf.RoundToInt((float)array[(uint)k.Rarity] * num / 5f) * 5); } private static byte[] StockPayload() { return HatNet.Build(delegate(BinaryWriter w) { w.Write(StockDay); w.Write(KeyPrice); w.Write((byte)Event); w.Write(Stock.Count); foreach (StoreItem item in Stock) { if (item.Mystery) { HatNet.WriteKey(w, null); } else { HatNet.WriteKey(w, item.Display); } w.Write(item.Price); w.Write(item.ListPrice); w.Write(item.Sold); w.Write(item.Mystery); w.Write(item.PreOwned); } w.Write((byte)Vendors.Current); }); } public static void Host_SendStock(ulong client) { if (HatNet.IsHost) { Host_EnsureStock(); HatNet.ToClient("HatHunt.Stock", client, StockPayload()); } } public static void Host_OnBuy(ulong sender, byte[] data) { //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: 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_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) if (!HatNet.IsHost) { return; } Vector3? val = null; HatKey? hatKey = null; int num; int num2; using (BinaryReader binaryReader = HatNet.Reader(data)) { num = binaryReader.ReadInt32(); num2 = binaryReader.ReadInt32(); if (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length && binaryReader.ReadBoolean()) { val = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); } if (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) { hatKey = HatNet.ReadKey(binaryReader); } } int idx = HatManager.PlayerIndexOf(sender); if (idx < 0) { return; } if (!CanShop()) { Host_Notice(sender, "The booth is only open at the Company."); return; } Host_EnsureStock(); Terminal val2 = FindTerminal(); if ((Object)(object)val2 == (Object)null) { Host_Notice(sender, "Terminal not found."); return; } int num3; if (num < 0) { num2 = Mathf.Clamp(num2, 1, 20); num3 = KeyPrice * num2; } else { if (num >= Stock.Count) { Host_Notice(sender, "No such store item."); return; } if (Stock[num].Sold) { Host_Notice(sender, "Sorry, that one just sold."); HatNet.ToAll("HatHunt.Stock", StockPayload()); return; } if (hatKey.HasValue && !Stock[num].Mystery && !Stock[num].Display.Equals(hatKey.Value)) { Host_Notice(sender, "The stock just changed - take another look."); HatNet.ToAll("HatHunt.Stock", StockPayload()); return; } num3 = Stock[num].Price; } if (val2.groupCredits < num3) { Host_Notice(sender, "Not enough credits (" + num3 + " needed, you have " + val2.groupCredits + ")."); return; } val2.groupCredits -= num3; try { val2.SyncGroupCreditsClientRpc(val2.groupCredits, val2.numberOfItemsInDropship); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Credit sync failed: " + ex.Message)); } Vector3 pos = WorldLoot.BoothDropPoint(idx); PlayerControllerB val3 = (((Object)(object)StartOfRound.Instance != (Object)null && idx < StartOfRound.Instance.allPlayerScripts.Length) ? StartOfRound.Instance.allPlayerScripts[idx] : null); if (val.HasValue && (Object)(object)val3 != (Object)null) { Vector3 val4 = val.Value - ((Component)val3).transform.position; if (((Vector3)(ref val4)).sqrMagnitude < 64f) { pos = val.Value; } } if (num < 0) { if (!((Object)(object)WorldLoot.Host_SpawnVanillaKey(pos, inFactory: false) != (Object)null)) { Host_Grant(idx, 0, 0, 1, 1); } HatNet.ToAll("HatHunt.Chat", HatNet.Build(delegate(BinaryWriter w) { w.Write("<color=#FFD54A>" + HatManager.PlayerName(idx) + "</color> bought a key from " + Vendors.Def.Name + "."); })); HatNet.ToClient("HatHunt.Notice", sender, HatNet.Build(delegate(BinaryWriter w) { w.Write(Vendors.Def.Name + " slides a key across the counter."); })); return; } StoreItem storeItem = Stock[num]; storeItem.Sold = true; if (storeItem.PreOwned) { soldThisSession.Remove(storeItem.Key); } HatKey key = storeItem.Key; Hat hat = HatGen.Generate(key); string text = "<color=#FFD54A>" + HatManager.PlayerName(idx) + "</color>"; string text2 = string.Concat("<color=", HatGen.RarityHex(key.Rarity), ">[", key.Rarity, "]</color> ", hat.RichName()); bool flag = (Object)(object)WorldLoot.Host_SpawnHat(key, pos, inFactory: false) != (Object)null; if (!flag) { HatManager.Instance.Host_GiveHat(idx, key, FoundReason.Store, ""); } string chat; string notice; if (storeItem.Scam) { chat = text + " bought the 'Legendary' deal of the century... it's a " + text2 + ". " + Vendors.Def.Name + " won't make eye contact."; notice = "Wait... that's not the hat that was on the counter. No refunds."; } else if (storeItem.Mystery) { chat = text + " unwrapped " + Vendors.Def.Name + "'s mystery hat: " + text2 + "!"; notice = "You pull the tarp off: " + text2 + ". It's in front of the booth."; } else { chat = text + " bought a " + text2 + " from " + Vendors.Def.Name + "."; notice = "Sold. It's on the ground in front of the booth - pick it up and put it on."; } if (flag) { HatNet.ToAll("HatHunt.Chat", HatNet.Build(delegate(BinaryWriter w) { w.Write(chat); })); HatNet.ToClient("HatHunt.Notice", sender, HatNet.Build(delegate(BinaryWriter w) { w.Write(notice); })); } HatNet.ToAll("HatHunt.Stock", StockPayload()); } public static int SellPrice(HatKey k) { int[] array = new int[5] { Plugin.CfgPriceCommon.Value, Plugin.CfgPriceUncommon.Value, Plugin.CfgPriceRare.Value, Plugin.CfgPriceEpic.Value, Plugin.CfgPriceLegendary.Value }; float num = 0.9f + 0.2f * ((float)(k.Seed & 0xFFFF) / 65535f); return Round5((float)array[(uint)k.Rarity] * Vendors.Def.SellMul * num); } public static void Host_OnSell(ulong sender, byte[] data) { if (!HatNet.IsHost) { return; } HatKey? hatKey; using (BinaryReader r = HatNet.Reader(data)) { hatKey = HatNet.ReadKey(r); } int num = HatManager.PlayerIndexOf(sender); if (!hatKey.HasValue || num < 0) { return; } if (!CanShop()) { Host_Notice(sender, "The booth is only open at the Company."); return; } HatKey k = hatKey.Value; if (soldThisSession.Contains(k)) { Host_Notice(sender, "\"You already sold me that one.\""); return; } Terminal val = FindTerminal(); if ((Object)(object)val == (Object)null) { Host_Notice(sender, "Terminal not found."); return; } Host_EnsureStock(); soldThisSession.Add(k); int price = SellPrice(k); val.groupCredits += price; try { val.SyncGroupCreditsClientRpc(val.groupCredits, val.numberOfItemsInDropship); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Credit sync failed: " + ex.Message)); } Random rng = HatManager.Instance.Rng; int num2 = 0; for (int num3 = Stock.Count - 1; num3 >= 0; num3--) { if (Stock[num3].PreOwned && !Stock[num3].Sold && ++num2 >= 6) { Stock.RemoveAt(num3); } } int num4 = VendorPrice(k, rng); Stock.Add(new StoreItem { Key = k, Price = num4, ListPrice = num4, PreOwned = true }); HatNet.ToAll("HatHunt.Stock", StockPayload()); Hat hat = HatGen.Generate(k); string who = "<color=#FFD54A>" + HatManager.PlayerName(num) + "</color>"; HatNet.ToAll("HatHunt.Chat", HatNet.Build(delegate(BinaryWriter w) { w.Write(string.Concat(who, " sold a <color=", HatGen.RarityHex(k.Rarity), ">[", k.Rarity, "]</color> ", hat.RichName(), " to ", Vendors.Def.Name, " for $", price, ".")); })); HatNet.ToClient("HatHunt.SellOk", sender, HatNet.Build(delegate(BinaryWriter w) { HatNet.WriteKey(w, k); w.Write(price); })); } public static string RequestSell(HatKey k) { if (Busy) { return "Hang on... (waiting for the host)"; } if (!HatNet.Online) { return "You need to be in a lobby."; } if (!CanShop()) { return "The booth only trades at the Company."; } if (!Collection.Hats.Contains(k)) { return "You don't have that hat any more."; } SetPending(Pending.Sell); HatNet.ToHost("HatHunt.Sell", HatNet.Build(delegate(BinaryWriter w) { HatNet.WriteKey(w, k); })); return null; } public static void Client_OnSellOk(byte[] data) { HatKey? hatKey; int num; using (BinaryReader binaryReader = HatNet.Reader(data)) { hatKey = HatNet.ReadKey(binaryReader); num = binaryReader.ReadInt32(); } if (pending == Pending.Sell) { pending = Pending.None; } if (hatKey.HasValue) { Hat hat = HatGen.Generate(hatKey.Value); bool flag = Collection.Equipped.HasValue && Collection.Equipped.Value.Equals(hatKey.Value); List<HatKey> list = new List<HatKey>(); list.Add(hatKey.Value); Collection.RemoveAll(list); if ((Object)(object)HatManager.Instance != (Object)null) { HatManager.Instance.Equip(Collection.EquippedIndex); } string text = "Sold " + hat.RichName() + " for <color=#FFD54A>$" + num + "</color>." + (flag ? " (You were wearing it.)" : ""); if (ShopWindow.IsOpen) { ShopWindow.OnNotice(text); } else { HatInteraction.Flash(text, 3f); } RefreshTerminalIfOpen(); } } public static void Client_OnStock(byte[] data) { LastStockAt = Time.time; if (HatNet.IsHost) { RefreshTerminalIfOpen(); return; } using (BinaryReader binaryReader = HatNet.Reader(data)) { StockDay = binaryReader.ReadInt32(); KeyPrice = binaryReader.ReadInt32(); Event = (BoothEvent)binaryReader.ReadByte(); int num = binaryReader.ReadInt32(); Stock.Clear(); for (int i = 0; i < num; i++) { HatKey? hatKey = HatNet.ReadKey(binaryReader); int price = binaryReader.ReadInt32(); int listPrice = binaryReader.ReadInt32(); bool sold = binaryReader.ReadBoolean(); bool flag = binaryReader.ReadBoolean(); bool preOwned = binaryReader.ReadBoolean(); if (hatKey.HasValue || flag) { Stock.Add(new StoreItem { Key = (hatKey.HasValue ? hatKey.Value : default(HatKey)), Price = price, ListPrice = listPrice, Sold = sold, Mystery = flag, PreOwned = preOwned }); } } if (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) { int num2 = binaryReader.ReadByte(); if (num2 < Vendors.All.Length) { Vendors.Current = (VendorId)num2; } } } RefreshTerminalIfOpen(); } public static void Client_OnGrant(byte[] data) { int idx; byte b; int num; byte b3; byte b2; using (BinaryReader binaryReader = HatNet.Reader(data)) { idx = binaryReader.ReadInt32(); b = binaryReader.ReadByte(); b2 = binaryReader.ReadByte(); num = binaryReader.ReadInt32(); b3 = binaryReader.ReadByte(); } b2 = (byte)Mathf.Clamp((int)b2, 0, 3); string text = ((b != 0) ? ("a <color=" + CrateHex[b2] + ">" + CrateNames[b2] + "</color>") : ((num > 1) ? (num + " Hat Keys") : "a Hat Key")); HatManager.ChatPublic("<color=#FFD54A>" + HatManager.PlayerName(idx) + "</color> " + ((b3 == 1) ? "bought " : "found ") + text + "!"); if (!HatManager.IsLocalIndex(idx)) { return; } if (b == 0) { Collection.Keys += num; if (b3 == 1 && pending == Pending.Buy) { pending = Pending.None; } HatManager.TipPublic((b3 == 1) ? "Purchased!" : "You found a Hat Key!", "Keys: " + Collection.Keys + "\nUse it at the terminal: hats open"); } else { Collection.Crates[b2] += num; HatManager.TipPublic("You found a " + CrateNames[b2] + "!", "Contains " + CrateBlurb[b2] + ".\nNeeds a Hat Key. Terminal: hats crates"); } Collection.Save(); HatManager.PlayJingle(); RefreshTerminalIfOpen(); } public static void Client_OnNotice(byte[] data) { string text; using (BinaryReader binaryReader = HatNet.Reader(data)) { text = binaryReader.ReadString(); } pending = Pending.None; pendingTrade.Clear(); if (ShopWindow.IsOpen) { ShopWindow.OnNotice(text); } else { HatManager.TipPublic("Hat Hunt", text); HatInteraction.Flash(text, 3f); } LastResult = "<color=#FF7B7B>" + text + "</color>"; LastResultTime = Time.time; RefreshTerminalIfOpen(); } public static void OnLocalHatResult(FoundReason reason) { if (reason == FoundReason.TradeUp && pending == Pending.Trade) { Collection.RemoveAll(pendingTrade); pendingTrade.Clear(); pending = Pending.None; HatManager.Instance.Equip(Collection.EquippedIndex); } else if (reason == FoundReason.Crate && pending == Pending.Open) { Collection.Keys = Math.Max(0, Collection.Keys - 1); Collection.Crates[(uint)pendingCrate] = Math.Max(0, Collection.Crates[(uint)pendingCrate] - 1); Collection.Save(); pending = Pending.None; } else if (reason == FoundReason.Store && pending == Pending.Buy) { pending = Pending.None; } } public static void RefreshTerminalIfOpen() { TerminalMenu.Redraw(); } public static string RequestTrade(List<HatKey> chosen) { int num = Mathf.Max(2, Plugin.CfgTradeCount.Value); if (Busy) { return "Waiting for the host to answer your last request..."; } if (!HatNet.Online) { return "You need to be in a lobby."; } if (chosen.Count != num) { return "Pick exactly " + num + " hats."; } Rarity rarity = chosen[0].Rarity; if (chosen.Any((HatKey k) => k.Rarity != rarity)) { return "All hats must be the same rarity."; } if (rarity == Rarity.Legendary) { return "Legendary is already the top rarity."; } pendingTrade = new List<HatKey>(chosen); SetPending(Pending.Trade); HatNet.ToHost("HatHunt.Trade", HatNet.Build(delegate(BinaryWriter w) { w.Write(chosen.Count); foreach (HatKey item in chosen) { HatNet.WriteKey(w, item); } })); return null; } public static List<HatKey> AutoPick(Rarity r) { int num = Mathf.Max(2, Plugin.CfgTradeCount.Value); List<HatKey> list = new List<HatKey>(); for (int i = 0; i < Collection.Hats.Count; i++) { if (list.Count >= num) { break; } if (Collection.Hats[i].Rarity == r && i != Collection.EquippedIndex) { list.Add(Collection.Hats[i]); } } return list; } public static string RequestOpen(CrateType t) { if (Busy) { return "Waiting for the host to answer your last request..."; } if (!HatNet.Online) { return "You need to be in a lobby."; } if (Collection.Crates[(uint)t] <= 0) { return "You don't have a " + CrateNames[(uint)t] + "."; } if (Collection.Keys <= 0) { return "You need a Hat Key. Buy one at the shady booth at the Company."; } pendingCrate = t; SetPending(Pending.Open); HatNet.ToHost("HatHunt.Open", HatNet.Build(delegate(BinaryWriter w) { w.Write((byte)t); })); return null; } public static string RequestBuy(int slot) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if (Busy) { return "Hang on... (waiting for the host)"; } if (!HatNet.Online) { return "You need to be in a lobby."; } if (!CanShop()) { return "The booth only trades at the Company."; } if (slot >= 0 && (slot >= Stock.Count || Stock[slot].Sold)) { return "Sold out."; } int num = ((slot < 0) ? KeyPrice : Stock[slot].Price); int num2 = Credits(); if (num2 >= 0 && num2 < num) { return "Not enough credits."; } SetPending(Pending.Buy); Vector3? drop = null; if ((Object)(object)HatBooth.Instance != (Object)null) { drop = ((Component)HatBooth.Instance).transform.TransformPoint(new Vector3(Random.Range(-0.4f, 0.4f), 0.4f, 1.15f)); } HatNet.ToHost("HatHunt.Buy", HatNet.Build(delegate(BinaryWriter w) { //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_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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) w.Write(slot); w.Write(1); w.Write(drop.HasValue); if (drop.HasValue) { w.Write(drop.Value.x); w.Write(drop.Value.y); w.Write(drop.Value.z); } HatNet.WriteKey(w, (slot >= 0 && !Stock[slot].Mystery) ? new HatKey?(Stock[slot].Display) : ((HatKey?)null)); })); return null; } public static int Credits() { if ((Object)(object)cachedTerminal == (Object)null) { cachedTerminal = FindTerminal(); } return ((Object)(object)cachedTerminal != (Object)null) ? cachedTerminal.groupCredits : (-1); } public static string CrateName(int i) { return "<color=" + CrateHex[i] + ">" + CrateNames[i] + "</color>"; } public static string CrateInfo(int i) { return CrateBlurb[i]; } public static string RarityTag(Rarity r) { return Tag(r); } } public enum EffectType : byte { Swiftness, Springy, Endurance, SecondWind, Toughness, Featherfall, Regeneration, LongReach, Climber, Fortune, Lantern, Sluggish, Heavy, Wheezy, Fragile } public static class Encounters { private class Runaway { public HatItem Item; public int Hops; public float CalmUntil; public bool Announced; } public static bool VendorActive; private static int vendorLevel = -1; private static Vector3 vendorPos; private static float vendorYaw; private static int lastLandingKey = int.MinValue; private static bool landedHandled; private static Vector3? pendingGuardAt; private static string pendingRumour; private static float nextRunawayCheck; private static readonly List<Runaway> runaways = new List<Runaway>(); private const byte EvVendor = 1; private const byte EvFlash = 2; private const byte EvCrateFx = 3; private static Random Rng => HatManager.Instance.Rng; public static void ResetSession() { VendorActive = false; vendorLevel = -1; lastLandingKey = int.MinValue; landedHandled = false; pendingGuardAt = null; pendingRumour = null; runaways.Clear(); } public static void Tick() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return; } if (VendorActive && (instance.inShipPhase || (Object)(object)instance.currentLevel == (Object)null || instance.currentLevel.levelID != vendorLevel)) { VendorActive = false; } if (!HatNet.IsHost) { return; } if (instance.inShipPhase || !instance.shipHasLanded || (Object)(object)instance.currentLevel == (Object)null) { landedHandled = false; return; } int num = instance.randomMapSeed * 31 + instance.currentLevel.levelID; if (num != lastLandingKey || !landedHandled) { lastLandingKey = num; landedHandled = true; Host_OnLanded(instance); } } public static void FastTick() { if (!HatNet.IsHost || runaways.Count == 0 || Time.time < nextRunawayCheck) { return; } nextRunawayCheck = Time.time + 0.1f; try { Host_CheckRunaways(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("runaway hat: " + ex.Message)); } } private static void Host_OnLanded(StartOfRound sor) { //IL_0053: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (!Economy.AtCompany() && Rng.NextDouble() * 100.0 < (double)Plugin.CfgVendorChance.Value) { if (FindVendorSpot(sor, out var pos, out var yaw)) { VendorActive = true; vendorLevel = sor.currentLevel.levelID; vendorPos = pos; vendorYaw = yaw; Economy.Host_PrepareStock(); HatNet.ToAll("HatHunt.Encounter", VendorPayload()); HatNet.ToAll("HatHunt.Chat", HatNet.Build(delegate(BinaryWriter w) { w.Write("<color=#FFD54A>Psst...</color> <color=" + Vendors.Def.Hex + ">" + Vendors.Def.Name + "</color> set up a booth outside, not far from the ship. Hats & keys, credits only."); })); Plugin.Log.LogInfo((object)("HatHunt: the vendor set up shop at " + pos)); } } else if (VendorActive) { VendorActive = false; HatNet.ToAll("HatHunt.Encounter", VendorPayload()); } if (pendingRumour != null) { string r = pendingRumour; HatNet.ToAll("HatHunt.Chat", HatNet.Build(delegate(BinaryWriter w) { w.Write(r); })); pendingRumour = null; } if (pendingGuardAt.HasValue) { try { Host_SpawnGuard(pendingGuardAt.Value); } catch (Exception ex) { Plugin.Log.LogWarning((object)("stash guard: " + ex.Message)); } pendingGuardAt = null; } } private static byte[] VendorPayload() { return HatNet.Build(delegate(BinaryWriter w) { w.Write(1); w.Write(VendorActive); w.Write(vendorLevel); w.Write(vendorPos.x); w.Write(vendorPos.y); w.Write(vendorPos.z); w.Write(vendorYaw); }); } public static void Host_CrateFx(Vector3 p, Quaternion q, CrateType t, HatKey key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) HatNet.ToAll("HatHunt.Encounter", HatNet.Build(delegate(BinaryWriter w) { w.Write(3); w.Write(p.x); w.Write(p.y); w.Write(p.z); w.Write(q.x); w.Write(q.y); w.Write(q.z); w.Write(q.w); w.Write((byte)t); HatNet.WriteKey(w, key); })); } public static void Host_SyncTo(ulong client) { if (HatNet.IsHost && VendorActive) { HatNet.ToClient("HatHunt.Encounter", client, VendorPayload()); } } private static bool FindVendorSpot(StartOfRound sor, out Vector3 pos, out float yaw) { //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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017b: 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_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: 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_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: 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_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: 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_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) pos = Vector3.zero; yaw = 0f; RoundManager instance = RoundManager.Instance; GameObject[] array = (((Object)(object)instance != (Object)null && instance.outsideAINodes != null && instance.outsideAINodes.Length > 0) ? instance.outsideAINodes : GameObject.FindGameObjectsWithTag("OutsideAINode")); if (array == null || array.Length == 0) { return false; } Vector3 position = sor.elevatorTransform.position; int num = LayerMask.NameToLayer("Player"); int num2 = sor.collidersAndRoomMaskAndDefault & -5 & ~((num >= 0) ? (1 << num) : 0); List<GameObject> list = new List<GameObject>(array); for (int num3 = list.Count - 1; num3 > 0; num3--) { int index = Rng.Next(num3 + 1); GameObject value = list[num3]; list[num3] = list[index]; list[index] = value; } RaycastHit val = default(RaycastHit); RaycastHit val7 = default(RaycastHit); foreach (GameObject item in list) { if ((Object)(object)item == (Object)null) { continue; } Vector3 position2 = item.transform.position; float num4 = Vector3.Distance(new Vector3(position2.x, 0f, position2.z), new Vector3(position.x, 0f, position.z)); if (!(num4 >= 14f) || !(num4 <= 48f) || !Physics.Raycast(position2 + Vector3.up * 6f, Vector3.down, ref val, 14f, num2, (QueryTriggerInteraction)1) || !(((RaycastHit)(ref val)).normal.y >= 0.88f)) { continue; } Vector3 point = ((RaycastHit)(ref val)).point; Vector3 val2 = position - point; val2.y = 0f; if (!(((Vector3)(ref val2)).sqrMagnitude >= 0.01f)) { continue; } Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up); if (Physics.CheckBox(point + val3 * HatBooth.CheckCenter, HatBooth.CheckExtents, val3, num2, (QueryTriggerInteraction)1)) { continue; } bool flag = true; Vector3[] array2 = (Vector3[])(object)new Vector3[4] { new Vector3(-2.4f, 0f, -0.85f), new Vector3(2.4f, 0f, -0.85f), new Vector3(-2.4f, 0f, 1.25f), new Vector3(2.4f, 0f, 1.25f) }; foreach (Vector3 val4 in array2) { Vector3 val5 = val4 * (HatBooth.Scale / 1.4f); Vector3 val6 = point + val3 * val5; if (!Physics.Raycast(val6 + Vector3.up * 1.5f, Vector3.down, ref val7, 3f, num2, (QueryTriggerInteraction)1) || Mathf.Abs(((RaycastHit)(ref val7)).point.y - point.y) > 0.45f) { flag = false; break; } } if (flag) { pos = point; yaw = ((Quaternion)(ref val3)).eulerAngles.y; return true; } } return false; } public static bool VendorHere(out Scene scene, out Vector3 pos, out Quaternion rot) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //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) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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) scene = default(Scene); pos = vendorPos; rot = Quaternion.Euler(0f, vendorYaw, 0f); StartOfRound instance = StartOfRound.Instance; if (!VendorActive || (Object)(object)instance == (Object)null || (Object)(object)instance.currentLevel == (Object)null || instance.inShipPhase || instance.currentLevel.levelID != vendorLevel) { return false; } scene = SceneManager.GetSceneByName(instance.currentLevel.sceneName); return ((Scene)(ref scene)).IsValid() && ((Scene)(ref scene)).isLoaded; } public static void Client_OnEncounter(byte[] data) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = HatNet.Reader(data); switch (binaryReader.ReadByte()) { case 1: { bool vendorActive = binaryReader.ReadBoolean(); int num = binaryReader.ReadInt32(); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); float num2 = binaryReader.ReadSingle(); if (!HatNet.IsHost) { VendorActive = vendorActive; vendorLevel = num; vendorPos = val; vendorYaw = num2; } break; } case 2: { string text = binaryReader.ReadString(); HatInteraction.Flash(text, 3f); break; } case 3: { Vector3 pos = default(Vector3); ((Vector3)(ref pos))..ctor(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); Quaternion rot = default(Quaternion); ((Quaternion)(ref rot))..ctor(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); CrateType type = (CrateType)Mathf.Clamp((int)binaryReader.ReadByte(), 0, 3); HatKey? key = HatNet.ReadKey(binaryReader); CrateFx.Play(pos, rot, type, key); break; } } } public static void Host_OnLevelLoot(List<HatItem> spawnedHats) { if (!HatNet.IsHost) { return; } runaways.Clear(); pendingGuardAt = null; pendingRumour = null; RoundManager instance = RoundManager.Instance; if ((Object)(object)instance == (Object)null || Economy.AtCompany()) { return; } if (Rng.NextDouble() * 100.0 < (double)Plugin.CfgStashChance.Value) { try { Host_SpawnStash(instance); } catch (Exception ex) { Plugin.Log.LogWarning((object)("hat stash: " + ex.Message)); } } if (spawnedHats.Count > 0 && Rng.NextDouble() * 100.0 < (double)Plugin.CfgRunawayChance.Value) { HatItem hatItem = spawnedHats[Rng.Next(spawnedHats.Count)]; if ((Object)(object)hatItem != (Object)null && hatItem.HasKey && ((GrabbableObject)hatItem).isInFactory) { WorldLoot.Host_SetFlags(hatItem, 1); runaways.Add(new Runaway { Item = hatItem, Hops = 3, CalmUntil = 0f }); Plugin.Log.LogInfo((object)"HatHunt: one of today's hats is a runaway."); } } } private static bool FloorAt(Vector3 near, float spread, out Vector3 floor) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_0041: 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_0050: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_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) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) floor = near; StartOfRound instance = StartOfRound.Instance; RaycastHit val2 = default(RaycastHit); for (int i = 0; i < 8; i++) { Vector3 val = new Vector3((float)Rng.NextDouble() - 0.5f, 0f, (float)Rng.NextDouble() - 0.5f) * spread * 2f; if (Physics.Raycast(near + val + Vector3.up * 1.2f, Vector3.down, ref val2, 4f, instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1) && ((RaycastHit)(ref val2)).normal.y > 0.7f) { floor = ((RaycastHit)(ref val2)).point + Vector3.up * 0.25f; return true; } } return false; } private static void Host_SpawnStash(RoundManager rm) { //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_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_0163: 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) //IL_0122: 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_0175: 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_01af: Unknown result type (might be due to invalid IL or missing references) //IL_0256: 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_023d: 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_02dd: Unknown result type (might be due to invalid IL or missing references) GameObject[] insideAINodes = rm.insideAINodes; if (insideAINodes == null || insideAINodes.Length == 0) { return; } Vector3 val = Vector3.zero; EntranceTeleport val2 = null; float num = float.MaxValue; Vector3 val3 = (((Object)(object)insideAINodes[0] != (Object)null) ? insideAINodes[0].transform.position : Vector3.zero); EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>(); foreach (EntranceTeleport val4 in array) { if (!((Object)(object)val4 == (Object)null) && val4.entranceId == 0) { Vector3 val5 = ((Component)val4).transform.position - val3; float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; val2 = val4; } } } if ((Object)(object)val2 != (Object)null) { val = ((Component)val2).transform.position; } GameObject val6 = null; float num2 = -1f; for (int j = 0; j < 6; j++) { GameObject val7 = insideAINodes[Rng.Next(insideAINodes.Length)]; if (!((Object)(object)val7 == (Object)null)) { float num3 = (((Object)(object)val2 != (Object)null) ? Vector3.Distance(val7.transform.position, val) : ((float)Rng.NextDouble())); if (num3 > num2) { num2 = num3; val6 = val7; } } } if ((Object)(object)val6 == (Object)null) { return; } Vector3 position = val6.transform.position; int num4 = 0; for (int k = 0; k < 3; k++) { if (FloorAt(position, 0.9f, out var floor)) { Rarity rarity = HatGen.RollRarity(Rng, HatManager.Instance.DropWeights(), 0.8f); if ((Object)(object)WorldLoot.Host_SpawnHat(Registry.CreateUnique(Rng, rarity), floor, inFactory: true) != (Object)null) { num4++; } } } if (FloorAt(position, 0.7f, out var floor2)) { double num5 = Rng.NextDouble(); CrateType t = ((!(num5 >= 0.25)) ? CrateType.Golden : ((!(num5 >= 0.5)) ? CrateType.Otaku : ((!(num5 >= 0.7)) ? CrateType.Wig : CrateType.Scavenger))); if ((Object)(object)WorldLoot.Host_SpawnCrate(t, floor2, inFactory: true) != (Object)null) { num4++; } } if (FloorAt(position, 0.7f, out var floor3) && (Object)(object)WorldLoot.Host_SpawnVanillaKey(floor3, inFactory: true) != (Object)null) { num4++; } if (num4 != 0) { if (Plugin.CfgStashGuard.Value) { pendingGuardAt = position; } pendingRumour = (Plugin.CfgStashGuard.Value ? "<color=#FFD54A>Rumour has it</color> someone stashed a pile of hats somewhere in this facility... <color=#FF7B7B>and something is guarding it.</color>" : "<color=#FFD54A>Rumour has it</color> someone stashed a pile of hats somewhere in this facility."); Plugin.Log.LogInfo((object)string.Concat("HatHunt: hat stash at ", position, " (", num4, " items)")); } } private static void Host_SpawnGuard(Vector3 at) { //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_0231: 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_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) RoundManager instance = RoundManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.currentLevel == (Object)null || instance.currentLevel.Enemies == null || instance.currentLevel.Enemies.Count == 0) { return; } EnemyType val = null; string[] array = new string[6] { "hoard", "spider", "crawler", "centipede", "spring", "puffer" }; foreach (string value in array) { foreach (SpawnableEnemyWithRarity enemy in instance.currentLevel.Enemies) { if (enemy != null && (Object)(object)enemy.enemyType != (Object)null && (Object)(object)enemy.enemyType.enemyPrefab != (Object)null && enemy.enemyType.enemyName != null && enemy.enemyType.enemyName.ToLowerInvariant().Contains(value)) { val = enemy.enemyType; break; } } if ((Object)(object)val != (Object)null) { break; } } if ((Object)(object)val == (Object)null) { foreach (SpawnableEnemyWithRarity enemy2 in instance.currentLevel.Enemies) { if (enemy2 != null && (Object)(object)enemy2.enemyType != (Object)null && (Object)(object)enemy2.enemyType.enemyPrefab != (Object)null && !enemy2.enemyType.isOutsideEnemy) { val = enemy2.enemyType; break; } } } if ((Object)(object)val == (Object)null) { return; } Vector3 val2 = at; bool flag = false; NavMeshHit val4 = default(NavMeshHit); for (int j = 0; j < 6; j++) { if (flag) { break; } Vector3 val3 = new Vector3((float)Rng.NextDouble() - 0.5f, 0f, (float)Rng.NextDouble() - 0.5f) * 6f; if (NavMesh.SamplePosition(at + val3, ref val4, 4f, -1)) { val2 = ((NavMeshHit)(ref val4)).position; flag = true; } } if (flag) { instance.SpawnEnemyGameObject(val2, (float)Rng.NextDouble() * 360f, -1, val); Plugin.Log.LogInfo((object)("HatHunt: a " + val.enemyName + " guards the hat stash.")); } } private static void Host_CheckRunaways() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return; } for (int num = runaways.Count - 1; num >= 0; num--) { Runaway runaway = runaways[num]; HatItem item = runaway.Item; if ((Object)(object)item == (Object)null || (Object)(object)((NetworkBehaviour)item).NetworkObject == (Object)null || !((NetworkBehaviour)item).NetworkObject.IsSpawned) { runaways.RemoveAt(num); } else if (((GrabbableObject)item).isHeld || ((GrabbableObject)item).hasBeenHeld || ((GrabbableObject)item).isHeldByEnemy || ((GrabbableObject)item).heldByPlayerOnServer || (Object)(object)((GrabbableObject)item).playerHeldBy != (Object)null) { runaways.RemoveAt(num); if ((Object)(object)((GrabbableObject)item).playerHeldBy != (Object)null) { string who = ((GrabbableObject)item).playerHeldBy.playerUsername; HatNet.ToAll("HatHunt.Chat", HatNet.Build(delegate(BinaryWriter w) { w.Write("<color=#FFD54A>" + who + "</color> caught the runaway hat!"); })); } } else if (runaway.Hops > 0 && Time.time >= runaway.CalmUntil) { Vector3 val = ((Component)item).transform.position + Vector3.up * 0.15f; PlayerControllerB val2 = null; bool flag = false; PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts; foreach (PlayerControllerB val3 in allPlayerScripts) { if (!((Object)(object)val3 == (Object)null) && val3.isPlayerControlled && !val3.isPlayerDead) { Vector3 val4 = (((Object)(object)val3.gameplayCamera != (Object)null) ? ((Component)val3.gameplayCamera).transform.position : (((Component)val3).transform.position + Vector3.up * 1.6f)); float num3 = Mathf.Max(3f, val3.grabDistance) + 1.5f; Vector3 val5 = val4 - val; float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude; if (sqrMagnitude < num3 * num3) { flag = true; break; } if (val3.isInsideFactory && sqrMagnitude <= 56.25f && !((Object)(object)val2 != (Object)null) && !Physics.Linecast(val4, val, instance.collidersAndRoomMask, (QueryTriggerInteraction)1)) { val2 = val3; } } } if (flag) { runaway.CalmUntil = Time.time + 0.5f; } else if (!((Object)(object)val2 == (Object)null)) { Hop(runaway, val2); } } } } private static void Hop(Runaway ra, PlayerControllerB spooker) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) RoundManager instance = RoundManager.Instance; HatItem item = ra.Item; if ((Object)(object)instance == (Object)null || instance.insideAINodes == null || instance.insideAINodes.Length == 0) { ra.Hops = 0; return; } Vector3 position = ((Component)item).transform.position; Vector3? val = null; for (int i = 0; i < 20; i++) { if (val.HasValue) { break; } GameObject val2 = instance.insideAINodes[Rng.Next(instance.insideAINodes.Length)]; if (!((Object)(object)val2 == (Object)null)) { float num = Vector3.Distance(val2.transform.position, position); if (num >= 7f && num <= 18f && FloorAt(val2.transform.position, 0.4f, out var floor)) { val = floor; } } } if (!val.HasValue) { ra.CalmUntil = Time.time + 3f; return; } HatKey key = item.Key; int scrapValue = ((GrabbableObject)item).scrapValue; ulong networkObjectId = ((NetworkBehaviour)item).NetworkObjectId; ItemData.ById.Remove(networkObjectId); ((NetworkBehaviour)item).NetworkObject.Despawn(true); HatItem hatItem = WorldLoot.Host_SpawnHat(key, val.Value, inFactory: true, scrapValue); ra.Hops--; if ((Object)(object)hatItem == (Object)null) { ra.Item = null; return; } WorldLoot.Host_SetFlags(hatItem, (byte)((ra.Hops > 0) ? 1u : 3u)); ra.Item = hatItem; ra.CalmUntil = Time.time + 2.5f; string line = ((ra.Hops > 0) ? "The hat <b>skitters off</b> into the dark!" : "The hat scurries away... it looks exhausted."); HatNet.ToClient("HatHunt.Encounter", spooker.actualClientId, HatNet.Build(delegate(BinaryWriter w) { w.Write(2); w.Write(line); })); if (!ra.Announced) { ra.Announced = true; string who = spooker.playerUsername; HatNet.ToAll("HatHunt.Chat", HatNet.Build(delegate(BinaryWriter w) { w.Write("<color=#FFD54A>" + who + "</color> spooked a <color=#7FE7FF>runaway hat</color>! Catch it!"); })); } } } public class FaceCamera : MonoBehaviour { public Transform Target; private void LateUpdate() { //IL_001d: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Target != (Object)null) { ((Component)this).transform.rotation = Quaternion.LookRotation(((Component)this).transform.position - Target.position, Vector3.up); } } } public enum Finish : byte { Matte, Satin, Glossy, Metallic } public enum FoundReason : byte { Found, TradeUp, Crate, Store, Worn } public class Hat { public HatKey Key; public string Name; public HatDesign Design; public List<HatEffect> Effects = new List<HatEffect>(); p