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.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace RepairRequiresMats;
[BepInPlugin("aedenthorn.RepairRequiresMats", "Repair Requires Mats", "0.6.1")]
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_0049: 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)
//IL_005d: 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)
{
//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
//IL_04fa: Expected O, but got Unknown
//IL_0516: Unknown result type (might be due to invalid IL or missing references)
//IL_051d: Expected O, but got Unknown
if (!modEnabled.Value || !___m_tempWornItems.Any())
{
return;
}
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>();
foreach (ItemData ___m_tempWornItem in ___m_tempWornItems)
{
if (!Traverse.Create((object)__instance).Method("CanRepair", new object[1] { ___m_tempWornItem }).GetValue<bool>())
{
list4.Add(new RepairItemData(___m_tempWornItem));
continue;
}
List<Requirement> list6 = RepairReqs(___m_tempWornItem);
if (list6 == null)
{
list.Add(new RepairItemData(___m_tempWornItem));
continue;
}
List<string> list7 = new List<string>();
foreach (Requirement item in list6)
{
if (item.m_amount != 0)
{
list7.Add($"{item.m_amount}/{((Humanoid)Player.m_localPlayer).GetInventory().CountItems(item.m_resItem.m_itemData.m_shared.m_name, -1, true)} {Localization.instance.Localize(item.m_resItem.m_itemData.m_shared.m_name)}");
}
}
bool flag = true;
foreach (Requirement item2 in list6)
{
if (Object.op_Implicit((Object)(object)item2.m_resItem))
{
int amount = item2.m_amount;
if (((Humanoid)Player.m_localPlayer).GetInventory().CountItems(item2.m_resItem.m_itemData.m_shared.m_name, -1, true) < amount)
{
flag = false;
break;
}
}
}
if (!flag)
{
list3.Add(new RepairItemData(___m_tempWornItem, list7));
}
else
{
list2.Add(new RepairItemData(___m_tempWornItem, list7));
}
}
orderedWornItems = new List<ItemData>();
foreach (RepairItemData item3 in list)
{
list5.Add("<color=#" + hasEnoughTooltipColor.Value + ">" + Localization.instance.Localize(item3.item.m_shared.m_name) + ": Free</color>");
orderedWornItems.Add(item3.item);
}
foreach (RepairItemData item4 in list2)
{
list5.Add("<color=#" + hasEnoughTooltipColor.Value + ">" + Localization.instance.Localize(item4.item.m_shared.m_name) + ": " + string.Join(", ", item4.reqstring) + "</color>");
orderedWornItems.Add(item4.item);
}
foreach (RepairItemData item5 in list3)
{
list5.Add("<color=#" + notEnoughTooltipColor.Value + ">" + Localization.instance.Localize(item5.item.m_shared.m_name) + ": " + string.Join(", ", item5.reqstring) + "</color>");
orderedWornItems.Add(item5.item);
}
foreach (RepairItemData item6 in list4)
{
orderedWornItems.Add(item6.item);
}
___m_tempWornItems = new List<ItemData>(orderedWornItems);
if (showAllRepairsInToolTip.Value)
{
UITooltip val = (UITooltip)typeof(UITooltip).GetField("m_current", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
GameObject val2 = (GameObject)typeof(UITooltip).GetField("m_tooltip", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
if (!((Object)(object)val2 == (Object)null) && !(((Object)((Component)val).transform).name != "RepairButton"))
{
((Component)Utils.FindChild(val2.transform, "Text", (IterativeSearchType)0)).GetComponent<TMP_Text>().richText = true;
((Component)Utils.FindChild(val2.transform, "Text", (IterativeSearchType)0)).GetComponent<TMP_Text>().alignment = (TextAlignmentOptions)1026;
((Component)Utils.FindChild(val2.transform, "Text", (IterativeSearchType)0)).GetComponent<TMP_Text>().text = "<b><color=#" + titleTooltipColor.Value + ">" + Localization.instance.Localize("$inventory_repairbutton") + "</color></b>\r\n" + string.Join("\r\n", list5);
}
}
}
}
[HarmonyPatch(typeof(InventoryGui), "CanRepair")]
private static class InventoryGui_CanRepair_Patch
{
private static void Postfix(ItemData item, ref bool __result)
{
if (!modEnabled.Value || !modEnabled.Value || !Environment.StackTrace.Contains("RepairOneItem") || Environment.StackTrace.Contains("HaveRepairableItems") || !__result || item?.m_shared == null || !((Object)(object)Player.m_localPlayer != (Object)null) || orderedWornItems.Count <= 0)
{
return;
}
if (orderedWornItems[0] != item)
{
__result = false;
return;
}
List<Requirement> list = RepairReqs(item, log: true);
if (list == null)
{
return;
}
List<string> list2 = new List<string>();
foreach (Requirement item2 in list)
{
if (item2?.m_resItem?.m_itemData?.m_shared != null)
{
list2.Add($"{item2.m_amount}/{((Humanoid)Player.m_localPlayer).GetInventory().CountItems(item2.m_resItem.m_itemData.m_shared.m_name, -1, true)} {Localization.instance.Localize(item2.m_resItem.m_itemData.m_shared.m_name)}");
}
}
bool flag = true;
foreach (Requirement item3 in list)
{
if (Object.op_Implicit((Object)(object)item3.m_resItem))
{
int amount = item3.m_amount;
if (((Humanoid)Player.m_localPlayer).GetInventory().CountItems(item3.m_resItem.m_itemData.m_shared.m_name, -1, true) < amount)
{
flag = false;
break;
}
}
}
string text;
if (flag)
{
Player.m_localPlayer.ConsumeResources(list.ToArray(), 1, -1);
text = "Used " + string.Join(", ", list2) + " to repair " + Localization.instance.Localize(item.m_shared.m_name);
__result = true;
}
else
{
text = "Require " + string.Join(", ", list2) + " to repair " + item.m_shared.m_name;
__result = false;
}
((Character)Player.m_localPlayer).Message((MessageType)1, text, 0, (Sprite)null);
Dbgl(text);
}
}
[HarmonyPatch(typeof(Terminal), "InputText")]
private static class InputText_Patch
{
private static bool Prefix(Terminal __instance)
{
if (!modEnabled.Value)
{
return true;
}
string text = ((TMP_InputField)__instance.m_input).text;
if (text.ToLower().Equals("repairmod reset"))
{
((BaseUnityPlugin)context).Config.Reload();
((BaseUnityPlugin)context).Config.Save();
Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
Traverse.Create((object)__instance).Method("AddString", new object[1] { "Repair Items config reloaded" }).GetValue();
return false;
}
return true;
}
}
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;
public static ConfigEntry<int> nexusID;
private static List<ItemData> orderedWornItems = new List<ItemData>();
private static BepInExPlugin context;
private static Assembly epicLootAssembly;
private static MethodInfo epicLootIsMagic;
private static MethodInfo epicLootGetRarity;
private static MethodInfo epicLootGetEnchantCosts;
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");
nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 215, "Nexus mod ID for updates");
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", "FFFFFFFF", "Color to use in tooltip for items with enough resources to repair.");
notEnoughTooltipColor = ((BaseUnityPlugin)this).Config.Bind<string>("General", "NotEnoughTooltipColor", "FF0000FF", "Color to use in tooltip for items with enough resources to repair.");
materialRequirementMult = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaterialRequirementMult", 0.5f, "Multiplier for amount of each material required.");
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
}
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.EnchantTabController").GetMethod("GetEnchantCosts", BindingFlags.Static | BindingFlags.Public);
Dbgl($"Loaded Epic Loot assembly; epicLootIsMagic {epicLootIsMagic != null}, epicLootGetRarity {epicLootGetRarity != null}, epicLootGetEnchantCosts {epicLootGetEnchantCosts != null}");
}
}
private static List<Requirement> RepairReqs(ItemData item, bool log = false)
{
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: 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_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0192: Expected O, but got Unknown
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: 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_010a: 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);
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);
List<KeyValuePair<ItemDrop, int>> list2 = (List<KeyValuePair<ItemDrop, int>>)epicLootGetEnchantCosts.Invoke(null, new object[2] { item, num2 });
foreach (KeyValuePair<ItemDrop, int> item2 in list2)
{
list.Add(new Requirement
{
m_amount = item2.Value,
m_resItem = item2.Key
});
}
}
catch
{
}
}
List<Requirement> list3 = new List<Requirement>();
for (int i = 0; i < list.Count; i++)
{
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 num5 = Mathf.RoundToInt((float)num3 * num * materialRequirementMult.Value);
if (num5 > 0)
{
val.m_amount = num5;
list3.Add(val);
}
}
if (!list3.Any())
{
return null;
}
return list3;
}
}
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;
}
}