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.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("Padilha")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ValheimHolster")] [assembly: AssemblyTitle("ValheimHolster")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ValheimHolster { 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 _entries = new List(); private static readonly HashSet _used = new HashSet(); private static readonly HashSet _unplacedLogged = new HashSet(); public const string HideKey = "ValheimHolster.Hide"; public const string QuiverKey = "ValheimHolster.Quiver"; private static float _stateTimer; private static int _lastHide = -1; private static int _lastQuiver = int.MinValue; public static void MarkDirty() { _timer = 0f; _stateTimer = 0f; } public static void Tick() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { _lastWritten = null; _lastHide = -1; _lastQuiver = int.MinValue; return; } PublishState(localPlayer); _timer -= Time.deltaTime; if (_timer > 0f) { return; } _timer = 0.25f; ZNetView component = ((Component)localPlayer).GetComponent(); 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)("Extras publicados: " + Describe())); } } } private static void PublishState(Player player) { _stateTimer -= Time.deltaTime; if (_stateTimer > 0f) { return; } _stateTimer = 0.1f; ZNetView component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { return; } ZDO zDO = component.GetZDO(); int num = ((HolsterConfig.Enabled.Value && ShouldHide(player)) ? 1 : 0); if (num != _lastHide) { _lastHide = num; zDO.Set("ValheimHolster.Hide", num == 1); } int num2 = (HolsterConfig.Enabled.Value ? QuiverAmmo(player) : 0); if (num2 != _lastQuiver) { if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogInfo((object)("Aljava: munição publicada = " + num2)); } _lastQuiver = num2; zDO.Set("ValheimHolster.Quiver", num2); } } private static bool ShouldHide(Player p) { try { bool flag = ((Character)p).InBed() || p.IsSleeping(); if (HolsterConfig.HideWhenSleeping.Value && flag) { return true; } if (HolsterConfig.HideWhenSitting.Value && !flag && (((Character)p).IsSitting() || ((Character)p).IsAttached())) { return true; } if (HolsterConfig.HideWhenSwimming.Value && ((Character)p).IsSwimming()) { return true; } if (HolsterConfig.HideIndoors.Value && p.InShelter()) { return true; } } catch { } return false; } public static int QuiverAmmo(Player p) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 if (!HolsterConfig.QuiverEnabled.Value) { return 0; } Inventory inventory = ((Humanoid)p).GetInventory(); if (inventory == null) { return 0; } ItemData val = null; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem?.m_shared != null && (int)allItem.m_shared.m_itemType == 4 && !string.IsNullOrEmpty(allItem.m_shared.m_ammoType)) { if (allItem.m_equipped) { val = allItem; break; } if (val == null && HolsterLogic.IsMarked(allItem)) { val = allItem; } } } if (val == null) { return 0; } ItemData ammoItem = ((Humanoid)p).GetAmmoItem(); if (ammoItem == null || ammoItem.m_shared.m_ammoType != val.m_shared.m_ammoType || !inventory.ContainsItem(ammoItem)) { ammoItem = inventory.GetAmmoItem(val.m_shared.m_ammoType, (string)null); } int num = ((ammoItem != null) ? HolsterLogic.ItemHash(ammoItem) : 0); if (num == 0) { return -1; } return num; } public static string Compute(Player p, bool preview) { //IL_01f9: 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)) { 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("Sem encaixe livre pra {0} (tipo={1}). Usados: {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 "(nenhuma)"; } 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 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 _entries = new List(); private readonly List _instances = new List(); private Player _player; private bool _handsFreed; private bool _hidden; private GameObject _quiver; private int _quiverHash; private int _quiverRevision = -1; private float _quiverTimer; private bool _wasHidden; private void Awake() { _vis = ((Component)this).GetComponent(); _nview = ((Component)this).GetComponent(); } private void OnDestroy() { Clear(); if ((Object)(object)_quiver != (Object)null) { Object.Destroy((Object)(object)_quiver); } } private void Update() { UpdateHidden(); UpdateQuiver(); _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(); } 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 = (_nview.IsOwner() ? 0.05f : 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 UpdateHidden() { if ((Object)(object)_vis == (Object)null) { return; } bool flag = (Object)(object)_nview != (Object)null && _nview.IsValid(); _hidden = flag && HolsterConfig.Enabled.Value && _nview.GetZDO().GetBool("ValheimHolster.Hide", false); if (!_hidden && !_wasHidden) { return; } _wasHidden = _hidden; bool show = !_hidden; foreach (GameObject instance in _instances) { SetShown(instance, show); } if (VanillaAccess.LeftBackInstance != null) { SetShown(VanillaAccess.LeftBackInstance.Invoke(_vis), show); } if (VanillaAccess.RightBackInstance != null) { SetShown(VanillaAccess.RightBackInstance.Invoke(_vis), show); } SetShown(_quiver, show); } private static void SetShown(GameObject go, bool show) { if ((Object)(object)go != (Object)null && go.activeSelf != show) { go.SetActive(show); } } private void UpdateQuiver() { _quiverTimer -= Time.deltaTime; if (_quiverTimer > 0f || (Object)(object)_vis == (Object)null) { return; } int num; if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { _quiverTimer = 0.2f; num = ((HolsterConfig.Enabled.Value && HolsterConfig.QuiverEnabled.Value) ? _nview.GetZDO().GetInt("ValheimHolster.Quiver", 0) : 0); } else { _quiverTimer = 0.5f; if ((Object)(object)_player == (Object)null) { _player = ((Component)this).GetComponent(); } num = (((Object)(object)_player != (Object)null && HolsterConfig.Enabled.Value && HolsterConfig.ShowInMenu.Value) ? ExtraHolster.QuiverAmmo(_player) : 0); } if (num != _quiverHash || _quiverRevision != HolsterConfig.VisualRevision || (num != 0 && !((Object)(object)_quiver != (Object)null))) { _quiverHash = num; _quiverRevision = HolsterConfig.VisualRevision; if ((Object)(object)_quiver != (Object)null) { Object.Destroy((Object)(object)_quiver); } _quiver = ((num != 0) ? Quiver.Build(_vis, num) : null); if ((Object)(object)_quiver != (Object)null && _hidden) { _quiver.SetActive(false); } } } 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)$"Encaixe {entry.Joint} não existe neste personagem"); } 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)$"Falha ao desenhar {entry.Hash} em {entry.Joint}"); } continue; } if (entry.Joint == HolsterJoint.HipRight || entry.Joint == HolsterJoint.HipLeft) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(entry.Hash); HolsterLogic.ApplyHipOffset(s: (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent() : null)?.m_itemData.m_shared, t: val2.transform, left: entry.Joint == HolsterJoint.HipLeft, character: ((Component)_vis).transform); } val2.AddComponent().Init(entry.Hash, Motion.Kind.Body); if (_hidden) { val2.SetActive(false); } _instances.Add(val2); } } } internal static class MenuHelper { public static bool InMainMenu { get { if ((Object)(object)FejdStartup.instance != (Object)null) { return (Object)(object)Player.m_localPlayer == (Object)null; } return false; } } } public enum TextLanguage { Auto, English, Portuguese } public static class HolsterConfig { public static ConfigEntry Enabled; public static ConfigEntry Language; public static ConfigEntry DebugLog; public static ConfigEntry MarkKey; public static ConfigEntry OnlyMarked; public static ConfigEntry HolsterOnSwap; public static ConfigEntry ShowExtras; public static ConfigEntry MaxExtras; public static ConfigEntry CrossBigWeapons; public static ConfigEntry HolsterTools; public static ConfigEntry ShowTooltip; public static ConfigEntry SmoothMotion; public static ConfigEntry MotionDuration; public static ConfigEntry HideWhenSitting; public static ConfigEntry HideWhenSleeping; public static ConfigEntry HideWhenSwimming; public static ConfigEntry HideIndoors; public static ConfigEntry SwapWithHideKey; public static ConfigEntry DoubleTapEmpty; public static ConfigEntry DoubleTapWindow; public static ConfigEntry WheelEnabled; public static ConfigEntry WheelHoldTime; public static ConfigEntry WheelOnlyMarked; public static ConfigEntry WheelGamepad; public static ConfigEntry OneHandOnHip; public static ConfigEntry UseLeftHip; public static ConfigEntry HipTiltBack; public static ConfigEntry HipRollOut; public static ConfigEntry HipUp; public static ConfigEntry HipForward; public static ConfigEntry HipInward; public static ConfigEntry AxeHeadUp; public static ConfigEntry AxeTilt; public static ConfigEntry AxeUp; public static ConfigEntry KnifeTilt; public static ConfigEntry KnifeRoll; public static ConfigEntry KnifeInward; public static ConfigEntry KnifeUp; public static ConfigEntry KnifeForward; public static ConfigEntry HipPositionOffset; public static ConfigEntry HipRotationOffset; public static ConfigEntry AutoEquipShield; public static ConfigEntry NoShieldWithAxe; public static ConfigEntry AutoUnequipShield; public static ConfigEntry LockHotbar; public static ConfigEntry ShowInMenu; public static ConfigEntry MenuFreeHands; public static ConfigEntry KeepLoaded; public static ConfigEntry ReloadWhileRunning; public static ConfigEntry ReloadNeedsAmmo; public static ConfigEntry ReloadSpeed; public static ConfigEntry QuiverEnabled; public static ConfigEntry QuiverArrows; public static ConfigEntry QuiverPosition; public static ConfigEntry QuiverRotation; public static ConfigEntry QuiverScale; private static ConfigFile _cfg; private static Dictionary> _oldValues; private static readonly List _migrated = new List(); public static int VisualRevision { get; private set; } public static void Bind(ConfigFile cfg) { //IL_075f: Unknown result type (might be due to invalid IL or missing references) //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_09c3: Unknown result type (might be due to invalid IL or missing references) //IL_09f8: Unknown result type (might be due to invalid IL or missing references) _cfg = cfg; _oldValues = ReadFile(cfg.ConfigFilePath); Enabled = B("1 - General", "Enabled", "1 - Geral", "Ativado", def: true, "Turns the mod on/off.", "Liga/desliga o mod."); Language = B("1 - General", "Language", null, null, TextLanguage.Auto, "Language of the in-game texts (messages, tooltip, wheel). Auto = follows the game language.", "Idioma dos textos do jogo (mensagens, tooltip, roda). Auto = segue o idioma do jogo."); DebugLog = B("1 - General", "Debug log", "1 - Geral", "Log detalhado", def: false, "Writes what the mod is doing (marking, attach points) to LogOutput.log. Useful for bug reports.", "Escreve no LogOutput.log o que o mod está fazendo (marcação, encaixes). Útil pra reportar problemas."); MarkKey = B("2 - Body", "Mark key", "2 - Corpo", "Tecla marcar", (KeyCode)104, "With the inventory open, hover a weapon and press this key to mark/unmark it. Marked weapons stay on your body and show up in the wheel.", "Com o inventário aberto, passe o mouse numa arma e aperte essa tecla pra marcar/desmarcar. Armas marcadas ficam no corpo e entram na roda."); OnlyMarked = B("2 - Body", "Only marked weapons on body", "2 - Corpo", "So armas marcadas ficam no corpo", def: true, "On: only marked weapons hang on your body; the rest just leave your hands. Off: any swapped weapon stays on the body.", "Ligado: só armas marcadas ficam penduradas no corpo; as outras simplesmente saem da mão. Desligado: qualquer arma trocada fica no corpo."); HolsterOnSwap = B("2 - Body", "Holster on swap", "2 - Corpo", "Guardar ao trocar de arma", def: true, "When you equip another weapon, the one in your hand goes to your body instead of vanishing.", "Ao equipar outra arma, a que estava na mão vai pro corpo em vez de sumir."); ShowExtras = B("2 - Body", "Show all marked weapons", "2 - Corpo", "Mostrar todas as marcadas", def: true, "Shows every marked weapon on your body, not just the two the game keeps.", "Mostra no corpo todas as armas marcadas, não só as duas que o jogo guarda."); MaxExtras = B("2 - Body", "Max extra weapons", "2 - Corpo", "Maximo de armas extras", 10, "How many extra marked weapons can show on your body (one per free spot).", "Quantas armas marcadas extras podem aparecer no corpo (uma por encaixe livre).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 10)); CrossBigWeapons = B("2 - Body", "Cross big weapons", "2 - Corpo", "Cruzar armas grandes", def: true, "Two big weapons (staff, greatsword, atgeir, bow...) on the same spot are crossed in an X on your back.", "Duas armas grandes (cajado, espadão, atgeir, arco...) no mesmo lugar ficam cruzadas em X nas costas."); HolsterTools = B("2 - Body", "Tools on body", "2 - Corpo", "Ferramentas no corpo", def: false, "Tools (hammer, hoe, cultivator, pickaxe, fishing rod, torch) can also stay on your body. Off: tools never stay on the body.", "Ferramentas (martelo, enxada, cultivador, picareta, vara de pesca, tocha) também podem ficar no corpo. Desligado: ferramentas nunca ficam no corpo."); ShowTooltip = B("2 - Body", "Show in tooltip", "2 - Corpo", "Mostrar no tooltip", def: true, "Shows in the weapon tooltip whether it is marked.", "Mostra no tooltip da arma se ela está marcada."); SmoothMotion = B("2 - Body", "Smooth motion", "2 - Corpo", "Animacao suave", def: true, "Weapons slide from your hand to your body (and back), grow in when they come from the inventory and shrink out when they go back.", "A arma desliza da mão pro corpo (e do corpo pra mão), cresce quando sai do inventário e encolhe quando volta pra ele."); MotionDuration = B("2 - Body", "Motion duration", "2 - Corpo", "Duracao da animacao", 0.3f, "Seconds a weapon takes to go from your hand to your body.", "Segundos que a arma leva pra ir da mão pro corpo.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 1f)); HideWhenSitting = B("2 - Body", "Hide when sitting", null, null, def: true, "Weapons on the body disappear while you sit (chair, bench, ground or ship).", "As armas do corpo somem enquanto você está sentado (cadeira, banco, chão ou barco)."); HideWhenSleeping = B("2 - Body", "Hide when sleeping", null, null, def: true, "Weapons on the body disappear while you lie in bed.", "As armas do corpo somem enquanto você está deitado na cama."); HideWhenSwimming = B("2 - Body", "Hide when swimming", null, null, def: false, "Weapons on the body disappear while you swim.", "As armas do corpo somem enquanto você nada."); HideIndoors = B("2 - Body", "Hide indoors", null, null, def: false, "Weapons on the body disappear while you are under a roof (inside a house).", "As armas do corpo somem enquanto você está debaixo de um teto (dentro de casa)."); SwapWithHideKey = B("3 - Hide key (R)", "Tap swaps weapon", "3 - Tecla R", "Toque troca de arma", def: true, "A tap on R swaps the weapon in your hand with the one you used before.", "Um toque no R troca a arma da mão pela que estava antes."); DoubleTapEmpty = B("3 - Hide key (R)", "Double tap empties hands", "3 - Tecla R", "Dois toques esvaziam a mao", def: true, "Two quick taps on R empty your hands (marked weapons go to your body). When on, a single tap waits a moment to see if a second one comes.", "Dois toques rápidos no R tiram tudo da mão (o que estiver marcado vai pro corpo). Ligado, o toque simples espera um instante pra ver se vem o segundo."); DoubleTapWindow = B("3 - Hide key (R)", "Double tap window", "3 - Tecla R", "Tempo entre os dois toques", 0.28f, "Seconds between the two taps.", "Segundos entre os dois toques.", (AcceptableValueBase)(object)new AcceptableValueRange(0.15f, 0.6f)); WheelEnabled = B("3 - Hide key (R)", "Hold opens wheel", "3 - Tecla R", "Segurar abre a roda", def: true, "Holding R opens the weapon wheel: move the mouse sideways (or scroll) to spin, release to equip, right click cancels. With ValheimDualWield: left/right click picks the hand, middle click cancels.", "Segurar o R abre a roda de armas: mouse pros lados (ou scroll) gira, soltar equipa, botão direito cancela. Com o ValheimDualWield: botão esquerdo/direito escolhe a mão, o do meio cancela."); WheelHoldTime = B("3 - Hide key (R)", "Hold time", "3 - Tecla R", "Tempo segurando", 0.25f, "Seconds holding R until the wheel opens.", "Segundos segurando o R até a roda abrir.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 1f)); WheelOnlyMarked = B("3 - Hide key (R)", "Wheel only marked weapons", "3 - Tecla R", "Roda so com armas marcadas", def: true, "On: the wheel shows marked weapons (and the ones on your body). Off: every weapon in the inventory.", "Ligado: a roda mostra as armas marcadas (e as que estão guardadas). Desligado: todas as armas do inventário."); WheelGamepad = B("3 - Hide key (R)", "Gamepad wheel", null, null, def: true, "Gamepad: hold the hide button to open the wheel, aim with the right stick, release to equip, B cancels.", "Controle: segure o botão de guardar pra abrir a roda, aponte com o analógico direito, solte pra equipar, B cancela."); OneHandOnHip = B("4 - Hip", "One-handed on hip", "4 - Quadril", "Arma de uma mao no quadril", def: true, "Swords, axes, maces and knives (not spears) sit on your hip instead of your back.", "Espadas, machados, maças e facas (lanças não) ficam na cintura em vez das costas."); UseLeftHip = B("4 - Hip", "Use both sides", "4 - Quadril", "Usar os dois lados", def: true, "The second marked one-handed weapon goes on the other hip.", "A segunda arma de uma mão marcada vai pro outro lado do quadril."); HipTiltBack = B("4 - Hip", "Tilt back", "4 - Quadril", "Inclinacao pra tras", 35f, "Tilt in degrees. Positive = tip back and handle forward; 0 = straight.", "Graus de inclinação. Positivo = ponta pra trás e cabo pra frente; 0 = reta.", (AcceptableValueBase)(object)new AcceptableValueRange(-90f, 90f)); HipRollOut = B("4 - Hip", "Roll out", "4 - Quadril", "Giro pra fora", 0f, "Sideways roll in degrees. Positive = tip away from the leg (mirrored on both sides); 0 = straight.", "Graus de giro lateral. Positivo = ponta se afasta da perna (espelhado nos dois lados); 0 = reta.", (AcceptableValueBase)(object)new AcceptableValueRange(-45f, 45f)); HipUp = B("4 - Hip", "Height", "4 - Quadril", "Altura", 0.08f, "Meters to raise (positive) or lower the hip weapon.", "Metros pra subir (positivo) ou descer a arma da cintura.", (AcceptableValueBase)(object)new AcceptableValueRange(-0.3f, 0.3f)); HipForward = B("4 - Hip", "Forward", "4 - Quadril", "Frente", 0.06f, "Meters to move the hip weapon forward (positive) or back.", "Metros pra levar a arma da cintura pra frente (positivo) ou pra trás.", (AcceptableValueBase)(object)new AcceptableValueRange(-0.3f, 0.3f)); HipInward = B("4 - Hip", "Closer to body", "4 - Quadril", "Aproximar do corpo", 0.05f, "Meters the hip weapon is pulled toward the body (positive) or pushed away.", "Metros que a arma da cintura é puxada pra perto do corpo (positivo) ou afastada.", (AcceptableValueBase)(object)new AcceptableValueRange(-0.3f, 0.3f)); AxeHeadUp = B("4 - Hip", "Axe and mace - head up", null, null, def: true, "Axes and maces hang head up, like through a belt loop. Off: same pose as swords.", "Machados e maças ficam com a cabeça pra cima, como num passador do cinto. Desligado: mesma posição das espadas."); AxeTilt = B("4 - Hip", "Axe and mace - tilt", null, null, 20f, "Tilt in degrees for head-up axes and maces. Positive = head forward, handle back.", "Inclinação dos machados e maças de cabeça pra cima. Positivo = cabeça pra frente, cabo pra trás.", (AcceptableValueBase)(object)new AcceptableValueRange(-90f, 90f)); AxeUp = B("4 - Hip", "Axe and mace - height", null, null, 0f, "Meters to raise (positive) or lower head-up axes and maces.", "Metros pra subir (positivo) ou descer os machados e maças.", (AcceptableValueBase)(object)new AcceptableValueRange(-0.3f, 0.3f)); KnifeTilt = B("4 - Hip", "Knife - tilt", "4 - Quadril", "Faca - inclinacao", 10f, "Tilt for knives only (positive = tip back).", "Inclinação só da faca (positivo = ponta pra trás).", (AcceptableValueBase)(object)new AcceptableValueRange(-90f, 90f)); KnifeRoll = B("4 - Hip", "Knife - roll out", "4 - Quadril", "Faca - giro pra fora", 0f, "Sideways roll for knives only (positive = tip away from the leg).", "Giro lateral só da faca (positivo = ponta se afasta da perna).", (AcceptableValueBase)(object)new AcceptableValueRange(-45f, 45f)); KnifeInward = B("4 - Hip", "Knife - closer to thigh", "4 - Quadril", "Faca - aproximar da coxa", 0.03f, "Meters the knife is pulled toward the leg.", "Metros que a faca é puxada pra perto da perna.", (AcceptableValueBase)(object)new AcceptableValueRange(-0.3f, 0.3f)); KnifeUp = B("4 - Hip", "Knife - height", "4 - Quadril", "Faca - altura", 0.06f, "Meters to raise (positive) or lower the knife.", "Metros pra subir (positivo) ou descer a faca.", (AcceptableValueBase)(object)new AcceptableValueRange(-0.3f, 0.3f)); KnifeForward = B("4 - Hip", "Knife - forward", "4 - Quadril", "Faca - frente", 0f, "Meters to move the knife forward (positive) or back.", "Metros pra levar a faca pra frente (positivo) ou pra trás.", (AcceptableValueBase)(object)new AcceptableValueRange(-0.3f, 0.3f)); HipPositionOffset = B("4 - Hip", "Position fine-tune", "4 - Quadril", "Ajuste de posicao", Vector3.zero, "Fine position tweak (the other side is mirrored).", "Ajuste fino da posição (o outro lado é espelhado)."); HipRotationOffset = B("4 - Hip", "Rotation fine-tune", "4 - Quadril", "Ajuste de rotacao", Vector3.zero, "Fine rotation tweak, in degrees.", "Ajuste fino da rotação, em graus."); AutoEquipShield = B("5 - Shield", "Shield with one-handed weapon", "5 - Escudo", "Escudo junto com arma de uma mao", def: true, "When you take a one-handed weapon with an empty left hand, the strongest shield in your inventory comes along.", "Ao pegar uma arma de uma mão com a mão esquerda vazia, o escudo mais forte do inventário vem junto."); NoShieldWithAxe = B("5 - Shield", "Except with axe", "5 - Escudo", "Exceto com machado", def: true, "Axes don't pull the shield (so you can chop trees without the movement penalty).", "Machado não puxa o escudo (pra cortar árvore sem a penalidade de movimento)."); AutoUnequipShield = B("5 - Shield", "Shield follows weapon", "5 - Escudo", "Escudo acompanha a arma", def: true, "When the one-handed weapon leaves your hand, the shield goes with it (to your back if marked).", "Quando a arma de uma mão sai da mão, o escudo sai junto (e vai pras costas se estiver marcado)."); LockHotbar = B("6 - Hotbar", "Number only equips", "6 - Hotbar", "Numero so equipa", def: false, "Pressing the hotbar number of a weapon already in your hand doesn't take it out of your hand.", "Apertar o número da hotbar de uma arma que já está na mão não tira ela da mão."); ShowInMenu = B("7 - Menu", "Show weapons in menu", "7 - Menu", "Mostrar armas no menu", def: true, "Main menu characters (preview and the ValheimMenu campfire) show their marked weapons on the body.", "Os personagens do menu (preview e fogueira do ValheimMenu) aparecem com as armas marcadas no corpo."); MenuFreeHands = B("7 - Menu", "Free hands in menu", "7 - Menu", "Maos livres no menu", def: true, "In the menu, the equipped weapon leaves the hand: if marked, it shows on the body.", "No menu, a arma equipada sai da mão: se estiver marcada, aparece no corpo."); KeepLoaded = B("8 - Reload", "Stay loaded when holstered", "8 - Recarga", "Continua carregada ao guardar", def: true, "A crossbow (or any weapon that needs reloading) put away loaded stays loaded when it comes back to your hand.", "Besta (ou qualquer arma que precisa recarregar) guardada carregada continua carregada quando volta pra mão."); ReloadWhileRunning = B("8 - Reload", "Reload while running", "8 - Recarga", "Recarregar correndo", def: true, "You can run while reloading, without cancelling the reload or slowing down.", "Dá pra correr enquanto recarrega, sem cancelar a recarga e sem ficar andando devagar."); ReloadNeedsAmmo = B("8 - Reload", "Reload only with ammo", "8 - Recarga", "So recarrega com municao", def: true, "The crossbow only starts reloading if you have bolts (or its ammo) in the inventory.", "A besta só começa a recarregar se você tiver virote (ou a munição dela) no inventário."); ReloadSpeed = B("8 - Reload", "Reload speed", "8 - Recarga", "Velocidade de recarga", 1f, "Reload speed multiplier. 1 = normal, 2 = twice as fast, 0.5 = half.", "Multiplicador da velocidade de recarga. 1 = normal, 2 = duas vezes mais rápido, 0.5 = metade.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 5f)); QuiverEnabled = B("9 - Quiver", "Show quiver", null, null, def: true, "A quiver shows on your back when you carry a marked (or equipped) bow or crossbow, with the arrows/bolts you have (empty if you have none).", "Uma aljava aparece nas costas quando você leva um arco ou besta marcado (ou na mão), com as flechas/virotes que você tem (vazia se não tiver nenhuma)."); QuiverArrows = B("9 - Quiver", "Arrows shown", null, null, 6, "How many arrows stick out of the quiver.", "Quantas flechas aparecem saindo da aljava.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 10)); QuiverPosition = B("9 - Quiver", "Position", null, null, new Vector3(0.12f, 0.02f, -0.03f), "Quiver position relative to the upper back, in meters (x = right, y = up, z = forward).", "Posição da aljava nas costas, em metros (x = direita, y = cima, z = frente)."); QuiverRotation = B("9 - Quiver", "Rotation", null, null, new Vector3(0f, 0f, -25f), "Quiver rotation in degrees (z = lean to the side).", "Rotação da aljava em graus (z = inclinação pro lado)."); QuiverScale = B("9 - Quiver", "Size", null, null, 1f, "Quiver size multiplier.", "Multiplicador do tamanho da aljava.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 2f)); DropMigrated(); ConfigEntryBase[] array = (ConfigEntryBase[])(object)new ConfigEntryBase[30] { (ConfigEntryBase)Enabled, (ConfigEntryBase)OnlyMarked, (ConfigEntryBase)ShowExtras, (ConfigEntryBase)MaxExtras, (ConfigEntryBase)CrossBigWeapons, (ConfigEntryBase)HolsterTools, (ConfigEntryBase)OneHandOnHip, (ConfigEntryBase)UseLeftHip, (ConfigEntryBase)HipTiltBack, (ConfigEntryBase)HipRollOut, (ConfigEntryBase)HipUp, (ConfigEntryBase)HipForward, (ConfigEntryBase)HipInward, (ConfigEntryBase)AxeHeadUp, (ConfigEntryBase)AxeTilt, (ConfigEntryBase)AxeUp, (ConfigEntryBase)KnifeTilt, (ConfigEntryBase)KnifeRoll, (ConfigEntryBase)KnifeInward, (ConfigEntryBase)KnifeUp, (ConfigEntryBase)KnifeForward, (ConfigEntryBase)HipPositionOffset, (ConfigEntryBase)HipRotationOffset, (ConfigEntryBase)ShowInMenu, (ConfigEntryBase)MenuFreeHands, (ConfigEntryBase)QuiverEnabled, (ConfigEntryBase)QuiverArrows, (ConfigEntryBase)QuiverPosition, (ConfigEntryBase)QuiverRotation, (ConfigEntryBase)QuiverScale }; for (int i = 0; i < array.Length; i++) { SubscribeChanged(array[i], Visual); } static void Visual() { VisualRevision++; VanillaAccess.RefreshAllVisuals(); ExtraHolster.MarkDirty(); } } private static void SubscribeChanged(ConfigEntryBase entry, Action action) { EventInfo eventInfo = ((object)entry).GetType().GetEvent("SettingChanged"); if (!(eventInfo == null)) { EventHandler handler = delegate { action(); }; eventInfo.AddEventHandler(entry, handler); } } private static ConfigEntry B(string section, string key, string oldSection, string oldKey, T def, string en, string pt, AcceptableValueBase range = null) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown ConfigEntry val = _cfg.Bind(section, key, def, new ConfigDescription(en + "\n\nPT-BR: " + pt, range, Array.Empty())); if (!Has(section, key) && oldSection != null && TryOld(oldSection, oldKey, out var value)) { try { ((ConfigEntryBase)val).SetSerializedValue(value); _migrated.Add(new ConfigDefinition(oldSection, oldKey)); } catch { } } return val; } private static bool Has(string section, string key) { if (_oldValues != null && _oldValues.TryGetValue(section, out var value)) { return value.ContainsKey(key); } return false; } private static bool TryOld(string section, string key, out string value) { value = null; if (_oldValues != null && _oldValues.TryGetValue(section, out var value2)) { return value2.TryGetValue(key, out value); } return false; } private static void DropMigrated() { if (_migrated.Count == 0) { return; } try { if (AccessTools.Property(typeof(ConfigFile), "OrphanedEntries")?.GetValue(_cfg) is Dictionary dictionary) { foreach (ConfigDefinition item in _migrated) { dictionary.Remove(item); } } _cfg.Save(); Plugin.Log.LogInfo((object)$"Config: {_migrated.Count} opções migradas pros nomes novos."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Config: não deu pra limpar as opções antigas: " + ex.Message)); } } private static Dictionary> ReadFile(string path) { Dictionary> dictionary = new Dictionary>(); try { if (!File.Exists(path)) { return dictionary; } string key = ""; string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0 || text.StartsWith("#")) { continue; } if (text.StartsWith("[") && text.EndsWith("]")) { key = text.Substring(1, text.Length - 2); continue; } int num = text.IndexOf('='); if (num > 0) { if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new Dictionary()); } value[text.Substring(0, num).Trim()] = text.Substring(num + 1).Trim(); } } } catch { } return dictionary; } } 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected I4, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected I4, but got Unknown if (s == null) { return HolsterJoint.None; } if (HolsterConfig.OneHandOnHip.Value && HolsterLogic.GoesOnHip(s)) { if (rightHand || !HolsterConfig.UseLeftHip.Value) { return HolsterJoint.HipRight; } return HolsterJoint.HipLeft; } 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 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00eb: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_015d: 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) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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) 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 DualWieldLeftKey = "morgnar.dualwield.lefthand"; public const string DualWieldGuid = "morgnar.valheimdualwield"; private static int _dualWield = -1; public const string CustomDataKey = "ValheimHolster.Marked"; public static bool DualWieldInstalled { get { if (_dualWield < 0) { _dualWield = (Chainloader.PluginInfos.ContainsKey("morgnar.valheimdualwield") ? 1 : 0); } return _dualWield == 1; } } 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; } Inventory inventory = h.GetInventory(); if (inventory != null) { return inventory.ContainsItem(item); } return false; } 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; } Inventory inventory = h.GetInventory(); if (inventory != null) { return inventory.ContainsItem(item); } return false; } 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; } private static bool UsesBothHands(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_001b: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 SharedData val = item?.m_shared; if (val == null) { return false; } ItemType itemType = val.m_itemType; if ((int)itemType == 4 || (int)itemType == 14 || (int)itemType == 22) { return true; } return false; } private static void SetDualLeftMark(ItemData item, bool left) { if (item != null) { if (item.m_customData == null) { item.m_customData = new Dictionary(); } if (left) { item.m_customData["morgnar.dualwield.lefthand"] = "1"; } else { item.m_customData.Remove("morgnar.dualwield.lefthand"); } } } public static void EquipHands(Player p, ItemData pickR, ItemData pickL) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 if ((pickR == null && pickL == null) || ((Character)p).InAttack() || ((Character)p).InDodge()) { return; } ItemData val = VanillaAccess.RightItem.Invoke((Humanoid)(object)p); ItemData val2 = VanillaAccess.LeftItem.Invoke((Humanoid)(object)p); if (pickR != null && pickR == pickL) { pickL = null; } if (IsShield(pickR)) { if (pickL == null) { pickL = pickR; } pickR = null; } if (pickL != null && !DualWieldInstalled && (int)pickL.m_shared.m_itemType == 3) { if (pickR == null) { pickR = pickL; } pickL = null; } ItemData val3 = pickR ?? val; ItemData val4 = pickL ?? val2; if (UsesBothHands(val3)) { val4 = ((pickL != null && pickR == null) ? pickL : null); } if (UsesBothHands(val4)) { val3 = val4; val4 = null; } if (val4 != null && val4 == val3) { val4 = null; } if (pickL != null && pickR == null && UsesBothHands(val)) { val3 = null; } if (val3 == val && val4 == val2) { return; } ItemData val5 = VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p); ItemData val6 = VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p); Busy = true; try { if (val != null) { ((Humanoid)p).UnequipItem(val, false); } if (val2 != null) { ((Humanoid)p).UnequipItem(val2, false); } if (val3 != null) { SetDualLeftMark(val3, left: false); ((Humanoid)p).EquipItem(val3, true); } if (val4 != null) { SetDualLeftMark(val4, left: true); ((Humanoid)p).EquipItem(val4, val3 == null); } ItemData val7 = ((val != null && !val.m_equipped) ? val : null); ItemData val8 = ((val2 != null && !val2.m_equipped) ? val2 : null); VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p) = (StillHolsterable((Humanoid)(object)p, val7) ? val7 : (StillHolsterable((Humanoid)(object)p, val5) ? val5 : null)); VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p) = (StillHolsterable((Humanoid)(object)p, val8) ? val8 : (StillHolsterable((Humanoid)(object)p, val6) ? val6 : null)); if (val7 != null || val8 != null) { LastRight = val7; LastLeft = val8; } VanillaAccess.SetupVisEquipment((Humanoid)(object)p); } finally { Busy = false; } ExtraHolster.MarkDirty(); } public static ItemData FindBestShield(Humanoid h) { Inventory inventory = h.GetInventory(); if (inventory == null) { return null; } ItemData result = null; float num = float.MinValue; foreach (ItemData allItem in inventory.GetAllItems()) { if (IsShield(allItem) && (!allItem.m_shared.m_useDurability || !(allItem.m_durability <= 0f))) { float baseBlockPower = allItem.GetBaseBlockPower(allItem.m_quality); if (baseBlockPower > num) { num = baseBlockPower; result = allItem; } } } return result; } public static void TryAutoEquipShield(Humanoid h, ItemData weapon) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0021: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) 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(); } 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 SortedInventory(Inventory inv) { return from i in inv.GetAllItems() where i != null orderby i.m_gridPos.y, i.m_gridPos.x select i; } public static IEnumerable PlacementOrder(Inventory inv) { return from i in SortedInventory(inv) orderby HolsterJoints.IsDualWeapon(i.m_shared) ? 1 : 0 select i; } public static List WheelItems(Player p) { List list = new List(); 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) && !DualWieldInstalled)) { 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) { ItemData val = (UsableLast((Humanoid)(object)p, LastLeft) ? LastLeft : null); ItemData val2 = (UsableLast((Humanoid)(object)p, LastRight) ? LastRight : null); bool num = val != null && val2 != null; bool busy = Busy; if (num) { Busy = true; } try { if (val != null) { ((Humanoid)p).EquipItem(val, true); } if (val2 != null) { ((Humanoid)p).EquipItem(val2, true); } return; } finally { Busy = busy; } } VanillaAccess.ShowHandItems((Humanoid)(object)p); } } finally { ModCall = false; HideKeyThisFrame = hideKeyThisFrame; } } public static bool IsAxeOrMace(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) { if ((int)s.m_skillType != 7) { return (int)s.m_skillType == 3; } return true; } return false; } public static void ApplyHipOffset(Transform t, bool left, Transform character, SharedData s) { //IL_00f1: 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_00f9: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_0139: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019e: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: 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_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: 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_01d9: 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_023a: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: 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_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)character == (Object)null)) { bool num = IsKnife(s); bool flag = !num && HolsterConfig.AxeHeadUp.Value && IsAxeOrMace(s); float num2 = (num ? HolsterConfig.KnifeTilt.Value : (flag ? HolsterConfig.AxeTilt.Value : HolsterConfig.HipTiltBack.Value)); float num3 = (num ? HolsterConfig.KnifeRoll.Value : (flag ? 0f : HolsterConfig.HipRollOut.Value)); float num4 = (num ? HolsterConfig.KnifeUp.Value : (flag ? (HolsterConfig.HipUp.Value + HolsterConfig.AxeUp.Value) : HolsterConfig.HipUp.Value)); float num5 = (num ? HolsterConfig.KnifeForward.Value : HolsterConfig.HipForward.Value); float num6 = (num ? HolsterConfig.KnifeInward.Value : HolsterConfig.HipInward.Value); float num7 = (left ? 1f : (-1f)); Vector3 right = character.right; Vector3 up = character.up; Vector3 forward = character.forward; Quaternion val = Quaternion.AngleAxis(num3 * num7, forward) * Quaternion.AngleAxis(num2, right); Vector3 val2 = val * (flag ? up : (-up)); Vector3 val3 = val * forward; float num8 = 0f; if (TryGetBladeAxes(t, out var blade, out var edge, out var length)) { Quaternion val4 = Quaternion.LookRotation(val2, val3); Quaternion val5 = Quaternion.LookRotation(blade, edge); t.rotation = val4 * Quaternion.Inverse(val5); num8 = length * Mathf.Abs(t.lossyScale.x); } 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); if (flag && num8 > 0f) { t.position -= val2 * (num8 * 0.75f); } float num9 = Mathf.Abs(character.lossyScale.x); t.position += (up * num4 + forward * num5 - num7 * right * num6 + right * value.x + up * value.y + forward * value.z) * num9; } } private static bool TryGetBladeAxes(Transform root, out Vector3 blade, out Vector3 edge, out float length) { //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_001f: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: 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_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: 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_00f7: 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_0101: 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) //IL_010e: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) blade = Vector3.zero; edge = Vector3.zero; length = 0f; bool flag = false; Vector3 val = Vector3.positiveInfinity; Vector3 val2 = Vector3.negativeInfinity; Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(false); foreach (Renderer val3 in componentsInChildren) { if (!val3.enabled) { continue; } Mesh val4 = null; if (val3 is MeshRenderer) { MeshFilter component = ((Component)val3).GetComponent(); 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; length = Mathf.Max(Mathf.Abs(((Vector3)(ref val2))[num]), Mathf.Abs(((Vector3)(ref val))[num])); 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) { 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); } VanillaAccess.HiddenRightItem.Invoke((Humanoid)(object)p) = (StillHolsterable((Humanoid)(object)p, val) ? val : (StillHolsterable((Humanoid)(object)p, val3) ? val3 : null)); VanillaAccess.HiddenLeftItem.Invoke((Humanoid)(object)p) = (StillHolsterable((Humanoid)(object)p, val2) ? val2 : (StillHolsterable((Humanoid)(object)p, val4) ? val4 : null)); VanillaAccess.SetupVisEquipment((Humanoid)(object)p); VanillaAccess.TriggerHolsterAnim((Humanoid)(object)p); } finally { Busy = false; } ExtraHolster.MarkDirty(); } private static void ToggleMark(Player player) { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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)("Marcar: nenhum item sob o 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, Loc.T("This item can't stay on your body.", "Esse item não pode ficar no corpo."), 0, (Sprite)null, false); return; } if (IsTool(hoveredPlayerItem) && !HolsterConfig.HolsterTools.Value) { ((Character)player).Message((MessageType)1, Loc.T("Tools never stay on your body.", "Ferramentas nunca são guardadas no corpo."), 0, (Sprite)null, false); return; } bool flag = !IsMarked(hoveredPlayerItem); SetMarked(hoveredPlayerItem, flag); 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("Marcar: {0} tipo={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 ? "marcado" : "desmarcado")); } ((Character)player).Message((MessageType)1, flag ? Loc.T(text + ": stays on your body", text + ": fica no corpo") : Loc.T(text + ": won't stay on your body", text + ": não fica no corpo"), 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 TMP_Text Badge; 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 readonly Color PickColor = new Color(0.45f, 1f, 0.55f, 1f); private static readonly Color HintColor = new Color(0.8f, 0.74f, 0.62f, 0.7f); private static float _swallowUntil; 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 _items = new List(); private static ItemData _pickR; private static ItemData _pickL; 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 TMP_Text _picksLabel; private static TMP_Text _hint; private static readonly List _slots = new List(); private static bool _gamepad; private static bool _joyWheelUsed; private static float _stickRepeatAt; private const float StickRepeat = 0.2f; private static TMP_FontAsset _font; public static bool Holding { get; private set; } public static bool IsOpen { get; private set; } public static bool BlocksInput { get { if (!IsOpen) { return Time.unscaledTime < _swallowUntil; } return true; } } 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; _gamepad = false; _holdStart = Now; _secondPress = _pendingTapAt >= 0f && Now - _pendingTapAt <= HolsterConfig.DoubleTapWindow.Value; } public static void OnJoyHideDown() { Holding = true; _gamepad = true; _joyWheelUsed = false; _holdStart = Now; _secondPress = false; } public static bool ConsumeJoyRelease() { bool joyWheelUsed = _joyWheelUsed; _joyWheelUsed = false; return joyWheelUsed; } 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 (_gamepad ? ZInput.GetButton("JoyHide") : ZInput.GetButton("Hide")) { if (!IsOpen && !_secondPress && Now - _holdStart >= HolsterConfig.WheelHoldTime.Value) { _items = HolsterLogic.WheelItems(localPlayer); if (_items.Count > 0) { Open(localPlayer); if (_gamepad) { _joyWheelUsed = true; } } } if (IsOpen && _gamepad) { if (ZInput.GetButtonDown("JoyButtonB")) { Holding = false; Close(instant: false); } else { ReadStickInput(); } } else { if (!IsOpen) { return; } bool dualWieldInstalled = HolsterLogic.DualWieldInstalled; if (UnityInput.Current.GetMouseButtonDown(2) || (!dualWieldInstalled && UnityInput.Current.GetMouseButtonDown(1))) { Holding = false; Close(instant: false); return; } if (dualWieldInstalled) { ReadPickInput(); } ReadSpinInput(); } return; } Holding = false; if (IsOpen) { int selected = Selected; ItemData val = ((selected >= 0) ? _items[selected] : null); ItemData pickR = _pickR; ItemData pickL = _pickL; Close(instant: false); if (pickR != null || pickL != null) { HolsterLogic.EquipHands(localPlayer, pickR, pickL); } else if (val != null && !val.m_equipped && !((Character)localPlayer).InAttack() && !((Character)localPlayer).InDodge()) { ((Humanoid)localPlayer).EquipItem(val, true); } } else if (!_gamepad) { 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 ReadPickInput() { int selected = Selected; if (selected < 0) { return; } ItemData val = _items[selected]; if (UnityInput.Current.GetMouseButtonDown(0)) { if (_pickL == val) { _pickL = null; } else { _pickL = val; if (_pickR == val) { _pickR = null; } } UpdatePicksLabel(); } if (!UnityInput.Current.GetMouseButtonDown(1)) { return; } if (_pickR == val) { _pickR = null; } else { _pickR = val; if (_pickL == val) { _pickL = null; } } UpdatePicksLabel(); } private static string ItemName(ItemData item) { if (Localization.instance == null) { return item.m_shared.m_name; } return Localization.instance.Localize(item.m_shared.m_name); } private static void UpdatePicksLabel() { if (!((Object)(object)_picksLabel == (Object)null)) { string text = ((_pickL != null) ? ItemName(_pickL) : "—"); string text2 = ((_pickR != null) ? ItemName(_pickR) : "—"); _picksLabel.text = ((_pickL == null && _pickR == null) ? "" : ("E: " + text + " · D: " + text2)); } } private static void ReadStickInput() { if (_items.Count > 1) { float num = ZInput.GetJoyRightStickX(); if (Mathf.Abs(num) < 0.15f) { num = (ZInput.GetButton("JoyDPadRight") ? 1f : (ZInput.GetButton("JoyDPadLeft") ? (-1f) : 0f)); } if (Mathf.Abs(num) < 0.5f) { _stickRepeatAt = 0f; } else if (!(Now < _stickRepeatAt)) { _targetIndex += ((num > 0f) ? 1 : (-1)); _stickRepeatAt = Now + ((_stickRepeatAt == 0f) ? 0.32000002f : 0.2f); } } } private static void ReadSpinInput() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (_items.Count > 1) { _mouseAccum += ZInput.GetMouseDelta().x; 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(); _group.alpha = 0f; _root.SetActive(true); IsOpen = true; _closingAt = -1f; _openedAt = Now; _mouseAccum = 0f; _spinVelocity = 0f; _shownSelected = -1; _pickR = null; _pickL = null; 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(); try { for (int j = 0; j < _items.Count; j++) { _slots.Add(CreateSlot(j, _items[j], _items[j] == val || _items[j] == val2)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Roda: falha ao montar os slots: " + ex.Message)); IsOpen = false; _root.SetActive(false); return; } SetLabels(null); UpdatePicksLabel(); _hint.text = (_gamepad ? Loc.T("Right stick: spin · release to equip · B: cancel", "Analógico direito: girar · solte pra equipar · B: cancelar") : (HolsterLogic.DualWieldInstalled ? Loc.T("Left click: left hand · right click: right hand · middle: cancel", "Clique esq.: mão esquerda · dir.: mão direita · meio: cancelar") : Loc.T("Release R to equip · right click: cancel", "Solte o R pra equipar · botão direito: cancelar"))); Animate(); } private static void Close(bool instant) { if (!IsOpen && _closingAt < 0f) { return; } IsOpen = false; if (_gamepad) { _swallowUntil = Now + 0.2f; } 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: 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 || _slots.Count != count) { return; } 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); ItemData val = _items[i]; bool flag = val == _pickR || val == _pickL; ((Graphic)slot.Rim).color = Color.Lerp(flag ? PickColor : (slot.Holstered ? RimHolstered : RimIdle), Gold, slot.Pop * (flag ? 0.35f : 1f)); string text = ((val == _pickL) ? "E" : ((val == _pickR) ? "D" : "")); if (slot.Badge.text != text) { slot.Badge.text = text; } 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; _picksLabel.alpha = _group.alpha; } 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 ? Loc.T(" · holstered", " · guardada") : ""); } } private static string KindName(ItemData item) { //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_0029: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Invalid comparison between Unknown and I4 //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Invalid comparison between Unknown and I4 SharedData shared = item.m_shared; if (HolsterJoints.IsStaff(shared)) { return Loc.T("Staff", "Cajado"); } ItemType itemType = shared.m_itemType; if ((int)itemType <= 14) { switch (itemType - 3) { case 1: if ((int)shared.m_skillType != 14) { return Loc.T("Bow", "Arco"); } return Loc.T("Crossbow", "Besta"); case 2: return Loc.T("Shield", "Escudo"); case 0: if ((int)shared.m_skillType != 5) { if ((int)shared.m_skillType != 2) { return Loc.T("One-handed", "Uma mão"); } return Loc.T("Knife", "Faca"); } return Loc.T("Spear", "Lança"); } if ((int)itemType == 14) { goto IL_009d; } } else { if ((int)itemType == 15) { return Loc.T("Torch", "Tocha"); } if ((int)itemType == 19) { return Loc.T("Tool", "Ferramenta"); } if ((int)itemType == 22) { goto IL_009d; } } return ""; IL_009d: return Loc.T("Two-handed", "Duas mãos"); } 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) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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(), 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; obj.Badge = NewText("Badge", (Transform)(object)val2, FindGameFont(), 22f, 14f, PickColor, new Vector2(30.240002f, -30.240002f), 34f, (FontStyles)1); obj.Badge.text = ""; return obj; } private static void EnsureUI() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_005e: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00dd: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_029f: 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) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("ValheimHolster_Wheel"); Object.DontDestroyOnLoad((Object)(object)_root); Canvas obj = _root.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 500; CanvasScaler obj2 = _root.AddComponent(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 1f; _group = _root.AddComponent(); _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); _picksLabel = NewText("Picks", (Transform)(object)_content, font, 15f, 11f, PickColor, new Vector2(0f, -44f), width, (FontStyles)1); _hint = NewText("Hint", (Transform)(object)_content, font, 15f, 11f, HintColor, new Vector2(0f, -251f), 640f, (FontStyles)0); _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_006a: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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(); 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; if (val.activeInHierarchy) { try { ((TMP_Text)val3).outlineWidth = 0.18f; ((TMP_Text)val3).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)220); } catch { } } 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[] 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 dictionary = new Dictionary(); TMP_Text[] array3 = (((Object)(object)Hud.instance != (Object)null) ? ((Component)Hud.instance).GetComponentsInChildren(true) : Resources.FindObjectsOfTypeAll()); 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 item in dictionary) { if (item.Value > num) { num = item.Value; _font = item.Key; } } if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogInfo((object)("Roda: fonte " + (((Object)(object)_font != (Object)null) ? ((Object)_font).name : "NENHUMA"))); } 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(); 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)Grid != (Object)null && (Object)(object)Element != (Object)null) { return ((Component)Element).gameObject.activeInHierarchy; } return false; } } public static void Enter(GameObject tooltipGo) { InventoryElement componentInParent = tooltipGo.GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null)) { _source = tooltipGo; Element = componentInParent; Grid = ((Component)componentInParent).GetComponentInParent(); } } 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"); } } internal static class KeepLoaded { internal const string LoadedKey = "ValheimHolster.Loaded"; private static readonly FieldRef WeaponLoaded = AccessTools.FieldRefAccess("m_weaponLoaded"); private static readonly MethodInfo SetWeaponLoaded = AccessTools.Method(typeof(Player), "SetWeaponLoaded", (Type[])null, (Type[])null); internal static bool NeedsReload(ItemData item) { if (item?.m_shared?.m_attack != null) { return item.m_shared.m_attack.m_requiresReload; } return false; } internal static void OnUnequip(Player player, ItemData item) { if (NeedsReload(item)) { if (WeaponLoaded.Invoke(player) == item) { item.m_customData["ValheimHolster.Loaded"] = "1"; } else { item.m_customData.Remove("ValheimHolster.Loaded"); } } } internal static void OnEquip(Player player, ItemData item) { if (NeedsReload(item) && item.m_customData.ContainsKey("ValheimHolster.Loaded")) { item.m_customData.Remove("ValheimHolster.Loaded"); if (SetWeaponLoaded != null) { SetWeaponLoaded.Invoke(player, new object[1] { item }); } } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] internal static class KeepLoaded_Unequip_Patch { [HarmonyPriority(800)] private static void Prefix(Humanoid __instance, ItemData item) { if (HolsterConfig.Enabled.Value && HolsterConfig.KeepLoaded.Value) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && item != null && __instance.IsItemEquiped(item)) { KeepLoaded.OnUnequip(val, item); } } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class KeepLoaded_Equip_Patch { [HarmonyPriority(0)] private static void Postfix(Humanoid __instance, ItemData item, bool __result) { if (__result && HolsterConfig.Enabled.Value && HolsterConfig.KeepLoaded.Value) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && item != null) { KeepLoaded.OnEquip(val, item); } } } } internal static class ReloadTweaks { internal const int ReloadActionType = 2; [ThreadStatic] internal static bool InCheckRun; private static readonly FieldInfo ActionQueue = AccessTools.Field(typeof(Player), "m_actionQueue"); private static readonly MethodInfo IsReloadQueued = AccessTools.Method(typeof(Player), "IsReloadActionQueued", (Type[])null, (Type[])null); private static FieldInfo _typeField; internal static bool Active(Player p) { if ((Object)(object)p != (Object)null && (Object)(object)p == (Object)(object)Player.m_localPlayer && HolsterConfig.Enabled.Value) { return HolsterConfig.ReloadWhileRunning.Value; } return false; } internal static bool Reloading(Player p) { if (IsReloadQueued != null) { return (bool)IsReloadQueued.Invoke(p, null); } return false; } internal static void ClearExceptReload(Player p) { if (!(ActionQueue?.GetValue(p) is IList list)) { return; } for (int num = list.Count - 1; num >= 0; num--) { object obj = list[num]; if (obj == null) { list.RemoveAt(num); } else { if (_typeField == null) { _typeField = AccessTools.Field(obj.GetType(), "m_type"); } if (_typeField == null || Convert.ToInt32(_typeField.GetValue(obj)) != 2) { list.RemoveAt(num); } } } } } [HarmonyPatch(typeof(Player), "CheckRun")] internal static class ReloadTweaks_CheckRun_Patch { private static void Prefix(Player __instance) { ReloadTweaks.InCheckRun = ReloadTweaks.Active(__instance); } private static Exception Finalizer(Exception __exception) { ReloadTweaks.InCheckRun = false; return __exception; } } [HarmonyPatch(typeof(Player), "ClearActionQueue")] internal static class ReloadTweaks_ClearActionQueue_Patch { private static bool Prefix(Player __instance) { if (!ReloadTweaks.InCheckRun) { return true; } ReloadTweaks.ClearExceptReload(__instance); return false; } } [HarmonyPatch(typeof(Player), "InMinorActionSlowdown")] internal static class ReloadTweaks_Slowdown_Patch { private static void Postfix(Player __instance, ref bool __result) { if (__result && ReloadTweaks.Active(__instance) && ReloadTweaks.Reloading(__instance)) { __result = false; } } } [HarmonyPatch(typeof(ItemData), "GetWeaponLoadingTime")] internal static class ReloadTweaks_LoadingTime_Patch { private static void Postfix(ItemData __instance, ref float __result) { if (HolsterConfig.Enabled.Value && __instance.m_shared.m_attack.m_requiresReload) { float value = HolsterConfig.ReloadSpeed.Value; if (value > 0.01f && Mathf.Abs(value - 1f) > 0.001f) { __result /= value; } } } } [HarmonyPatch(typeof(Player), "QueueReloadAction")] internal static class ReloadTweaks_NeedsAmmo_Patch { private static ItemData _warned; private static bool Prefix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !HolsterConfig.Enabled.Value || !HolsterConfig.ReloadNeedsAmmo.Value) { return true; } ItemData currentWeapon = ((Humanoid)__instance).GetCurrentWeapon(); if (currentWeapon == null || !currentWeapon.m_shared.m_attack.m_requiresReload) { return true; } if (string.IsNullOrEmpty(currentWeapon.m_shared.m_ammoType)) { return true; } if (((Humanoid)__instance).GetInventory().GetAmmoItem(currentWeapon.m_shared.m_ammoType, (string)null) != null) { _warned = null; return true; } if (_warned != currentWeapon) { _warned = currentWeapon; ((Character)__instance).Message((MessageType)2, "$msg_outof " + currentWeapon.m_shared.m_ammoType, 0, (Sprite)null, false); } return false; } } internal static class Loc { private static string _gameLang; private static float _checkedAt = -10f; public static bool Portuguese { get { switch ((HolsterConfig.Language != null) ? HolsterConfig.Language.Value : TextLanguage.Auto) { case TextLanguage.English: return false; case TextLanguage.Portuguese: return true; default: if (_gameLang == null || Time.unscaledTime - _checkedAt > 5f) { _checkedAt = Time.unscaledTime; try { _gameLang = ((Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : ""); } catch { _gameLang = ""; } } if (_gameLang != null) { return _gameLang.StartsWith("Portuguese"); } return false; } } } public static string T(string en, string pt) { if (!Portuguese) { return en; } return pt; } } internal static class MarkBadge { private const string BadgeName = "ValheimHolster_Badge"; private static Sprite _circle; private static readonly Color BadgeColor = new Color(1f, 0.62f, 0.15f, 1f); private static readonly Color RimColor = new Color(0.1f, 0.06f, 0.02f, 0.95f); public static void Refresh(InventoryGrid grid) { if ((Object)(object)grid == (Object)null) { return; } Inventory inventory = grid.GetInventory(); List list = VanillaAccess.GridElements(grid); int num = VanillaAccess.GridWidth(grid); if (inventory == null || list == null || num <= 0) { return; } bool value = HolsterConfig.Enabled.Value; for (int i = 0; i < list.Count; i++) { InventoryElement val = list[i]; if ((Object)(object)val == (Object)null) { continue; } ItemData itemAt = inventory.GetItemAt(i % num, i / num); bool flag = value && itemAt != null && HolsterLogic.IsMarked(itemAt); Transform val2 = ((Component)val).transform.Find("ValheimHolster_Badge"); if ((Object)(object)val2 == (Object)null) { if (!flag) { continue; } val2 = Create(((Component)val).transform); } if (((Component)val2).gameObject.activeSelf != flag) { ((Component)val2).gameObject.SetActive(flag); } } } private static Transform Create(Transform parent) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_014c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_circle == (Object)null) { _circle = UiUtil.Circle(); } GameObject val = new GameObject("ValheimHolster_Badge", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(3f, -3f); val2.sizeDelta = new Vector2(16f, 16f); Image obj = val.AddComponent(); obj.sprite = _circle; ((Graphic)obj).color = RimColor; ((Graphic)obj).raycastTarget = false; GameObject val4 = new GameObject("Dot", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent((Transform)(object)val2, false); RectTransform val5 = (RectTransform)val4.transform; ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val5.anchorMax = val3; val5.anchorMin = val3; val5.sizeDelta = new Vector2(11f, 11f); Image obj2 = val4.AddComponent(); obj2.sprite = _circle; ((Graphic)obj2).color = BadgeColor; ((Graphic)obj2).raycastTarget = false; val.transform.SetAsLastSibling(); return (Transform)(object)val2; } } internal static class Motion { internal enum Kind { Hand, Body } internal class Record { public int Hash; public Kind Kind; public Vector3 LocalPos; public Quaternion LocalRot; public float Time; public bool Claimed; } private const float Window = 1f; private static readonly Dictionary> _records = new Dictionary>(); private static readonly List _dead = new List(); internal static bool On { get { if (HolsterConfig.Enabled.Value) { return HolsterConfig.SmoothMotion.Value; } return false; } } internal static float Duration => Mathf.Max(0.05f, HolsterConfig.MotionDuration.Value); internal static void Remember(VisEquipment vis, int hash, Kind kind, Transform t) { //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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) if (!((Object)(object)vis == (Object)null) && !((Object)(object)t == (Object)null) && hash != 0) { List list = Get(vis); Prune(list); Transform transform = ((Component)vis).transform; list.Add(new Record { Hash = hash, Kind = kind, LocalPos = transform.InverseTransformPoint(t.position), LocalRot = Quaternion.Inverse(transform.rotation) * t.rotation, Time = Time.time }); } } internal static Record Take(VisEquipment vis, int hash, Kind kind) { List list = Get(vis); Prune(list); for (int num = list.Count - 1; num >= 0; num--) { Record record = list[num]; if (record.Hash == hash && record.Kind == kind && !record.Claimed) { record.Claimed = true; return record; } } return null; } internal static bool Recent(VisEquipment vis, int hash, Kind kind, float seconds) { List list = Get(vis); for (int num = list.Count - 1; num >= 0; num--) { Record record = list[num]; if (record.Hash == hash && record.Kind == kind && Time.time - record.Time <= seconds) { return true; } } return false; } internal static bool Claimed(VisEquipment vis, int hash) { if (!_records.TryGetValue(((Object)vis).GetInstanceID(), out var value)) { return false; } for (int num = value.Count - 1; num >= 0; num--) { if (value[num].Hash == hash && value[num].Kind == Kind.Hand) { return value[num].Claimed; } } return false; } private static List Get(VisEquipment vis) { int instanceID = ((Object)vis).GetInstanceID(); if (!_records.TryGetValue(instanceID, out var value)) { if (_records.Count > 64) { Cleanup(); } value = new List(); _records[instanceID] = value; } return value; } private static void Prune(List list) { float now = Time.time; list.RemoveAll((Record r) => now - r.Time > 1f); } private static void Cleanup() { _dead.Clear(); foreach (KeyValuePair> record in _records) { Prune(record.Value); if (record.Value.Count == 0) { _dead.Add(record.Key); } } foreach (int item in _dead) { _records.Remove(item); } } internal static float EaseInOut(float t) { return t * t * (3f - 2f * t); } internal static void SpawnGhost(VisEquipment vis, GameObject source, int hash, Transform hand) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_00f0: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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) if ((Object)(object)source == (Object)null || (Object)(object)hand == (Object)null) { return; } GameObject val = new GameObject("ValheimHolster_Ghost"); val.transform.SetParent(hand, false); val.transform.position = source.transform.position; val.transform.rotation = source.transform.rotation; val.transform.localScale = Vector3.one; int num = 0; MeshFilter[] componentsInChildren = source.GetComponentsInChildren(); foreach (MeshFilter val2 in componentsInChildren) { MeshRenderer component = ((Component)val2).GetComponent(); if (!((Object)(object)component == (Object)null) && ((Renderer)component).enabled && !((Object)(object)val2.sharedMesh == (Object)null)) { GameObject val3 = new GameObject("part"); val3.transform.SetParent(val.transform, false); val3.transform.position = ((Component)val2).transform.position; val3.transform.rotation = ((Component)val2).transform.rotation; val3.transform.localScale = Divide(((Component)val2).transform.lossyScale, val.transform.lossyScale); val3.AddComponent().sharedMesh = val2.sharedMesh; MeshRenderer obj = val3.AddComponent(); ((Renderer)obj).sharedMaterials = ((Renderer)component).sharedMaterials; ((Renderer)obj).shadowCastingMode = ((Renderer)component).shadowCastingMode; num++; } } if (num == 0) { Object.Destroy((Object)(object)val); return; } MotionGhost motionGhost = val.AddComponent(); motionGhost.Vis = vis; motionGhost.Hash = hash; } private static Vector3 Divide(Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_000d: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) return new Vector3((b.x != 0f) ? (a.x / b.x) : a.x, (b.y != 0f) ? (a.y / b.y) : a.y, (b.z != 0f) ? (a.z / b.z) : a.z); } } internal class MotionTween : MonoBehaviour { public int Hash; public Motion.Kind Kind; private float _created = -1f; private VisEquipment _vis; private Vector3 _toPos; private Vector3 _toScale; private Quaternion _toRot; private Motion.Record _from; private bool _pop; private float _t; private bool _started; private bool _waiting; private float _wait; public void Init(int hash, Motion.Kind kind) { Hash = hash; Kind = kind; _created = Time.time; } private void Start() { //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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_00fc: Unknown result type (might be due to invalid IL or missing references) _vis = ((Component)this).GetComponentInParent(); _toPos = ((Component)this).transform.localPosition; _toRot = ((Component)this).transform.localRotation; _toScale = ((Component)this).transform.localScale; if ((Object)(object)_vis == (Object)null || !Motion.On) { ((Behaviour)this).enabled = false; return; } if (_created >= 0f && Time.time - _created > 0.5f) { ((Behaviour)this).enabled = false; return; } Motion.Kind kind = ((Kind != Motion.Kind.Body) ? Motion.Kind.Body : Motion.Kind.Hand); _from = Motion.Take(_vis, Hash, kind); if (_from == null) { if (Kind == Motion.Kind.Body && Motion.Recent(_vis, Hash, Motion.Kind.Body, 0.6f)) { ((Behaviour)this).enabled = false; return; } if (Kind == Motion.Kind.Hand) { _waiting = true; ((Component)this).transform.localScale = _toScale * 0.01f; return; } _pop = true; } _started = true; Apply(0f); } private void LateUpdate() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (_waiting) { _wait += Time.deltaTime; _from = Motion.Take(_vis, Hash, Motion.Kind.Body); if (_from == null && _wait < 0.15f) { ((Component)this).transform.localScale = _toScale * 0.01f; return; } _waiting = false; _pop = _from == null; ((Component)this).transform.localScale = _toScale; _started = true; Apply(0f); } else if (_started) { _t += Time.deltaTime / (_pop ? (Motion.Duration * 0.7f) : Motion.Duration); if (_t >= 1f) { Finish(); } else { Apply(_t); } } } private void Apply(float t) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0077: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00b5: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00f3: 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_00fd: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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) if (_pop) { float num = UiUtil.EaseOutBack(Mathf.Clamp01(t)); ((Component)this).transform.localScale = _toScale * Mathf.Max(0.01f, num); return; } float num2 = Motion.EaseInOut(Mathf.Clamp01(t)); Transform transform = ((Component)_vis).transform; Vector3 val = transform.TransformPoint(_from.LocalPos); Quaternion val2 = transform.rotation * _from.LocalRot; Transform parent = ((Component)this).transform.parent; Vector3 val3 = (((Object)(object)parent != (Object)null) ? parent.TransformPoint(_toPos) : _toPos); Quaternion val4 = (((Object)(object)parent != (Object)null) ? (parent.rotation * _toRot) : _toRot); Vector3 position = Vector3.Lerp(val, val3, num2) + transform.forward * (Mathf.Sin(num2 * MathF.PI) * 0.08f * transform.lossyScale.x); ((Component)this).transform.position = position; ((Component)this).transform.rotation = Quaternion.Slerp(val2, val4, num2); } private void Finish() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) _waiting = false; ((Component)this).transform.localPosition = _toPos; ((Component)this).transform.localRotation = _toRot; ((Component)this).transform.localScale = _toScale; _started = false; ((Behaviour)this).enabled = false; } private void OnDestroy() { if (Kind == Motion.Kind.Body && (Object)(object)_vis != (Object)null) { if (_started || _waiting) { Finish(); } Motion.Remember(_vis, Hash, Motion.Kind.Body, ((Component)this).transform); } } } internal class MotionGhost : MonoBehaviour { public VisEquipment Vis; public int Hash; private float _age; private float _shrink = -1f; private Vector3 _scale; private void Start() { //IL_0007: 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) _scale = ((Component)this).transform.localScale; } private void LateUpdate() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) _age += Time.deltaTime; if ((Object)(object)Vis == (Object)null || !Motion.On || Motion.Claimed(Vis, Hash)) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } if (_shrink < 0f) { if (_age < 0.12f) { return; } _shrink = 0f; } _shrink += Time.deltaTime / (Motion.Duration * 0.6f); if (_shrink >= 1f) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num = 1f - Motion.EaseInOut(_shrink); ((Component)this).transform.localScale = _scale * Mathf.Max(0.01f, num); } } internal struct HandState { public int OldHash; public bool Changed; } [HarmonyPatch(typeof(VisEquipment), "SetRightHandEquipped")] internal static class Motion_RightHand_Patch { private static readonly FieldRef CurHash = AccessTools.FieldRefAccess("m_currentRightItemHash"); private static readonly FieldRef Inst = AccessTools.FieldRefAccess("m_rightItemInstance"); private static void Prefix(VisEquipment __instance, int hash, out HandState __state) { __state = default(HandState); if (!Motion.On) { return; } int num = CurHash.Invoke(__instance); if (num != hash) { __state = new HandState { OldHash = num, Changed = true }; GameObject val = Inst.Invoke(__instance); if (num != 0 && (Object)(object)val != (Object)null) { Motion.Remember(__instance, num, Motion.Kind.Hand, val.transform); Motion.SpawnGhost(__instance, val, num, __instance.m_rightHand); } } } private static void Postfix(VisEquipment __instance, int hash, HandState __state) { if (__state.Changed && hash != 0) { GameObject val = Inst.Invoke(__instance); if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent() == (Object)null) { val.AddComponent().Init(hash, Motion.Kind.Hand); } } } } [HarmonyPatch(typeof(VisEquipment), "SetLeftHandEquipped")] internal static class Motion_LeftHand_Patch { private static readonly FieldRef CurHash = AccessTools.FieldRefAccess("m_currentLeftItemHash"); private static readonly FieldRef Inst = AccessTools.FieldRefAccess("m_leftItemInstance"); private static void Prefix(VisEquipment __instance, int hash, out HandState __state) { __state = default(HandState); if (!Motion.On) { return; } int num = CurHash.Invoke(__instance); if (num != hash) { __state = new HandState { OldHash = num, Changed = true }; GameObject val = Inst.Invoke(__instance); if (num != 0 && (Object)(object)val != (Object)null) { Motion.Remember(__instance, num, Motion.Kind.Hand, val.transform); Motion.SpawnGhost(__instance, val, num, __instance.m_leftHand); } } } private static void Postfix(VisEquipment __instance, int hash, HandState __state) { if (__state.Changed && hash != 0) { GameObject val = Inst.Invoke(__instance); if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent() == (Object)null) { val.AddComponent().Init(hash, Motion.Kind.Hand); } } } } [HarmonyPatch(typeof(VisEquipment), "AttachBackItem")] internal static class Motion_BackItem_Patch { private static void Postfix(int hash, GameObject __result) { if (!((Object)(object)__result == (Object)null) && hash != 0 && (Object)(object)__result.GetComponent() == (Object)null) { __result.AddComponent().Init(hash, Motion.Kind.Body); } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class Motion_Equip_Patch { private static void Postfix(Humanoid __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { ExtraHolster.MarkDirty(); } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] internal static class Motion_Unequip_Patch { private static void Postfix(Humanoid __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { ExtraHolster.MarkDirty(); } } } internal struct EquipState { public bool Track; public ItemData Right; public ItemData Left; public ItemData HiddenRight; public ItemData HiddenLeft; } [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) ? val3 : ((HolsterLogic.StillHolsterable(__instance, __state.HiddenRight) && __state.HiddenRight != item) ? __state.HiddenRight : null)); ItemData val6 = (HolsterLogic.StillHolsterable(__instance, val4) ? val4 : ((HolsterLogic.StillHolsterable(__instance, __state.HiddenLeft) && __state.HiddenLeft != item) ? __state.HiddenLeft : null)); 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), "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(Player), "Update")] internal static class Player_Update_Patch { private static void Prefix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } bool buttonDown = ZInput.GetButtonDown("Hide"); bool buttonUp = ZInput.GetButtonUp("JoyHide"); HolsterLogic.HideKeyThisFrame = buttonDown || buttonUp; HolsterLogic.SuppressVanillaHide = false; if (HolsterConfig.Enabled.Value && HolsterConfig.WheelEnabled.Value && HolsterConfig.WheelGamepad.Value) { if (ZInput.GetButtonDown("JoyHide") && !Hud.InRadial() && VanillaAccess.TakeInput((Character)(object)__instance)) { HolsterWheel.OnJoyHideDown(); } if (buttonUp && HolsterWheel.ConsumeJoyRelease()) { HolsterLogic.SuppressVanillaHide = true; HolsterLogic.HideKeyThisFrame = false; } } if (buttonDown && HolsterConfig.Enabled.Value && HolsterConfig.WheelEnabled.Value && !Hud.InRadial() && VanillaAccess.TakeInput((Character)(object)__instance)) { HolsterLogic.SuppressVanillaHide = true; HolsterWheel.OnHideDown(); } } private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { HolsterLogic.HideKeyThisFrame = false; HolsterLogic.SuppressVanillaHide = false; } } } [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), "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(VisEquipment), "AttachBackItem")] internal static class VisEquipment_AttachBackItem_Patch { private static bool Prefix(VisEquipment __instance, int hash, int variant, int quality, object[] __args, ref GameObject __result) { if (!HolsterConfig.Enabled.Value || (Object)(object)ObjectDB.instance == (Object)null) { return true; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(hash); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val == (Object)null) { return true; } if (!HolsterConfig.OneHandOnHip.Value || (Object)(object)__instance.m_backTool == (Object)null) { return true; } if (!HolsterLogic.GoesOnHip(val.m_itemData.m_shared)) { return true; } bool flag = __args != null && __args.Length > 2 && __args[2] is bool flag2 && !flag2 && HolsterConfig.UseLeftHip.Value; Transform val2 = (flag ? HolsterJoints.Resolve(__instance, HolsterJoint.HipLeft) : __instance.m_backTool); if ((Object)(object)val2 == (Object)null) { val2 = __instance.m_backTool; flag = false; } GameObject val3 = VanillaAccess.AttachItem(__instance, hash, variant, quality, val2); if ((Object)(object)val3 == (Object)null) { return true; } HolsterLogic.ApplyHipOffset(val3.transform, flag, ((Component)__instance).transform, val.m_itemData.m_shared); __result = val3; return false; } } [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(Player), "SetMouseLook")] internal static class Player_SetMouseLook_Patch { private static bool Prefix() { return !HolsterWheel.BlocksInput; } } [HarmonyPatch(typeof(Player), "SetControls")] internal static class Player_SetControls_Patch { private static void Prefix(Player __instance, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold, ref bool dodge) { if (HolsterWheel.BlocksInput && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { attack = (attackHold = (secondaryAttack = (secondaryAttackHold = (block = (blockHold = (dodge = false)))))); } } } [HarmonyPatch(typeof(VisEquipment), "Awake")] internal static class VisEquipment_Awake_Patch { private static void Postfix(VisEquipment __instance) { if (!((Object)(object)((Component)__instance).GetComponent() == (Object)null) && (Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } } [HarmonyPatch(typeof(UITooltip), "OnPointerEnter")] internal static class UITooltip_OnPointerEnter_Patch { private static void Postfix(UITooltip __instance) { HoverTracker.Enter(((Component)__instance).gameObject); } } [HarmonyPatch(typeof(UITooltip), "OnPointerExit")] internal static class UITooltip_OnPointerExit_Patch { private static void Postfix(UITooltip __instance) { HoverTracker.Exit(((Component)__instance).gameObject); } } [HarmonyPatch] internal static class ItemData_GetTooltip_Patch { private static MethodBase TargetMethod() { MethodInfo[] methods = typeof(ItemData).GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "GetTooltip") && !(methodInfo.ReturnType != typeof(string))) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != 0 && parameters[0].ParameterType == typeof(ItemData)) { return methodInfo; } } } return null; } private static bool Prepare() { return TargetMethod() != null; } private static void Postfix(ItemData item, ref string __result) { //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) if (HolsterConfig.Enabled.Value && HolsterConfig.ShowTooltip.Value && item != null && HolsterLogic.IsHandItem(item) && (!HolsterLogic.IsTool(item) || HolsterConfig.HolsterTools.Value)) { string text = ((object)HolsterConfig.MarkKey.Value/*cast due to .constrained prefix*/).ToString(); __result += (HolsterLogic.IsMarked(item) ? Loc.T("\nStays on body (" + text + " to unmark)", "\nFica no corpo (" + text + " pra desmarcar)") : Loc.T("\n" + text + ": keep on body", "\n" + text + ": deixar no corpo")); } } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] internal static class InventoryGrid_UpdateGui_Patch { private static void Postfix(InventoryGrid __instance) { if ((Object)(object)InventoryGui.instance != (Object)null && (Object)(object)__instance == (Object)(object)InventoryGui.instance.m_playerGrid) { MarkBadge.Refresh(__instance); } } } [HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")] internal static class ZInput_GetMouseScrollWheel_Patch { private static void Postfix(ref float __result) { if (HolsterWheel.BlocksInput) { __result = 0f; } } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] internal static class GameCamera_UpdateCamera_Patch { private static readonly FieldRef Distance = AccessTools.FieldRefAccess("m_distance"); private static void Prefix(GameCamera __instance, out float __state) { __state = Distance.Invoke(__instance); } private static void Postfix(GameCamera __instance, float __state) { if (HolsterWheel.BlocksInput) { Distance.Invoke(__instance) = __state; } } } [BepInPlugin("padilha.ValheimHolster", "ValheimHolster", "1.0.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string ModGuid = "padilha.ValheimHolster"; public const string ModName = "ValheimHolster"; public const string ModVersion = "1.0.4"; internal static Plugin Instance; internal static ManualLogSource Log; private Harmony _harmony; private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; HolsterConfig.Bind(CreateConfig()); VanillaAccess.Init(); _harmony = new Harmony("padilha.ValheimHolster"); Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0) { try { _harmony.CreateClassProcessor(type).Patch(); } catch (Exception ex) { Log.LogError((object)("Falha ao aplicar " + type.Name + ": " + ex.Message)); } } } Log.LogInfo((object)"ValheimHolster 1.0.4 carregado."); } private ConfigFile CreateConfig() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown string text = Path.Combine(Paths.ConfigPath, "ValheimHolster"); Directory.CreateDirectory(text); ConfigFile val = new ConfigFile(Path.Combine(text, "ValheimHolster.cfg"), true, ((BaseUnityPlugin)this).Info.Metadata); FieldInfo fieldInfo = AccessTools.Field(typeof(BaseUnityPlugin), "k__BackingField"); if (fieldInfo != null) { fieldInfo.SetValue(this, val); } else { Log.LogWarning((object)"Não deu pra trocar a Config do plugin — o Configuration Manager pode não mostrar as opções."); } return val; } private void Update() { HolsterLogic.HandleHotkeys(); HolsterWheel.Tick(); ExtraHolster.Tick(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class Quiver { public const int Empty = -1; private const float Height = 0.5f; private const float Radius = 0.065f; private const int Segments = 14; private static readonly Color Leather = new Color(0.32f, 0.2f, 0.11f, 1f); private static readonly Color LeatherDark = new Color(0.18f, 0.11f, 0.06f, 1f); private static Mesh _tube; private static Mesh _rim; private static Material _leather; private static Material _leatherDark; private static readonly Dictionary> _arrowCache = new Dictionary>(); public static GameObject Build(VisEquipment vis, int ammoHash) { try { return BuildInner(vis, ammoHash); } catch (Exception ex) { if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogWarning((object)("Aljava: " + ex.Message)); } return null; } } private static GameObject BuildInner(VisEquipment vis, int ammoHash) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: 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_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: 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_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: 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_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0232: 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_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_0301: 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) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Expected O, but got Unknown Transform val = (((Object)(object)vis.m_backBow != (Object)null) ? vis.m_backBow : vis.m_backMelee); if ((Object)(object)val == (Object)null || (Object)(object)val.parent == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return null; } bool flag = ammoHash == -1; List<(Mesh, Material[], Matrix4x4)> list = (flag ? null : ArrowParts(ammoHash)); if (!flag && (list == null || list.Count == 0)) { if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogWarning((object)"Aljava: munição sem modelo, montando vazia."); } flag = true; } Material[] sample = ((!flag) ? list[0].Item2 : SampleMaterials(vis)); Transform transform = ((Component)vis).transform; GameObject val2 = new GameObject("ValheimHolster_Quiver"); Transform transform2 = val2.transform; transform2.SetParent(transform, false); transform2.localScale = Vector3.one * HolsterConfig.QuiverScale.Value; QuiverFollow quiverFollow = val2.AddComponent(); quiverFollow.Anchor = val; quiverFollow.Character = transform; quiverFollow.Offset = HolsterConfig.QuiverPosition.Value; quiverFollow.Rotation = Quaternion.Euler(HolsterConfig.QuiverRotation.Value); quiverFollow.Snap(); GameObject val3 = new GameObject("Tube"); val3.transform.SetParent(transform2, false); val3.transform.localPosition = new Vector3(0f, -0.25f, 0f); AddMesh(val3, TubeMesh(), LeatherMaterial(sample, dark: false)); GameObject val4 = new GameObject("Rim"); val4.transform.SetParent(val3.transform, false); val4.transform.localPosition = new Vector3(0f, 0.45f, 0f); AddMesh(val4, RimMesh(), LeatherMaterial(sample, dark: true)); if (flag) { return val2; } Bounds val5 = ArrowBounds(list); Vector3 size = ((Bounds)(ref val5)).size; int num = 2; if (size.x > ((Vector3)(ref size))[num]) { num = 0; } if (size.y > ((Vector3)(ref size))[num]) { num = 1; } float num2 = Mathf.Max(((Vector3)(ref size))[num], 0.05f); Vector3 zero = Vector3.zero; ((Vector3)(ref zero))[num] = 1f; Vector3 center = ((Bounds)(ref val5)).center; int num3 = num; Vector3 max = ((Bounds)(ref val5)).max; ((Vector3)(ref center))[num3] = ((Vector3)(ref max))[num]; float num4 = 0.11f; float num5 = Mathf.Clamp((0.45f + num4) / num2, 0.2f, 1.6f); Quaternion val6 = Quaternion.FromToRotation(zero, Vector3.down); int num6 = Mathf.Clamp(HolsterConfig.QuiverArrows.Value, 1, 10); Random random = new Random(ammoHash); for (int i = 0; i < num6; i++) { float num7 = (float)i / (float)num6 * MathF.PI * 2f + (float)random.NextDouble() * 0.4f; float num8 = ((num6 == 1) ? 0f : 0.029249998f); Transform transform3 = new GameObject("Arrow" + i).transform; transform3.SetParent(val3.transform, false); transform3.localScale = Vector3.one * num5; transform3.localRotation = Quaternion.Euler(Mathf.Lerp(-4f, 4f, (float)random.NextDouble()), (float)random.NextDouble() * 360f, 0f) * val6; float num9 = 0.03f + (float)random.NextDouble() * 0.03f; transform3.localPosition = new Vector3(Mathf.Cos(num7) * num8, num9, Mathf.Sin(num7) * num8) - transform3.localRotation * (center * num5); foreach (var item2 in list) { GameObject val7 = new GameObject("part"); val7.transform.SetParent(transform3, false); Transform transform4 = val7.transform; Matrix4x4 item = item2.Item3; transform4.localPosition = ((Matrix4x4)(ref item)).MultiplyPoint3x4(Vector3.zero); Transform transform5 = val7.transform; item = item2.Item3; transform5.localRotation = ((Matrix4x4)(ref item)).rotation; Transform transform6 = val7.transform; item = item2.Item3; transform6.localScale = ((Matrix4x4)(ref item)).lossyScale; AddMesh(val7, item2.Item1, item2.Item2); } } return val2; } private static Material[] SampleMaterials(VisEquipment vis) { Renderer[] componentsInChildren = ((Component)vis).GetComponentsInChildren(); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMaterial != (Object)null) { return val.sharedMaterials; } } return null; } private static void AddMesh(GameObject go, Mesh mesh, Material[] mats) { go.AddComponent().sharedMesh = mesh; ((Renderer)go.AddComponent()).sharedMaterials = mats; } private static void AddMesh(GameObject go, Mesh mesh, Material mat) { AddMesh(go, mesh, (Material[])(object)new Material[1] { mat }); } private static List<(Mesh mesh, Material[] mats, Matrix4x4 m)> ArrowParts(int hash) { if (_arrowCache.TryGetValue(hash, out List<(Mesh, Material[], Matrix4x4)> value)) { return value; } List<(Mesh, Material[], Matrix4x4)> list = new List<(Mesh, Material[], Matrix4x4)>(); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(hash); GameObject val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent() : null)?.m_itemData?.m_shared?.m_attack?.m_attackProjectile; string arg = "projectile"; if ((Object)(object)val == (Object)null || !Collect(val.transform, list, includeInactive: false)) { list.Clear(); if ((Object)(object)val == (Object)null || !Collect(val.transform, list, includeInactive: true)) { list.Clear(); arg = "drop"; if ((Object)(object)itemPrefab != (Object)null) { Collect(itemPrefab.transform, list, includeInactive: false); } } } if (HolsterConfig.DebugLog.Value) { Plugin.Log.LogInfo((object)$"Aljava: {(((Object)(object)itemPrefab != (Object)null) ? ((Object)itemPrefab).name : hash.ToString())} -> {list.Count} malha(s) ({arg})"); } _arrowCache[hash] = list; return list; } private static bool Collect(Transform root, List<(Mesh, Material[], Matrix4x4)> into, bool includeInactive) { //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0142: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); LODGroup[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { LOD[] lODs = componentsInChildren[i].GetLODs(); Renderer[] renderers; for (int j = 1; j < lODs.Length; j++) { renderers = lODs[j].renderers; foreach (Renderer val in renderers) { if ((Object)(object)val != (Object)null) { hashSet.Add(val); } } } if (lODs.Length == 0) { continue; } renderers = lODs[0].renderers; foreach (Renderer val2 in renderers) { if ((Object)(object)val2 != (Object)null) { hashSet.Remove(val2); } } } MeshFilter[] componentsInChildren2 = ((Component)root).GetComponentsInChildren(true); foreach (MeshFilter val3 in componentsInChildren2) { MeshRenderer component = ((Component)val3).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)val3.sharedMesh == (Object)null) && !hashSet.Contains((Renderer)(object)component) && (includeInactive || ((Component)val3).gameObject.activeInHierarchy || IsActiveInPrefab(((Component)val3).transform, root))) { Matrix4x4 item = root.worldToLocalMatrix * ((Component)val3).transform.localToWorldMatrix; into.Add((val3.sharedMesh, ((Renderer)component).sharedMaterials, item)); } } return into.Count > 0; } private static bool IsActiveInPrefab(Transform t, Transform root) { Transform val = t; while ((Object)(object)val != (Object)null) { if (!((Component)val).gameObject.activeSelf) { return false; } if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } return true; } private static Bounds ArrowBounds(List<(Mesh mesh, Material[] mats, Matrix4x4 m)> parts) { //IL_0004: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) bool flag = false; Bounds result = default(Bounds); foreach (var part in parts) { Bounds bounds = part.mesh.bounds; for (int i = 0; i < 8; i++) { Vector3 val = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((i & 1) != 0) ? 1 : (-1)), (float)(((i & 2) != 0) ? 1 : (-1)), (float)(((i & 4) != 0) ? 1 : (-1)))); Matrix4x4 item = part.m; Vector3 val2 = ((Matrix4x4)(ref item)).MultiplyPoint3x4(val); if (!flag) { result = new Bounds(val2, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val2); } } } return result; } private static Material LeatherMaterial(Material[] sample, bool dark) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_00df: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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) if (dark && (Object)(object)_leatherDark != (Object)null) { return _leatherDark; } if (!dark && (Object)(object)_leather != (Object)null) { return _leather; } Material val = null; Shader val2 = Shader.Find("Standard"); if ((Object)(object)val2 != (Object)null) { val = new Material(val2); } else if (sample != null && sample.Length != 0 && (Object)(object)sample[0] != (Object)null) { val = new Material(sample[0]); if (val.HasProperty("_MainTex")) { val.SetTexture("_MainTex", (Texture)null); } if (val.HasProperty("_BumpMap")) { val.SetTexture("_BumpMap", (Texture)null); } if (val.HasProperty("_EmissionColor")) { val.SetColor("_EmissionColor", Color.black); } } if ((Object)(object)val == (Object)null) { return null; } ((Object)val).name = (dark ? "ValheimHolster_LeatherDark" : "ValheimHolster_Leather"); Color val3 = (dark ? LeatherDark : Leather); if (val.HasProperty("_Color")) { val.SetColor("_Color", val3); } if (val.HasProperty("_Glossiness")) { val.SetFloat("_Glossiness", 0.15f); } if (val.HasProperty("_Metallic")) { val.SetFloat("_Metallic", 0f); } if (dark) { _leatherDark = val; } else { _leather = val; } return val; } private static Mesh TubeMesh() { if (!((Object)(object)_tube != (Object)null)) { return _tube = Cylinder("ValheimHolster_QuiverTube", 0.065f, 0.05525f, 0.5f, bottom: true); } return _tube; } private static Mesh RimMesh() { if (!((Object)(object)_rim != (Object)null)) { return _rim = Cylinder("ValheimHolster_QuiverRim", 0.0702f, 0.0702f, 0.05f, bottom: false); } return _rim; } private static Mesh Cylinder(string name, float rTop, float rBottom, float h, bool bottom) { //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0240: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_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_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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List list2 = new List(); List list3 = new List(); List list4 = new List(); Vector3 val = default(Vector3); for (int i = 0; i < 2; i++) { bool flag = i == 1; int count = list.Count; float num = (flag ? 0.94f : 1f); for (int j = 0; j <= 14; j++) { float num2 = (float)j / 14f * MathF.PI * 2f; ((Vector3)(ref val))..ctor(Mathf.Cos(num2), 0f, Mathf.Sin(num2)); list.Add(val * rBottom * num); list2.Add(flag ? (-val) : val); list3.Add(new Vector2((float)j / 14f, 0f)); list.Add(val * rTop * num + Vector3.up * h); list2.Add(flag ? (-val) : val); list3.Add(new Vector2((float)j / 14f, 1f)); } for (int k = 0; k < 14; k++) { int num3 = count + k * 2; int item = num3 + 1; int item2 = num3 + 2; int item3 = num3 + 3; if (!flag) { list4.Add(num3); list4.Add(item); list4.Add(item2); list4.Add(item2); list4.Add(item); list4.Add(item3); } else { list4.Add(num3); list4.Add(item2); list4.Add(item); list4.Add(item2); list4.Add(item3); list4.Add(item); } } } if (bottom) { int count2 = list.Count; list.Add(Vector3.zero); list2.Add(Vector3.down); list3.Add(new Vector2(0.5f, 0.5f)); for (int l = 0; l <= 14; l++) { float num4 = (float)l / 14f * MathF.PI * 2f; list.Add(new Vector3(Mathf.Cos(num4), 0f, Mathf.Sin(num4)) * rBottom); list2.Add(Vector3.down); list3.Add(new Vector2(0.5f, 0.5f)); } for (int m = 0; m < 14; m++) { list4.Add(count2); list4.Add(count2 + 1 + m); list4.Add(count2 + 2 + m); } int count3 = list.Count; float num5 = h * 0.01f; list.Add(Vector3.up * num5); list2.Add(Vector3.up); list3.Add(new Vector2(0.5f, 0.5f)); for (int n = 0; n <= 14; n++) { float num6 = (float)n / 14f * MathF.PI * 2f; list.Add(new Vector3(Mathf.Cos(num6), 0f, Mathf.Sin(num6)) * rBottom * 0.94f + Vector3.up * num5); list2.Add(Vector3.up); list3.Add(new Vector2(0.5f, 0.5f)); } for (int num7 = 0; num7 < 14; num7++) { list4.Add(count3); list4.Add(count3 + 2 + num7); list4.Add(count3 + 1 + num7); } } Mesh val2 = new Mesh { name = name }; val2.SetVertices(list); val2.SetNormals(list2); val2.SetUVs(0, list3); val2.SetTriangles(list4, 0); val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } internal class QuiverFollow : MonoBehaviour { public Transform Anchor; public Transform Character; public Vector3 Offset; public Quaternion Rotation; private Character _char; private bool _hasRest; private Quaternion _restRel = Quaternion.identity; private float _calmFor; private void Start() { _char = ((Component)this).GetComponentInParent(); } private void LateUpdate() { CaptureRest(); Snap(); } private void CaptureRest() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (_hasRest || (Object)(object)Anchor == (Object)null || (Object)(object)Character == (Object)null) { return; } bool flag = true; if ((Object)(object)_char != (Object)null) { try { int num; if (!_char.InAttack() && _char.IsOnGround() && !_char.IsSwimming() && !_char.IsSitting()) { Vector3 velocity = _char.GetVelocity(); num = ((((Vector3)(ref velocity)).magnitude < 0.5f) ? 1 : 0); } else { num = 0; } flag = (byte)num != 0; } catch { flag = true; } } _calmFor = (flag ? (_calmFor + Time.deltaTime) : 0f); if (!(_calmFor < 0.3f)) { _restRel = Quaternion.Inverse(Character.rotation) * Anchor.rotation; _hasRest = true; } } public void Snap() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Anchor == (Object)null) && !((Object)(object)Character == (Object)null)) { float num = Mathf.Abs(Character.lossyScale.x); Quaternion val = (_hasRest ? (Anchor.rotation * Quaternion.Inverse(_restRel)) : Character.rotation); ((Component)this).transform.position = Anchor.position + val * (Offset * num); ((Component)this).transform.rotation = val * Rotation; } } } internal static class UiUtil { private static Sprite _circle; private static Sprite _ring; private static Sprite _glow; private static Sprite _triangle; public static Sprite Circle(int size = 128) { if (!((Object)(object)_circle != (Object)null)) { return _circle = Make(size, (float d, float r) => Mathf.Clamp01(r - d)); } return _circle; } public static Sprite Ring(int size = 256, float thickness = 0.06f) { if (!((Object)(object)_ring != (Object)null)) { return _ring = Make(size, delegate(float d, float r) { float num = r * thickness; float num2 = r - num; return Mathf.Clamp01(r - d) * Mathf.Clamp01(d - num2 + 1f); }); } return _ring; } public static Sprite Glow(int size = 128) { if (!((Object)(object)_glow != (Object)null)) { return _glow = Make(size, delegate(float d, float r) { float num = Mathf.Clamp01(1f - d / r); return num * num; }); } return _glow; } public static Sprite Triangle(int size = 64) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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) if ((Object)(object)_triangle != (Object)null) { return _triangle; } Texture2D val = NewTex(size); Color32[] array = (Color32[])(object)new Color32[size * size]; for (int i = 0; i < size; i++) { float num = ((float)i + 0.5f) / (float)size * 0.5f; for (int j = 0; j < size; j++) { float num2 = ((float)j + 0.5f) / (float)size - 0.5f; float num3 = (num - Mathf.Abs(num2)) * (float)size; array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(Mathf.Clamp01(num3) * 255f)); } } val.SetPixels32(array); val.Apply(); return _triangle = Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f)); } private static Sprite Make(int size, Func alpha) { //IL_00aa: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0076: Unknown result type (might be due to invalid IL or missing references) Texture2D val = NewTex(size); float num = (float)size * 0.5f; Color32[] array = (Color32[])(object)new Color32[size * size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float arg = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(num, num)); array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(Mathf.Clamp01(alpha(arg, num)) * 255f)); } } val.SetPixels32(array); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f)); } private static Texture2D NewTex(int size) { //IL_0004: 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) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return new Texture2D(size, size, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; } public static float EaseOutCubic(float t) { t = Mathf.Clamp01(t); float num = 1f - t; return 1f - num * num * num; } public static float EaseOutBack(float t) { t = Mathf.Clamp01(t); float num = t - 1f; return 1f + 2.70158f * num * num * num + 1.70158f * num * num; } } internal static class VanillaAccess { public static FieldRef RightItem; public static FieldRef LeftItem; public static FieldRef HiddenRightItem; public static FieldRef HiddenLeftItem; public static FieldRef VisEquipment; public static FieldRef ZAnim; private static MethodInfo _setupVisEquipment; private static MethodInfo _showHandItems; private static MethodInfo _takeInput; private static MethodInfo _getButtonPos; private static MethodInfo _attachItem; private static ParameterInfo[] _attachParams; public static FieldRef LeftBackInstance; public static FieldRef RightBackInstance; private static FieldRef _currentLeftBackHash; private static FieldRef _currentRightBackHash; private static FieldRef> _gridElements; private static FieldRef _gridWidth; public static void Init() { RightItem = AccessTools.FieldRefAccess("m_rightItem"); LeftItem = AccessTools.FieldRefAccess("m_leftItem"); HiddenRightItem = AccessTools.FieldRefAccess("m_hiddenRightItem"); HiddenLeftItem = AccessTools.FieldRefAccess("m_hiddenLeftItem"); VisEquipment = AccessTools.FieldRefAccess("m_visEquipment"); ZAnim = AccessTools.FieldRefAccess("m_zanim"); _setupVisEquipment = AccessTools.Method(typeof(Humanoid), "SetupVisEquipment", (Type[])null, (Type[])null); _showHandItems = AccessTools.Method(typeof(Humanoid), "ShowHandItems", (Type[])null, (Type[])null); _takeInput = AccessTools.Method(typeof(Character), "TakeInput", (Type[])null, (Type[])null); _getButtonPos = AccessTools.Method(typeof(InventoryGrid), "GetButtonPos", new Type[1] { typeof(GameObject) }, (Type[])null); _attachItem = AccessTools.Method(typeof(VisEquipment), "AttachItem", (Type[])null, (Type[])null); _attachParams = _attachItem?.GetParameters(); LeftBackInstance = TryRef("m_leftBackItemInstance"); RightBackInstance = TryRef("m_rightBackItemInstance"); _currentLeftBackHash = TryRef("m_currentLeftBackItemHash"); _currentRightBackHash = TryRef("m_currentRightBackItemHash"); if (_setupVisEquipment == null) { Plugin.Log.LogError((object)"Humanoid.SetupVisEquipment não encontrado."); } if (_attachItem == null) { Plugin.Log.LogError((object)"VisEquipment.AttachItem não encontrado."); } } private static FieldRef TryRef(string name) { try { return AccessTools.FieldRefAccess(name); } catch { return null; } } public static void SetupVisEquipment(Humanoid h) { VisEquipment val = VisEquipment.Invoke(h); if (!((Object)(object)val == (Object)null) && !(_setupVisEquipment == null)) { _setupVisEquipment.Invoke(h, new object[2] { val, false }); } } public static void TriggerHolsterAnim(Humanoid h) { ZSyncAnimation val = ZAnim.Invoke((Character)(object)h); if ((Object)(object)val != (Object)null) { val.SetTrigger("equip_hip"); } } public static GameObject AttachItem(VisEquipment vis, int hash, int variant, int quality, Transform joint) { if (_attachItem == null || (Object)(object)joint == (Object)null) { return null; } object[] array = new object[_attachParams.Length]; for (int i = 0; i < _attachParams.Length; i++) { ParameterInfo parameterInfo = _attachParams[i]; switch (parameterInfo.Name) { case "itemHash": array[i] = hash; break; case "variant": array[i] = variant; break; case "joint": array[i] = joint; break; case "enableEquipEffects": array[i] = false; break; case "backAttach": array[i] = true; break; case "quality": array[i] = quality; break; default: array[i] = (parameterInfo.HasDefaultValue ? parameterInfo.DefaultValue : (parameterInfo.ParameterType.IsValueType ? Activator.CreateInstance(parameterInfo.ParameterType) : null)); break; } } try { object? obj = _attachItem.Invoke(vis, array); return (GameObject)((obj is GameObject) ? obj : null); } catch (Exception ex) { Plugin.Log.LogWarning((object)$"Falha ao anexar item {hash}: {ex.InnerException?.Message ?? ex.Message}"); return null; } } public static void RefreshAllVisuals() { if (_currentLeftBackHash == null || _currentRightBackHash == null) { return; } foreach (IMonoUpdater instance in VisEquipment.Instances) { VisEquipment val = (VisEquipment)(object)((instance is VisEquipment) ? instance : null); if (!((Object)(object)val == (Object)null)) { _currentLeftBackHash.Invoke(val) = 0; _currentRightBackHash.Invoke(val) = 0; } } } public static void ShowHandItems(Humanoid h) { if (!(_showHandItems == null)) { ParameterInfo[] parameters = _showHandItems.GetParameters(); object[] array = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = ((parameters[i].Name == "animation") ? ((object)true) : ((parameters[i].ParameterType == typeof(bool)) ? ((object)false) : null)); } _showHandItems.Invoke(h, array); } } public static bool TakeInput(Character c) { if (_takeInput == null) { return true; } try { return (bool)_takeInput.Invoke(c, null); } catch { return true; } } public static ItemData GetHoveredPlayerItem() { //IL_00b0: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_playerGrid == (Object)null) { return null; } InventoryGrid playerGrid = instance.m_playerGrid; if (!HoverTracker.IsValid || (Object)(object)HoverTracker.Grid != (Object)(object)playerGrid) { return null; } Inventory inventory = playerGrid.GetInventory(); if (inventory == null) { return null; } GameObject gameObject = ((Component)HoverTracker.Element).gameObject; if (_getButtonPos != null) { try { Vector2i val = (Vector2i)_getButtonPos.Invoke(playerGrid, new object[1] { gameObject }); if (val.x >= 0) { ItemData itemAt = inventory.GetItemAt(val.x, val.y); if (itemAt != null) { return itemAt; } } } catch { } } Vector2i position = HoverTracker.Element.Position; return inventory.GetItemAt(position.x, position.y); } public static List GridElements(InventoryGrid g) { if (_gridElements == null) { try { _gridElements = AccessTools.FieldRefAccess>("m_elements"); } catch { return null; } } return _gridElements.Invoke(g); } public static int GridWidth(InventoryGrid g) { if (_gridWidth == null) { try { _gridWidth = AccessTools.FieldRefAccess("m_width"); } catch { return 0; } } return _gridWidth.Invoke(g); } } }