Decompiled source of Derpability v1.0.1

plugins/Derpability/Derpability.dll

Decompiled 19 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Derpability.Patches;
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("Wagnarok")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Valheim mod to reduce maximum durability on equipment after repairs.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Derpability")]
[assembly: AssemblyTitle("Derpability")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 Derpability
{
	[BepInPlugin("wagnarok.valeim.derpability", "Derpability", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "wagnarok.valeim.derpability";

		public const string PluginName = "Derpability";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		private readonly Harmony _harmony = new Harmony("wagnarok.valeim.derpability");

		public static ConfigEntry<float> MaxDurabilityLossPerRepair;

		public static ConfigEntry<float> BrokenThresholdPercent;

		private void Awake()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MaxDurabilityLossPerRepair = ((BaseUnityPlugin)this).Config.Bind<float>("Repair", "MaxDurabilityLossPerRepair", 0.1f, "Maximum fraction of the item's ORIGINAL max durability lost per repair (when item is at 0 durability). Actual loss is scaled by how damaged the item was. Default 0.10 = up to 10% loss per repair.");
			BrokenThresholdPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Repair", "BrokenThresholdPercent", 0.3f, new ConfigDescription("Once an item's current max durability reaches this fraction of its original max, it can no longer be repaired but still functions until it hits 0. Default 0.30 = unrepairable at 30%. Maximum 0.37 ensures wear stage colors remain within 0-100%.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.37f), Array.Empty<object>()));
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			TryPatchTooltip();
			TryPatchCanUpgrade();
			Log.LogInfo((object)"Derpability v1.0.0 loaded successfully.");
		}

		private void OnDestroy()
		{
			_harmony.UnpatchAll("wagnarok.valeim.derpability");
		}

		private void TryPatchCanUpgrade()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(InventoryGui), "AddRecipeToList", new Type[4]
			{
				typeof(Player),
				typeof(Recipe),
				typeof(ItemData),
				typeof(bool)
			}, (Type[])null);
			if (methodInfo == null)
			{
				Log.LogWarning((object)"AddRecipeToList patch skipped — method not found.");
				return;
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(BlockUpgradeIfBrokenPatch), "Postfix", (Type[])null, (Type[])null);
			_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null);
			Log.LogInfo((object)"Upgrade block patch applied to AddRecipeToList.");
		}

		private void TryPatchTooltip()
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ItemData), "GetTooltip", new Type[5]
			{
				typeof(ItemData),
				typeof(int),
				typeof(bool),
				typeof(float),
				typeof(int)
			}, (Type[])null);
			if (methodInfo == null)
			{
				Log.LogWarning((object)"Tooltip patch skipped — dumping all ItemData methods with 'Tooltip' in name:");
				MethodInfo[] methods = typeof(ItemData).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo2 in methods)
				{
					if (methodInfo2.Name.Contains("ooltip"))
					{
						Log.LogWarning((object)("  " + (methodInfo2.IsStatic ? "static " : "") + methodInfo2.ReturnType.Name + " " + methodInfo2.Name + "(" + string.Join(", ", Array.ConvertAll(methodInfo2.GetParameters(), (ParameterInfo p) => p.ParameterType.Name)) + ")"));
					}
				}
			}
			else
			{
				MethodInfo methodInfo3 = AccessTools.Method(typeof(BrokenItemTooltipPatch), "Postfix", (Type[])null, (Type[])null);
				_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null);
				Log.LogInfo((object)"Tooltip patch applied successfully.");
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "SendPeerInfo")]
	public static class ZNet_SendPeerInfo_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(ZRpc rpc)
		{
			rpc.Invoke("Derpability_VersionCheck", new object[1] { "1.0.0" });
			Plugin.Log.LogInfo((object)"Sent Derpability version 1.0.0 to peer.");
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class ZNet_OnNewConnection_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(ZNetPeer peer)
		{
			peer.m_rpc.Register<string>("Derpability_VersionCheck", (Action<ZRpc, string>)delegate(ZRpc rpc, string version)
			{
				if (version != "1.0.0")
				{
					Plugin.Log.LogWarning((object)("Kicking peer: Derpability version mismatch. Server=1.0.0, Client=" + version));
					ZNet.instance.Disconnect(peer);
				}
				else
				{
					Plugin.Log.LogInfo((object)("Peer passed Derpability version check (v" + version + ")."));
				}
			});
		}
	}
}
namespace Derpability.Patches
{
	internal static class ItemKeys
	{
		public const string OriginalMaxDurability = "ee_original_max";

