Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RamUniversalRebench v1.0.3
RamUniversalRebench.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace JustinRampage.UniversalRebench; [BepInPlugin("justinrampage.universalrebench", "RamUniversalRebench", "1.0.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class RamUniversalRebenchPlugin : BaseUnityPlugin { private sealed class StationChoice { public CraftingStation Station; public string DisplayName; public string PrefabName; public float Distance; public int Level; } private sealed class RemoteMeshBuilder { private readonly List<Vector3> vertices = new List<Vector3>(); private readonly List<Vector3> normals = new List<Vector3>(); private readonly List<Vector2> uvs = new List<Vector2>(); private readonly List<int>[] submeshes = new List<int>[6]; public RemoteMeshBuilder() { for (int i = 0; i < submeshes.Length; i++) { submeshes[i] = new List<int>(); } } private void Face(Vector3 a, Vector3 b, Vector3 c, Vector3 d, Vector3 n, int material) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) int count = vertices.Count; vertices.Add(a); vertices.Add(b); vertices.Add(c); vertices.Add(d); for (int i = 0; i < 4; i++) { normals.Add(n); } uvs.Add(new Vector2(0f, 0f)); uvs.Add(new Vector2(1f, 0f)); uvs.Add(new Vector2(1f, 1f)); uvs.Add(new Vector2(0f, 1f)); submeshes[material].Add(count); submeshes[material].Add(count + 1); submeshes[material].Add(count + 2); submeshes[material].Add(count); submeshes[material].Add(count + 2); submeshes[material].Add(count + 3); } public void Box(Vector3 center, Vector3 size, int material) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0045: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) Vector3 val = center - size * 0.5f; Vector3 val2 = center + size * 0.5f; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(val.x, val.y, val.z); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(val.x, val.y, val2.z); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(val.x, val2.y, val.z); Vector3 val6 = default(Vector3); ((Vector3)(ref val6))..ctor(val.x, val2.y, val2.z); Vector3 val7 = default(Vector3); ((Vector3)(ref val7))..ctor(val2.x, val.y, val.z); Vector3 val8 = default(Vector3); ((Vector3)(ref val8))..ctor(val2.x, val.y, val2.z); Vector3 val9 = default(Vector3); ((Vector3)(ref val9))..ctor(val2.x, val2.y, val.z); Vector3 val10 = default(Vector3); ((Vector3)(ref val10))..ctor(val2.x, val2.y, val2.z); Face(val6, val10, val9, val5, Vector3.up, material); Face(val7, val8, val4, val3, Vector3.down, material); Face(val10, val6, val4, val8, Vector3.forward, material); Face(val5, val9, val7, val3, Vector3.back, material); Face(val6, val5, val3, val4, Vector3.left, material); Face(val9, val10, val8, val7, Vector3.right, material); } public Mesh Build() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown Mesh val = new Mesh(); ((Object)val).name = "UniversalRebench_DecorativeTVRemote"; val.vertices = vertices.ToArray(); val.normals = normals.ToArray(); val.uv = uvs.ToArray(); val.subMeshCount = submeshes.Length; for (int i = 0; i < submeshes.Length; i++) { val.SetTriangles(submeshes[i].ToArray(), i); } val.RecalculateBounds(); return val; } } public const string PluginGuid = "justinrampage.universalrebench"; public const string PluginName = "RamUniversalRebench"; public const string PluginVersion = "1.0.3"; private const string PieceName = "piece_ramuniversalrebench"; private const string ArtisanName = "piece_artisanstation"; private const float UseRadius = 3.1f; private Harmony harmony; private ConfigEntry<float> searchRadius; private ConfigEntry<string> benchHex; private ConfigEntry<string> peltHex; private ConfigEntry<string> metalHex; private ConfigEntry<string> gemLiquidHex; private ConfigEntry<string> mistHex; private ConfigEntry<bool> mistEnabled; private ConfigEntry<bool> showRemote; private ConfigEntry<float> remoteScale; private ConfigEntry<float> remoteOffsetX; private ConfigEntry<float> remoteOffsetY; private ConfigEntry<float> remoteOffsetZ; private ConfigEntry<string> chainHex; private ConfigEntry<string> toolsHex; private ConfigEntry<bool> appearanceMaterialReport; private ConfigEntry<bool> autoRepairEnabled; private ConfigEntry<int> maxAutoRepairs; private static bool repairEligibilityScope; private static MethodInfo nativeRepairOne; private static bool nativeRepairReady; private static Coroutine repairRoutine; private static readonly List<ItemData> repairSnapshot = new List<ItemData>(); private static readonly Dictionary<string, Recipe> repairRecipes = new Dictionary<string, Recipe>(); private static RamUniversalRebenchPlugin instance; private static CraftingStation activeBench; private static CraftingStation activeSource; private static float proxyLastUsed; private static bool pendingNativeInteraction; private static readonly List<StationChoice> stationChoices = new List<StationChoice>(); private static InventoryGui trackedGui; private static GameObject headerOverlay; private static Transform craftingTabParent; private static TMP_Text hiddenNativeStationName; private static Color nativeStationNameOriginalColor; private static bool gamepadSelectorFocus; private static bool craftFilterBridgeEnabled; private static int suppressFilterThroughFrame = -1; private static MethodInfo padPressed; private static MethodInfo padActive; private static MethodInfo padReset; private static bool padResolved; private static float nextHeaderAttempt; private static FieldInfo craftFilterFocus; private static FieldInfo craftFilterPopup; private static MethodInfo craftFilterPaint; private static bool filterResolved; private static RectTransform nativeRecipeListRoot; private static TMP_Text dropdownFontSource; private static ScrollRect stationScroll; private static GameObject stationButton; private static TextMeshProUGUI buttonLabel; private static TextMeshProUGUI dropdownArrow; private static GameObject optionsPanel; private static bool optionsOpen; private static int optionIndex; private const int MaxVisibleRows = 18; private const float OptionHeight = 26f; private const int InitialRepairDelayFrames = 3; private static readonly List<Button> optionButtons = new List<Button>(); private static readonly Color NormalOption = new Color(0.15f, 0.13f, 0.11f, 1f); private static readonly Color SelectedOption = new Color(0.28f, 0.21f, 0.1f, 1f); private static readonly string[] PeltPartNames = new string[9] { "pelt", "hide", "leather", "fur", "skin", "cloth", "rug", "fabric", "trollhide" }; private static readonly string[] ChainPartNames = new string[5] { "chain", "links", "chainlink", "link_chain", "hanginglink" }; private static readonly string[] ToolPartNames = new string[16] { "tools", "tool_", "_tool", "hammer", "tongs", "anvil", "pliers", "wrench", "chisel", "saw", "axehead", "axe_head", "clamp", "vise", "vice", "file_tool" }; private void Awake() { //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Expected O, but got Unknown instance = this; searchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "StationSearchRadius", 15f, "Maximum distance in metres from the Universal Rebench to any real crafting station (2–30). Does not change vanilla station requirements."); benchHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "BenchHex", "#101010", "Color of the Universal Rebench body. Edit this hex value, then restart Valheim."); peltHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "PeltHex", "#0095da", "Pelt texture color (Rampage Blue by default). Existing configs keep their saved value. Restart Valheim after editing."); metalHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "MetalHex", "#777B82", "Experimental shared metal atlas region tint for chain, tools, gears, and pestle. These components are NOT independently isolated. Restart Valheim after editing."); gemLiquidHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "GemLiquidHex", "#e91919", "Optional color for an identifiable Artisan Table TearChanal/TearChannel diffuse texture. If no matching texture exists on the cloned model, the original crystal and liquid appearance is preserved. Restart Valheim after editing."); mistEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "TintCrystalMist", true, "Tint only the smoke particles behind the crystal. The pelt, crystal, and liquid are unchanged."); mistHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "CrystalMistHex", "#e91919", "Color for the mist behind the hanging crystal. Restart Valheim after changing."); showRemote = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "ShowRemote", true, "Show a small decorative universal TV remote resting on the blue pelt. Restart Valheim after changing."); remoteScale = ((BaseUnityPlugin)this).Config.Bind<float>("Remote Position", "Scale", 1f, "Remote size multiplier (0.5 to 1.5). Restart Valheim after changing."); remoteOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Remote Position", "OffsetX", -0.25f, "Fine-tune remote placement left/right in bench-local meters. Restart Valheim after changing."); remoteOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Remote Position", "OffsetY", -0.51f, "Fine-tune remote placement height in bench-local meters. Restart Valheim after changing."); remoteOffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>("Remote Position", "OffsetZ", 1f, "Fine-tune remote placement front/back in bench-local meters. Restart Valheim after changing."); chainHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "ChainHex", "#e91919", "Reserved for a future independently colorable chain; Artisan Table currently shares its texture/mesh."); toolsHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "ToolsHex", "#C0C0C0", "Reserved for future independently colorable tools; not applied in this build."); appearanceMaterialReport = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "LogMaterialMap", false, "Legacy v0.1.13 diagnostic option. The texture-atlas tint now logs a compact result automatically."); autoRepairEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto Repair", "Enabled", false, "Experimental: when opening Universal Rebench, repair eligible worn items using Valheim's native repair routine. Off by default. Does not move or equip any items."); maxAutoRepairs = ((BaseUnityPlugin)this).Config.Bind<int>("Auto Repair", "MaxRepairsPerInteraction", 64, "Hard safety limit (1-128) for auto repairs per Rebench interaction. One native repair call per frame; stops immediately if no repair occurs."); PrefabManager.OnVanillaPrefabsAvailable += RegisterBench; harmony = new Harmony("justinrampage.universalrebench"); PatchRequired("Interact", "InteractPrefix", isPrefix: true); PatchRequired("InUseDistance", "InUseDistancePostfix", isPrefix: false); PatchOptional("GetHoverText", "HoverTextPostfix", isPrefix: false); PatchInventoryUpdate(); PatchGamepadNavigation(); PatchCraftFilterInputBridge(); PatchScopedRepairEligibility(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RamUniversalRebench 1.0.3 loaded. Native station-name dropdown; Craft Filter remains optional."); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterBench; StopAutoRepair(); ResetSession(); if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)instance == (Object)(object)this) { instance = null; } } private void PatchRequired(string methodName, string patchName, bool isPrefix) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(CraftingStation), methodName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(RamUniversalRebenchPlugin), patchName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogError((object)("Required crafting API missing: " + methodName + ". Prototype cannot provide station routing.")); } else if (isPrefix) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private void PatchOptional(string methodName, string patchName, bool isPrefix) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(CraftingStation), methodName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(RamUniversalRebenchPlugin), patchName, (Type[])null, (Type[])null); if (!(methodInfo == null) && !(methodInfo2 == null)) { if (isPrefix) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private void PatchInventoryUpdate() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGui), "Update", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(RamUniversalRebenchPlugin), "InventoryUpdatePostfix", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"InventoryGui.Update unavailable; station-name dropdown cannot be displayed."); } else { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private void PatchScopedRepairEligibility() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGui), "CanRepair", new Type[1] { typeof(ItemData) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(RamUniversalRebenchPlugin), "ScopedCanRepairPostfix", (Type[])null, (Type[])null); nativeRepairOne = AccessTools.Method(typeof(InventoryGui), "RepairOneItem", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null || nativeRepairOne == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Native repair API unavailable. Experimental auto-repair disabled; all other Rebench functions remain enabled."); return; } ParameterInfo[] parameters = nativeRepairOne.GetParameters(); if (parameters.Length != 0 && (parameters.Length != 1 || !(parameters[0].ParameterType == typeof(bool)))) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Unexpected RepairOneItem signature. Experimental auto-repair disabled."); return; } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); nativeRepairReady = true; } private static void ScopedCanRepairPostfix(ItemData item, ref bool __result) { if ((!repairEligibilityScope | __result) || item == null || item.m_shared == null || !item.m_shared.m_canBeReparied || (Object)(object)activeBench == (Object)null || (Object)(object)instance == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !PlayerNearBench(localPlayer, activeBench)) { return; } try { Recipe value = null; string name = item.m_shared.m_name; if (string.IsNullOrEmpty(name)) { return; } if (!repairRecipes.TryGetValue(name, out value)) { value = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetRecipe(item) : null); repairRecipes[name] = value; } if ((Object)(object)value == (Object)null) { return; } foreach (StationChoice stationChoice in stationChoices) { CraftingStation station = stationChoice.Station; if (!((Object)(object)station == (Object)null) && station.m_canRepair && instance.SourceWithinRange(activeBench, station) && (((Object)(object)value.m_repairStation != (Object)null && value.m_repairStation.m_name == station.m_name) || ((Object)(object)value.m_craftingStation != (Object)null && value.m_craftingStation.m_name == station.m_name)) && Mathf.Min(station.GetLevel(true), 4) >= value.m_minStationLevel && station.CheckUsable(localPlayer, false)) { __result = true; break; } } } catch (Exception ex) { if ((Object)(object)instance != (Object)null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)("Auto-repair eligibility check skipped: " + ex.Message)); } } } private void StartAutoRepair() { StopAutoRepair(); if (autoRepairEnabled.Value && nativeRepairReady && !((Object)(object)activeBench == (Object)null) && !((Object)(object)activeSource == (Object)null)) { repairRoutine = ((MonoBehaviour)this).StartCoroutine(AutoRepairOnce(activeBench, activeSource)); } } private void StopAutoRepair() { if (repairRoutine != null) { ((MonoBehaviour)this).StopCoroutine(repairRoutine); repairRoutine = null; } repairEligibilityScope = false; repairRecipes.Clear(); repairSnapshot.Clear(); } private IEnumerator AutoRepairOnce(CraftingStation bench, CraftingStation source) { int attempts = 0; while (!InventoryGui.IsVisible() && attempts++ < 10) { yield return null; } Player player = Player.m_localPlayer; if ((Object)(object)player == (Object)null || !InventoryGui.IsVisible() || !CanAutoRepairHere(player, bench, source)) { repairRoutine = null; yield break; } for (int i = 0; i < 3; i++) { if ((Object)(object)player == (Object)null || !InventoryGui.IsVisible() || !CanAutoRepairHere(player, bench, source)) { repairRoutine = null; yield break; } yield return null; } int repaired = 0; int cap = Mathf.Clamp(maxAutoRepairs.Value, 1, 128); repairRecipes.Clear(); try { while (repaired < cap && CanAutoRepairHere(player, bench, source)) { InventoryGui val = InventoryGui.instance; if ((Object)(object)val == (Object)null || !InventoryGui.IsVisible()) { break; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { break; } repairSnapshot.Clear(); inventory.GetWornItems(repairSnapshot); if (repairSnapshot.Count == 0) { break; } float num = 0f; foreach (ItemData item in repairSnapshot) { if (item != null && item.m_shared != null) { num += Mathf.Max(0f, item.m_durability); } } repairEligibilityScope = true; try { object[] parameters = ((nativeRepairOne.GetParameters().Length == 0) ? null : new object[1] { false }); nativeRepairOne.Invoke(val, parameters); } finally { repairEligibilityScope = false; } float num2 = 0f; foreach (ItemData item2 in repairSnapshot) { if (item2 != null && item2.m_shared != null) { num2 += Mathf.Max(0f, item2.m_durability); } } if (num2 <= num + 0.001f) { break; } repaired++; yield return null; } } finally { repairEligibilityScope = false; repairSnapshot.Clear(); repairRecipes.Clear(); repairRoutine = null; } if (repaired > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Universal Rebench auto-repaired " + repaired + " items via native repair (" + stationChoices.Count + " nearby station types).")); } } private bool CanAutoRepairHere(Player player, CraftingStation bench, CraftingStation source) { if ((Object)(object)player != (Object)null && (Object)(object)activeBench == (Object)(object)bench && (Object)(object)activeSource == (Object)(object)source && PlayerNearBench(player, bench) && SourceWithinRange(bench, source) && (Object)(object)player.GetCurrentCraftingStation() == (Object)(object)source && source.m_canRepair) { return source.CheckUsable(player, false); } return false; } private void PatchGamepadNavigation() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGui), "UpdateRecipeGamepadInput", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(RamUniversalRebenchPlugin), "GamepadRecipePrefix", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Controller navigation callback unavailable; mouse selection still works."); return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo3 = AccessTools.Method(typeof(InventoryGui), "Update", (Type[])null, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(typeof(RamUniversalRebenchPlugin), "GamepadCancelPrefix", (Type[])null, (Type[])null); if (methodInfo3 != null && methodInfo4 != null) { harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private void PatchCraftFilterInputBridge() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown Type type = AccessTools.TypeByName("JustinRampage.ModOrigin.ModOriginPlugin"); if (!(type == null)) { MethodInfo methodInfo = AccessTools.Method(type, "HandleRecipeGamepadInput", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(RamUniversalRebenchPlugin), "CraftFilterInputPrefix", (Type[])null, (Type[])null); if (methodInfo != null && methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); craftFilterBridgeEnabled = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Optional Craft Filter controller-focus handoff enabled."); } } } private static bool CraftFilterInputPrefix(ref bool __result) { if (Time.frameCount <= suppressFilterThroughFrame) { __result = false; return false; } if ((Object)(object)trackedGui == (Object)null || !IsOurCraftingScreen(trackedGui) || !IsCraftTab(trackedGui) || !PadActive()) { return true; } if (gamepadSelectorFocus) { HandleSelectorInput(trackedGui); __result = false; return false; } if (CraftFilterOnHeader() && PadLeft()) { EnterSelectorFocus(); __result = false; return false; } return true; } private static void EnterSelectorFocus() { gamepadSelectorFocus = true; try { if (craftFilterFocus != null) { craftFilterFocus.SetValue(null, -1); } if (craftFilterPaint != null) { craftFilterPaint.Invoke(null, null); } } catch (Exception ex) { if ((Object)(object)instance != (Object)null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)("Filter focus handoff: " + ex.Message)); } } if ((Object)(object)instance != (Object)null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)"Rebench controller focus entered."); } } private static void ReturnSelectorFocusToCrafting(InventoryGui gui) { if (optionsOpen) { CloseOptions(); } gamepadSelectorFocus = false; if (!IsCraftTab(gui) || craftFilterFocus == null) { return; } try { craftFilterFocus.SetValue(null, 0); if (craftFilterPaint != null) { craftFilterPaint.Invoke(null, null); } } catch (Exception ex) { if ((Object)(object)instance != (Object)null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)("Return to Type filter: " + ex.Message)); } } } private static void HandleSelectorInput(InventoryGui gui) { if ((Object)(object)instance == (Object)null) { return; } if (optionsOpen) { if (stationChoices.Count == 0) { CloseOptions(); } else if (PadUp()) { instance.FocusOption((optionIndex - 1 + stationChoices.Count) % stationChoices.Count); } else if (PadBelow()) { instance.FocusOption((optionIndex + 1) % stationChoices.Count); } else if (PadDown("JoyButtonA") && optionIndex >= 0 && optionIndex < stationChoices.Count) { suppressFilterThroughFrame = Time.frameCount + 1; StationChoice choice = stationChoices[optionIndex]; instance.RouteTo(choice); } } else if (PadDown("JoyButtonA")) { instance.OpenOptions(); } else if (PadRight() || PadBelow()) { ReturnSelectorFocusToCrafting(gui); } } private static bool IsCraftTab(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return false; } try { MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGui), "InCraftTab", Type.EmptyTypes, (Type[])null); return methodInfo != null && (bool)methodInfo.Invoke(gui, null); } catch { return false; } } private static void ResolveGamepadInput() { if (!padResolved) { padResolved = true; Type type = AccessTools.TypeByName("ZInput"); if (!(type == null)) { padPressed = AccessTools.Method(type, "GetButtonDown", new Type[1] { typeof(string) }, (Type[])null); padActive = AccessTools.Method(type, "IsGamepadActive", Type.EmptyTypes, (Type[])null); padReset = AccessTools.Method(type, "ResetButtonStatus", new Type[1] { typeof(string) }, (Type[])null); } } } private static bool PadActive() { ResolveGamepadInput(); try { return padActive != null && (bool)padActive.Invoke(null, null); } catch { return false; } } private static bool PadDown(string name) { try { return padPressed != null && (bool)padPressed.Invoke(null, new object[1] { name }); } catch { return false; } } private static bool PadUp() { if (!PadDown("JoyDPadUp") && !PadDown("JoyLStickUp")) { return PadDown("JoyRStickUp"); } return true; } private static bool PadBelow() { if (!PadDown("JoyDPadDown") && !PadDown("JoyLStickDown")) { return PadDown("JoyRStickDown"); } return true; } private static bool PadLeft() { if (!PadDown("JoyDPadLeft") && !PadDown("JoyLStickLeft")) { return PadDown("JoyRStickLeft"); } return true; } private static bool PadRight() { if (!PadDown("JoyDPadRight") && !PadDown("JoyLStickRight")) { return PadDown("JoyRStickRight"); } return true; } private static bool CraftFilterOnHeader() { if (!filterResolved) { filterResolved = true; Type type = AccessTools.TypeByName("JustinRampage.ModOrigin.ModOriginPlugin"); if (type != null) { craftFilterFocus = AccessTools.Field(type, "padFilterFocus"); craftFilterPopup = AccessTools.Field(type, "padPopupOpen"); craftFilterPaint = AccessTools.Method(type, "PaintPadFocus", (Type[])null, (Type[])null); } } if (craftFilterFocus == null) { return false; } try { int num = (int)craftFilterFocus.GetValue(null); bool flag = craftFilterPopup != null && (bool)craftFilterPopup.GetValue(null); return num == 0 && !flag; } catch { return false; } } private static bool IsOurCraftingScreen(InventoryGui gui) { if ((Object)(object)gui != (Object)null && (Object)(object)stationButton != (Object)null && stationButton.activeInHierarchy && (Object)(object)activeBench != (Object)null && (Object)(object)activeSource != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && PlayerNearBench(Player.m_localPlayer, activeBench) && InventoryGui.IsVisible() && (Object)(object)Player.m_localPlayer.GetCurrentCraftingStation() == (Object)(object)activeSource) { return CraftPanelVisible(gui); } return false; } private static void GamepadCancelPrefix(InventoryGui __instance) { if (!gamepadSelectorFocus || !IsOurCraftingScreen(__instance) || !PadActive() || !PadDown("JoyButtonB")) { return; } if (optionsOpen) { CloseOptions(); } else { gamepadSelectorFocus = false; } try { if (padReset != null) { padReset.Invoke(null, new object[1] { "JoyButtonB" }); } } catch { } } private static bool GamepadRecipePrefix(InventoryGui __instance) { if (!IsOurCraftingScreen(__instance) || !PadActive()) { gamepadSelectorFocus = false; return true; } if (craftFilterBridgeEnabled && IsCraftTab(__instance)) { return true; } if (gamepadSelectorFocus) { HandleSelectorInput(__instance); return false; } if (!PadUp()) { return true; } try { MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGui), "GetSelectedRecipeIndex", new Type[1] { typeof(bool) }, (Type[])null); if (methodInfo == null || (int)methodInfo.Invoke(__instance, new object[1] { false }) != 0) { return true; } } catch { return true; } EnterSelectorFocus(); return false; } private void RegisterBench() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= RegisterBench; try { PieceConfig val = new PieceConfig { Name = "Universal Rebench", Description = "One bench, many stations. Requires nearby real crafting stations.", PieceTable = "Hammer", Category = "Crafting", CraftingStation = "piece_workbench" }; val.AddRequirement("FineWood", 6, true); val.AddRequirement("GreydwarfEye", 6, true); val.AddRequirement("SurtlingCore", 6, true); CustomPiece val2 = new CustomPiece("piece_ramuniversalrebench", "piece_artisanstation", val); if ((Object)(object)val2.PiecePrefab == (Object)null || (Object)(object)val2.Piece == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not clone the Artisan Table. No custom bench registered."); return; } CraftingStation component = val2.PiecePrefab.GetComponent<CraftingStation>(); if ((Object)(object)component == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"The cloned Artisan Table has no CraftingStation component. Aborting registration."); return; } component.m_name = "Universal Rebench"; component.m_rangeBuild = 0f; component.m_canRepair = false; RecolorBench(val2.PiecePrefab); TintCrystalMist(val2.PiecePrefab); if (showRemote.Value) { try { AddDecorativeRemote(val2.PiecePrefab); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Decorative remote skipped: " + ex)); } } PieceManager.Instance.AddPiece(val2); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered piece_ramuniversalrebench as a separate Hammer crafting piece."); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to register Universal Rebench: " + ex2)); } } private static bool HasNamedPart(string identity, string[] names) { for (int i = 0; i < names.Length; i++) { if (identity.IndexOf(names[i], StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static string RendererPath(Transform transform, Transform root) { List<string> list = new List<string>(); Transform val = transform; int num = 0; while ((Object)(object)val != (Object)null && num++ < 32) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list.ToArray()); } private void TintCrystalMist(GameObject prefab) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00de: 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_0146: Expected O, but got Unknown //IL_0173: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) if (!mistEnabled.Value) { return; } Color val = ParseColor(mistHex.Value, new Color(0.914f, 0.098f, 0.098f)); ParticleSystem[] componentsInChildren = prefab.GetComponentsInChildren<ParticleSystem>(true); int num = 0; foreach (ParticleSystem val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || ((Object)((Component)val2).gameObject).name != "smoke_expl") { continue; } Transform parent = ((Component)val2).transform.parent; if ((Object)(object)parent == (Object)null || ((Object)parent).name != "Tear") { continue; } try { MainModule main = val2.main; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; Color color = ((MinMaxGradient)(ref startColor)).color; ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(val.r, val.g, val.b, color.a)); ParticleSystemRenderer component = ((Component)val2).GetComponent<ParticleSystemRenderer>(); if ((Object)(object)component != (Object)null) { Material[] sharedMaterials = ((Renderer)component).sharedMaterials; if (sharedMaterials != null && sharedMaterials.Length != 0) { Material[] array = (Material[])(object)new Material[sharedMaterials.Length]; for (int j = 0; j < sharedMaterials.Length; j++) { Material val3 = sharedMaterials[j]; if (!((Object)(object)val3 == (Object)null)) { Material val4 = new Material(val3); ((Object)val4).name = "RamRebench_Mist_" + ((Object)val3).name; if (val4.HasProperty("_TintColor")) { Color color2 = val4.GetColor("_TintColor"); val4.SetColor("_TintColor", new Color(val.r, val.g, val.b, color2.a)); } else if (val4.HasProperty("_Color")) { Color color3 = val4.GetColor("_Color"); val4.SetColor("_Color", new Color(val.r, val.g, val.b, color3.a)); } array[j] = val4; } } ((Renderer)component).sharedMaterials = array; } } num++; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Crystal mist tint could not be applied: " + ex.Message)); } } if (num > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Crystal mist tint applied to " + num + " Tear/smoke_expl system(s).")); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Crystal mist emitter Tear/smoke_expl was not found; leaving original mist unchanged."); } } private static Material MakeRemoteMaterial(Material template, Color color, string label) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(template); ((Object)val).name = "RebenchRemote_" + label; if (val.HasProperty("_MainTex")) { val.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture); } if (val.HasProperty("_BumpMap")) { val.SetTexture("_BumpMap", (Texture)null); } if (val.HasProperty("_Metallic")) { val.SetFloat("_Metallic", 0.15f); } if (val.HasProperty("_Color")) { val.SetColor("_Color", color); } if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", color); } if (val.HasProperty("_EmissionColor")) { val.SetColor("_EmissionColor", Color.black); } return val; } private unsafe void AddDecorativeRemote(GameObject prefab) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_023e: 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_026e: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Expected O, but got Unknown //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_0528: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0555: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) Transform val = prefab.transform.Find("New/high/ArtisanTable.004"); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Decorative remote: intact Artisan Table mesh not found; placement skipped."); return; } Mesh val2 = null; MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null) { val2 = component.sharedMesh; } if ((Object)(object)val2 == (Object)null) { SkinnedMeshRenderer component2 = ((Component)val).GetComponent<SkinnedMeshRenderer>(); if ((Object)(object)component2 != (Object)null) { val2 = component2.sharedMesh; } } if ((Object)(object)val2 == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Decorative remote: no mesh bounds available; placement skipped."); return; } Bounds bounds = val2.bounds; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(((Bounds)(ref bounds)).center.x, Mathf.Lerp(((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y, 0.89f), Mathf.Lerp(((Bounds)(ref bounds)).min.z, ((Bounds)(ref bounds)).max.z, 0.61f)); Vector3 val4 = prefab.transform.InverseTransformPoint(val.TransformPoint(val3)); val4 += new Vector3(remoteOffsetX.Value, remoteOffsetY.Value + 0.024f, remoteOffsetZ.Value); Renderer component3 = ((Component)val).GetComponent<Renderer>(); Material val5 = null; if ((Object)(object)component3 != (Object)null) { Material[] sharedMaterials = component3.sharedMaterials; foreach (Material val6 in sharedMaterials) { if ((Object)(object)val6 != (Object)null && ((Object)val6).name.Contains("ArtisanTable")) { val5 = val6; break; } } if ((Object)(object)val5 == (Object)null) { val5 = component3.sharedMaterial; } } if ((Object)(object)val5 == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Decorative remote: no suitable Valheim material found; skipped."); return; } RemoteMeshBuilder remoteMeshBuilder = new RemoteMeshBuilder(); remoteMeshBuilder.Box(new Vector3(0f, 0f, 0f), new Vector3(0.062f, 0.018f, 0.198f), 0); remoteMeshBuilder.Box(new Vector3(0f, 0.01f, 0f), new Vector3(0.055f, 0.003f, 0.181f), 1); remoteMeshBuilder.Box(new Vector3(0f, 0.014f, 0.074f), new Vector3(0.013f, 0.003f, 0.012f), 3); remoteMeshBuilder.Box(new Vector3(0f, 0.014f, 0.029f), new Vector3(0.038f, 0.003f, 0.038f), 2); remoteMeshBuilder.Box(new Vector3(0f, 0.016f, 0.029f), new Vector3(0.015f, 0.003f, 0.015f), 1); for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { remoteMeshBuilder.Box(new Vector3((float)(k - 1) * 0.017f, 0.014f, -0.008f - (float)j * 0.017f), new Vector3(0.011f, 0.003f, 0.009f), 2); } } remoteMeshBuilder.Box(new Vector3(-0.018f, 0.014f, -0.075f), new Vector3(0.008f, 0.003f, 0.008f), 3); remoteMeshBuilder.Box(new Vector3(-0.006f, 0.014f, -0.075f), new Vector3(0.008f, 0.003f, 0.008f), 4); remoteMeshBuilder.Box(new Vector3(0.006f, 0.014f, -0.075f), new Vector3(0.008f, 0.003f, 0.008f), 5); remoteMeshBuilder.Box(new Vector3(0.018f, 0.014f, -0.075f), new Vector3(0.008f, 0.003f, 0.008f), 2); GameObject val7 = new GameObject("Universal_Remote_EasterEgg"); val7.transform.SetParent(prefab.transform, false); val7.transform.localPosition = val4; val7.transform.localRotation = Quaternion.Euler(0f, -20f, 0f); val7.transform.localScale = Vector3.one * Mathf.Clamp(remoteScale.Value, 0.5f, 1.5f); val7.AddComponent<MeshFilter>().sharedMesh = remoteMeshBuilder.Build(); ((Renderer)val7.AddComponent<MeshRenderer>()).sharedMaterials = (Material[])(object)new Material[6] { MakeRemoteMaterial(val5, new Color(0.07f, 0.075f, 0.085f), "Shell"), MakeRemoteMaterial(val5, new Color(0.14f, 0.15f, 0.16f), "Face"), MakeRemoteMaterial(val5, new Color(0.48f, 0.5f, 0.53f), "Buttons"), MakeRemoteMaterial(val5, new Color(0.91f, 0.1f, 0.1f), "Red"), MakeRemoteMaterial(val5, new Color(0f, 0.58f, 0.86f), "Blue"), MakeRemoteMaterial(val5, new Color(0.95f, 0.72f, 0.15f), "Yellow") }; ManualLogSource logger = ((BaseUnityPlugin)this).Logger; string[] obj = new string[6] { "Decorative TV remote attached to Universal Rebench at ", null, null, null, null, null }; Vector3 val8 = val4; obj[1] = ((object)(*(Vector3*)(&val8))/*cast due to .constrained prefix*/).ToString(); obj[2] = " (scale "; obj[3] = val7.transform.localScale.x.ToString(); obj[4] = "). Model bounds: "; Bounds val9 = bounds; obj[5] = ((object)(*(Bounds*)(&val9))/*cast due to .constrained prefix*/).ToString(); logger.LogInfo((object)string.Concat(obj)); } private void RecolorBench(GameObject prefab) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) Color benchColor = ParseColor(benchHex.Value, new Color(0.063f, 0.063f, 0.063f)); Color peltColor = ParseColor(peltHex.Value, new Color(0f, 0.584f, 0.855f)); Color metalColor = ParseColor(metalHex.Value, new Color(0.467f, 0.482f, 0.51f)); Color tearColor = ParseColor(gemLiquidHex.Value, new Color(0.914f, 0.098f, 0.098f)); Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); Dictionary<int, Texture2D> dictionary = new Dictionary<int, Texture2D>(); Dictionary<int, Texture2D> dictionary2 = new Dictionary<int, Texture2D>(); int num = 0; int num2 = 0; int num3 = 0; foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { continue; } Material[] array = (Material[])(object)new Material[sharedMaterials.Length]; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if ((Object)(object)val2 == (Object)null) { continue; } Material val3 = new Material(val2); ((Object)val3).name = "RamRebench_" + ((Object)val2).name; Texture obj = (val2.HasProperty("_MainTex") ? val2.GetTexture("_MainTex") : null); Texture2D val4 = (Texture2D)(object)((obj is Texture2D) ? obj : null); if ((Object)(object)val4 != (Object)null && (((Object)val4).name == "Artisan_Table_d" || ((Object)val4).name == "Artisan_Table_Worn_d")) { int instanceID = ((Object)val4).GetInstanceID(); if (!dictionary.TryGetValue(instanceID, out var value)) { value = CreateTintedAtlas(val4, benchColor, peltColor, metalColor); if ((Object)(object)value != (Object)null) { dictionary[instanceID] = value; } } if ((Object)(object)value != (Object)null) { val3.SetTexture("_MainTex", (Texture)(object)value); if (val3.HasProperty("_Color")) { val3.SetColor("_Color", Color.white); } if (val3.HasProperty("_BaseColor")) { val3.SetColor("_BaseColor", Color.white); } num++; } } else { string propertyName; Texture2D val5 = FindNamedTearTexture(val2, out propertyName); if ((Object)(object)val5 != (Object)null) { int instanceID2 = ((Object)val5).GetInstanceID(); if (!dictionary2.TryGetValue(instanceID2, out var value2)) { value2 = CreateTintedTear(val5, tearColor); if ((Object)(object)value2 != (Object)null) { dictionary2[instanceID2] = value2; } } if ((Object)(object)value2 != (Object)null) { val3.SetTexture(propertyName, (Texture)(object)value2); if (propertyName == "_MainTex" || propertyName == "_BaseMap") { if (val3.HasProperty("_Color")) { val3.SetColor("_Color", Color.white); } if (val3.HasProperty("_BaseColor")) { val3.SetColor("_BaseColor", Color.white); } } num2++; } else { num3++; } } else { num3++; } } array[j] = val3; } val.sharedMaterials = array; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Rebench atlas appearance: " + dictionary.Count + " Artisan texture(s) recolored, " + num + " material slots; " + dictionary2.Count + " Tear texture(s), " + num2 + " Tear material slots; " + num3 + " other slots preserved. MetalHex affects one shared metal UV region.")); if (num2 == 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Rebench optional Tear tint not applied: no usable TearChanal/TearChannel diffuse texture found on the cloned prefab; original crystal and liquid preserved."); } if (num == 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Rebench pelt tint inactive: could not find/read Artisan_Table_d. The original Artisan Table appearance was preserved."); } } private static bool IsNamedTearTexture(string name) { if (string.IsNullOrEmpty(name)) { return false; } if (!name.StartsWith("TearChanal_d", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("TearChannel_d", StringComparison.OrdinalIgnoreCase)) { return name.StartsWith("TearChanel_d", StringComparison.OrdinalIgnoreCase); } return true; } private static Texture2D FindNamedTearTexture(Material material, out string propertyName) { propertyName = null; if ((Object)(object)material == (Object)null) { return null; } string[] texturePropertyNames; try { texturePropertyNames = material.GetTexturePropertyNames(); } catch { return null; } if (texturePropertyNames == null) { return null; } string[] array = texturePropertyNames; foreach (string text in array) { Texture2D val = null; try { Texture texture = material.GetTexture(text); val = (Texture2D)(object)((texture is Texture2D) ? texture : null); } catch { continue; } if ((Object)(object)val != (Object)null && IsNamedTearTexture(((Object)val).name)) { propertyName = text; return val; } } return null; } private Texture2D CreateTintedAtlas(Texture2D source, Color benchColor, Color peltColor, Color metalColor) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0181: 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_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) if (((Texture)source).width < 128 || ((Texture)source).height < 128 || ((Texture)source).width > 1024 || ((Texture)source).height > 1024) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Rebench skipped unexpected texture dimensions for " + ((Object)source).name + ": " + ((Texture)source).width + "x" + ((Texture)source).height)); return null; } RenderTexture active = RenderTexture.active; RenderTexture val = null; Texture2D val2 = null; try { val = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0); Graphics.Blit((Texture)(object)source, val); RenderTexture.active = val; val2 = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, false); val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0, false); val2.Apply(false, false); Color32[] pixels = val2.GetPixels32(); int num = Mathf.RoundToInt((float)((Texture)source).width * 156f / 256f); int num2 = Mathf.RoundToInt((float)((Texture)source).height * 100f / 256f); int num3 = 0; for (int i = 0; i < ((Texture)source).height; i++) { for (int j = 0; j < ((Texture)source).width; j++) { int num4 = i * ((Texture)source).width + j; Color32 val3 = pixels[num4]; float num5 = ((float)(int)val3.r * 0.299f + (float)(int)val3.g * 0.587f + (float)(int)val3.b * 0.114f) / 255f; bool num6 = j >= num && i < num2; bool flag = j >= num && i >= num2; Color val4 = (num6 ? peltColor : (flag ? metalColor : benchColor)); float num7 = (num6 ? (0.38f + 1.12f * num5) : (flag ? (0.55f + 0.95f * num5) : (0.45f + 1f * num5))); pixels[num4] = new Color32((byte)Mathf.Clamp(Mathf.RoundToInt(val4.r * num7 * 255f), 0, 255), (byte)Mathf.Clamp(Mathf.RoundToInt(val4.g * num7 * 255f), 0, 255), (byte)Mathf.Clamp(Mathf.RoundToInt(val4.b * num7 * 255f), 0, 255), val3.a); if (num6) { num3++; } } } val2.SetPixels32(pixels); val2.Apply(false, true); ((Object)val2).name = "RamRebench_Colored_" + ((Object)source).name; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Rebench recolored texture " + ((Object)source).name + " (" + ((Texture)source).width + "x" + ((Texture)source).height + ") including " + num3 + " pelt-region pixels.")); return val2; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Rebench could not recolor " + ((Object)source).name + ": " + ex.Message)); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } return null; } finally { RenderTexture.active = active; if ((Object)(object)val != (Object)null) { RenderTexture.ReleaseTemporary(val); } } } private Texture2D CreateTintedTear(Texture2D source, Color tearColor) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) if (((Texture)source).width < 128 || ((Texture)source).height < 128 || ((Texture)source).width > 2048 || ((Texture)source).height > 2048) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Rebench skipped unexpected Tear texture dimensions: " + ((Texture)source).width + "x" + ((Texture)source).height)); return null; } RenderTexture active = RenderTexture.active; RenderTexture val = null; Texture2D val2 = null; try { val = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0); Graphics.Blit((Texture)(object)source, val); RenderTexture.active = val; val2 = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, false); val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0, false); val2.Apply(false, false); Color32[] pixels = val2.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { Color32 val3 = pixels[i]; float num = ((float)(int)val3.r * 0.299f + (float)(int)val3.g * 0.587f + (float)(int)val3.b * 0.114f) / 255f; float num2 = Mathf.Clamp01(0.53f + 0.65f * num); pixels[i] = new Color32((byte)Mathf.Clamp(Mathf.RoundToInt(tearColor.r * num2 * 255f), 0, 255), (byte)Mathf.Clamp(Mathf.RoundToInt(tearColor.g * num2 * 255f), 0, 255), (byte)Mathf.Clamp(Mathf.RoundToInt(tearColor.b * num2 * 255f), 0, 255), val3.a); } val2.SetPixels32(pixels); val2.Apply(false, true); ((Object)val2).name = "RamRebench_Colored_" + ((Object)source).name; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Rebench recolored Tear texture " + ((Object)source).name + " (" + ((Texture)source).width + "x" + ((Texture)source).height + ").")); return val2; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Rebench could not recolor Tear texture " + ((Object)source).name + ": " + ex.Message)); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } return null; } finally { RenderTexture.active = active; if ((Object)(object)val != (Object)null) { RenderTexture.ReleaseTemporary(val); } } } private static Color ParseColor(string text, Color fallback) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (!ColorUtility.TryParseHtmlString(text ?? "", ref result)) { return fallback; } return result; } private static bool IsOurBench(CraftingStation station) { if ((Object)(object)station != (Object)null && (Object)(object)((Component)station).gameObject != (Object)null) { return ((Object)((Component)station).gameObject).name.StartsWith("piece_ramuniversalrebench", StringComparison.Ordinal); } return false; } private static bool InteractPrefix(CraftingStation __instance, Humanoid __0, bool __1, ref bool __result) { if (!IsOurBench(__instance) || (Object)(object)instance == (Object)null) { return true; } __result = false; if (__1 || (Object)(object)__0 == (Object)null || (Object)(object)__0 != (Object)(object)Player.m_localPlayer || InventoryGui.IsVisible() || !PlayerNearBench(Player.m_localPlayer, __instance)) { return false; } instance.OpenDefault(__instance); __result = true; return false; } private static void HoverTextPostfix(CraftingStation __instance, ref string __result) { if (IsOurBench(__instance)) { string text = "Universal Rebench\n[<color=yellow><b>$KEY_Use</b></color>] Craft & Repair"; __result = ((Localization.instance != null) ? Localization.instance.Localize(text) : "Universal Rebench\nCraft & Repair"); } } private static void InUseDistancePostfix(CraftingStation __instance, ref bool __result) { if (!__result && !((Object)(object)instance == (Object)null) && !((Object)(object)activeSource == (Object)null) && !((Object)(object)activeBench == (Object)null) && !((Object)(object)__instance != (Object)(object)activeSource)) { Player localPlayer = Player.m_localPlayer; if (PlayerNearBench(localPlayer, activeBench) && instance.SourceWithinRange(activeBench, activeSource) && (pendingNativeInteraction || ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.GetCurrentCraftingStation() == (Object)(object)activeSource))) { __result = true; } } } private void OpenDefault(CraftingStation bench) { CloseOptions(); activeBench = bench; ScanStationsOnce(bench); if (stationChoices.Count == 0) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "No nearby crafting stations. Build a Workbench first.", 0, (Sprite)null, false); } activeBench = null; return; } StationChoice stationChoice = stationChoices.Find((StationChoice s) => s.PrefabName == "piece_workbench"); if (stationChoice == null) { stationChoice = stationChoices[0]; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Rebench opened, " + stationChoices.Count + " real station types; starting with " + stationChoice.DisplayName + ".")); RouteTo(stationChoice); StartAutoRepair(); } private void ScanStationsOnce(CraftingStation bench) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) stationChoices.Clear(); if ((Object)(object)bench == (Object)null) { return; } float num = Mathf.Clamp(searchRadius.Value, 2f, 30f); Dictionary<string, StationChoice> dictionary = new Dictionary<string, StationChoice>(StringComparer.Ordinal); CraftingStation[] array = Object.FindObjectsByType<CraftingStation>((FindObjectsSortMode)0); foreach (CraftingStation val in array) { if ((Object)(object)val == (Object)null || IsOurBench(val) || (Object)(object)((Component)val).gameObject == (Object)null) { continue; } float num2 = Vector3.Distance(((Component)bench).transform.position, ((Component)val).transform.position); if (num2 > num) { continue; } string text = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(); if (!string.IsNullOrEmpty(text)) { string displayName = HumanizeStationPrefab(text); string text2 = TryLocalizeStationName(val.m_name); if (!string.IsNullOrEmpty(text2) && !text2.StartsWith("$", StringComparison.Ordinal)) { displayName = text2; } int level = 0; try { level = val.GetLevel(true); } catch (Exception) { } if (!dictionary.TryGetValue(text, out var value) || !(value.Distance <= num2)) { dictionary[text] = new StationChoice { Station = val, PrefabName = text, DisplayName = displayName, Distance = num2, Level = level }; } } } stationChoices.AddRange(dictionary.Values); stationChoices.Sort((StationChoice a, StationChoice b) => string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase)); foreach (StationChoice stationChoice in stationChoices) { ((BaseUnityPlugin)this).Logger.LogInfo((object)(" Station found: " + stationChoice.DisplayName + " [" + stationChoice.PrefabName + "] level " + stationChoice.Level + " distance " + stationChoice.Distance.ToString("F1") + "m")); } } private static string HumanizeStationPrefab(string prefab) { return prefab switch { "piece_workbench" => "Workbench", "forge" => "Forge", "piece_blackforge" => "Black Forge", "piece_magetable" => "Galdr Table", "piece_artisanstation" => "Artisan Table", "piece_stonecutter" => "Stonecutter", "piece_cauldron" => "Cauldron", _ => (prefab.StartsWith("piece_", StringComparison.Ordinal) ? prefab.Substring(6) : prefab).Replace('_', ' '), }; } private static string TryLocalizeStationName(string token) { if (string.IsNullOrEmpty(token) || !token.StartsWith("$", StringComparison.Ordinal)) { return token; } try { Type type = AccessTools.TypeByName("Localization"); if (type == null) { return null; } BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; PropertyInfo property = type.GetProperty("instance", bindingAttr); object obj = ((property != null) ? property.GetValue(null, null) : null); if (obj == null) { FieldInfo field = type.GetField("instance", bindingAttr); if (field != null) { obj = field.GetValue(null); } } if (obj == null) { return null; } MethodInfo method = type.GetMethod("Localize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); return (method != null) ? (method.Invoke(obj, new object[1] { token }) as string) : null; } catch (Exception) { return null; } } private static bool PlayerNearBench(Player player, CraftingStation bench) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)null && (Object)(object)bench != (Object)null) { return Vector3.Distance(((Component)player).transform.position, ((Component)bench).transform.position) <= 3.1f; } return false; } private bool SourceWithinRange(CraftingStation bench, CraftingStation source) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bench != (Object)null && (Object)(object)source != (Object)null) { return Vector3.Distance(((Component)bench).transform.position, ((Component)source).transform.position) <= Mathf.Clamp(searchRadius.Value, 2f, 30f); } return false; } private void RouteTo(StationChoice choice) { if (repairRoutine != null) { StopAutoRepair(); } CraftingStation val = choice?.Station; if ((Object)(object)val == (Object)null || (Object)(object)activeBench == (Object)null || !SourceWithinRange(activeBench, val) || !PlayerNearBench(Player.m_localPlayer, activeBench)) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Crafting station unavailable or out of range.", 0, (Sprite)null, false); } return; } CloseOptions(); CraftingStation val2 = activeSource; activeSource = val; proxyLastUsed = Time.time; pendingNativeInteraction = true; try { val.Interact((Humanoid)(object)Player.m_localPlayer, false, false); if ((Object)(object)Player.m_localPlayer.GetCurrentCraftingStation() != (Object)(object)val) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Native interaction did not select " + choice.DisplayName + ".")); activeSource = val2; return; } UpdateHeaderLabel(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Rebench selected " + choice.DisplayName + " level " + val.GetLevel(true) + ".")); } catch (Exception ex) { activeSource = val2; ((BaseUnityPlugin)this).Logger.LogError((object)("Rebench station switch failed: " + ex)); } finally { pendingNativeInteraction = false; } } private static void InventoryUpdatePostfix(InventoryGui __instance) { //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)instance == (Object)null) { return; } if (!((Object)(object)activeBench != (Object)null) || !((Object)(object)activeSource != (Object)null) || !((Object)(object)Player.m_localPlayer != (Object)null) || !InventoryGui.IsVisible() || !((Object)(object)Player.m_localPlayer.GetCurrentCraftingStation() == (Object)(object)activeSource) || !CraftPanelVisible(__instance)) { gamepadSelectorFocus = false; if (optionsOpen) { CloseOptions(); } if ((Object)(object)stationButton != (Object)null && stationButton.activeSelf) { stationButton.SetActive(false); } SetNativeNameHidden(hidden: false); return; } if (((Object)(object)trackedGui != (Object)(object)__instance || (Object)(object)stationButton == (Object)null) && Time.unscaledTime >= nextHeaderAttempt) { instance.CreateHeader(__instance); } if ((Object)(object)stationButton == (Object)null) { return; } if (!stationButton.activeSelf) { stationButton.SetActive(true); } SetNativeNameHidden(hidden: true); RefreshHeaderSize(__instance); if ((Object)(object)stationButton != (Object)null) { Image component = stationButton.GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = (gamepadSelectorFocus ? new Color(0.52f, 0.34f, 0.12f, 1f) : new Color(0.24f, 0.16f, 0.08f, 0.97f)); } } UpdateHeaderLabel(); } private static bool CraftPanelVisible(InventoryGui ui) { if ((Object)(object)ui == (Object)null || (Object)(object)ui.m_craftingStationName == (Object)null || !((Component)ui.m_craftingStationName).gameObject.activeInHierarchy) { return false; } try { if ((Object)(object)trackedGui == (Object)(object)ui && (Object)(object)nativeRecipeListRoot != (Object)null) { if (!((Component)nativeRecipeListRoot).gameObject.activeInHierarchy) { return false; } if ((Object)(object)craftingTabParent != (Object)null) { return ((Component)craftingTabParent).gameObject.activeInHierarchy; } return true; } RectTransform value = Traverse.Create((object)ui).Field("m_recipeListRoot").GetValue<RectTransform>(); if ((Object)(object)value == (Object)null || !((Component)value).gameObject.activeInHierarchy) { return false; } object value2 = Traverse.Create((object)ui).Field("m_tabCraft").GetValue(); Component val = (Component)((value2 is Component) ? value2 : null); if ((Object)(object)val != (Object)null && (Object)(object)val.transform.parent != (Object)null) { return ((Component)val.transform.parent).gameObject.activeInHierarchy; } object value3 = Traverse.Create((object)ui).Field("m_crafting").GetValue(); Component val2 = (Component)((value3 is Component) ? value3 : null); if ((Object)(object)val2 != (Object)null) { return val2.gameObject.activeInHierarchy; } GameObject val3 = (GameObject)((value3 is GameObject) ? value3 : null); return (Object)(object)val3 == (Object)null || val3.activeInHierarchy; } catch { return false; } } private void Update() { if (!((Object)(object)activeBench == (Object)null)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !PlayerNearBench(localPlayer, activeBench) || ((Object)(object)activeSource != (Object)null && !SourceWithinRange(activeBench, activeSource)) || (Time.time - proxyLastUsed > 1f && !InventoryGui.IsVisible())) { ResetSession(); } else if (optionsOpen && !CraftPanelVisible(trackedGui)) { CloseOptions(); } } } private static void UpdateHeaderLabel() { if (!((Object)(object)buttonLabel == (Object)null) && !((Object)(object)activeSource == (Object)null)) { StationChoice stationChoice = stationChoices.Find((StationChoice c) => (Object)(object)c.Station == (Object)(object)activeSource); string obj = ((stationChoice != null) ? stationChoice.DisplayName : HumanizeStationPrefab(((Object)((Component)activeSource).gameObject).name.Replace("(Clone)", "").Trim())); int num = CurrentLevel(activeSource, stationChoice?.Level ?? 1); string text = obj.Trim().ToUpperInvariant() + " - LVL " + num; if (((TMP_Text)buttonLabel).text != text) { ((TMP_Text)buttonLabel).text = text; } } } private static int CurrentLevel(CraftingStation station, int fallback) { if ((Object)(object)station == (Object)null) { return fallback; } try { return station.GetLevel(true); } catch (Exception) { return fallback; } } private static void SetNativeNameHidden(bool hidden) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)hiddenNativeStationName == (Object)null)) { if (!hidden) { ((Graphic)hiddenNativeStationName).color = nativeStationNameOriginalColor; } else { ((Graphic)hiddenNativeStationName).color = new Color(nativeStationNameOriginalColor.r, nativeStationNameOriginalColor.g, nativeStationNameOriginalColor.b, 0f); } } } private static void RefreshHeaderSize(InventoryGui ui) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)stationButton == (Object)null || (Object)(object)ui == (Object)null || (Object)(object)ui.m_craftingStationName == (Object)null) { return; } RectTransform rectTransform = ui.m_craftingStationName.rectTransform; Transform transform = stationButton.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)rectTransform == (Object)null || (Object)(object)val == (Object)null) { return; } Transform parent = ((Transform)rectTransform).parent; RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null); Rect rect; float width; if ((Object)(object)val2 != (Object)null) { rect = val2.rect; if (((Rect)(ref rect)).width > 10f) { rect = val2.rect; width = ((Rect)(ref rect)).width; goto IL_009f; } } rect = rectTransform.rect; width = ((Rect)(ref rect)).width; goto IL_009f; IL_009f: float num = width; float num2 = Mathf.Max(180f, num - 132f); rect = rectTransform.rect; float num3 = Mathf.Clamp(Mathf.Max(((Rect)(ref rect)).width, num * 0.5f), 180f, num2); rect = rectTransform.rect; float num4 = Mathf.Clamp(Mathf.Max(30f, ((Rect)(ref rect)).height + 4f), 30f, 42f); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(num3, num4); Vector2 val4 = val.sizeDelta - val3; if (((Vector2)(ref val4)).sqrMagnitude > 0.25f) { val.sizeDelta = val3; } } private static TextMeshProUGUI AddLabel(Transform parent, TMP_Text source, string text, float size) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) GameObject val = new GameObject("Label", new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = new Vector2(8f, 0f); val2.offsetMax = new Vector2(-4f, 0f); TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).font = source.font; ((TMP_Text)obj).fontSize = size; ((TMP_Text)obj).enableAutoSizing = true; ((TMP_Text)obj).fontSizeMin = 10f; ((TMP_Text)obj).fontSizeMax = size; ((Graphic)obj).color = new Color(0.94f, 0.77f, 0.41f); ((TMP_Text)obj).alignment = (TextAlignmentOptions)4097; ((Graphic)obj).raycastTarget = false; ((TMP_Text)obj).overflowMode = (TextOverflowModes)1; ((TMP_Text)obj).text = text; val.SetActive(true); return obj; } private static GameObject MakeButton(string name, Transform parent, Action onClick, Color color) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0076: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); val.transform.SetParent(parent, false); ((Graphic)val.GetComponent<Image>()).color = color; ((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { onClick(); }); return val; } private void CreateHeader(InventoryGui ui) { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Expected O, but got Unknown //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) ResetUI(); if ((Object)(object)ui == (Object)null || (Object)(object)ui.m_craftingStationName == (Object)null || (Object)(object)ui.m_craftingStationName.font == (Object)null) { return; } object value = Traverse.Create((object)ui).Field("m_tabCraft").GetValue(); Component val = (Component)((value is Component) ? value : null); craftingTabParent = (((Object)(object)val != (Object)null) ? val.transform.parent : null); nativeRecipeListRoot = Traverse.Create((object)ui).Field("m_recipeListRoot").GetValue<RectTransform>(); if (!((Object)(object)nativeRecipeListRoot == (Object)null)) { TMP_Text craftingStationName = ui.m_craftingStationName; RectTransform rectTransform = craftingStationName.rectTransform; Canvas componentInParent = ((Component)craftingStationName).GetComponentInParent<Canvas>(); if (!((Object)(object)rectTransform == (Object)null) && !((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.rootCanvas == (Object)null)) { dropdownFontSource = craftingStationName; stationButton = MakeButton("RamRebenchStationNameDropdown", (Transform)(object)rectTransform, ToggleOptions, new Color(0.24f, 0.16f, 0.08f, 0.97f)); RectTransform val2 = (RectTransform)stationButton.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = Vector2.zero; val2.sizeDelta = new Vector2(240f, 30f); Outline obj = stationButton.AddComponent<Outline>(); ((Shadow)obj).effectColor = new Color(0.72f, 0.47f, 0.16f, 0.94f); ((Shadow)obj).effectDistance = new Vector2(1f, -1f); ((Shadow)obj).useGraphicAlpha = false; buttonLabel = AddLabel(stationButton.transform, craftingStationName, "WORKBENCH - LVL 1", 18f); ((TMP_Text)buttonLabel).fontStyle = (FontStyles)0; ((TMP_Text)buttonLabel).fontSizeMin = 14f; ((TMP_Text)buttonLabel).rectTransform.offsetMax = new Vector2(-31f, 0f); dropdownArrow = AddLabel(stationButton.transform, craftingStationName, "▼", 17f); ((TMP_Text)dropdownArrow).fontStyle = (FontStyles)0; ((TMP_Text)dropdownArrow).alignment = (TextAlignmentOptions)4100; ((TMP_Text)dropdownArrow).rectTransform.anchorMin = new Vector2(1f, 0f); ((TMP_Text)dropdownArrow).rectTransform.anchorMax = new Vector2(1f, 1f); ((TMP_Text)dropdownArrow).rectTransform.offsetMin = new Vector2(-32f, 0f); ((TMP_Text)dropdownArrow).rectTransform.offsetMax = new Vector2(-10f, 0f); Button component = stationButton.GetComponent<Button>(); Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component).navigation = navigation; stationButton.transform.SetAsLastSibling(); headerOverlay = new GameObject("RamUniversalRebenchPopupCanvas", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(GraphicRaycaster) }); headerOverlay.transform.SetParent(((Component)componentInParent.rootCanvas).transform, false); RectTransform val4 = (RectTransform)headerOverlay.transform; val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val3 = (val4.offsetMin = (val4.offsetMax = Vector2.zero)); Canvas component2 = headerOverlay.GetComponent<Canvas>(); component2.overrideSorting = true; component2.sortingOrder = 14980; headerOverlay.SetActive(false); trackedGui = ui; nextHeaderAttempt = 0f; hiddenNativeStationName = craftingStationName; nativeStationNameOriginalColor = ((Graphic)craftingStationName).color; RefreshHeaderSize(ui); UpdateHeaderLabel(); SetNativeNameHidden(hidden: true); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Rebench dropdown attached to native crafting-station NAME label (no inventory-mod-specific offsets)."); } } } private void ToggleOptions() { if (optionsOpen) { CloseOptions(); } else { OpenOptions(); } } private void OpenOptions() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Expected O, but got Unknown //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (migh