using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Photon.Pun; using UnityEngine; using Zorro.Core; using Zorro.Core.Serizalization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyTitle("Splice Spools")] [assembly: AssemblyDescription("PEAK BepInEx plugin that splices matching inventory rope spools into one longer spool.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Splice Spools")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4006febd-7a9f-457c-865d-a3d4e2a97d25")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace Splice_Spools { [BepInPlugin("tony4twentys.Splice_Spools", "Splice_Spools", "1.0.0")] [BepInProcess("PEAK.exe")] public class SpliceSpoolsPlugin : BaseUnityPlugin { public const string PluginGuid = "tony4twentys.Splice_Spools"; public const string PluginName = "Splice_Spools"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry SpliceKeyConfig; internal static ConfigEntry IncludeBackpackConfig; private Harmony _harmony; private string _toastText; private float _toastUntil; internal static bool PendingWeightRefresh; internal static SpliceSpoolsPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; SpliceKeyConfig = ((BaseUnityPlugin)this).Config.Bind("Splice", "Splice Key", (KeyCode)103, "Press this key to splice matching rope spools in your inventory into one longer spool per rope type."); IncludeBackpackConfig = ((BaseUnityPlugin)this).Config.Bind("Splice", "Include Backpack", true, "When true, leftover rope in a worn backpack is included when splicing."); _harmony = new Harmony("tony4twentys.Splice_Spools"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Splice Spools loaded. Splice key: {SpliceKeyConfig.Value}. " + "Backpack: " + (IncludeBackpackConfig.Value ? "included" : "ignored") + ".")); } private void Update() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (PendingWeightRefresh) { PendingWeightRefresh = false; TryRefreshLocalWeight(); } if ((int)SpliceKeyConfig.Value != 0 && Input.GetKeyDown(SpliceKeyConfig.Value) && !IsGameplayInputBlocked()) { Character localCharacter = Character.localCharacter; if (!((Object)(object)((localCharacter != null) ? localCharacter.player : null) == (Object)null) && localCharacter.IsLocal) { SpliceExecutor.TrySplice(localCharacter, out var message); ShowToast(message); ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } } } private void OnGUI() { //IL_0064: 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_007b: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(_toastText) && !(Time.unscaledTime > _toastUntil)) { Rect val = default(Rect); ((Rect)(ref val))..ctor(((float)Screen.width - 520f) * 0.5f, 72f, 520f, 36f); GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.Box(val, GUIContent.none); GUI.color = Color.white; GUIStyle val2 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 16, fontStyle = (FontStyle)1 }; GUI.Label(val, _toastText, val2); } } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } Log = null; } internal static void TryRefreshLocalWeight() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter?.refs?.items == (Object)null) { return; } try { localCharacter.refs.items.RefreshAllCharacterCarryWeightRPC(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Weight refresh skipped: " + ex.Message)); } } } internal void ShowToast(string text) { _toastText = text; _toastUntil = Time.unscaledTime + 2.5f; } private static bool IsGameplayInputBlocked() { if (GUIManager.InPauseMenu) { return true; } GUIManager instance = GUIManager.instance; return (Object)(object)instance != (Object)null && instance.windowBlockingInput; } } internal static class GameItemIds { public const ushort AntiRopeSpoolItemId = 1; public const ushort RopeSpoolItemId = 65; } internal static class RopeSpoolLengthHelper { public const float MetersPerSegment = 0.25f; public const float OutOfRopeSegmentThreshold = 2f; public const float DefaultSpoolStartFuel = 60f; public const float SegmentEpsilon = 0.01f; public static float SegmentsToMeters(float segments) { return segments * 0.25f; } public static float GetSpoolStartFuel(Item prefab) { if ((Object)(object)prefab == (Object)null) { return 60f; } RopeSpool component = ((Component)prefab).GetComponent(); return ((Object)(object)component != (Object)null) ? component.ropeStartFuel : 60f; } public static float GetSpoolStartFuel(ItemSlot slot) { return GetSpoolStartFuel((slot != null) ? slot.prefab : null); } public static float GetRemainingSegments(Item prefab, ItemInstanceData data) { float spoolStartFuel = GetSpoolStartFuel(prefab); if (data == null) { return spoolStartFuel; } FloatItemData val = default(FloatItemData); if (data.TryGetDataEntry((DataEntryKey)10, ref val)) { return Mathf.Max(0f, val.Value); } FloatItemData val2 = default(FloatItemData); if (data.TryGetDataEntry((DataEntryKey)11, ref val2)) { return Mathf.Max(0f, val2.Value * spoolStartFuel); } return spoolStartFuel; } public static float GetRemainingSegments(ItemSlot slot) { if (slot == null || slot.IsEmpty()) { return 0f; } return GetRemainingSegments(slot.prefab, slot.data); } public static float GetRemainingMeters(Item prefab, ItemInstanceData data) { return SegmentsToMeters(GetRemainingSegments(prefab, data)); } public static int GetScaledCarryWeight(Item prefab, ItemInstanceData data) { if ((Object)(object)prefab == (Object)null) { return 0; } int carryWeight = prefab.CarryWeight; if (!SpliceInventory.IsRopeSpoolPrefab(prefab)) { return carryWeight; } float spoolStartFuel = GetSpoolStartFuel(prefab); if (spoolStartFuel <= 0.01f) { return carryWeight; } float remainingSegments = GetRemainingSegments(prefab, data); return Mathf.RoundToInt((float)carryWeight * (remainingSegments / spoolStartFuel)); } public static bool HasSplicableLength(float segments) { return segments > 2.01f; } } internal static class ItemDataHelper { public static void SetFloatEntry(ItemInstanceData data, DataEntryKey key, float value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) FloatItemData val = default(FloatItemData); if (data.TryGetDataEntry(key, ref val)) { val.Value = value; return; } FloatItemData val2 = new FloatItemData(); ((DataEntryValue)val2).Init(); val2.Value = value; data.RegisterEntry(key, val2); } } internal static class SpliceInventory { private const byte TempInventorySlotId = 250; public static bool IsRopeSpoolPrefab(Item prefab) { if ((Object)(object)prefab == (Object)null || (Object)(object)((Component)prefab).GetComponent() != (Object)null) { return false; } if ((Object)(object)((Component)prefab).GetComponent() != (Object)null) { return true; } if (prefab.itemID == 65 || prefab.itemID == 1) { return true; } string text = ((Object)((Component)prefab).gameObject).name ?? string.Empty; return text.IndexOf("Rope Spool", StringComparison.OrdinalIgnoreCase) >= 0; } public static bool IsAntiRopeSpoolPrefab(Item prefab) { if ((Object)(object)prefab == (Object)null) { return false; } RopeSpool component = ((Component)prefab).GetComponent(); if ((Object)(object)component != (Object)null && component.isAntiRope) { return true; } if (prefab.itemID == 1) { return true; } string text = ((Object)((Component)prefab).gameObject).name ?? string.Empty; return text.IndexOf("Anti-Rope Spool", StringComparison.OrdinalIgnoreCase) >= 0; } public static List GetRopeSpoolSlots(Character character) { List list = new List(); if ((Object)(object)((character != null) ? character.player : null) == (Object)null) { return list; } AppendRopeSlots(character.player.itemSlots, list); if (character.player.tempFullSlot != null && !character.player.tempFullSlot.IsEmpty() && IsRopeSpoolPrefab(character.player.tempFullSlot.prefab)) { list.Add(character.player.tempFullSlot); } if (SpliceSpoolsPlugin.IncludeBackpackConfig.Value) { AppendBackpackRopeSlots(character, list); } return list; } private static void AppendRopeSlots(ItemSlot[] slots, List ropeSlots) { if (slots == null) { return; } foreach (ItemSlot val in slots) { if (val != null && !val.IsEmpty() && IsRopeSpoolPrefab(val.prefab)) { ropeSlots.Add(val); } } } private static void AppendBackpackRopeSlots(Character character, List ropeSlots) { if (character.player.backpackSlot != null && !((ItemSlot)character.player.backpackSlot).IsEmpty()) { ItemInstanceData data = ((ItemSlot)character.player.backpackSlot).data; BackpackData val = default(BackpackData); if (data != null && data.TryGetDataEntry((DataEntryKey)7, ref val)) { AppendRopeSlots(val.itemSlots, ropeSlots); } } } public static bool IsBackpackSlot(Character character, ItemSlot slot) { if ((Object)(object)((character != null) ? character.player : null) == (Object)null || slot == null || character.player.backpackSlot == null || ((ItemSlot)character.player.backpackSlot).IsEmpty()) { return false; } ItemInstanceData data = ((ItemSlot)character.player.backpackSlot).data; BackpackData val = default(BackpackData); if (data == null || !data.TryGetDataEntry((DataEntryKey)7, ref val) || val.itemSlots == null) { return false; } ItemSlot[] itemSlots = val.itemSlots; foreach (ItemSlot val2 in itemSlots) { if (val2 == slot) { return true; } } return false; } public static bool TryGetHeldSpool(Character character, out Item item, out RopeSpool spool) { object obj; if (character == null) { obj = null; } else { CharacterData data = character.data; obj = ((data != null) ? data.currentItem : null); } item = (Item)obj; spool = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent() : null); return (Object)(object)spool != (Object)null; } public static bool IsHeldSpoolBusy(Character character, bool isAntiRope) { if (!TryGetHeldSpool(character, out var item, out var spool)) { return false; } if (spool.isAntiRope != isAntiRope) { return false; } return (Object)(object)spool.ropeInstance != (Object)null || (Object)(object)spool.rope != (Object)null || item.isUsingPrimary; } public static ItemSlot FindSlotForItem(Character character, Item item) { if ((Object)(object)((character != null) ? character.player : null) == (Object)null || (Object)(object)item == (Object)null) { return null; } if (item.data != null && item.data.guid != Guid.Empty) { ItemSlot val = FindSlotByGuid(character, item.data.guid); if (val != null) { return val; } } foreach (ItemSlot ropeSpoolSlot in GetRopeSpoolSlots(character)) { if (SlotMatchesHeldItem(character, ropeSpoolSlot)) { return ropeSpoolSlot; } } return null; } private static ItemSlot FindSlotByGuid(Character character, Guid guid) { ItemSlot val = FindSlotByGuid(character.player.itemSlots, guid); if (val != null) { return val; } if (SlotHasGuid(character.player.tempFullSlot, guid)) { return character.player.tempFullSlot; } BackpackData val2 = default(BackpackData); if (character.player.backpackSlot != null && !((ItemSlot)character.player.backpackSlot).IsEmpty() && ((ItemSlot)character.player.backpackSlot).data != null && ((ItemSlot)character.player.backpackSlot).data.TryGetDataEntry((DataEntryKey)7, ref val2)) { return FindSlotByGuid(val2.itemSlots, guid); } return null; } private static ItemSlot FindSlotByGuid(ItemSlot[] slots, Guid guid) { if (slots == null) { return null; } foreach (ItemSlot val in slots) { if (SlotHasGuid(val, guid)) { return val; } } return null; } private static bool SlotHasGuid(ItemSlot slot, Guid guid) { return slot != null && !slot.IsEmpty() && slot.data != null && slot.data.guid == guid; } public static bool SlotMatchesHeldItem(Character character, ItemSlot slot) { //IL_00c4: 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_00d7: Unknown result type (might be due to invalid IL or missing references) object obj; if (character == null) { obj = null; } else { CharacterData data = character.data; obj = ((data != null) ? data.currentItem : null); } Item val = (Item)obj; if ((Object)(object)val == (Object)null || slot == null || slot.IsEmpty() || (Object)(object)slot.prefab == (Object)null) { return false; } if (val.data != null && slot.data != null && val.data.guid != Guid.Empty && val.data.guid == slot.data.guid) { return true; } Optionable valueOrDefault = (character.refs?.items?.currentSelectedSlot).GetValueOrDefault(); return valueOrDefault.IsSome && valueOrDefault.Value == slot.itemSlotID && slot.prefab.itemID == val.itemID; } public static void ApplyFuelToSlot(ItemSlot slot, float remaining, float startFuel) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (slot.data == null) { slot.data = new ItemInstanceData(Guid.NewGuid()); } ItemDataHelper.SetFloatEntry(slot.data, (DataEntryKey)10, remaining); float value = ((startFuel > 0f) ? Mathf.Clamp01(remaining / startFuel) : 0f); ItemDataHelper.SetFloatEntry(slot.data, (DataEntryKey)11, value); } public static void ApplyFuelToHeldItem(Item item, float remaining, float startFuel) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if (!((Object)(object)item == (Object)null)) { if (item.data == null) { item.data = new ItemInstanceData(Guid.NewGuid()); } ItemDataHelper.SetFloatEntry(item.data, (DataEntryKey)10, remaining); RopeSpool component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null) { ((ItemComponent)component).OnInstanceDataSet(); } float useRemainingPercentage = ((startFuel > 0f) ? Mathf.Clamp01(remaining / startFuel) : 0f); item.SetUseRemainingPercentage(useRemainingPercentage); } } public static void EmptySlotLocal(Character character, ItemSlot slot) { if (slot == null) { return; } if (IsBackpackSlot(character, slot) || slot.itemSlotID == 250) { slot.EmptyOut(); return; } ItemSlot itemSlot = character.player.GetItemSlot(slot.itemSlotID); if (itemSlot != null) { itemSlot.EmptyOut(); } } public static void SyncInventory(Character character) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((character != null) ? character.player : null) == (Object)null || !PhotonNetwork.InRoom) { return; } PhotonView component = ((Component)character.player).GetComponent(); if ((Object)(object)component == (Object)null) { return; } try { InventorySyncData val = default(InventorySyncData); ((InventorySyncData)(ref val))..ctor(character.player.itemSlots, character.player.backpackSlot, character.player.tempFullSlot); byte[] array = IBinarySerializable.ToManagedArray(val); component.RPC("SyncInventoryRPC", (RpcTarget)1, new object[2] { array, !PhotonNetwork.IsMasterClient }); if (!PhotonNetwork.IsMasterClient) { component.RPC("SyncInventoryRPC", (RpcTarget)2, new object[2] { array, true }); } } catch (Exception ex) { SpliceSpoolsPlugin.Log.LogWarning((object)("Inventory sync skipped: " + ex.Message)); } } public static void PushHeldItemData(Item item) { if (item?.data == null || !PhotonNetwork.InRoom) { return; } PhotonView component = ((Component)item).GetComponent(); if ((Object)(object)component == (Object)null || (!component.IsMine && !PhotonNetwork.IsMasterClient)) { return; } try { component.RPC("SetItemInstanceDataRPC", (RpcTarget)1, new object[1] { item.data }); } catch (Exception ex) { SpliceSpoolsPlugin.Log.LogWarning((object)("Held spool sync skipped: " + ex.Message)); } } } internal static class SpliceExecutor { public static bool TrySplice(Character character, out string message) { List ropeSpoolSlots = SpliceInventory.GetRopeSpoolSlots(character); List list = new List(); List list2 = new List(); CollectSplicable(ropeSpoolSlots, list, list2); bool flag = false; bool flag2 = false; float combinedMeters = 0f; float combinedMeters2 = 0f; int spoolCount = 0; int spoolCount2 = 0; if (list.Count >= 2) { if (SpliceInventory.IsHeldSpoolBusy(character, isAntiRope: false)) { message = "Finish placing your rope before splicing."; return false; } flag = TrySpliceGroup(character, list, isAntiRope: false, out combinedMeters, out spoolCount); } if (list2.Count >= 2) { if (SpliceInventory.IsHeldSpoolBusy(character, isAntiRope: true)) { if (flag) { SyncAfterSplice(character, null); message = BuildResultMessage(splicedNormal: true, spoolCount, combinedMeters, splicedAnti: false, 0, 0f) + " Anti-grav spool is in use."; return true; } message = "Finish placing your anti-grav rope before splicing."; return false; } flag2 = TrySpliceGroup(character, list2, isAntiRope: true, out combinedMeters2, out spoolCount2); } if (!flag && !flag2) { message = ((list.Count + list2.Count == 0) ? "No leftover rope spools to splice." : "Need at least two matching rope spools to splice."); return false; } SpliceInventory.TryGetHeldSpool(character, out var item, out var _); SyncAfterSplice(character, item); message = BuildResultMessage(flag, spoolCount, combinedMeters, flag2, spoolCount2, combinedMeters2); return true; } private static void CollectSplicable(List allSpools, List normal, List anti) { foreach (ItemSlot allSpool in allSpools) { float remainingSegments = RopeSpoolLengthHelper.GetRemainingSegments(allSpool); if (RopeSpoolLengthHelper.HasSplicableLength(remainingSegments)) { if (SpliceInventory.IsAntiRopeSpoolPrefab(allSpool.prefab)) { anti.Add(allSpool); } else { normal.Add(allSpool); } } } } private static bool TrySpliceGroup(Character character, List slots, bool isAntiRope, out float combinedMeters, out int spoolCount) { combinedMeters = 0f; spoolCount = slots.Count; if (slots.Count < 2) { return false; } ItemSlot val = ChooseTargetSlot(character, slots, isAntiRope); if (val == null) { return false; } float num = 0f; foreach (ItemSlot slot in slots) { num += RopeSpoolLengthHelper.GetRemainingSegments(slot); } if (!RopeSpoolLengthHelper.HasSplicableLength(num)) { return false; } float spoolStartFuel = RopeSpoolLengthHelper.GetSpoolStartFuel(val); SpliceInventory.ApplyFuelToSlot(val, num, spoolStartFuel); if (SpliceInventory.SlotMatchesHeldItem(character, val)) { SpliceInventory.ApplyFuelToHeldItem(character.data.currentItem, num, spoolStartFuel); } foreach (ItemSlot slot2 in slots) { if (slot2 != val) { SpliceInventory.EmptySlotLocal(character, slot2); } } combinedMeters = RopeSpoolLengthHelper.SegmentsToMeters(num); return true; } private static ItemSlot ChooseTargetSlot(Character character, List slots, bool isAntiRope) { foreach (ItemSlot slot in slots) { if (SpliceInventory.SlotMatchesHeldItem(character, slot) && SpliceInventory.IsAntiRopeSpoolPrefab(slot.prefab) == isAntiRope) { return slot; } } return slots[0]; } private static void SyncAfterSplice(Character character, Item held) { SpliceInventory.SyncInventory(character); if ((Object)(object)held != (Object)null) { SpliceInventory.PushHeldItemData(held); } if ((Object)(object)character.refs?.items != (Object)null) { character.refs.items.RefreshAllCharacterCarryWeightRPC(); } if (character.player?.itemsChangedAction != null) { character.player.itemsChangedAction(character.player.itemSlots); } } private static string BuildResultMessage(bool splicedNormal, int normalCount, float normalMeters, bool splicedAnti, int antiCount, float antiMeters) { if (splicedNormal && splicedAnti) { return $"Spliced {normalCount} rope spools into {normalMeters:0.##}m and {antiCount} anti-grav spools into {antiMeters:0.##}m."; } if (splicedAnti) { return $"Spliced {antiCount} anti-grav spools into {antiMeters:0.##}m."; } return $"Spliced {normalCount} rope spools into {normalMeters:0.##}m."; } } [HarmonyPatch(typeof(Item), "GetItemName")] internal static class Item_GetItemName_Splice_Patch { private static void Postfix(Item __instance, ItemInstanceData data, ref string __result) { try { if (SpliceInventory.IsRopeSpoolPrefab(__instance) && !string.IsNullOrEmpty(__result)) { ItemInstanceData data2 = data ?? __instance.data; float remainingMeters = RopeSpoolLengthHelper.GetRemainingMeters(__instance, data2); __result = $"{__result} ({remainingMeters:0.#}m)"; } } catch (Exception ex) { ManualLogSource log = SpliceSpoolsPlugin.Log; if (log != null) { log.LogWarning((object)("Name patch skipped: " + ex.Message)); } } } } [HarmonyPatch(typeof(CharacterAfflictions), "UpdateWeight")] internal static class CharacterAfflictions_UpdateWeight_Splice_Patch { private static void Postfix(CharacterAfflictions __instance) { try { Character character = __instance.character; if (!((Object)(object)((character != null) ? character.player : null) == (Object)null)) { int vanilla = 0; int scaled = 0; AddSpoolWeights(character.player.itemSlots, ref vanilla, ref scaled); AddSpoolWeights(GetBackpackInnerSlots(character), ref vanilla, ref scaled); AddSpoolWeights((ItemSlot[])(object)new ItemSlot[1] { character.player.GetItemSlot((byte)250) }, ref vanilla, ref scaled); if (vanilla != scaled) { float currentStatus = __instance.GetCurrentStatus((STATUSTYPE)7); int num = Mathf.RoundToInt(currentStatus / 0.025f); __instance.SetStatus((STATUSTYPE)7, 0.025f * (float)(num - vanilla + scaled), true); } } } catch (Exception ex) { ManualLogSource log = SpliceSpoolsPlugin.Log; if (log != null) { log.LogWarning((object)("Weight patch skipped: " + ex.Message)); } } } private static void AddSpoolWeights(ItemSlot[] slots, ref int vanilla, ref int scaled) { if (slots == null) { return; } foreach (ItemSlot val in slots) { if (val != null && !val.IsEmpty() && SpliceInventory.IsRopeSpoolPrefab(val.prefab)) { vanilla += val.prefab.CarryWeight; scaled += RopeSpoolLengthHelper.GetScaledCarryWeight(val.prefab, val.data); } } } private static ItemSlot[] GetBackpackInnerSlots(Character character) { if (character.player.backpackSlot == null || ((ItemSlot)character.player.backpackSlot).IsEmpty()) { return null; } ItemInstanceData data = ((ItemSlot)character.player.backpackSlot).data; BackpackData val = default(BackpackData); if (data == null || !data.TryGetDataEntry((DataEntryKey)7, ref val)) { return null; } return val.itemSlots; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class RopeSpool_RopeFuel_Splice_Patch { private static void Postfix(RopeSpool __instance, float value) { try { Item item = ((ItemComponent)__instance).item; Character val = (((Object)(object)item != (Object)null) ? item.holderCharacter : null); if (!((Object)(object)val == (Object)null) && val.IsLocal) { ItemSlot val2 = SpliceInventory.FindSlotForItem(val, item); if (val2 != null && val2.data != item.data) { SpliceInventory.ApplyFuelToSlot(val2, value, RopeSpoolLengthHelper.GetSpoolStartFuel(val2)); } SpliceSpoolsPlugin.PendingWeightRefresh = true; } } catch (Exception ex) { ManualLogSource log = SpliceSpoolsPlugin.Log; if (log != null) { log.LogWarning((object)("Fuel sync skipped: " + ex.Message)); } } } } }