Decompiled source of FrostwolfBackpack v0.1.0

plugins/FrostwolfBackpack/FrostwolfBackpack.dll

Decompiled 3 weeks ago
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 BepInEx;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FrostwolfBackpack")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FrostwolfBackpack")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1f6de12b-4520-4192-bc0d-b7b0ead14778")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FrostwolfBackpack;

public class Class1
{
}
[BepInPlugin("purplepanda.valhime.frostwolfbackpack", "Frostwolf Backpack", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class FrostwolfBackpackPlugin : BaseUnityPlugin
{
	public const string ModGuid = "purplepanda.valhime.frostwolfbackpack";

	public const string ModName = "Frostwolf Backpack";

	public const string Version = "0.1.0";

	private Harmony _harmony;

	private CustomItem _backpackItem;

	private CustomRecipe _backpackRecipe;

	internal static string FrostEffectName;

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		_harmony = new Harmony("purplepanda.valhime.frostwolfbackpack");
		_harmony.PatchAll();
		CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new BackpackStoreCommand());
		CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new BackpackTakeCommand());
		PrefabManager.OnVanillaPrefabsAvailable += RegisterBackpack;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Frostwolf Backpack 0.1.0 loaded.");
		Logger.LogInfo((object)"Frostwolf Backpack 0.1.0 loaded via Jotunn.");
	}

	private void OnDestroy()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= RegisterBackpack;
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}

	private void RegisterBackpack()
	{
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Expected O, but got Unknown
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Expected O, but got Unknown
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: Expected O, but got Unknown
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Expected O, but got Unknown
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Expected O, but got Unknown
		//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0308: Expected O, but got Unknown
		//IL_0315: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Expected O, but got Unknown
		//IL_0333: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Expected O, but got Unknown
		try
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("BeltStrength");
			if ((Object)(object)prefab == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Could not find BeltStrength prefab!");
				return;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("FrostwolfBackpack", prefab);
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Cloned FrostwolfBackpack has no ItemDrop component.");
				return;
			}
			SharedData shared = component.m_itemData.m_shared;
			shared.m_name = "Frostwolf Backpack";
			shared.m_description = "A rugged backpack lined with wolf fur. Grants frost resistance and extra carrying space.";
			shared.m_itemType = (ItemType)18;
			shared.m_useDurability = true;
			shared.m_maxDurability = 100f;
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("CapeWolf");
			if ((Object)(object)prefab2 != (Object)null)
			{
				ItemDrop component2 = prefab2.GetComponent<ItemDrop>();
				if ((Object)(object)component2 != (Object)null && component2.m_itemData.m_shared.m_icons != null && component2.m_itemData.m_shared.m_icons.Length != 0)
				{
					shared.m_icons = (Sprite[])(object)new Sprite[1];
					shared.m_icons[0] = component2.m_itemData.m_shared.m_icons[0];
				}
			}
			GameObject prefab3 = PrefabManager.Instance.GetPrefab("MeadFrostResist");
			if ((Object)(object)prefab3 != (Object)null)
			{
				ItemDrop component3 = prefab3.GetComponent<ItemDrop>();
				if ((Object)(object)component3 != (Object)null)
				{
					SharedData shared2 = component3.m_itemData.m_shared;
					if ((Object)(object)shared2.m_consumeStatusEffect != (Object)null)
					{
						shared.m_equipStatusEffect = shared2.m_consumeStatusEffect;
						FrostEffectName = ((Object)shared2.m_consumeStatusEffect).name;
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Frostwolf Backpack now uses FrostResistance status effect '" + FrostEffectName + "' from MeadFrostResist."));
					}
					else
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"MeadFrostResist has no consumeStatusEffect – cannot copy frost resistance.");
					}
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"MeadFrostResist prefab has no ItemDrop.");
				}
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find MeadFrostResist prefab – backpack will not give frost resistance.");
			}
			_backpackItem = new CustomItem(val, true);
			ItemManager.Instance.AddItem(_backpackItem);
			RecipeConfig val2 = new RecipeConfig();
			val2.Name = "Recipe_FrostwolfBackpack";
			val2.Item = "FrostwolfBackpack";
			val2.Amount = 1;
			val2.CraftingStation = "forge";
			val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[4]
			{
				new RequirementConfig
				{
					Item = "Silver",
					Amount = 10,
					Recover = true
				},
				new RequirementConfig
				{
					Item = "WolfPelt",
					Amount = 12,
					Recover = true
				},
				new RequirementConfig
				{
					Item = "WolfHairBundle",
					Amount = 5,
					Recover = true
				},
				new RequirementConfig
				{
					Item = "FreezeGland",
					Amount = 8,
					Recover = true
				}
			};
			RecipeConfig val3 = val2;
			_backpackRecipe = new CustomRecipe(val3);
			ItemManager.Instance.AddRecipe(_backpackRecipe);
			_backpackRecipe = new CustomRecipe(val3);
			ItemManager.Instance.AddRecipe(_backpackRecipe);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Frostwolf Backpack item & recipe registered via RecipeConfig.");
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Error registering Frostwolf Backpack: {arg}");
		}
	}
}
[HarmonyPatch(typeof(Inventory), "GetTotalWeight")]
public static class FrostwolfBackpackWeightPatch
{
	private const string BackpackPrefabName = "FrostwolfBackpack";