		public const string CurrentMaxDurability = "ee_current_max";
	}
	internal static class DurabilityHelper
	{
		internal static bool BypassPatch;

		private static float ParseOrDefault(ItemData item, string key, float fallback)
		{
			if (item.m_customData.TryGetValue(key, out var value) && float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return fallback;
		}

		private static void Store(ItemData item, string key, float value)
		{
			item.m_customData[key] = value.ToString("F4", CultureInfo.InvariantCulture);
		}

		public static float CalcOriginalMax(ItemData item)
		{
			return item.m_shared.m_maxDurability + (float)Mathf.Max(0, item.m_quality - 1) * item.m_shared.m_durabilityPerLevel;
		}

		public static float GetOriginalMax(ItemData item)
		{
			float num = ParseOrDefault(item, "ee_original_max", -1f);
			if (!(num > 0f))
			{
				return CalcOriginalMax(item);
			}
			return num;
		}

		public static float GetCurrentMax(ItemData item)
		{
			float num = ParseOrDefault(item, "ee_current_max", -1f);
			if (!(num > 0f))
			{
				return GetOriginalMax(item);
			}
			return num;
		}

		public static bool HasBeenDegraded(ItemData item)
		{
			return item.m_customData.ContainsKey("ee_current_max");
		}

		public static void ApplyRepairDegradation(ItemData item)
		{
			BypassPatch = true;
			float maxDurability = item.GetMaxDurability();
			BypassPatch = false;
			if (!item.m_customData.ContainsKey("ee_original_max"))
			{
				Store(item, "ee_original_max", maxDurability);
			}
			float originalMax = GetOriginalMax(item);
			float currentMax = GetCurrentMax(item);
			if (!(maxDurability - item.m_durability <= 0f))
			{
				float num = 1f - Mathf.Clamp01(item.m_durability / currentMax);
				float num2 = originalMax * Plugin.MaxDurabilityLossPerRepair.Value * num;
				float num3 = Mathf.Max(currentMax - num2, 0f);
				Store(item, "ee_current_max", num3);
				Plugin.Log.LogDebug((object)("Repaired " + item.m_shared.m_name + ": " + $"damage was {num * 100f:F1}%, " + $"degraded max {currentMax:F1} -> {num3:F1} (loss: {num2:F1}) " + $"(original: {originalMax:F1}, threshold: {originalMax * Plugin.BrokenThresholdPercent.Value:F1})"));
			}
		}

		public static bool IsUnrepairable(ItemData item)
		{
			if (!HasBeenDegraded(item))
			{
				return false;
			}
			float originalMax = GetOriginalMax(item);
			return GetCurrentMax(item) <= originalMax * Plugin.BrokenThresholdPercent.Value;
		}

		public static float GetWearRatio(ItemData item)
		{
			if (!HasBeenDegraded(item))
			{
				return 1f;
			}
			float originalMax = GetOriginalMax(item);
			if (originalMax <= 0f)
			{
				return 1f;
			}
			return GetCurrentMax(item) / originalMax;
		}
	}
	internal static class WearStage
	{
		public static float Red => Plugin.BrokenThresholdPercent.Value;

		public static float Orange => Plugin.BrokenThresholdPercent.Value * 2f;

