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();
}
}
}