	private static void Postfix(Inventory __instance, ref float __result)
	{
		try
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || __instance != ((Humanoid)localPlayer).GetInventory())
			{
				return;
			}
			BackpackComponent component = ((Component)localPlayer).GetComponent<BackpackComponent>();
			if ((Object)(object)component == (Object)null || component.BackpackInventory == null)
			{
				return;
			}
			float totalWeight = component.BackpackInventory.GetTotalWeight();
			if (!(totalWeight <= 0f))
			{
				if (IsBackpackEquipped(localPlayer))
				{
					__result += totalWeight * 0.9f;
				}
				else
				{
					__result += totalWeight;
				}
			}
		}
		catch
		{
		}
	}

	internal static bool IsBackpackEquipped(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return false;
		}
		List<ItemData> equippedItems = inventory.GetEquippedItems();
		if (equippedItems == null)
		{
			return false;
		}
		foreach (ItemData item in equippedItems)
		{
			if (item == null || !((Object)(object)item.m_dropPrefab != (Object)null) || !(((Object)item.m_dropPrefab).name == "FrostwolfBackpack"))
			{
				continue;
			}
			if (!item.m_shared.m_useDurability || item.m_shared.m_maxDurability <= 0f)
			{
				return true;
			}
			if (item.m_durability <= 0f)
			{
				return false;
			}
			return true;
		}
		return false;
	}
}
[HarmonyPatch(typeof(Player), "Update")]
public static class FrostwolfBackpackFrostRefreshPatch
{
	private static readonly FieldInfo SeManField = typeof(Character).GetField("m_seman", BindingFlags.Instance | BindingFlags.NonPublic);

	private static void Postfix(Player __instance)
	{
		try
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || string.IsNullOrEmpty(FrostwolfBackpackPlugin.FrostEffectName) || !FrostwolfBackpackWeightPatch.IsBackpackEquipped(__instance) || SeManField == null)
			{
				return;
			}
			object? value = SeManField.GetValue(__instance);
			SEMan val = (SEMan)((value is SEMan) ? value : null);
			if (val != null)
			{
				int stableHashCode = StringExtensionMethods.GetStableHashCode(FrostwolfBackpackPlugin.FrostEffectName);
				if (!val.HaveStatusEffect(stableHashCode))
				{
					val.AddStatusEffect(stableHashCode, false, 0, 0f);
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Character), "Damage")]
public static class FrostwolfBackpackDurabilityPatch
{
	private static void Postfix(Character __instance, HitData hit)
	{
		try
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || hit == null)
			{
				return;
			}
			float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage();
			if (totalDamage <= 0f)
			{
				return;
			}
			Inventory inventory = ((Humanoid)val).GetInventory();
			if (inventory == null)
			{
				return;
			}
			ItemData val2 = null;
			List<ItemData> equippedItems = inventory.GetEquippedItems();
			if (equippedItems != null)
			{
				foreach (ItemData item in equippedItems)
				{
					if ((Object)(object)item?.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == "FrostwolfBackpack")
					{
						val2 = item;
						break;
					}
				}
			}
			if (val2 != null && val2.m_shared.m_useDurability && !(val2.m_shared.m_maxDurability <= 0f))
			{
				float num = Mathf.Max(1f, totalDamage * 0.05f);
				val2.m_durability = Mathf.Max(0f, val2.m_durability - num);
			}
		}
		catch
		{
		}
	}
}
public class BackpackComponent : MonoBehaviour
{
	private const string CustomDataKey = "purplepanda.valhime.backpack.inventory";