		public static float Yellow => Plugin.BrokenThresholdPercent.Value * 2.67f;
	}
	[HarmonyPatch(typeof(ItemData), "GetMaxDurability", new Type[] { typeof(int) })]
	public static class GetMaxDurabilityPatch
	{
		[HarmonyPostfix]
		public static void Postfix(ItemData __instance, ref float __result)
		{
			if (!DurabilityHelper.BypassPatch && DurabilityHelper.HasBeenDegraded(__instance))
			{
				float currentMax = DurabilityHelper.GetCurrentMax(__instance);
				if (currentMax < __result)
				{
					__result = currentMax;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	public static class EquipItemClampPatch
	{
		[HarmonyPrefix]
		public static void Prefix(ItemData item)
		{
			if (item != null && item.m_shared.m_useDurability && DurabilityHelper.HasBeenDegraded(item))
			{
				float currentMax = DurabilityHelper.GetCurrentMax(item);
				if (item.m_durability > currentMax)
				{
					item.m_durability = currentMax;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "SetCraftingStation")]
	public static class RestoreHandItemOnStationExitPatch
	{
		private static ItemData _savedRightItem;

		private static MethodInfo _getRightItem;

		private static MethodInfo _queueEquipItem;

		private static bool _reflected;

		private static bool TryReflect()
		{
			if (_reflected)
			{
				if (_getRightItem != null)
				{
					return _queueEquipItem != null;
				}
				return false;
			}
			_reflected = true;
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			_getRightItem = typeof(Humanoid).GetMethod("GetRightItem", bindingAttr);
			_queueEquipItem = typeof(Player).GetMethod("QueueEquipAction", bindingAttr) ?? typeof(Humanoid).GetMethod("QueueEquipAction", bindingAttr);
			if (_getRightItem == null)
			{
				Plugin.Log.LogWarning((object)"RestoreHandItem: GetRightItem not found");
			}
			if (_queueEquipItem == null)
			{
				Plugin.Log.LogWarning((object)"RestoreHandItem: QueueEquipAction not found");
			}
			if (_getRightItem != null)
			{
				return _queueEquipItem != null;
			}
			return false;
		}

		[HarmonyPrefix]
		public static void Prefix(Player __instance, CraftingStation station)
		{
			if (!((Object)(object)station == (Object)null) && TryReflect())
			{
				object? obj = _getRightItem.Invoke(__instance, null);
				_savedRightItem = (ItemData)((obj is ItemData) ? obj : null);
			}
		}

		[HarmonyPostfix]
		public static void Postfix(Player __instance, CraftingStation station)
		{
			if (!((Object)(object)station != (Object)null) && _savedRightItem != null && TryReflect())
			{
				if (!((Humanoid)__instance).IsItemEquiped(_savedRightItem))
				{
					_queueEquipItem.Invoke(__instance, new object[1] { _savedRightItem });
					Plugin.Log.LogDebug((object)("Re-queued hand item after leaving crafting station: " + _savedRightItem.m_shared.m_name));
				}
				_savedRightItem = null;
			}
		}
	}
	public static class BlockRepairIfBrokenPatch
	{
		[HarmonyPostfix]
		public static void Postfix(ItemData item, ref bool __result)
		{
			if (item != null && __result && DurabilityHelper.IsUnrepairable(item))
			{
				__result = false;
				Plugin.Log.LogDebug((object)("Repair blocked: " + item.m_shared.m_name + " is too worn to repair."));
			}
		}
	}
	public static class BlockUpgradeIfBrokenPatch
	{
		public static void Postfix(Player player, Recipe recipe, ItemData item, ref bool canCraft)
		{
			if (item != null && canCraft && DurabilityHelper.IsUnrepairable(item))
			{
				canCraft = false;
				Plugin.Log.LogDebug((object)("Upgrade blocked: " + item.m_shared.m_name + " is too worn to upgrade."));
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
	public static class ReduceMaxDurabilityOnRepairPatch
	{
		[HarmonyPrefix]
		public static void Prefix()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			List<ItemData> list = new List<ItemData>();
			((Humanoid)Player.m_localPlayer).GetInventory().GetWornItems(list);
			foreach (ItemData item in list)
			{
				if (item.m_shared.m_canBeReparied && item.m_durability < item.GetMaxDurability() && !DurabilityHelper.IsUnrepairable(item))
				{
					float durability = item.m_durability;
					DurabilityHelper.ApplyRepairDegradation(item);
					item.m_durability = durability;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
	public static class PreserveWearRatioOnUpgradePatch
	{
		private static readonly Dictionary<Vector2i, (float ratio, int quality)> _snapshot = new Dictionary<Vector2i, (float, int)>();

		[HarmonyPrefix]
		public static void Prefix(InventoryGui __instance, Player player)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			_snapshot.Clear();
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (allItem.m_shared.m_useDurability && DurabilityHelper.HasBeenDegraded(allItem))
				{
					float wearRatio = DurabilityHelper.GetWearRatio(allItem);
					if (wearRatio < 1f)
					{
						_snapshot[allItem.m_gridPos] = (wearRatio, allItem.m_quality);
					}
				}
			}
		}

		[HarmonyPostfix]
		public static void Postfix(InventoryGui __instance, Player player)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || _snapshot.Count == 0)
			{
				return;
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (allItem.m_shared.m_useDurability && _snapshot.TryGetValue(allItem.m_gridPos, out (float, int) value) && allItem.m_quality > value.Item2 && !DurabilityHelper.IsUnrepairable(allItem))
				{
					DurabilityHelper.BypassPatch = true;
					float maxDurability = allItem.GetMaxDurability();
					DurabilityHelper.BypassPatch = false;
					float num = maxDurability * value.Item1;
					float durability = allItem.m_durability;
					allItem.m_customData["ee_original_max"] = maxDurability.ToString("F4", CultureInfo.InvariantCulture);
					allItem.m_customData["ee_current_max"] = num.ToString("F4", CultureInfo.InvariantCulture);
					allItem.m_durability = Mathf.Min(durability, num);
					Plugin.Log.LogDebug((object)($"Upgraded {allItem.m_shared.m_name} q{allItem.m_quality}: " + $"new original max={maxDurability:F1}, " + $"preserved wear ratio={value.Item1:P0}, " + $"new current max={num:F1}"));
				}
			}
			_snapshot.Clear();
		}
	}
	public static class BrokenItemTooltipPatch
	{
		private const string Tag = "Too worn to repair";

		public static void Postfix(ItemData item, ref string __result)
		{
			if (item != null && __result != null && !__result.Contains("Too worn to repair") && item.m_shared.m_useDurability)
			{
				float wearRatio = DurabilityHelper.GetWearRatio(item);
				if (DurabilityHelper.IsUnrepairable(item))
				{
					__result += "\n<color=red>⚠ Too worn to repair — use until it breaks</color>";
				}
				else if (wearRatio < WearStage.Orange)
				{
					__result += "\n<color=orange>Heavily worn — limited repairs remaining</color>";
				}
				else if (wearRatio < WearStage.Yellow)
				{
					__result += "\n<color=yellow>Worn — showing signs of wear</color>";
				}
			}
		}
	}
	[HarmonyPatch(typeof(HotkeyBar), "UpdateIcons")]
	public static class HotbarDurabilityColorPatch
	{
		private static FieldInfo _elementsField;

		private static FieldInfo _elementDurabilityField;

		private static FieldInfo _elementUsedField;

		private static bool _reflected;

		private static bool TryReflect()
		{
			if (_reflected)
			{
				return _elementsField != null;
			}
			_reflected = true;
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			_elementsField = typeof(HotkeyBar).GetField("m_elements", bindingAttr);
			Type type = typeof(HotkeyBar).GetNestedType("ElementData", BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(HotkeyBar).GetNestedType("Element", BindingFlags.Public | BindingFlags.NonPublic);
			if (type != null)
			{
				_elementDurabilityField = type.GetField("m_durability", bindingAttr);
				_elementUsedField = type.GetField("m_used", bindingAttr);
			}
			if (_elementsField == null || _elementDurabilityField == null)
			{
				Plugin.Log.LogWarning((object)"HotbarDurabilityColorPatch: reflection incomplete — hotbar colors disabled.");
				return false;
			}
			Plugin.Log.LogInfo((object)"HotbarDurabilityColorPatch: reflection succeeded.");
			return true;
		}

		[HarmonyPostfix]
		public static void Postfix(HotkeyBar __instance, Player player)
		{
			//IL_00d7: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			if (!TryReflect() || (Object)(object)player == (Object)null || !(_elementsField.GetValue(__instance) is IList list))
			{
				return;
			}
			for (int i = 0; i < list.Count; i++)
			{
				object obj = list[i];
				if (_elementUsedField != null && !(bool)_elementUsedField.GetValue(obj))
				{
					continue;
				}
				ItemData itemAt = ((Humanoid)player).GetInventory().GetItemAt(i, 0);
				if (itemAt == null || !itemAt.m_shared.m_useDurability)
				{
					continue;
				}
				object? value = _elementDurabilityField.GetValue(obj);
				GuiBar val = (GuiBar)((value is GuiBar) ? value : null);
				if (!((Object)(object)val == (Object)null))
				{
					((Component)val).gameObject.SetActive(true);
					val.SetValue(itemAt.GetDurabilityPercentage());
					float wearRatio = DurabilityHelper.GetWearRatio(itemAt);
					if (wearRatio <= WearStage.Red)
					{
						val.SetColor(new Color(1f, 0.2f, 0.2f));
					}
					else if (wearRatio <= WearStage.Orange)
					{
						val.SetColor(new Color(1f, 0.5f, 0f));
					}
					else if (wearRatio <= WearStage.Yellow)
					{
						val.SetColor(new Color(1f, 1f, 0f));
					}
					else
					{
						val.ResetColor();
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
	public static class DurabilityBarColorPatch
	{
		private static FieldInfo _inventoryField;

		private static FieldInfo _elementsField;

		private static FieldInfo _elementDurabilityField;

		private static FieldInfo _elementPosField;

		private static bool _reflected;

		private static bool TryReflect()
		{
			if (_reflected)
			{
				return _inventoryField != null;
			}
			_reflected = true;
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			_inventoryField = typeof(InventoryGrid).GetField("m_inventory", bindingAttr);
			_elementsField = typeof(InventoryGrid).GetField("m_elements", bindingAttr);
			Type nestedType = typeof(InventoryGrid).GetNestedType("Element", BindingFlags.Public | BindingFlags.NonPublic);
			if (nestedType != null)
			{
				_elementDurabilityField = nestedType.GetField("m_durability", bindingAttr);
				_elementPosField = nestedType.GetField("m_pos", bindingAttr);
			}
			if (_inventoryField == null || _elementsField == null || _elementDurabilityField == null || _elementPosField == null)
			{
				Plugin.Log.LogWarning((object)"DurabilityBarColorPatch: failed to reflect InventoryGrid fields — bar colors disabled.");
				return false;
			}
			Plugin.Log.LogInfo((object)"DurabilityBarColorPatch: reflection succeeded.");
			return true;
		}

		[HarmonyPostfix]
		public static void Postfix(InventoryGrid __instance)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			if (!TryReflect())
			{
				return;
			}
			object? value = _inventoryField.GetValue(__instance);
			Inventory val = (Inventory)((value is Inventory) ? value : null);
			if (val == null || !(_elementsField.GetValue(__instance) is IList list))
			{
				return;
			}
			Dictionary<Vector2i, object> dictionary = new Dictionary<Vector2i, object>();
			foreach (object item in list)
			{
				Vector2i key = (Vector2i)_elementPosField.GetValue(item);
				dictionary[key] = item;
			}
			foreach (ItemData allItem in val.GetAllItems())
			{
				if (!allItem.m_shared.m_useDurability || !dictionary.TryGetValue(allItem.m_gridPos, out var value2))
				{
					continue;
				}
				object? value3 = _elementDurabilityField.GetValue(value2);
				GuiBar val2 = (GuiBar)((value3 is GuiBar) ? value3 : null);
				if (!((Object)(object)val2 == (Object)null))
				{
					((Component)val2).gameObject.SetActive(true);
					val2.SetValue(allItem.GetDurabilityPercentage());
					float wearRatio = DurabilityHelper.GetWearRatio(allItem);
					if (wearRatio <= WearStage.Red)
					{
						val2.SetColor(new Color(1f, 0.2f, 0.2f));
					}
					else if (wearRatio <= WearStage.Orange)
					{
						val2.SetColor(new Color(1f, 0.5f, 0f));
					}
					else if (wearRatio <= WearStage.Yellow)
					{
						val2.SetColor(new Color(1f, 1f, 0f));
					}
					else
					{
						val2.ResetColor();
					}
				}
			}
		}
	}
}