Decompiled source of RepairRequiresCoins v1.2.10

plugins\RepairRequiresMats.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.10")]
[assembly: AssemblyInformationalVersion("1.2.10+59113effb466be575e3be9a7312b70e36ffc844b")]
[assembly: AssemblyVersion("1.2.10.0")]
public class WeaponAndArmorValues
{
	public float BlackMetalScrap { get; set; }

	public float BlackMetal { get; set; }

	public float Bronze { get; set; }

	public float Chain { get; set; }

	public float Chitin { get; set; }

	public float Copper { get; set; }

	public float CopperOre { get; set; }

	public float Flametal { get; set; }

	public float FlametalOre { get; set; }

	public float Frometal { get; set; }

	public float FrometalOre { get; set; }

	public float FrostinfusedDarkmetal { get; set; }

	public float HeatedIron { get; set; }

	public float Heavymetal { get; set; }

	public float HeavymetalOre { get; set; }

	public float Heavyscale { get; set; }

	public float Iron { get; set; }

	public float LeatherScraps { get; set; }

	public float PrimordialIce { get; set; }

	public float ScrapIron { get; set; }

	public float Silver { get; set; }

	public float SilverOre { get; set; }

	public float Tin { get; set; }

	public float TinOre { get; set; }

	public float DeerHide { get; set; }

	public float TrollHide { get; set; }

	public float WolfPelt { get; set; }

	public float LoxPelt { get; set; }

	public float WitheredBone { get; set; }

	public float BoneFragments { get; set; }

	public float LinenThread { get; set; }

	public float ElderBark { get; set; }

	public float Obsidian { get; set; }

	public float FreezeGland { get; set; }

	public float Crystal { get; set; }

	public float YimirRemains { get; set; }

	public float HardAntler { get; set; }

	public float SalamanderFurTH { get; set; }

	public float WolfFang { get; set; }

	public float Root { get; set; }

	public float Flint { get; set; }

	public float Needle { get; set; }

	public float Wood { get; set; }

	public float FineWood { get; set; }

	public float RoundLog { get; set; }

	public float SerpentScale { get; set; }

	public float WorldTreeFragment { get; set; }

	public float BurningWorldTreeFragment { get; set; }

	public float Stone { get; set; }
}
namespace RepairRequiresMats;