	private Player _player;

	public Inventory BackpackInventory { get; private set; }

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		_player = ((Component)this).GetComponent<Player>();
		BackpackInventory = new Inventory("Frostwolf Backpack", (Sprite)null, 4, 3);
		LoadFromCustomData();
	}

	private void OnDestroy()
	{
		SaveToCustomData();
	}

	public void LoadFromCustomData()
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		if ((Object)(object)_player == (Object)null || _player.m_customData == null || !_player.m_customData.TryGetValue("purplepanda.valhime.backpack.inventory", out var value) || string.IsNullOrEmpty(value))
		{
			return;
		}
		try
		{
			ZPackage val = new ZPackage(value);
			BackpackInventory.Load(val);
		}
		catch (Exception arg)
		{
			Logger.LogWarning((object)$"Failed to load backpack inventory: {arg}");
		}
	}

	public void SaveToCustomData()
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Expected O, but got Unknown
		if ((Object)(object)_player == (Object)null)
		{
			return;
		}
		if (_player.m_customData == null)
		{
			_player.m_customData = new Dictionary<string, string>();
		}
		try
		{
			ZPackage val = new ZPackage();
			BackpackInventory.Save(val);
			_player.m_customData["purplepanda.valhime.backpack.inventory"] = val.GetBase64();
		}
		catch (Exception arg)
		{
			Logger.LogWarning((object)$"Failed to save backpack inventory: {arg}");
		}
	}

	public void StoreAll()
	{
		if ((Object)(object)_player == (Object)null)
		{
			return;
		}
		if (!FrostwolfBackpackWeightPatch.IsBackpackEquipped(_player))
		{
			Logger.LogInfo((object)"Cannot store items: Frostwolf Backpack is not equipped or is broken.");
			return;
		}
		Inventory inventory = ((Humanoid)_player).GetInventory();
		if (inventory == null)
		{
			return;
		}
		List<ItemData> list = new List<ItemData>(inventory.GetAllItems());
		foreach (ItemData item in list)
		{
			if (item != null && !item.m_equipped && (!((Object)(object)item.m_dropPrefab != (Object)null) || !(((Object)item.m_dropPrefab).name == "FrostwolfBackpack")) && BackpackInventory.CanAddItem(item, item.m_stack) && BackpackInventory.AddItem(item))
			{
				inventory.RemoveItem(item);
			}
		}
		SaveToCustomData();
		Logger.LogInfo((object)"Stored items into Frostwolf Backpack inventory.");
	}

	public void TakeAll()
	{
		if ((Object)(object)_player == (Object)null)
		{
			return;
		}
		Inventory inventory = ((Humanoid)_player).GetInventory();
		if (inventory == null)
		{
			return;
		}
		List<ItemData> list = new List<ItemData>(BackpackInventory.GetAllItems());
		foreach (ItemData item in list)
		{
			if (item != null && inventory.CanAddItem(item, item.m_stack) && inventory.AddItem(item))
			{
				BackpackInventory.RemoveItem(item);
			}
		}
		SaveToCustomData();
		Logger.LogInfo((object)"Moved items from Frostwolf Backpack inventory to player inventory.");
	}
}
[HarmonyPatch(typeof(Player), "Awake")]
public static class PlayerBackpackAttachPatch
{
	private static void Postfix(Player __instance)
	{
		if ((Object)(object)((Component)__instance).GetComponent<BackpackComponent>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<BackpackComponent>();
		}
	}
}
public class BackpackContainer : Container
{
	private BackpackComponent _backpackComponent;

