Decompiled source of FlametalHammer v0.1.0

FlametalHammer.dll

Decompiled 2 weeks ago
using 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();
			}
		}
	}
}