[BepInPlugin("cjayride.RepairRequiresCoins", "Repair Requires Coins", "1.2.10")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class BepInExPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(UITooltip), "LateUpdate")]
	private static class UITooltip_LateUpdate_Patch
	{
		private static void Postfix(UITooltip __instance, UITooltip ___m_current, GameObject ___m_tooltip)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (modEnabled.Value && (Object)(object)___m_current == (Object)(object)__instance && (Object)(object)___m_tooltip != (Object)null && ((Object)((Component)___m_current).transform).name == "RepairButton")
			{
				___m_tooltip.transform.position = Input.mousePosition + new Vector3(-200f, -100f);
			}
		}
	}

	[HarmonyPatch(typeof(InventoryGui), "UpdateRepair")]
	private static class InventoryGui_UpdateRepair_Patch
	{
		private static void Postfix(InventoryGui __instance, ref List<ItemData> ___m_tempWornItems)
		{
			if (modEnabled.Value)
			{
				RefreshRepairOffer(___m_tempWornItems);
				___m_tempWornItems = new List<ItemData>(orderedWornItems);
				ApplyRepairTooltipSource();
				StyleRepairTooltipText();
			}
		}
	}

	[HarmonyPatch(typeof(UITooltip), "UpdateTextElements")]
	private static class UITooltip_UpdateTextElements_Patch
	{
		private static void Postfix(UITooltip __instance)
		{
			if (modEnabled.Value && !((Object)(object)__instance == (Object)null) && !string.IsNullOrEmpty(repairTooltipBody) && IsRepairButtonTooltip(__instance))
			{
				__instance.m_topic = repairTooltipTopic;
				__instance.m_text = repairTooltipBody;
				StyleRepairTooltipText();
			}
		}
	}

	[HarmonyPatch(typeof(InventoryGui), "CanRepair")]
	private static class InventoryGui_CanRepair_Patch
	{
		private static void Postfix(ItemData item, ref bool __result)
		{
			if (modEnabled.Value)
			{
				if (!CanEverBeRepaired(item) || !IsAtRequiredRepairStation(item))
				{
					__result = false;
				}
				if ((paidRepairFrame != Time.frameCount || paidRepairItem != item) && (!allowUnpaidCanRepair & __result) && HasPositiveCost(RepairReqs(item)) && (paidRepairFrame != Time.frameCount || paidRepairItem != item))
				{
					__result = false;
				}
			}
		}
	}

	[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
	private static class InventoryGui_RepairOneItem_Patch
	{
		private static bool Prefix()
		{
			if (!modEnabled.Value)
			{
				return true;
			}
			allowUnpaidCanRepair = false;
			try
			{
				return TryPayForNextRepair();
			}
			catch
			{
				return false;
			}
		}

		private static void Postfix()
		{
			allowUnpaidCanRepair = true;
		}
	}

	public const string Version = "1.2.10";

	public const string ModName = "Repair Requires Coins";

	private static bool isDebug = true;

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<bool> showAllRepairsInToolTip;

	public static ConfigEntry<float> materialRequirementMult;

	public static ConfigEntry<string> titleTooltipColor;

	public static ConfigEntry<string> hasEnoughTooltipColor;

	public static ConfigEntry<string> notEnoughTooltipColor;

	private static List<ItemData> orderedWornItems = new List<ItemData>();

	private static int paidRepairFrame = -1;

	private static ItemData paidRepairItem;

	private static bool allowUnpaidCanRepair = true;

	private static string repairTooltipTopic = "Repair an Item";

	private static string repairTooltipBody = "";

	private static string repairTooltipBodyPlain = "";

	private static readonly List<RepairOfferLine> senealOfferLines = new List<RepairOfferLine>();

	private static bool senealDrawingOurTip;

	private static string senealStationLine = "";

	private static int senealCoinCount = 0;

	private static BepInExPlugin context;

	private static Assembly epicLootAssembly;

	private static MethodInfo epicLootIsMagic;

	private static MethodInfo epicLootGetRarity;

	private static MethodInfo epicLootGetEnchantCosts;

	private static MethodInfo swmarlyGetPocketCoins;

	private static MethodInfo swmarlySetPocketCoins;

	private const string SwmarlyQolGuid = "Swmarly.ValheimQOL";

	private const string CurrencyPocketGuid = "Azumatt.CurrencyPocket";

	private const string SwmarlyCoinKey = "SwmarlyValheimQOL_Coins";

	private const string CoinPocketCountKey = "CoinPocket_CoinCount";

	private static bool currencyPocketLoaded;

	public static WeaponAndArmorValues savedValues;

	public static ConfigEntry<bool> coinOnly;

	public static ConfigEntry<float> BlackMetalScrap;

	public static ConfigEntry<float> BlackMetal;

	public static ConfigEntry<float> Bronze;

	public static ConfigEntry<float> Chain;

	public static ConfigEntry<float> Chitin;

	public static ConfigEntry<float> Copper;

	public static ConfigEntry<float> CopperOre;

	public static ConfigEntry<float> Flametal;

	public static ConfigEntry<float> FlametalOre;

	public static ConfigEntry<float> Frometal;

	public static ConfigEntry<float> FrometalOre;

	public static ConfigEntry<float> FrostinfusedDarkmetal;

	public static ConfigEntry<float> HeatedIron;

	public static ConfigEntry<float> Heavymetal;

	public static ConfigEntry<float> HeavymetalOre;

	public static ConfigEntry<float> Heavyscale;

	public static ConfigEntry<float> Iron;

	public static ConfigEntry<float> ScrapIron;

	public static ConfigEntry<float> LeatherScraps;

	public static ConfigEntry<float> PrimordialIce;

	public static ConfigEntry<float> Silver;

	public static ConfigEntry<float> SilverOre;

	public static ConfigEntry<float> Tin;

	public static ConfigEntry<float> TinOre;

	public static ConfigEntry<float> DeerHide;

	public static ConfigEntry<float> TrollHide;

	public static ConfigEntry<float> WolfPelt;

	public static ConfigEntry<float> LoxPelt;

	public static ConfigEntry<float> WitheredBone;

	public static ConfigEntry<float> BoneFragments;

	public static ConfigEntry<float> LinenThread;

	public static ConfigEntry<float> ElderBark;

	public static ConfigEntry<float> Obsidian;

	public static ConfigEntry<float> FreezeGland;

	public static ConfigEntry<float> Crystal;

	public static ConfigEntry<float> YimirRemains;

	public static ConfigEntry<float> HardAntler;

	public static ConfigEntry<float> SalamanderFurTH;

	public static ConfigEntry<float> WolfFang;

	public static ConfigEntry<float> Root;

	public static ConfigEntry<float> Flint;

	public static ConfigEntry<float> Needle;

	public static ConfigEntry<float> Wood;

	public static ConfigEntry<float> FineWood;

	public static ConfigEntry<float> RoundLog;

	public static ConfigEntry<float> SerpentScale;

	public static ConfigEntry<float> WorldTreeFragment;

	public static ConfigEntry<float> BurningWorldTreeFragment;

	public static ConfigEntry<float> Stone;

	private static MethodInfo inventoryRemoveByName;

	private static CraftingStation liveLevelStation;

	private static int liveLevelValue;

	private static int liveLevelFrame;

	public static void Dbgl(string str = "", bool pref = true)
	{
		if (isDebug)
		{
			Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
		}
	}

	private void Awake()
	{
		context = this;
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
		showAllRepairsInToolTip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowAllRepairsInToolTip", true, "Show all repairs in tooltip when hovering over repair button.");
		titleTooltipColor = ((BaseUnityPlugin)this).Config.Bind<string>("General", "TitleTooltipColor", "FFFFFFFF", "Color to use in tooltip title.");
		hasEnoughTooltipColor = ((BaseUnityPlugin)this).Config.Bind<string>("General", "HasEnoughTooltipColor", "00FF00FF", "Color to use in tooltip for repairable item names.");
		notEnoughTooltipColor = ((BaseUnityPlugin)this).Config.Bind<string>("General", "NotEnoughTooltipColor", "FF0000FF", "Color to use in tooltip for items that cannot be repaired yet.");
		materialRequirementMult = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaterialRequirementMult", 0.5f, "Multiplier for amount of each material required.");
		coinOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CoinOnly", true, "If true, repair costs coins only. If false, repair costs coins plus the original materials.");
		savedValues = new WeaponAndArmorValues();
		BlackMetalScrap = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "BlackMetalScrap", 5f, "BlackMetalScrap exchange rate");
		BlackMetal = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "BlackMetal", 5f, "BlackMetal exchange rate");
		Bronze = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Bronze", 2f, "Bronze exchange rate");
		Chain = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Chain", 2f, "Chain exchange rate");
		Chitin = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Chitin", 2f, "Chitin exchange rate");
		Copper = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Copper", 1f, "Copper exchange rate");
		CopperOre = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "CopperOre", 1f, "CopperOre exchange rate");
		Flametal = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Flametal", 21f, "Flametal exchange rate");
		FlametalOre = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "FlametalOre", 21f, "FlametalOre exchange rate");
		Frometal = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Frometal", 13f, "Frometal exchange rate");
		FrometalOre = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "FrometalOre", 13f, "FrometalOre exchange rate");
		FrostinfusedDarkmetal = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "FrostinfusedDarkmetal", 85f, "FrostinfusedDarkmetal exchange rate");
		HeatedIron = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "HeatedIron", 2f, "HeatedIron exchange rate");
		Heavymetal = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Heavymetal", 8f, "Heavymetal exchange rate");
		HeavymetalOre = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "HeavymetalOre", 8f, "HeavymetalOre exchange rate");
		Heavyscale = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Heavyscale", 8f, "Heavyscale exchange rate");
		Iron = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Iron", 2f, "Iron exchange rate");
		ScrapIron = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "ScrapIron", 2f, "ScrapIron exchange rate");
		LeatherScraps = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "LeatherScraps", 1f, "LeatherScraps exchange rate");
		PrimordialIce = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "PrimordialIce", 13f, "PrimordialIce exchange rate");
		Silver = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Silver", 2f, "Silver exchange rate");
		SilverOre = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "SilverOre", 2f, "SilverOre exchange rate");
		Tin = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Tin", 1f, "Tin exchange rate");
		TinOre = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "TinOre", 1f, "TinOre exchange rate");
		DeerHide = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "DeerHide", 1f, "DeerHide exchange rate");
		TrollHide = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "TrollHide", 2f, "TrollHide exchange rate");
		WolfPelt = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "WolfPelt", 3f, "WolfPelt exchange rate");
		LoxPelt = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "LoxPelt", 5f, "LoxPelt exchange rate");
		WitheredBone = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "WitheredBone", 3f, "WitheredBone exchange rate");
		BoneFragments = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "BoneFragments", 1f, "BoneFragments exchange rate");
		LinenThread = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "LinenThread", 5f, "LinenThread exchange rate");
		ElderBark = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "ElderBark", 1f, "ElderBark exchange rate");
		Obsidian = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Obsidian", 5f, "Obsidian exchange rate");
		FreezeGland = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "FreezeGland", 1f, "FreezeGland exchange rate");
		Crystal = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Crystal", 1f, "Crystal exchange rate");
		YimirRemains = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "YimirRemains", 3f, "YimirRemains exchange rate");
		HardAntler = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "HardAntler", 1f, "HardAntler exchange rate");
		SalamanderFurTH = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "SalamanderFurTH", 9f, "SalamanderFurTH exchange rate");
		WolfFang = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "WolfFang", 3f, "WolfFang exchange rate");
		Root = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Root", 2f, "Root exchange rate");
		Flint = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Flint", 1f, "Flint exchange rate");
		Needle = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Needle", 5f, "Needle exchange rate");
		Wood = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Wood", 1f, "Wood exchange rate");
		FineWood = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "FineWood", 1f, "FineWood exchange rate");
		RoundLog = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "RoundLog", 1f, "RoundLog exchange rate");
		SerpentScale = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "SerpentScale", 3f, "SerpentScale exchange rate");
		WorldTreeFragment = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "WorldTreeFragment", 8f, "WorldTreeFragment exchange rate");
		BurningWorldTreeFragment = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "BurningWorldTreeFragment", 13f, "BurningWorldTreeFragment exchange rate");
		Stone = ((BaseUnityPlugin)this).Config.Bind<float>("Item Values", "Stone", 1f, "Stone exchange rate");
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		try
		{
			savedValues.BlackMetalScrap = BlackMetalScrap.Value;
			savedValues.BlackMetal = BlackMetal.Value;
			savedValues.Bronze = Bronze.Value;
			savedValues.BlackMetal = BlackMetal.Value;
			savedValues.Bronze = Bronze.Value;
			savedValues.Chain = Chain.Value;
			savedValues.Chitin = Chitin.Value;
			savedValues.Copper = Copper.Value;
			savedValues.CopperOre = CopperOre.Value;
			savedValues.Flametal = Flametal.Value;
			savedValues.FlametalOre = FlametalOre.Value;
			savedValues.Frometal = Frometal.Value;
			savedValues.FrometalOre = FrometalOre.Value;
			savedValues.FrostinfusedDarkmetal = FrostinfusedDarkmetal.Value;
			savedValues.HeatedIron = HeatedIron.Value;
			savedValues.Heavymetal = Heavymetal.Value;
			savedValues.HeavymetalOre = HeavymetalOre.Value;
			savedValues.Heavyscale = Heavyscale.Value;
			savedValues.Iron = Iron.Value;
			savedValues.LeatherScraps = LeatherScraps.Value;
			savedValues.PrimordialIce = PrimordialIce.Value;
			savedValues.ScrapIron = ScrapIron.Value;
			savedValues.Silver = Silver.Value;
			savedValues.SilverOre = SilverOre.Value;
			savedValues.Tin = Tin.Value;
			savedValues.TinOre = TinOre.Value;
			savedValues.DeerHide = DeerHide.Value;
			savedValues.TrollHide = TrollHide.Value;
			savedValues.WolfPelt = WolfPelt.Value;
			savedValues.LoxPelt = LoxPelt.Value;
			savedValues.WitheredBone = WitheredBone.Value;
			savedValues.BoneFragments = BoneFragments.Value;
			savedValues.LinenThread = LinenThread.Value;
			savedValues.ElderBark = ElderBark.Value;
			savedValues.Obsidian = Obsidian.Value;
			savedValues.FreezeGland = FreezeGland.Value;
			savedValues.Crystal = Crystal.Value;
			savedValues.YimirRemains = YimirRemains.Value;
			savedValues.HardAntler = HardAntler.Value;
			savedValues.SalamanderFurTH = SalamanderFurTH.Value;
			savedValues.WolfFang = WolfFang.Value;
			savedValues.Flint = Flint.Value;
			savedValues.Needle = Needle.Value;
			savedValues.Wood = Wood.Value;
			savedValues.FineWood = FineWood.Value;
			savedValues.RoundLog = RoundLog.Value;
			savedValues.SerpentScale = SerpentScale.Value;
			savedValues.WorldTreeFragment = WorldTreeFragment.Value;
			savedValues.BurningWorldTreeFragment = BurningWorldTreeFragment.Value;
			savedValues.Stone = Stone.Value;
		}
		catch
		{
			savedValues.BlackMetalScrap = 5f;
			savedValues.BlackMetal = 5f;
			savedValues.Bronze = 2f;
			savedValues.Chain = 2f;
			savedValues.Chitin = 2f;
			savedValues.Copper = 1f;
			savedValues.CopperOre = 1f;
			savedValues.Flametal = 21f;
			savedValues.FlametalOre = 21f;
			savedValues.Frometal = 13f;
			savedValues.FrometalOre = 85f;
			savedValues.FrostinfusedDarkmetal = 2f;
			savedValues.HeatedIron = 8f;
			savedValues.Heavymetal = 8f;
			savedValues.HeavymetalOre = 8f;
			savedValues.Heavyscale = 2f;
			savedValues.Iron = 1f;
			savedValues.LeatherScraps = 13f;
			savedValues.PrimordialIce = 2f;
			savedValues.ScrapIron = 2f;
			savedValues.Silver = 2f;
			savedValues.SilverOre = 2f;
			savedValues.Tin = 1f;
			savedValues.TinOre = 1f;
			savedValues.DeerHide = 1f;
			savedValues.TrollHide = 2f;
			savedValues.WolfPelt = 3f;
			savedValues.LoxPelt = 5f;
			savedValues.WitheredBone = 3f;
			savedValues.BoneFragments = 1f;
			savedValues.LinenThread = 5f;
			savedValues.ElderBark = 1f;
			savedValues.Obsidian = 5f;
			savedValues.FreezeGland = 1f;
			savedValues.Crystal = 1f;
			savedValues.YimirRemains = 3f;
			savedValues.HardAntler = 1f;
			savedValues.SalamanderFurTH = 9f;
			savedValues.WolfFang = 3f;
			savedValues.Root = 2f;
			savedValues.Flint = 1f;
			savedValues.Needle = 5f;
			savedValues.Wood = 1f;
			savedValues.FineWood = 1f;
			savedValues.RoundLog = 1f;
			savedValues.SerpentScale = 3f;
			savedValues.WorldTreeFragment = 8f;
			savedValues.BurningWorldTreeFragment = 13f;
			savedValues.Stone = 1f;
		}
	}

	private void Start()
	{
		if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot"))
		{
			epicLootAssembly = ((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType().Assembly;
			epicLootIsMagic = epicLootAssembly.GetType("EpicLoot.ItemDataExtensions").GetMethod("IsMagic", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null);
			epicLootGetRarity = epicLootAssembly.GetType("EpicLoot.ItemDataExtensions").GetMethod("GetRarity", BindingFlags.Static | BindingFlags.Public);
			epicLootGetEnchantCosts = epicLootAssembly.GetType("EpicLoot.Crafting.EnchantHelper").GetMethod("GetEnchantCosts", BindingFlags.Static | BindingFlags.Public);
			Dbgl($"Loaded Epic Loot assembly; epicLootIsMagic {epicLootIsMagic != null}, epicLootGetRarity {epicLootGetRarity != null}, epicLootGetEnchantCosts {epicLootGetEnchantCosts != null}");
		}
		TryPatchSeneaLRepairTip();
		currencyPocketLoaded = Chainloader.PluginInfos.ContainsKey("Azumatt.CurrencyPocket");
		if (currencyPocketLoaded)
		{
			Dbgl("Detected Azumatt CurrencyPocket; repairs can spend CoinPocket_CoinCount.");
		}
		if (Chainloader.PluginInfos.ContainsKey("Swmarly.ValheimQOL"))
		{
			Type type = ((object)Chainloader.PluginInfos["Swmarly.ValheimQOL"].Instance).GetType();
			BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			swmarlyGetPocketCoins = type.GetMethod("GetPocketCoins", bindingAttr, null, new Type[1] { typeof(Player) }, null);
			swmarlySetPocketCoins = type.GetMethod("SetPocketCoins", bindingAttr, null, new Type[2]
			{
				typeof(Player),
				typeof(int)
			}, null);
			Dbgl($"Loaded Swmarly Valheim QOL coin pocket; GetPocketCoins {swmarlyGetPocketCoins != null}, SetPocketCoins {swmarlySetPocketCoins != null}");
		}
	}

	private static bool HasEnoughRequirements(List<Requirement> reqs)
	{
		if (reqs == null || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			return true;
		}
		foreach (Requirement req in reqs)
		{
			if (Object.op_Implicit((Object)(object)req.m_resItem) && CountNamedItems(((Humanoid)Player.m_localPlayer).GetInventory(), req.m_resItem.m_itemData.m_shared.m_name) < req.m_amount)
			{
				return false;
			}
		}
		return true;
	}

	private static bool HasPositiveCost(List<Requirement> reqs)
	{
		if (reqs == null)
		{
			return false;
		}
		foreach (Requirement req in reqs)
		{
			if (req != null && req.m_amount > 0)
			{
				return true;
			}
		}
		return false;
	}

	private static void RefreshRepairOffer(IEnumerable<ItemData> wornItems)
	{
		List<RepairItemData> list = new List<RepairItemData>();
		List<RepairItemData> list2 = new List<RepairItemData>();
		List<RepairItemData> list3 = new List<RepairItemData>();
		List<RepairItemData> list4 = new List<RepairItemData>();
		List<string> list5 = new List<string>();
		List<string> list6 = new List<string>();
		senealOfferLines.Clear();
		foreach (ItemData item2 in wornItems ?? Enumerable.Empty<ItemData>())
		{
			if (!CanEverBeRepaired(item2))
			{
				continue;
			}
			if (!IsAtRequiredRepairStation(item2))
			{
				list4.Add(new RepairItemData(item2));
				continue;
			}
			List<Requirement> list7 = RepairReqs(item2);
			if (list7 == null)
			{
				list.Add(new RepairItemData(item2));
				continue;
			}
			List<string> list8 = new List<string>();
			foreach (Requirement item3 in list7)
			{
				if (item3.m_amount != 0)
				{
					list8.Add(FormatRequirementLine(item3));
				}
			}
			RepairItemData item = new RepairItemData(item2, list8);
			if (!HasEnoughRequirements(list7))
			{
				list3.Add(item);
			}
			else
			{
				list2.Add(item);
			}
		}
		orderedWornItems = new List<ItemData>();
		foreach (RepairItemData item4 in list)
		{
			string text = Localization.instance.Localize(item4.item.m_shared.m_name);
			list5.Add("<color=#FFFFFFFF>" + text + "</color>: <color=#00FF00FF>Free</color>");
			list6.Add(text + ": Free");
			senealOfferLines.Add(new RepairOfferLine
			{
				Name = text,
				Cost = "Free",
				Note = "",
				Icon = GetItemIcon(item4.item)
			});
			orderedWornItems.Add(item4.item);
		}
		foreach (RepairItemData item5 in list2)
		{
			AddCostLines(item5, list5, list6);
		}
		foreach (RepairItemData item6 in list3)
		{
			AddCostLines(item6, list5, list6);
		}
		foreach (RepairItemData item7 in list4)
		{
			string text2 = Localization.instance.Localize(item7.item.m_shared.m_name);
			string repairNeedLabel = GetRepairNeedLabel(item7.item);
			list5.Add("<color=#FFFFFFFF>" + text2 + "</color> - <color=#FF0000FF>" + repairNeedLabel + "</color>");
			list6.Add(text2 + " - " + repairNeedLabel);
			senealOfferLines.Add(new RepairOfferLine
			{
				Name = text2,
				Cost = "",
				Note = repairNeedLabel,
				Icon = GetItemIcon(item7.item)
			});
			orderedWornItems.Add(item7.item);
		}
		senealCoinCount = (((Object)(object)Player.m_localPlayer != (Object)null) ? CountNamedItems(((Humanoid)Player.m_localPlayer).GetInventory(), "$item_coins") : 0);
		senealStationLine = GetCurrentStationLevelLabel();
		if (list5.Count == 0)
		{
			list5.Add("No worn items at this station.");
		}
		list5.Add("-------------------- \r\n <b><color=#FFFFFFFF>Coins</color>: <color=#FFFF00FF>" + senealCoinCount + "</color></b>");
		repairTooltipTopic = "Repair an Item";
		repairTooltipBody = (string.IsNullOrEmpty(senealStationLine) ? "" : (senealStationLine + "\r\n -------------------- \r\n")) + string.Join("\r\n", list5);
		repairTooltipBodyPlain = BuildSeneaLPlainBody();
		if (!showAllRepairsInToolTip.Value)
		{
			repairTooltipBody = "Repair costs coins.\r\nCoins: " + senealCoinCount;
			repairTooltipBodyPlain = repairTooltipBody;
		}
	}

	private static void AddCostLines(RepairItemData rid, List<string> richLines, List<string> plainLines)
	{
		string text = Localization.instance.Localize(rid.item.m_shared.m_name);
		List<string> list = rid.reqstring ?? new List<string>();
		List<string> values = list.Select(StripRichText).ToList();
		richLines.Add("<color=#FFFFFFFF>" + text + "</color>: " + string.Join(", ", list));
		plainLines.Add(text + "  —  " + string.Join(", ", values));
		senealOfferLines.Add(new RepairOfferLine
		{
			Name = text,
			Cost = string.Join(", ", values),
			Note = "",
			Icon = GetItemIcon(rid.item)
		});
		orderedWornItems.Add(rid.item);
	}

	private static string BuildSeneaLPlainBody()
	{
		List<string> list = new List<string>();
		foreach (RepairOfferLine senealOfferLine in senealOfferLines)
		{
			if (!string.IsNullOrEmpty(senealOfferLine.Note) && string.IsNullOrEmpty(senealOfferLine.Cost))
			{
				list.Add(senealOfferLine.Name + "\n    " + senealOfferLine.Note);
			}
			else if (!string.IsNullOrEmpty(senealOfferLine.Cost))
			{
				list.Add(senealOfferLine.Name + "\n    " + senealOfferLine.Cost);
			}
			else
			{
				list.Add(senealOfferLine.Name);
			}
		}
		if (list.Count == 0)
		{
			list.Add("No worn items at this station.");
		}
		return string.Join("\n\n", list);
	}

	private static string StripRichText(string text)
	{
		if (string.IsNullOrEmpty(text))
		{
			return text;
		}
		return Regex.Replace(text, "<[^>]+>", "");
	}

	private static void RebuildWornItemsFromInventory()
	{
		List<ItemData> list = new List<ItemData>();
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			((Humanoid)Player.m_localPlayer).GetInventory().GetWornItems(list);
		}
		RefreshRepairOffer(list);
	}

	private static bool TryPayForNextRepair()
	{
		paidRepairItem = null;
		paidRepairFrame = -1;
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return true;
		}
		List<ItemData> list = new List<ItemData>();
		((Humanoid)Player.m_localPlayer).GetInventory().GetWornItems(list);
		RefreshRepairOffer(list);
		ItemData val = null;
		foreach (ItemData item in list)
		{
			if (!CanEverBeRepaired(item) || !IsAtRequiredRepairStation(item))
			{
				continue;
			}
			List<Requirement> list2 = RepairReqs(item, log: true);
			if (!HasPositiveCost(list2))
			{
				if (val == null)
				{
					val = item;
				}
				continue;
			}
			List<string> list3 = new List<string>();
			foreach (Requirement item2 in list2)
			{
				if (item2?.m_resItem?.m_itemData?.m_shared != null)
				{
					list3.Add(FormatRequirementLine(item2, colored: false));
				}
			}
			if (!HasEnoughRequirements(list2))
			{
				((Character)Player.m_localPlayer).Message((MessageType)1, "Require " + string.Join(", ", list3) + " to repair " + Localization.instance.Localize(item.m_shared.m_name), 0, (Sprite)null, false);
				return false;
			}
			ConsumeRepairRequirements(Player.m_localPlayer, list2);
			paidRepairItem = item;
			paidRepairFrame = Time.frameCount;
			((Character)Player.m_localPlayer).Message((MessageType)1, "Used " + string.Join(", ", list3) + " to repair " + Localization.instance.Localize(item.m_shared.m_name), 0, (Sprite)null, false);
			return true;
		}
		if (val != null)
		{
			paidRepairItem = val;
			paidRepairFrame = Time.frameCount;
			return true;
		}
		if (list.Count > 0)
		{
			((Character)Player.m_localPlayer).Message((MessageType)1, "Require coins to repair", 0, (Sprite)null, false);
			return false;
		}
		return true;
	}

	private static bool IsCoinName(string itemName)
	{
		return itemName == "$item_coins";
	}

	private static int CountNamedItems(Inventory inventory, string itemName)
	{
		if (inventory == null || string.IsNullOrEmpty(itemName))
		{
			return 0;
		}
		int num = 0;
		foreach (ItemData allItem in inventory.GetAllItems())
		{
			if (allItem?.m_shared?.m_name == itemName)
			{
				num += allItem.m_stack;
			}
		}
		if (IsCoinName(itemName) && (Object)(object)Player.m_localPlayer != (Object)null && inventory == ((Humanoid)Player.m_localPlayer).GetInventory())
		{
			num += GetPocketCoins(Player.m_localPlayer);
		}
		return num;
	}

	private static int GetPocketCoins(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return 0;
		}
		if (swmarlyGetPocketCoins != null)
		{
			try
			{
				return Math.Max(0, (int)swmarlyGetPocketCoins.Invoke(null, new object[1] { player }));
			}
			catch
			{
			}
		}
		if (player.m_customData == null)
		{
			return 0;
		}
		if (currencyPocketLoaded && TryReadCustomCoins(player, "CoinPocket_CoinCount", out var coins))
		{
			return coins;
		}
		if (TryReadCustomCoins(player, "SwmarlyValheimQOL_Coins", out var coins2))
		{
			return coins2;
		}
		if (TryReadCustomCoins(player, "CoinPocket_CoinCount", out coins2))
		{
			return coins2;
		}
		return 0;
	}

	private static bool TryReadCustomCoins(Player player, string key, out int coins)
	{
		coins = 0;
		if (player.m_customData.TryGetValue(key, out var value) && int.TryParse(value, out coins))
		{
			return coins >= 0;
		}
		return false;
	}

	private static void SetPocketCoins(Player player, int coins)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		coins = Math.Max(0, coins);
		if (swmarlySetPocketCoins != null)
		{
			try
			{
				swmarlySetPocketCoins.Invoke(null, new object[2] { player, coins });
				return;
			}
			catch
			{
			}
		}
		if (player.m_customData != null)
		{
			if (currencyPocketLoaded || player.m_customData.ContainsKey("CoinPocket_CoinCount"))
			{
				player.m_customData["CoinPocket_CoinCount"] = coins.ToString();
			}
			if (!currencyPocketLoaded || player.m_customData.ContainsKey("SwmarlyValheimQOL_Coins"))
			{
				player.m_customData["SwmarlyValheimQOL_Coins"] = coins.ToString();
			}
		}
	}

	private static void SpendCoins(Player player, int amount)
	{
		if ((Object)(object)player == (Object)null || amount <= 0)
		{
			return;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		int num = 0;
		if (inventory != null)
		{
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem?.m_shared?.m_name == "$item_coins")
				{
					num += allItem.m_stack;
				}
			}
		}
		int num2 = Math.Min(num, amount);
		if (num2 > 0)
		{
			RemoveNamedItems(inventory, "$item_coins", num2);
		}
		int num3 = amount - num2;
		if (num3 > 0)
		{
			SetPocketCoins(player, GetPocketCoins(player) - num3);
		}
	}

	private static void RemoveNamedItems(Inventory inventory, string itemName, int amount)
	{
		if (inventory == null || string.IsNullOrEmpty(itemName) || amount <= 0)
		{
			return;
		}
		if (inventoryRemoveByName == null)
		{
			MethodInfo methodInfo = null;
			foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeof(Inventory)))
			{
				if (!(declaredMethod.Name != "RemoveItem"))
				{
					ParameterInfo[] parameters = declaredMethod.GetParameters();
					if (parameters.Length >= 2 && !(parameters[0].ParameterType != typeof(string)) && !(parameters[1].ParameterType != typeof(int)) && (methodInfo == null || parameters.Length < methodInfo.GetParameters().Length))
					{
						methodInfo = declaredMethod;
					}
				}
			}
			inventoryRemoveByName = methodInfo;
		}
		if (inventoryRemoveByName != null)
		{
			ParameterInfo[] parameters2 = inventoryRemoveByName.GetParameters();
			object[] array = new object[parameters2.Length];
			array[0] = itemName;
			array[1] = amount;
			for (int i = 2; i < parameters2.Length; i++)
			{
				if (parameters2[i].HasDefaultValue)
				{
					array[i] = parameters2[i].DefaultValue;
				}
				else if (parameters2[i].ParameterType == typeof(int))
				{
					array[i] = -1;
				}
				else if (parameters2[i].ParameterType == typeof(bool))
				{
					array[i] = true;
				}
				else
				{
					array[i] = null;
				}
			}
			inventoryRemoveByName.Invoke(inventory, array);
			return;
		}
		List<ItemData> allItems = inventory.GetAllItems();
		int num = allItems.Count - 1;
		while (num >= 0 && amount > 0)
		{
			ItemData val = allItems[num];
			if (!(val?.m_shared?.m_name != itemName))
			{
				int num2 = Mathf.Min(val.m_stack, amount);
				val.m_stack -= num2;
				amount -= num2;
				if (val.m_stack <= 0)
				{
					inventory.RemoveItem(val);
				}
			}
			num--;
		}
	}

	private static void ConsumeRepairRequirements(Player player, List<Requirement> reqs)
	{
		if ((Object)(object)player == (Object)null || reqs == null)
		{
			return;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		foreach (Requirement req in reqs)
		{
			if (req?.m_resItem?.m_itemData?.m_shared != null)
			{
				string name = req.m_resItem.m_itemData.m_shared.m_name;
				if (IsCoinName(name))
				{
					SpendCoins(player, req.m_amount);
				}
				else
				{
					RemoveNamedItems(inventory, name, req.m_amount);
				}
			}
		}
	}

	private static void TryPatchSeneaLRepairTip()
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Expected O, but got Unknown
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Expected O, but got Unknown
		Type type = AccessTools.TypeByName("SeneaLUI.Inv.CraftView");
		MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "RepairTip", (Type[])null, (Type[])null) : null);
		if (!(methodInfo == null))
		{
			Harmony val = new Harmony("cjayride.RepairRequiresCoins.seneal");
			val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(BepInExPlugin), "SeneaLRepairTipPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			Type type2 = AccessTools.TypeByName("SeneaLUI.Components.Tooltip");
			MethodInfo methodInfo2 = ((type2 != null) ? AccessTools.Method(type2, "Build", (Type[])null, (Type[])null) : null);
			MethodInfo methodInfo3 = ((type2 != null) ? AccessTools.Method(type2, "LayRow", (Type[])null, (Type[])null) : null);
			if (methodInfo2 != null)
			{
				val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(BepInExPlugin), "SeneaLTooltipBuildPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (methodInfo3 != null)
			{
				val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(BepInExPlugin), "SeneaLTooltipLayRowPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			Dbgl("Patched SeneaL CraftView.RepairTip");
		}
	}

	private static Sprite GetItemIcon(ItemData item)
	{
		if (item == null)
		{
			return null;
		}
		try
		{
			return item.GetIcon();
		}
		catch
		{
			return (item.m_shared != null && item.m_shared.m_icons != null && item.m_shared.m_icons.Length != 0) ? item.m_shared.m_icons[0] : null;
		}
	}

	private static void SeneaLTooltipBuildPrefix(object tip)
	{
		senealDrawingOurTip = false;
		foreach (RepairOfferLine senealOfferLine in senealOfferLines)
		{
			senealOfferLine.IconUsed = false;
		}
		if (tip != null)
		{
			senealDrawingOurTip = Traverse.Create(tip).Field("Source").GetValue<string>() == "RepairRequiresCoins";
		}
	}

	private static void SeneaLTooltipLayRowPostfix(object row, object r)
	{
		if (!senealDrawingOurTip)
		{
			return;
		}
		try
		{
			object obj = row;
			object obj2 = r;
			if (!(Traverse.Create(obj2).Field("Label").GetValue() is TMP_Text))
			{
				if (!(Traverse.Create(obj).Field("Label").GetValue() is TMP_Text))
				{
					return;
				}
				object obj3 = obj;
				obj = obj2;
				obj2 = obj3;
			}
			string name = Traverse.Create(obj).Field("Label").GetValue() as string;
			object value = Traverse.Create(obj2).Field("Label").GetValue();
			TMP_Text val = (TMP_Text)((value is TMP_Text) ? value : null);
			if (!((Object)(object)val == (Object)null))
			{
				ApplySeneaLRowIcon(val, TakeOfferIcon(name));
			}
		}
		catch
		{
		}
	}

	private static Sprite TakeOfferIcon(string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return null;
		}
		foreach (RepairOfferLine senealOfferLine in senealOfferLines)
		{
			if (!senealOfferLine.IconUsed && !(senealOfferLine.Name != name))
			{
				senealOfferLine.IconUsed = true;
				return senealOfferLine.Icon;
			}
		}
		return null;
	}

	private static void ApplySeneaLRowIcon(TMP_Text label, Sprite icon)
	{
		//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_00be: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: 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)
		//IL_0136: 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_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)label == (Object)null)
		{
			return;
		}
		Transform val = label.transform.Find("RepairRequiresCoinsIcon");
		if ((Object)(object)icon == (Object)null)
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				((Component)val).gameObject.SetActive(false);
			}
			label.margin = new Vector4(0f, label.margin.y, label.margin.z, label.margin.w);
			return;
		}
		RectTransform val3;
		Image component;
		if ((Object)(object)val == (Object)null)
		{
			GameObject val2 = new GameObject("RepairRequiresCoinsIcon", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			})
			{
				layer = ((Component)label).gameObject.layer
			};
			val2.transform.SetParent(label.transform, false);
			val3 = val2.GetComponent<RectTransform>();
			val3.anchorMin = new Vector2(0f, 0.5f);
			val3.anchorMax = new Vector2(0f, 0.5f);
			val3.pivot = new Vector2(0f, 0.5f);
			val3.sizeDelta = new Vector2(20f, 20f);
			val3.anchoredPosition = new Vector2(0f, 0f);
			component = val2.GetComponent<Image>();
			((Graphic)component).raycastTarget = false;
			component.preserveAspect = true;
			component.type = (Type)0;
		}
		else
		{
			val3 = (RectTransform)(object)((val is RectTransform) ? val : null);
			component = ((Component)val).GetComponent<Image>();
			((Component)val).gameObject.SetActive(true);
		}
		if ((Object)(object)component != (Object)null)
		{
			component.sprite = icon;
			component.overrideSprite = icon;
			((Graphic)component).color = Color.white;
			((Graphic)component).material = null;
		}
		if ((Object)(object)val3 != (Object)null)
		{
			val3.sizeDelta = new Vector2(20f, 20f);
			val3.anchoredPosition = new Vector2(0f, 0f);
			((Transform)val3).localScale = Vector3.one;
		}
		label.margin = new Vector4(26f, label.margin.y, label.margin.z, label.margin.w);
	}

	private static void SeneaLRepairTipPostfix(object __result)
	{
		if (!modEnabled.Value || __result == null)
		{
			return;
		}
		if (senealOfferLines.Count == 0 && string.IsNullOrEmpty(repairTooltipBodyPlain))
		{
			RebuildWornItemsFromInventory();
		}
		Traverse val = Traverse.Create(__result);
		if (val.Method("Reset", new Type[2]
		{
			typeof(string),
			typeof(int)
		}, (object[])null).MethodExists())
		{
			val.Method("Reset", new Type[2]
			{
				typeof(string),
				typeof(int)
			}, (object[])null).GetValue(new object[2]
			{
				"Repair",
				Random.Range(1, int.MaxValue)
			});
		}
		if (val.Field("Title").FieldExists())
		{
			val.Field("Title").SetValue((object)"Repair");
		}
		if (val.Field("Sub").FieldExists())
		{
			string text = senealStationLine;
			text = ((!string.IsNullOrEmpty(text)) ? (text + "   ·   Coins: " + senealCoinCount) : ("Coins: " + senealCoinCount));
			val.Field("Sub").SetValue((object)text);
		}
		if (val.Field("Warn").FieldExists())
		{
			val.Field("Warn").SetValue((object)"");
		}
		if (val.Field("RichText").FieldExists())
		{
			val.Field("RichText").SetValue((object)false);
		}
		if (val.Field("Source").FieldExists())
		{
			val.Field("Source").SetValue((object)"RepairRequiresCoins");
		}
		if (val.Field("Icon").FieldExists())
		{
			val.Field("Icon").SetValue((object)null);
		}
		IList list = (val.Field("Rows").FieldExists() ? (val.Field("Rows").GetValue() as IList) : null);
		list?.Clear();
		(val.Field("Footer").FieldExists() ? (val.Field("Footer").GetValue() as IList) : null)?.Clear();
		if (senealOfferLines.Count == 0)
		{
			if (val.Field("Body").FieldExists())
			{
				val.Field("Body").SetValue((object)"No worn items at this station.");
			}
			return;
		}
		if (val.Field("Body").FieldExists())
		{
			val.Field("Body").SetValue((object)"");
		}
		foreach (RepairOfferLine senealOfferLine in senealOfferLines)
		{
			string text2 = ((!string.IsNullOrEmpty(senealOfferLine.Cost)) ? senealOfferLine.Cost : senealOfferLine.Note);
			if (val.Method("AddRow", new Type[3]
			{
				typeof(string),
				typeof(string),
				typeof(string)
			}, (object[])null).MethodExists())
			{
				val.Method("AddRow", new Type[3]
				{
					typeof(string),
					typeof(string),
					typeof(string)
				}, (object[])null).GetValue(new object[3] { senealOfferLine.Name, text2, "" });
			}
		}
		if ((list == null || list.Count == 0) && val.Field("Body").FieldExists())
		{
			val.Field("Body").SetValue((object)BuildSeneaLPlainBody());
		}
	}

	private static UITooltip GetRepairButtonTooltip()
	{
		InventoryGui instance = InventoryGui.instance;
		if ((Object)(object)instance == (Object)null)
		{
			return null;
		}
		object? obj = AccessTools.Field(typeof(InventoryGui), "m_repairButton")?.GetValue(instance);
		Button val = (Button)((obj is Button) ? obj : null);
		if (!Object.op_Implicit((Object)(object)val))
		{
			return null;
		}
		return ((Component)val).GetComponent<UITooltip>();
	}

	private static bool IsRepairButtonTooltip(UITooltip tooltip)
	{
		if ((Object)(object)tooltip == (Object)null)
		{
			return false;
		}
		if (((Object)((Component)tooltip).transform).name == "RepairButton")
		{
			return true;
		}
		UITooltip repairButtonTooltip = GetRepairButtonTooltip();
		if ((Object)(object)repairButtonTooltip != (Object)null)
		{
			return (Object)(object)tooltip == (Object)(object)repairButtonTooltip;
		}
		return false;
	}

	private static void ApplyRepairTooltipSource()
	{
		UITooltip repairButtonTooltip = GetRepairButtonTooltip();
		if (!((Object)(object)repairButtonTooltip == (Object)null))
		{
			repairButtonTooltip.m_topic = repairTooltipTopic;
			repairButtonTooltip.m_text = repairTooltipBody;
		}
	}

	private static void StyleRepairTooltipText()
	{
		object? obj = AccessTools.Field(typeof(UITooltip), "m_tooltip")?.GetValue(null);
		GameObject val = (GameObject)((obj is GameObject) ? obj : null);
		object? obj2 = AccessTools.Field(typeof(UITooltip), "m_current")?.GetValue(null);
		UITooltip val2 = (UITooltip)((obj2 is UITooltip) ? obj2 : null);
		if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || !IsRepairButtonTooltip(val2))
		{
			return;
		}
		Transform val3 = Utils.FindChild(val.transform, "Text", (IterativeSearchType)0);
		TMP_Text val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<TMP_Text>() : null);
		if (!((Object)(object)val4 == (Object)null))
		{
			val4.richText = true;
			val4.alignment = (TextAlignmentOptions)1026;
			val4.fontSize = 20f;
			val4.text = "<b><color=#" + titleTooltipColor.Value + ">" + repairTooltipTopic + "</color></b>\r\n" + repairTooltipBody;
			Transform val5 = Utils.FindChild(val.transform, "Topic", (IterativeSearchType)0);
			TMP_Text val6 = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponent<TMP_Text>() : null);
			if ((Object)(object)val6 != (Object)null)
			{
				val6.text = repairTooltipTopic;
			}
		}
	}

	private static string FormatRequirementLine(Requirement req, bool colored = true)
	{
		string name = req.m_resItem.m_itemData.m_shared.m_name;
		string text = Localization.instance.Localize(name);
		bool flag = name == "$item_coins" || ((Object)req.m_resItem).name == "Coins";
		if (!colored)
		{
			return req.m_amount + " " + (flag ? "Coins" : text);
		}
		if (flag)
		{
			string text2 = ((CountNamedItems(((Humanoid)Player.m_localPlayer).GetInventory(), name) >= req.m_amount) ? "FFFF00FF" : "FF0000FF");
			return "<color=#" + text2 + ">" + req.m_amount + "</color> <color=#FFFFFFFF>Coins</color>";
		}
		string text3 = ((CountNamedItems(((Humanoid)Player.m_localPlayer).GetInventory(), name) >= req.m_amount) ? "00FF00FF" : "FF0000FF");
		return "<color=#" + text3 + ">" + req.m_amount + "</color> " + text;
	}

	private static bool CanEverBeRepaired(ItemData item)
	{
		if (item?.m_shared == null || !item.m_shared.m_canBeReparied)
		{
			return false;
		}
		Recipe val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetRecipe(item) : null);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		if (!Object.op_Implicit((Object)(object)val.m_repairStation))
		{
			return Object.op_Implicit((Object)(object)val.m_craftingStation);
		}
		return true;
	}

	private static bool RecipeRepairsAtStation(Recipe recipe, CraftingStation current)
	{
		if ((Object)(object)recipe == (Object)null || !Object.op_Implicit((Object)(object)current))
		{
			return false;
		}
		if (Object.op_Implicit((Object)(object)recipe.m_repairStation) && recipe.m_repairStation.m_name == current.m_name)
		{
			return true;
		}
		if (Object.op_Implicit((Object)(object)recipe.m_craftingStation) && recipe.m_craftingStation.m_name == current.m_name)
		{
			return true;
		}
		return false;
	}

	private static CraftingStation GetRequiredRepairStation(Recipe recipe)
	{
		if ((Object)(object)recipe == (Object)null)
		{
			return null;
		}
		if (Object.op_Implicit((Object)(object)recipe.m_repairStation))
		{
			return recipe.m_repairStation;
		}
		return recipe.m_craftingStation;
	}

	private static int GetRequiredRepairStationLevel(Recipe recipe)
	{
		if ((Object)(object)recipe == (Object)null)
		{
			return 1;
		}
		return Mathf.Max(1, recipe.m_minStationLevel);
	}

	private static bool IsAtRequiredRepairStation(ItemData item)
	{
		if (item == null || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			return false;
		}
		CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation();
		if (!Object.op_Implicit((Object)(object)currentCraftingStation))
		{
			return false;
		}
		Recipe val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetRecipe(item) : null);
		if ((Object)(object)val == (Object)null || !RecipeRepairsAtStation(val, currentCraftingStation))
		{
			return false;
		}
		return GetLiveStationLevel(currentCraftingStation) >= GetRequiredRepairStationLevel(val);
	}

	private static int GetLiveStationLevel(CraftingStation station)
	{
		if (!Object.op_Implicit((Object)(object)station))
		{
			return 0;
		}
		int frameCount = Time.frameCount;
		if (liveLevelFrame == frameCount && (Object)(object)liveLevelStation == (Object)(object)station)
		{
			return liveLevelValue;
		}
		FieldInfo fieldInfo = AccessTools.Field(typeof(CraftingStation), "m_updateExtensionTimer");
		if (fieldInfo != null)
		{
			fieldInfo.SetValue(station, 999f);
		}
		MethodInfo methodInfo = AccessTools.Method(typeof(CraftingStation), "GetExtensions", (Type[])null, (Type[])null);
		if (methodInfo != null)
		{
			methodInfo.Invoke(station, null);
		}
		FieldInfo fieldInfo2 = AccessTools.Field(typeof(CraftingStation), "m_attachedExtensions");
		IList list = ((fieldInfo2 != null) ? (fieldInfo2.GetValue(station) as IList) : null);
		int num = 0;
		if (list != null)
		{
			foreach (object item in list)
			{
				if (Object.op_Implicit((Object)((item is Object) ? item : null)))
				{
					num++;
				}
			}
		}
		else
		{
			num = Math.Max(0, station.GetLevel(true) - 1);
		}
		liveLevelStation = station;
		liveLevelFrame = frameCount;
		liveLevelValue = 1 + num;
		return liveLevelValue;
	}

	private static string GetCurrentStationLevelLabel()
	{
		CraftingStation val = (((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetCurrentCraftingStation() : null);
		if (!Object.op_Implicit((Object)(object)val))
		{
			return "";
		}
		return Localization.instance.Localize(val.m_name) + " Lvl: " + GetLiveStationLevel(val);
	}

	private static string GetRepairNeedLabel(ItemData item)
	{
		Recipe val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetRecipe(item) : null);
		if ((Object)(object)val == (Object)null)
		{
			return "Needs recipe";
		}
		CraftingStation requiredRepairStation = GetRequiredRepairStation(val);
		if (!Object.op_Implicit((Object)(object)requiredRepairStation))
		{
			return "cannot repair here";
		}
		string text = Localization.instance.Localize(requiredRepairStation.m_name);
		return "Needs " + text + " Lvl: " + GetRequiredRepairStationLevel(val);
	}

	private static ItemDrop GetCoinsItemDrop()
	{
		GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("Coins") : null);
		if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
		{
			val = ZNetScene.instance.GetPrefab("Coins");
		}
		if (!((Object)(object)val != (Object)null))
		{
			return null;
		}
		return val.GetComponent<ItemDrop>();
	}

	private static List<Requirement> RepairReqs(ItemData item, bool log = false)
	{
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Expected O, but got Unknown
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: 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_018d: Expected O, but got Unknown
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Expected O, but got Unknown
		float num = (item.GetMaxDurability() - item.m_durability) / item.GetMaxDurability();
		Recipe recipe = ObjectDB.instance.GetRecipe(item);
		if (recipe == null)
		{
			return null;
		}
		List<Requirement> list = new List<Requirement>(recipe.m_resources);
		int calculatedRepairCoinCost = 0;
		bool flag = false;
		if (epicLootAssembly != null)
		{
			try
			{
				MethodInfo methodInfo = epicLootIsMagic;
				object[] parameters = (object[])(object)new ItemData[1] { item };
				flag = (bool)methodInfo.Invoke(null, parameters);
			}
			catch
			{
			}
		}
		if (flag)
		{
			try
			{
				MethodInfo methodInfo2 = epicLootGetRarity;
				object[] parameters = (object[])(object)new ItemData[1] { item };
				int num2 = (int)methodInfo2.Invoke(null, parameters);
				foreach (KeyValuePair<ItemDrop, int> item2 in (List<KeyValuePair<ItemDrop, int>>)epicLootGetEnchantCosts.Invoke(null, new object[2] { item, num2 }))
				{
					list.Add(new Requirement
					{
						m_amount = item2.Value,
						m_resItem = item2.Key
					});
				}
			}
			catch
			{
			}
		}
		List<Requirement> list2 = new List<Requirement>();
		bool hasValuedMaterial = false;
		for (int i = 0; i < list.Count; i++)
		{
			if (!((Object)(object)list[i]?.m_resItem == (Object)null))
			{
				Requirement val = new Requirement
				{
					m_resItem = list[i].m_resItem,
					m_amount = list[i].m_amount,
					m_amountPerLevel = list[i].m_amountPerLevel,
					m_recover = list[i].m_recover
				};
				int num3 = 0;
				for (int num4 = item.m_quality; num4 > 0; num4--)
				{
					num3 += val.GetAmount(num4);
				}
				int amount = Mathf.RoundToInt((float)num3 * num * materialRequirementMult.Value);
				val.m_amount = amount;
				ApplyMaterialRepairCost(val, list2, ref calculatedRepairCoinCost, ref hasValuedMaterial);
			}
		}
		if (calculatedRepairCoinCost == 0 && hasValuedMaterial && num > 0f)
		{
			calculatedRepairCoinCost = 1;
		}
		if (calculatedRepairCoinCost > 0)
		{
			ItemDrop coinsItemDrop = GetCoinsItemDrop();
			if ((Object)(object)coinsItemDrop == (Object)null && coinOnly.Value)
			{
				if (list2.Count <= 0)
				{
					return null;
				}
				return list2;
			}
			if ((Object)(object)coinsItemDrop != (Object)null && calculatedRepairCoinCost > 0)
			{
				list2.Add(new Requirement
				{
					m_resItem = coinsItemDrop,
					m_amount = calculatedRepairCoinCost,
					m_amountPerLevel = 0,
					m_recover = false
				});
			}
		}
		if (list2.Count == 0)
		{
			return null;
		}
		return list2;
	}

	private static void ApplyMaterialRepairCost(Requirement req, List<Requirement> reqs, ref int calculatedRepairCoinCost, ref bool hasValuedMaterial)
	{
		float rate;
		bool flag = TryGetMaterialRate(req.m_resItem, out rate);
		if (flag && rate == -1f)
		{
			return;
		}
		if (flag)
		{
			hasValuedMaterial = true;
		}
		if (flag && req.m_amount > 0)
		{
			if (rate * (float)req.m_amount <= 1f)
			{
				calculatedRepairCoinCost++;
			}
			else
			{
				calculatedRepairCoinCost += Mathf.RoundToInt(rate * (float)req.m_amount);
			}
		}
		if (!coinOnly.Value && req.m_amount > 0)
		{
			reqs.Add(req);
		}
	}

	private static bool TryGetMaterialRate(ItemDrop drop, out float rate)
	{
		rate = 0f;
		if ((Object)(object)drop == (Object)null)
		{
			return false;
		}
		string name = ((Object)drop).name;
		if (!string.IsNullOrEmpty(name))
		{
			name = name.Replace("(Clone)", "").Trim();
			if (TryGetMaterialRateByProperty(name, out rate))
			{
				return true;
			}
		}
		string text = drop.m_itemData?.m_shared?.m_name;
		if (string.IsNullOrEmpty(text))
		{
			return false;
		}
		return TryGetMaterialRateByProperty(SharedTokenToPropertyName(text), out rate);
	}

	private static string SharedTokenToPropertyName(string sharedName)
	{
		if (sharedName.StartsWith("$item_"))
		{
			sharedName = sharedName.Substring(6);
		}
		string[] array = sharedName.Split(new char[1] { '_' });
		string text = "";
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			if (text2.Length != 0)
			{
				text = text + char.ToUpperInvariant(text2[0]) + ((text2.Length > 1) ? text2.Substring(1) : "");
			}
		}
		return text;
	}

	private static bool TryGetMaterialRateByProperty(string propertyName, out float rate)
	{
		rate = 0f;
		if (savedValues == null || string.IsNullOrEmpty(propertyName))
		{
			return false;
		}
		PropertyInfo[] properties = typeof(WeaponAndArmorValues).GetProperties();
		foreach (PropertyInfo propertyInfo in properties)
		{
			if (string.Equals(propertyInfo.Name, propertyName, StringComparison.OrdinalIgnoreCase))
			{
				rate = Convert.ToSingle(propertyInfo.GetValue(savedValues, null));
				return true;
			}
		}
		return false;
	}
}
internal class RepairOfferLine
{
	public string Name;

	public string Cost;

	public string Note;

	public Sprite Icon;

	public bool IconUsed;
}
internal class RepairItemData : ItemData
{
	public List<string> reqstring;

	public ItemData item;

	public RepairItemData(ItemData item, List<string> reqstring = null)
	{
		this.reqstring = reqstring;
		this.item = item;
	}
}