Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BetterTweaks v1.0.0
BetterTweaks.dll
Decompiled 13 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BetterTweaks.Combat; using BetterTweaks.Combat.Archery; using BetterTweaks.Combat.Archery.Animation; using BetterTweaks.Combat.Archery.Animation.Audio; using BetterTweaks.Combat.Configuration; using BetterTweaks.Combat.Melee; using BetterTweaks.Combat.Patches; using BetterTweaks.Configuration; using BetterTweaks.Networking; using BetterTweaks.Patching; using BetterTweaks.Persistence; using BetterTweaks.Services; using HarmonyLib; using MagicaCloth2; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Animations; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("BetterTweaks.MenuSmoke")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("BetterTweaks")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BetterTweaks")] [assembly: AssemblyTitle("BetterTweaks")] [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 BetterTweaks { [BepInPlugin("torubaki.bettertweaks", "BetterTweaks", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "torubaki.bettertweaks"; public const string Version = "1.0.0"; internal static Plugin Instance; internal static Settings Settings; internal static readonly OwnedOverrides Overrides = new OwnedOverrides(); private Harmony harmony; internal static string LoadError; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Instance = this; LoadError = "Initialization has not completed. Inspect the BetterTweaks log before loading a character."; harmony = new Harmony("torubaki.bettertweaks"); PatchRegistry patchRegistry = new PatchRegistry(harmony, ((BaseUnityPlugin)this).Logger); patchRegistry.Add(typeof(Player), "Load", new Type[1] { typeof(ZPackage) }, typeof(Plugin), "BeforeLoad"); patchRegistry.Add(typeof(Player), "Save", new Type[1] { typeof(ZPackage) }, typeof(Plugin), "BeforeSave"); try { Settings = new Settings(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); InventorySlots.Install(patchRegistry); EquipmentActions.Install(patchRegistry); ControlOverrides.Install(patchRegistry); ResourceAccess.Install(patchRegistry); ForgeRecipes.Install(patchRegistry); CraftingStations.Install(patchRegistry); BuildingTools.Install(patchRegistry); TerrainRadius.Install(patchRegistry); TerrainLimits.Install(patchRegistry); FreePlacement.Install(patchRegistry); CameraInput.Install(patchRegistry); LowerGroundFeatures.Install(patchRegistry); UnlockAllFeatures.Install(patchRegistry); WeatherProtection.Install(patchRegistry); BuildingExtras.Install(patchRegistry); BuildingEffects.Install(patchRegistry); ProductionFeatures.Install(patchRegistry); WardFeatures.Install(patchRegistry); TurretFeatures.Install(patchRegistry); CreatureLoot.Install(patchRegistry); WorldFeatures.Install(patchRegistry); MapFeatures.Install(patchRegistry); Recycling.Install(patchRegistry); PlayerFeatures.Install(patchRegistry); FoodFeatures.Install(patchRegistry); FoodAndBuffs.Install(patchRegistry); MagicFeatures.Install(patchRegistry); EquipmentRules.Install(patchRegistry); CombatRuntime.Install(harmony, ((BaseUnityPlugin)this).Logger); SessionProtocol.Install(patchRegistry); Settings.EditRequested += SessionProtocol.RequestEdit; LoadError = null; if (patchRegistry.Failures.Count != 0) { LoadError = "Unsupported game methods: " + string.Join(", ", patchRegistry.Failures); } Settings.Changed += Refresh; ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("BetterTweaks {0}; game assembly {1}; Unity {2}; BepInEx {3}.", "1.0.0", typeof(Player).Assembly.GetName().Version, Application.unityVersion, typeof(BaseUnityPlugin).Assembly.GetName().Version)); } catch (Exception ex) { LoadError = "Initialization failed; character loading and saving are blocked. " + ex.Message; ((BaseUnityPlugin)this).Logger.LogError((object)ex); } if (LoadError != null) { ((BaseUnityPlugin)this).Logger.LogError((object)LoadError); } } private void Start() { if (LoadError != null) { return; } try { ControlOverrides.Refresh(); } catch (Exception ex) { LoadError = "Control initialization failed: " + ex.Message; ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } private static bool BeforeLoad() { if (LoadError == null) { return true; } throw new InvalidOperationException("BetterTweaks blocked character loading. " + LoadError); } private static void BeforeSave() { if (LoadError != null) { throw new InvalidOperationException("BetterTweaks blocked character saving. " + LoadError); } } private void Refresh() { if (LoadError == null) { Overrides.Restore(); PlayerFeatures.Refresh(); FoodAndBuffs.Refresh(); SummonFeatures.Refresh(); LanternUtility.Refresh(); ForgeRecipes.Refresh(); CraftingStations.Refresh(); BuildingExtras.Refresh(); WardFeatures.Refresh(); BuildingTools.Refresh(); LowerGroundFeatures.Refresh(); TerrainRadius.Tick(); if (!Settings.On("BuildCamera.General", "Enabled")) { CameraInput.Exit(); } InventorySlots.Refresh(); ControlOverrides.Refresh(); } } private void Update() { if (Settings != null && LoadError == null) { SessionProtocol.Tick(); MapFeatures.Tick(); MapPins.Tick(); TerrainRadius.Tick(); CameraInput.Tick(); FreePlacement.Tick(); if (!((Object)(object)Player.m_localPlayer == (Object)null)) { BuildingTools.Tick(); EquipmentRules.Tick(); ResourceAccess.Tick(); Recycling.Tick(); } } } private void OnGUI() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (LoadError != null) { GUI.Box(new Rect(20f, 20f, (float)Mathf.Min(Screen.width - 40, 900), 100f), "BetterTweaks: character loading/saving blocked\n" + LoadError); } } private void OnDestroy() { CombatRuntime.Close(); if (Settings != null) { Settings.Changed -= Refresh; } if (Settings != null) { Settings.EditRequested -= SessionProtocol.RequestEdit; } BuildingExtras.Close(); CameraInput.Exit(); TerrainRadius.Close(); FreePlacement.Close(); BuildingTools.Close(); LowerGroundFeatures.Close(); UnlockAllFeatures.Close(); InventorySlots.Close(); SessionProtocol.Close(); PlayerFeatures.Close(); FoodFeatures.Close(); FoodAndBuffs.Close(); SummonFeatures.Close(); Overrides.Restore(); EquipmentRules.Close(); CraftingStations.Close(); ForgeRecipes.Close(); ControlOverrides.Close(); LanternUtility.Close(); EquipmentActions.Close(); ContainerWindow.Close(); InventoryDiagnostics.Close(); UtilityVisibility.Close(); WardFeatures.Close(); MapFeatures.Close(); MapPins.Close(); if (harmony != null) { PatchRegistry.Unpatch(harmony); } ConfigFileLayout.Close(); Settings?.Dispose(); Settings = null; Instance = null; } internal static void Warn(string text) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)text); } } internal static void Info(string text) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)text); } } } } namespace BetterTweaks.Services { internal static class AmmoSlots { internal const int Index = 28; private static bool syncing; [ThreadStatic] private static Player restoring; internal static bool IsAmmo(ItemData item) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 if (item != null) { if ((int)item.m_shared.m_itemType != 9) { return (int)item.m_shared.m_itemType == 23; } return true; } return false; } internal static void Install(PatchRegistry patches) { patches.Add(typeof(Player), "OnInventoryChanged", Type.EmptyTypes, typeof(AmmoSlots), null, "Changed"); patches.Add(typeof(Player), "EquipInventoryItems", Type.EmptyTypes, typeof(AmmoSlots), "BeginRestore", null, "EndRestore"); } private static void BeginRestore(Player __instance, out Player __state) { __state = restoring; restoring = __instance; } private static Exception EndRestore(Player __state, Exception __exception) { restoring = __state; return __exception; } private static void Changed(Player __instance) { if (syncing || (Object)(object)restoring == (Object)(object)__instance || !InventorySlots.AmmoFor(__instance) || EquipmentSlots.Changing(__instance) || Fields.Get<bool>(__instance, "m_isLoading")) { return; } ItemData val = InventorySlots.At(__instance, 28); if (!IsAmmo(val) || ((Humanoid)__instance).GetAmmoItem() == val) { return; } syncing = true; try { ((Humanoid)__instance).EquipItem(val, false); } finally { syncing = false; } } internal static ItemData Current(Player player) { if ((Object)(object)player == (Object)null) { return null; } Inventory inventory = ((Humanoid)player).GetInventory(); ItemData ammoItem = ((Humanoid)player).GetAmmoItem(); if (!IsAmmo(ammoItem) || !ammoItem.m_equipped || ammoItem.m_stack <= 0 || !inventory.ContainsItem(ammoItem)) { return null; } return ammoItem; } internal static int Count(Player player, ItemData ammo) { if (ammo != null) { return (from i in ((Humanoid)player).GetInventory().GetAllItems() where i.m_shared.m_name == ammo.m_shared.m_name select i).Sum((ItemData i) => i.m_stack); } return 0; } } internal static class BuildingEffects { [ThreadStatic] private static string category; private static Settings S => Plugin.Settings; public static void Install(PatchRegistry p) { p.Add(typeof(EffectList), "Create", new Type[6] { typeof(Vector3), typeof(Quaternion), typeof(Transform), typeof(float), typeof(int), typeof(ZDOID) }, typeof(BuildingEffects), "Filter", "Particles", "RestoreEffects"); p.Add(typeof(Player), "PlacePiece", new Type[5] { typeof(Piece), typeof(Vector3), typeof(Quaternion), typeof(bool), typeof(bool) }, typeof(BuildingEffects), "Place", null, "End"); Context(p, typeof(TerrainModifier), "OnPlaced"); Context(p, typeof(TerrainOp), "OnPlaced"); Context(p, typeof(Attack), "DoAreaAttack"); Context(p, typeof(Attack), "DoNonAttack"); Context(p, typeof(Attack), "DoMeleeAttack"); Context(p, typeof(Attack), "FireProjectileBurst"); Context(p, typeof(Character), "OnDeath"); Context(p, typeof(Ragdoll), "DestroyNow"); Context(p, typeof(Projectile), "OnHit", typeof(Collider), typeof(Vector3), typeof(bool), typeof(Vector3)); p.Add(typeof(FootStep), "DoEffect", new Type[2] { typeof(StepEffect), typeof(Vector3) }, typeof(BuildingEffects), "Step", null, "RestoreStep"); p.Add(typeof(FootStep), "SetEffectCreator", new Type[1] { typeof(GameObject) }, typeof(BuildingEffects), null, "StepParticles"); Context(p, typeof(WearNTear), "Destroy", typeof(HitData), typeof(bool)); } private static void Context(PatchRegistry p, Type type, string method, params Type[] args) { p.Add(type, method, args, typeof(BuildingEffects), "Begin", null, "End"); } private static void Begin(object __instance, MethodBase __originalMethod, out string __state) { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Invalid comparison between Unknown and I4 //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Invalid comparison between Unknown and I4 //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Invalid comparison between Unknown and I4 //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Invalid comparison between Unknown and I4 __state = category; Type declaringType = __originalMethod.DeclaringType; if (declaringType == typeof(Attack)) { ItemData val = Fields.Get<ItemData>(__instance, "m_weapon"); string text = BuildingTools.ToolName(val); Character val2 = Fields.Get<Character>(__instance, "m_character"); bool flag = (val != null && (int)val.m_shared.m_skillType == 8) || (val != null && (int)val.m_shared.m_skillType == 14); category = ((text == "Hoe") ? "Hoe Dust" : ((text == "Cultivator") ? "Cultivator Dust" : (((Object)(object)val2 != (Object)null && !(val2 is Player)) ? "Creature Dust" : (flag ? "Archery Dust" : (((val != null && (int)val.m_shared.m_itemType == 14) || (val != null && (int)val.m_shared.m_itemType == 3) || (val != null && (int)val.m_shared.m_itemType == 22) || (val != null && (int)val.m_shared.m_skillType == 11)) ? "Melee Dust" : null))))); } else if (declaringType == typeof(Projectile)) { Projectile val3 = (Projectile)__instance; Character val4 = Fields.Get<Character>(val3, "m_owner"); category = (((Object)(object)val4 != (Object)null && !(val4 is Player)) ? "Creature Dust" : (((int)val3.m_skill == 8 || (int)val3.m_skill == 14) ? "Archery Dust" : null)); } else if (declaringType == typeof(Character) || declaringType == typeof(Ragdoll)) { category = ((__instance is Player) ? null : "Creature Dust"); } else if (declaringType == typeof(WearNTear)) { category = "Build Dust"; } else if (category != "Cultivator Dust") { category = "Hoe Dust"; } } private static void Place(Player __instance, Piece __0, out string __state) { __state = category; string text = BuildingTools.ToolName(Fields.Get<ItemData>(__instance, "m_rightItem")); string text2 = ((Object)__0).name.ToLowerInvariant(); category = ((text == "Cultivator" || text2.Contains("replant") || text2.Contains("cultivate")) ? "Cultivator Dust" : ((text == "Hoe" || text2.Contains("road") || text2.Contains("raise") || text2.Contains("path_") || text2.Contains("paved")) ? "Hoe Dust" : "Build Dust")); } private static Exception End(string __state, Exception __exception) { category = __state; return __exception; } private static bool Enabled(string kind) { return kind switch { "Creature Dust" => S.On("Enemies", "Hide Creature Dust"), "Melee Dust" => S.On("Melee", "Hide Melee Dust"), "Archery Dust" => S.On("Archery", "Hide Archery Dust"), _ => S.On("Effects.Dust Toggles", kind), }; } private static void Particles(GameObject[] __result) { if (category == null || (!(category == "Archery Dust") && !(category == "Melee Dust") && !(category == "Creature Dust")) || !Enabled(category)) { return; } foreach (GameObject val in __result) { if ((Object)(object)val != (Object)null) { HideDustParticles(val); } } } private static void HideDustParticles(GameObject effect) { ParticleSystem[] componentsInChildren = effect.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val in componentsInChildren) { bool flag = false; Transform val2 = ((Component)val).transform; while ((Object)(object)val2 != (Object)null) { if (IsDust(((Component)val2).gameObject)) { flag = true; break; } val2 = (((Object)(object)val2 == (Object)(object)effect.transform) ? null : val2.parent); } if (flag) { val.Stop(false, (ParticleSystemStopBehavior)0); } } } private static bool IsDust(GameObject prefab) { return ((Object)prefab).name.IndexOf("dust", StringComparison.OrdinalIgnoreCase) >= 0; } private static void StepParticles(FootStep __instance, GameObject __0) { Character val = Fields.Get<Character>(__instance, "m_character"); if ((Object)(object)val != (Object)null && !(val is Player) && Enabled("Creature Dust")) { HideDustParticles(__0); } } private static void Step(FootStep __instance, StepEffect effect, out GameObject[] __state) { __state = null; Character val = Fields.Get<Character>(__instance, "m_character"); if (!((Object)(object)val == (Object)null) && !(val is Player) && Enabled("Creature Dust") && effect.m_effectPrefabs.Any((GameObject p) => (Object)(object)p != (Object)null && IsDust(p))) { __state = effect.m_effectPrefabs; effect.m_effectPrefabs = __state.Where((GameObject p) => (Object)(object)p == (Object)null || !IsDust(p)).ToArray(); } } private static Exception RestoreStep(StepEffect effect, GameObject[] __state, Exception __exception) { if (__state != null) { effect.m_effectPrefabs = __state; } return __exception; } private static bool IsVfx(EffectData e) { if ((Object)(object)e?.m_prefab == (Object)null) { return false; } string text = ((Object)e.m_prefab).name.ToLowerInvariant(); if (!text.Contains("vfx") && !text.StartsWith("fx_")) { return text.Contains("dust"); } return true; } private static void Filter(EffectList __instance, out EffectData[] __state) { __state = null; if (category == null || !Enabled(category)) { return; } Func<EffectData, bool> remove = ((category == "Archery Dust" || category == "Melee Dust" || category == "Creature Dust") ? ((Func<EffectData, bool>)((EffectData e) => (Object)(object)e?.m_prefab != (Object)null && IsDust(e.m_prefab))) : new Func<EffectData, bool>(IsVfx)); if (__instance.m_effectPrefabs.Any(remove)) { __state = __instance.m_effectPrefabs; __instance.m_effectPrefabs = __state.Where((EffectData e) => !remove(e)).ToArray(); } } private static Exception RestoreEffects(EffectList __instance, EffectData[] __state, Exception __exception) { if (__state != null) { __instance.m_effectPrefabs = __state; } return __exception; } } internal static class BuildingExtras { private static readonly HashSet<Fireplace> fires = new HashSet<Fireplace>(); private static readonly OwnedOverrides overrides = new OwnedOverrides(); private static readonly HashSet<string> torches = new HashSet<string> { "piece_groundtorch_wood", "piece_groundtorch", "piece_groundtorch_green", "piece_groundtorch_blue", "piece_walltorch", "piece_brazierceiling01", "piece_brazierfloor01", "piece_brazierfloor02", "piece_jackoturnip" }; internal static void Install(PatchRegistry patches) { patches.Add(typeof(Player), "UpdatePlacementGhost", new Type[1] { typeof(bool) }, typeof(BuildingExtras), null, "Crops"); patches.Add(typeof(Fireplace), "Awake", Type.EmptyTypes, typeof(BuildingExtras), null, "FireAwake"); } private static void Crops(Player __instance) { //IL_0017: 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) if (!Plugin.Settings.On("Player", "cropNotifier") || (int)__instance.GetPlacementStatus() != 0) { return; } GameObject val = Fields.Get<GameObject>(__instance, "m_placementGhost"); Plant val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Plant>() : null); if ((Object)(object)val2 == (Object)null) { return; } int mask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid" }); Collider[] array = Physics.OverlapSphere(val.transform.position, val2.m_growRadius, mask); foreach (Collider val3 in array) { if (!((Component)val3).transform.IsChildOf(val.transform) && !((Object)(object)((Component)val3).GetComponentInParent<Plant>() == (Object)null)) { Fields.Set(__instance, "m_placementStatus", (object)(PlacementStatus)5); Piece component = val.GetComponent<Piece>(); if (component != null) { component.SetInvalidPlacementHeightlight(true); } break; } } } private static void FireAwake(Fireplace __instance) { fires.Add(__instance); Configure(__instance); } private static void Configure(Fireplace fire) { bool flag = torches.Contains(Utils.GetPrefabName(((Component)fire).gameObject)); if (Plugin.Settings.On("FireSource", flag ? "torches" : "fires")) { overrides.Set(fire, "infiniteFuel", () => fire.m_infiniteFuel, delegate(bool value) { fire.m_infiniteFuel = value; }, value: true); } } internal static void Refresh() { overrides.Restore(); fires.RemoveWhere((Fireplace fire) => (Object)(object)fire == (Object)null); foreach (Fireplace fire in fires) { Configure(fire); } } internal static void Close() { overrides.Restore(); fires.Clear(); } } internal static class BuildingTools { private sealed class PlacementState { internal Player Previous; internal Attack Attack; internal float Stamina; } private static float nextScan; private static Player freeBuilder; private static readonly HashSet<SharedData> logged = new HashSet<SharedData>(); internal static string ToolName(ItemData item) { if (item == null) { return null; } string a = (((Object)(object)item.m_dropPrefab == (Object)null) ? "" : ((Object)item.m_dropPrefab).name.Replace("(Clone)", "")); string[] array = new string[3] { "Hammer", "Hoe", "Cultivator" }; foreach (string text in array) { if (string.Equals(a, text, StringComparison.OrdinalIgnoreCase) || string.Equals(item.m_shared.m_name, "$item_" + text.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase)) { return text; } } return null; } internal static bool FreeDurability(ItemData item) { string text = ToolName(item); if (text != null) { return Plugin.Settings.On("BuildingTools", text + " No Durability Drain"); } return false; } internal static bool FreeStamina(ItemData item) { string text = ToolName(item); if (text != null) { return Plugin.Settings.On("BuildingTools", text + " No Stamina Drain"); } return false; } internal static bool FreeStation(ItemData item) { string text = ToolName(item); if (text != null) { return Plugin.Settings.On("BuildingTools", text + " No Workbench Requirement"); } return false; } public static void Install(PatchRegistry p) { p.Add(typeof(Player), "GetBuildStamina", Type.EmptyTypes, typeof(BuildingTools), "BuildStamina"); p.Add(typeof(Attack), "GetAttackStamina", Type.EmptyTypes, typeof(BuildingTools), "AttackStamina"); p.Add(typeof(Player), "UpdatePlacement", new Type[2] { typeof(bool), typeof(float) }, typeof(BuildingTools), "BeginPlacement", null, "EndPlacement"); p.Add(typeof(Player), "HaveStamina", new Type[1] { typeof(float) }, typeof(BuildingTools), "HaveStamina"); p.Add(typeof(Humanoid), "StartAttack", new Type[2] { typeof(Character), typeof(bool) }, typeof(BuildingTools), "BeginAttack", null, "EndAttack"); p.Add(typeof(Player), "HaveRequirements", new Type[2] { typeof(Piece), typeof(RequirementMode) }, typeof(BuildingTools), "WithoutStation", null, "RestoreStation"); p.Add(typeof(Player), "CheckCanRemovePiece", new Type[1] { typeof(Piece) }, typeof(BuildingTools), "WithoutStation", null, "RestoreStation"); } private static bool BuildStamina(Player __instance, ref float __result) { if (!FreeStamina(Fields.Get<ItemData>(__instance, "m_rightItem"))) { return true; } __result = 0f; return false; } private static bool AttackStamina(Attack __instance, ref float __result) { if (!FreeStamina(Fields.Get<ItemData>(__instance, "m_weapon"))) { return true; } __result = 0f; return false; } private static void BeginPlacement(Player __instance, out PlacementState __state) { __state = BeginScope(__instance, Fields.Get<ItemData>(__instance, "m_rightItem")); } private static PlacementState BeginScope(Player player, ItemData item) { PlacementState placementState = new PlacementState { Previous = freeBuilder }; freeBuilder = null; if ((Object)(object)player == (Object)null || !FreeStamina(item)) { return placementState; } freeBuilder = player; placementState.Attack = item.m_shared.m_attack; if (placementState.Attack != null) { placementState.Stamina = placementState.Attack.m_attackStamina; placementState.Attack.m_attackStamina = 0f; } return placementState; } private static Exception EndPlacement(PlacementState __state, Exception __exception) { if (__state != null) { freeBuilder = __state.Previous; if (__state.Attack != null && __state.Attack.m_attackStamina == 0f) { __state.Attack.m_attackStamina = __state.Stamina; } } return __exception; } private static bool HaveStamina(Player __instance, ref bool __result) { if ((Object)(object)__instance != (Object)(object)freeBuilder || (Object)(object)freeBuilder == (Object)null) { return true; } __result = true; return false; } private static void BeginAttack(Humanoid __instance, out PlacementState __state) { __state = BeginScope((Player)(object)((__instance is Player) ? __instance : null), __instance.GetCurrentWeapon()); } private static Exception EndAttack(PlacementState __state, Exception __exception) { return EndPlacement(__state, __exception); } private static void WithoutStation(Player __instance, Piece piece, out CraftingStation __state) { __state = null; if (!((Object)(object)piece == (Object)null) && FreeStation(Fields.Get<ItemData>(__instance, "m_rightItem"))) { __state = piece.m_craftingStation; piece.m_craftingStation = null; } } private static Exception RestoreStation(Piece piece, CraftingStation __state, Exception __exception) { if ((Object)(object)piece != (Object)null && (Object)(object)__state != (Object)null && (Object)(object)piece.m_craftingStation == (Object)null) { piece.m_craftingStation = __state; } return __exception; } public static void Refresh() { nextScan = 0f; logged.Clear(); Tick(); } public static void Tick() { if (Time.unscaledTime < nextScan) { return; } nextScan = Time.unscaledTime + Mathf.Max(0.25f, Plugin.Settings.Get<float>("BuildingTools", "Scan Interval Seconds")); IEnumerable<ItemData> first = (((Object)(object)ObjectDB.instance == (Object)null) ? Enumerable.Empty<ItemData>() : (from g in ObjectDB.instance.m_items select g.GetComponent<ItemDrop>() into i where (Object)(object)i != (Object)null select i.m_itemData)); IEnumerable<ItemData> enumerable; if (!((Object)(object)Player.m_localPlayer == (Object)null)) { IEnumerable<ItemData> allItems = ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems(); enumerable = allItems; } else { enumerable = Enumerable.Empty<ItemData>(); } IEnumerable<ItemData> second = enumerable; foreach (ItemData item in first.Concat(second).Where(FreeDurability)) { SharedData s = item.m_shared; if (s.m_useDurability && logged.Add(s) && Plugin.Settings.On("BuildingTools", "Log Changes")) { Plugin.Info("Building tool durability disabled: " + s.m_name); } Plugin.Overrides.Set(s, "m_useDurability", () => s.m_useDurability, delegate(bool v) { s.m_useDurability = v; }, value: false); } } internal static void Close() { freeBuilder = null; logged.Clear(); nextScan = 0f; } } internal static class CameraInput { private static bool active; private static Player owner; private static Vector3 position; private static float yaw; private static float pitch; private static float health; private static float sailOffset; private static Vector3? stationPoint; private static Camera drivenCamera; private static float nearClip; private static bool Enabled => Plugin.Settings.On("BuildCamera.General", "Enabled"); internal static bool Active => active; private static bool Applies(Player player) { if (active && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)owner) { return (Object)(object)player == (Object)(object)Player.m_localPlayer; } return false; } private static bool CanStay(Player player) { if (Enabled && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)owner && (Object)(object)GameCamera.instance != (Object)null && !GameCamera.InFreeFly() && !((Character)player).IsDead() && !((Character)player).IsTeleporting() && !((Character)player).IsAttached() && !((Character)player).InCutscene()) { return ((Character)player).InPlaceMode(); } return false; } internal static bool HasBuildToggle() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (Enabled && InventorySlots.InputAllowed && ((Character)Player.m_localPlayer).InPlaceMode()) { KeyboardShortcut val = Plugin.Settings.Get<KeyboardShortcut>("BuildCamera.1 - Keys", "Toggle"); return ((KeyboardShortcut)(ref val)).IsDown(); } return false; } internal static void Install(PatchRegistry p) { p.Add(typeof(GameCamera), "GetCameraPosition", new Type[3] { typeof(float), typeof(Vector3).MakeByRefType(), typeof(Quaternion).MakeByRefType() }, typeof(CameraInput), null, "Sailing"); p.Add(typeof(GameCamera), "UpdateCamera", new Type[1] { typeof(float) }, typeof(CameraInput), "Camera"); p.Add(typeof(Player), "UpdatePlacementGhost", new Type[1] { typeof(bool) }, typeof(CameraInput), "Placement", null, "RestorePlacement"); p.Add(typeof(Player), "PieceRayTest", new Type[6] { typeof(Vector3).MakeByRefType(), typeof(Vector3).MakeByRefType(), typeof(Piece).MakeByRefType(), typeof(Heightmap).MakeByRefType(), typeof(Collider).MakeByRefType(), typeof(bool) }, typeof(CameraInput), "Placement", "Reach", "RestorePlacement"); p.Add(typeof(PlayerController), "FixedUpdate", Type.EmptyTypes, typeof(CameraInput), "Controls"); p.Add(typeof(PlayerController), "LateUpdate", Type.EmptyTypes, typeof(CameraInput), "Look"); p.Add(typeof(GameCamera), "UpdateListner", Type.EmptyTypes, typeof(CameraInput), "Listener"); p.Add(typeof(Player), "UpdateWearNTearHover", Type.EmptyTypes, typeof(CameraInput), "Hover", null, "RestorePlacement"); string[] array = new string[2] { "RemovePiece", "CopyPiece" }; foreach (string name in array) { p.Add(typeof(Player), name, Type.EmptyTypes, typeof(CameraInput), "Removal", null, "RestorePlacement"); } p.Add(typeof(Player), "HaveRequirements", new Type[2] { typeof(Piece), typeof(RequirementMode) }, typeof(CameraInput), "BuildStation", null, "RestoreStation"); p.Add(typeof(Player), "CheckCanRemovePiece", new Type[1] { typeof(Piece) }, typeof(CameraInput), "RemoveStation", null, "RestoreStation"); p.Add(typeof(CraftingStation), "HaveBuildStationInRange", new Type[2] { typeof(string), typeof(Vector3) }, typeof(CameraInput), "Station"); p.Add(typeof(Player), "OnDamaged", new Type[1] { typeof(HitData) }, typeof(CameraInput), "Damaged"); } internal static void Tick() { //IL_006a: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: 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_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_023f: 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_0249: 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_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: 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_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: 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_027e: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0315: 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_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0340: 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_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (active && !CanStay(localPlayer)) { Exit(); } if (HasBuildToggle()) { if (active) { Exit(); } else if ((Object)(object)GameCamera.instance != (Object)null) { owner = localPlayer; if (!CanStay(localPlayer)) { owner = null; return; } active = true; position = ((Component)GameCamera.instance).transform.position; Vector3 eulerAngles = ((Component)GameCamera.instance).transform.eulerAngles; yaw = eulerAngles.y; pitch = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x); health = ((Character)localPlayer).GetHealth(); } } if (!active) { return; } if (Plugin.Settings.On("BuildCamera.3 - Limits", "ExitWhenHit") && ((Character)localPlayer).GetHealth() < health) { Exit(); return; } health = ((Character)localPlayer).GetHealth(); ClampPosition(localPlayer); if (InventorySlots.InputAllowed && (!((Object)(object)Hud.instance != (Object)null) || !((Object)(object)Hud.instance.m_buildUi != (Object)null) || !Hud.instance.m_buildUi.SearchFieldFocused)) { Vector2 val = ZInput.GetMouseDelta() * PlayerController.m_mouseSens * Plugin.Settings.Percent("BuildCamera.2 - Movement", "MouseSensitivity"); if (PlayerController.m_invertMouse) { val.y = 0f - val.y; } if (ZInput.IsGamepadActive() && !ZInput.GetButton("JoyRotate")) { val.x += ZInput.GetJoyRightStickX() * 110f * Time.unscaledDeltaTime * PlayerController.m_gamepadSens * (float)((!PlayerController.m_invertCameraX) ? 1 : (-1)); val.y -= ZInput.GetJoyRightStickY() * 110f * Time.unscaledDeltaTime * PlayerController.m_gamepadSens * (float)((!PlayerController.m_invertCameraY) ? 1 : (-1)); } yaw = Mathf.Repeat(yaw + val.x, 360f); pitch = Mathf.Clamp(pitch - val.y, -89f, 89f); Quaternion val2 = Quaternion.Euler(pitch, yaw, 0f); Vector3 val3 = val2 * Vector3.forward; if (Plugin.Settings.On("BuildCamera.2 - Movement", "HorizontalMovement")) { val3 = Quaternion.Euler(0f, yaw, 0f) * Vector3.forward; } Vector3 val4 = val3 * (float)((ZInput.GetButton("Forward") ? 1 : 0) - (ZInput.GetButton("Backward") ? 1 : 0)); val4 += val2 * Vector3.right * (float)((ZInput.GetButton("Right") ? 1 : 0) - (ZInput.GetButton("Left") ? 1 : 0)); val4 += Vector3.up * (float)((ZInput.GetButton("Jump") ? 1 : 0) - (ZInput.GetButton("Crouch") ? 1 : 0)); if (ZInput.IsGamepadActive()) { Vector2 joyLeftStick = ZInput.GetJoyLeftStick(); val4 += val3 * joyLeftStick.y + val2 * Vector3.right * joyLeftStick.x; } float num = Plugin.Settings.Get<float>("BuildCamera.2 - Movement", "Speed") * (ZInput.GetButton("Run") ? Plugin.Settings.Percent("BuildCamera.2 - Movement", "RunMultiplier") : 1f); position += Vector3.ClampMagnitude(val4, 1f) * num * Time.unscaledDeltaTime; ClampPosition(localPlayer); } } private static void ClampPosition(Player p) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0028: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0071: 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_0080: 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_00bc: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)((Character)p).m_eye != (Object)null) ? ((Character)p).m_eye.position : ((Component)p).transform.position); position = val + Vector3.ClampMagnitude(position - val, Plugin.Settings.Get<float>("BuildCamera.3 - Limits", "MaxDistance")); RaycastHit val2 = default(RaycastHit); if (Plugin.Settings.On("BuildCamera.3 - Limits", "StayAboveGround") && Physics.Raycast(position + Vector3.up * 100f, Vector3.down, ref val2, 200f, LayerMask.GetMask(new string[1] { "terrain" }))) { position.y = Mathf.Max(position.y, ((RaycastHit)(ref val2)).point.y + 0.2f); } } private static bool Camera(GameCamera __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!active) { return true; } if (!CanStay(Player.m_localPlayer)) { Exit(); return true; } ((Component)__instance).transform.SetPositionAndRotation(position, Quaternion.Euler(pitch, yaw, 0f)); Camera component = ((Component)__instance).GetComponent<Camera>(); if ((Object)(object)component != (Object)null) { if ((Object)(object)drivenCamera != (Object)(object)component) { RestoreClip(); drivenCamera = component; nearClip = component.nearClipPlane; } component.nearClipPlane = __instance.m_nearClipPlaneMin; } return false; } private static bool Controls(PlayerController __instance) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) Player component = ((Component)__instance).GetComponent<Player>(); if (!Applies(component)) { return true; } float num = (float)AccessTools.Field(typeof(PlayerController), "takeInputDelay").GetValue(null); AccessTools.Field(typeof(PlayerController), "takeInputDelay").SetValue(null, Mathf.Max(0f, num - Time.deltaTime)); Fields.Set(component, "m_autoRun", false); component.SetControls(Vector3.zero, false, false, false, false, false, false, false, false, false, false, false); return false; } private static bool Look(PlayerController __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Player component = ((Component)__instance).GetComponent<Player>(); if (!Applies(component)) { return true; } component.SetMouseLook(Vector2.zero); return false; } private static bool Listener(GameCamera __instance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!active) { return true; } AudioListener val = Fields.Get<AudioListener>(__instance, "m_listner"); if ((Object)(object)val != (Object)null) { ((Component)val).transform.localPosition = Vector3.zero; } return false; } private static void Sailing(float dt, ref Vector3 pos) { if (active || !Plugin.Settings.On("Interface", "Raise Sailing Camera")) { sailOffset = 0f; return; } Player localPlayer = Player.m_localPlayer; Ship val = ((localPlayer != null) ? localPlayer.GetControlledShip() : null); float num = 0f; if ((Object)(object)val != (Object)null) { num = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "") switch { "VikingShip_Ashlands" => 5, "VikingShip" => 4, "Karve" => 3, "Raft" => 2, _ => 0, }; } sailOffset = Mathf.Lerp(sailOffset, num, Mathf.Clamp01(dt * 2f)); pos.y += sailOffset; } private static void Placement(Player __instance, out float __state) { __state = __instance.m_maxPlaceDistance; if (Applies(__instance)) { __instance.m_maxPlaceDistance = 1000f; } } private static Exception RestorePlacement(Player __instance, float __state, Exception __exception) { if (__instance.m_maxPlaceDistance == 1000f) { __instance.m_maxPlaceDistance = __state; } return __exception; } private static void Reach(Player __instance, ref bool __result, Vector3 point) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (Applies(__instance) && __result) { GameObject val = Fields.Get<GameObject>(__instance, "m_placementGhost"); float num = ((!((Object)(object)val == (Object)null)) ? (val.GetComponent<Piece>()?.m_extraPlacementDistance ?? 0) : 0); if (Vector3.Distance(position, point) > Plugin.Settings.Get<float>("BuildCamera.3 - Limits", "PlacementReach") + num) { __result = false; } } } private static bool RemovalReach(Player player) { //IL_0017: 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) RaycastHit val = default(RaycastHit); if ((Object)(object)GameCamera.instance != (Object)null && Physics.Raycast(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, ref val, Plugin.Settings.Get<float>("BuildCamera.3 - Limits", "PlacementReach"), Fields.Get<int>(player, "m_removeRayMask"))) { return ((RaycastHit)(ref val)).distance <= Plugin.Settings.Get<float>("BuildCamera.3 - Limits", "PlacementReach"); } return false; } private static bool Hover(Player __instance, out float __state) { __state = __instance.m_maxPlaceDistance; if (!Applies(__instance)) { return true; } if (!RemovalReach(__instance)) { Fields.Set(__instance, "m_hoveringPiece", null); return false; } __instance.m_maxPlaceDistance = 1000f; return true; } private static bool Removal(Player __instance, ref bool __result, out float __state) { __state = __instance.m_maxPlaceDistance; if (!Applies(__instance)) { return true; } if (!RemovalReach(__instance)) { __result = false; return false; } __instance.m_maxPlaceDistance = 1000f; return true; } private static void BuildStation(Player __instance, RequirementMode mode, out Vector3? __state) { //IL_001e: 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) __state = stationPoint; stationPoint = null; if (Applies(__instance) && (int)mode == 0 && Plugin.Settings.On("BuildCamera.3 - Limits", "WorkbenchNearPiece")) { GameObject val = Fields.Get<GameObject>(__instance, "m_placementGhost"); if ((Object)(object)val != (Object)null) { stationPoint = val.transform.position; } } } private static void RemoveStation(Player __instance, Piece piece, out Vector3? __state) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) __state = stationPoint; stationPoint = null; if (Applies(__instance) && (Object)(object)piece != (Object)null && Plugin.Settings.On("BuildCamera.3 - Limits", "WorkbenchNearPiece")) { stationPoint = ((Component)piece).transform.position; } } private static void Station(ref Vector3 point) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (stationPoint.HasValue) { point = stationPoint.Value; } } private static Exception RestoreStation(Vector3? __state, Exception __exception) { stationPoint = __state; return __exception; } private static void RestoreClip() { if ((Object)(object)drivenCamera != (Object)null) { drivenCamera.nearClipPlane = nearClip; } drivenCamera = null; } private static void Damaged(Player __instance) { if (Applies(__instance) && Plugin.Settings.On("BuildCamera.3 - Limits", "ExitWhenHit")) { Exit(); } } internal static void Exit() { RestoreClip(); active = false; owner = null; stationPoint = null; } } internal static class CarryWeight { private struct BaseScope { internal bool Changed; internal float Original; internal float Written; } internal static void Install(PatchRegistry patches) { patches.Add(typeof(Player), "GetMaxCarryWeight", Type.EmptyTypes, typeof(CarryWeight), "Begin", null, "End"); patches.Add(typeof(SE_Stats), "ModifyMaxCarryWeight", new Type[2] { typeof(float), typeof(float).MakeByRefType() }, typeof(CarryWeight), "Bonus"); } private static void Begin(Player __instance, out BaseScope __state) { __state = default(BaseScope); Settings settings = Plugin.Settings; __state = new BaseScope { Changed = true, Original = __instance.m_maxCarryWeight, Written = settings.Get<float>("Player", "baseMaximumWeight") }; __instance.m_maxCarryWeight = __state.Written; } private static Exception End(Player __instance, BaseScope __state, Exception __exception) { if (__state.Changed && __instance.m_maxCarryWeight == __state.Written) { __instance.m_maxCarryWeight = __state.Original; } return __exception; } private static bool Bonus(SE_Stats __instance, ref float limit) { if (__instance.m_addMaxCarryWeight <= 0f) { return true; } float num = Plugin.Settings.Get<float>("Player", "baseMegingjordBuff") - 150f; limit = Mathf.Max(0f, limit + __instance.m_addMaxCarryWeight + num); return false; } } internal static class ContainerWindow { private static InventoryGui owner; private static ContainerWindowDrag handle; private static Vector2 initial; internal static RectTransform Root => owner?.m_container; internal static void Install(PatchRegistry p) { p.Add(typeof(InventoryGui), "UpdateContainer", new Type[1] { typeof(Player) }, typeof(ContainerWindow), null, "Update"); p.Add(typeof(InventoryGui), "OnDestroy", Type.EmptyTypes, typeof(ContainerWindow), "Destroyed"); } private static void Update(InventoryGui __instance) { //IL_003c: 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_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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0118: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_0156: 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_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: 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_0198: 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) if (!((Component)__instance.m_container).gameObject.activeInHierarchy || Plugin.Settings == null) { return; } if ((Object)(object)owner != (Object)(object)__instance) { Close(); owner = __instance; initial = owner.m_container.anchoredPosition; handle = ((Component)owner.m_container).gameObject.AddComponent<ContainerWindowDrag>(); } if (!handle.Dragging) { if (!InventorySlots.Active) { owner.m_container.anchoredPosition = initial; return; } Vector2 val = Plugin.Settings.Get<Vector2>("Equipment.Container Window", "Container Position"); Matrix4x4 val2 = SlotPanel.LayoutMatrix(((Transform)owner.m_container).parent, owner); Matrix4x4 val3 = ((Matrix4x4)(ref val2)).inverse * SlotPanel.LayoutMatrix((Transform)(object)owner.m_player, owner); Matrix4x4 val4 = ((Matrix4x4)(ref val2)).inverse * SlotPanel.LayoutMatrix((Transform)(object)owner.m_container, owner); Rect rect = owner.m_player.rect; float y = ((Matrix4x4)(ref val3)).MultiplyPoint3x4(Vector2.op_Implicit(((Rect)(ref rect)).min)).y; rect = owner.m_container.rect; float xMin = ((Rect)(ref rect)).xMin; rect = owner.m_container.rect; float y2 = ((Matrix4x4)(ref val4)).MultiplyPoint3x4(Vector2.op_Implicit(new Vector2(xMin, ((Rect)(ref rect)).yMax))).y; Vector2 val5 = owner.m_container.anchoredPosition + Vector2.up * (y - 12f - y2); SetPosition((val == Vector2.zero) ? val5 : val); } } internal static void SetPosition(Vector2 position) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_004a: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0062: 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) //IL_006b: 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) //IL_0079: 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_0083: 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) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_00a6: 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_00ec: 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_00be: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_014a: 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_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_0158: 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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017a: 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_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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) RectTransform root = Root; if ((Object)(object)root == (Object)null) { return; } root.anchoredPosition = position; Transform parent = ((Transform)owner.m_player).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { return; } Matrix4x4 val2 = SlotPanel.LayoutMatrix((Transform)(object)root, owner); Rect rect = root.rect; Vector2 val3 = Vector2.op_Implicit(((Matrix4x4)(ref val2)).MultiplyPoint3x4(Vector2.op_Implicit(((Rect)(ref rect)).min))); rect = root.rect; Vector2 val4 = Vector2.op_Implicit(((Matrix4x4)(ref val2)).MultiplyPoint3x4(Vector2.op_Implicit(((Rect)(ref rect)).max))); float x = val3.x; rect = val.rect; float num; if (!(x < ((Rect)(ref rect)).xMin)) { float x2 = val4.x; rect = val.rect; if (!(x2 > ((Rect)(ref rect)).xMax)) { num = 0f; } else { rect = val.rect; num = ((Rect)(ref rect)).xMax - val4.x; } } else { rect = val.rect; num = ((Rect)(ref rect)).xMin - val3.x; } float y = val3.y; rect = val.rect; float num2; if (!(y < ((Rect)(ref rect)).yMin)) { float y2 = val4.y; rect = val.rect; if (!(y2 > ((Rect)(ref rect)).yMax)) { num2 = 0f; } else { rect = val.rect; num2 = ((Rect)(ref rect)).yMax - val4.y; } } else { rect = val.rect; num2 = ((Rect)(ref rect)).yMin - val3.y; } Vector2 val5 = default(Vector2); ((Vector2)(ref val5))..ctor(num, num2); Vector2 anchoredPosition = root.anchoredPosition; Matrix4x4 val6 = SlotPanel.LayoutMatrix(((Transform)root).parent, owner); val6 = ((Matrix4x4)(ref val6)).inverse; root.anchoredPosition = anchoredPosition + Vector2.op_Implicit(((Matrix4x4)(ref val6)).MultiplyVector(Vector2.op_Implicit(val5))); } private static void Destroyed(InventoryGui __instance) { if ((Object)(object)owner == (Object)(object)__instance) { Close(); } } internal static void Close() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner != (Object)null) { owner.m_container.anchoredPosition = initial; } if ((Object)(object)handle != (Object)null) { Object.Destroy((Object)(object)handle); } owner = null; handle = null; } } internal sealed class ContainerWindowDrag : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler, IPointerClickHandler { internal bool Dragging; private Vector2 start; private Vector2 origin; private static bool Modifier() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut val = Plugin.Settings.Get<KeyboardShortcut>("Equipment.Container Window", "Container Drag Key"); if ((int)((KeyboardShortcut)(ref val)).MainKey != 0) { return ((KeyboardShortcut)(ref val)).IsPressed(); } return true; } private static bool Background(PointerEventData data) { //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_0017: 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_0032: 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) RaycastResult pointerPressRaycast = data.pointerPressRaycast; if (!((Object)(object)((RaycastResult)(ref pointerPressRaycast)).gameObject == (Object)null)) { pointerPressRaycast = data.pointerPressRaycast; if ((Object)(object)((RaycastResult)(ref pointerPressRaycast)).gameObject.GetComponentInParent<InventoryGrid>() == (Object)null) { pointerPressRaycast = data.pointerPressRaycast; return (Object)(object)((RaycastResult)(ref pointerPressRaycast)).gameObject.GetComponentInParent<Selectable>() == (Object)null; } return false; } return true; } private static bool Point(PointerEventData data, out Vector2 point) { //IL_000a: 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_0021: Expected O, but got Unknown return RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)((Transform)ContainerWindow.Root).parent, data.position, data.pressEventCamera, ref point); } public void OnBeginDrag(PointerEventData data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if ((int)data.button == 0 && Background(data) && Modifier() && Plugin.Settings.On("Equipment.Container Window", "Container Draggable") && Point(data, out start)) { origin = ContainerWindow.Root.anchoredPosition; Dragging = true; } } public void OnDrag(PointerEventData data) { //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_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) if (Dragging && Point(data, out var point)) { ContainerWindow.SetPosition(origin + point - start); } } public void OnEndDrag(PointerEventData data) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (Dragging) { Dragging = false; Plugin.Settings.SetLocal<Vector2>("Equipment.Container Window", "Container Position", ContainerWindow.Root.anchoredPosition); } } public void OnPointerClick(PointerEventData data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((int)data.button == 1 && Background(data) && Modifier()) { Plugin.Settings.SetLocal<Vector2>("Equipment.Container Window", "Container Position", Vector2.zero); } } private void OnDisable() { Dragging = false; } } internal static class ControlOverrides { private static string lastControls; private static ZInput lastInput; internal static void Install(PatchRegistry patches) { patches.Add(typeof(ZInput), "Load", Type.EmptyTypes, typeof(ControlOverrides), null, "Loaded"); } private static void Loaded() { lastInput = null; Refresh(); } internal static void Refresh() { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c0: 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_0124: 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_006d: 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) Settings settings = Plugin.Settings; if (settings == null || ZInput.instance == null) { return; } bool flag = settings.On("Controls", "Override Controls"); HashSet<KeyCode> hashSet = new HashSet<KeyCode>(); KeyboardShortcut val; if (InventorySlots.Active && settings.On("Equipment.Toggles", "Enable Quick Slots")) { for (int i = 1; i <= settings.Get<int>("Equipment.Quick Slots", "Quick Slot Count"); i++) { val = settings.Get<KeyboardShortcut>("Equipment.Hotkeys", "Quick slot hotkey " + i); hashSet.Add(((KeyboardShortcut)(ref val)).MainKey); } } if (InventorySlots.Active && settings.On("Equipment.Equipment Panel", "Equipment Panel Draggable")) { val = settings.Get<KeyboardShortcut>("Equipment.Equipment Panel", "Equipment Panel Drag Key"); hashSet.Add(((KeyboardShortcut)(ref val)).MainKey); } if (settings.On("Interface", "Drag Ammo Slot Panel")) { val = settings.Get<KeyboardShortcut>("Interface", "Ammo Slot Panel Drag Key"); hashSet.Add(((KeyboardShortcut)(ref val)).MainKey); } if (settings.On("Equipment.Container Window", "Container Draggable")) { val = settings.Get<KeyboardShortcut>("Equipment.Container Window", "Container Drag Key"); hashSet.Add(((KeyboardShortcut)(ref val)).MainKey); } if (settings.On("Recycling", "Enabled")) { hashSet.Add(settings.Get<KeyCode>("Recycling", "DiscardHotkey")); } hashSet.Remove((KeyCode)0); string text = flag + ":" + string.Join(",", hashSet.OrderBy((KeyCode k) => k)); if (lastInput == ZInput.instance && lastControls == text) { return; } lastInput = ZInput.instance; lastControls = text; if (flag) { MethodInfo pathMethod = typeof(ZInput).GetMethod("KeyCodeToPath", BindingFlags.Static | BindingFlags.NonPublic); HashSet<string> paths = new HashSet<string>(hashSet.Select((KeyCode k) => (string)pathMethod.Invoke(null, new object[2] { k, false })), StringComparer.OrdinalIgnoreCase); ButtonDef[] array = Fields.Get<Dictionary<string, ButtonDef>>(ZInput.instance, "m_buttons").Values.Where((ButtonDef b) => b.Rebindable && paths.Contains(b.GetActionPath(true))).ToArray(); foreach (ButtonDef val2 in array) { val2.Rebind(string.Empty); PlatformPrefs.SetString("kbmBinding_" + val2.Name, string.Empty); } } } internal static void Close() { lastControls = null; lastInput = null; } } internal static class CosmeticArmor { private const string HiddenHelmetKey = "torubaki.bettertweaks.hideHelmet"; private const string HiddenCapeKey = "torubaki.bettertweaks.hideCape"; private static readonly ItemType[] Types; internal static bool CapeButtonEnabled => Plugin.Settings.On("Interface", "Hide Cape Button"); internal static bool ButtonEnabled => Plugin.Settings.On("Interface", "Hide Helmet Button"); internal static bool HelmetHidden(Player player) { if ((Object)(object)player != (Object)null && ButtonEnabled && InventorySlots.EquipmentFor(player) && player.m_customData.TryGetValue("torubaki.bettertweaks.hideHelmet", out var value)) { return value == "true"; } return false; } internal static bool CapeHidden(Player player) { if ((Object)(object)player != (Object)null && CapeButtonEnabled && InventorySlots.EquipmentFor(player) && player.m_customData.TryGetValue("torubaki.bettertweaks.hideCape", out var value)) { return value == "true"; } return false; } internal static void ToggleCape(Player player) { if (!((Object)(object)player == (Object)null) && CapeButtonEnabled && InventorySlots.EquipmentFor(player)) { if (CapeHidden(player)) { player.m_customData.Remove("torubaki.bettertweaks.hideCape"); } else { player.m_customData["torubaki.bettertweaks.hideCape"] = "true"; } Changed(player); } } internal static void Loaded(Player player) { if (!ButtonEnabled) { player.m_customData.Remove("torubaki.bettertweaks.hideHelmet"); } if (!CapeButtonEnabled) { player.m_customData.Remove("torubaki.bettertweaks.hideCape"); } } internal static void ToggleHelmet(Player player) { if (!((Object)(object)player == (Object)null) && ButtonEnabled && InventorySlots.EquipmentFor(player)) { if (HelmetHidden(player)) { player.m_customData.Remove("torubaki.bettertweaks.hideHelmet"); } else { player.m_customData["torubaki.bettertweaks.hideHelmet"] = "true"; } Changed(player); } } internal static bool IsSlot(int slot) { if (slot >= 24) { return slot < 28; } return false; } internal static bool Matches(ItemData item, int slot) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 if (item != null && IsSlot(slot)) { return (int)item.m_shared.m_itemType == (int)Types[slot - 24]; } return false; } internal static bool Allows(Player player, ItemData item, Vector2i position) { //IL_0008: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (InventorySlots.CosmeticsFor(player) && position.x >= 0 && position.x < 8) { return Matches(item, (position.y - InventorySlots.PositionFor(player, 0).y) * 8 + position.x); } return false; } internal static void Install(PatchRegistry patches) { patches.Add(typeof(Humanoid), "SetupVisEquipment", new Type[2] { typeof(VisEquipment), typeof(bool) }, typeof(CosmeticArmor), null, "Visuals"); patches.Add(typeof(Player), "OnInventoryChanged", Type.EmptyTypes, typeof(CosmeticArmor), null, "Changed"); patches.Add(typeof(Inventory), "UpdateTotalWeight", Type.EmptyTypes, typeof(CosmeticArmor), null, "Weight"); } private static ItemData Display(Player player, int slot, string regular) { ItemData val = (InventorySlots.CosmeticsFor(player) ? InventorySlots.At(player, slot) : null); if (!Matches(val, slot)) { return Fields.Get<ItemData>(player, regular); } return val; } private static int Hash(ItemData item) { if (!((Object)(object)item?.m_dropPrefab == (Object)null)) { return StringExtensionMethods.GetStableHashCode(((Object)item.m_dropPrefab).name); } return 0; } private static void Visuals(Humanoid __instance, VisEquipment visEq) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)visEq == (Object)null) && !((Object)(object)InventorySlots.Owner(((Humanoid)val).GetInventory()) == (Object)null)) { ItemData item = Display(val, 24, "m_helmetItem"); ItemData item2 = Display(val, 25, "m_chestItem"); ItemData item3 = Display(val, 26, "m_legItem"); ItemData val2 = Display(val, 27, "m_shoulderItem"); visEq.SetHelmetItem((!HelmetHidden(val)) ? Hash(item) : 0); visEq.SetChestItem(Hash(item2)); visEq.SetLegItem(Hash(item3)); visEq.SetShoulderItem((!CapeHidden(val)) ? Hash(val2) : 0, val2?.m_variant ?? 0, val2?.m_quality ?? 0); } } private static void Changed(Player __instance) { if (!((Object)(object)InventorySlots.Owner(((Humanoid)__instance).GetInventory()) == (Object)null)) { ZNetView val = Fields.Get<ZNetView>(__instance, "m_nview"); if (!((Object)(object)val == (Object)null) && (val.GetZDO() == null || val.IsOwner())) { Visuals((Humanoid)(object)__instance, Fields.Get<VisEquipment>(__instance, "m_visEquipment")); } } } private static void Weight(Inventory __instance) { Player player = InventorySlots.Owner(__instance); if (!((Object)(object)player == (Object)null) && InventorySlots.CosmeticsFor(player)) { Fields.Set(__instance, "m_totalWeight", Fields.Get<float>(__instance, "m_totalWeight") - (from i in __instance.GetAllItems() where Matches(i, InventorySlots.SlotFor(player, i)) select i).Sum((ItemData i) => i.GetWeight(-1))); } } static CosmeticArmor() { ItemType[] array = new ItemType[4]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); Types = (ItemType[])(object)array; } } internal static class CraftingStations { private static readonly HashSet<CraftingStation> stations = new HashSet<CraftingStation>(); private static readonly HashSet<StationExtension> extensions = new HashSet<StationExtension>(); private static bool restoring; private static readonly OwnedOverrides overrides = new OwnedOverrides(); internal static void Install(PatchRegistry patches) { patches.Add(typeof(CraftingStation), "Start", Type.EmptyTypes, typeof(CraftingStations), null, "Ready"); patches.Add(typeof(StationExtension), "Awake", Type.EmptyTypes, typeof(CraftingStations), null, "Extension"); patches.Add(typeof(CraftingStation), "GetExtensions", Type.EmptyTypes, typeof(CraftingStations), null, "SpawnRadius"); patches.Add(typeof(ZNetScene), "Awake", Type.EmptyTypes, typeof(CraftingStations), null, "CompactSpacing"); } private static void Ready(CraftingStation __instance) { stations.Add(__instance); Configure(__instance); } private static void Configure(CraftingStation station) { overrides.Set(station, "m_rangeBuild", () => station.m_rangeBuild, delegate(float value) { station.m_rangeBuild = value; }, Plugin.Settings.Get<float>("Workbench", "workbenchRange")); if (Plugin.Settings.On("Workbench", "disableRoofCheck")) { overrides.Set(station, "m_craftRequireRoof", () => station.m_craftRequireRoof, delegate(bool value) { station.m_craftRequireRoof = value; }, value: false); } } private static void Extension(StationExtension __instance) { extensions.Add(__instance); overrides.Set(__instance, "m_maxStationDistance", () => __instance.m_maxStationDistance, delegate(float value) { __instance.m_maxStationDistance = value; }, Plugin.Settings.Get<float>("Workbench", "workbenchAttachmentRange")); } private static void SpawnRadius(CraftingStation __instance) { if (restoring) { return; } float num = Plugin.Settings.Get<float>("Workbench", "workbenchEnemySpawnRange"); if (num <= 0f) { return; } Collider effectAreaCollider = __instance.m_effectAreaCollider; SphereCollider val = (SphereCollider)(object)((effectAreaCollider is SphereCollider) ? effectAreaCollider : null); if (val != null) { val.radius = num; return; } Collider effectAreaCollider2 = __instance.m_effectAreaCollider; CapsuleCollider val2 = (CapsuleCollider)(object)((effectAreaCollider2 is CapsuleCollider) ? effectAreaCollider2 : null); if (val2 != null) { val2.radius = num; } } private static void CompactSpacing() { if ((Object)(object)ZNetScene.instance == (Object)null || !Plugin.Settings.Tweak("Station Extensions Changes")) { return; } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { Piece piece = prefab.GetComponent<Piece>(); if ((Object)(object)piece != (Object)null && piece.m_spaceRequirement >= 2f) { overrides.Set(piece, "m_spaceRequirement", () => piece.m_spaceRequirement, delegate(float value) { piece.m_spaceRequirement = value; }, 1f); } } } private static void RefreshStations(bool restore) { stations.RemoveWhere((CraftingStation station) => (Object)(object)station == (Object)null); extensions.RemoveWhere((StationExtension extension) => (Object)(object)extension == (Object)null); restoring = restore; try { if (!restore) { StationExtension[] array = extensions.ToArray(); for (int num = 0; num < array.Length; num++) { Extension(array[num]); } } CraftingStation[] array2 = stations.ToArray(); foreach (CraftingStation val in array2) { if (!restore) { Configure(val); } Fields.Set(val, "m_updateExtensionTimer", 2f); Fields.Call(val, "GetExtensions", Type.EmptyTypes); } } finally { restoring = false; } } internal static void Refresh() { overrides.Restore(); CompactSpacing(); RefreshStations(restore: false); } internal static void Close() { overrides.Restore(); RefreshStations(restore: true); stations.Clear(); extensions.Clear(); } } internal static class CreatureLoot { private static readonly HashSet<ZDO> spawningLoot = new HashSet<ZDO>(); internal static void Install(PatchRegistry p) { p.Add(typeof(Ragdoll), "Start", Type.EmptyTypes, typeof(CreatureLoot), null, "EarlyLoot"); p.Add(typeof(Ragdoll), "FixedUpdate", Type.EmptyTypes, typeof(CreatureLoot), null, "EarlyLoot"); p.Add(typeof(Ragdoll), "SpawnLoot", new Type[1] { typeof(Vector3) }, typeof(CreatureLoot), "BeginLoot", null, "EndLoot"); } private static void EarlyLoot(Ragdoll __instance) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Settings.On("Enemies", "Instant Loot Drops")) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner() && component.GetZDO().GetInt(ZDOVars.s_drops, 0) > 0) { Fields.Call(__instance, "SpawnLoot", new Type[1] { typeof(Vector3) }, ((Component)__instance).transform.position); } } } private static bool BeginLoot(Ragdoll __instance, out ZDO __state) { __state = null; ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { return false; } ZDO zDO = component.GetZDO(); if (zDO.GetBool("torubaki.bettertweaks.loot.spawned.v1", false) || zDO.GetInt(ZDOVars.s_drops, 0) <= 0) { return false; } if (!spawningLoot.Add(zDO)) { return false; } __state = zDO; return true; } private static Exception EndLoot(ZDO __state, bool __runOriginal, Exception __exception) { if (__state != null) { spawningLoot.Remove(__state); } if (__state != null && __runOriginal && __exception == null) { __state.Set("torubaki.bettertweaks.loot.spawned.v1", true); __state.Set(ZDOVars.s_drops, 0, false); } return __exception; } } internal static class EquipmentActions { internal const string LoadedKey = "torubaki.bettertweaks.crossbowLoaded"; private static readonly Dictionary<Player, int> running = new Dictionary<Player, int>(); private static readonly Dictionary<Player, int> unequipping = new Dictionary<Player, int>(); private static bool Keep => Plugin.Settings.Tweak("Keep Crossbows Loaded"); internal static void Install(PatchRegistry patches) { Type typeFromHandle = typeof(EquipmentActions); patches.Add(typeof(Player), "CheckRun", new Type[2] { typeof(Vector3), typeof(float) }, typeFromHandle, "BeginRun", null, "EndRun"); patches.Add(typeof(Player), "ClearActionQueue", Type.EmptyTypes, typeFromHandle, "ClearQueue"); patches.Add(typeof(Player), "InMinorActionSlowdown", Type.EmptyTypes, typeFromHandle, "Slowdown", "ReloadSlowdown"); patches.Add(typeof(Player), "SetWeaponLoaded", new Type[1] { typeof(ItemData) }, typeFromHandle, null, "Loaded"); patches.Add(typeof(Player), "ResetLoadedWeapon", Type.EmptyTypes, typeFromHandle, "BeforeReset", "AfterReset"); patches.Add(typeof(Humanoid), "UnequipItem", new Type[2] { typeof(ItemData), typeof(bool) }, typeFromHandle, "BeginUnequip", null, "EndUnequip"); patches.Add(typeof(Humanoid), "EquipItem", new Type[2] { typeof(ItemData), typeof(bool) }, typeFromHandle, null, "Equipped"); } private static bool Crossbow(ItemData item) { if (item != null && item.m_shared.m_attack != null && item.m_shared.m_attack.m_requiresReload) { if (!(((object)Unsafe.As<AnimationState, AnimationState>(ref item.m_shared.m_animationState)/*cast due to .constrained prefix*/).ToString() == "Crossbow")) { return item.m_shared.m_name == "$item_graplinghook"; } return true; } return false; } private static int Depth(Dictionary<Player, int> scope, Player player) { if (!scope.TryGetValue(player, out var value)) { return 0; } return value; } private static void BeginRun(Player __instance) { running[__instance] = Depth(running, __instance) + 1; } private static void EndRun(Player __instance) { if (Depth(running, __instance) <= 1) { running.Remove(__instance); } else { running[__instance]--; } } private static bool ClearQueue(Player __instance) { if (Depth(running, __instance) == 0) { return true; } bool flag = Plugin.Settings.On("MovingEquipment", "Enabled"); bool flag2 = Plugin.Settings.Tweak("Crossbow Reload While Moving") && Crossbow(((Humanoid)__instance).GetCurrentWeapon()); if (!flag && !flag2) { return true; } IList list = Fields.Get<IList>(__instance, "m_actionQueue"); for (int num = list.Count - 1; num >= 0; num--) { string text = Fields.Get<object>(list[num], "m_type").ToString(); if ((!flag || (!(text == "Equip") && !(text == "Unequip"))) && (!flag2 || !(text == "Reload"))) { list.RemoveAt(num); } } return false; } private static bool Slowdown(Player __instance, ref bool __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Settings.On("MovingEquipment", "Enabled") && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { if (!((Character)__instance).IsRunning()) { Vector3 val = Fields.Get<Vector3>(__instance, "m_moveDir"); if (((Vector3)(ref val)).sqrMagnitude <= 0.0001f) { goto IL_0045; } } IList list = Fields.Get<IList>(__instance, "m_actionQueue"); if (list.Count != 0) { string text = Fields.Get<object>(list[0], "m_type").ToString(); if (text != "Equip" && text != "Unequip") { return true; } } __result = false; return false; } goto IL_0045; IL_0045: return true; } private static void ReloadSlowdown(Player __instance, ref bool __result) { if (__result && ((Character)__instance).IsRunning()) { IList list = Fields.Get<IList>(__instance, "m_actionQueue"); if (list.Count != 0 && Fields.Get<object>(list[0], "m_type").ToString() == "Reload" && Plugin.Settings.Tweak("Crossbow Reload While Moving") && Crossbow(Fields.Get<ItemData>(list[0], "m_item"))) { __result = false; } } } private static void Loaded(Player __instance, ItemData __0) { if (Keep && Crossbow(__0)) { __0.m_customData["torubaki.bettertweaks.crossbowLoaded"] = "1"; } } private static void BeforeReset(Player __instance, out ItemData __state) { __state = Fields.Get<ItemData>(__instance, "m_weaponLoaded"); } private static void AfterReset(Player __instance, ItemData __state) { if (__state != null && Depth(unequipping, __instance) == 0) { __state.m_customData.Remove("torubaki.bettertweaks.crossbowLoaded"); } } private static void BeginUnequip(Humanoid __instance, ItemData __0, out Player __state) { __state = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)__state == (Object)null || !Keep || !Crossbow(__0)) { __state = null; return; } if (Fields.Get<ItemData>(__state, "m_weaponLoaded") == __0) { __0.m_customData["torubaki.bettertweaks.crossbowLoaded"] = "1"; } unequipping[__state] = Depth(unequipping, __state) + 1; } private static void EndUnequip(Player __state) { if (!((Object)(object)__state == (Object)null)) { if (Depth(unequipping, __state) <= 1) { unequipping.Remove(__state); } else { unequipping[__state]--; } } } private static void Equipped(Humanoid __instance, ItemData __0, bool __result) { if (__result && Keep) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && Crossbow(__0) && __0.m_customData.TryGetValue("torubaki.bettertweaks.crossbowLoaded", out var value) && value == "1") { Fields.Call(val, "SetWeaponLoaded", new Type[1] { typeof(ItemData) }, __0); } } } internal static void Close() { running.Clear(); unequipping.Clear(); } } internal static class EquipmentRules { private sealed class Pending { internal ItemData Item; internal bool Equip; } private sealed class Hands { internal ItemData Left; internal ItemData Right; } private static readonly Dictionary<Player, List<Pending>> queued = new Dictionary<Player, List<Pending>>(); private static readonly Dictionary<Player, Hands> swimming = new Dictionary<Player, Hands>(); [ThreadStatic] private static Humanoid updating; [ThreadStatic] private static int automating; [ThreadStatic] private static int hiding; private static bool Enabled(string key) { return Plugin.Settings.Get<bool>("Player", key); } internal static void Install(PatchRegistry p) { p.Add(typeof(Player), "ToggleEquipped", new Type[1] { typeof(ItemData) }, typeof(EquipmentRules), "Queue"); p.Add(typeof(Humanoid), "EquipItem", new Type[2] { typeof(ItemData), typeof(bool) }, typeof(EquipmentRules), null, "Equipped"); p.Add(typeof(Humanoid), "UnequipItem", new Type[2] { typeof(ItemData), typeof(bool) }, typeof(EquipmentRules), null, "Unequipped"); p.Add(typeof(Humanoid), "UpdateEquipment", new Type[1] { typeof(float) }, typeof(EquipmentRules), "UpdateEquipment", null, "EndUpdate"); p.Add(typeof(Humanoid), "HideHandItems", new Type[2] { typeof(bool), typeof(bool) }, typeof(EquipmentRules), "Hide", "Hidden", "EndHide"); p.Add(typeof(Humanoid), "ShowHandItems", new Type[2] { typeof(bool), typeof(bool) }, typeof(EquipmentRules), "Show"); } private static bool Queue(Player __instance, ItemData __0, ref bool __result) { if (!Enabled("queueWeaponChanges") || !((Character)__instance).InAttack() || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || __0 == null || !__0.IsEquipable() || !((Humanoid)__instance).GetInventory().ContainsItem(__0)) { return true; } if (!queued.TryGetValue(__instance, out var value)) { queued.Add(__instance, value = new List<Pending>()); } Pending pending = value.FirstOrDefault((Pending p) => p.Item == __0); bool flag = !(pending?.Equip ?? ((Humanoid)__instance).IsItemEquiped(__0)); if (pending != null) { value.Remove(pending); } if (flag != ((Humanoid)__instance).IsItemEquiped(__0) && value.Count < 32) { value.Add(new Pending { Item = __0, Equip = flag }); } __result = true; return false; } private static void Equipped(Humanoid __instance, ItemData __0, bool __result) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Invalid comparison between Unknown and I4 //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Invalid comparison between Unknown and I4 if (!__result) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer || automating > 0 || hiding > 0 || __0 == null) { return; } if ((Object)(object)updating != (Object)(object)val) { swimming.Remove(val); } if (!Enabled("autoEquipShield") || (int)__0.m_shared.m_itemType != 3) { return; } ItemData obj = Fields.Get<ItemData>(val, "m_leftItem"); if (obj != null && (int)obj.m_shared.m_itemType == 5) { return; } ItemData val2 = (from i in ((Humanoid)val).GetInventory().GetAllItems() where (int)i.m_shared.m_itemType == 5 && (!i.m_shared.m_useDurability || i.m_durability > 0f) orderby i.GetBaseBlockPower() descending select i).FirstOrDefault(); if (val2 == null) { return; } automating++; try { ((Humanoid)val).EquipItem(val2, false); } finally { automating--; } } private static void Unequipped(Humanoid __instance, ItemData __0) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer || automating > 0 || hiding > 0 || !Enabled("autoUnequipShield") || __0 == null || (int)__0.m_shared.m_itemType != 3 || ((Humanoid)val).IsItemEquiped(__0)) { return; } ItemData val2 = Fields.Get<ItemData>(val, "m_leftItem"); if (val2 == null || (int)val2.m_shared.m_itemType != 5) { return; } automating++; try { ((Humanoid)val).UnequipItem(val2, false); } finally { automating--; } } private static void UpdateEquipment(Humanoid __instance, out Humanoid __state) { __state = updating; updating = __instance; } private static Exception EndUpdate(Humanoid __state, Exception __exception) { updating = __state; return __exception; } private static bool Hide(Humanoid __instance, ref bool __result, out int __state) { __state = hiding; hiding++; Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if ((Object)(object)updating != (Object)(object)val) { swimming.Remove(val); return true; } if (!((Character)val).IsSwimming() || ((Character)val).IsOnGround()) { return true; } if (Enabled("dontUnequipItemsWhenSwimming")) { __result = false; return false; } return true; } private static void Hidden(Humanoid __instance, bool __result) { if (__result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !((Object)(object)updating != (Object)(object)val) && Enabled("reequipItemsAfterSwimming") && ((Character)val).IsSwimming()) { swimming[val] = new Hands { Left = Fields.Get<ItemData>(val, "m_hiddenLeftItem"), Right = Fields.Get<ItemData>(val, "m_hiddenRightItem") }; } } } private static Exception EndHide(int __state, Exception __exception) { hiding = __state; return __exception; } private static void Show(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && automating == 0) { swimming.Remove(val); } } internal static void Tick() { Player player = Player.m_localPlayer; Player[] array = queued.Keys.Where((Player p) => (Object)(object)p == (Object)null || (Object)(object)p != (Object)(object)player || ((Character)p).IsDead()).ToArray(); foreach (Player key in array) { queued.Remove(key); } array = swimming.Keys.Where((Player p) => (Object)(object)p == (Object)null || (Object)(object)p != (Object)(object)player || ((Character)p).IsDead()).ToArray(); foreach (Player key2 in array) { swimming.Remove(key2); } if ((Object)(object)player == (Object)null || ((Character)player).IsDead()) { return; } if (!Enabled("queueWeaponChanges")) { queued.Clear(); } if (!Enabled("reequipItemsAfterSwimming")) { swimming.Clear(); } if (((Character)player).InAttack() || ((Character)player).InDodge() || ((Character)player).IsStaggering() || ((Character)player).IsKnockedBack() || ((Character)player).InMinorAction() || ((Character)player).IsTeleporting()) { return; } if (queued.TryGetValue(player, out var value) && value.Count > 0) { Pending pending = value[0]; value.RemoveAt(0); if (((Humanoid)player).GetInventory().ContainsItem(pending.Item) && ((Humanoid)player).IsItemEquiped(pending.Item) != pending.Equip) { Fields.Call(player, "ToggleEquipped", new Type[1] { typeof(ItemData) }, pending.Item); } } if (((Character)player).IsSwimming() || !((Character)player).IsOnGround() || !swimming.TryGetValue(player, out var value2)) { return; } swimming.Remove(player); automating++; try { Restore(player, value2.Right, "m_hiddenRightItem"); Restore(player, value2.Left, "m_hiddenLeftItem"); } finally { automating--; } } private static void Restore(Player player, ItemData item, string field) { if (item != null && Fields.Get<ItemData>(player, field) == item && ((Humanoid)player).GetInventory().ContainsItem(item) && ((Humanoid)player).EquipItem(item, true)) { Fields.Set(player, field, null); } } internal static void Close() { queued.Clear(); swimming.Clear(); updating = null; automating = (hiding = 0); } } internal static class EquipmentSlots { private sealed class Scope { internal Player Player; internal ItemData Item; internal ItemData Primary; internal ItemData Displaced; internal Vector2i Destination; internal Vector2i Return; internal bool Substituted; internal bool Restored; internal bool ReturnToInventory; } private static readonly FieldInfo Utility = typeof(Humanoid).GetField("m_utilityItem", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo[] Gear = new string[8] { "m_leftItem", "m_rightItem", "m_chestItem", "m_legItem", "m_helmetItem", "m_shoulderItem", "m_utilityItem", "m_trinketItem" }.Select((string n) => typeof(Humanoid).GetField(n, BindingFlags.Instance | BindingFlags.NonPublic)).ToArray(); private static readonly Dictionary<Player, HashSet<ItemData>> active = new Dictionary<Player, HashSet<ItemData>>(); private static readonly List<Scope> scopes = new List<Scope>(); private static readonly Dictionary<ItemData, (Player Player, Vector2i Position)> unequipTargets = new Dictionary<ItemData, (Player, Vector2i)>(); internal static void Install(PatchRegistry p) { if (Utility == null || Gear.Any((FieldInfo f) => f == null)) { throw new MissingFieldException("Required Humanoid equipment fields are unavailable."); } LanternUtility.Install(p); UtilityVisuals.Install(p); Type typeFromHandle = typeof(EquipmentSlots); p.Add(typeof(Player), "RemoveEquipAction", new Type[1] { typeof(ItemData) }, typeFromHandle, null, "ClearUnequipTargets"); p.Add(typeof(Player), "ClearActionQueue", Type.EmptyTypes, typeFromHandle, null, "Cle