Decompiled source of ReefPacks v0.1.1

ReefPacks.dll

Decompiled 7 hours ago
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<ItemData, PackData> cache = new ConditionalWeakTable<ItemData, PackData>();

		private static readonly FieldRef<Inventory, int> invWidth = AccessTools.FieldRefAccess<Inventory, int>("m_width");

		private static readonly FieldRef<Inventory, int> invHeight = AccessTools.FieldRefAccess<Inventory, int>("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<string, string>();
				}
				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<ItemData> list = null;
			foreach (ItemData allItem in Inv.GetAllItems())
			{
				if (IsPack(allItem))
				{
					(list ?? (list = new List<ItemData>())).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<ItemData> 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<ItemData>())).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<Vector2>[] Grid;

		public ConfigEntry<int> 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<Vector2>[4];
				for (int j = 1; j <= 4; j++)
				{
					packDef.Grid[j - 1] = cfg.Bind<Vector2>(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<int>(text, "Carry Bonus", packDef.CarryDefault, new ConfigDescription("Extra carry weight while the pack is worn.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(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<Container, Inventory> containerInventory = AccessTools.FieldRefAccess<Container, Inventory>("m_inventory");

		private static readonly FieldRef<InventoryGui, Container> currentContainer = AccessTools.FieldRefAccess<InventoryGui, Container>("m_currentContainer");

		private static readonly MethodInfo closeContainer = AccessTools.Method(typeof(InventoryGui), "CloseContainer", (Type[])null, (Type[])null);

		private static readonly FieldRef<Humanoid, ItemData> shoulderItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_shoulderItem");

		private static bool wasVisible;

		internal static bool IsPlayerContainer(Container c)
		{
			if ((Object)(object)c != (Object)null)
			{
				return (Object)(object)((Component)c).GetComponent<Player>() != (Object)null;
			}
			return false;
		}

		internal static Container PlayerContainer(Player p)
		{
			if (!((Object)(object)p != (Object)null))
			{
				return null;
			}
			return ((Component)p).GetComponent<Container>();
		}

		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<Container>() == (Object)null)
					{
						((Component)__instance).gameObject.AddComponent<Container>().m_name = "$reefpacks_pack";
					}
					ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
					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<VisEquipment, List<GameObject>> shoulderInstances = AccessTools.FieldRefAccess<VisEquipment, List<GameObject>>("m_shoulderItemInstances");

			private static void Postfix(VisEquipment __instance, int hash, bool __result)
			{
				if (!__result || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				try
				{
					List<GameObject> 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<SkinnedMeshRenderer>(true);
						SkinnedMeshRenderer[] componentsInChildren2 = ((Component)child).GetComponentsInChildren<SkinnedMeshRenderer>(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<ItemDrop>();
					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<InventoryGui, Recipe> craftRecipe = AccessTools.FieldRefAccess<InventoryGui, Recipe>("m_craftRecipe");

			private static readonly FieldRef<InventoryGui, ItemData> upgradeItem = AccessTools.FieldRefAccess<InventoryGui, ItemData>("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<float> WeightMultiplier;

		internal static ConfigEntry<float> WeightThreshold;

		internal static ConfigEntry<int> MaxPacks;

		internal static ConfigEntry<KeyboardShortcut> OpenKey;

		internal static ConfigEntry<bool> 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<float>("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<float>(0f, 1f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			WeightThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>(0f, 20f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			MaxPacks = ((BaseUnityPlugin)this).Config.Bind<int>("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<int>(0, 20), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			OpenKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "Open pack", new KeyboardShortcut((KeyCode)105, Array.Empty<KeyCode>()), "With the inventory open: opens and closes the worn pack. Client-side.");
			OpenWithInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("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<SE_Stats>();
				((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);
			}
		}
	}
}