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 StvirisGeorgianCuisine v0.3.3
plugins/StvirisGeorgianCuisine/StvirisGeorgianCuisine.dll
Decompiled 5 days agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using BepInEx; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Newtonsoft.Json; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace StvirisGeorgianCuisine; [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInPlugin("private.khinkali.food", "StvirisGeorgianCuisine", "0.3.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { [Serializable] public class AssetManifest { public AssetEntry[] assets; } [Serializable] public class AssetEntry { public string name; public AssetPart[] parts; public AssetAnchor[] anchors; } [Serializable] public class AssetPart { public string name; public string mesh; public string texture; public float metallic; public float roughness; public float emission; } [Serializable] public class AssetAnchor { public string name; public float[] position; } [Serializable] private class MeshData { public string name; public float[] positions; public float[] normals; public float[] uv; public int[] triangles; } public const string Guid = "private.khinkali.food"; public const string Version = "0.3.3"; private string assetDirectory; private static bool HasGraphics => (int)SystemInfo.graphicsDeviceType != 4; private void ProtectAllFoodLODs() { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) if (!HasGraphics) { return; } string[] array = new string[8] { "KhinkaliMod_Khinkali", "KhinkaliMod_MincedMeat", "SGC_MtsvadiRaw", "SGC_Mtsvadi", "SGC_ShotiStarterMix", "SGC_ShotiStarter", "SGC_ShotiDough", "SGC_Shoti" }; foreach (string text in array) { GameObject itemPrefab = ItemManager.Instance.GetItem(text).ItemPrefab; if (!Object.op_Implicit((Object)(object)itemPrefab.GetComponentInChildren<LODGroup>(true))) { Transform val = itemPrefab.transform.Find("attach"); GameObject val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).gameObject : itemPrefab); Renderer[] array2 = (from r in val2.GetComponentsInChildren<MeshRenderer>(true) where ((Renderer)r).enabled && ((Component)r).gameObject.activeSelf select r).Cast<Renderer>().ToArray(); if (array2.Length == 0) { throw new InvalidOperationException("No dropped food renderer: " + text); } LODGroup val3 = val2.AddComponent<LODGroup>(); val3.SetLODs((LOD[])(object)new LOD[1] { new LOD(0.001f, array2) }); val3.RecalculateBounds(); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Verified authored/native LOD protection for all eight food and ingredient items."); } private void RegisterMakali() { AssetManifest manifest = JsonConvert.DeserializeObject<AssetManifest>(File.ReadAllText(Path.Combine(assetDirectory, "Makali_Mtsvadi.assets.json"))); CustomItem val = CreateSkewer(cooked: false, manifest); CustomItem val2 = CreateSkewer(cooked: true, manifest); CustomPiece val3 = CreateMakali(val.ItemDrop, val2.ItemDrop, manifest); try { if (!ItemManager.Instance.AddItem(val) || !ItemManager.Instance.AddItem(val2) || !PieceManager.Instance.AddPiece(val3)) { throw new InvalidOperationException("Could not register Makali recipe chain."); } } catch { PieceManager.Instance.RemovePiece(val3); ItemManager.Instance.RemoveItem(val); ItemManager.Instance.RemoveItem(val2); throw; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered Makali (six slots, coal) and raw/cooked Mtsvadi."); } private CustomItem CreateSkewer(bool cooked, AssetManifest manifest) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00ff: 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_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: 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_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) string id = (cooked ? "SGC_Mtsvadi" : "SGC_MtsvadiRaw"); ItemConfig val = new ItemConfig(); val.Name = (cooked ? "Mtsvadi" : "Mtsvadi (raw)"); val.Description = (cooked ? "Juicy pork, marinated with onion and grilled slowly over charcoal." : "Five hand-cut pieces of marinated pork. Ready for the Makali."); val.StackSize = 20; val.Weight = 1f; val.Amount = 1; val.CraftingStation = (cooked ? null : "piece_preptable"); val.MinStationLevel = 1; val.Requirements = (RequirementConfig[])(object)(cooked ? new RequirementConfig[0] : new RequirementConfig[2] { new RequirementConfig("RawMeat", 1, 0, true), new RequirementConfig("Onion", 1, 0, true) }); ItemConfig val2 = val; CustomItem val3 = new CustomItem(id, "RawMeat", val2); GameObject itemPrefab = val3.ItemPrefab; ItemData itemData = val3.ItemDrop.m_itemData; SharedData shared = itemData.m_shared; shared.m_itemType = (ItemType)((!cooked) ? 1 : 2); shared.m_food = (cooked ? 65 : 0); shared.m_foodStamina = (cooked ? 40 : 0); shared.m_foodEitr = 0f; shared.m_foodBurnTime = (cooked ? 1500 : 0); shared.m_foodRegen = (cooked ? 4 : 0); shared.m_maxStackSize = 20; shared.m_weight = 1f; shared.m_teleportable = true; shared.m_maxQuality = 1; shared.m_isDrink = false; shared.m_consumeStatusEffect = null; shared.m_appendToolTip = null; shared.m_useDurability = false; shared.m_value = 0; itemData.m_stack = 1; itemData.m_quality = 1; LODGroup[] componentsInChildren = itemPrefab.GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val4 in componentsInChildren) { Object.DestroyImmediate((Object)(object)val4); } MeshRenderer[] componentsInChildren2 = itemPrefab.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val5 in componentsInChildren2) { ((Renderer)val5).enabled = false; } SkinnedMeshRenderer[] componentsInChildren3 = itemPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val6 in componentsInChildren3) { ((Renderer)val6).enabled = false; } Collider[] componentsInChildren4 = itemPrefab.GetComponentsInChildren<Collider>(true); foreach (Collider val7 in componentsInChildren4) { val7.enabled = false; } string[] array = new string[2] { "attach", "attach_cook" }; foreach (string text in array) { Transform val8 = itemPrefab.transform.Find(text); if (Object.op_Implicit((Object)(object)val8)) { ((Object)val8).name = "unused_" + text; } } itemPrefab.transform.localScale = Vector3.one; GameObject parent = Child(itemPrefab, "attach", Vector3.zero); Bounds val9 = BuildModel(parent, manifest.assets.First((AssetEntry a) => a.name == id)); BoxCollider val10 = itemPrefab.AddComponent<BoxCollider>(); val10.center = ((Bounds)(ref val9)).center; val10.size = ((Bounds)(ref val9)).size; Rigidbody component = itemPrefab.GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component)) { component.mass = 1f; } if (HasGraphics) { shared.m_icons = (Sprite[])(object)new Sprite[1] { LoadIcon(id) }; } return val3; } private CustomPiece CreateMakali(ItemDrop raw, ItemDrop cooked, AssetManifest manifest) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: 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_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_0598: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_05de: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Unknown result type (might be due to invalid IL or missing references) //IL_068f: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = PrefabManager.Instance.GetPrefab("piece_cookingstation_iron"); CookingStation component = prefab.GetComponent<CookingStation>(); PieceConfig val = new PieceConfig(); val.Name = "Makali"; val.Description = "A charcoal brazier for six Mtsvadi skewers. Load coal on the left."; val.PieceTable = "Hammer"; val.Category = "Crafting"; val.CraftingStation = "forge"; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Iron", 4, 0, true), new RequirementConfig("Silver", 8, 0, true) }; CustomPiece val2 = new CustomPiece("SGC_Makali", "piece_cookingstation_iron", val); GameObject piecePrefab = val2.PiecePrefab; piecePrefab.transform.localScale = Vector3.one; LODGroup[] componentsInChildren = piecePrefab.GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val3 in componentsInChildren) { Object.DestroyImmediate((Object)(object)val3); } Transform[] array = ((IEnumerable)piecePrefab.transform).Cast<Transform>().ToArray(); foreach (Transform val4 in array) { Object.DestroyImmediate((Object)(object)((Component)val4).gameObject); } CookingStation component2 = piecePrefab.GetComponent<CookingStation>(); component2.m_name = "Makali"; component2.m_requireFire = false; component2.m_useFuel = true; component2.m_useFueldWhileEmpty = false; component2.m_fuelItem = PrefabManager.Instance.GetPrefab("Coal").GetComponent<ItemDrop>(); component2.m_overCookedItem = component2.m_fuelItem; component2.m_maxFuel = 10; component2.m_secPerFuel = 180; component2.m_canOvercookItems = true; component2.m_canGiveBonusYield = false; component2.m_moveObjectWhileCooking = false; component2.m_fireCheckPoints = (Transform[])(object)new Transform[0]; List<ItemConversion> list = new List<ItemConversion>(); ItemConversion val5 = new ItemConversion(); val5.m_from = raw; val5.m_to = cooked; val5.m_cookTime = 45f; list.Add(val5); component2.m_conversion = list; component2.m_incompatibleItems = new List<ItemMessage>(); component2.m_donePS = (ParticleSystem[])(object)new ParticleSystem[0]; component2.m_burntPS = (ParticleSystem[])(object)new ParticleSystem[0]; component2.m_addEffect = SoundEffects(component.m_addEffect); component2.m_doneEffect = SoundEffects(component.m_doneEffect); component2.m_overcookedEffect = SoundEffects(component.m_overcookedEffect); component2.m_pickEffector = SoundEffects(component.m_pickEffector); component2.m_fuelAddedEffects = SoundEffects(PrefabManager.Instance.GetPrefab("smelter").GetComponent<Smelter>().m_fuelAddedEffects); component2.m_haveFireObject = null; component2.m_cookingObject = null; component2.m_addItemTooltip = "Place raw Mtsvadi"; component2.m_fullyCookedTooltip = "Collect Mtsvadi"; component2.m_noCookableItemsMessage = "You have no raw Mtsvadi"; GameObject val6 = Child(piecePrefab, "model", Vector3.zero); AssetEntry asset = manifest.assets.First((AssetEntry a) => a.name == "SGC_Makali"); BuildModel(val6, asset); component2.m_haveFuelObject = ((Component)val6.transform.Find("Makali_EmberGlow")).gameObject; component2.m_haveFuelObject.SetActive(false); component2.m_spawnPoint = Child(piecePrefab, "output", Anchor(asset, "output")).transform; component2.m_spawnForce = 1f; component2.m_slots = (Transform[])(object)new Transform[6]; for (int num = 0; num < 6; num++) { GameObject val7 = Object.Instantiate<GameObject>(((Component)component.m_slots[0]).gameObject, piecePrefab.transform, false); ((Object)val7).name = "slot_" + (num + 1); val7.transform.localPosition = Anchor(asset, ((Object)val7).name); val7.transform.localRotation = Quaternion.identity; val7.transform.localScale = Vector3.one; Transform[] array2 = ((IEnumerable)val7.transform).Cast<Transform>().ToArray(); foreach (Transform val8 in array2) { Object.DestroyImmediate((Object)(object)((Component)val8).gameObject); } ParticleSystem component3 = val7.GetComponent<ParticleSystem>(); component3.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = component3.main; ((MainModule)(ref main)).startSize = new MinMaxCurve(0.06f, 0.13f); ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.6f, 1.3f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.12f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.65f, 0.65f, 0.65f, 0.12f)); ((MainModule)(ref main)).maxParticles = 12; EmissionModule emission = component3.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(1.5f); ((EmissionModule)(ref emission)).enabled = false; ShapeModule shape = component3.shape; ((ShapeModule)(ref shape)).radius = 0.05f; AudioSource component4 = val7.GetComponent<AudioSource>(); component4.volume = 0.18f; component4.spatialBlend = 1f; component4.minDistance = 1.5f; component4.maxDistance = 12f; component4.mute = true; component4.rolloffMode = (AudioRolloffMode)0; ((Behaviour)component4).enabled = true; component4.loop = true; component4.playOnAwake = false; AudioClip val9 = ((IEnumerable<AudioClip>)Resources.FindObjectsOfTypeAll<AudioClip>()).FirstOrDefault((Func<AudioClip, bool>)((AudioClip a) => ((Object)a).name == "Sizzle_FleshBurning_Loop")); if (Object.op_Implicit((Object)(object)val9)) { component4.clip = val9; } component2.m_slots[num] = val7.transform; } component2.m_addFoodSwitch = MakeSwitch(piecePrefab, "add_skewers", new Vector3(0f, 0.87f, 0f), new Vector3(1.34f, 0.16f, 0.7f)); component2.m_addFuelSwitch = MakeSwitch(piecePrefab, "add_coal_left", Anchor(asset, "fuel_left"), new Vector3(0.3f, 0.24f, 0.47f)); AddBox(piecePrefab, new Vector3(0f, 0.735f, 0f), new Vector3(1.42f, 0.26f, 0.68f)); float[] array3 = new float[2] { -0.63f, 0.63f }; foreach (float num4 in array3) { float[] array4 = new float[2] { -0.27f, 0.27f }; foreach (float num6 in array4) { AddBox(piecePrefab, new Vector3(num4, 0.33f, num6), new Vector3(0.08f, 0.61f, 0.08f)); } } WearNTear component5 = piecePrefab.GetComponent<WearNTear>(); component5.m_new = val6; component5.m_worn = val6; component5.m_broken = val6; component5.m_wet = null; component5.m_fragmentRoots = (GameObject[])(object)new GameObject[1] { val6 }; component5.m_autoCreateFragments = true; component5.m_noRoofWear = false; component5.m_health = 500f; piecePrefab.AddComponent<Makali>(); if (HasGraphics) { val2.Piece.m_icon = LoadIcon("SGC_Makali"); } return val2; } private static EffectList SoundEffects(EffectList source) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown EffectList val = new EffectList(); val.m_effectPrefabs = source.m_effectPrefabs.Where((EffectData e) => Object.op_Implicit((Object)(object)e.m_prefab) && (Object.op_Implicit((Object)(object)e.m_prefab.GetComponentInChildren<ZSFX>(true)) || Object.op_Implicit((Object)(object)e.m_prefab.GetComponentInChildren<AudioSource>(true)))).ToArray(); return val; } private Sprite LoadIcon(string id) { //IL_002c: 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) Texture2D val = LoadTexture(id + ".png", mipmaps: false); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static GameObject Child(GameObject parent, string name, Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.layer = parent.layer; val.transform.SetParent(parent.transform, false); val.transform.localPosition = position; return val; } private static void AddBox(GameObject go, Vector3 center, Vector3 size) { //IL_0008: 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) BoxCollider val = go.AddComponent<BoxCollider>(); val.center = center; val.size = size; } private static Switch MakeSwitch(GameObject parent, string name, Vector3 position, Vector3 size) { //IL_0002: 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_000f: Unknown result type (might be due to invalid IL or missing references) GameObject val = Child(parent, name, position); AddBox(val, Vector3.zero, size); return val.AddComponent<Switch>(); } private static Vector3 Anchor(AssetEntry asset, string name) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) float[] position = asset.anchors.First((AssetAnchor a) => a.name == name).position; return new Vector3(position[0], position[1], position[2]); } private Bounds BuildModel(GameObject parent, AssetEntry asset) { //IL_0002: 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_00a5: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown //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_011d: 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_0148: 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) //IL_023b: Unknown result type (might be due to invalid IL or missing references) Bounds result = default(Bounds); bool flag = true; Material val = (HasGraphics ? ((Renderer)PrefabManager.Instance.GetPrefab("RawMeat").GetComponentsInChildren<MeshRenderer>(true).First((MeshRenderer r) => Object.op_Implicit((Object)(object)((Renderer)r).sharedMaterial))).sharedMaterial : null); AssetPart[] parts = asset.parts; foreach (AssetPart assetPart in parts) { GameObject val2 = Child(parent, assetPart.name, Vector3.zero); Mesh val3 = LoadMesh(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(assetPart.mesh))); if (flag) { result = val3.bounds; flag = false; } else { ((Bounds)(ref result)).Encapsulate(val3.bounds); } if (!HasGraphics) { continue; } val2.AddComponent<MeshFilter>().sharedMesh = val3; Material val4 = new Material(val); ((Object)val4).name = assetPart.name + "_Material"; Texture2D val5 = LoadTexture(assetPart.texture, mipmaps: true); ((Texture)val5).wrapMode = (TextureWrapMode)(!(asset.name == "SGC_Makali")); val4.mainTexture = (Texture)(object)val5; val4.mainTextureScale = Vector2.one; val4.mainTextureOffset = Vector2.zero; if (val4.HasProperty("_Color")) { val4.SetColor("_Color", Color.white); } if (val4.HasProperty("_BumpMap")) { val4.SetTexture("_BumpMap", (Texture)null); } if (val4.HasProperty("_MetallicGlossMap")) { val4.SetTexture("_MetallicGlossMap", (Texture)null); } if (val4.HasProperty("_Metallic")) { val4.SetFloat("_Metallic", assetPart.metallic); } if (val4.HasProperty("_Glossiness")) { val4.SetFloat("_Glossiness", 1f - assetPart.roughness); } val4.DisableKeyword("_NORMALMAP"); val4.DisableKeyword("_METALLICGLOSSMAP"); if (assetPart.emission > 0f) { val4.EnableKeyword("_EMISSION"); if (val4.HasProperty("_EmissionMap")) { val4.SetTexture("_EmissionMap", (Texture)(object)val5); } if (val4.HasProperty("_EmissionColor")) { val4.SetColor("_EmissionColor", Color.white * assetPart.emission); } } ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = val4; } if (HasGraphics) { Renderer[] array = (from r in parent.GetComponentsInChildren<MeshRenderer>(true) where ((Renderer)r).enabled select r).Cast<Renderer>().ToArray(); if (array.Length > 0) { LODGroup val6 = parent.AddComponent<LODGroup>(); val6.SetLODs((LOD[])(object)new LOD[1] { new LOD(0.001f, array) }); val6.RecalculateBounds(); } } return result; } private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) assetDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets"); new Harmony("private.khinkali.food").PatchAll(typeof(Plugin).Assembly); PrefabManager.OnVanillaPrefabsAvailable += RegisterItems; } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterItems; } private void RegisterItems() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= RegisterItems; try { string[] array = new string[7] { "RawMeat", "DeerMeat", "LoxMeat", "BarleyFlour", "Cloudberry", "piece_preptable", "piece_cauldron" }; foreach (string text in array) { if (!Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(text))) { throw new InvalidOperationException("Required vanilla prefab missing: " + text); } } CustomItem val = CreateItem("KhinkaliMod_MincedMeat", "Minced meat", "Deer, boar and lox, finely chopped for a hearty filling.", food: false, "piece_preptable", 1, (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("DeerMeat", 1, 0, false), new RequirementConfig("RawMeat", 1, 0, false), new RequirementConfig("LoxMeat", 1, 0, false) }); CustomItem val2 = CreateItem("KhinkaliMod_Khinkali", "Khinkali", "A pleated dumpling filled with rich meat and broth. Hold it by the knot.", food: true, "piece_cauldron", 4, (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("KhinkaliMod_MincedMeat", 1, 0, false), new RequirementConfig("BarleyFlour", 2, 0, false) }); if (!ItemManager.Instance.AddItem(val)) { throw new InvalidOperationException("Could not register minced meat."); } if (!ItemManager.Instance.AddItem(val2)) { ItemManager.Instance.RemoveItem(val); throw new InvalidOperationException("Could not register Khinkali."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered minced meat and Khinkali: 80 health, 35 stamina, 1500 seconds, 5 regeneration. Recipes: prep table 1, cauldron 4."); RegisterMakali(); RegisterShoti(); ProtectAllFoodLODs(); RegisterServingTrayFoods(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("StvirisGeorgianCuisine registration failed. " + ex)); } } private CustomItem CreateItem(string id, string displayName, string description, bool food, string station, int level, RequirementConfig[] requirements) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Expected O, but got Unknown //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0363: 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_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Invalid comparison between Unknown and I4 //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04ae: Expected O, but got Unknown //IL_04e8: 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_0513: Unknown result type (might be due to invalid IL or missing references) //IL_05f3: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Unknown result type (might be due to invalid IL or missing references) ItemConfig val = new ItemConfig(); val.Name = displayName; val.Description = description; val.Amount = 1; val.Enabled = true; val.CraftingStation = station; val.MinStationLevel = level; val.RequireOnlyOneIngredient = false; val.StackSize = 20; val.Weight = (food ? 0.5f : 1f); val.Requirements = requirements; ItemConfig val2 = val; CustomItem val3 = new CustomItem(id, "RawMeat", val2); GameObject itemPrefab = val3.ItemPrefab; SharedData shared = val3.ItemDrop.m_itemData.m_shared; shared.m_itemType = (ItemType)((!food) ? 1 : 2); shared.m_maxStackSize = 20; shared.m_maxQuality = 1; shared.m_weight = (food ? 0.5f : 1f); shared.m_teleportable = true; shared.m_food = (food ? 80f : 0f); shared.m_foodStamina = (food ? 35f : 0f); shared.m_foodEitr = 0f; shared.m_foodBurnTime = (food ? 1500f : 0f); shared.m_foodRegen = (food ? 5f : 0f); shared.m_isDrink = false; shared.m_consumeStatusEffect = null; shared.m_appendToolTip = null; shared.m_useDurability = false; shared.m_value = 0; val3.ItemDrop.m_itemData.m_stack = 1; val3.ItemDrop.m_itemData.m_quality = 1; Material val4 = (from r in itemPrefab.GetComponentsInChildren<MeshRenderer>(true) select ((Renderer)r).sharedMaterial).FirstOrDefault((Func<Material, bool>)((Material m) => (Object)(object)m != (Object)null)); LODGroup[] componentsInChildren = itemPrefab.GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val5 in componentsInChildren) { Object.DestroyImmediate((Object)(object)val5); } MeshRenderer[] componentsInChildren2 = itemPrefab.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val6 in componentsInChildren2) { ((Renderer)val6).enabled = false; } SkinnedMeshRenderer[] componentsInChildren3 = itemPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val7 in componentsInChildren3) { ((Renderer)val7).enabled = false; } Collider[] componentsInChildren4 = itemPrefab.GetComponentsInChildren<Collider>(true); foreach (Collider val8 in componentsInChildren4) { val8.enabled = false; } Transform val9 = itemPrefab.transform.Find("attach"); if (Object.op_Implicit((Object)(object)val9)) { ((Object)val9).name = "vanilla_attach_disabled"; } GameObject val10 = new GameObject("attach"); val10.layer = itemPrefab.layer; val10.transform.SetParent(itemPrefab.transform, false); Mesh val11 = LoadMesh(id); string text = (food ? "Cloudberry" : "RawMeat"); Bounds worldMeshBounds = GetWorldMeshBounds(PrefabManager.Instance.GetPrefab(text)); float num5 = Mathf.Max(((Bounds)(ref worldMeshBounds)).size.x, ((Bounds)(ref worldMeshBounds)).size.z) * (food ? 0.85f : 1f); Bounds bounds = val11.bounds; float num6 = ((Bounds)(ref bounds)).size.x * Mathf.Abs(itemPrefab.transform.lossyScale.x); Bounds bounds2 = val11.bounds; float num7 = Mathf.Max(num6, ((Bounds)(ref bounds2)).size.z * Mathf.Abs(itemPrefab.transform.lossyScale.z)); if (num5 <= 0f || num7 <= 0f) { throw new InvalidOperationException("Invalid food display bounds."); } float num8 = num5 / num7; ((BaseUnityPlugin)this).Logger.LogInfo((object)(id + " ground width: " + num5.ToString("F3") + " m; scale " + num8.ToString("F2") + "; reference " + text)); val10.transform.localScale = Vector3.one * num8; BoxCollider val12 = itemPrefab.AddComponent<BoxCollider>(); Bounds bounds3 = val11.bounds; val12.center = ((Bounds)(ref bounds3)).center * num8; Bounds bounds4 = val11.bounds; val12.size = ((Bounds)(ref bounds4)).size * num8; Rigidbody component = itemPrefab.GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component)) { component.mass = shared.m_weight; } if ((int)SystemInfo.graphicsDeviceType != 4) { if (!Object.op_Implicit((Object)(object)val4)) { throw new InvalidOperationException("RawMeat has no mesh material to clone."); } val10.AddComponent<MeshFilter>().sharedMesh = val11; Material val13 = new Material(val4); ((Object)val13).name = id + "_Material"; string filename = (food ? "Khinkali_BaseColor.png" : "MincedMeat_BaseColor.png"); Texture2D mainTexture = LoadTexture(filename, mipmaps: true); val13.mainTexture = (Texture)(object)mainTexture; val13.mainTextureScale = Vector2.one; val13.mainTextureOffset = Vector2.zero; if (val13.HasProperty("_Color")) { val13.SetColor("_Color", Color.white); } if (val13.HasProperty("_BumpMap")) { val13.SetTexture("_BumpMap", (Texture)null); } if (val13.HasProperty("_MetallicGlossMap")) { val13.SetTexture("_MetallicGlossMap", (Texture)null); } if (val13.HasProperty("_Metallic")) { val13.SetFloat("_Metallic", 0f); } if (val13.HasProperty("_Glossiness")) { val13.SetFloat("_Glossiness", 0.12f); } val13.DisableKeyword("_NORMALMAP"); val13.DisableKeyword("_METALLICGLOSSMAP"); ((Renderer)val10.AddComponent<MeshRenderer>()).sharedMaterial = val13; Texture2D val14 = LoadTexture(id + ".png", mipmaps: false); shared.m_icons = (Sprite[])(object)new Sprite[1] { Sprite.Create(val14, new Rect(0f, 0f, (float)((Texture)val14).width, (float)((Texture)val14).height), new Vector2(0.5f, 0.5f)) }; } return val3; } private static Bounds GetWorldMeshBounds(GameObject prefab) { //IL_0002: 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_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_0062: 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_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) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00c5: 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_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_00be: Unknown result type (might be due to invalid IL or missing references) Bounds result = default(Bounds); bool flag = false; MeshFilter[] componentsInChildren = prefab.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val.sharedMesh)) { continue; } MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>(); if (!Object.op_Implicit((Object)(object)component) || !((Renderer)component).enabled) { continue; } Bounds bounds = val.sharedMesh.bounds; for (int j = 0; j < 8; j++) { Vector3 val2 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))); Vector3 val3 = ((Component)val).transform.TransformPoint(val2); if (!flag) { result = new Bounds(val3, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val3); } } } if (!flag) { throw new InvalidOperationException("No visible mesh bounds for " + ((Object)prefab).name); } return result; } private Texture2D LoadTexture(string filename, bool mipmaps) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, mipmaps); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(assetDirectory, filename)))) { throw new InvalidDataException("Invalid PNG: " + filename); } ((Object)val).name = filename; ((Texture)val).filterMode = (FilterMode)(!mipmaps); ((Texture)val).wrapMode = (TextureWrapMode)1; return val; } private Mesh LoadMesh(string id) { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown MeshData meshData = JsonUtility.FromJson<MeshData>(File.ReadAllText(Path.Combine(assetDirectory, id + ".mesh.json"))); if (meshData == null || meshData.positions == null || meshData.positions.Length == 0 || meshData.positions.Length % 3 != 0) { throw new InvalidDataException("Invalid vertex data: " + id); } int count = meshData.positions.Length / 3; if (meshData.normals == null || meshData.normals.Length != count * 3 || meshData.uv == null || meshData.uv.Length != count * 2 || meshData.triangles == null || meshData.triangles.Length % 3 != 0 || meshData.triangles.Any((int i) => i < 0 || i >= count)) { throw new InvalidDataException("Invalid topology/UVs: " + id); } Vector3[] array = (Vector3[])(object)new Vector3[count]; Vector3[] array2 = (Vector3[])(object)new Vector3[count]; Vector2[] array3 = (Vector2[])(object)new Vector2[count]; for (int num = 0; num < count; num++) { ref Vector3 reference = ref array[num]; reference = new Vector3(meshData.positions[num * 3], meshData.positions[num * 3 + 1], meshData.positions[num * 3 + 2]); ref Vector3 reference2 = ref array2[num]; reference2 = new Vector3(meshData.normals[num * 3], meshData.normals[num * 3 + 1], meshData.normals[num * 3 + 2]); ref Vector2 reference3 = ref array3[num]; reference3 = new Vector2(meshData.uv[num * 2], meshData.uv[num * 2 + 1]); } Mesh val = new Mesh(); ((Object)val).name = id; val.vertices = array; val.normals = array2; val.uv = array3; val.triangles = meshData.triangles; Mesh val2 = val; val2.RecalculateBounds(); return val2; } private void RegisterServingTrayFoods() { GameObject prefab = PrefabManager.Instance.GetPrefab("Bread"); PieceTable buildPieces = PrefabManager.Instance.GetPrefab("Feaster").GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces; string[] array = new string[3] { "KhinkaliMod_Khinkali", "SGC_Mtsvadi", "SGC_Shoti" }; foreach (string text in array) { GameObject itemPrefab = ItemManager.Instance.GetItem(text).ItemPrefab; ItemDrop item = itemPrefab.GetComponent<ItemDrop>(); SharedData shared = item.m_itemData.m_shared; GameObject gameObject = ((Component)itemPrefab.transform.Find("attach")).gameObject; foreach (Collider item2 in from c in itemPrefab.GetComponentsInChildren<Collider>(true) where !c.enabled select c) { Object.DestroyImmediate((Object)(object)item2); } Piece val = itemPrefab.GetComponent<Piece>() ?? itemPrefab.AddComponent<Piece>(); WearNTear val2 = itemPrefab.GetComponent<WearNTear>() ?? itemPrefab.AddComponent<WearNTear>(); CopyServingFields<Piece>(prefab.GetComponent<Piece>(), val); CopyServingFields<WearNTear>(prefab.GetComponent<WearNTear>(), val2); val.m_name = shared.m_name; val.m_description = shared.m_description; val.m_icon = shared.m_icons.FirstOrDefault(); val.m_resources = prefab.GetComponent<Piece>().m_resources.Select(delegate(Requirement r) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown Requirement val4 = new Requirement(); CopyServingFields<Requirement>(r, val4); val4.m_resItem = item; return val4; }).ToArray(); val2.m_new = gameObject; val2.m_worn = gameObject; val2.m_broken = gameObject; val2.m_fragmentRoots = (GameObject[])(object)new GameObject[1] { gameObject }; val2.m_nonSolidRenderers = new List<Renderer>(); if (!Object.op_Implicit((Object)(object)itemPrefab.GetComponent<ServingTrayFood>())) { itemPrefab.AddComponent<ServingTrayFood>(); } if (!Object.op_Implicit((Object)(object)item.m_pieceDisabledObj)) { Transform val3 = ((IEnumerable<Transform>)itemPrefab.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform p) => ((Object)p).name.IndexOf("ItemSparkles", StringComparison.OrdinalIgnoreCase) >= 0)); if (Object.op_Implicit((Object)(object)val3)) { item.m_pieceDisabledObj = ((Component)val3).gameObject; } } if (!buildPieces.m_pieces.Contains(itemPrefab)) { buildPieces.m_pieces.Add(itemPrefab); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered Khinkali, Mtsvadi and Shoti in the serving tray."); } private static void CopyServingFields<T>(T source, T target) { FieldInfo[] fields = typeof(T).GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (!typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType)) { fieldInfo.SetValue(target, fieldInfo.GetValue(source)); } } } private void RegisterShoti() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Expected O, but got Unknown Recipe val = Resources.FindObjectsOfTypeAll<Recipe>().First((Recipe r) => Object.op_Implicit((Object)(object)r.m_item) && ((Object)r.m_item).name == "BreadDough"); CookingStation component = PrefabManager.Instance.GetPrefab("piece_oven").GetComponent<CookingStation>(); ItemConversion val2 = component.m_conversion.First((ItemConversion c) => Object.op_Implicit((Object)(object)c.m_from) && ((Object)c.m_from).name == "BreadDough" && ((Object)c.m_to).name == "Bread"); Fermenter component2 = PrefabManager.Instance.GetPrefab("fermenter").GetComponent<Fermenter>(); AssetManifest manifest = JsonConvert.DeserializeObject<AssetManifest>(File.ReadAllText(Path.Combine(assetDirectory, "Shoti.assets.json"))); int minStationLevel = val.m_minStationLevel; CustomItem mix = CreateShotiItem("SGC_ShotiStarterMix", "Shoti starter mix", "Flour and water, stirred together. Ferment for ten minutes to yield three Shoti starters.", "RawMeat", minStationLevel, (RequirementConfig[])(object)new RequirementConfig[1] { new RequirementConfig("BarleyFlour", 6, 0, false) }, manifest); CustomItem val3 = CreateShotiItem("SGC_ShotiStarter", "Shoti starter", "A lively, bubbly bread starter, ready to raise Shoti dough.", "RawMeat", minStationLevel, (RequirementConfig[])(object)new RequirementConfig[0], manifest); CustomItem dough = CreateShotiItem("SGC_ShotiDough", "Shoti dough", "Leavened barley dough. Bake it in a stone oven.", "BreadDough", minStationLevel, (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("BarleyFlour", 10, 0, false), new RequirementConfig("SGC_ShotiStarter", 1, 0, false) }, null); CustomItem val4 = CreateShotiItem("SGC_Shoti", "Shoti", "A long Georgian loaf with a crisp, toasted crust and a soft heart.", "Bread", minStationLevel, (RequirementConfig[])(object)new RequirementConfig[0], manifest); CustomItem[] array = (CustomItem[])(object)new CustomItem[4] { mix, val3, dough, val4 }; List<CustomItem> list = new List<CustomItem>(); try { CustomItem[] array2 = array; foreach (CustomItem val5 in array2) { if (!ItemManager.Instance.AddItem(val5)) { throw new InvalidOperationException("Could not register " + ((Object)val5.ItemPrefab).name); } list.Add(val5); } List<ItemConversion> conversion = component2.m_conversion; ItemConversion val6 = new ItemConversion(); val6.m_from = mix.ItemDrop; val6.m_to = val3.ItemDrop; val6.m_producedItems = 3; conversion.Add(val6); List<ItemConversion> conversion2 = component.m_conversion; ItemConversion val7 = new ItemConversion(); val7.m_from = dough.ItemDrop; val7.m_to = val4.ItemDrop; val7.m_cookTime = val2.m_cookTime; conversion2.Add(val7); } catch { component2.m_conversion.RemoveAll((ItemConversion c) => (Object)(object)c.m_from == (Object)(object)mix.ItemDrop); component.m_conversion.RemoveAll((ItemConversion c) => (Object)(object)c.m_from == (Object)(object)dough.ItemDrop); foreach (CustomItem item in list) { ItemManager.Instance.RemoveItem(item); } throw; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered Shoti: preparation level " + minStationLevel + ", 600-second fermentation yielding 3 starters, vanilla bread baking time " + val2.m_cookTime + " seconds.")); } private CustomItem CreateShotiItem(string id, string name, string description, string template, int level, RequirementConfig[] requirements, AssetManifest manifest) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00ba: 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_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: 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_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_031c: 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_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) bool flag = id == "SGC_Shoti"; string text = id; ItemConfig val = new ItemConfig(); val.Name = name; val.Description = description; val.StackSize = 20; val.Weight = 1f; val.Amount = 1; val.Enabled = true; val.CraftingStation = ((requirements.Length > 0) ? "piece_preptable" : null); val.MinStationLevel = level; val.Requirements = requirements; CustomItem val2 = new CustomItem(text, template, val); GameObject itemPrefab = val2.ItemPrefab; ItemData itemData = val2.ItemDrop.m_itemData; SharedData shared = itemData.m_shared; shared.m_itemType = (ItemType)((!flag) ? 1 : 2); shared.m_food = (flag ? 25 : 0); shared.m_foodStamina = (flag ? 80 : 0); shared.m_foodEitr = 0f; shared.m_foodBurnTime = (flag ? 1200 : 0); shared.m_foodRegen = (flag ? 5 : 0); shared.m_maxStackSize = 20; shared.m_weight = 1f; shared.m_teleportable = true; shared.m_maxQuality = 1; shared.m_isDrink = false; shared.m_consumeStatusEffect = null; shared.m_appendToolTip = null; shared.m_useDurability = false; shared.m_value = 0; itemData.m_stack = 1; itemData.m_quality = 1; Rigidbody component = itemPrefab.GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component)) { component.mass = 1f; } if (manifest == null) { return val2; } LODGroup[] componentsInChildren = itemPrefab.GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val3 in componentsInChildren) { Object.DestroyImmediate((Object)(object)val3); } MeshRenderer[] componentsInChildren2 = itemPrefab.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val4 in componentsInChildren2) { ((Renderer)val4).enabled = false; } SkinnedMeshRenderer[] componentsInChildren3 = itemPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren3) { ((Renderer)val5).enabled = false; } Collider[] componentsInChildren4 = itemPrefab.GetComponentsInChildren<Collider>(true); foreach (Collider val6 in componentsInChildren4) { val6.enabled = false; } string[] array = new string[2] { "attach", "attach_cook" }; foreach (string text2 in array) { Transform val7 = itemPrefab.transform.Find(text2); if (Object.op_Implicit((Object)(object)val7)) { ((Object)val7).name = "unused_" + text2; } } itemPrefab.transform.localScale = Vector3.one; GameObject val8 = Child(itemPrefab, "attach", Vector3.zero); Bounds val9 = BuildModel(val8, manifest.assets.First((AssetEntry a) => a.name == id)); BoxCollider val10 = itemPrefab.AddComponent<BoxCollider>(); val10.center = ((Bounds)(ref val9)).center; val10.size = ((Bounds)(ref val9)).size; if (flag) { Bounds worldMeshBounds = GetWorldMeshBounds(PrefabManager.Instance.GetPrefab("Bread")); float num = Mathf.Min(1f, Mathf.Max(((Bounds)(ref worldMeshBounds)).size.x, ((Bounds)(ref worldMeshBounds)).size.z) / Mathf.Max(((Bounds)(ref val9)).size.x, ((Bounds)(ref val9)).size.z)); GameObject val11 = Object.Instantiate<GameObject>(val8, itemPrefab.transform, false); ((Object)val11).name = "attach_cook"; val11.transform.localScale = Vector3.one * num; LODGroup[] componentsInChildren5 = val11.GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val12 in componentsInChildren5) { val12.enabled = false; } Renderer[] componentsInChildren6 = val11.GetComponentsInChildren<Renderer>(true); foreach (Renderer val13 in componentsInChildren6) { val13.enabled = false; } val11.AddComponent<ShotiCookVisual>(); } if (HasGraphics) { shared.m_icons = (Sprite[])(object)new Sprite[1] { LoadIcon(id) }; } return val2; } } public sealed class Makali : MonoBehaviour { [HarmonyPatch(typeof(CookingStation), "UpdateCooking")] private static class CookingPatch { private static bool Prefix(CookingStation __instance) { Makali component = ((Component)__instance).GetComponent<Makali>(); if (!Object.op_Implicit((Object)(object)component)) { return true; } component.Tick(); return false; } } [HarmonyPatch(typeof(CookingStation), "SetSlotVisual")] private static class SmokePatch { private static void Prefix(CookingStation __instance, string item, ref bool fireLit) { if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Makali>())) { fireLit = fireLit && item == "SGC_MtsvadiRaw"; } } } [HarmonyPatch(typeof(CookingStation), "HoverText")] private static class HoverPatch { private static void Postfix(CookingStation __instance, ref string __result) { Makali component = ((Component)__instance).GetComponent<Makali>(); if (Object.op_Implicit((Object)(object)component)) { __result += component.StatusText(); } } } [HarmonyPatch] private static class MutationPatch { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(CookingStation), "RPC_AddFuel", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(CookingStation), "RPC_AddItem", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(CookingStation), "RPC_RemoveDoneItem", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(CookingStation), "DropAllItems", (Type[])null, (Type[])null); } private static bool Prefix(CookingStation __instance, MethodBase __originalMethod, object[] __args) { Makali component = ((Component)__instance).GetComponent<Makali>(); if (!Object.op_Implicit((Object)(object)component)) { return true; } if (!component.Owner) { return false; } component.Tick(); if (__originalMethod.Name == "RPC_AddFuel" && component.Fuel > 9f) { component.Refund("Coal"); return false; } if (__originalMethod.Name == "RPC_AddItem") { if ((string)__args[1] != "SGC_MtsvadiRaw") { return false; } bool flag = false; for (int i = 0; i < 6; i++) { if (component.View.GetZDO().GetString("slot" + i, "") == "") { flag = true; } } if (!flag) { component.Refund("SGC_MtsvadiRaw"); return false; } } return true; } } private static readonly MethodInfo Delta = AccessTools.Method(typeof(CookingStation), "GetDeltaTime", (Type[])null, (Type[])null); private static readonly MethodInfo FuelGet = AccessTools.Method(typeof(CookingStation), "GetFuel", (Type[])null, (Type[])null); private static readonly MethodInfo FuelSet = AccessTools.Method(typeof(CookingStation), "SetFuel", (Type[])null, (Type[])null); private static readonly MethodInfo Visual = AccessTools.Method(typeof(CookingStation), "UpdateVisual", (Type[])null, (Type[])null); private static readonly MethodInfo Hover = AccessTools.Method(typeof(CookingStation), "HoverText", (Type[])null, (Type[])null); private CookingStation station; private ZNetView view; public float Fuel => (float)FuelGet.Invoke(Station, null); private CookingStation Station { get { if (!Object.op_Implicit((Object)(object)station)) { return station = ((Component)this).GetComponent<CookingStation>(); } return station; } } private ZNetView View { get { if (!Object.op_Implicit((Object)(object)view)) { return view = ((Component)this).GetComponent<ZNetView>(); } return view; } } public bool Owner { get { if (Object.op_Implicit((Object)(object)View) && View.IsValid()) { return View.IsOwner(); } return false; } } public void Tick() { //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_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_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_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)View) || !View.IsValid()) { return; } CookingStation val = Station; ZDO zDO = View.GetZDO(); if (Owner) { float elapsed = (float)Delta.Invoke(val, null); string[] array = new string[6]; float[] array2 = new float[6]; for (int i = 0; i < 6; i++) { array[i] = zDO.GetString("slot" + i, ""); array2[i] = zDO.GetFloat("slot" + i, 0f); } float coal = Fuel; float num = MakaliTiming.Advance(elapsed, ref coal, array, array2); if (num > 0f) { FuelSet.Invoke(val, new object[1] { coal }); for (int j = 0; j < 6; j++) { string text = zDO.GetString("slot" + j, ""); zDO.Set("slot" + j, array[j]); zDO.Set("slot" + j, array2[j]); zDO.Set("slotstatus" + j, (array[j] == "Coal") ? 2 : ((array[j] == "SGC_Mtsvadi") ? 1 : 0)); if (text != array[j]) { if (array[j] == "SGC_Mtsvadi") { val.m_doneEffect.Create(val.m_slots[j].position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } else if (array[j] == "Coal") { val.m_overcookedEffect.Create(val.m_slots[j].position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } } } } } Visual.Invoke(val, new object[1] { Fuel > 0f }); for (int k = 0; k < val.m_slots.Length; k++) { AudioSource component = ((Component)val.m_slots[k]).GetComponent<AudioSource>(); if (Object.op_Implicit((Object)(object)component) && ((Behaviour)component).isActiveAndEnabled) { bool flag = Fuel > 0f && zDO.GetString("slot" + k, "") == "SGC_MtsvadiRaw"; component.mute = !flag; if (flag && !component.isPlaying) { component.Play(); } else if (!flag && component.isPlaying) { component.Stop(); } } } if (Object.op_Implicit((Object)(object)val.m_addFoodSwitch)) { val.m_addFoodSwitch.m_hoverText = (string)Hover.Invoke(val, null); } } public string StatusText() { if (!Object.op_Implicit((Object)(object)View) || !View.IsValid()) { return ""; } int num = 0; int num2 = 0; int num3 = 0; for (int i = 0; i < 6; i++) { switch (View.GetZDO().GetString("slot" + i, "")) { case "SGC_MtsvadiRaw": num++; break; case "SGC_Mtsvadi": num2++; break; case "Coal": num3++; break; } } return "\nSkewers: " + (num + num2 + num3) + "/6 | Ready: " + num2 + ((num3 > 0) ? (" | Burnt: " + num3) : "") + "\nCoal: " + Fuel.ToString("0.0") + "/10" + ((Fuel <= 0f && num + num2 > 0) ? " — paused; add coal on the left" : ""); } public void Refund(string id) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = ZNetScene.instance.GetPrefab(id); if (Object.op_Implicit((Object)(object)prefab)) { Object.Instantiate<GameObject>(prefab, Station.m_spawnPoint.position, Quaternion.identity); } } } public static class MakaliTiming { public const string Raw = "SGC_MtsvadiRaw"; public const string Cooked = "SGC_Mtsvadi"; public const float CookSeconds = 45f; public const float BurnSeconds = 90f; public const float SecondsPerCoal = 180f; public static float Advance(float elapsed, ref float coal, string[] items, float[] progress) { float num = 0f; for (int i = 0; i < items.Length; i++) { if (items[i] == "SGC_MtsvadiRaw" || items[i] == "SGC_Mtsvadi") { num = Math.Max(num, 90f - progress[i]); } } float num2 = Math.Max(0f, Math.Min(Math.Max(0f, elapsed), Math.Min(Math.Max(0f, coal) * 180f, num))); coal = Math.Max(0f, coal - num2 / 180f); for (int j = 0; j < items.Length; j++) { if (!(items[j] != "SGC_MtsvadiRaw") || !(items[j] != "SGC_Mtsvadi")) { progress[j] = Math.Min(90f, progress[j] + num2); if (progress[j] >= 90f) { items[j] = "Coal"; } else if (progress[j] >= 45f) { items[j] = "SGC_Mtsvadi"; } } } return num2; } } public sealed class ServingTrayFood : MonoBehaviour { [HarmonyPatch(typeof(ItemDrop), "MakePiece")] private static class PlacedParticles { private static void Postfix(ItemDrop __instance) { if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<ServingTrayFood>())) { ParticleSystemRenderer component = ((Component)__instance).GetComponent<ParticleSystemRenderer>(); if (Object.op_Implicit((Object)(object)component)) { ((Renderer)component).enabled = false; } } } } } public sealed class ShotiCookVisual : MonoBehaviour { private void Awake() { bool enabled = !Object.op_Implicit((Object)(object)((Component)this).GetComponentInParent<ItemDrop>()); LODGroup[] componentsInChildren = ((Component)this).GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val in componentsInChildren) { val.enabled = enabled; } Renderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren2) { val2.enabled = enabled; } } } public static class Shoti { [HarmonyPatch(typeof(CookingStation), "OnInteract")] private static class YieldPatch { private static void Prefix(CookingStation __instance, out bool __state) { __state = __instance.m_canGiveBonusYield; if (NextReadyIsShoti(__instance)) { __instance.m_canGiveBonusYield = false; } } private static void Finalizer(CookingStation __instance, bool __state) { __instance.m_canGiveBonusYield = __state; } } [HarmonyPatch(typeof(CookingStation), "RPC_RemoveDoneItem")] private static class OwnerYieldPatch { private static void Prefix(CookingStation __instance, ref int __2) { if (NextReadyIsShoti(__instance)) { __2 = 1; } } } [HarmonyPatch(typeof(Fermenter), "GetStatus")] private static class DurationPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { FieldInfo field = AccessTools.Field(typeof(Fermenter), "m_fermentationDuration"); MethodInfo method = AccessTools.Method(typeof(Shoti), "FermentationDuration", (Type[])null, (Type[])null); bool patched = false; foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Ldfld && object.Equals(instruction.operand, field)) { instruction.opcode = OpCodes.Call; instruction.operand = method; patched = true; } yield return instruction; } if (!patched) { throw new InvalidOperationException("Valheim fermenter duration lookup changed; Shoti timing patch could not be applied."); } } } public const string Mix = "SGC_ShotiStarterMix"; public const string Starter = "SGC_ShotiStarter"; public const string Dough = "SGC_ShotiDough"; public const string Bread = "SGC_Shoti"; public static float FermentationDuration(Fermenter station) { ZNetView component = ((Component)station).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || component.GetZDO().GetInt(ZDOVars.s_content, 0) != StringExtensionMethods.GetStableHashCode("SGC_ShotiStarterMix")) { return station.m_fermentationDuration; } return 600f; } public static bool NextReadyIsShoti(CookingStation station) { ZNetView component = ((Component)station).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid()) { return false; } for (int i = 0; i < station.m_slots.Length; i++) { string text = component.GetZDO().GetString("slot" + i, ""); if (!(text == "")) { int num = component.GetZDO().GetInt("slotstatus" + i, 0); if (num == 1 || num == 2) { return text == "SGC_Shoti"; } } } return false; } }