using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Bootstrap; using FishNet; using FishNet.Broadcast; using FishNet.Connection; using FishNet.Managing; using FishNet.Managing.Object; using FishNet.Object; using FishNet.Serializing; using FishNet.Transporting; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PortableGrillMod { public static class Rules { public const byte ItemId = 247; public const ushort PrefabCollection = 42423; public const int Price = 2500; public const int ResalePrice = 1250; public const float UseRange = 5f; public const float VendorRange = 5f; public const float VendorLookDot = 0.72f; public const float DeployRange = 8f; public const float HoldSeconds = 1f; public const float VanillaCookPerTick = 0.025f; public const float CookSpeedMultiplier = 0.9f; public const float CookPerTick = 0.022499999f; public const float CookingTriggerWidth = 0.88f; public const float CookingTriggerHeight = 1.1f; public const float CookingTriggerDepth = 0.68f; public const float CookingTriggerCenterY = 0.8f; public static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } public static bool SurfaceAllowed(float normalY) { if (Finite(normalY)) { return normalY >= 0.02f; } return false; } public static bool CanPickUp(bool freeSlot, bool emptyHands) { return freeSlot || emptyHands; } public static bool CanUseVendor(float distance, float lookDot) { if (Finite(distance) && Finite(lookDot) && distance <= 5.35f) { return lookDot >= 0.72f; } return false; } } [Serializable] public sealed class GrillData { public int serial; public ulong owner; public string ownerName; public bool deployed; public bool available = true; public Vector3 position; public Vector3 surfaceNormal = Vector3.up; public float yaw; public Quaternion Rotation => Quaternion.FromToRotation(Vector3.up, (((Vector3)(ref surfaceNormal)).sqrMagnitude > 0.01f) ? surfaceNormal : Vector3.up) * Quaternion.Euler(0f, yaw, 0f); } [Serializable] public sealed class WorldData { public string name; public List grills = new List(); } [Serializable] public sealed class SaveData { public int version = 1; public int nextSerial = 1; public List worlds = new List(); } [Serializable] public sealed class Command { public int protocol = 1; public int sequence; public int serial; public string action; public Vector3 position; public Vector3 normal; } [Serializable] public sealed class Snapshot { public int protocol = 1; public string world; public List grills = new List(); } [Serializable] public sealed class Reply { public int sequence; public int serial; public string message; } public struct RequestMessage : IBroadcast { public string json; } public struct StateMessage : IBroadcast { public string json; } public struct ReplyMessage : IBroadcast { public string json; } public static class Codec { private sealed class Fields : DefaultContractResolver { protected override IList CreateProperties(Type type, MemberSerialization mode) { return (from f in type.GetFields(BindingFlags.Instance | BindingFlags.Public) where !f.IsNotSerialized select ((DefaultContractResolver)this).CreateProperty((MemberInfo)f, (MemberSerialization)2)).ToList(); } } private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings { ContractResolver = (IContractResolver)(object)new Fields(), TypeNameHandling = (TypeNameHandling)0, ObjectCreationHandling = (ObjectCreationHandling)2, MaxDepth = 24 }; public static string ToJson(object value, bool pretty = false) { return JsonConvert.SerializeObject(value, (Formatting)(pretty ? 1 : 0), Settings); } public static T FromJson(string json) { return JsonConvert.DeserializeObject(json, Settings); } } public static class GrillItem { public static Item Prefab; private static GameObject storage; public static bool Is(Item item) { if ((Object)(object)item != (Object)null && item.ID == 247) { return (Object)(object)((Component)item).GetComponent() != (Object)null; } return false; } public static int Serial(Item item) { if (!Is(item)) { return 0; } return Mathf.RoundToInt(item.BettingMultiplier); } public static void Register() { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0294: 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_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Expected O, but got Unknown //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0494: 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) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Prefab != (Object)null || (Object)(object)InstanceFinder.NetworkManager == (Object)null) { return; } Dictionary dictionary = (Dictionary)AccessTools.Field(typeof(GameInfo), "_idToSpawnable").GetValue(null); if (dictionary.Count == 0) { return; } if (dictionary.ContainsKey(247)) { throw new Exception("Portable Grill item ID 247 is already in use."); } Item? obj = (from i in dictionary.Values where (Object)(object)i != (Object)null && ((object)i).GetType() == typeof(Item) && (Object)(object)((Component)i).GetComponent() != (Object)null orderby i.ID select i).FirstOrDefault(); if ((Object)(object)obj == (Object)null) { throw new Exception("No compatible base item prefab was found."); } storage = new GameObject("Portable Grill prefab storage"); storage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)storage); Item val = Object.Instantiate(obj, storage.transform); ((Object)val).name = "Portable Grill"; AccessTools.Field(typeof(Item), "_id").SetValue(val, (byte)247); AccessTools.Field(typeof(Item), "_cost").SetValue(val, 2500); AccessTools.Field(typeof(Item), "_worth").SetValue(val, 1250); AccessTools.Field(typeof(Item), "_ignoredBySeagulls").SetValue(val, true); AccessTools.Field(typeof(Item), "_ignoredByMoneyNPC").SetValue(val, false); AccessTools.Field(typeof(Item), "_ignoredByCloseDots").SetValue(val, false); AccessTools.Field(typeof(Item), "_heldPos").SetValue(val, (object)new Vector3(0.2f, -0.48f, 0.78f)); AccessTools.Field(typeof(Item), "_heldRot").SetValue(val, (object)new Vector3(8f, 12f, 0f)); Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); for (int num = 0; num < componentsInChildren.Length; num++) { componentsInChildren[num].enabled = false; } Collider[] componentsInChildren2 = ((Component)val).GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren2) { if (!val2.isTrigger) { val2.enabled = false; } } GameObject val3 = new GameObject("PortableGrillBodyCollider"); val3.transform.SetParent(((Component)val).transform, false); BoxCollider val4 = val3.AddComponent(); val4.center = new Vector3(0f, 0.23f, 0f); val4.size = new Vector3(1.16f, 0.48f, 1.02f); AccessTools.Field(typeof(Item), "_worldColliders").SetValue(val, new Collider[1] { (Collider)val4 }); Collider val5 = (Collider)AccessTools.Field(typeof(Item), "_pickUpCollider").GetValue(val); if ((Object)(object)val5 != (Object)null) { val5.isTrigger = true; } if (val5 is SphereCollider) { SphereCollider val6 = (SphereCollider)val5; val6.radius = 0.72f; val6.center = new Vector3(0f, 0.28f, 0f); } else if (val5 is BoxCollider) { BoxCollider val7 = (BoxCollider)val5; val7.size = new Vector3(1.42f, 0.88f, 1.25f); val7.center = new Vector3(0f, 0.28f, 0f); } AccessTools.Field(typeof(Item), "_outOfHandHolder").SetValue(val, null); AccessTools.Field(typeof(Item), "_inHandHolder").SetValue(val, null); PortableGrillVisual portableGrillVisual = ((Component)val).gameObject.AddComponent(); portableGrillVisual.Build(); AccessTools.Field(typeof(Item), "_mesh").SetValue(val, portableGrillVisual.InventoryMesh()); AccessTools.Field(typeof(Item), "_inventoryMeshScale").SetValue(val, 0.58f); AccessTools.Field(typeof(Item), "_inventoryMeshPos").SetValue(val, (object)new Vector3(0f, -0.12f, 0f)); AccessTools.Field(typeof(Item), "_inventoryMeshRot").SetValue(val, (object)new Vector3(20f, 35f, 0f)); AccessTools.Field(typeof(Item), "_renderers").SetValue(val, (from r in ((Component)portableGrillVisual).GetComponentsInChildren(true) where r.enabled select r).ToList()); NetworkObject component = ((Component)val).GetComponent(); component.SetIsSpawnable(true); PrefabObjects prefabObjects = InstanceFinder.NetworkManager.GetPrefabObjects((ushort)42423, true); if (prefabObjects.GetObjectCount() != 0) { throw new Exception("Portable Grill network prefab collection 42423 is occupied."); } prefabObjects.AddObject(component, false, true); dictionary.Add(247, val); ((Dictionary)AccessTools.Field(typeof(GameInfo), "_allItems").GetValue(null)).Add(247, val); ((Dictionary)AccessTools.Field(typeof(GameInfo), "_nameToSpawnable").GetValue(null)).Add("portablegrillmod", val); Prefab = val; Plugin.Log("Registered Portable Grill item and network prefab."); } } public sealed class PortableGrillVisual : MonoBehaviour { private static Material stone; private static Material metal; private static Material wood; private static Material ember; private Mesh inventoryMesh; private PortableGrillCooker cooker; private bool lastActive; public Mesh InventoryMesh() { return inventoryMesh; } private void Awake() { cooker = ((Component)this).GetComponent(); } private static Material Make(Color color, float metallic = 0f) { //IL_0018: 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) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown Material val = new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard")) { color = color }; if (val.HasProperty("_Metallic")) { val.SetFloat("_Metallic", metallic); } if (val.HasProperty("_Smoothness")) { val.SetFloat("_Smoothness", metallic * 0.45f); } return val; } public void Build() { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0224: 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_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: 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_0404: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((Component)this).transform.Find("PortableGrillModel") != (Object)null) { return; } if ((Object)(object)stone == (Object)null) { stone = Make(new Color(0.16f, 0.18f, 0.21f)); metal = Make(new Color(0.055f, 0.06f, 0.07f), 0.75f); wood = Make(new Color(0.31f, 0.12f, 0.045f)); ember = Make(new Color(1f, 0.2f, 0.015f)); } Transform transform = new GameObject("PortableGrillModel").transform; transform.SetParent(((Component)this).transform, false); transform.localPosition = new Vector3(0f, -0.05f, 0f); transform.localScale = Vector3.one * 0.8f; for (int i = 0; i < 10; i++) { float num = (float)i * (float)Math.PI * 2f / 10f; Transform val = Part("RingStone", transform, (PrimitiveType)0, new Vector3(Mathf.Cos(num) * 0.57f, 0.13f, Mathf.Sin(num) * 0.5f), new Vector3(0.38f, 0.27f, 0.34f), stone, Quaternion.Euler(12f, (float)i * 36f, 8f)); if ((Object)(object)inventoryMesh == (Object)null) { inventoryMesh = ((Component)val).GetComponent().sharedMesh; } } Part("LogA", transform, (PrimitiveType)2, new Vector3(0f, 0.23f, 0f), new Vector3(0.1f, 0.43f, 0.1f), wood, Quaternion.Euler(90f, 42f, 0f)); Part("LogB", transform, (PrimitiveType)2, new Vector3(0f, 0.25f, 0f), new Vector3(0.1f, 0.43f, 0.1f), wood, Quaternion.Euler(90f, -42f, 0f)); Part("EmberCore", transform, (PrimitiveType)0, new Vector3(0f, 0.27f, 0f), new Vector3(0.38f, 0.13f, 0.31f), ember, Quaternion.identity); float num2 = 0.49f; Part("GrateLeft", transform, (PrimitiveType)2, new Vector3(-0.53f, num2, 0f), new Vector3(0.032f, 0.43f, 0.032f), metal, Quaternion.Euler(90f, 0f, 0f)); Part("GrateRight", transform, (PrimitiveType)2, new Vector3(0.53f, num2, 0f), new Vector3(0.032f, 0.43f, 0.032f), metal, Quaternion.Euler(90f, 0f, 0f)); Part("GrateFront", transform, (PrimitiveType)2, new Vector3(0f, num2, -0.42f), new Vector3(0.032f, 0.53f, 0.032f), metal, Quaternion.Euler(0f, 0f, 90f)); Part("GrateBack", transform, (PrimitiveType)2, new Vector3(0f, num2, 0.42f), new Vector3(0.032f, 0.53f, 0.032f), metal, Quaternion.Euler(0f, 0f, 90f)); for (int j = -3; j <= 3; j++) { Part("GrateBar", transform, (PrimitiveType)2, new Vector3((float)j * 0.145f, num2 + 0.008f, 0f), new Vector3(0.024f, 0.41f, 0.024f), metal, Quaternion.Euler(90f, 0f, 0f)); } GameObject val2 = new GameObject("CookingTrigger"); val2.transform.SetParent(((Component)this).transform, false); BoxCollider val3 = val2.AddComponent(); ((Collider)val3).isTrigger = true; val3.center = new Vector3(0f, 0.8f, 0f); val3.size = new Vector3(0.88f, 1.1f, 0.68f); ((Collider)val3).enabled = false; cooker = ((Component)this).gameObject.AddComponent(); cooker.Configure(((Component)this).GetComponent(), (Collider)(object)val3); } public static Transform Part(string name, Transform parent, PrimitiveType primitive, Vector3 pos, Vector3 scale, Material material, Quaternion rotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) GameObject obj = GameObject.CreatePrimitive(primitive); ((Object)obj).name = name; obj.transform.SetParent(parent, false); obj.transform.localPosition = pos; obj.transform.localRotation = rotation; obj.transform.localScale = scale; Object.DestroyImmediate((Object)(object)obj.GetComponent()); obj.GetComponent().sharedMaterial = material; return obj.transform; } private void LateUpdate() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Plugin.Instance == (Object)null)) { Item component = ((Component)this).GetComponent(); GrillData grillData = Plugin.Instance.Find(GrillItem.Serial(component)); bool flag = grillData != null && grillData.deployed && (Object)(object)component != (Object)null && (Object)(object)component.SyncedHolder == (Object)null; if (flag) { ((Component)this).transform.SetPositionAndRotation(grillData.position, grillData.Rotation); } if ((Object)(object)cooker == (Object)null) { cooker = ((Component)this).GetComponent(); } if ((Object)(object)cooker != (Object)null && (flag != lastActive || flag)) { cooker.SetDeployed(flag); } lastActive = flag; } } } public sealed class PortableGrillCooker : MonoBehaviour { private Item grill; private Collider cookingTrigger; private readonly List items = new List(); private bool deployed; private bool effectsReady; private bool lit; private bool subscribed; private float nextEffectsSearch; private float sizzleVolume; private float cookPerTick = 0.022499999f; private Transform effectsRoot; private ParticleSystem smoke; private ParticleSystem flame; private AudioSource fireSource; private AudioSource sizzleSource; private void Awake() { grill = ((Component)this).GetComponent(); Transform val = ((Component)this).transform.Find("CookingTrigger"); cookingTrigger = (((Object)(object)val == (Object)null) ? null : ((Component)val).GetComponent()); Subscribe(); } private void Subscribe() { if (!subscribed) { NPCManager.OnUnlockedGrill += OnUnlocked; subscribed = true; } } public void Configure(Item owner, Collider trigger) { grill = owner; cookingTrigger = trigger; Subscribe(); } private void OnDisable() { deployed = false; items.Clear(); sizzleVolume = 0f; if ((Object)(object)sizzleSource != (Object)null) { sizzleSource.Stop(); } StopEffects(); } private void OnDestroy() { if (subscribed) { NPCManager.OnUnlockedGrill -= OnUnlocked; } } private bool Unlocked() { if ((Object)(object)NPCManager.Instance != (Object)null) { return NPCManager.Instance.GrillUnlocked; } return false; } private void OnUnlocked() { RefreshLit(); } public void SetDeployed(bool value) { deployed = value; if ((Object)(object)cookingTrigger != (Object)null) { cookingTrigger.enabled = value; } if (!value) { items.Clear(); sizzleVolume = 0f; if ((Object)(object)sizzleSource != (Object)null) { sizzleSource.Stop(); } StopEffects(); } else { RefreshLit(); } } private void Update() { if (!deployed) { return; } if (!effectsReady && Time.unscaledTime >= nextEffectsSearch) { nextEffectsSearch = Time.unscaledTime + 1f; EnsureEffects(); } RefreshLit(); float num = ((lit && items.Count > 0) ? 0.25f : 0f); sizzleVolume = Mathf.MoveTowards(sizzleVolume, num, Time.deltaTime * 0.55f); if ((Object)(object)sizzleSource != (Object)null) { sizzleSource.volume = sizzleVolume; if (sizzleVolume > 0.002f && !sizzleSource.isPlaying) { sizzleSource.Play(); } else if (sizzleVolume <= 0.002f && sizzleSource.isPlaying) { sizzleSource.Stop(); } } } private void FixedUpdate() { if (!deployed || !Unlocked()) { return; } for (int num = items.Count - 1; num >= 0; num--) { if ((Object)(object)items[num] == (Object)null || !((Component)items[num]).gameObject.activeInHierarchy || ((Object)(object)items[num].Creature != (Object)null && (Object)(object)((Item)items[num].Creature).BirdHolder != (Object)null)) { items.RemoveAt(num); } } if (!InstanceFinder.IsServerStarted) { return; } foreach (Item item in items) { if ((Object)(object)item != (Object)null && (Object)(object)item != (Object)(object)grill) { item.CookItem(cookPerTick); } } } private void OnTriggerStay(Collider other) { if (deployed && Unlocked()) { Item val = ItemManager.Get(other); if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)grill && !items.Contains(val)) { items.Add(val); } } } private void OnTriggerExit(Collider other) { Item val = ItemManager.Get(other); if ((Object)(object)val != (Object)null) { items.Remove(val); } } private void EnsureEffects() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown if (effectsReady) { return; } GrillBox val = Object.FindObjectsByType((FindObjectsInactive)0).FirstOrDefault(); if (!((Object)(object)val == (Object)null)) { FieldInfo fieldInfo = AccessTools.Field(typeof(GrillBox), "_cookPerTick"); if (fieldInfo != null) { cookPerTick = Mathf.Max(0.0001f, (float)fieldInfo.GetValue(val) * 0.9f); } effectsRoot = new GameObject("Portable Grill Vanilla Effects").transform; effectsRoot.SetParent(((Component)this).transform, false); effectsRoot.localPosition = new Vector3(0f, 0.2f, 0f); effectsRoot.localScale = Vector3.one * 0.8f; smoke = CloneParticle((ParticleSystem)AccessTools.Field(typeof(GrillBox), "_smokeParticles").GetValue(val), "Smoke"); flame = CloneParticle((ParticleSystem)AccessTools.Field(typeof(GrillBox), "_grillParticles").GetValue(val), "Flame"); fireSource = CloneAudio((AudioSource)AccessTools.Field(typeof(GrillBox), "_fireSource").GetValue(val), "Fire"); sizzleSource = CloneAudio((AudioSource)AccessTools.Field(typeof(GrillBox), "_sizzlingSource").GetValue(val), "Sizzle"); if ((Object)(object)sizzleSource != (Object)null) { sizzleSource.volume = 0f; sizzleSource.loop = true; } effectsReady = (Object)(object)smoke != (Object)null || (Object)(object)flame != (Object)null || (Object)(object)fireSource != (Object)null || (Object)(object)sizzleSource != (Object)null; if (effectsReady && deployed && Unlocked()) { StartEffects(); } } } private ParticleSystem CloneParticle(ParticleSystem source, string name) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0034: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } GameObject val = new GameObject("Portable Grill " + name); val.transform.SetParent(effectsRoot, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = ((Component)source).transform.localRotation; val.transform.localScale = ((name == "Flame") ? new Vector3(0.78f, 0.3f, 0.78f) : new Vector3(0.58f, 0.48f, 0.58f)); ParticleSystem obj = val.AddComponent(); MainModule main = source.main; MainModule main2 = obj.main; ((MainModule)(ref main2)).duration = ((MainModule)(ref main)).duration; ((MainModule)(ref main2)).loop = true; ((MainModule)(ref main2)).startLifetime = ((MainModule)(ref main)).startLifetime; ((MainModule)(ref main2)).startSpeed = ((MainModule)(ref main)).startSpeed; ((MainModule)(ref main2)).startSize = ((MainModule)(ref main)).startSize; ((MainModule)(ref main2)).startColor = ((MainModule)(ref main)).startColor; ((MainModule)(ref main2)).gravityModifier = ((MainModule)(ref main)).gravityModifier; ((MainModule)(ref main2)).simulationSpace = (ParticleSystemSimulationSpace)0; ((MainModule)(ref main2)).scalingMode = (ParticleSystemScalingMode)0; ((MainModule)(ref main2)).maxParticles = ((MainModule)(ref main)).maxParticles; if (name == "Flame") { ((MainModule)(ref main2)).startSpeedMultiplier = ((MainModule)(ref main2)).startSpeedMultiplier * 0.24f; ((MainModule)(ref main2)).startLifetimeMultiplier = ((MainModule)(ref main2)).startLifetimeMultiplier * 0.58f; ((MainModule)(ref main2)).startSizeMultiplier = ((MainModule)(ref main2)).startSizeMultiplier * 0.72f; } EmissionModule emission = source.emission; EmissionModule emission2 = obj.emission; ((EmissionModule)(ref emission2)).enabled = ((EmissionModule)(ref emission)).enabled; ((EmissionModule)(ref emission2)).rateOverTime = ((EmissionModule)(ref emission)).rateOverTime; ShapeModule shape = source.shape; ShapeModule shape2 = obj.shape; ((ShapeModule)(ref shape2)).enabled = true; if (name == "Flame") { ((ShapeModule)(ref shape2)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape2)).radius = 0.34f; } else { ((ShapeModule)(ref shape2)).shapeType = ((ShapeModule)(ref shape)).shapeType; ((ShapeModule)(ref shape2)).radius = Mathf.Min(((ShapeModule)(ref shape)).radius, 0.24f); ((ShapeModule)(ref shape2)).angle = ((ShapeModule)(ref shape)).angle; } ParticleSystemRenderer component = ((Component)source).GetComponent(); ParticleSystemRenderer component2 = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component2).sharedMaterial = ((Renderer)component).sharedMaterial; component2.renderMode = component.renderMode; component2.mesh = component.mesh; component2.sortingFudge = component.sortingFudge; } obj.Stop(true, (ParticleSystemStopBehavior)0); return obj; } private AudioSource CloneAudio(AudioSource source, string name) { //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_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } GameObject val = new GameObject("Portable Grill " + name); val.transform.SetParent(effectsRoot, false); AudioSource obj = val.AddComponent(); obj.clip = source.clip; obj.loop = source.loop; obj.playOnAwake = false; obj.spatialBlend = 1f; obj.rolloffMode = source.rolloffMode; obj.minDistance = Mathf.Min(source.minDistance, 1.5f); obj.maxDistance = Mathf.Min(source.maxDistance, 14f); obj.pitch = source.pitch; obj.volume = source.volume; return obj; } private void RefreshLit() { bool flag = deployed && Unlocked(); if (flag == lit) { if (flag && effectsReady) { StartEffects(); } return; } lit = flag; if (lit) { EnsureEffects(); StartEffects(); } else { StopEffects(); } } private void StartEffects() { if ((Object)(object)smoke != (Object)null && !smoke.isPlaying) { smoke.Play(); } if ((Object)(object)flame != (Object)null && !flame.isPlaying) { flame.Play(); } if ((Object)(object)fireSource != (Object)null && !fireSource.isPlaying) { fireSource.Play(); } } private void StopEffects() { lit = false; if ((Object)(object)smoke != (Object)null) { smoke.Stop(true, (ParticleSystemStopBehavior)0); } if ((Object)(object)flame != (Object)null) { flame.Stop(true, (ParticleSystemStopBehavior)0); } if ((Object)(object)fireSource != (Object)null) { fireSource.Stop(); } } } [BepInPlugin("ponyfisher.howtofish.portablegrillmod", "Portable Grill Mod", "0.1.2")] [DefaultExecutionOrder(29300)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "ponyfisher.howtofish.portablegrillmod"; public static Plugin Instance; public List Current = new List(); public int Selected; public string Status = "Unlock the vanilla grill, then purchase a Portable Grill from any money vendor."; private SaveData save = new SaveData(); private WorldData world; private NetworkManager manager; private Harmony harmony; private string savePath; private bool persistenceReady = true; private bool registrationFailed; private bool catalogReady; private bool nearMoneyVendor; private Component hoveredInteractable; private float nextTick; private float nextSave; private float nextState; private float nextVendorScan; private float nextIconRefresh; private float nextHello; private float statusUntil; private int sequence; private readonly Dictionary lastSequence = new Dictionary(); private readonly Dictionary rateLimit = new Dictionary(); private readonly Dictionary grills = new Dictionary(); private float useStarted; private Item activeTarget; private bool holdFired; private GUIStyle hintStyle; public static void Log(string text) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)text); } } private void Awake() { //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown Instance = this; savePath = Path.Combine(Paths.ConfigPath, "PortableGrillMod-worlds.json"); try { if (File.Exists(savePath)) { save = Codec.FromJson(File.ReadAllText(savePath)); if (save == null || save.version != 1 || save.worlds == null) { throw new Exception("Unrecognized save format"); } } } catch (Exception ex) { persistenceReady = false; Status = "Portable Grill save data could not be read; actions are paused."; ((BaseUnityPlugin)this).Logger.LogError((object)ex); } GenericWriter.SetWrite((Action)delegate(Writer w, RequestMessage v) { w.WriteString(v.json); }); GenericReader.SetRead((Func)((Reader r) => new RequestMessage { json = r.ReadStringAllocated() })); GenericWriter.SetWrite((Action)delegate(Writer w, StateMessage v) { w.WriteString(v.json); }); GenericReader.SetRead((Func)((Reader r) => new StateMessage { json = r.ReadStringAllocated() })); GenericWriter.SetWrite((Action)delegate(Writer w, ReplyMessage v) { w.WriteString(v.json); }); GenericReader.SetRead((Func)((Reader r) => new ReplyMessage { json = r.ReadStringAllocated() })); harmony = new Harmony("ponyfisher.howtofish.portablegrillmod"); harmony.PatchAll(typeof(Plugin).Assembly); Log("Portable Grill Mod 0.1.2 loaded. Unlock the vanilla grill, then press 7 at a money vendor."); } private void Update() { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) UpdateInteraction(); if ((Object)(object)manager != (Object)(object)InstanceFinder.NetworkManager) { RegisterNetwork(); } if (!registrationFailed && (Object)(object)GrillItem.Prefab == (Object)null) { try { GrillItem.Register(); } catch (Exception ex) { registrationFailed = true; Status = "Portable Grill registration failed; see the BepInEx log."; ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } if ((Object)(object)GrillItem.Prefab != (Object)null && !catalogReady) { catalogReady = true; Log("Portable Grill catalog ready."); } if (catalogReady && Time.unscaledTime >= nextVendorScan) { nextVendorScan = Time.unscaledTime + 0.15f; nearMoneyVendor = (Object)(object)FocusedMoneyVendor(Player.LocalPlayer, 5f) != (Object)null; } Keyboard current = Keyboard.current; if (catalogReady && nearMoneyVendor && GrillUnlocked() && current != null && ((ButtonControl)current.digit7Key).wasPressedThisFrame) { Send("buy"); } if (catalogReady && Time.unscaledTime >= nextIconRefresh) { nextIconRefresh = Time.unscaledTime + 0.15f; PortableGrillInventoryIcon.RefreshAll(); } if (InstanceFinder.IsServerStarted && SaveManager.CurServerSave != null) { string name = SaveManager.CurServerSave.Name; if (world == null || world.name != name) { world = save.worlds.FirstOrDefault((WorldData w) => w.name == name); if (world == null) { world = new WorldData { name = name }; save.worlds.Add(world); } Current = world.grills; grills.Clear(); lastSequence.Clear(); rateLimit.Clear(); } if (Time.unscaledTime >= nextTick) { nextTick = Time.unscaledTime + 0.2f; AuditWorld(); } if (Time.unscaledTime >= nextState) { nextState = Time.unscaledTime + 0.35f; Broadcast(); } if (Time.unscaledTime >= nextSave) { nextSave = Time.unscaledTime + 8f; Persist(); } } else if (!InstanceFinder.IsClientStarted) { world = null; Current = new List(); grills.Clear(); } if (InstanceFinder.IsClientStarted && !InstanceFinder.IsServerStarted && Time.unscaledTime >= nextHello) { nextHello = Time.unscaledTime + 3f; Send("hello"); } } public static bool GrillUnlocked() { if ((Object)(object)NPCManager.Instance != (Object)null) { return NPCManager.Instance.GrillUnlocked; } return false; } private void RegisterNetwork() { if ((Object)(object)manager != (Object)null) { manager.ServerManager.UnregisterBroadcast((Action)Receive); manager.ClientManager.UnregisterBroadcast((Action)ReceiveState); manager.ClientManager.UnregisterBroadcast((Action)ReceiveReply); } manager = InstanceFinder.NetworkManager; if (!((Object)(object)manager == (Object)null)) { manager.ServerManager.RegisterBroadcast((Action)Receive, true); manager.ClientManager.RegisterBroadcast((Action)ReceiveState); manager.ClientManager.RegisterBroadcast((Action)ReceiveReply); } } public GrillData Find(int serial) { return Current.FirstOrDefault((GrillData g) => g.serial == serial); } public void Persist() { if (!persistenceReady || !InstanceFinder.IsServerStarted || world == null) { return; } try { string text = savePath + ".tmp"; File.WriteAllText(text, Codec.ToJson(save, pretty: true)); if (File.Exists(savePath)) { File.Replace(text, savePath, savePath + ".bak"); } else { File.Move(text, savePath); } } catch (Exception ex) { persistenceReady = false; Status = "Portable Grill Mod could not save; actions are paused."; ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } public void Send(string action, Vector3 position = default(Vector3), Vector3 normal = default(Vector3), int serial = 0) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.LocalPlayer == (Object)null) { SetStatus("Load into a game first."); return; } Command command = new Command { action = action, serial = ((serial > 0) ? serial : Selected), position = position, normal = normal, sequence = ++sequence }; if (InstanceFinder.IsServerStarted) { Execute(Player.LocalPlayer, command, null); } else if ((Object)(object)manager != (Object)null && InstanceFinder.IsClientStarted) { manager.ClientManager.Broadcast(new RequestMessage { json = Codec.ToJson(command) }, (Channel)0); if (action != "hello") { SetStatus("Waiting for the host..."); } } } private void Receive(NetworkConnection connection, RequestMessage message, Channel channel) { if (!InstanceFinder.IsServerStarted || message.json == null || message.json.Length > 2048) { return; } try { Command command = Codec.FromJson(message.json); if (command != null && command.protocol == 1 && command.sequence > 0 && (!lastSequence.TryGetValue(connection.ClientId, out var value) || command.sequence > value) && (!rateLimit.TryGetValue(connection.ClientId, out var value2) || !(Time.unscaledTime - value2 < 0.1f))) { lastSequence[connection.ClientId] = command.sequence; rateLimit[connection.ClientId] = Time.unscaledTime; Player val = ((IEnumerable)Object.FindObjectsByType()).FirstOrDefault((Func)((Player p) => ((NetworkBehaviour)p).Owner == connection)); if ((Object)(object)val != (Object)null) { Execute(val, command, connection); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Rejected Portable Grill request: " + ex.Message)); } } private void SetStatus(string message) { Status = message; statusUntil = Time.unscaledTime + 4f; } private void Respond(Command cmd, NetworkConnection connection, string message, int selected = 0) { Reply value = new Reply { sequence = cmd.sequence, serial = selected, message = message }; if (connection == (NetworkConnection)null || connection.IsLocalClient) { SetStatus(message); if (selected > 0) { Selected = selected; } } else { manager.ServerManager.Broadcast(connection, new ReplyMessage { json = Codec.ToJson(value) }, true, (Channel)0); } } private void ReceiveReply(ReplyMessage message, Channel channel) { Reply reply = Codec.FromJson(message.json); if (reply != null) { SetStatus(reply.message); if (reply.serial > 0) { Selected = reply.serial; } } } private void ReceiveState(StateMessage message, Channel channel) { if (!InstanceFinder.IsServerStarted && message.json != null && message.json.Length <= 250000) { Snapshot snapshot = Codec.FromJson(message.json); if (snapshot != null && snapshot.protocol == 1 && snapshot.grills != null) { Current = snapshot.grills; } } } private void Broadcast() { if ((Object)(object)manager != (Object)null && world != null) { manager.ServerManager.Broadcast(new StateMessage { json = Codec.ToJson(new Snapshot { world = world.name, grills = Current }) }, true, (Channel)0); } } private void ScanGrills() { grills.Clear(); Item[] array = Object.FindObjectsByType((FindObjectsInactive)1); foreach (Item val in array) { if (GrillItem.Is(val) && ((NetworkBehaviour)val).IsSpawned && !((NetworkBehaviour)val).IsDeinitializing) { int num = GrillItem.Serial(val); if (num > 0 && !grills.ContainsKey(num)) { grills.Add(num, val); } } } } private Item FindGrill(int serial) { if (grills.TryGetValue(serial, out var value) && (Object)(object)value != (Object)null && ((NetworkBehaviour)value).IsSpawned && !((NetworkBehaviour)value).IsDeinitializing) { return value; } value = ((IEnumerable)Object.FindObjectsByType((FindObjectsInactive)1)).FirstOrDefault((Func)((Item i) => GrillItem.Is(i) && ((NetworkBehaviour)i).IsSpawned && !((NetworkBehaviour)i).IsDeinitializing && GrillItem.Serial(i) == serial)); if ((Object)(object)value != (Object)null) { grills[serial] = value; } return value; } private void AuditWorld() { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) ScanGrills(); foreach (KeyValuePair grill in grills) { Item value = grill.Value; GrillData grillData = Find(grill.Key); if (grillData == null) { Player syncedHolder = value.SyncedHolder; grillData = new GrillData { serial = grill.Key, owner = (((Object)(object)syncedHolder == (Object)null) ? 0 : syncedHolder.SteamID), ownerName = (((Object)(object)syncedHolder == (Object)null) ? null : syncedHolder.SteamName) }; Current.Add(grillData); save.nextSerial = Math.Max(save.nextSerial, grill.Key + 1); } grillData.available = true; if ((Object)(object)value.SyncedHolder != (Object)null) { grillData.deployed = false; } else if (grillData.deployed) { value.RigidbodySync.SetKinematic(true); if (Vector3.Distance(((Component)value).transform.position, grillData.position) > 0.05f) { value.RigidbodySync.TeleportToPosRot(grillData.position, grillData.Rotation, (float[])null, (Quaternion[])null); } } } foreach (GrillData item in Current) { item.available = grills.ContainsKey(item.serial); } } private int OpenSlot(Player player) { int num = (int)AccessTools.Method(typeof(PlayerInventory), "GetTotalSlots", (Type[])null, (Type[])null).Invoke(player.Inventory, null); Item val = default(Item); for (byte b = 0; b < num; b++) { if (!player.Inventory._items.TryGetValue(b, ref val) || (Object)(object)val == (Object)null) { return b; } } return -1; } private Item SpawnGrill(Player player, int slot, int serial) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_0078: 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) Item val = Object.Instantiate(GrillItem.Prefab, ((Component)player).transform.position + Vector3.up, Quaternion.identity, Server.Instance.DynamicObjectsHolder); val.LoadFromSave(new SavedItem { Exists = true, ItemID = 247, BettingMultiplier = serial, Weight = 1f, KillScoreMultiplier = 1f }); InstanceFinder.ServerManager.Spawn(((Component)val).gameObject, (NetworkConnection)null, default(Scene)); val.SetSyncedHolder(player, true); player.Inventory.AddItem((byte)slot, val); if (!player.Inventory.HasItemInInventory(val)) { InstanceFinder.ServerManager.Despawn(((Component)val).gameObject, (DespawnType?)null); throw new Exception("Inventory did not accept the Portable Grill."); } return val; } private bool Ground(Player player, Command cmd, Item grill, out RaycastHit hit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) hit = default(RaycastHit); if (!Rules.Finite(cmd.position.x) || !Rules.Finite(cmd.position.y) || !Rules.Finite(cmd.position.z) || !Rules.SurfaceAllowed(cmd.normal.y) || Vector3.Distance(cmd.position, player.CamObject.position) > 8.35f) { return false; } Vector3 normalized = ((Vector3)(ref cmd.normal)).normalized; foreach (RaycastHit item in from h in Physics.RaycastAll(cmd.position + normalized * 0.35f, -normalized, 0.8f, -1, (QueryTriggerInteraction)1) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if (((Component)((RaycastHit)(ref current)).collider).gameObject.layer != LayerMask.NameToLayer("Water") && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent() != (Object)null) && Rules.SurfaceAllowed(((RaycastHit)(ref current)).normal.y) && !(Vector3.Dot(((RaycastHit)(ref current)).normal, normalized) < 0.5f)) { hit = current; return true; } } return false; } private float Distance(Player player, Item item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) return Mathf.Min(Vector3.Distance(((Component)player).transform.position, ((Component)item).transform.position), ((Object)(object)player.CamObject == (Object)null) ? float.MaxValue : Vector3.Distance(player.CamObject.position, ((Component)item).transform.position)); } private void Execute(Player player, Command cmd, NetworkConnection connection) { //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0295: 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_029f: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0337: 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_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) if (cmd.action == "hello") { Broadcast(); return; } if (!persistenceReady || world == null || (Object)(object)GrillItem.Prefab == (Object)null || player.Dying.IsDead) { Respond(cmd, connection, "Portable Grill Mod is not ready on the host."); return; } ScanGrills(); try { if (cmd.action == "buy") { if (!GrillUnlocked()) { Respond(cmd, connection, "Complete the vanilla grill unlock before purchasing a Portable Grill."); return; } if ((Object)(object)FocusedMoneyVendor(player, 5f) == (Object)null) { Respond(cmd, connection, "Move close to and look at a money vendor to buy a Portable Grill."); return; } int num = OpenSlot(player); if (num < 0) { Respond(cmd, connection, "Free an inventory slot before buying a Portable Grill."); return; } if (!Wallet.Charge(player, 2500)) { Respond(cmd, connection, "You need $" + 2500.ToString("N0") + " to buy a Portable Grill."); return; } int num2 = save.nextSerial++; try { SpawnGrill(player, num, num2); } catch { Wallet.Credit(player, 2500); throw; } Current.Add(new GrillData { serial = num2, owner = player.SteamID, ownerName = player.SteamName }); Persist(); Broadcast(); Respond(cmd, connection, "Portable Grill purchased and added to your inventory.", num2); return; } GrillData grillData = Find(cmd.serial); Item val = FindGrill(cmd.serial); if (grillData == null || (Object)(object)val == (Object)null) { Respond(cmd, connection, "That Portable Grill is unavailable."); return; } bool flag = (Object)(object)val.SyncedHolder == (Object)(object)player; if (!flag && Distance(player, val) > 5.35f) { Respond(cmd, connection, "Move within " + 5f.ToString("0") + " metres of the Portable Grill."); return; } if (cmd.action == "deploy") { if (!flag || grillData.deployed) { Respond(cmd, connection, "Hold that Portable Grill before deploying it."); return; } if (!Ground(player, cmd, val, out var hit)) { Respond(cmd, connection, "Look at an upward-facing surface within 8 metres."); return; } val.SpawnFromInventory(); player.Inventory.RemoveItem(val); if ((Object)(object)val.Holder != (Object)null) { val.Drop(false, default(Vector3), default(Vector3)); } val.SetSyncedHolder((Player)null, true); val.ReconcileLocalHolderWithSyncedHolder(); if ((Object)(object)player.Holding.HeldItem == (Object)(object)val) { player.Hands.DropItem(false, val); player.Holding.DropItem(false, val); player.Holding.SetHeldItem((Item)null); } if ((Object)(object)player.Holding.UninitializedHeldItem == (Object)(object)val) { player.Holding.SetUninitializedHeldItem((Item)null); } grillData.position = ((RaycastHit)(ref hit)).point + ((RaycastHit)(ref hit)).normal * 0.015f; grillData.surfaceNormal = ((RaycastHit)(ref hit)).normal; Quaternion curPlayerRot = player.CurPlayerRot; grillData.yaw = ((Quaternion)(ref curPlayerRot)).eulerAngles.y; grillData.deployed = true; val.RigidbodySync.ServerSetSyncedSimulator(((NetworkBehaviour)Server.Instance).Owner); val.RigidbodySync.TeleportToPosRot(grillData.position, grillData.Rotation, (float[])null, (Quaternion[])null); val.RigidbodySync.SetKinematic(true); Respond(cmd, connection, "Portable Grill deployed and ready to cook.", grillData.serial); } else { if (!(cmd.action == "pickup")) { return; } if (flag) { Respond(cmd, connection, "The Portable Grill is already in your inventory."); return; } int num3 = OpenSlot(player); bool emptyHands = (Object)(object)player.Holding.HeldItem == (Object)null && (Object)(object)player.Holding.UninitializedHeldItem == (Object)null && (Object)(object)player.Inventory.SyncedCurItem == (Object)null; if (!Rules.CanPickUp(num3 >= 0, emptyHands)) { Respond(cmd, connection, "Free an inventory slot or empty your hands first."); return; } grillData.deployed = false; val.RigidbodySync.SetKinematic(false); int value = player.Inventory._syncedCurSlot.Value; val.SetSyncedHolder(player, true); if (num3 >= 0) { player.Inventory.AddItem((byte)num3, val); } val.ReconcileLocalHolderWithSyncedHolder(); if (num3 >= 0) { player.Inventory.ServerSetSyncedCurSlot(value); } Respond(cmd, connection, "Portable Grill picked up.", grillData.serial); } Persist(); Broadcast(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); Respond(cmd, connection, "Portable Grill Mod could not complete that action. Check the BepInEx log."); } } public static bool IsMoneyVendor(NPC npc) { if ((Object)(object)npc == (Object)null) { return false; } FieldInfo fieldInfo = AccessTools.Field(typeof(NPC), "_quests"); return ((fieldInfo == null) ? null : (fieldInfo.GetValue(npc) as IEnumerable))?.Any((NPCQuest q) => (Object)(object)q != (Object)null && (int)q.Type == 1) ?? false; } public void SetHoveredInteractable(Component value, bool active) { if (active) { hoveredInteractable = value; } else if ((Object)(object)hoveredInteractable == (Object)(object)value) { hoveredInteractable = null; } } private static NPC VendorFrom(Component component) { if ((Object)(object)component == (Object)null) { return null; } NPC componentInParent = component.GetComponentInParent(); if (!((Object)(object)componentInParent != (Object)null)) { return component.GetComponentInChildren(true); } return componentInParent; } public NPC FocusedMoneyVendor(Player player, float range) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.CamObject == (Object)null) { return null; } if ((Object)(object)player == (Object)(object)Player.LocalPlayer && (Object)(object)hoveredInteractable != (Object)null) { NPC val = VendorFrom(hoveredInteractable); if (IsMoneyVendor(val) && Vector3.Distance(((Component)player).transform.position, ((Component)val).transform.position) <= range + 0.35f) { return val; } } foreach (RaycastHit item in from h in Physics.RaycastAll(player.CamObject.position, player.CamObject.forward, range, -1, (QueryTriggerInteraction)2) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent() == (Object)(object)player)) { NPC componentInParent = ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent(); if (IsMoneyVendor(componentInParent)) { return componentInParent; } if (!((RaycastHit)(ref current)).collider.isTrigger) { break; } } } NPC result = null; float num = 0.72f; RaycastHit val3 = default(RaycastHit); foreach (NPC item2 in Object.FindObjectsByType().Where(IsMoneyVendor)) { Vector3 val2 = (((Object)(object)item2.MouthPosForItems != (Object)null) ? item2.MouthPosForItems.position : (((Component)item2).transform.position + Vector3.up)) - player.CamObject.position; float magnitude = ((Vector3)(ref val2)).magnitude; if (!(magnitude <= 0.01f)) { float num2 = Vector3.Dot(player.CamObject.forward, val2 / magnitude); if (Rules.CanUseVendor(magnitude, num2) && !(num2 < num) && Physics.Raycast(player.CamObject.position, val2 / magnitude, ref val3, magnitude + 0.5f, -1, (QueryTriggerInteraction)2) && !((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent() != (Object)(object)item2)) { result = item2; num = num2; } } } return result; } public void CompleteSale(Item item) { if (!InstanceFinder.IsServerStarted || (Object)(object)item == (Object)null) { return; } int num = GrillItem.Serial(item); GrillData grillData = Find(num); if (grillData != null) { Current.Remove(grillData); grills.Remove(num); if (Selected == num) { Selected = 0; } SetStatus("Portable Grill sold for $" + 1250.ToString("N0") + "."); Persist(); Broadcast(); } } private void OnDestroy() { Persist(); if (harmony != null) { harmony.UnpatchSelf(); } Instance = null; } private void DrawVendorPrompt() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) if (catalogReady && nearMoneyVendor && GrillUnlocked() && !((Object)(object)Player.LocalPlayer == (Object)null)) { GUIStyle val = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 18, fontStyle = (FontStyle)1 }; val.normal.textColor = (Color)((Wallet.Balance(Player.LocalPlayer) >= 2500) ? Color.white : new Color(1f, 0.45f, 0.35f)); float num = 470f; float num2 = ((float)Screen.width - num) * 0.5f; float num3 = (float)Screen.height * 0.67f; if (Chainloader.PluginInfos.ContainsKey("ponyfisher.howtofish.coolermod") || Chainloader.PluginInfos.ContainsKey("ponyfisher.howtofish.waterwalkingboots")) { num3 -= 46f; } GUI.Box(new Rect(num2, num3, num, 38f), "[7] Buy Portable Grill - $" + 2500.ToString("N0"), val); if (Time.unscaledTime < statusUntil) { GUIStyle val2 = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 14, fontStyle = (FontStyle)1 }; val2.normal.textColor = Color.white; GUI.Box(new Rect(num2 + 20f, num3 + 42f, num - 40f, 30f), Status, val2); } } } private void OnGUI() { DrawInteractionHint(); DrawVendorPrompt(); } public static bool IsDeployed(Item item) { if ((Object)(object)Instance != (Object)null && GrillItem.Is(item) && (Object)(object)item.SyncedHolder == (Object)null) { return Instance.Find(GrillItem.Serial(item))?.deployed ?? false; } return false; } private Item RayGrill(float range) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null) { return null; } foreach (RaycastHit item in from h in Physics.RaycastAll(localPlayer.CamObject.position, localPlayer.CamObject.forward, range, -1, (QueryTriggerInteraction)2) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if ((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent() == (Object)(object)localPlayer) { continue; } Item componentInParent = ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent(); if (!((Object)(object)componentInParent != (Object)null) || !((Object)(object)componentInParent.SyncedHolder == (Object)(object)localPlayer)) { if (GrillItem.Is(componentInParent) && IsDeployed(componentInParent)) { return componentInParent; } if (!((RaycastHit)(ref current)).collider.isTrigger) { return null; } } } return null; } private Item InteractionTarget() { Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.BlockInputs || localPlayer.Dying.IsDead) { return null; } Item heldItem = localPlayer.Holding.HeldItem; if (GrillItem.Is(heldItem)) { return heldItem; } return RayGrill(5f); } public bool CapturesInteract() { if (!((Object)(object)InteractionTarget() != (Object)null)) { return (Object)(object)activeTarget != (Object)null; } return true; } private bool CrosshairSurface(Item held, out RaycastHit surface) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) surface = default(RaycastHit); Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null) { return false; } foreach (RaycastHit item in from h in Physics.RaycastAll(localPlayer.CamObject.position, localPlayer.CamObject.forward, 8f, -1, (QueryTriggerInteraction)1) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent() == (Object)(object)localPlayer) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent() == (Object)(object)held)) { if (((Component)((RaycastHit)(ref current)).collider).gameObject.layer == LayerMask.NameToLayer("Water") || !Rules.SurfaceAllowed(((RaycastHit)(ref current)).normal.y)) { return false; } surface = current; return true; } } return false; } private void FireHeldAction(Item target) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_003d: 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) Selected = GrillItem.Serial(target); if ((Object)(object)target.SyncedHolder == (Object)(object)Player.LocalPlayer) { if (!CrosshairSurface(target, out var surface)) { SetStatus("Look at an upward-facing surface within 8 metres."); } else { Send("deploy", ((RaycastHit)(ref surface)).point, ((RaycastHit)(ref surface)).normal); } } else { Send("pickup"); } } private void UpdateInteraction() { Keyboard current = Keyboard.current; if (current != null) { if (((ButtonControl)current.eKey).wasPressedThisFrame) { activeTarget = InteractionTarget(); useStarted = Time.unscaledTime; holdFired = false; } if ((Object)(object)activeTarget != (Object)null && ((ButtonControl)current.eKey).isPressed && !holdFired && Time.unscaledTime - useStarted >= 1f) { holdFired = true; FireHeldAction(activeTarget); } if (((ButtonControl)current.eKey).wasReleasedThisFrame) { activeTarget = null; holdFired = false; } if (!((ButtonControl)current.eKey).isPressed && !((ButtonControl)current.eKey).wasReleasedThisFrame && (Object)(object)activeTarget != (Object)null && Time.unscaledTime - useStarted > 2f) { activeTarget = null; holdFired = false; } } } private void DrawInteractionHint() { //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown Item val = activeTarget ?? InteractionTarget(); if (!((Object)(object)val == (Object)null)) { string text = (((Object)(object)val.SyncedHolder == (Object)(object)Player.LocalPlayer) ? "Hold E to deploy Portable Grill" : "Hold E to pick up Portable Grill"); if ((Object)(object)activeTarget != (Object)null && Keyboard.current != null && ((ButtonControl)Keyboard.current.eKey).isPressed) { text = text + " " + Mathf.Clamp01((Time.unscaledTime - useStarted) / 1f).ToString("P0"); } if (hintStyle == null) { hintStyle = new GUIStyle(GUI.skin.box) { fontSize = 15, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } GUI.Box(new Rect((float)Screen.width / 2f - 270f, (float)Screen.height * 0.73f, 540f, 42f), text, hintStyle); } } } internal static class Wallet { private static Type WalletType => Type.GetType("NoSharedMoney.Wallets, NoSharedMoney", throwOnError: false); public static int Balance(Player player) { Type walletType = WalletType; if (walletType != null) { return (int)AccessTools.Method(walletType, "Get", new Type[1] { typeof(Player) }, (Type[])null).Invoke(null, new object[1] { player }); } return MoneyManager.Money; } public static bool Charge(Player player, int cost) { Type walletType = WalletType; if (walletType != null) { MethodInfo methodInfo = AccessTools.Method(walletType, "Get", new Type[1] { typeof(Player) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(walletType, "Remove", new Type[2] { typeof(Player), typeof(int) }, (Type[])null); if ((int)methodInfo.Invoke(null, new object[1] { player }) < cost) { return false; } methodInfo2.Invoke(null, new object[2] { player, cost }); return true; } if ((Object)(object)MoneyManager.Instance == (Object)null || !MoneyManager.CanAfford(cost)) { return false; } MoneyManager.RemoveMoney(cost, player); return true; } public static void Credit(Player player, int amount) { Type walletType = WalletType; if (walletType != null) { AccessTools.Method(walletType, "Add", new Type[2] { typeof(Player), typeof(int) }, (Type[])null).Invoke(null, new object[2] { player, amount }); } else { MoneyManager.AddMoney(amount, player); } } } [HarmonyPatch(typeof(PlayerHolding), "PickUpInput")] internal static class PortableGrillCaptureInteract { private static bool Prefix() { if (!((Object)(object)Plugin.Instance == (Object)null)) { return !Plugin.Instance.CapturesInteract(); } return true; } } [HarmonyPatch(typeof(GameInfo), "Awake")] internal static class RegisterPortableGrill { private static void Postfix() { try { GrillItem.Register(); } catch (Exception ex) { Plugin.Log("Portable Grill registration deferred: " + ex.Message); } } } [HarmonyPatch(typeof(Interactable), "Hover")] internal static class PortableGrillVendorHoverStart { private static void Postfix(Interactable __instance) { if ((Object)(object)Plugin.Instance != (Object)null) { Plugin.Instance.SetHoveredInteractable((Component)(object)__instance, active: true); } } } [HarmonyPatch(typeof(Interactable), "UnHover")] internal static class PortableGrillVendorHoverStop { private static void Postfix(Interactable __instance) { if ((Object)(object)Plugin.Instance != (Object)null) { Plugin.Instance.SetHoveredInteractable((Component)(object)__instance, active: false); } } } [HarmonyPatch(typeof(Item), "GetName")] internal static class PortableGrillName { private static bool Prefix(Item __instance, ref string __result) { if (!GrillItem.Is(__instance)) { return true; } __result = "Portable Grill"; return false; } } [HarmonyPatch(typeof(MoneyManager), "SellItem")] internal static class PortableGrillSale { private static void Postfix(Item item) { if (GrillItem.Is(item) && (Object)(object)Plugin.Instance != (Object)null) { Plugin.Instance.CompleteSale(item); } } } [HarmonyPatch(typeof(Item), "SetSyncedHolder")] internal static class PortableGrillHolder { private static void Postfix(Item __instance) { if (GrillItem.Is(__instance) && !((Object)(object)__instance.SyncedHolder == (Object)null) && !((Object)(object)Plugin.Instance == (Object)null)) { GrillData grillData = Plugin.Instance.Find(GrillItem.Serial(__instance)); if (grillData != null) { grillData.deployed = false; } } } } [HarmonyPatch(typeof(SaveManager), "SaveServer")] internal static class SavePortableGrills { private static void Postfix() { if ((Object)(object)Plugin.Instance != (Object)null) { Plugin.Instance.Persist(); } } } [HarmonyPatch(typeof(SaveManager), "GetWorldItemSavePriority")] internal static class PortableGrillSavePriority { private static bool Prefix(Item item, ref int __result) { if (!GrillItem.Is(item)) { return true; } __result = 0; return false; } } [HarmonyPatch(typeof(ItemManager), "RemoveItemsFarAwar")] internal static class KeepPortableGrills { private static void Prefix(List toRemove) { toRemove.RemoveAll(GrillItem.Is); } } [HarmonyPatch(typeof(Item), "PickUp")] internal static class NoDirectPortableGrillPickup { private static bool Prefix(Item __instance, bool calledFromLocal, bool sendToServer) { if (calledFromLocal || sendToServer) { return !Plugin.IsDeployed(__instance); } return true; } } [HarmonyPatch(typeof(Item), "get_CanPickUp")] internal static class PortableGrillPickupPrompt { private static void Postfix(Item __instance, ref bool __result) { if (Plugin.IsDeployed(__instance)) { __result = false; } } } [HarmonyPatch(typeof(Item), "DestroyItem")] internal static class ProtectPortableGrill { private static bool Prefix(Item __instance) { return !Plugin.IsDeployed(__instance); } } [HarmonyPatch(typeof(RigidbodySync), "SetKinematic")] internal static class AnchorPortableGrill { private static void Prefix(RigidbodySync __instance, ref bool kinematic) { if (Plugin.IsDeployed(((Component)__instance).GetComponent())) { kinematic = true; } } } [HarmonyPatch(typeof(RigidbodySync), "StartSimulateLocal")] internal static class PreventPortableGrillExplosion { private static bool Prefix(RigidbodySync __instance) { return !Plugin.IsDeployed(((Component)__instance).GetComponent()); } } [HarmonyPatch(typeof(Item), "UpdateLayer")] internal static class SolidPortableGrill { private static void Prefix(Item __instance, ref bool ____disablePlayerColOnGround) { if (Plugin.IsDeployed(__instance)) { ____disablePlayerColOnGround = false; } } } public sealed class PortableGrillSlotIcon : MonoBehaviour { private InventorySlot slot; private Renderer previewRenderer; private MeshFilter filter; private GameObject overlay; private bool previousRenderer; private bool applied; private static Texture2D icon; private static void Load() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown if ((Object)(object)icon != (Object)null) { return; } using Stream stream = typeof(PortableGrillSlotIcon).Assembly.GetManifestResourceStream("PortableGrillMod.portable-grill-icon.png"); if (stream == null) { return; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); icon = new Texture2D(2, 2, (TextureFormat)4, false); ImageConversion.LoadImage(icon, memoryStream.ToArray()); ((Texture)icon).wrapMode = (TextureWrapMode)1; } private void CreateOverlay(RawImage nativeImage) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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) //IL_007f: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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) if (!((Object)(object)overlay != (Object)null)) { overlay = new GameObject("Portable Grill Mod Icon", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage) }); overlay.transform.SetParent(((Component)nativeImage).transform, false); RectTransform val = (RectTransform)overlay.transform; val.anchorMin = Vector2.zero; val.anchorMax = Vector2.one; val.offsetMin = Vector2.zero; val.offsetMax = Vector2.zero; ((Transform)val).localScale = Vector3.one; RawImage component = overlay.GetComponent(); component.texture = (Texture)(object)icon; component.uvRect = new Rect(0f, 0f, 1f, 1f); ((Graphic)component).color = Color.white; ((Graphic)component).raycastTarget = false; } } public void Apply(InventorySlot target) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown slot = target; if (!GrillItem.Is(slot.Item)) { return; } Load(); if ((Object)(object)icon == (Object)null) { return; } RawImage val = (RawImage)AccessTools.Field(typeof(InventorySlot), "_itemImage").GetValue(slot); previewRenderer = (Renderer)AccessTools.Field(typeof(InventorySlot), "_renderer").GetValue(slot); filter = (MeshFilter)AccessTools.Field(typeof(InventorySlot), "_filter").GetValue(slot); if (!((Object)(object)val == (Object)null)) { CreateOverlay(val); if (!applied) { previousRenderer = (Object)(object)previewRenderer == (Object)null || previewRenderer.enabled; applied = true; } if ((Object)(object)previewRenderer != (Object)null) { previewRenderer.enabled = false; } overlay.SetActive(true); } } public void Restore() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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) if (!applied) { return; } InventorySlot val = slot; Item val2 = (((Object)(object)val == (Object)null) ? null : val.Item); if ((Object)(object)overlay != (Object)null) { overlay.SetActive(false); } applied = false; if ((Object)(object)val2 != (Object)null && !GrillItem.Is(val2) && (Object)(object)filter != (Object)null) { filter.mesh = val2.Mesh; ((Component)filter).transform.localPosition = val2.InventoryMeshPos; ((Component)filter).transform.localEulerAngles = val2.InventoryMeshRot; ((Component)filter).transform.localScale = Vector3.one * val2.InventoryMeshScale; if ((Object)(object)previewRenderer != (Object)null) { previewRenderer.enabled = true; } try { AccessTools.Method(typeof(InventorySlot), "ApplyCookness", (Type[])null, (Type[])null).Invoke(val, new object[1] { val2 }); AccessTools.Method(typeof(InventorySlot), "ApplySkin", (Type[])null, (Type[])null).Invoke(val, new object[1] { val2 }); } catch { } } else if ((Object)(object)previewRenderer != (Object)null) { previewRenderer.enabled = previousRenderer; } slot = null; } private void Update() { if (applied && ((Object)(object)slot == (Object)null || !GrillItem.Is(slot.Item))) { Restore(); } } private void OnDestroy() { Restore(); } } [HarmonyPatch(typeof(InventorySlot), "SetItem")] internal static class PortableGrillInventoryIcon { public static void RefreshAll() { InventorySlot[] array = Object.FindObjectsByType((FindObjectsInactive)1); foreach (InventorySlot val in array) { PortableGrillSlotIcon portableGrillSlotIcon = ((Component)val).GetComponent(); if (GrillItem.Is(val.Item)) { if ((Object)(object)portableGrillSlotIcon == (Object)null) { portableGrillSlotIcon = ((Component)val).gameObject.AddComponent(); } portableGrillSlotIcon.Apply(val); } else if ((Object)(object)portableGrillSlotIcon != (Object)null) { portableGrillSlotIcon.Restore(); } } } private static void Prefix(InventorySlot __instance, Item item) { if ((Object)(object)__instance.Item != (Object)(object)item) { ((Component)__instance).GetComponent()?.Restore(); } } private static void Postfix(InventorySlot __instance) { if (GrillItem.Is(__instance.Item)) { (((Component)__instance).GetComponent() ?? ((Component)__instance).gameObject.AddComponent()).Apply(__instance); } } } }