Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Keep da weapons on my back plz v1.0.0
ValheimHolster.dll
Decompiled 9 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ValheimHolster")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.4")] [assembly: AssemblyProduct("ValheimHolster")] [assembly: AssemblyTitle("ValheimHolster")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 ValheimHolster { internal static class EnglishConfig { private static readonly Dictionary<string, string> Sections = new Dictionary<string, string> { { "1 - Geral", "1 - General" }, { "2 - Corpo", "2 - Body" }, { "3 - Tecla R", "3 - R key" }, { "4 - Quadril", "4 - Hips" }, { "5 - Escudo", "5 - Shield" }, { "6 - Hotbar", "6 - Hotbar" }, { "7 - Menu", "7 - Menu" }, { "8 - Recarga", "8 - Reloading" } }; private static readonly Dictionary<string, string> Keys = new Dictionary<string, string> { { "1 - Geral/Ativado", "Enabled" }, { "1 - Geral/Log detalhado", "Detailed logging" }, { "2 - Corpo/Tecla marcar", "Mark key" }, { "2 - Corpo/So armas marcadas ficam no corpo", "Only marked weapons on body" }, { "2 - Corpo/Guardar ao trocar de arma", "Holster when switching weapons" }, { "2 - Corpo/Mostrar todas as marcadas", "Show all marked weapons" }, { "2 - Corpo/Maximo de armas extras", "Maximum extra weapons" }, { "2 - Corpo/Cruzar armas grandes", "Cross large weapons" }, { "2 - Corpo/Ferramentas no corpo", "Holster tools" }, { "2 - Corpo/Mostrar no tooltip", "Show mark in tooltip" }, { "3 - Tecla R/Toque troca de arma", "Tap to switch weapons" }, { "3 - Tecla R/Dois toques esvaziam a mao", "Double tap to empty hands" }, { "3 - Tecla R/Tempo entre os dois toques", "Double tap interval" }, { "3 - Tecla R/Segurar abre a roda", "Hold to open weapon wheel" }, { "3 - Tecla R/Tempo segurando", "Wheel hold time" }, { "3 - Tecla R/Roda so com armas marcadas", "Only marked weapons in wheel" }, { "4 - Quadril/Arma de uma mao no quadril", "One-handed weapons on hips" }, { "4 - Quadril/Usar os dois lados", "Use both hips" }, { "4 - Quadril/Inclinacao pra tras", "Backward tilt" }, { "4 - Quadril/Giro pra fora", "Outward rotation" }, { "4 - Quadril/Altura", "Height" }, { "4 - Quadril/Frente", "Forward offset" }, { "4 - Quadril/Aproximar do corpo", "Inward offset" }, { "4 - Quadril/Faca - inclinacao", "Knife - backward tilt" }, { "4 - Quadril/Faca - giro pra fora", "Knife - outward rotation" }, { "4 - Quadril/Faca - aproximar da coxa", "Knife - inward offset" }, { "4 - Quadril/Faca - altura", "Knife - height" }, { "4 - Quadril/Faca - frente", "Knife - forward offset" }, { "4 - Quadril/Ajuste de posicao", "Position adjustment" }, { "4 - Quadril/Ajuste de rotacao", "Rotation adjustment" }, { "5 - Escudo/Escudo junto com arma de uma mao", "Auto-equip shield with one-handed weapon" }, { "5 - Escudo/Exceto com machado", "Exclude axes" }, { "5 - Escudo/Escudo acompanha a arma", "Unequip shield with weapon" }, { "6 - Hotbar/Numero so equipa", "Hotbar numbers only equip" }, { "7 - Menu/Mostrar armas no menu", "Show weapons in main menu" }, { "7 - Menu/Maos livres no menu", "Empty hands in main menu" }, { "8 - Recarga/Continua carregada ao guardar", "Keep loaded when holstered" }, { "8 - Recarga/Recarregar correndo", "Reload while running" }, { "8 - Recarga/So recarrega com municao", "Require ammunition to reload" }, { "8 - Recarga/Velocidade de recarga", "Reload speed" } }; internal static string Translate(string input) { string[] array = input.Replace("\r\n", "\n").Split('\n'); string text = ""; for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.StartsWith("[") && text2.EndsWith("]")) { text = text2.Substring(1, text2.Length - 2); if (Sections.TryGetValue(text, out var value)) { array[i] = "[" + value + "]"; } } else if (!text2.StartsWith("#") && !text2.StartsWith(";")) { int num = array[i].IndexOf('='); if (num >= 0 && Keys.TryGetValue(text + "/" + array[i].Substring(0, num).Trim(), out var value2)) { array[i] = value2 + " " + array[i].Substring(num); } } } return string.Join("\n", array); } internal static void Migrate(string file) { if (!File.Exists(file)) { return; } string text = File.ReadAllText(file); string text2 = Translate(text); if (!(text.Replace("\r\n", "\n") == text2)) { string text3 = file + ".before-english.bak"; if (!File.Exists(text3)) { File.Copy(file, text3); } File.WriteAllText(file, text2, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); } } } internal struct EquipState { public bool Track; public ItemData Right; public ItemData Left; public ItemData HiddenRight; public ItemData HiddenLeft; } internal struct ExtraEntry { public HolsterJoint Joint; public int Hash; public int Variant; public int Quality; } internal static class ExtraHolster { public const string ZdoKey = "ValheimHolster.Extra"; private static float _timer; private static string _lastWritten; private static readonly List<ExtraEntry> _entries = new List<ExtraEntry>(); private static readonly HashSet<HolsterJoint> _used = new HashSet<HolsterJoint>(); private static readonly HashSet<int> _unplacedLogged = new HashSet<int>(); public static void MarkDirty() { _timer = 0f; } public static void Tick() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { _lastWritten = null; return; } _timer -= Time.deltaTime; if (_timer > 0f) { return; } _timer = 0.25f; ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { return; } string text = ((HolsterConfig.Enabled.Value && HolsterConfig.ShowExtras.Value) ? Compute(localPlayer, preview: false) : ""); if (!(text == _lastWritten)) { _lastWritten = text; component.GetZDO().Set("ValheimHolster.Extra", text); if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogInfo((object)("Published extra holsters: " + Describe())); } } } public static string Compute(Player p, bool preview) { //IL_01fa: Unknown result type (might be due to invalid IL or missing references) _entries.Clear(); _used.Clear(); Inventory inventory = ((Humanoid)p).GetInventory(); if (inventory == null) { return ""; } ItemData val = (preview ? null : VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p)); ItemData val2 = (preview ? null : VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p)); bool flag = preview && HolsterConfig.MenuFreeHands.Value && MenuHelper.InMainMenu; if (val != null) { _used.Add(HolsterJoints.VanillaJoint(val.m_shared, rightHand: true)); } if (val2 != null) { _used.Add(HolsterJoints.VanillaJoint(val2.m_shared, rightHand: false)); } int value = HolsterConfig.MaxExtras.Value; foreach (ItemData item in HolsterLogic.PlacementOrder(inventory, p)) { if (_entries.Count >= value) { break; } if (!HolsterLogic.IsMarked(item) || !HolsterLogic.CanHolster(item) || (item.m_equipped && !flag) || item == val || item == val2) { continue; } int num = HolsterLogic.ItemHash(item); if (num == 0) { continue; } bool flag2 = false; foreach (HolsterJoint item2 in HolsterJoints.Candidates(item.m_shared)) { if (!_used.Contains(item2)) { _used.Add(item2); _entries.Add(new ExtraEntry { Joint = item2, Hash = num, Variant = item.m_variant, Quality = item.m_quality }); flag2 = true; break; } } if (!flag2 && HolsterConfig.DebugLog.Value && !_unplacedLogged.Contains(num)) { _unplacedLogged.Add(num); Plugin.Log.LogInfo((object)string.Format("No free attachment point for {0} (type={1}). In use: {2}", item.m_shared.m_name, item.m_shared.m_itemType, string.Join(",", _used))); } } StringBuilder stringBuilder = new StringBuilder("1|"); for (int i = 0; i < _entries.Count; i++) { if (i > 0) { stringBuilder.Append(';'); } ExtraEntry extraEntry = _entries[i]; stringBuilder.Append((int)extraEntry.Joint).Append(':').Append(extraEntry.Hash) .Append(':') .Append(extraEntry.Variant) .Append(':') .Append(extraEntry.Quality); } return stringBuilder.ToString(); } private static string Describe() { if (_entries.Count == 0) { return "(none)"; } StringBuilder stringBuilder = new StringBuilder(); foreach (ExtraEntry entry in _entries) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(entry.Hash) : null); stringBuilder.Append(((Object)(object)val != (Object)null) ? ((Object)val).name : entry.Hash.ToString()).Append('@').Append(entry.Joint) .Append(' '); } return stringBuilder.ToString(); } public static void Parse(string data, List<ExtraEntry> into) { into.Clear(); if (string.IsNullOrEmpty(data) || !data.StartsWith("1|")) { return; } string text = data.Substring(2); if (text.Length == 0) { return; } string[] array = text.Split(';'); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(':'); if (array2.Length >= 4 && int.TryParse(array2[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(array2[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { int.TryParse(array2[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3); int.TryParse(array2[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result4); if (result > 0 && result <= 10 && result2 != 0) { into.Add(new ExtraEntry { Joint = (HolsterJoint)result, Hash = result2, Variant = result3, Quality = result4 }); } } } } } public class ExtraHolsterVisual : MonoBehaviour { private VisEquipment _vis; private ZNetView _nview; private string _last; private int _lastRevision = -1; private float _timer; private readonly List<ExtraEntry> _entries = new List<ExtraEntry>(); private readonly List<GameObject> _instances = new List<GameObject>(); private Player _player; private bool _handsFreed; private void Awake() { _vis = ((Component)this).GetComponent<VisEquipment>(); _nview = ((Component)this).GetComponent<ZNetView>(); } private void OnDestroy() { Clear(); } private void Update() { _timer -= Time.deltaTime; if (_timer > 0f || (Object)(object)_vis == (Object)null) { return; } string text; if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { _timer = 0.5f; if ((Object)(object)_player == (Object)null) { _player = ((Component)this).GetComponent<Player>(); } if ((Object)(object)_player == (Object)null) { return; } bool flag = HolsterConfig.Enabled.Value && HolsterConfig.ShowInMenu.Value; text = (flag ? ExtraHolster.Compute(_player, preview: true) : ""); UpdateMenuHands(flag && HolsterConfig.MenuFreeHands.Value && MenuHelper.InMainMenu); } else { _timer = 0.2f; text = (HolsterConfig.Enabled.Value ? _nview.GetZDO().GetString("ValheimHolster.Extra", "") : ""); } bool flag2 = false; foreach (GameObject instance in _instances) { if ((Object)(object)instance == (Object)null) { flag2 = true; break; } } if (!(text == _last) || _lastRevision != HolsterConfig.VisualRevision || flag2) { _last = text; _lastRevision = HolsterConfig.VisualRevision; Rebuild(); } } private void UpdateMenuHands(bool free) { if (free) { _vis.SetRightItem(0, 0); _vis.SetLeftItem(0, 0, 0); _handsFreed = true; } else if (_handsFreed) { _handsFreed = false; VanillaAccess.SetupVisEquipment((Humanoid)(object)_player); } } private void Clear() { foreach (GameObject instance in _instances) { if ((Object)(object)instance != (Object)null) { Object.Destroy((Object)(object)instance); } } _instances.Clear(); } private void Rebuild() { Clear(); ExtraHolster.Parse(_last, _entries); if (_entries.Count == 0 || (Object)(object)ObjectDB.instance == (Object)null) { return; } foreach (ExtraEntry entry in _entries) { Transform val = HolsterJoints.Resolve(_vis, entry.Joint); if ((Object)(object)val == (Object)null) { if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogWarning((object)$"Attachment point {entry.Joint} does not exist on this character"); } continue; } GameObject val2 = VanillaAccess.AttachItem(_vis, entry.Hash, entry.Variant, entry.Quality, val); if ((Object)(object)val2 == (Object)null) { if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogWarning((object)$"Failed to render {entry.Hash} at {entry.Joint}"); } continue; } if (entry.Joint == HolsterJoint.HipRight || entry.Joint == HolsterJoint.HipLeft) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(entry.Hash); ItemDrop val3 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); bool knife = (Object)(object)val3 != (Object)null && HolsterLogic.IsKnife(val3.m_itemData.m_shared); HolsterLogic.ApplyHipOffset(val2.transform, entry.Joint == HolsterJoint.HipLeft, ((Component)_vis).transform, knife); } _instances.Add(val2); } } } public static class HolsterConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> DebugLog; public static ConfigEntry<KeyCode> MarkKey; public static ConfigEntry<bool> OnlyMarked; public static ConfigEntry<bool> HolsterOnSwap; public static ConfigEntry<bool> ShowExtras; public static ConfigEntry<int> MaxExtras; public static ConfigEntry<bool> CrossBigWeapons; public static ConfigEntry<bool> HolsterTools; public static ConfigEntry<bool> ShowTooltip; public static ConfigEntry<bool> KeepLoaded; public static ConfigEntry<bool> ReloadWhileRunning; public static ConfigEntry<float> ReloadSpeed; public static ConfigEntry<bool> ReloadNeedsAmmo; public static ConfigEntry<bool> SwapWithHideKey; public static ConfigEntry<bool> DoubleTapEmpty; public static ConfigEntry<float> DoubleTapWindow; public static ConfigEntry<bool> WheelEnabled; public static ConfigEntry<float> WheelHoldTime; public static ConfigEntry<bool> WheelOnlyMarked; public static ConfigEntry<float> WheelMouseSensitivity; public static ConfigEntry<bool> OneHandOnHip; public static ConfigEntry<bool> UseLeftHip; public static ConfigEntry<float> HipTiltBack; public static ConfigEntry<float> HipRollOut; public static ConfigEntry<float> HipUp; public static ConfigEntry<float> HipForward; public static ConfigEntry<float> HipInward; public static ConfigEntry<float> KnifeTilt; public static ConfigEntry<float> KnifeRoll; public static ConfigEntry<float> KnifeInward; public static ConfigEntry<float> KnifeUp; public static ConfigEntry<float> KnifeForward; public static ConfigEntry<Vector3> HipPositionOffset; public static ConfigEntry<Vector3> HipRotationOffset; public static ConfigEntry<bool> AutoEquipShield; public static ConfigEntry<bool> NoShieldWithAxe; public static ConfigEntry<bool> AutoUnequipShield; public static ConfigEntry<bool> LockHotbar; public static ConfigEntry<bool> ShowInMenu; public static ConfigEntry<bool> MenuFreeHands; public static int VisualRevision { get; private set; } public static void Bind(ConfigFile cfg) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Expected O, but got Unknown //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Expected O, but got Unknown //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Expected O, but got Unknown //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Expected O, but got Unknown //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Expected O, but got Unknown //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Expected O, but got Unknown //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Expected O, but got Unknown //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Expected O, but got Unknown //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Expected O, but got Unknown //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Expected O, but got Unknown //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Expected O, but got Unknown //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_0600: Expected O, but got Unknown Enabled = cfg.Bind<bool>("1 - General", "Enabled", true, "Enable or disable the mod."); DebugLog = cfg.Bind<bool>("1 - General", "Detailed logging", false, "Write marking and attachment details to LogOutput.log for troubleshooting."); MarkKey = cfg.Bind<KeyCode>("2 - Body", "Mark key", (KeyCode)104, "With the inventory open, hover over a weapon and press this key to mark or unmark it. Marked weapons stay on your body and appear in the wheel. Also works in Safe Pouch slots."); OnlyMarked = cfg.Bind<bool>("2 - Body", "Only marked weapons on body", true, "Enabled: only marked weapons stay on your body. Disabled: any weapon you swap away from can be holstered."); HolsterOnSwap = cfg.Bind<bool>("2 - Body", "Holster when switching weapons", true, "When equipping another weapon, holster the previous weapon instead of making it disappear."); ShowExtras = cfg.Bind<bool>("2 - Body", "Show all marked weapons", true, "Show all marked weapons on your body, beyond the two supported by the base game."); MaxExtras = cfg.Bind<int>("2 - Body", "Maximum extra weapons", 10, new ConfigDescription("Maximum number of extra marked weapons shown on your body, one per available attachment point.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>())); CrossBigWeapons = cfg.Bind<bool>("2 - Body", "Cross large weapons", true, "Two large weapons sharing a position, such as staves, greatswords, atgeirs or bows, cross in an X on your back."); HolsterTools = cfg.Bind<bool>("2 - Body", "Holster tools", false, "Allow hammers, hoes, cultivators, pickaxes, fishing rods and torches on your body. Disabled: tools are never holstered."); ShowTooltip = cfg.Bind<bool>("2 - Body", "Show mark in tooltip", true, "Show whether a weapon is marked in its tooltip."); SwapWithHideKey = cfg.Bind<bool>("3 - R key", "Tap to switch weapons", true, "Tap R to switch to the weapon you were using previously."); DoubleTapEmpty = cfg.Bind<bool>("3 - R key", "Double tap to empty hands", true, "Double tap R to empty your hands; marked weapons are holstered. A single tap waits briefly for a possible second tap."); DoubleTapWindow = cfg.Bind<float>("3 - R key", "Double tap interval", 0.28f, new ConfigDescription("Maximum time between two taps, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.15f, 0.6f), Array.Empty<object>())); WheelEnabled = cfg.Bind<bool>("3 - R key", "Hold to open weapon wheel", true, "Hold R to open the weapon wheel. Move the mouse sideways or scroll to rotate, release R to equip, or right-click to cancel."); WheelHoldTime = cfg.Bind<float>("3 - R key", "Wheel hold time", 0.25f, new ConfigDescription("Time to hold R before opening the wheel, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); WheelOnlyMarked = cfg.Bind<bool>("3 - R key", "Only marked weapons in wheel", true, "Enabled: show marked and currently holstered weapons. Disabled: consider all eligible inventory weapons. Includes Safe Pouch weapons."); WheelMouseSensitivity = cfg.Bind<float>("3 - R key", "Wheel mouse sensitivity", 3f, new ConfigDescription("Mouse sensitivity multiplier for rotating the weapon wheel. 1 = original sensitivity; 3 = one-third of the original swipe distance per weapon. Higher values require less mouse movement.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>())); OneHandOnHip = cfg.Bind<bool>("4 - Hips", "One-handed weapons on hips", true, "Place swords, axes, maces and knives on the hips instead of the back. Spears are excluded."); UseLeftHip = cfg.Bind<bool>("4 - Hips", "Use both hips", true, "Place a second marked one-handed weapon on the opposite hip."); HipTiltBack = cfg.Bind<float>("4 - Hips", "Backward tilt", 35f, new ConfigDescription("Tilt in degrees. Positive angles point the tip backward and the handle forward; zero is straight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-90f, 90f), Array.Empty<object>())); HipRollOut = cfg.Bind<float>("4 - Hips", "Outward rotation", 0f, new ConfigDescription("Sideways rotation in degrees. Positive angles point the tip away from the leg, mirrored on each side; zero is straight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-45f, 45f), Array.Empty<object>())); HipUp = cfg.Bind<float>("4 - Hips", "Height", 0.08f, new ConfigDescription("Move the hip weapon upward with positive values or downward with negative values, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.3f, 0.3f), Array.Empty<object>())); HipForward = cfg.Bind<float>("4 - Hips", "Forward offset", 0.06f, new ConfigDescription("Move the hip weapon forward with positive values or backward with negative values, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.3f, 0.3f), Array.Empty<object>())); HipInward = cfg.Bind<float>("4 - Hips", "Inward offset", 0.05f, new ConfigDescription("Move the hip weapon closer to the body with positive values or farther away with negative values, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.3f, 0.3f), Array.Empty<object>())); KnifeTilt = cfg.Bind<float>("4 - Hips", "Knife - backward tilt", 10f, new ConfigDescription("Knife tilt in degrees. Positive angles point the tip backward.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-90f, 90f), Array.Empty<object>())); KnifeRoll = cfg.Bind<float>("4 - Hips", "Knife - outward rotation", 0f, new ConfigDescription("Knife sideways rotation in degrees. Positive angles point the tip away from the leg.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-45f, 45f), Array.Empty<object>())); KnifeInward = cfg.Bind<float>("4 - Hips", "Knife - inward offset", 0.03f, new ConfigDescription("Move the knife closer to the leg, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.3f, 0.3f), Array.Empty<object>())); KnifeUp = cfg.Bind<float>("4 - Hips", "Knife - height", 0.06f, new ConfigDescription("Move the knife upward with positive values or downward with negative values, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.3f, 0.3f), Array.Empty<object>())); KnifeForward = cfg.Bind<float>("4 - Hips", "Knife - forward offset", 0f, new ConfigDescription("Move the knife forward with positive values or backward with negative values, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.3f, 0.3f), Array.Empty<object>())); HipPositionOffset = cfg.Bind<Vector3>("4 - Hips", "Position adjustment", Vector3.zero, "Fine position adjustment, mirrored on the opposite side."); HipRotationOffset = cfg.Bind<Vector3>("4 - Hips", "Rotation adjustment", Vector3.zero, "Fine rotation adjustment, in degrees."); AutoEquipShield = cfg.Bind<bool>("5 - Shield", "Auto-equip shield with one-handed weapon", true, "When equipping a one-handed weapon with an empty left hand, equip the strongest shield from the inventory or Safe Pouch."); NoShieldWithAxe = cfg.Bind<bool>("5 - Shield", "Exclude axes", true, "Do not automatically equip a shield with an axe, avoiding the movement penalty while chopping trees."); AutoUnequipShield = cfg.Bind<bool>("5 - Shield", "Unequip shield with weapon", true, "When the one-handed weapon leaves your hand, remove the shield too. Marked shields are holstered on your back."); LockHotbar = cfg.Bind<bool>("6 - Hotbar", "Hotbar numbers only equip", false, "Pressing the hotbar number of a weapon already in your hand keeps it equipped."); ShowInMenu = cfg.Bind<bool>("7 - Menu", "Show weapons in main menu", true, "Show marked weapons on menu characters, including the preview and ValheimMenu campfire."); MenuFreeHands = cfg.Bind<bool>("7 - Menu", "Empty hands in main menu", true, "Remove equipped weapons from the hands in the menu. Marked weapons appear holstered."); KeepLoaded = cfg.Bind<bool>("8 - Reloading", "Keep loaded when holstered", true, "A loaded crossbow or other reloadable weapon stays loaded when holstered and drawn again."); ReloadWhileRunning = cfg.Bind<bool>("8 - Reloading", "Reload while running", true, "Allow running during reload without canceling it or slowing to a walk."); ReloadNeedsAmmo = cfg.Bind<bool>("8 - Reloading", "Require ammunition to reload", true, "Only start reloading a crossbow when matching bolts or ammunition are available."); ReloadSpeed = cfg.Bind<float>("8 - Reloading", "Reload speed", 1f, new ConfigDescription("Reload speed multiplier: 1 is normal, 2 is twice as fast, and 0.5 is half speed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>())); Enabled.SettingChanged += delegate { Visual(); }; OnlyMarked.SettingChanged += delegate { Visual(); }; ShowExtras.SettingChanged += delegate { Visual(); }; MaxExtras.SettingChanged += delegate { Visual(); }; CrossBigWeapons.SettingChanged += delegate { Visual(); }; HolsterTools.SettingChanged += delegate { Visual(); }; OneHandOnHip.SettingChanged += delegate { Visual(); }; UseLeftHip.SettingChanged += delegate { Visual(); }; HipTiltBack.SettingChanged += delegate { Visual(); }; HipRollOut.SettingChanged += delegate { Visual(); }; HipUp.SettingChanged += delegate { Visual(); }; HipForward.SettingChanged += delegate { Visual(); }; HipInward.SettingChanged += delegate { Visual(); }; KnifeTilt.SettingChanged += delegate { Visual(); }; KnifeRoll.SettingChanged += delegate { Visual(); }; KnifeInward.SettingChanged += delegate { Visual(); }; KnifeUp.SettingChanged += delegate { Visual(); }; KnifeForward.SettingChanged += delegate { Visual(); }; HipPositionOffset.SettingChanged += delegate { Visual(); }; HipRotationOffset.SettingChanged += delegate { Visual(); }; ShowInMenu.SettingChanged += delegate { Visual(); }; MenuFreeHands.SettingChanged += delegate { Visual(); }; static void Visual() { VisualRevision++; VanillaAccess.RefreshAllVisuals(); ExtraHolster.MarkDirty(); } } } public enum HolsterJoint { None, HipRight, HipLeft, BackMelee, BackTwoHand, BackAtgeir, BackBow, BackShield, BackTwoHandCross, BackAtgeirCross, BackBowCross } internal static class HolsterJoints { private const string HipLeftName = "ValheimHolster_HipLeft"; private const string TwoHandCrossName = "ValheimHolster_TwoHandCross"; private const string AtgeirCrossName = "ValheimHolster_AtgeirCross"; private const string BowCrossName = "ValheimHolster_BowCross"; public const HolsterJoint MaxJoint = HolsterJoint.BackBowCross; private const float CrossBackOffset = 0.04f; public static bool IsDualWeapon(SharedData s) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if (s != null && (int)s.m_itemType != 5) { return (int)AttachType(s) == 5; } return false; } public static bool IsStaff(SharedData s) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if (s != null) { if ((int)s.m_skillType != 9) { return (int)s.m_skillType == 10; } return true; } return false; } public static ItemType AttachType(SharedData s) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if ((int)s.m_attachOverride == 0) { return s.m_itemType; } return s.m_attachOverride; } public static HolsterJoint VanillaJoint(SharedData s, bool rightHand) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected I4, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected I4, but got Unknown if (s == null) { return HolsterJoint.None; } if (HolsterConfig.OneHandOnHip.Value && HolsterLogic.GoesOnHip(s)) { return HolsterJoint.HipRight; } ItemType val = AttachType(s); switch (val - 3) { default: switch (val - 14) { case 1: if (!rightHand) { return HolsterJoint.HipRight; } return HolsterJoint.BackMelee; case 0: case 8: return HolsterJoint.BackTwoHand; case 5: return HolsterJoint.HipRight; case 6: return HolsterJoint.BackAtgeir; default: return HolsterJoint.None; } case 0: return HolsterJoint.BackMelee; case 1: return HolsterJoint.BackBow; case 2: return HolsterJoint.BackShield; } } public static IEnumerable<HolsterJoint> Candidates(SharedData s) { bool cross = HolsterConfig.CrossBigWeapons.Value; if (IsDualWeapon(s)) { yield return HolsterJoint.BackShield; yield break; } if (IsStaff(s)) { yield return HolsterJoint.BackAtgeir; if (cross) { yield return HolsterJoint.BackAtgeirCross; } yield return HolsterJoint.BackTwoHand; if (cross) { yield return HolsterJoint.BackTwoHandCross; } yield return HolsterJoint.BackBow; if (cross) { yield return HolsterJoint.BackBowCross; } yield break; } HolsterJoint first = VanillaJoint(s, rightHand: true); if (first == HolsterJoint.None) { yield break; } yield return first; switch (first) { case HolsterJoint.HipRight: if (HolsterLogic.GoesOnHip(s)) { if (HolsterConfig.UseLeftHip.Value) { yield return HolsterJoint.HipLeft; } yield return HolsterJoint.BackMelee; } break; case HolsterJoint.BackMelee: yield return HolsterJoint.BackAtgeir; break; case HolsterJoint.BackTwoHand: if (cross) { yield return HolsterJoint.BackTwoHandCross; } yield return HolsterJoint.BackAtgeir; if (cross) { yield return HolsterJoint.BackAtgeirCross; } break; case HolsterJoint.BackBow: if (cross) { yield return HolsterJoint.BackBowCross; } break; case HolsterJoint.BackAtgeir: if (cross) { yield return HolsterJoint.BackAtgeirCross; } yield return HolsterJoint.BackTwoHand; if (cross) { yield return HolsterJoint.BackTwoHandCross; } break; } } public static Transform Resolve(VisEquipment vis, HolsterJoint joint) { return (Transform)(joint switch { HolsterJoint.HipRight => vis.m_backTool, HolsterJoint.HipLeft => GetOrCreateMirror(vis, vis.m_backTool, "ValheimHolster_HipLeft", 0f), HolsterJoint.BackTwoHandCross => GetOrCreateMirror(vis, vis.m_backTwohandedMelee, "ValheimHolster_TwoHandCross", 0.04f), HolsterJoint.BackAtgeirCross => GetOrCreateMirror(vis, vis.m_backAtgeir, "ValheimHolster_AtgeirCross", 0.04f), HolsterJoint.BackBowCross => GetOrCreateMirror(vis, vis.m_backBow, "ValheimHolster_BowCross", 0.04f), HolsterJoint.BackMelee => vis.m_backMelee, HolsterJoint.BackTwoHand => vis.m_backTwohandedMelee, HolsterJoint.BackAtgeir => vis.m_backAtgeir, HolsterJoint.BackBow => vis.m_backBow, HolsterJoint.BackShield => vis.m_backShield, _ => null, }); } private static Transform GetOrCreateMirror(VisEquipment vis, Transform source, string name, float backOffset) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null || (Object)(object)source.parent == (Object)null) { return null; } Transform parent = source.parent; Transform val = parent.Find(name); if ((Object)(object)val != (Object)null) { return val; } Vector3 val2 = parent.InverseTransformDirection(((Component)vis).transform.right); int num = 0; float num2 = Mathf.Abs(val2.x); if (Mathf.Abs(val2.y) > num2) { num = 1; num2 = Mathf.Abs(val2.y); } if (Mathf.Abs(val2.z) > num2) { num = 2; } Vector3 val3 = source.localPosition; Quaternion localRotation = source.localRotation; switch (num) { case 0: val3.x = 0f - val3.x; ((Quaternion)(ref localRotation))..ctor(localRotation.x, 0f - localRotation.y, 0f - localRotation.z, localRotation.w); break; case 1: val3.y = 0f - val3.y; ((Quaternion)(ref localRotation))..ctor(0f - localRotation.x, localRotation.y, 0f - localRotation.z, localRotation.w); break; default: val3.z = 0f - val3.z; ((Quaternion)(ref localRotation))..ctor(0f - localRotation.x, 0f - localRotation.y, localRotation.z, localRotation.w); break; } if (backOffset != 0f) { val3 += parent.InverseTransformDirection(-((Component)vis).transform.forward) * backOffset / Mathf.Max(parent.lossyScale.x, 0.0001f); } Transform transform = new GameObject(name).transform; transform.SetParent(parent, false); transform.localPosition = val3; transform.localRotation = localRotation; transform.localScale = source.localScale; return transform; } } internal static class HolsterLogic { public static bool Busy; public static bool HideKeyThisFrame; public static int EquipDepth; public static bool ModCall; public static bool SuppressVanillaHide; public static ItemData LastRight; public static ItemData LastLeft; public const string CustomDataKey = "ValheimHolster.Marked"; private static readonly List<Vector3> _corners = new List<Vector3>(8); public static bool IsLocal(Humanoid h) { if ((Object)(object)h != (Object)null) { return (Object)(object)h == (Object)(object)Player.m_localPlayer; } return false; } public static bool IsActive(Humanoid h) { if (HolsterConfig.Enabled.Value) { return IsLocal(h); } return false; } public static bool IsTool(ItemData item) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 SharedData val = item?.m_shared; if (val == null) { return false; } ItemType itemType = val.m_itemType; if ((int)itemType == 15 || (int)itemType == 19) { return true; } if ((int)val.m_skillType != 12) { return (int)val.m_skillType == 104; } return true; } public static bool IsHandItem(ItemData item) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_001e: 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_0022: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 SharedData val = item?.m_shared; if (val == null) { return false; } ItemType itemType = val.m_itemType; if ((int)itemType <= 15) { if (itemType - 3 <= 2 || itemType - 14 <= 1) { goto IL_0037; } } else if ((int)itemType == 19 || (int)itemType == 22) { goto IL_0037; } return false; IL_0037: return true; } public static bool CanHolster(ItemData item) { if (!IsHandItem(item)) { return false; } if (IsTool(item)) { return HolsterConfig.HolsterTools.Value; } if (HolsterConfig.OnlyMarked.Value && !IsMarked(item)) { return false; } return true; } public static bool IsOneHandWeapon(ItemData item) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (item?.m_shared != null && (int)item.m_shared.m_itemType == 3) { return !IsTool(item); } return false; } public static bool IsShield(ItemData item) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (item?.m_shared != null) { return (int)item.m_shared.m_itemType == 5; } return false; } public static bool GoesOnHip(SharedData s) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 if (s != null && (int)s.m_itemType == 3 && (int)s.m_skillType != 5 && (int)s.m_skillType != 12) { return (int)s.m_skillType != 104; } return false; } public static bool StillHolsterable(Humanoid h, ItemData item) { if (item == null || item.m_equipped) { return false; } if (!CanHolster(item)) { return false; } return SafePouchCompat.Contains(h, item); } public static void RememberLast(Humanoid h, ItemData right, ItemData left) { if (IsLocal(h)) { if (right != null && IsHandItem(right) && !IsTool(right)) { LastRight = right; } if (left != null && IsHandItem(left) && !IsTool(left)) { LastLeft = left; } else if (right != null && IsHandItem(right) && !IsTool(right)) { LastLeft = null; } } } private static bool UsableLast(Humanoid h, ItemData item) { if (item == null || item.m_equipped) { return false; } return SafePouchCompat.Contains(h, item); } public static bool SwapWithHolster(Humanoid h) { ItemData val = VanillaAccess.RightItem.Invoke(h); ItemData val2 = VanillaAccess.LeftItem.Invoke(h); ItemData val3 = VanillaAccess.HiddenRightItem.Invoke(h); ItemData val4 = VanillaAccess.HiddenLeftItem.Invoke(h); if (!StillHolsterable(h, val3)) { val3 = null; } if (!StillHolsterable(h, val4)) { val4 = null; } if (val3 == null && val4 == null) { val3 = (UsableLast(h, LastRight) ? LastRight : null); val4 = (UsableLast(h, LastLeft) ? LastLeft : null); if (val3 == null && val4 == null) { return false; } } Busy = true; try { if (val != null) { h.UnequipItem(val, false); } if (val2 != null) { h.UnequipItem(val2, false); } VanillaAccess.HiddenRightItem.Invoke(h) = null; VanillaAccess.HiddenLeftItem.Invoke(h) = null; if (val4 != null) { h.EquipItem(val4, true); } if (val3 != null) { h.EquipItem(val3, true); } VanillaAccess.HiddenRightItem.Invoke(h) = (StillHolsterable(h, val) ? val : null); VanillaAccess.HiddenLeftItem.Invoke(h) = (StillHolsterable(h, val2) ? val2 : null); if (val != null || val2 != null) { LastRight = val; LastLeft = val2; } VanillaAccess.SetupVisEquipment(h); VanillaAccess.TriggerHolsterAnim(h); } finally { Busy = false; } return true; } public static ItemData FindBestShield(Humanoid h) { Inventory inventory = h.GetInventory(); if (inventory == null) { return null; } ItemData result = null; float num = float.MinValue; foreach (ItemData item in SafePouchCompat.AllItems(inventory, (Player)(object)((h is Player) ? h : null))) { if (IsShield(item) && (!item.m_shared.m_useDurability || !(item.m_durability <= 0f))) { float baseBlockPower = item.GetBaseBlockPower(item.m_quality); if (baseBlockPower > num) { num = baseBlockPower; result = item; } } } return result; } public static void TryAutoEquipShield(Humanoid h, ItemData weapon) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 if (!HolsterConfig.AutoEquipShield.Value || !IsOneHandWeapon(weapon) || VanillaAccess.LeftItem.Invoke(h) != null || (HolsterConfig.NoShieldWithAxe.Value && (int)weapon.m_shared.m_skillType == 7)) { return; } ItemData val = FindBestShield(h); if (val == null || val.m_equipped) { return; } ItemData val2 = VanillaAccess.HiddenRightItem.Invoke(h); ItemData val3 = VanillaAccess.HiddenLeftItem.Invoke(h); Busy = true; try { if (val3 == val) { val3 = null; } h.EquipItem(val, false); VanillaAccess.HiddenRightItem.Invoke(h) = (StillHolsterable(h, val2) ? val2 : null); VanillaAccess.HiddenLeftItem.Invoke(h) = (StillHolsterable(h, val3) ? val3 : null); VanillaAccess.SetupVisEquipment(h); } finally { Busy = false; } } public static void TryAutoUnequipShield(Humanoid h) { if (!HolsterConfig.AutoUnequipShield.Value) { return; } ItemData val = VanillaAccess.LeftItem.Invoke(h); if (!IsShield(val) || IsOneHandWeapon(VanillaAccess.RightItem.Invoke(h))) { return; } Busy = true; try { h.UnequipItem(val, false); if (StillHolsterable(h, val)) { VanillaAccess.HiddenLeftItem.Invoke(h) = val; VanillaAccess.SetupVisEquipment(h); } } finally { Busy = false; } } private static bool TextBlocked() { if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return true; } if (Console.IsVisible()) { return true; } if (TextInput.IsVisible()) { return true; } if (Menu.IsVisible()) { return true; } return false; } public static void HandleHotkeys() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //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) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && HolsterConfig.Enabled.Value) { KeyCode value = HolsterConfig.MarkKey.Value; if ((int)value != 0 && InventoryGui.IsVisible() && !TextBlocked() && UnityInput.Current.GetKeyDown(value)) { ToggleMark(localPlayer); } } } public static bool IsMarked(ItemData item) { if (item?.m_customData != null) { return item.m_customData.ContainsKey("ValheimHolster.Marked"); } return false; } public static void SetMarked(ItemData item, bool marked) { if (item != null) { if (item.m_customData == null) { item.m_customData = new Dictionary<string, string>(); } if (marked) { item.m_customData["ValheimHolster.Marked"] = "1"; } else { item.m_customData.Remove("ValheimHolster.Marked"); } } } public static int ItemHash(ItemData item) { if (!((Object)(object)item?.m_dropPrefab != (Object)null)) { return 0; } return StringExtensionMethods.GetStableHashCode(((Object)item.m_dropPrefab).name); } public static IEnumerable<ItemData> SortedInventory(Inventory inv, Player owner = null) { return from i in SafePouchCompat.AllItems(inv, owner) where i != null orderby i.m_gridPos.y, i.m_gridPos.x select i; } public static IEnumerable<ItemData> PlacementOrder(Inventory inv, Player owner = null) { return from i in SortedInventory(inv, owner) orderby HolsterJoints.IsDualWeapon(i.m_shared) ? 1 : 0 select i; } public static List<ItemData> WheelItems(Player p) { List<ItemData> list = new List<ItemData>(); Inventory inventory = ((Humanoid)p).GetInventory(); if (inventory == null) { return list; } ItemData val = VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p); ItemData val2 = VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p); foreach (ItemData item in SortedInventory(inventory)) { if (item.m_equipped || !CanHolster(item) || IsShield(item)) { continue; } bool flag = item == val || item == val2; if (!HolsterConfig.WheelOnlyMarked.Value || IsMarked(item) || flag) { list.Add(item); if (list.Count >= 12) { break; } } } return list; } public static void TapHide(Player p) { ModCall = true; bool hideKeyThisFrame = HideKeyThisFrame; HideKeyThisFrame = true; try { if (VanillaAccess.RightItem.Invoke((Humanoid)(object)p) != null || VanillaAccess.LeftItem.Invoke((Humanoid)(object)p) != null) { if (!((Character)p).InAttack() && !((Character)p).InDodge()) { ((Humanoid)p).HideHandItems(false, true); } } else { if ((((Character)p).IsSwimming() && !((Character)p).IsOnGround()) || ((Character)p).InDodge()) { return; } if (VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p) != null || VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p) != null) { VanillaAccess.ShowHandItems((Humanoid)(object)p); return; } ItemData val = (UsableLast((Humanoid)(object)p, LastLeft) ? LastLeft : null); ItemData val2 = (UsableLast((Humanoid)(object)p, LastRight) ? LastRight : null); if (val != null) { ((Humanoid)p).EquipItem(val, true); } if (val2 != null) { ((Humanoid)p).EquipItem(val2, true); } } } finally { ModCall = false; HideKeyThisFrame = hideKeyThisFrame; } } public static void ApplyHipOffset(Transform t, bool left, Transform character, bool knife = false) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)character == (Object)null)) { float num = (knife ? HolsterConfig.KnifeTilt.Value : HolsterConfig.HipTiltBack.Value); float num2 = (knife ? HolsterConfig.KnifeRoll.Value : HolsterConfig.HipRollOut.Value); float num3 = (knife ? HolsterConfig.KnifeUp.Value : HolsterConfig.HipUp.Value); float num4 = (knife ? HolsterConfig.KnifeForward.Value : HolsterConfig.HipForward.Value); float num5 = (knife ? HolsterConfig.KnifeInward.Value : HolsterConfig.HipInward.Value); float num6 = (left ? 1f : (-1f)); Vector3 right = character.right; Vector3 up = character.up; Vector3 forward = character.forward; Quaternion val = Quaternion.AngleAxis(num2 * num6, forward) * Quaternion.AngleAxis(num, right); Vector3 val2 = val * -up; Vector3 val3 = val * forward; if (TryGetBladeAxes(t, out var blade, out var edge)) { Quaternion val4 = Quaternion.LookRotation(val2, val3); Quaternion val5 = Quaternion.LookRotation(blade, edge); t.rotation = val4 * Quaternion.Inverse(val5); } else { t.rotation = val * t.rotation; } Vector3 value = HolsterConfig.HipPositionOffset.Value; Vector3 value2 = HolsterConfig.HipRotationOffset.Value; if (left) { value.x = 0f - value.x; value2.y = 0f - value2.y; value2.z = 0f - value2.z; } t.rotation *= Quaternion.Euler(value2); float num7 = Mathf.Abs(character.lossyScale.x); t.position += (up * num3 + forward * num4 - num6 * right * num5 + right * value.x + up * value.y + forward * value.z) * num7; } } private static bool TryGetBladeAxes(Transform root, out Vector3 blade, out Vector3 edge) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) blade = Vector3.zero; edge = Vector3.zero; bool flag = false; Vector3 val = Vector3.positiveInfinity; Vector3 val2 = Vector3.negativeInfinity; Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren) { Mesh val4 = null; if (val3 is MeshRenderer) { MeshFilter component = ((Component)val3).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null) { val4 = component.sharedMesh; } } else { SkinnedMeshRenderer val5 = (SkinnedMeshRenderer)(object)((val3 is SkinnedMeshRenderer) ? val3 : null); if (val5 != null) { val4 = val5.sharedMesh; } } if (!((Object)(object)val4 == (Object)null)) { Bounds bounds = val4.bounds; Matrix4x4 val6 = root.worldToLocalMatrix * ((Component)val3).transform.localToWorldMatrix; for (int j = 0; j < 8; j++) { Vector3 val7 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))); Vector3 val8 = ((Matrix4x4)(ref val6)).MultiplyPoint3x4(val7); val = Vector3.Min(val, val8); val2 = Vector3.Max(val2, val8); flag = true; } } } if (!flag) { return false; } Vector3 val9 = val2 - val; int num = 0; if (val9.y > ((Vector3)(ref val9))[num]) { num = 1; } if (val9.z > ((Vector3)(ref val9))[num]) { num = 2; } int num2 = ((num == 0) ? 1 : 0); for (int k = 0; k < 3; k++) { if (k != num && ((Vector3)(ref val9))[k] > ((Vector3)(ref val9))[num2]) { num2 = k; } } if (((Vector3)(ref val9))[num] < 0.01f) { return false; } float num3 = ((Mathf.Abs(((Vector3)(ref val2))[num]) >= Mathf.Abs(((Vector3)(ref val))[num])) ? 1f : (-1f)); blade = Vector3.zero; ((Vector3)(ref blade))[num] = num3; edge = Vector3.zero; ((Vector3)(ref edge))[num2] = 1f; return true; } public static bool IsKnife(SharedData s) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (s != null) { return (int)s.m_skillType == 2; } return false; } public static void EmptyHands(Player p) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown if (((Character)p).InAttack() || ((Character)p).InDodge()) { return; } ItemData val = VanillaAccess.RightItem.Invoke((Humanoid)(object)p); ItemData val2 = VanillaAccess.LeftItem.Invoke((Humanoid)(object)p); if (val == null && val2 == null) { return; } ItemData val3 = VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p); ItemData val4 = VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p); LastRight = val; LastLeft = val2; Busy = true; try { if (val != null) { ((Humanoid)p).UnequipItem(val, false); } if (val2 != null) { ((Humanoid)p).UnequipItem(val2, false); } ref ItemData reference = ref VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p); object obj = ((!StillHolsterable((Humanoid)(object)p, val)) ? (StillHolsterable((Humanoid)(object)p, val3) ? val3 : null) : val); reference = (ItemData)obj; ref ItemData reference2 = ref VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p); object obj2 = ((!StillHolsterable((Humanoid)(object)p, val2)) ? (StillHolsterable((Humanoid)(object)p, val4) ? val4 : null) : val2); reference2 = (ItemData)obj2; VanillaAccess.SetupVisEquipment((Humanoid)(object)p); VanillaAccess.TriggerHolsterAnim((Humanoid)(object)p); } finally { Busy = false; } ExtraHolster.MarkDirty(); } private static void ToggleMark(Player player) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) ItemData hoveredPlayerItem = VanillaAccess.GetHoveredPlayerItem(); if (hoveredPlayerItem == null) { if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogInfo((object)("Mark: no item under the mouse (" + HoverTracker.Describe() + ")")); } return; } string text = ((Localization.instance != null) ? Localization.instance.Localize(hoveredPlayerItem.m_shared.m_name) : hoveredPlayerItem.m_shared.m_name); if (!IsHandItem(hoveredPlayerItem)) { ((Character)player).Message((MessageType)1, "This item cannot be holstered.", 0, (Sprite)null, false); return; } if (IsTool(hoveredPlayerItem) && !HolsterConfig.HolsterTools.Value) { ((Character)player).Message((MessageType)1, "Tool holstering is disabled.", 0, (Sprite)null, false); return; } bool flag = !IsMarked(hoveredPlayerItem); SetMarked(hoveredPlayerItem, flag); SafePouchCompat.StoreMark(hoveredPlayerItem); if (!flag && HolsterConfig.OnlyMarked.Value) { bool flag2 = false; if (VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)player) == hoveredPlayerItem) { VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)player) = null; flag2 = true; } if (VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)player) == hoveredPlayerItem) { VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)player) = null; flag2 = true; } if (flag2) { VanillaAccess.SetupVisEquipment((Humanoid)(object)player); } } if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogInfo((object)string.Format("Mark: {0} type={1} attach={2} skill={3} -> {4}", hoveredPlayerItem.m_shared.m_name, hoveredPlayerItem.m_shared.m_itemType, hoveredPlayerItem.m_shared.m_attachOverride, hoveredPlayerItem.m_shared.m_skillType, flag ? "marked" : "unmarked")); } ((Character)player).Message((MessageType)1, flag ? (text + ": marked for holstering") : (text + ": no longer marked for holstering"), 0, (Sprite)null, false); ExtraHolster.MarkDirty(); } } internal static class HolsterWheel { private class Slot { public RectTransform Root; public CanvasGroup Group; public Image Glow; public Image Base; public Image Rim; public Image Icon; public float Pop; public bool Holstered; } private const float RingRadius = 175f; private const float SlotSize = 84f; private const float IconSize = 58f; private const float MouseStep = 55f; private const float SpinSmooth = 0.075f; private const float FadeInTime = 0.14f; private const float FadeOutTime = 0.1f; private const float SlotInTime = 0.22f; private const float SlotStagger = 0.03f; private const float LabelPopTime = 0.16f; private const float SelectSpring = 18f; private static readonly Color Gold = new Color(1f, 0.78f, 0.38f, 1f); private static readonly Color BgCenter = new Color(0f, 0f, 0f, 0.92f); private static readonly Color PlateColor = new Color(0.03f, 0.025f, 0.02f, 0.88f); private static readonly Color TrackColor = new Color(1f, 0.82f, 0.5f, 0.28f); private static readonly Color SlotBase = new Color(0.03f, 0.025f, 0.02f, 0.95f); private static readonly Color SlotBaseSelected = new Color(0.2f, 0.12f, 0.04f, 0.97f); private static readonly Color RimIdle = new Color(1f, 0.85f, 0.6f, 0.35f); private static readonly Color RimHolstered = new Color(0.55f, 0.8f, 1f, 0.6f); private static readonly Color LabelColor = new Color(1f, 0.92f, 0.75f, 1f); private static readonly Color SubLabelColor = new Color(0.8f, 0.74f, 0.62f, 0.85f); private static float _holdStart; private static float _pendingTapAt = -1f; private static bool _secondPress; private static float _openedAt; private static float _closingAt = -1f; private static float _labelChangedAt; private static List<ItemData> _items = new List<ItemData>(); private static int _targetIndex; private static float _currentIndex; private static float _spinVelocity; private static float _mouseAccum; private static int _shownSelected = -1; private static GameObject _root; private static CanvasGroup _group; private static RectTransform _content; private static RectTransform _ring; private static RectTransform _pointer; private static TMP_Text _label; private static TMP_Text _subLabel; private static readonly List<Slot> _slots = new List<Slot>(); private static TMP_FontAsset _font; public static bool Holding { get; private set; } public static bool IsOpen { get; private set; } private static int Selected { get { if (_items.Count != 0) { return Mod(_targetIndex, _items.Count); } return -1; } } private static float Dt => Time.unscaledDeltaTime; private static float Now => Time.unscaledTime; private static int Mod(int a, int n) { return (a % n + n) % n; } public static void OnHideDown() { Holding = true; _holdStart = Now; _secondPress = _pendingTapAt >= 0f && Now - _pendingTapAt <= HolsterConfig.DoubleTapWindow.Value; } public static void Tick() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || InventoryGui.IsVisible() || Menu.IsVisible()) { Holding = false; _pendingTapAt = -1f; _secondPress = false; Close(instant: true); return; } if (IsOpen || _closingAt >= 0f) { Animate(); } if (!Holding && _pendingTapAt >= 0f && Now - _pendingTapAt > HolsterConfig.DoubleTapWindow.Value) { _pendingTapAt = -1f; HolsterLogic.TapHide(localPlayer); } if (!Holding) { return; } if (ZInput.GetButton("Hide")) { if (!IsOpen && !_secondPress && Now - _holdStart >= HolsterConfig.WheelHoldTime.Value) { _items = HolsterLogic.WheelItems(localPlayer); if (_items.Count > 0) { Open(localPlayer); } } if (IsOpen) { if (UnityInput.Current.GetMouseButtonDown(1)) { Holding = false; Close(instant: false); } else { ReadSpinInput(); } } return; } Holding = false; if (IsOpen) { int selected = Selected; ItemData val = ((selected >= 0) ? _items[selected] : null); Close(instant: false); if (val != null && !val.m_equipped && !((Character)localPlayer).InAttack() && !((Character)localPlayer).InDodge()) { ((Humanoid)localPlayer).EquipItem(val, true); } } else if (_secondPress) { _secondPress = false; _pendingTapAt = -1f; HolsterLogic.EmptyHands(localPlayer); } else if (HolsterConfig.DoubleTapEmpty.Value && (VanillaAccess.RightItem.Invoke((Humanoid)(object)localPlayer) != null || VanillaAccess.LeftItem.Invoke((Humanoid)(object)localPlayer) != null)) { _pendingTapAt = Now; } else { HolsterLogic.TapHide(localPlayer); } } private static void ReadSpinInput() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (_items.Count > 1) { _mouseAccum += ZInput.GetMouseDelta().x * HolsterConfig.WheelMouseSensitivity.Value; while (_mouseAccum >= 55f) { _targetIndex++; _mouseAccum -= 55f; } while (_mouseAccum <= -55f) { _targetIndex--; _mouseAccum += 55f; } float y = UnityInput.Current.mouseScrollDelta.y; if (y > 0.01f) { _targetIndex--; } else if (y < -0.01f) { _targetIndex++; } } } private static void Open(Player p) { EnsureUI(); IsOpen = true; _closingAt = -1f; _openedAt = Now; _mouseAccum = 0f; _spinVelocity = 0f; _shownSelected = -1; ItemData val = VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p); ItemData val2 = VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p); _targetIndex = 0; for (int i = 0; i < _items.Count; i++) { if (_items[i] == val || _items[i] == val2) { _targetIndex = i; break; } } _currentIndex = (float)_targetIndex - 1.2f; foreach (Slot slot in _slots) { Object.Destroy((Object)(object)((Component)slot.Root).gameObject); } _slots.Clear(); for (int j = 0; j < _items.Count; j++) { _slots.Add(CreateSlot(j, _items[j], _items[j] == val || _items[j] == val2)); } SetLabels(null); _group.alpha = 0f; _root.SetActive(true); Animate(); } private static void Close(bool instant) { if (!IsOpen && _closingAt < 0f) { return; } IsOpen = false; if (instant || (Object)(object)_root == (Object)null) { _closingAt = -1f; if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } else if (_closingAt < 0f) { _closingAt = Now; } } private static void Animate() { //IL_0042: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028d: 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_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null) { return; } if (!IsOpen) { float num = Mathf.Clamp01((Now - _closingAt) / 0.1f); _group.alpha = 1f - num; ((Transform)_content).localScale = Vector3.one * Mathf.Lerp(1f, 0.9f, UiUtil.EaseOutCubic(num)); if (num >= 1f) { _closingAt = -1f; _root.SetActive(false); } return; } int count = _items.Count; if (count != 0) { float num2 = Now - _openedAt; _group.alpha = UiUtil.EaseOutCubic(num2 / 0.14f); ((Transform)_content).localScale = Vector3.one * Mathf.Lerp(0.85f, 1f, UiUtil.EaseOutBack(num2 / 0.224f)); _currentIndex = Mathf.SmoothDamp(_currentIndex, (float)_targetIndex, ref _spinVelocity, 0.075f, float.PositiveInfinity, Dt); float num3 = 360f / (float)count; int selected = Selected; for (int i = 0; i < count; i++) { Slot slot = _slots[i]; float t = (num2 - (float)i * 0.03f) / 0.22f; float num4 = 175f * UiUtil.EaseOutBack(t); float num5 = UiUtil.EaseOutCubic(t); float num6 = Mathf.DeltaAngle(0f, (_currentIndex - (float)i) * num3); float num7 = (90f + num6) * (MathF.PI / 180f); slot.Root.anchoredPosition = new Vector2(Mathf.Cos(num7), Mathf.Sin(num7)) * num4; float num8 = 1f - Mathf.Clamp01(Mathf.Abs(num6) / 150f); slot.Group.alpha = num5 * Mathf.Lerp(0.35f, 1f, num8); float num9 = ((i == selected) ? 1f : 0f); slot.Pop = Mathf.Lerp(slot.Pop, num9, 1f - Mathf.Exp(-18f * Dt)); float num10 = Mathf.Lerp(0.82f, 1f, num8) + slot.Pop * 0.3f; ((Transform)slot.Root).localScale = Vector3.one * num10 * Mathf.Lerp(0.4f, 1f, num5); ((Graphic)slot.Base).color = Color.Lerp(SlotBase, SlotBaseSelected, slot.Pop); ((Graphic)slot.Rim).color = Color.Lerp(slot.Holstered ? RimHolstered : RimIdle, Gold, slot.Pop); Color gold = Gold; gold.a = 0.55f * slot.Pop * (0.85f + 0.15f * Mathf.Sin(Now * 6f)); ((Graphic)slot.Glow).color = gold; } float num11 = Mathf.Sin(Now * 5f) * 3f; _pointer.anchoredPosition = new Vector2(0f, 243f + num11); if (selected != _shownSelected) { _shownSelected = selected; _labelChangedAt = Now; SetLabels(_items[selected]); } float t2 = Mathf.Clamp01((Now - _labelChangedAt) / 0.16f); float num12 = Mathf.Lerp(1.15f, 1f, UiUtil.EaseOutCubic(t2)); ((Transform)_label.rectTransform).localScale = Vector3.one * num12; _label.alpha = Mathf.Lerp(0.2f, 1f, UiUtil.EaseOutCubic(t2)); _subLabel.alpha = _label.alpha * SubLabelColor.a; } } private static void SetLabels(ItemData item) { if (!((Object)(object)_label == (Object)null)) { if (item == null) { _label.text = ""; _subLabel.text = ""; return; } _label.text = ((Localization.instance != null) ? Localization.instance.Localize(item.m_shared.m_name) : item.m_shared.m_name); Player localPlayer = Player.m_localPlayer; bool flag = (Object)(object)localPlayer != (Object)null && (item == VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)localPlayer) || item == VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)localPlayer)); _subLabel.text = KindName(item) + (flag ? " · holstered" : ""); } } private static string KindName(ItemData item) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_001f: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected I4, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Invalid comparison between Unknown and I4 SharedData shared = item.m_shared; if (HolsterJoints.IsStaff(shared)) { return "Staff"; } ItemType itemType = shared.m_itemType; if ((int)itemType <= 14) { switch (itemType - 3) { case 1: if ((int)shared.m_skillType != 14) { return "Bow"; } return "Crossbow"; case 2: return "Shield"; case 0: if ((int)shared.m_skillType != 5) { if ((int)shared.m_skillType != 2) { return "One-handed"; } return "Knife"; } return "Spear"; } if ((int)itemType == 14) { goto IL_0069; } } else { if ((int)itemType == 15) { return "Torch"; } if ((int)itemType == 19) { return "Tool"; } if ((int)itemType == 22) { goto IL_0069; } } return ""; IL_0069: return "Two-handed"; } private static Slot CreateSlot(int index, ItemData item, bool holstered) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Slot" + index, new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)_ring, false); val2.sizeDelta = new Vector2(84f, 84f); Slot obj = new Slot { Root = val2, Group = val.AddComponent<CanvasGroup>(), Holstered = holstered }; obj.Group.interactable = false; obj.Group.blocksRaycasts = false; obj.Glow = NewImage("Glow", (Transform)(object)val2, UiUtil.Glow(), 159.59999f); ((Graphic)obj.Glow).color = Color.clear; obj.Base = NewImage("Base", (Transform)(object)val2, UiUtil.Circle(), 84f); obj.Rim = NewImage("Rim", (Transform)(object)val2, UiUtil.Ring(), 90f); obj.Icon = NewImage("Icon", (Transform)(object)val2, item.GetIcon(), 58f); obj.Icon.preserveAspect = true; return obj; } private static void EnsureUI() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("ValheimHolster_Wheel"); Object.DontDestroyOnLoad((Object)(object)_root); Canvas obj = _root.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 500; CanvasScaler obj2 = _root.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 1f; _group = _root.AddComponent<CanvasGroup>(); _group.interactable = false; _group.blocksRaycasts = false; _content = (RectTransform)new GameObject("Content", new Type[1] { typeof(RectTransform) }).transform; ((Transform)_content).SetParent(_root.transform, false); _content.sizeDelta = Vector2.zero; ((Graphic)NewImage("Background", (Transform)(object)_content, UiUtil.Glow(), 621.60004f)).color = BgCenter; ((Graphic)NewImage("Track", (Transform)(object)_content, UiUtil.Ring(), 354f)).color = TrackColor; ((Graphic)NewImage("Plate", (Transform)(object)_content, UiUtil.Circle(), 256f)).color = PlateColor; _ring = (RectTransform)new GameObject("Ring", new Type[1] { typeof(RectTransform) }).transform; ((Transform)_ring).SetParent((Transform)(object)_content, false); _ring.sizeDelta = Vector2.zero; Image obj3 = NewImage("Pointer", (Transform)(object)_content, UiUtil.Triangle(), 26f); ((Graphic)obj3).color = Gold; _pointer = ((Graphic)obj3).rectTransform; TMP_FontAsset font = FindGameFont(); float width = 226f; _label = NewText("Label", (Transform)(object)_content, font, 24f, 14f, LabelColor, new Vector2(0f, 12f), width, (FontStyles)1); _subLabel = NewText("SubLabel", (Transform)(object)_content, font, 15f, 12f, SubLabelColor, new Vector2(0f, -18f), width, (FontStyles)2); _root.SetActive(false); } } private static TMP_Text NewText(string name, Transform parent, TMP_FontAsset font, float maxSize, float minSize, Color color, Vector2 pos, float width, FontStyles style) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.sizeDelta = new Vector2(width, maxSize + 12f); val2.anchoredPosition = pos; val.SetActive(false); TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>(); if ((Object)(object)font != (Object)null) { ((TMP_Text)val3).font = font; } val.SetActive(true); ((TMP_Text)val3).fontStyle = style; ((TMP_Text)val3).enableAutoSizing = true; ((TMP_Text)val3).fontSizeMax = maxSize; ((TMP_Text)val3).fontSizeMin = minSize; ((TMP_Text)val3).fontSize = maxSize; ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; ((Graphic)val3).color = color; ((TMP_Text)val3).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)val3).overflowMode = (TextOverflowModes)1; ((Graphic)val3).raycastTarget = false; ((TMP_Text)val3).outlineWidth = 0.18f; ((TMP_Text)val3).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)220); return (TMP_Text)(object)val3; } private static TMP_FontAsset FindGameFont() { if ((Object)(object)_font != (Object)null) { return _font; } TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); TMP_FontAsset[] array2 = array; foreach (TMP_FontAsset val in array2) { if ((Object)(object)val != (Object)null && ((Object)val).name.ToLowerInvariant().Contains("averia") && ((Object)val).name.ToLowerInvariant().Contains("bold")) { return _font = val; } } array2 = array; foreach (TMP_FontAsset val2 in array2) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name.ToLowerInvariant().Contains("averia")) { return _font = val2; } } Dictionary<TMP_FontAsset, int> dictionary = new Dictionary<TMP_FontAsset, int>(); TMP_Text[] array3 = (((Object)(object)Hud.instance != (Object)null) ? ((Component)Hud.instance).GetComponentsInChildren<TMP_Text>(true) : Resources.FindObjectsOfTypeAll<TMP_Text>()); foreach (TMP_Text val3 in array3) { if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.font == (Object)null)) { dictionary.TryGetValue(val3.font, out var value); dictionary[val3.font] = value + 1; } } int num = -1; foreach (KeyValuePair<TMP_FontAsset, int> item in dictionary) { if (item.Value > num) { num = item.Value; _font = item.Key; } } if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogInfo((object)("Wheel: font " + (((Object)(object)_font != (Object)null) ? ((Object)_font).name : "NONE"))); } return _font; } private static Image NewImage(string name, Transform parent, Sprite sprite, float size) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); Image obj = val.AddComponent<Image>(); obj.sprite = sprite; ((Graphic)obj).raycastTarget = false; ((Graphic)obj).rectTransform.sizeDelta = new Vector2(size, size); return obj; } } internal static class HoverTracker { private static GameObject _source; public static InventoryGrid Grid { get; private set; } public static InventoryElement Element { get; private set; } public static bool IsValid { get { if ((Object)(object)Element != (Object)null && ((Object)(object)Grid != (Object)null || SafePouchCompat.OwnsElement(Element))) { return ((Component)Element).gameObject.activeInHierarchy; } return false; } } public static void Enter(GameObject tooltipGo) { InventoryElement componentInParent = tooltipGo.GetComponentInParent<InventoryElement>(); if (!((Object)(object)componentInParent == (Object)null)) { _source = tooltipGo; Element = componentInParent; Grid = ((Component)componentInParent).GetComponentInParent<InventoryGrid>(); } } public static void Exit(GameObject tooltipGo) { if (!((Object)(object)tooltipGo != (Object)(object)_source)) { _source = null; Element = null; Grid = null; } } public static string Describe() { return "grid=" + (((Object)(object)Grid != (Object)null) ? ((Object)Grid).name : "null") + " element=" + (((Object)(object)Element != (Object)null) ? ((Object)Element).name : "null"); } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class Humanoid_EquipItem_Patch { private static void Prefix(Humanoid __instance, ItemData item, out EquipState __state) { HolsterLogic.EquipDepth++; __state = default(EquipState); if (!HolsterLogic.Busy && HolsterLogic.IsActive(__instance) && HolsterConfig.HolsterOnSwap.Value && HolsterLogic.IsHandItem(item)) { __state = new EquipState { Track = true, Right = VanillaAccess.RightItem.Invoke(__instance), Left = VanillaAccess.LeftItem.Invoke(__instance), HiddenRight = VanillaAccess.HiddenRightItem.Invoke(__instance), HiddenLeft = VanillaAccess.HiddenLeftItem.Invoke(__instance) }; } } private static void Postfix(Humanoid __instance, ItemData item, bool __result, EquipState __state) { if (!__result) { return; } if (__state.Track) { ItemData val = VanillaAccess.RightItem.Invoke(__instance); ItemData val2 = VanillaAccess.LeftItem.Invoke(__instance); ItemData val3 = ((__state.Right != null && __state.Right != val && __state.Right != val2) ? __state.Right : null); ItemData val4 = ((__state.Left != null && __state.Left != val && __state.Left != val2) ? __state.Left : null); if (val3 != null || val4 != null) { HolsterLogic.RememberLast(__instance, val3, val4); } ItemData val5 = ((!HolsterLogic.StillHolsterable(__instance, val3)) ? ((HolsterLogic.StillHolsterable(__instance, __state.HiddenRight) && __state.HiddenRight != item) ? __state.HiddenRight : null) : val3); ItemData val6 = ((!HolsterLogic.StillHolsterable(__instance, val4)) ? ((HolsterLogic.StillHolsterable(__instance, __state.HiddenLeft) && __state.HiddenLeft != item) ? __state.HiddenLeft : null) : val4); VanillaAccess.HiddenRightItem.Invoke(__instance) = val5; VanillaAccess.HiddenLeftItem.Invoke(__instance) = val6; VanillaAccess.SetupVisEquipment(__instance); } if (!HolsterLogic.Busy && HolsterLogic.EquipDepth == 1 && HolsterLogic.IsActive(__instance)) { HolsterLogic.TryAutoEquipShield(__instance, item); } } private static void Finalizer() { HolsterLogic.EquipDepth--; } } [HarmonyPatch(typeof(Humanoid), "HideHandItems")] internal static class Humanoid_HideHandItems_Patch { private static bool Prefix(Humanoid __instance, bool onlyRightHand, ref bool __result) { if (HolsterLogic.SuppressVanillaHide && !HolsterLogic.ModCall && HolsterLogic.IsLocal(__instance)) { __result = false; return false; } if (HolsterLogic.Busy || onlyRightHand || !HolsterLogic.HideKeyThisFrame) { return true; } if (!HolsterLogic.IsActive(__instance) || !HolsterConfig.SwapWithHideKey.Value) { return true; } if (((Character)__instance).IsSwimming()) { return true; } if (HolsterLogic.SwapWithHolster(__instance)) { __result = true; return false; } if (HolsterLogic.ModCall && HolsterConfig.DoubleTapEmpty.Value) { __result = false; return false; } return true; } private static void Postfix(Humanoid __instance) { if (HolsterLogic.HideKeyThisFrame && HolsterLogic.IsActive(__instance) && HolsterConfig.OnlyMarked.Value) { bool flag = false; ItemData val = VanillaAccess.HiddenRightItem.Invoke(__instance); ItemData val2 = VanillaAccess.HiddenLeftItem.Invoke(__instance); if (val != null && !HolsterLogic.CanHolster(val)) { VanillaAccess.HiddenRightItem.Invoke(__instance) = null; flag = true; } if (val2 != null && !HolsterLogic.CanHolster(val2)) { VanillaAccess.HiddenLeftItem.Invoke(__instance) = null; flag = true; } if (flag) { VanillaAccess.SetupVisEquipment(__instance); } } } } [HarmonyPatch(typeof(Humanoid), "ShowHandItems")] internal static class Humanoid_ShowHandItems_Patch { private static bool Prefix(Humanoid __instance) { if (HolsterLogic.SuppressVanillaHide && !HolsterLogic.ModCall) { return !HolsterLogic.IsLocal(__instance); } return true; } } [HarmonyPatch(typeof(Humanoid), "ToggleEquipped")] internal static class Humanoid_ToggleEquipped_Patch { private static bool Prefix(Humanoid __instance, ItemData item, ref bool __result) { if (!HolsterConfig.LockHotbar.Value || !HolsterLogic.IsActive(__instance)) { return true; } if (InventoryGui.IsVisible()) { return true; } if (!__instance.IsItemEquiped(item) || !HolsterLogic.IsHandItem(item) || HolsterLogic.IsTool(item)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] internal static class Humanoid_UnequipItem_Patch { private static void Postfix(Humanoid __instance, ItemData item) { if (!HolsterLogic.Busy && HolsterLogic.EquipDepth <= 0 && HolsterLogic.IsActive(__instance) && HolsterLogic.IsOneHandWeapon(item)) { HolsterLogic.TryAutoUnequipShield(__instance); } } } [HarmonyPatch(typeof(InventoryGri