	private static readonly FieldInfo InventoryField = typeof(Container).GetField("m_inventory", BindingFlags.Instance | BindingFlags.NonPublic);

	public void Init(BackpackComponent comp)
	{
		_backpackComponent = comp;
		base.m_name = "Frostwolf Backpack";
		if (InventoryField != null)
		{
			InventoryField.SetValue(this, comp.BackpackInventory);
		}
		else
		{
			Logger.LogWarning((object)"BackpackContainer: Could not find Container.m_inventory field via reflection.");
		}
	}

	private void OnDestroy()
	{
		_backpackComponent?.SaveToCustomData();
	}
}
[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
public static class FrostwolfBackpackRightClickPatch
{
	private static bool Prefix(InventoryGrid grid, ItemData item, Vector2i pos)
	{
		if (item == null || (Object)(object)item.m_dropPrefab == (Object)null || ((Object)item.m_dropPrefab).name != "FrostwolfBackpack")
		{
			return true;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return false;
		}
		BackpackComponent component = ((Component)localPlayer).GetComponent<BackpackComponent>();
		if ((Object)(object)component == (Object)null)
		{
			return false;
		}
		BackpackContainer backpackContainer = ((Component)localPlayer).GetComponent<BackpackContainer>();
		if ((Object)(object)backpackContainer == (Object)null)
		{
			backpackContainer = ((Component)localPlayer).gameObject.AddComponent<BackpackContainer>();
		}
		backpackContainer.Init(component);
		InventoryGui.instance.Show((Container)(object)backpackContainer, 1);
		return false;
	}
}
[HarmonyPatch(typeof(Player), "Update")]
public static class FrostwolfBackpackHotkeyPatch
{
	private static void Postfix(Player __instance)
	{
		if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !FrostwolfBackpackWeightPatch.IsBackpackEquipped(__instance) || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || !ZInput.GetKeyDown((KeyCode)98, false))
		{
			return;
		}
		BackpackComponent component = ((Component)__instance).GetComponent<BackpackComponent>();
		if (!((Object)(object)component == (Object)null) && !((Object)(object)InventoryGui.instance == (Object)null))
		{
			BackpackContainer backpackContainer = ((Component)__instance).GetComponent<BackpackContainer>();
			if ((Object)(object)backpackContainer == (Object)null)
			{
				backpackContainer = ((Component)__instance).gameObject.AddComponent<BackpackContainer>();
			}
			backpackContainer.Init(component);
			InventoryGui.instance.Show((Container)(object)backpackContainer, 1);
		}
	}
}
[HarmonyPatch(typeof(InventoryGui), "Hide")]
public static class FrostwolfBackpackInventoryGuiHidePatch
{
	private static void Prefix()
	{
		try
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				((Component)localPlayer).GetComponent<BackpackComponent>()?.SaveToCustomData();
			}
		}
		catch
		{
		}
	}
}
public class BackpackStoreCommand : ConsoleCommand
{
	public override string Name => "bp_store";

	public override string Help => "Move items from player inventory into the Frostwolf Backpack (requires it to be equipped and not broken).";

	public override void Run(string[] args)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			Logger.LogInfo((object)"bp_store: No local player.");
			return;
		}
		BackpackComponent component = ((Component)localPlayer).GetComponent<BackpackComponent>();
		if ((Object)(object)component == (Object)null)
		{
			Logger.LogInfo((object)"bp_store: Backpack component not found on player.");
		}
		else
		{
			component.StoreAll();
		}
	}
}
public class BackpackTakeCommand : ConsoleCommand
{
	public override string Name => "bp_take";

	public override string Help => "Move items from the Frostwolf Backpack back into player inventory.";

	public override void Run(string[] args)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			Logger.LogInfo((object)"bp_take: No local player.");
			return;
		}
		BackpackComponent component = ((Component)localPlayer).GetComponent<BackpackComponent>();
		if ((Object)(object)component == (Object)null)
		{
			Logger.LogInfo((object)"bp_take: Backpack component not found on player.");
		}
		else
		{
			component.TakeAll();
		}
	}
}