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 FlametalHammer v0.1.0
FlametalHammer.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Adam Robichaud")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2026 Adam Robichaud")] [assembly: AssemblyDescription("A Flametal Hammer forged at the Black Forge that counts as having a Stonecutter in range wherever you build.")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+77ff767723d7ff106efe13c38e875b9629d256c1")] [assembly: AssemblyProduct("FlametalHammer")] [assembly: AssemblyTitle("FlametalHammer")] [assembly: AssemblyVersion("0.1.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 FlametalHammer { internal static class FlametalHammerItem { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDBAwakePatch { private static void Postfix(ObjectDB __instance) { Register(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDBCopyOtherDBPatch { private static void Postfix(ObjectDB __instance) { Register(__instance); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetSceneAwakePatch { private static void Prefix(ZNetScene __instance) { GameObject orCreatePrefab = GetOrCreatePrefab(((IEnumerable<GameObject>)__instance.m_prefabs).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => Object.op_Implicit((Object)(object)p) && ((Object)p).name == "Hammer"))); if (Object.op_Implicit((Object)(object)orCreatePrefab) && !__instance.m_prefabs.Contains(orCreatePrefab)) { __instance.m_prefabs.Add(orCreatePrefab); } } } [HarmonyPatch(typeof(Requirement), "GetAmount")] private static class GetAmountPatch { private static void Postfix(Requirement __instance, int qualityLevel, ref int __result) { if (__instance == _flametalRequirement && __instance != null) { __result = Plugin.FlametalCraftAmount.Value + Plugin.FlametalPerLevel.Value * (Mathf.Max(1, qualityLevel) - 1); } } } [HarmonyPatch(typeof(Recipe), "GetRequiredStationLevel")] private static class GetRequiredStationLevelPatch { private static void Postfix(Recipe __instance, ref int __result) { if (Object.op_Implicit((Object)(object)__instance) && (Object)(object)__instance == (Object)(object)_recipe) { __result = Mathf.Max(1, __instance.m_minStationLevel); } } } public const string PrefabName = "FlametalHammer"; public const string SharedName = "$item_hammer_flametal"; private const string DescriptionToken = "$item_hammer_flametal_description"; private const int MaxQuality = 4; private const string HammerPrefab = "Hammer"; private const string StonePrefab = "Stone"; private const string BlackForgePrefab = "blackforge"; private const string FlametalSharedName = "$item_flametal"; private static GameObject _container; private static GameObject _prefab; private static Recipe _recipe; private static Requirement _flametalRequirement; internal static Transform Container { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_container)) { _container = new GameObject("FlametalHammer_Prefabs"); _container.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_container); } return _container.transform; } } private static GameObject GetOrCreatePrefab(GameObject hammer) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)_prefab) || !Object.op_Implicit((Object)(object)hammer)) { return _prefab; } _prefab = Object.Instantiate<GameObject>(hammer, Container); ((Object)_prefab).name = "FlametalHammer"; ItemData itemData = _prefab.GetComponent<ItemDrop>().m_itemData; SharedData shared = hammer.GetComponent<ItemDrop>().m_itemData.m_shared; if (itemData.m_shared == shared) { itemData.m_shared = (SharedData)AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null).Invoke(shared, null); } SharedData shared2 = itemData.m_shared; shared2.m_name = "$item_hammer_flametal"; shared2.m_description = "$item_hammer_flametal_description"; shared2.m_maxQuality = 4; shared2.m_icons = (Sprite[])shared2.m_icons.Clone(); HeadTint.Apply(_prefab, shared2); Plugin.Log.LogInfo((object)("Created FlametalHammer from " + ((Object)hammer).name)); return _prefab; } private static Recipe GetOrCreateRecipe(ObjectDB db) { //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)_recipe)) { return _recipe; } Recipe val = ((IEnumerable<Recipe>)db.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item) && ((Object)r.m_item).name == "Hammer")); CraftingStation val2 = db.m_recipes.Select((Recipe r) => (!Object.op_Implicit((Object)(object)r)) ? null : r.m_craftingStation).FirstOrDefault((Func<CraftingStation, bool>)((CraftingStation s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "blackforge")); ItemDrop val3 = db.m_items.Select((GameObject i) => (!Object.op_Implicit((Object)(object)i)) ? null : i.GetComponent<ItemDrop>()).FirstOrDefault((Func<ItemDrop, bool>)((ItemDrop d) => Object.op_Implicit((Object)(object)d) && d.m_itemData.m_shared.m_name == "$item_flametal")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val3)) { Plugin.Log.LogWarning((object)(string.Format("Cannot build the {0} recipe: hammer recipe {1}, ", "FlametalHammer", Object.op_Implicit((Object)(object)val)) + $"black forge {Object.op_Implicit((Object)(object)val2)}, flametal {Object.op_Implicit((Object)(object)val3)}.")); return null; } _flametalRequirement = new Requirement { m_resItem = val3, m_amount = Plugin.FlametalCraftAmount.Value, m_amountPerLevel = Plugin.FlametalPerLevel.Value, m_recover = true }; _recipe = ScriptableObject.CreateInstance<Recipe>(); ((Object)_recipe).name = "Recipe_FlametalHammer"; ((Object)_recipe).hideFlags = (HideFlags)32; _recipe.m_item = _prefab.GetComponent<ItemDrop>(); _recipe.m_amount = 1; _recipe.m_enabled = true; _recipe.m_qualityResultAmountMultiplier = val.m_qualityResultAmountMultiplier; _recipe.m_listSortWeight = val.m_listSortWeight; _recipe.m_craftingStation = val2; _recipe.m_repairStation = null; _recipe.m_minStationLevel = Plugin.BlackForgeLevel.Value; _recipe.m_resources = val.m_resources.Where((Requirement r) => Object.op_Implicit((Object)(object)r.m_resItem) && ((Object)r.m_resItem).name != "Stone").Select((Func<Requirement, Requirement>)((Requirement r) => new Requirement { m_resItem = r.m_resItem, m_amount = r.m_amount, m_extraAmountOnlyOneIngredient = r.m_extraAmountOnlyOneIngredient, m_amountPerLevel = r.m_amountPerLevel, m_upgraderResource = r.m_upgraderResource, m_recover = r.m_recover })).Concat((IEnumerable<Requirement>)(object)new Requirement[1] { _flametalRequirement }) .ToArray(); return _recipe; } private static void Register(ObjectDB db) { GameObject itemPrefab = db.GetItemPrefab("Hammer"); if (!Object.op_Implicit((Object)(object)itemPrefab)) { return; } GameObject orCreatePrefab = GetOrCreatePrefab(itemPrefab); if (!db.m_items.Contains(orCreatePrefab)) { db.m_items.Add(orCreatePrefab); AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null).Invoke(db, null); } Recipe orCreateRecipe = GetOrCreateRecipe(db); if (Object.op_Implicit((Object)(object)orCreateRecipe)) { orCreateRecipe.m_minStationLevel = Plugin.BlackForgeLevel.Value; if (!db.m_recipes.Contains(orCreateRecipe)) { db.m_recipes.Add(orCreateRecipe); } } } } internal static class HeadTint { private static readonly Color Tint = new Color(0.8f, 0.88f, 1f); private const float Gain = 1.25f; private static readonly Vector2[] IconHeadOutline = (Vector2[])(object)new Vector2[9] { new Vector2(20f, 0f), new Vector2(45f, 7f), new Vector2(58f, 11f), new Vector2(55f, 23f), new Vector2(51f, 31f), new Vector2(37f, 26f), new Vector2(29f, 22f), new Vector2(15f, 18f), new Vector2(15f, 11f) }; private const float IconOutlineSize = 64f; private const float ModelHeadStart = 0.66f; private const int UvPadding = 2; internal static void Apply(GameObject prefab, SharedData shared) { if (shared.m_icons.Length != 0 && Object.op_Implicit((Object)(object)shared.m_icons[0])) { shared.m_icons[0] = TintIcon(shared.m_icons[0]); } MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val in componentsInChildren) { MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.sharedMesh) && Object.op_Implicit((Object)(object)((Renderer)val).sharedMaterial)) { TintModel(component.sharedMesh, val); } } } private static Color32 Recolor(Color32 c) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0069: 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) float num = (0.299f * (float)(int)c.r + 0.587f * (float)(int)c.g + 0.114f * (float)(int)c.b) / 255f * 1.25f; return new Color32(ToByte(num * Tint.r), ToByte(num * Tint.g), ToByte(num * Tint.b), c.a); } private static byte ToByte(float v) { return (byte)Mathf.Clamp(Mathf.RoundToInt(v * 255f), 0, 255); } private static Sprite TintIcon(Sprite icon) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) Rect textureRect = icon.textureRect; Texture2D val = CopyTexture((Texture)(object)icon.texture, textureRect, mipChain: false); int width = ((Texture)val).width; int height = ((Texture)val).height; Color32[] pixels = val.GetPixels32(); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (InsidePolygon(new Vector2(((float)j + 0.5f) * 64f / (float)width, ((float)(height - i) - 0.5f) * 64f / (float)height), IconHeadOutline)) { pixels[i * width + j] = Recolor(pixels[i * width + j]); } } } val.SetPixels32(pixels); val.Apply(false, true); float x = icon.pivot.x; Rect rect = icon.rect; float num = x / ((Rect)(ref rect)).width; float y = icon.pivot.y; rect = icon.rect; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(num, y / ((Rect)(ref rect)).height); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)width, (float)height), val2, icon.pixelsPerUnit); ((Object)obj).name = ((Object)icon).name + "_flametal"; ((Object)obj).hideFlags = (HideFlags)32; return obj; } private static bool InsidePolygon(Vector2 p, Vector2[] poly) { //IL_001b: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) bool flag = false; int num = 0; int num2 = poly.Length - 1; while (num < poly.Length) { if (poly[num].y > p.y != poly[num2].y > p.y && p.x < (poly[num2].x - poly[num].x) * (p.y - poly[num].y) / (poly[num2].y - poly[num].y) + poly[num].x) { flag = !flag; } num2 = num++; } return flag; } private static void TintModel(Mesh mesh, MeshRenderer renderer) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_00af: 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) Material sharedMaterial = ((Renderer)renderer).sharedMaterial; Texture val = (sharedMaterial.HasProperty("_MainTex") ? sharedMaterial.GetTexture("_MainTex") : null); if (!Object.op_Implicit((Object)(object)val)) { return; } if (!mesh.isReadable) { Plugin.Log.LogWarning((object)("Mesh " + ((Object)mesh).name + " is not readable; the model keeps its vanilla colors.")); return; } Texture2D val2 = CopyTexture(val, new Rect(0f, 0f, (float)val.width, (float)val.height), mipChain: true); int width = ((Texture)val2).width; int height = ((Texture)val2).height; bool[] array = HeadMask(mesh, width, height); Color32[] pixels = val2.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { if (array[i]) { pixels[i] = Recolor(pixels[i]); } } val2.SetPixels32(pixels); val2.Apply(true, true); Material val3 = new Material(sharedMaterial) { name = ((Object)sharedMaterial).name + "_flametal", hideFlags = (HideFlags)32 }; val3.SetTexture("_MainTex", (Texture)(object)val2); ((Renderer)renderer).sharedMaterial = val3; } private static bool[] HeadMask(Mesh mesh, int w, int h) { //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_001e: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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) Vector3[] vertices = mesh.vertices; Vector2[] uv = mesh.uv; int[] triangles = mesh.triangles; Bounds bounds = mesh.bounds; float num = ((Bounds)(ref bounds)).min.y + 0.66f * ((Bounds)(ref bounds)).size.y; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((float)w, (float)h); bool[] array = new bool[w * h]; bool[] array2 = new bool[w * h]; for (int i = 0; i < triangles.Length; i += 3) { int num2 = triangles[i]; int num3 = triangles[i + 1]; int num4 = triangles[i + 2]; FillTriangle((Mathf.Min(new float[3] { vertices[num2].y, vertices[num3].y, vertices[num4].y }) >= num) ? array : array2, w, h, Vector2.Scale(uv[num2], val), Vector2.Scale(uv[num3], val), Vector2.Scale(uv[num4], val)); } bool[] array3 = Dilate(array, w, h, 2); for (int j = 0; j < array3.Length; j++) { array3[j] &= !array2[j]; } return array3; } private static void FillTriangle(bool[] mask, int w, int h, Vector2 p0, Vector2 p1, Vector2 p2) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_0119: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(0, Mathf.FloorToInt(Mathf.Min(new float[3] { p0.x, p1.x, p2.x }))); int num2 = Mathf.Min(w - 1, Mathf.CeilToInt(Mathf.Max(new float[3] { p0.x, p1.x, p2.x }))); int num3 = Mathf.Max(0, Mathf.FloorToInt(Mathf.Min(new float[3] { p0.y, p1.y, p2.y }))); int num4 = Mathf.Min(h - 1, Mathf.CeilToInt(Mathf.Max(new float[3] { p0.y, p1.y, p2.y }))); Vector2 p3 = default(Vector2); for (int i = num3; i <= num4; i++) { for (int j = num; j <= num2; j++) { ((Vector2)(ref p3))..ctor((float)j + 0.5f, (float)i + 0.5f); float num5 = Edge(p0, p1, p3); float num6 = Edge(p1, p2, p3); float num7 = Edge(p2, p0, p3); if ((num5 >= 0f && num6 >= 0f && num7 >= 0f) || (num5 <= 0f && num6 <= 0f && num7 <= 0f)) { mask[i * w + j] = true; } } } } private static float Edge(Vector2 a, Vector2 b, Vector2 p) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) return (b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x); } private static bool[] Dilate(bool[] mask, int w, int h, int radius) { bool[] array = new bool[mask.Length]; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (!mask[i * w + j]) { continue; } for (int k = -radius; k <= radius; k++) { for (int l = -radius; l <= radius; l++) { int num = j + l; int num2 = i + k; if (num >= 0 && num < w && num2 >= 0 && num2 < h) { array[num2 * w + num] = true; } } } } } return array; } private static Texture2D CopyTexture(Texture source, Rect rect, bool mipChain) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_0060: 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_006c: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)0); RenderTexture active = RenderTexture.active; try { Graphics.Blit(source, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D((int)((Rect)(ref rect)).width, (int)((Rect)(ref rect)).height, (TextureFormat)4, mipChain, false) { name = ((Object)source).name + "_flametal", hideFlags = (HideFlags)32, filterMode = source.filterMode, wrapMode = source.wrapMode, anisoLevel = source.anisoLevel }; val.ReadPixels(rect, 0, 0, false); return val; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } } [BepInPlugin("com.puhpuhburr.flametalhammer", "FlametalHammer", "0.1.0")] public class Plugin : BaseUnityPlugin { public const string GUID = "com.puhpuhburr.flametalhammer"; public const string NAME = "FlametalHammer"; public const string VERSION = "0.1.0"; internal static ManualLogSource Log; internal static ConfigEntry<int> FlametalCraftAmount; internal static ConfigEntry<int> FlametalPerLevel; internal static ConfigEntry<int> BlackForgeLevel; private Harmony _harmony; private void Awake() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; FlametalCraftAmount = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Recipe", "FlametalCraftAmount", 5, new ConfigDescription("Flametal needed to forge the hammer at quality 1.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>())); FlametalPerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Recipe", "FlametalPerLevel", 5, new ConfigDescription("Extra Flametal added for each quality level. Upgrading to quality N costs FlametalCraftAmount + FlametalPerLevel * (N - 1).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>())); BlackForgeLevel = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Recipe", "BlackForgeLevel", 4, new ConfigDescription("Black Forge level needed to forge, upgrade (every quality) and repair the hammer. Takes effect the next time a world or the main menu loads.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6), Array.Empty<object>())); _harmony = new Harmony("com.puhpuhburr.flametalhammer"); _harmony.PatchAll(typeof(Plugin).Assembly); Translations.AddToLoadedLocalization(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class StonecutterPatches { [HarmonyPatch(typeof(CraftingStation), "HaveBuildStationInRange")] private static class HaveBuildStationInRangePatch { private static void Postfix(string name, Vector3 point, ref CraftingStation __result) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) if (Object.op_Implicit((Object)(object)__result)) { return; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !IsWieldingFlametalHammer((Humanoid)(object)localPlayer)) { return; } CraftingStation standIn = StandIn; if (Object.op_Implicit((Object)(object)standIn) && !(name != standIn.m_name)) { Vector3 val = ((Component)localPlayer).transform.position - point; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 1f) { __result = standIn; } } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] private static class EquipItemPatch { private static void Postfix(Humanoid __instance, ItemData item, bool __result) { if (__result && item != null && !(item.m_shared.m_name != "$item_hammer_flametal")) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer && Object.op_Implicit((Object)(object)StandIn)) { val.AddKnownStation(StandIn); } } } } private const string StonecutterPrefab = "piece_stonecutter"; private static readonly FieldRef<Humanoid, ItemData> RightItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_rightItem"); private static CraftingStation _standIn; private static CraftingStation StandIn { get { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_standIn) || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return _standIn; } GameObject prefab = ZNetScene.instance.GetPrefab("piece_stonecutter"); CraftingStation val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<CraftingStation>() : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } GameObject val2 = new GameObject("StonecutterStandIn"); val2.transform.SetParent(FlametalHammerItem.Container, false); _standIn = val2.AddComponent<CraftingStation>(); _standIn.m_name = val.m_name; _standIn.m_icon = val.m_icon; return _standIn; } } private static bool IsWieldingFlametalHammer(Humanoid humanoid) { ItemData val = RightItem.Invoke(humanoid); if (val != null) { return val.m_shared.m_name == "$item_hammer_flametal"; } return false; } } internal static class Translations { [HarmonyPatch(typeof(Localization), "SetupLanguage")] private static class SetupLanguagePatch { private static void Postfix(Localization __instance) { AddTo(__instance); } } private static readonly string[,] Words = new string[2, 2] { { "item_hammer_flametal", "Flametal Hammer" }, { "item_hammer_flametal_description", "A builder's hammer with a head of Flametal. Shapes stone as if a stonecutter stood beside you." } }; private static readonly FieldRef<Localization> LoadedInstance = AccessTools.StaticFieldRefAccess<Localization>(AccessTools.Field(typeof(Localization), "m_instance")); internal static void AddToLoadedLocalization() { Localization val = LoadedInstance.Invoke(); if (val != null) { AddTo(val); } } internal static void AddTo(Localization loc) { for (int i = 0; i < Words.GetLength(0); i++) { Traverse.Create((object)loc).Method("AddWord", new object[2] { Words[i, 0], Words[i, 1] }).GetValue(); } } } }