using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ReefPacks")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyInformationalVersion("0.1.1+4c1ec4abdf610b966bad294a804f8470817b98e8")] [assembly: AssemblyProduct("ReefPacks")] [assembly: AssemblyTitle("ReefPacks")] [assembly: AssemblyVersion("0.1.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ReefPacks { internal sealed class PackData { internal const string Key = "vapok.mods.adventurebackpacks#AdventureBackpacks.Components.BackpackComponent"; private static readonly ConditionalWeakTable cache = new ConditionalWeakTable(); private static readonly FieldRef invWidth = AccessTools.FieldRefAccess("m_width"); private static readonly FieldRef invHeight = AccessTools.FieldRefAccess("m_height"); internal readonly ItemData Item; internal readonly PackDef Def; internal Inventory Inv; private bool loading; private bool busy; private bool builtWithoutData; private string lastEmptyBlob; internal static bool IsPack(ItemData item) { return PackDef.Of(item) != null; } internal static PackData Get(ItemData item) { PackDef packDef = PackDef.Of(item); if (packDef == null) { return null; } if (!cache.TryGetValue(item, out var value)) { value = new PackData(item, packDef); cache.Add(item, value); } else { value.ReloadIfDataArrived(); } value.EnsureSize(); return value; } private PackData(ItemData item, PackDef def) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown Item = item; Def = def; Vector2Int val = def.GridFor(item.m_quality); Inv = new Inventory("$" + def.Token + " $vapok_mod_level " + item.m_quality, def.Icon, ((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y); Load(); Inv.m_onChanged = (Action)Delegate.Combine(Inv.m_onChanged, new Action(OnChanged)); } private void Load() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if (Item.m_customData != null && Item.m_customData.TryGetValue("vapok.mods.adventurebackpacks#AdventureBackpacks.Components.BackpackComponent", out var value) && !string.IsNullOrEmpty(value)) { loading = true; try { Inv.Load(new ZPackage(value)); } catch (Exception ex) { ReefPacksPlugin.Log.LogError((object)("pack contents corrupt (" + Def.Prefab + "): " + ex.GetType().Name + ": " + ex.Message)); } finally { loading = false; } builtWithoutData = false; } else { Save(); builtWithoutData = true; } } private void ReloadIfDataArrived() { if (builtWithoutData && Inv.NrOfItems() == 0 && Item.m_customData != null && Item.m_customData.TryGetValue("vapok.mods.adventurebackpacks#AdventureBackpacks.Components.BackpackComponent", out var value) && !string.IsNullOrEmpty(value) && !IsEmptyBlob(value)) { Load(); } } private bool IsEmptyBlob(string s) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (lastEmptyBlob == null) { ZPackage val = new ZPackage(); new Inventory("x", (Sprite)null, 1, 1).Save(val); lastEmptyBlob = val.GetBase64(); } return s == lastEmptyBlob; } internal void Save() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown if (!loading) { ZPackage val = new ZPackage(); Inv.Save(val); if (Item.m_customData == null) { Item.m_customData = new Dictionary(); } Item.m_customData["vapok.mods.adventurebackpacks#AdventureBackpacks.Components.BackpackComponent"] = val.GetBase64(); builtWithoutData = false; } } private void OnChanged() { if (loading || busy) { return; } busy = true; try { Save(); EjectPacks(); } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("pack changed: " + ex.GetType().Name + ": " + ex.Message)); } finally { busy = false; } } private void EjectPacks() { List list = null; foreach (ItemData allItem in Inv.GetAllItems()) { if (IsPack(allItem)) { (list ?? (list = new List())).Add(allItem); } } if (list == null) { return; } foreach (ItemData item in list) { Inv.RemoveItem(item); GiveBackOrDrop(item); } Save(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, "$reefpacks_pack_in_pack", 0, (Sprite)null, false); } } private static void GiveBackOrDrop(ItemData it) { //IL_003c: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer != (Object)null) || ((Humanoid)localPlayer).GetInventory() == null || !((Humanoid)localPlayer).GetInventory().AddItem(it)) { if ((Object)(object)localPlayer != (Object)null) { ItemDrop.DropItem(it, it.m_stack, ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward + ((Component)localPlayer).transform.up, ((Component)localPlayer).transform.rotation); } else { ReefPacksPlugin.Log.LogWarning((object)("ejected pack item lost (no local player): " + (((Object)(object)it.m_dropPrefab != (Object)null) ? ((Object)it.m_dropPrefab).name : "?"))); } } } internal void EnsureSize() { //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) Vector2Int val = Def.GridFor(Item.m_quality); int width = Inv.GetWidth(); int height = Inv.GetHeight(); if (width == ((Vector2Int)(ref val)).x && height == ((Vector2Int)(ref val)).y) { return; } List list = null; if (((Vector2Int)(ref val)).x < width || ((Vector2Int)(ref val)).y < height) { foreach (ItemData allItem in Inv.GetAllItems()) { if (allItem.m_gridPos.x >= ((Vector2Int)(ref val)).x || allItem.m_gridPos.y >= ((Vector2Int)(ref val)).y) { (list ?? (list = new List())).Add(allItem); } } } busy = true; try { if (list != null) { foreach (ItemData item in list) { Inv.RemoveItem(item); GiveBackOrDrop(item); } } invWidth.Invoke(Inv) = ((Vector2Int)(ref val)).x; invHeight.Invoke(Inv) = ((Vector2Int)(ref val)).y; } finally { busy = false; } Save(); } internal float ContentsWeight() { return Inv.GetTotalWeight(); } internal float ContentsWeight(float threshold, float multiplier) { if (threshold <= 0f) { return Inv.GetTotalWeight() * multiplier; } float num = 0f; foreach (ItemData allItem in Inv.GetAllItems()) { if (allItem != null) { float nonStackedWeight = allItem.GetNonStackedWeight(); float num2 = nonStackedWeight * (float)allItem.m_stack; num += ((nonStackedWeight >= threshold) ? (num2 * multiplier) : num2); } } return num; } } internal sealed class Ingredient { public readonly string Item; public readonly int Amount; public readonly int PerLevel; public Ingredient(string item, int amount, int perLevel) { Item = item; Amount = amount; PerLevel = perLevel; } } internal sealed class PackDef { public readonly string Prefab; public readonly string Bundle; public readonly string Token; public readonly string Name; public readonly string Description; public readonly string Station; public readonly int StationLevel; public readonly Ingredient[] Craft; public readonly Vector2[] GridDefault; public readonly int CarryDefault; public ConfigEntry[] Grid; public ConfigEntry CarryBonus; public SharedData Shared; internal static readonly PackDef[] All = new PackDef[6] { new PackDef("BackpackMeadows", "backpack_meadows", "vapok_mod_item_backpack_meadows", "Satchel", "A small backpack capable of holding things.", CraftingStations.Workbench, 2, new Ingredient[4] { new Ingredient("CapeDeerHide", 1, 0), new Ingredient("DeerHide", 8, 3), new Ingredient("BoneFragments", 2, 0), new Ingredient("LeatherScraps", 0, 5) }, G(3, 1, 4, 1, 5, 1, 6, 1), 5), new PackDef("BackpackBlackForest", "backpack_black_forest", "vapok_mod_item_backpack_blackforest", "Rugged Backpack", "A rugged backpack, complete with buckles and fine leather straps.", CraftingStations.Forge, 1, new Ingredient[4] { new Ingredient("CapeTrollHide", 1, 0), new Ingredient("Copper", 5, 0), new Ingredient("TrollHide", 0, 3), new Ingredient("Bronze", 0, 3) }, G(3, 2, 4, 2, 5, 2, 6, 2), 10), new PackDef("BackpackSwamp", "backpack_swamp", "vapok_mod_item_backpack_swamp", "Bloodbag Wetpack", "A durable backpack sealed using waterproof blood bags.", CraftingStations.Workbench, 2, new Ingredient[4] { new Ingredient("Bloodbag", 10, 2), new Ingredient("Root", 4, 0), new Ingredient("Guck", 4, 0), new Ingredient("Iron", 0, 5) }, G(2, 3, 3, 3, 4, 3, 5, 3), 15), new PackDef("BackpackMountains", "backpack_mountains", "vapok_mod_item_backpack_mountains", "Arctic Sherpa Pack", "An arctic backpack, fit for long treks through the mountains.", CraftingStations.Forge, 3, new Ingredient[4] { new Ingredient("CapeWolf", 1, 0), new Ingredient("WolfHairBundle", 10, 0), new Ingredient("WolfPelt", 0, 5), new Ingredient("Silver", 0, 5) }, G(3, 3, 4, 3, 5, 3, 6, 3), 20), new PackDef("BackpackPlains", "backpack_plains", "vapok_mod_item_backpack_plains", "Lox Hide Knappsack", "An adventuring backpack made from extremely durable lox hide.", CraftingStations.Forge, 3, new Ingredient[4] { new Ingredient("CapeLox", 1, 0), new Ingredient("Tar", 5, 0), new Ingredient("BlackMetal", 5, 5), new Ingredient("LoxPelt", 0, 2) }, G(3, 4, 4, 4, 5, 4, 6, 4), 25), new PackDef("BackpackMistlands", "backpack_mistlands", "vapok_mod_item_backpack_mistlands", "Explorers Wisppack", "A finely crafted, mystical backpack. Complete with it's own Box of Holding. No one is quite sure how it works.", CraftingStations.BlackForge, 1, new Ingredient[4] { new Ingredient("CapeFeather", 1, 0), new Ingredient("ScaleHide", 5, 4), new Ingredient("Eitr", 10, 2), new Ingredient("Softtissue", 0, 5) }, G(8, 2, 5, 4, 6, 4, 7, 4), 30) }; internal Sprite Icon { get { if (Shared == null || Shared.m_icons == null || Shared.m_icons.Length == 0) { return null; } return Shared.m_icons[0]; } } private PackDef(string prefab, string bundle, string token, string name, string description, string station, int stationLevel, Ingredient[] craft, Vector2[] grid, int carry) { Prefab = prefab; Bundle = bundle; Token = token; Name = name; Description = description; Station = station; StationLevel = stationLevel; Craft = craft; GridDefault = grid; CarryDefault = carry; } private static Vector2[] G(int w1, int h1, int w2, int h2, int w3, int h3, int w4, int h4) { //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_001c: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0045: Unknown result type (might be due to invalid IL or missing references) return (Vector2[])(object)new Vector2[4] { new Vector2((float)w1, (float)h1), new Vector2((float)w2, (float)h2), new Vector2((float)w3, (float)h3), new Vector2((float)w4, (float)h4) }; } internal static PackDef Of(ItemData item) { if (item == null || (Object)(object)item.m_dropPrefab == (Object)null) { return null; } return OfPrefab(((Object)item.m_dropPrefab).name); } internal static PackDef OfPrefab(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return null; } for (int i = 0; i < All.Length; i++) { if (All[i].Prefab == prefabName) { return All[i]; } } return null; } internal static void BindConfig(ConfigFile cfg) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown PackDef[] all = All; foreach (PackDef packDef in all) { string text = "Backpack: " + packDef.Name; packDef.Grid = new ConfigEntry[4]; for (int j = 1; j <= 4; j++) { packDef.Grid[j - 1] = cfg.Bind(text, "Backpack Size - Level " + j, packDef.GridDefault[j - 1], new ConfigDescription("Grid (width, height) of the pack at quality " + j + ". Width 1-8, height 1-256. Shrinking a grid dumps the overflow into the player's inventory or on the floor.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, Category = text, Order = 10 - j } })); } packDef.CarryBonus = cfg.Bind(text, "Carry Bonus", packDef.CarryDefault, new ConfigDescription("Extra carry weight while the pack is worn.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 300), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, Category = text, Order = 1 } })); } } internal Vector2Int GridFor(int quality) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(quality, 1, 4); Vector2 val = ((Grid != null && Grid[num - 1] != null) ? Grid[num - 1].Value : GridDefault[num - 1]); return new Vector2Int(Mathf.Clamp((int)val.x, 1, 8), Mathf.Clamp((int)val.y, 1, 256)); } internal RequirementConfig[] Requirements() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown RequirementConfig[] array = (RequirementConfig[])(object)new RequirementConfig[Craft.Length]; for (int i = 0; i < Craft.Length; i++) { array[i] = new RequirementConfig(Craft[i].Item, Craft[i].Amount, Craft[i].PerLevel, true); } return array; } } internal static class PackUi { private static readonly FieldRef containerInventory = AccessTools.FieldRefAccess("m_inventory"); private static readonly FieldRef currentContainer = AccessTools.FieldRefAccess("m_currentContainer"); private static readonly MethodInfo closeContainer = AccessTools.Method(typeof(InventoryGui), "CloseContainer", (Type[])null, (Type[])null); private static readonly FieldRef shoulderItem = AccessTools.FieldRefAccess("m_shoulderItem"); private static bool wasVisible; internal static bool IsPlayerContainer(Container c) { if ((Object)(object)c != (Object)null) { return (Object)(object)((Component)c).GetComponent() != (Object)null; } return false; } internal static Container PlayerContainer(Player p) { if (!((Object)(object)p != (Object)null)) { return null; } return ((Component)p).GetComponent(); } internal static ItemData Shoulder(Humanoid h) { if (!((Object)(object)h != (Object)null)) { return null; } return shoulderItem.Invoke(h); } internal static ItemData WornPack(Player p) { ItemData val = Shoulder((Humanoid)(object)p); if (!PackData.IsPack(val)) { return null; } return val; } internal static bool IsOpen(Player p) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)p == (Object)null) { return false; } Container val = PlayerContainer(p); if ((Object)(object)val != (Object)null) { return (Object)(object)currentContainer.Invoke(instance) == (Object)(object)val; } return false; } internal static void Open(Player p) { InventoryGui instance = InventoryGui.instance; Container val = PlayerContainer(p); ItemData val2 = WornPack(p); if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null || val2 == null) { return; } PackData packData = PackData.Get(val2); if (packData != null) { Container val3 = currentContainer.Invoke(instance); if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val) { val3.SetInUse(false); currentContainer.Invoke(instance) = null; } containerInventory.Invoke(val) = packData.Inv; val.m_width = packData.Inv.GetWidth(); val.m_height = packData.Inv.GetHeight(); val.m_bkg = packData.Def.Icon; val.m_name = packData.Inv.GetName(); instance.Show(val, 1); } } internal static void Close(Player p) { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null) && IsOpen(p) && !(closeContainer == null)) { closeContainer.Invoke(instance, null); } } internal static void OnUnequip(Player p, ItemData item) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown PackData.Get(item)?.Save(); if (IsOpen(p)) { Close(p); } Container val = PlayerContainer(p); if ((Object)(object)val != (Object)null) { containerInventory.Invoke(val) = new Inventory("Empty", (Sprite)null, 1, 1); } } internal static void Tick() { //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) Player localPlayer = Player.m_localPlayer; InventoryGui instance = InventoryGui.instance; if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null) { wasVisible = false; return; } bool flag = InventoryGui.IsVisible(); if (flag && !wasVisible && ReefPacksPlugin.OpenWithInventory.Value && WornPack(localPlayer) != null && !IsOpen(localPlayer)) { try { Open(localPlayer); } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("open with inventory: " + ex.GetType().Name + ": " + ex.Message)); } } wasVisible = flag; if (!flag || TextInput.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible()) { return; } KeyboardShortcut value = ReefPacksPlugin.OpenKey.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { return; } try { if (IsOpen(localPlayer)) { Close(localPlayer); } else if (WornPack(localPlayer) != null) { Open(localPlayer); } else { ((Character)localPlayer).Message((MessageType)2, "$reefpacks_no_pack", 0, (Sprite)null, false); } } catch (Exception ex2) { ReefPacksPlugin.Log.LogWarning((object)("open pack: " + ex2.GetType().Name + ": " + ex2.Message)); } } } internal static class Patches { [HarmonyPatch(typeof(Player), "Awake")] internal static class PlayerAwake { private static void Postfix(Player __instance) { try { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent().m_name = "$reefpacks_pack"; } ZNetView component = ((Component)__instance).GetComponent(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val != null && component.IsOwner() && val.GetLong(ZDOVars.s_creator, 0L) == 0L) { val.Set(ZDOVars.s_creator, 1L); } } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("Player.Awake: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(Container), "Load")] internal static class ContainerLoad { private static bool Prefix(Container __instance, ref bool __result) { if (!PackUi.IsPlayerContainer(__instance)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Container), "Save")] internal static class ContainerSave { private static bool Prefix(Container __instance) { return !PackUi.IsPlayerContainer(__instance); } } [HarmonyPatch(typeof(Container), "Interact", new Type[] { typeof(Humanoid), typeof(bool), typeof(bool) })] internal static class ContainerInteract { private static bool Prefix(Container __instance, ref bool __result) { if (!PackUi.IsPlayerContainer(__instance)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(ItemData), "GetWeight", new Type[] { typeof(int) })] internal static class GetWeight { private static void Postfix(ItemData __instance, ref float __result) { try { if (PackData.IsPack(__instance)) { PackData packData = PackData.Get(__instance); if (packData != null) { __result += packData.ContentsWeight(ReefPacksPlugin.WeightThreshold.Value, ReefPacksPlugin.WeightMultiplier.Value); } } } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("GetWeight: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(Inventory), "IsTeleportable", new Type[] { typeof(bool) })] internal static class IsTeleportable { private static void Postfix(Inventory __instance, bool allowAllItems, ref bool __result) { try { if (!__result) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || __instance != ((Humanoid)localPlayer).GetInventory()) { return; } foreach (ItemData allItem in __instance.GetAllItems()) { if (PackData.IsPack(allItem)) { PackData packData = PackData.Get(allItem); if (packData != null && !packData.Inv.IsTeleportable(allowAllItems)) { __result = false; break; } } } } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("IsTeleportable: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem", new Type[] { typeof(ItemData), typeof(bool) })] internal static class UnequipItem { private static void Prefix(Humanoid __instance, ItemData item) { try { if (item != null && PackData.IsPack(item)) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && PackUi.Shoulder((Humanoid)(object)val) == item) { PackUi.OnUnequip(val, item); } } } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("UnequipItem: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(VisEquipment), "SetShoulderEquipped")] internal static class ShoulderBones { private static readonly FieldRef> shoulderInstances = AccessTools.FieldRefAccess>("m_shoulderItemInstances"); private static void Postfix(VisEquipment __instance, int hash, bool __result) { if (!__result || (Object)(object)__instance == (Object)null) { return; } try { List list = shoulderInstances.Invoke(__instance); if (list == null || list.Count == 0) { return; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(hash) : null); if ((Object)(object)val == (Object)null || PackDef.OfPrefab(((Object)val).name) == null) { return; } Transform val2 = ((Component)__instance).transform.Find("Visual/Armature/Hips"); if ((Object)(object)val2 == (Object)null) { return; } int num = 0; for (int i = 0; i < val.transform.childCount; i++) { Transform child = val.transform.GetChild(i); if (!((Object)child).name.StartsWith("attach_skin")) { continue; } if (num >= list.Count) { break; } SkinnedMeshRenderer[] componentsInChildren = list[num].GetComponentsInChildren(true); SkinnedMeshRenderer[] componentsInChildren2 = ((Component)child).GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length && j < componentsInChildren.Length; j++) { Transform[] bones = componentsInChildren2[j].bones; Transform[] array = (Transform[])(object)new Transform[componentsInChildren[j].bones.Length]; for (int k = 0; k < array.Length && k < bones.Length; k++) { array[k] = FindInChildren(val2, ((Object)bones[k]).name); } componentsInChildren[j].bones = array; componentsInChildren[j].rootBone = val2; } num++; } } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("ShoulderBones: " + ex.Message)); } } private static Transform FindInChildren(Transform t, string name) { if (((Object)t).name == name) { return t; } for (int i = 0; i < t.childCount; i++) { Transform val = FindInChildren(t.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } } internal static class MaxPacksRule { private static float lastMessage; internal static int Limit { get { if (ReefPacksPlugin.MaxPacks == null) { return 0; } return ReefPacksPlugin.MaxPacks.Value; } } internal static int Count(Inventory inv) { int num = 0; if (inv == null) { return 0; } foreach (ItemData allItem in inv.GetAllItems()) { if (PackDef.Of(allItem) != null) { num++; } } return num; } internal static bool Full(Inventory inv) { if (Limit > 0) { return Count(inv) >= Limit; } return false; } internal static bool IsLocalPlayerInventory(Inventory inv) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { return inv == ((Humanoid)localPlayer).GetInventory(); } return false; } internal static void Say() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !(Time.time - lastMessage < 2f)) { lastMessage = Time.time; ((Character)localPlayer).Message((MessageType)2, Limit + ((Limit == 1) ? " pack at most" : " packs at most"), 0, (Sprite)null, false); } } } [HarmonyPatch(typeof(Humanoid), "Pickup")] internal static class MaxPacksPickup { private static bool Prefix(Humanoid __instance, GameObject go) { try { if (!(__instance is Player) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || (Object)(object)go == (Object)null) { return true; } ItemDrop component = go.GetComponent(); if ((Object)(object)component == (Object)null || component.m_itemData == null || PackDef.Of(component.m_itemData) == null) { return true; } if (!MaxPacksRule.Full(__instance.GetInventory())) { return true; } MaxPacksRule.Say(); return false; } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("MaxPacksPickup: " + ex.Message)); return true; } } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData), typeof(int), typeof(int), typeof(int) })] internal static class MaxPacksMove { private static bool Prefix(Inventory __instance, Inventory fromInventory, ItemData item, ref bool __result) { try { if (fromInventory == __instance || item == null || PackDef.Of(item) == null) { return true; } if (!MaxPacksRule.IsLocalPlayerInventory(__instance) || !MaxPacksRule.Full(__instance)) { return true; } MaxPacksRule.Say(); __result = false; return false; } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("MaxPacksMove: " + ex.Message)); return true; } } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] internal static class MaxPacksCraft { private static readonly FieldRef craftRecipe = AccessTools.FieldRefAccess("m_craftRecipe"); private static readonly FieldRef upgradeItem = AccessTools.FieldRefAccess("m_craftUpgradeItem"); private static bool Prefix(InventoryGui __instance, Player player) { try { Recipe val = craftRecipe.Invoke(__instance); if ((Object)(object)val == (Object)null || (Object)(object)val.m_item == (Object)null || upgradeItem.Invoke(__instance) != null) { return true; } if (PackDef.OfPrefab(((Object)((Component)val.m_item).gameObject).name) == null) { return true; } if ((Object)(object)player == (Object)null || !MaxPacksRule.Full(((Humanoid)player).GetInventory())) { return true; } MaxPacksRule.Say(); return false; } catch (Exception ex) { ReefPacksPlugin.Log.LogWarning((object)("MaxPacksCraft: " + ex.Message)); return true; } } } } [BepInPlugin("reef.packs", "Reef Packs", "0.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("vapok.mods.adventurebackpacks")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class ReefPacksPlugin : BaseUnityPlugin { public const string GUID = "reef.packs"; public const string NAME = "Reef Packs"; public const string VERSION = "0.1.1"; public const string BUILD = "reef"; internal static ManualLogSource Log; internal static ReefPacksPlugin Instance; internal static ConfigEntry WeightMultiplier; internal static ConfigEntry WeightThreshold; internal static ConfigEntry MaxPacks; internal static ConfigEntry OpenKey; internal static ConfigEntry OpenWithInventory; private Harmony harmony; private bool registered; private void Awake() { //IL_0042: 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_004f: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0104: 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_0164: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; WeightMultiplier = ((BaseUnityPlugin)this).Config.Bind("Packs", "Weight multiplier", 0.3f, new ConfigDescription("Contents weigh this fraction of their real weight while inside a pack (The Reef: 0.3).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); WeightThreshold = ((BaseUnityPlugin)this).Config.Bind("Packs", "Weight threshold", 2f, new ConfigDescription("The multiplier applies only to contents whose unit weight is at least this value (wood, stone, flint = 2; ores and bars = 10-12); lighter items keep their real weight. 0 = everything reduced.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 20f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); MaxPacks = ((BaseUnityPlugin)this).Config.Bind("Packs", "Max packs carried", 3, new ConfigDescription("A player carries at most this many packs (the worn one included): pickup, taking from a chest and crafting refuse the next one. 0 = no limit.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 20), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); OpenKey = ((BaseUnityPlugin)this).Config.Bind("Keys", "Open pack", new KeyboardShortcut((KeyCode)105, Array.Empty()), "With the inventory open: opens and closes the worn pack. Client-side."); OpenWithInventory = ((BaseUnityPlugin)this).Config.Bind("Keys", "Open with inventory", false, "true = the worn pack opens by itself every time the inventory opens. Client-side."); PackDef.BindConfig(((BaseUnityPlugin)this).Config); PrefabManager.OnVanillaPrefabsAvailable += RegisterPacks; harmony = new Harmony("reef.packs"); harmony.PatchAll(typeof(Patches.PlayerAwake)); harmony.PatchAll(typeof(Patches.ContainerLoad)); harmony.PatchAll(typeof(Patches.ContainerSave)); harmony.PatchAll(typeof(Patches.ContainerInteract)); harmony.PatchAll(typeof(Patches.GetWeight)); harmony.PatchAll(typeof(Patches.IsTeleportable)); harmony.PatchAll(typeof(Patches.UnequipItem)); harmony.PatchAll(typeof(Patches.ShoulderBones)); harmony.PatchAll(typeof(Patches.MaxPacksPickup)); harmony.PatchAll(typeof(Patches.MaxPacksMove)); harmony.PatchAll(typeof(Patches.MaxPacksCraft)); Log.LogInfo((object)"Reef Packs 0.1.1 loaded (build: reef)"); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private void Update() { PackUi.Tick(); } private void RegisterPacks() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterPacks; if (registered) { return; } registered = true; try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; string text2 = "vapok_mod_level"; localization.AddTranslation(ref text, ref text2, "Level"); text = "English"; text2 = "reefpacks_pack"; localization.AddTranslation(ref text, ref text2, "Pack"); text = "English"; text2 = "reefpacks_no_pack"; localization.AddTranslation(ref text, ref text2, "No pack on your back"); text = "English"; text2 = "reefpacks_pack_in_pack"; localization.AddTranslation(ref text, ref text2, "A pack cannot go inside a pack"); int num = 0; PackDef[] all = PackDef.All; foreach (PackDef packDef in all) { try { if (RegisterPack(packDef, executingAssembly, localization)) { num++; } } catch (Exception ex) { Log.LogError((object)("pack " + packDef.Prefab + ": " + ex)); } } Log.LogInfo((object)("packs registered: " + num + "/" + PackDef.All.Length)); } catch (Exception ex2) { Log.LogError((object)("RegisterPacks: " + ex2)); } } private static bool RegisterPack(PackDef def, Assembly asm, CustomLocalization loc) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown AssetBundle val = AssetUtils.LoadAssetBundleFromResources(def.Bundle, asm); if ((Object)(object)val == (Object)null) { Log.LogError((object)("bundle missing: " + def.Bundle)); return false; } try { ItemConfig val2 = new ItemConfig { Name = "$" + def.Token, Description = "$" + def.Token + "_description", CraftingStation = def.Station, MinStationLevel = def.StationLevel, Requirements = def.Requirements() }; CustomItem val3 = new CustomItem(val, def.Prefab, false, val2); if (!ItemManager.Instance.AddItem(val3)) { Log.LogError((object)("AddItem refused: " + def.Prefab)); return false; } def.Shared = val3.ItemDrop.m_itemData.m_shared; string text = "English"; loc.AddTranslation(ref text, ref def.Token, def.Name); text = "English"; string text2 = def.Token + "_description"; loc.AddTranslation(ref text, ref text2, def.Description); SE_Stats se = ScriptableObject.CreateInstance(); ((Object)se).name = "SE_ReefPack_" + def.Prefab; ((StatusEffect)se).m_name = def.Name; ((StatusEffect)se).m_icon = def.Icon; ((StatusEffect)se).m_tooltip = "Carry weight +" + def.CarryBonus.Value; se.m_addMaxCarryWeight = def.CarryBonus.Value; if (ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)se, false))) { def.Shared.m_equipStatusEffect = (StatusEffect)(object)se; def.CarryBonus.SettingChanged += delegate { se.m_addMaxCarryWeight = def.CarryBonus.Value; ((StatusEffect)se).m_tooltip = "Carry weight +" + def.CarryBonus.Value; }; } else { Log.LogWarning((object)("carry effect refused: " + ((Object)se).name)); } Log.LogInfo((object)("pack registered: " + def.Prefab + " (" + def.Name + ")")); return true; } finally { val.Unload(false); } } } }