using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BoneLib; using BoneLib.BoneMenu; using BoneLib.Notifications; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Bonelab; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.AI; using Il2CppSLZ.Marrow.Combat; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Interaction; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.PuppetMasta; using Il2CppSLZ.Marrow.SceneStreaming; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSLZ.VRMK; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LabFusion.Data; using LabFusion.Entities; using LabFusion.MonoBehaviours; using LabFusion.Network; using LabFusion.Network.Serialization; using LabFusion.Player; using LabFusion.RPC; using LabFusion.SDK.Modules; using LabFusion.Senders; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using Quality_Lab; using Quality_Lab.Features; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(ModMain), "Quality Of Lab", "2.0.1", "Dynamic Team", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("QualityLab")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("QualityLab")] [assembly: AssemblyTitle("QualityLab")] [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 Quality_Lab { public class ModMain : MelonMod { public static Instance Log { get; private set; } public override void OnInitializeMelon() { Log = ((MelonBase)this).LoggerInstance; Settings.Init(); Stats.Init(); ModMenu.Build(); try { ModuleManager.RegisterModule(); } catch (Exception ex) { Log.Warning("Fusion module not registered (LabFusion not installed?): " + ex.Message); } Hooking.OnLevelLoaded += OnLevelLoaded; Hooking.OnLevelUnloaded += OnLevelUnloaded; Log.Msg("Quality Of Lab loaded."); } public override void OnUpdate() { GodMode.Tick(); Movement.Tick(); World.Tick(); Combat.Tick(); ObjectScaling.Tick(); Spawning.Tick(); Stats.Tick(); Hud.Tick(); Hotkeys.Tick(); WristHud.Tick(); ServerBrowser.Tick(); Freecam.Tick(); Photo.Tick(); TimeScale.Tick(); } public override void OnFixedUpdate() { World.FixedTick(); } public override void OnGUI() { Hud.OnGUI(); } private static void OnLevelLoaded(LevelInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) KeepInventory.OnLevelLoaded(info); World.OnLevelLoaded(); Hud.OnLevelLoaded(); HolsterHider.OnLevelLoaded(); WristHud.OnLevelLoaded(); Movement.OnLevelLoaded(); ObjectScaling.OnLevelLoaded(); } private static void OnLevelUnloaded() { KeepInventory.OnLevelUnloaded(); } } public static class ModMenu { private static readonly Color _teal = new Color(0.2f, 0.8f, 0.8f); private static readonly Color _gold = new Color(1f, 0.84f, 0f); private static readonly Color _gray = new Color(0.6f, 0.6f, 0.6f); private static readonly Color _purple = new Color(0.7f, 0.3f, 1f); private static readonly Color _orange = new Color(1f, 0.55f, 0.1f); private static readonly Color _blue = new Color(0.3f, 0.6f, 1f); private static Page _fusionPlayersPage; private static Page _fusionInfoPage; private static Page _spawnRecentPage; public static void Build() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) Page parent = Page.Root.CreatePage("Quality Of Lab", _teal, 0, true); BuildQuickActionsPage(parent); BuildPlayerPage(parent); BuildMovementPage(parent); BuildCombatWorldPage(parent); BuildSpawnItemsPage(parent); BuildFusionPage(parent); BuildDirectorMorePage(parent); ModMain.Log.Msg("BoneMenu built."); } private static void BuildQuickActionsPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Quick Actions", _gold, 0, true); obj.CreateFunction("Top Up Health", Color.green, (Action)Combat.TopUpHealth); obj.CreateFunction("Top Up Ammo", Color.green, (Action)Combat.TopUpAmmoOnce); obj.CreateFunction("Magic Reload", Color.cyan, (Action)Combat.MagicReload); obj.CreateFunction("Quick Respawn", Color.red, (Action)Movement.QuickRespawn); obj.CreateFunction("Teleport to Aim", Color.green, (Action)Movement.TeleportToReticle); BuildQuickActionsMorePage(obj); } private static void BuildQuickActionsMorePage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00fb: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("More Quick Actions", _orange, 0, true); obj.CreateFunction("Identify Held Item", Color.cyan, (Action)Helpers.Identify); obj.CreateFunction("Toggle Slow-Mo", _purple, (Action)TimeScale.ToggleSlowMo); obj.CreateFunction("Restore Time Scale", _gray, (Action)TimeScale.Restore); obj.CreateFunction("Save Checkpoint 1", Color.green, (Action)delegate { Checkpoints.Save(0); }); obj.CreateFunction("Restore Checkpoint 1", Color.magenta, (Action)delegate { Checkpoints.Restore(0); }); obj.CreateFunction("Emergency Stop", Color.red, (Action)Helpers.PanicResetAll); } private static void BuildPlayerPage(Page parent) { //IL_0006: 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) Page obj = parent.CreatePage("Player", Color.green, 0, true); obj.CreateBool("Invincibility (God Mode)", Color.yellow, Settings.GodMode.Value, (Action)delegate(bool v) { Settings.GodMode.Value = v; }); BuildKeepInventoryPage(obj); BuildAvatarSuitePage(obj); BuildHolstersPage(obj); BuildItemInspectorPage(obj); BuildCheckpointsPage(obj); } private static void BuildAvatarSuitePage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Avatar", _purple, 0, true); BuildAvatarsPage(parent2); BuildAvatarScalePage(parent2); } private static void BuildCheckpointsPage(Page parent) { //IL_0006: 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_0048: 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_00a9: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Checkpoints", _teal, 0, true); obj.CreateFunction("Save to Checkpoint 1", Color.green, (Action)delegate { Checkpoints.Save(0); }); obj.CreateFunction("Restore Checkpoint 1", Color.magenta, (Action)delegate { Checkpoints.Restore(0); }); BuildCheckpointSlotsPage(obj); obj.CreateFunction("Clear All Checkpoints", _gray, (Action)Checkpoints.ClearAll); obj.CreateFunction(" - position + health, per-level guarded", _gray, (Action)delegate { }); } private static void BuildCheckpointSlotsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_009f: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Slots", _teal, 0, true); for (int i = 0; i < 5; i++) { int idx = i; Page obj = val.CreatePage($"Checkpoint {idx + 1}", _teal, 0, true); obj.CreateFunction("Save Here", Color.green, (Action)delegate { Checkpoints.Save(idx); }); obj.CreateFunction("Restore", Color.magenta, (Action)delegate { Checkpoints.Restore(idx); }); obj.CreateFunction("Clear", _gray, (Action)delegate { Checkpoints.Clear(idx); }); } } private static void BuildItemInspectorPage(Page parent) { //IL_0006: 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_0044: 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) Page obj = parent.CreatePage("Item Inspector", _teal, 0, true); obj.CreateFunction("Identify Held Object", Color.cyan, (Action)Helpers.Identify); obj.CreateBool("Auto-Identify on Pickup", Color.cyan, Settings.AutoPerception.Value, (Action)delegate(bool v) { Settings.AutoPerception.Value = v; Settings.Save(); }); obj.CreateFunction(" - logs barcode, mass, type for held item", _gray, (Action)delegate { }); } private static void BuildHolstersPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Holsters", _purple, 0, true); obj.CreateFunction("Restore All Holsters", Color.green, (Action)HolsterHider.ResetAll); obj.CreateFunction("Conceal All Holsters", _orange, (Action)HolsterHider.HideAll); obj.CreateFunction("Re-apply Visibility", Color.cyan, (Action)HolsterHider.ApplyAll); BuildHolsterSlotsPage(obj); } private static void BuildHolsterSlotsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Per-Slot Visibility", _purple, 0, true); for (int i = 0; i < 8; i++) { int idx = i; string text = HolsterHider.GroupNames[i]; Page obj = val.CreatePage(text, _purple, 0, true); obj.CreateInt("Visibility Mode", Color.cyan, Settings.HolsterVisibility[idx].Value, 1, 0, 2, (Action)delegate(int v) { HolsterHider.Set(idx, v); }); obj.CreateFunction("Visible", Color.green, (Action)delegate { HolsterHider.Set(idx, 0); }); obj.CreateFunction("Concealed", _orange, (Action)delegate { HolsterHider.Set(idx, 1); }); obj.CreateFunction("Disabled", Color.red, (Action)delegate { HolsterHider.Set(idx, 2); }); } } private static void BuildKeepInventoryPage(Page parent) { //IL_0006: 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) Page obj = parent.CreatePage("Keep Inventory", _gold, 0, true); obj.CreateInt("Active Slot", Color.cyan, Settings.SelectedSlot.Value, 1, 1, 5, (Action)delegate(int v) { Settings.SelectedSlot.Value = v; Settings.Save(); }); BuildInventoryQuickActionsPage(obj); BuildInventoryToggleablesPage(obj); BuildInventoryPerLevelPage(obj); BuildInventorySlotsPage(obj); } private static void BuildInventoryQuickActionsPage(Page parent) { //IL_0006: 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_0044: 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) Page obj = parent.CreatePage("Current Slot Actions", Color.green, 0, true); obj.CreateFunction("Capture Current Loadout", Color.green, (Action)KeepInventory.SaveCurrent); obj.CreateFunction("Equip Active Slot", Color.magenta, (Action)KeepInventory.ApplyCurrent); obj.CreateFunction("Erase Active Slot", _gray, (Action)KeepInventory.ClearCurrent); } private static void BuildInventoryToggleablesPage(Page parent) { //IL_0006: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Inventory Behavior", Color.cyan, 0, true); obj.CreateBool("Persist Between Levels", Color.cyan, Settings.KeepBetweenLevels.Value, (Action)delegate(bool v) { Settings.KeepBetweenLevels.Value = v; Settings.Save(); }); obj.CreateBool("Restore at Game Launch", Color.cyan, Settings.KeepOnStartup.Value, (Action)delegate(bool v) { Settings.KeepOnStartup.Value = v; Settings.Save(); }); obj.CreateBool("Auto-Capture When Level Ends", Color.cyan, Settings.AutoSaveOnLevelEnd.Value, (Action)delegate(bool v) { Settings.AutoSaveOnLevelEnd.Value = v; Settings.Save(); }); obj.CreateBool("Discard Empty Holsters on Restore", Color.cyan, Settings.StripEmptyHolsters.Value, (Action)delegate(bool v) { Settings.StripEmptyHolsters.Value = v; Settings.Save(); }); } private static void BuildInventoryPerLevelPage(Page parent) { //IL_0006: 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_0052: 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) Page obj = parent.CreatePage("Per-Level Loadouts", _purple, 0, true); obj.CreateBool("Per-Level Loadouts Active", Color.cyan, Settings.PerLevelLoadouts.Value, (Action)delegate(bool v) { Settings.PerLevelLoadouts.Value = v; Settings.Save(); }); obj.CreateFunction("Assign Slot to Current Level", Color.green, (Action)KeepInventory.BindCurrentLevelToCurrentSlot); obj.CreateFunction("Clear All Level Assignments", _gray, (Action)KeepInventory.ClearPerLevelBindings); } private static void BuildInventorySlotsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Slots", _gold, 0, true); for (int i = 1; i <= 5; i++) { BuildSlotPage(parent2, i); } } private static void BuildSlotPage(Page parent, int slot) { //IL_0057: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) string text = $"Slot {slot}: {KeepInventory.GetSlotName(slot)}"; Page obj = parent.CreatePage(text, _gold, 0, true); obj.CreateFunction("Capture to " + KeepInventory.GetSlotName(slot), Color.green, (Action)delegate { KeepInventory.SaveTo(slot); }); obj.CreateFunction("Equip " + KeepInventory.GetSlotName(slot), Color.magenta, (Action)delegate { KeepInventory.ApplySlot(slot); }); obj.CreateFunction("Erase " + KeepInventory.GetSlotName(slot), _gray, (Action)delegate { KeepInventory.ClearSlot(slot); }); obj.CreateFunction("Set as Active Slot", Color.cyan, (Action)delegate { Settings.SelectedSlot.Value = slot; Settings.Save(); }); } private static void BuildAvatarsPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Avatars", _purple, 0, true); obj.CreateFunction("Restore Default Avatar (Ford)", Color.green, (Action)Avatars.ResetToDefault); obj.CreateFunction("Random Vanilla Avatar", _orange, (Action)Avatars.RandomVanilla); BuildAvatarPresetsPage(obj); } private static void BuildAvatarPresetsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Presets", _purple, 0, true); (string, string)[] presets = Avatars.Presets; for (int i = 0; i < presets.Length; i++) { (string, string) tuple = presets[i]; string barcode = tuple.Item2; val.CreateFunction(tuple.Item1, Color.yellow, (Action)delegate { Avatars.SwapToBarcode(barcode); }); } } private static void BuildAvatarScalePage(Page parent) { //IL_0006: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Avatar Scale", _purple, 0, true); obj.CreateFloat("Avatar Scale", Color.yellow, Settings.AvatarScale.Value, 0.1f, 0.1f, 10f, (Action)delegate(float v) { Settings.AvatarScale.Value = v; }); obj.CreateFunction("Apply Scale", Color.green, (Action)AvatarScaling.Apply); obj.CreateFunction("Restore Default Scale", _gray, (Action)AvatarScaling.Reset); } private static void BuildMovementPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Movement", _orange, 0, true); BuildMovementAirPage(obj); BuildMovementTeleportPage(obj); obj.CreateFunction("Halt Momentum", Color.cyan, (Action)Movement.StopVelocity); obj.CreateFunction("Restore Defaults", _gray, (Action)ResetMovementDefaults); } private static void BuildMovementAirPage(Page parent) { //IL_0006: 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_0060: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Air & Jump", Color.cyan, 0, true); obj.CreateFloat("Jump Height Multiplier", Color.yellow, Settings.JumpMultiplier.Value, 0.1f, 0.1f, 5f, (Action)delegate(float v) { Settings.JumpMultiplier.Value = v; }); obj.CreateFunction("Instant Respawn", Color.red, (Action)Movement.QuickRespawn); } private static void BuildMovementTeleportPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Teleport & Markers", _orange, 0, true); obj.CreateFunction("Teleport to Aim Point", Color.green, (Action)Movement.TeleportToReticle); obj.CreateFunction("Drop Position Marker", Color.green, (Action)Movement.SavePositionMarker); obj.CreateFunction("Return to Marker", Color.magenta, (Action)Movement.TeleportToMarker); obj.CreateFunction("Remove Marker", _gray, (Action)Movement.ClearMarker); BuildMarkerSlotsPage(obj); } private static void BuildMarkerSlotsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Position Markers A/B/C", _orange, 0, true); for (int i = 0; i < 3; i++) { int slot = i; char value = (char)(65 + i); Page obj = val.CreatePage($"Marker {value}", _orange, 0, true); obj.CreateFunction("Capture Position", Color.green, (Action)delegate { Movement.SaveMarkerSlot(slot); }); obj.CreateFunction("Travel to Marker", Color.magenta, (Action)delegate { Movement.TeleportMarkerSlot(slot); }); obj.CreateFunction("Remove Marker", _gray, (Action)delegate { Movement.ClearMarkerSlot(slot); }); } } private static void BuildCombatWorldPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Combat & World", Color.red, 0, true); BuildCombatSubPage(parent2); BuildWorldSubPage(parent2); BuildNpcToolsPage(parent2); BuildCombatQuickFixPage(parent2); BuildTimeScalePage(parent2); } private static void BuildTimeScalePage(Page parent) { //IL_0006: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Time Scale", _purple, 0, true); obj.CreateBool("Apply Time Scale", Color.cyan, Settings.TimeScaleActive.Value, (Action)delegate(bool v) { Settings.TimeScaleActive.Value = v; Settings.Save(); }); obj.CreateFloat("Time Scale", Color.yellow, Settings.TimeScale.Value, 0.05f, 0.05f, 3f, (Action)delegate(float v) { Settings.TimeScale.Value = v; Settings.Save(); }); BuildTimeScalePresetsPage(obj); obj.CreateFloat("Slow-Mo Toggle Factor", Color.yellow, Settings.SlowMoFactor.Value, 0.05f, 0.05f, 1f, (Action)delegate(float v) { Settings.SlowMoFactor.Value = v; Settings.Save(); }); obj.CreateFunction("Toggle Slow-Mo", _purple, (Action)TimeScale.ToggleSlowMo); obj.CreateFunction("Restore (1.00x)", _gray, (Action)TimeScale.Restore); } private static void BuildTimeScalePresetsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Presets", _orange, 0, true); (string, float)[] presets = TimeScale.Presets; for (int i = 0; i < presets.Length; i++) { (string, float) tuple = presets[i]; float f = tuple.Item2; val.CreateFunction(tuple.Item1, Color.yellow, (Action)delegate { TimeScale.SetFactor(f); }); } } private static void BuildCombatSubPage(Page parent) { //IL_0006: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Combat", Color.red, 0, true); obj.CreateFloat("Outgoing Damage Multiplier", Color.yellow, Settings.DamageMultiplier.Value, 0.5f, 0f, 20f, (Action)delegate(float v) { Settings.DamageMultiplier.Value = v; }); obj.CreateBool("One-Hit Eliminate", Color.yellow, Settings.OneHitKill.Value, (Action)delegate(bool v) { Settings.OneHitKill.Value = v; }); obj.CreateBool("Auto-Heal", Color.cyan, Settings.AutoHeal.Value, (Action)delegate(bool v) { Settings.AutoHeal.Value = v; }); obj.CreateFloat("Auto-Heal Threshold", Color.cyan, Settings.AutoHealThreshold.Value, 0.05f, 0.05f, 1f, (Action)delegate(float v) { Settings.AutoHealThreshold.Value = v; }); obj.CreateBool("Unlimited Ammo Reserves", Color.cyan, Settings.InfiniteAmmo.Value, (Action)delegate(bool v) { Settings.InfiniteAmmo.Value = v; }); obj.CreateFloat("Incoming Damage Resistance", Color.cyan, Settings.DamageResistance.Value, 0.1f, 0f, 1f, (Action)delegate(float v) { Settings.DamageResistance.Value = v; }); } private static void BuildWorldSubPage(Page parent) { //IL_0006: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) Page obj = parent.CreatePage("World Physics", _purple, 0, true); obj.CreateFloat("Vertical Gravity", Color.yellow, Settings.GravityY.Value, 0.5f, -30f, 20f, (Action)delegate(float v) { Settings.GravityY.Value = v; }); obj.CreateFloat("Ragdoll Force Multiplier", Color.yellow, Settings.RagdollForceMul.Value, 0.5f, 0.1f, 10f, (Action)delegate(float v) { Settings.RagdollForceMul.Value = v; }); obj.CreateFloat("NPC Size Scale", Color.yellow, Settings.NpcScale.Value, 0.1f, 0.1f, 10f, (Action)delegate(float v) { Settings.NpcScale.Value = v; }); obj.CreateFloat("Explosion & Knockback Force", Color.yellow, Settings.ExplosionForceMul.Value, 0.5f, 0.1f, 20f, (Action)delegate(float v) { Settings.ExplosionForceMul.Value = v; }); } private static void BuildNpcToolsPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("NPC Tools", _orange, 0, true); obj.CreateFunction("Detonate at Aim Point", Color.red, (Action)World.ExplodeAtReticle); obj.CreateFunction("Repel All NPCs", _orange, (Action)World.PushAllNpcsAway); obj.CreateFunction("Summon All NPCs", _orange, (Action)World.PullAllNpcsToMe); obj.CreateFunction("Remove Nearest NPC", Color.red, (Action)Helpers.DespawnNearestNpc); obj.CreateFunction("Eliminate NPCs (30m)", Color.red, (Action)delegate { Helpers.KillAllNpcsInRange(); }); obj.CreateFunction("Remove NPCs (30m)", Color.red, (Action)delegate { Helpers.DespawnAllNpcsInRange(); }); } private static void BuildCombatQuickFixPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Quick Fix-Ups", Color.green, 0, true); obj.CreateFunction("Restore Full Health", Color.green, (Action)Combat.TopUpHealth); obj.CreateFunction("Refill All Ammo Reserves", Color.green, (Action)Combat.TopUpAmmoOnce); obj.CreateFunction("Instantly Reload Held", Color.green, (Action)Combat.MagicReload); obj.CreateFunction("Deplete Ammo Reserves", _gray, (Action)Combat.ClearAmmo); obj.CreateFunction("Pull Aimed Object to Hand", Color.cyan, (Action)Helpers.PullObjectToHand); obj.CreateFunction("Restore Combat Defaults", _gray, (Action)ResetCombatWorldDefaults); } private static void BuildSpawnItemsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Spawn & Items", _gold, 0, true); BuildQuickSpawnPage(parent2); BuildSpawnPresetsPage(parent2); BuildSpawnRecentPage(parent2); BuildTemplatesWarehousePage(parent2); BuildObjectScalePage(parent2); BuildClearItemsPage(parent2); } private static void BuildClearItemsPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Clear Items", Color.red, 0, true); obj.CreateFunction("Clear All Items", Color.red, (Action)ClearItems.ClearAll); obj.CreateFunction("Clear All Guns", _orange, (Action)ClearItems.ClearGuns); obj.CreateFunction("Clear All Melees", _orange, (Action)ClearItems.ClearMelees); obj.CreateFunction("Clear All NPCs", Color.yellow, (Action)ClearItems.ClearNpcs); obj.CreateFunction("Clear All Props", _gold, (Action)ClearItems.ClearProps); obj.CreateFunction(" - host only in Fusion lobbies", _gray, (Action)delegate { }); } private static void BuildQuickSpawnPage(Page parent) { //IL_0006: 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_0044: 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) Page obj = parent.CreatePage("Quick Spawn", Color.green, 0, true); obj.CreateFunction("Respawn Last Held Item", Color.green, (Action)Spawning.SpawnLastHeld); obj.CreateFunction("Random Vanilla Preset", _orange, (Action)WarehouseTools.SpawnRandomPreset); obj.CreateFunction("Random Item from Warehouse", _orange, (Action)WarehouseTools.SpawnRandomFromWarehouse); } private static void BuildTemplatesWarehousePage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Templates & Warehouse", _teal, 0, true); BuildTemplatesPage(parent2); BuildWarehousePage(parent2); } private static void BuildWarehousePage(Page parent) { //IL_0006: 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_0044: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Warehouse Tools", _teal, 0, true); obj.CreateFunction("Scan Warehouse Counts", Color.cyan, (Action)WarehouseTools.ScanCountsToLog); obj.CreateFunction("Print First 200 Barcodes", Color.cyan, (Action)delegate { WarehouseTools.PrintAllSpawnableBarcodes(); }); obj.CreateFunction("Print First 1000 Barcodes", Color.cyan, (Action)delegate { WarehouseTools.PrintAllSpawnableBarcodes(1000); }); obj.CreateFunction("Random Vanilla Preset", _orange, (Action)WarehouseTools.SpawnRandomPreset); obj.CreateFunction("Random Item from Warehouse", _orange, (Action)WarehouseTools.SpawnRandomFromWarehouse); } private static void BuildTemplatesPage(Page parent) { //IL_0006: 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) Page val = parent.CreatePage("Loadout Templates", _orange, 0, true); Templates.Template[] all = Templates.All; foreach (Templates.Template template in all) { Templates.Template template2 = template; val.CreateFunction(template2.Name, Color.yellow, (Action)delegate { Templates.Drop(template2); }); } } private static void BuildSpawnPresetsPage(Page parent) { //IL_0006: 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_004f: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Presets", _orange, 0, true); BuildPresetCategoryPage(parent2, "Weapons", _blue, new string[4] { "HandgunEder22training", "RifleM1Garand", "RifleMK18HoloForegrip", "MeleeIceAxe" }); BuildPresetCategoryPage(parent2, "Combatants", Color.red, new string[4] { "NPCCultist", "NPCSecurityGuard", "BulletBanker", "ApolloGiant" }); BuildPresetCategoryPage(parent2, "Peasants", Color.yellow, new string[7] { "NPCPeasantMaleL", "NPCPeasantMaleM", "NPCPeasantMaleS", "NPCPeasantFemL", "NPCPeasantFemM", "NPCPeasantFemS", "NPCPeasantNull" }); BuildPresetCategoryPage(parent2, "Apollo & Avatars", _purple, new string[3] { "ApolloGold", "BlueApollo", "ApolloGiant" }); BuildPresetCategoryPage(parent2, "Throwables", _gold, new string[6] { "BowlingBall", "BowlingPin", "WeightedCube", "BottleMelon", "BottlePill", "SodaCanB" }); BuildPresetCategoryPage(parent2, "Misc Props", _teal, new string[9] { "DonutBox", "PropHealthPickup", "CombatCrate", "ElectricGuitar", "DestructibleBarrel", "SkeletonSkull", "TargetSnake", "TargetBat", "BoxTurret" }); } private static void BuildPresetCategoryPage(Page parent, string title, Color tint, string[] shortNames) { //IL_0002: 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) Page val = parent.CreatePage(title, tint, 0, true); for (int i = 0; i < shortNames.Length; i++) { (string, string)? tuple = FindPreset(shortNames[i]); if (tuple.HasValue) { string item = tuple.Value.Item1; string barcode = tuple.Value.Item2; val.CreateFunction(item, Color.yellow, (Action)delegate { Spawning.SpawnAtReticle(barcode); }); } } } private static (string Name, string Barcode)? FindPreset(string shortName) { string value = "." + shortName; for (int i = 0; i < Spawning.Presets.Length; i++) { (string, string) value2 = Spawning.Presets[i]; if (value2.Item2 != null && value2.Item2.EndsWith(value, StringComparison.Ordinal)) { return value2; } } return null; } private static void BuildSpawnRecentPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) Page obj = (_spawnRecentPage = parent.CreatePage("Recent Spawns", _gold, 0, true)); obj.CreateFunction("Refresh List", Color.green, (Action)RefreshRecentSpawns); obj.CreateFunction("Clear History", _gray, (Action)Spawning.ClearRecent); } private static void RefreshRecentSpawns() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_00e0: Unknown result type (might be due to invalid IL or missing references) Page spawnRecentPage = _spawnRecentPage; if (spawnRecentPage == null) { return; } try { spawnRecentPage.RemoveAll(); } catch { return; } spawnRecentPage.CreateFunction("Refresh List", Color.green, (Action)RefreshRecentSpawns); spawnRecentPage.CreateFunction("Clear History", _gray, (Action)Spawning.ClearRecent); IReadOnlyList recentList = Spawning.RecentList; if (recentList.Count == 0) { spawnRecentPage.CreateFunction("(no recent spawns)", _gray, (Action)delegate { }); return; } foreach (string item in recentList) { string bc = item; string text = ShortBarcode(bc); spawnRecentPage.CreateFunction(text, Color.yellow, (Action)delegate { Spawning.SpawnAtReticle(bc); }); } } private static string ShortBarcode(string barcode) { if (string.IsNullOrEmpty(barcode)) { return "?"; } int num = barcode.LastIndexOf('.'); if (num <= 0 || num >= barcode.Length - 1) { return barcode; } return barcode.Substring(num + 1); } private static void BuildObjectScalePage(Page parent) { //IL_0006: 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_0061: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Object Scale", _purple, 0, true); obj.CreateFloat("Object Scale Factor", Color.yellow, Settings.ObjectScale.Value, 0.1f, 0.1f, 10f, (Action)delegate(float v) { Settings.ObjectScale.Value = v; }); obj.CreateBool("Scale Objects on Pickup", Color.cyan, Settings.ScaleOnPickup.Value, (Action)delegate(bool v) { Settings.ScaleOnPickup.Value = v; }); BuildScaleHeldPage(obj); BuildScaleFreezePage(obj); BuildScaleMemoryPage(obj); } private static void BuildScaleHeldPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Scale Held Object", Color.green, 0, true); obj.CreateFunction("Scale Left-Hand Object", Color.green, (Action)ObjectScaling.ScaleLeft); obj.CreateFunction("Scale Right-Hand Object", Color.green, (Action)ObjectScaling.ScaleRight); obj.CreateFunction("Scale Both Held Objects", Color.green, (Action)ObjectScaling.ScaleBoth); obj.CreateFunction("Restore Held Size", _gray, (Action)ObjectScaling.ResetHeld); } private static void BuildScaleFreezePage(Page parent) { //IL_0006: 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_0043: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Freeze / Unfreeze", Color.cyan, 0, true); obj.CreateFunction("Freeze Held Object", Color.cyan, (Action)ObjectScaling.FreezeHeld); obj.CreateFunction("Unfreeze All Objects", _gray, (Action)ObjectScaling.UnfreezeAll); } private static void BuildScaleMemoryPage(Page parent) { //IL_0006: 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_0051: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Remembered Scales", _purple, 0, true); obj.CreateBool("Remember Scales This Session", Color.cyan, Settings.RememberBarcodeScales.Value, (Action)delegate(bool v) { Settings.RememberBarcodeScales.Value = v; Settings.Save(); }); obj.CreateFunction("Forget Remembered Scales", _gray, (Action)ObjectScaling.ClearAllBarcodeScales); } private static void BuildFusionPage(Page parent) { //IL_0006: 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) Page obj = parent.CreatePage("Fusion", _blue, 0, true); obj.CreateFunction("Refresh Fusion Status", Color.cyan, (Action)RefreshFusionStatusHeader); BuildFusionQuickActionsPage(obj); BuildFusionLobbyInfoPage(obj); BuildFusionPlayersPage(obj); BuildFusionHostAndModesPage(obj); BuildFusionMultiplayerToolsPage(obj); } private static void BuildFusionQuickActionsPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Quick Actions", Color.green, 0, true); obj.CreateFunction("Travel to Host", Color.green, (Action)Fusion.TeleportToHost); obj.CreateFunction("Summon All Players (Host)", Color.green, (Action)Fusion.TeleportAllToMe); obj.CreateFunction("Duplicate Left-Hand Object", _orange, (Action)Fusion.CloneHeldLeft); obj.CreateFunction("Duplicate Right-Hand Object", _orange, (Action)Fusion.CloneHeldRight); } private static void BuildFusionLobbyInfoPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _fusionInfoPage = parent.CreatePage("Lobby Info", _teal, 0, true); RebuildFusionLobbyInfoPage(); } private static void RebuildFusionLobbyInfoPage() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) Page fusionInfoPage = _fusionInfoPage; if (fusionInfoPage != null) { try { fusionInfoPage.RemoveAll(); } catch { return; } fusionInfoPage.CreateFunction("Refresh", Color.green, (Action)RebuildFusionLobbyInfoPage); if (!Fusion.HasServer) { fusionInfoPage.CreateFunction("(offline — not currently in a lobby)", _gray, (Action)delegate { }); return; } BuildFusionLobbyInfoDetailsSub(fusionInfoPage); BuildFusionLobbyInfoLoggingSub(fusionInfoPage); } } private static void BuildFusionLobbyInfoDetailsSub(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Details", _teal, 0, true); obj.CreateFunction("Status : " + Fusion.LobbySummary(), _gray, (Action)delegate { }); obj.CreateFunction("Name : " + Trunc(Fusion.LobbyName(), 40), _gray, (Action)delegate { }); obj.CreateFunction("Host : " + Trunc(Fusion.LobbyHostName(), 40), _gray, (Action)delegate { }); obj.CreateFunction("Code : " + Trunc(Fusion.LobbyCode(), 40), _gray, (Action)delegate { }); obj.CreateFunction("Level : " + Trunc(Fusion.LevelTitle(), 40), _gray, (Action)delegate { }); obj.CreateFunction($"Players : {Fusion.PlayerCount} / {Fusion.MaxPlayers()} Privacy: {Fusion.PrivacyString()}", _gray, (Action)delegate { }); } private static void BuildFusionLobbyInfoLoggingSub(Page parent) { //IL_0006: 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_0043: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Print to Log", Color.cyan, 0, true); obj.CreateFunction("Print Full Lobby Info", Color.cyan, (Action)Fusion.PrintFullLobbyInfo); obj.CreateFunction("Print Lobby Settings", Color.cyan, (Action)Fusion.PrintLobbySettings); } private static string Trunc(string s, int max) { if (string.IsNullOrEmpty(s)) { return "(none)"; } if (s.Length > max) { return s.Substring(0, max - 1) + "…"; } return s; } private static void RefreshFusionStatusHeader() { Notifications.Info("Fusion: " + Fusion.LobbySummary()); RebuildFusionLobbyInfoPage(); } private static void BuildFusionHostAndModesPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Host Settings", Color.yellow, 0, true); BuildFusionHostTogglesPage(parent2); BuildFusionHostCyclesPage(parent2); BuildFusionHostPresetsPage(parent2); } private static void BuildFusionHostTogglesPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Host Toggles", Color.yellow, 0, true); obj.CreateFunction("Toggle Name Tags", Color.yellow, (Action)Fusion.ToggleNameTags); obj.CreateFunction("Toggle Player Mortality", Color.yellow, (Action)Fusion.ToggleMortality); obj.CreateFunction("Toggle Friendly Fire", Color.yellow, (Action)Fusion.ToggleFriendlyFire); obj.CreateFunction("Toggle Knockout", Color.yellow, (Action)Fusion.ToggleKnockout); obj.CreateFunction("Toggle Player Constraining", Color.yellow, (Action)Fusion.TogglePlayerConstraining); } private static void BuildFusionHostCyclesPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Host Cycles", _orange, 0, true); obj.CreateFunction("Cycle Player Capacity", _orange, (Action)Fusion.CycleMaxPlayers); obj.CreateFunction("Cycle Privacy Setting", _orange, (Action)Fusion.CyclePrivacy); obj.CreateFunction("Cycle Teleport Permissions", _orange, (Action)Fusion.CycleTeleportationPermission); obj.CreateFunction("Cycle Kick Permissions", _orange, (Action)Fusion.CycleKickingPermission); obj.CreateFunction("Cycle Dev Tools Permissions", _orange, (Action)Fusion.CycleDevToolsPermission); } private static void BuildFusionHostPresetsPage(Page parent) { //IL_0006: 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_0044: 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) Page obj = parent.CreatePage("Lobby Presets", _purple, 0, true); obj.CreateFunction("Vanilla Defaults", Color.green, (Action)Fusion.ResetLobbyDefaults); obj.CreateFunction("Sandbox Configuration", Color.cyan, (Action)Fusion.ResetLobbySandboxFriendly); obj.CreateFunction("PvP — Friendly Fire + Mortality", Color.red, (Action)Fusion.ResetLobbyPvP); } private static void BuildFusionMultiplayerToolsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Multiplayer Tools", _orange, 0, true); BuildFusionTeleportPage(parent2); BuildFusionServerBrowserPage(parent2); BuildFusionLoadoutSyncPage(parent2); } private static void BuildFusionTeleportPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Teleport Tools", _orange, 0, true); obj.CreateFunction("Travel to Host", Color.green, (Action)Fusion.TeleportToHost); obj.CreateFunction("Travel to Next Player", Color.green, (Action)Fusion.TeleportToNextPlayer); obj.CreateFunction("Travel to Previous Player", Color.green, (Action)Fusion.TeleportToPreviousPlayer); obj.CreateFunction("Summon All Players (Host)", _orange, (Action)Fusion.TeleportAllToMe); } private static void BuildFusionServerBrowserPage(Page parent) { //IL_0006: 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_0048: 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) Page obj = parent.CreatePage("Server Browser", _gold, 0, true); obj.CreateFunction("Save Current as Favorite", Color.green, (Action)delegate { ServerBrowser.SaveCurrentTo(Mathf.Clamp(Settings.SelectedSlot.Value - 1, 0, 4)); }); obj.CreateFunction("Rejoin Previous Lobby", Color.green, (Action)ServerBrowser.RejoinLast); obj.CreateFunction("Print Favorites to Log", Color.cyan, (Action)ServerBrowser.PrintFavoritesToLog); BuildFusionFavoritesSlotsPage(obj); } private static void BuildFusionFavoritesSlotsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Favorites Slots", _gold, 0, true); for (int i = 0; i < 5; i++) { int slot = i; string value = Settings.FavoriteName[slot].Value ?? $"Favorite {slot + 1}"; bool flag = string.IsNullOrEmpty(Settings.FavoriteCode[slot].Value); Page obj = val.CreatePage($"Favorite {slot + 1}: {value}{(flag ? " (unassigned)" : "")}", _gold, 0, true); obj.CreateFunction("Join This Lobby", Color.green, (Action)delegate { ServerBrowser.JoinSlot(slot); }); obj.CreateFunction("Assign Current Lobby Here", Color.cyan, (Action)delegate { ServerBrowser.SaveCurrentTo(slot); }); obj.CreateFunction("Clear Slot", _gray, (Action)delegate { ServerBrowser.ClearSlot(slot); }); } } private static void BuildFusionLoadoutSyncPage(Page parent) { //IL_0006: 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) Page obj = parent.CreatePage("Loadout Sync", _orange, 0, true); obj.CreateFunction("Open Loadout Folder", Color.cyan, (Action)LoadoutSync.OpenFolder); BuildFusionLoadoutSyncSlotsPage(obj); } private static void BuildFusionLoadoutSyncSlotsPage(Page parent) { //IL_0006: 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_0081: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Slots", _orange, 0, true); for (int i = 1; i <= 5; i++) { int slot = i; Page obj = val.CreatePage($"Slot {slot}: {KeepInventory.GetSlotName(slot)}", _orange, 0, true); obj.CreateFunction("Copy to Clipboard", Color.green, (Action)delegate { LoadoutSync.ExportToClipboard(slot); }); obj.CreateFunction("Export to File", Color.green, (Action)delegate { LoadoutSync.ExportToFile(slot); }); obj.CreateFunction("Paste from Clipboard", Color.magenta, (Action)delegate { LoadoutSync.ImportFromClipboard(slot); }); obj.CreateFunction("Import from File", Color.magenta, (Action)delegate { LoadoutSync.ImportFromFile(slot); }); obj.CreateFunction("Announce Shared Loadout", _gold, (Action)delegate { LoadoutSync.AnnounceExport(slot); }); } } private static void BuildFusionPlayersPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) (_fusionPlayersPage = parent.CreatePage("Players", _blue, 0, true)).CreateFunction("Refresh Player List", Color.green, (Action)RefreshFusionPlayers); } private static void RefreshFusionPlayers() { //IL_0039: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) Page fusionPlayersPage = _fusionPlayersPage; if (fusionPlayersPage == null) { return; } try { fusionPlayersPage.RemoveAll(); } catch (Exception ex) { ModMain.Log.Warning("Player list rebuild failed: " + ex.Message); return; } fusionPlayersPage.CreateFunction("Refresh Player List", Color.green, (Action)RefreshFusionPlayers); if (!Fusion.HasServer) { fusionPlayersPage.CreateFunction("Not currently in a lobby.", _gray, (Action)delegate { }); return; } List players = Fusion.GetPlayers(); if (players.Count == 0) { fusionPlayersPage.CreateFunction("(no players detected)", _gray, (Action)delegate { }); return; } foreach (Fusion.PlayerEntry item in players) { string text = Fusion.FormatPlayerLabel(item); byte smallID = item.SmallID; bool isLocal = item.IsLocal; Page parent = fusionPlayersPage.CreatePage(text, _blue, 0, true); BuildOnePlayerInfoPage(parent, item, smallID, isLocal); if (!isLocal) { BuildOnePlayerActionsPage(parent, smallID); } } ModMain.Log.Msg($"Players refreshed: {players.Count}."); } private static void BuildOnePlayerInfoPage(Page parent, Fusion.PlayerEntry p, byte sid, bool isLocal) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Info", _gray, 0, true); val.CreateFunction("Username: " + p.Username, _gray, (Action)delegate { }); if (!string.IsNullOrEmpty(p.Nickname)) { val.CreateFunction("Nickname: " + p.Nickname, _gray, (Action)delegate { }); } val.CreateFunction($"Player ID: {sid}", _gray, (Action)delegate { }); if (p.IsHost) { val.CreateFunction("Role: Host", _gold, (Action)delegate { }); } if (isLocal) { val.CreateFunction("Role: You", _teal, (Action)delegate { }); } } private static void BuildOnePlayerActionsPage(Page parent, byte sid) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Actions", Color.green, 0, true); obj.CreateFunction("Travel to Player", Color.green, (Action)delegate { Fusion.TeleportToPlayer(sid); }); obj.CreateFunction("Summon Player (Host)", _orange, (Action)delegate { Fusion.BringPlayer(sid); }); } private static void BuildDirectorMorePage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Director & More", _purple, 0, true); BuildCinematicsPage(parent2); BuildHudPage(parent2); BuildHotkeysPage(parent2); BuildProfilesAndAboutPage(parent2); } private static void BuildCinematicsPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Cinematics", _purple, 0, true); BuildFreecamPage(parent2); BuildCinematicPhotoPage(parent2); } private static void BuildFreecamPage(Page parent) { //IL_0006: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Freecam", _blue, 0, true); obj.CreateBool("Freecam Active", Color.cyan, Settings.FreecamEnabled.Value, (Action)delegate(bool v) { if (v) { Freecam.Start(); } else { Freecam.Stop(); } }); obj.CreateFloat("Camera Speed (m/s)", Color.yellow, Settings.FreecamSpeed.Value, 0.5f, 0.5f, 25f, (Action)delegate(float v) { Settings.FreecamSpeed.Value = v; Settings.Save(); }); obj.CreateFunction("Toggle Freecam", Color.green, (Action)Freecam.Toggle); obj.CreateFunction(" - R-stick: translate, L-stick: rotate", _gray, (Action)delegate { }); obj.CreateFunction(" - A: ascend, B: descend", _gray, (Action)delegate { }); } private static void BuildCinematicPhotoPage(Page parent) { //IL_0006: 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_0044: 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_00a4: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Cinematic Photo", _teal, 0, true); obj.CreateFunction("Capture Now", Color.green, (Action)Photo.TakeScreenshot); obj.CreateFunction("Capture After Countdown", Color.cyan, (Action)delegate { Photo.StartCountdown(Settings.PhotoCountdownSecs.Value); }); obj.CreateFunction("Burst Capture", _orange, (Action)delegate { Photo.StartBurst(Settings.PhotoBurstCount.Value); }); obj.CreateFunction("Open Screenshot Folder", Color.cyan, (Action)Photo.OpenPhotoFolder); BuildCinematicPhotoOptionsPage(obj); } private static void BuildCinematicPhotoOptionsPage(Page parent) { //IL_0006: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Options", Color.cyan, 0, true); obj.CreateBool("Capture at 2x Resolution", Color.cyan, Settings.PhotoSupersize.Value, (Action)delegate(bool v) { Settings.PhotoSupersize.Value = v; Settings.Save(); }); obj.CreateBool("Hide HUD During Countdown", Color.cyan, Settings.PhotoHideHud.Value, (Action)delegate(bool v) { Settings.PhotoHideHud.Value = v; Settings.Save(); }); obj.CreateInt("Countdown Duration (s)", Color.yellow, Settings.PhotoCountdownSecs.Value, 1, 1, 10, (Action)delegate(int v) { Settings.PhotoCountdownSecs.Value = v; Settings.Save(); }); obj.CreateInt("Burst Image Count", Color.yellow, Settings.PhotoBurstCount.Value, 1, 2, 12, (Action)delegate(int v) { Settings.PhotoBurstCount.Value = v; Settings.Save(); }); } private static void BuildHudPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("HUD", _teal, 0, true); BuildHudOverlaysPage(obj); obj.CreateBool("In-VR Wrist HUD", Color.cyan, Settings.WristHudEnabled.Value, (Action)delegate(bool v) { Settings.WristHudEnabled.Value = v; Settings.Save(); }); BuildHudStatsPage(obj); obj.CreateFunction("Restore HUD Defaults", _gray, (Action)ResetHudDefaults); } private static void BuildHudOverlaysPage(Page parent) { //IL_0006: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Overlays", Color.cyan, 0, true); obj.CreateBool("Performance Stats Overlay", Color.cyan, Settings.StatsOverlay.Value, (Action)delegate(bool v) { Settings.StatsOverlay.Value = v; Settings.Save(); }); obj.CreateBool("Display Lobby Info Banner", Color.cyan, Settings.ShowLobbyInfo.Value, (Action)delegate(bool v) { Settings.ShowLobbyInfo.Value = v; Settings.Save(); }); obj.CreateBool("On-Screen Crosshair", Color.cyan, Settings.Crosshair.Value, (Action)delegate(bool v) { Settings.Crosshair.Value = v; Settings.Save(); }); } private static void BuildHudStatsPage(Page parent) { //IL_0006: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Session Stats", _gray, 0, true); obj.CreateFunction("Print Stats to Log", Color.cyan, (Action)PrintStatsToLog); obj.CreateFunction("Clear Session Stats", _gray, (Action)Stats.Reset); obj.CreateFunction(" - " + Stats.FormatCombatSummary(), _gray, (Action)delegate { }); obj.CreateFunction(" - " + Stats.FormatSummary(), _gray, (Action)delegate { }); } private static void PrintStatsToLog() { ModMain.Log.Msg("---- Quality Of Lab stats ----"); ModMain.Log.Msg(" " + Stats.FormatSummary()); ModMain.Log.Msg(" " + Stats.FormatCombatSummary()); } private static void BuildHotkeysPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Hotkeys", _orange, 0, true); for (int i = 0; i < 4; i++) { BuildOneHotkeyPage(val, i); } val.CreateFunction("Clear All Hotkey Bindings", _gray, (Action)ResetHotkeys); val.CreateFunction("Print Hotkey Reference", Color.yellow, (Action)PrintHotkeyReference); } private static void BuildOneHotkeyPage(Page parent, int slotIdx) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) int value = slotIdx + 1; int value2 = Settings.HotkeyTrigger[slotIdx].Value; int value3 = Settings.HotkeyAction[slotIdx].Value; string text = $"Hotkey {value}: {Hotkeys.TriggerName(value2)} -> {Hotkeys.ActionName(value3)}"; Page obj = parent.CreatePage(text, _orange, 0, true); int idx = slotIdx; HotkeyTriggerKind value4 = (HotkeyTriggerKind)Settings.HotkeyTrigger[idx].Value; HotkeyActionKind value5 = (HotkeyActionKind)Settings.HotkeyAction[idx].Value; obj.CreateEnum("Trigger", Color.cyan, (Enum)value4, (Action)delegate(Enum v) { Settings.HotkeyTrigger[idx].Value = (int)(HotkeyTriggerKind)(object)v; Settings.Save(); }); obj.CreateEnum("Action", Color.cyan, (Enum)value5, (Action)delegate(Enum v) { Settings.HotkeyAction[idx].Value = (int)(HotkeyActionKind)(object)v; Settings.Save(); }); obj.CreateFunction("Clear This Binding", _gray, (Action)delegate { Settings.HotkeyTrigger[idx].Value = 0; Settings.HotkeyAction[idx].Value = 0; Settings.Save(); }); } private static void PrintHotkeyReference() { ModMain.Log.Msg("--- Hotkey Triggers ---"); for (int i = 0; i < 5; i++) { ModMain.Log.Msg($" {i} = {Hotkeys.TriggerName(i)}"); } ModMain.Log.Msg("--- Hotkey Actions ---"); for (int j = 0; j < 58; j++) { ModMain.Log.Msg($" {j} = {Hotkeys.ActionName(j)}"); } } private static void BuildProfilesAndAboutPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Page parent2 = parent.CreatePage("Profiles & About", _gray, 0, true); BuildProfilesPage(parent2); BuildAboutPage(parent2); BuildEmergencyPage(parent2); } private static void BuildProfilesPage(Page parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) Page val = parent.CreatePage("Profiles", _blue, 0, true); for (int i = 1; i <= 3; i++) { int slot = i; string text = $"Profile {slot}: {Profiles.GetName(slot)}{(Profiles.HasData(slot) ? "" : " (unassigned)")}"; Page obj = val.CreatePage(text, _blue, 0, true); obj.CreateFunction("Save Current Settings to Profile", Color.green, (Action)delegate { Profiles.SaveTo(slot); }); obj.CreateFunction("Load Profile", Color.magenta, (Action)delegate { Profiles.LoadFrom(slot); }); obj.CreateFunction("Erase Profile", _gray, (Action)delegate { Profiles.Clear(slot); }); } } private static void BuildAboutPage(Page parent) { //IL_0006: 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_0048: 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) Page obj = parent.CreatePage("About", _teal, 0, true); obj.CreateFunction("Quality Of Lab v2.0.1", Color.white, (Action)delegate { }); obj.CreateFunction("by Dynamic Team", _gray, (Action)delegate { }); BuildAboutFeaturesPage(obj); BuildAboutLogToolsPage(obj); obj.CreateFunction("Print Version Info to Log", Color.green, (Action)PrintAbout); } private static void BuildAboutFeaturesPage(Page parent) { //IL_0006: 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_004e: 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_00ad: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Features", _teal, 0, true); obj.CreateFunction(" - Player suite + 5-slot Keep Inventory", _gray, (Action)delegate { }); BuildAboutFeaturesMorePage(obj); obj.CreateFunction(" - Spawn presets + Templates + Warehouse", _gray, (Action)delegate { }); obj.CreateFunction(" - Fusion: lobby + browser + loadout sync", _gray, (Action)delegate { }); obj.CreateFunction(" - Director: Freecam + Photo", _gray, (Action)delegate { }); } private static void BuildAboutFeaturesMorePage(Page parent) { //IL_0006: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("More Features", _teal, 0, true); obj.CreateFunction(" - Time Scale + Checkpoints", _gray, (Action)delegate { }); obj.CreateFunction(" - Categorised spawn presets + combat stats", _gray, (Action)delegate { }); obj.CreateFunction(" - Movement: jump / teleport / markers", _gray, (Action)delegate { }); obj.CreateFunction(" - Combat + World physics, NPC tools", _gray, (Action)delegate { }); } private static void BuildAboutLogToolsPage(Page parent) { //IL_0006: 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_0044: 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) Page obj = parent.CreatePage("Log Tools", Color.cyan, 0, true); obj.CreateFunction("Print Settings Snapshot to Log", Color.cyan, (Action)Helpers.PrintSettingsSnapshot); obj.CreateFunction("Print Recent Activity to Log", Color.cyan, (Action)Notifications.PrintRecentToLog); obj.CreateFunction("Clear Activity Log", _gray, (Action)Notifications.Clear); } private static void BuildEmergencyPage(Page parent) { //IL_0006: 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_0044: 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) Page obj = parent.CreatePage("Emergency Stop / Reset", Color.red, 0, true); obj.CreateFunction("Emergency Stop — Disable All Effects", Color.red, (Action)Helpers.PanicResetAll); obj.CreateFunction("Restore All Toggles to Default", _gray, (Action)ResetAll); obj.CreateFunction("Clear All Hotkey Bindings", _gray, (Action)ResetHotkeys); } private static void PrintAbout() { ModMain.Log.Msg("==== Quality Of Lab v2.0.1 ===="); ModMain.Log.Msg("by Dynamic Team"); ModMain.Log.Msg("Root pages (7): Quick Actions / Player / Movement / Combat & World / Spawn & Items / Fusion / Director & More"); ModMain.Log.Msg($"Loadout slots: {5}"); ModMain.Log.Msg($"Checkpoint slots: {5}"); ModMain.Log.Msg($"Hotkey slots: {4}"); ModMain.Log.Msg($"Hotkey actions: {58}"); ModMain.Log.Msg("Time scale: " + TimeScale.Status()); ModMain.Log.Msg("Fusion lobby: " + Fusion.LobbySummary()); } private static void ResetCombatWorldDefaults() { Settings.DamageMultiplier.Value = 1f; Settings.OneHitKill.Value = false; Settings.AutoHeal.Value = false; Settings.AutoHealThreshold.Value = 0.5f; Settings.InfiniteAmmo.Value = false; Settings.DamageResistance.Value = 0f; Settings.GravityY.Value = -9.81f; Settings.RagdollForceMul.Value = 1f; Settings.NpcScale.Value = 1f; Settings.ExplosionForceMul.Value = 1f; Settings.Save(); ModMain.Log.Msg("Quality Of Lab: combat & world defaults restored."); } private static void ResetMovementDefaults() { Settings.JumpMultiplier.Value = 1f; Settings.Save(); ModMain.Log.Msg("Quality Of Lab: movement defaults restored."); } private static void ResetHudDefaults() { Settings.StatsOverlay.Value = false; Settings.Crosshair.Value = false; Settings.ShowLobbyInfo.Value = false; Settings.WristHudEnabled.Value = false; Settings.Save(); ModMain.Log.Msg("Quality Of Lab: HUD defaults restored."); } private static void ResetHotkeys() { for (int i = 0; i < 4; i++) { Settings.HotkeyTrigger[i].Value = 0; Settings.HotkeyAction[i].Value = 0; } Settings.Save(); ModMain.Log.Msg("Quality Of Lab: hotkeys cleared."); } private static void ResetAll() { Settings.GodMode.Value = false; Settings.KeepBetweenLevels.Value = false; Settings.KeepOnStartup.Value = false; Settings.AutoSaveOnLevelEnd.Value = false; Settings.StripEmptyHolsters.Value = true; Settings.AvatarScale.Value = 1f; Settings.ObjectScale.Value = 1f; Settings.ScaleOnPickup.Value = false; Settings.JumpMultiplier.Value = 1f; Settings.HasPositionMarker.Value = false; Settings.GravityY.Value = -9.81f; Settings.RagdollForceMul.Value = 1f; Settings.NpcScale.Value = 1f; Settings.DamageMultiplier.Value = 1f; Settings.OneHitKill.Value = false; Settings.AutoHeal.Value = false; Settings.AutoHealThreshold.Value = 0.5f; Settings.InfiniteAmmo.Value = false; Settings.DamageResistance.Value = 0f; Settings.StatsOverlay.Value = false; Settings.Crosshair.Value = false; Settings.ShowLobbyInfo.Value = false; Settings.ExplosionForceMul.Value = 1f; Settings.FrictionMul.Value = 1f; Settings.BouncinessAdd.Value = 0f; Settings.WristHudEnabled.Value = false; Settings.TimeScaleActive.Value = false; Settings.TimeScale.Value = 1f; for (int i = 0; i < 4; i++) { Settings.HotkeyTrigger[i].Value = 0; Settings.HotkeyAction[i].Value = 0; } Settings.Save(); ModMain.Log.Msg("Quality Of Lab: settings reset."); } } public static class Settings { public const string Category = "QualityLab"; public const int LoadoutSlotCount = 5; public const int HotkeySlotCount = 4; public const int HolsterCount = 8; public const int ProfileSlotCount = 3; public const int FavoriteCodeCount = 5; public const int CheckpointCount = 5; public const int MarkerSlotCount = 3; public static MelonPreferences_Category Cat { get; private set; } public static MelonPreferences_Entry GodMode { get; private set; } public static MelonPreferences_Entry KeepBetweenLevels { get; private set; } public static MelonPreferences_Entry KeepOnStartup { get; private set; } public static MelonPreferences_Entry SelectedSlot { get; private set; } public static MelonPreferences_Entry[] SlotName { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry[] SlotData { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry AvatarScale { get; private set; } public static MelonPreferences_Entry ObjectScale { get; private set; } public static MelonPreferences_Entry JumpMultiplier { get; private set; } public static MelonPreferences_Entry GravityY { get; private set; } public static MelonPreferences_Entry RagdollForceMul { get; private set; } public static MelonPreferences_Entry NpcScale { get; private set; } public static MelonPreferences_Entry DamageMultiplier { get; private set; } public static MelonPreferences_Entry OneHitKill { get; private set; } public static MelonPreferences_Entry AutoHeal { get; private set; } public static MelonPreferences_Entry AutoHealThreshold { get; private set; } public static MelonPreferences_Entry InfiniteAmmo { get; private set; } public static MelonPreferences_Entry DamageResistance { get; private set; } public static MelonPreferences_Entry Crosshair { get; private set; } public static MelonPreferences_Entry ShowLobbyInfo { get; private set; } public static MelonPreferences_Entry ExplosionForceMul { get; private set; } public static MelonPreferences_Entry FrictionMul { get; private set; } public static MelonPreferences_Entry BouncinessAdd { get; private set; } public static MelonPreferences_Entry[] HolsterVisibility { get; private set; } = new MelonPreferences_Entry[8]; public static MelonPreferences_Entry[] ProfileName { get; private set; } = new MelonPreferences_Entry[3]; public static MelonPreferences_Entry[] ProfileData { get; private set; } = new MelonPreferences_Entry[3]; public static MelonPreferences_Entry StatsOverlay { get; private set; } public static MelonPreferences_Entry HasPositionMarker { get; private set; } public static MelonPreferences_Entry MarkerX { get; private set; } public static MelonPreferences_Entry MarkerY { get; private set; } public static MelonPreferences_Entry MarkerZ { get; private set; } public static MelonPreferences_Entry[] MarkerHas { get; private set; } = new MelonPreferences_Entry[3]; public static MelonPreferences_Entry[] MarkerXs { get; private set; } = new MelonPreferences_Entry[3]; public static MelonPreferences_Entry[] MarkerYs { get; private set; } = new MelonPreferences_Entry[3]; public static MelonPreferences_Entry[] MarkerZs { get; private set; } = new MelonPreferences_Entry[3]; public static MelonPreferences_Entry AutoSaveOnLevelEnd { get; private set; } public static MelonPreferences_Entry StripEmptyHolsters { get; private set; } public static MelonPreferences_Entry PerLevelLoadouts { get; private set; } public static MelonPreferences_Entry LevelSlotMap { get; private set; } public static MelonPreferences_Entry ScaleOnPickup { get; private set; } public static MelonPreferences_Entry RememberBarcodeScales { get; private set; } public static MelonPreferences_Entry AutoPerception { get; private set; } public static MelonPreferences_Entry PhotoSupersize { get; private set; } public static MelonPreferences_Entry WristHudEnabled { get; private set; } public static MelonPreferences_Entry[] FavoriteCode { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry[] FavoriteName { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry LastLobbyCode { get; private set; } public static MelonPreferences_Entry[] HotkeyTrigger { get; private set; } = new MelonPreferences_Entry[4]; public static MelonPreferences_Entry[] HotkeyAction { get; private set; } = new MelonPreferences_Entry[4]; public static MelonPreferences_Entry FreecamEnabled { get; private set; } public static MelonPreferences_Entry FreecamSpeed { get; private set; } public static MelonPreferences_Entry PhotoHideHud { get; private set; } public static MelonPreferences_Entry PhotoCountdownSecs { get; private set; } public static MelonPreferences_Entry PhotoBurstCount { get; private set; } public static MelonPreferences_Entry TimeScale { get; private set; } public static MelonPreferences_Entry TimeScaleActive { get; private set; } public static MelonPreferences_Entry SlowMoFactor { get; private set; } public static MelonPreferences_Entry PauseAffectsAudio { get; private set; } public static MelonPreferences_Entry[] CheckpointHas { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry[] CheckpointX { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry[] CheckpointY { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry[] CheckpointZ { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry[] CheckpointHp { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry[] CheckpointLevel { get; private set; } = new MelonPreferences_Entry[5]; public static MelonPreferences_Entry[] CheckpointName { get; private set; } = new MelonPreferences_Entry[5]; public static void Init() { Cat = MelonPreferences.CreateCategory("QualityLab", "Quality Of Lab"); GodMode = Cat.CreateEntry("GodMode", false, "God Mode", (string)null, false, false, (ValueValidator)null, (string)null); KeepBetweenLevels = Cat.CreateEntry("KeepBetweenLevels", false, "Keep Inventory Between Levels", (string)null, false, false, (ValueValidator)null, (string)null); KeepOnStartup = Cat.CreateEntry("KeepOnStartup", false, "Apply Saved Inventory on Startup", (string)null, false, false, (ValueValidator)null, (string)null); SelectedSlot = Cat.CreateEntry("SelectedSlot", 1, "Selected Loadout Slot (1-5)", (string)null, false, false, (ValueValidator)null, (string)null); for (int i = 0; i < 5; i++) { int value = i + 1; SlotName[i] = Cat.CreateEntry($"SlotName{value}", $"Slot {value}", $"Loadout slot {value} display name", (string)null, false, false, (ValueValidator)null, (string)null); SlotData[i] = Cat.CreateEntry($"SlotData{value}", "", $"Loadout slot {value} serialized data", (string)null, false, false, (ValueValidator)null, (string)null); } AvatarScale = Cat.CreateEntry("AvatarScale", 1f, "Avatar Scale", (string)null, false, false, (ValueValidator)null, (string)null); ObjectScale = Cat.CreateEntry("ObjectScale", 1f, "Object Scale", (string)null, false, false, (ValueValidator)null, (string)null); JumpMultiplier = Cat.CreateEntry("JumpMultiplier", 1f, "Jump Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); GravityY = Cat.CreateEntry("GravityY", -9.81f, "Gravity Y (default -9.81)", (string)null, false, false, (ValueValidator)null, (string)null); RagdollForceMul = Cat.CreateEntry("RagdollForceMul", 1f, "Ragdoll Force Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); NpcScale = Cat.CreateEntry("NpcScale", 1f, "NPC Scale Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); DamageMultiplier = Cat.CreateEntry("DamageMultiplier", 1f, "Damage Multiplier (you -> enemies)", (string)null, false, false, (ValueValidator)null, (string)null); OneHitKill = Cat.CreateEntry("OneHitKill", false, "One-Hit Kill", (string)null, false, false, (ValueValidator)null, (string)null); AutoHeal = Cat.CreateEntry("AutoHeal", false, "Auto-Heal", (string)null, false, false, (ValueValidator)null, (string)null); AutoHealThreshold = Cat.CreateEntry("AutoHealThreshold", 0.5f, "Auto-Heal Threshold (0..1 of max)", (string)null, false, false, (ValueValidator)null, (string)null); InfiniteAmmo = Cat.CreateEntry("InfiniteAmmo", false, "Infinite Ammo (refills hip inventory)", (string)null, false, false, (ValueValidator)null, (string)null); DamageResistance = Cat.CreateEntry("DamageResistance", 0f, "Damage Resistance (0=normal, 1=immune)", (string)null, false, false, (ValueValidator)null, (string)null); Crosshair = Cat.CreateEntry("Crosshair", false, "Center crosshair overlay", (string)null, false, false, (ValueValidator)null, (string)null); ShowLobbyInfo = Cat.CreateEntry("ShowLobbyInfo", false, "Show Fusion lobby info in stats", (string)null, false, false, (ValueValidator)null, (string)null); ExplosionForceMul = Cat.CreateEntry("ExplosionForceMul", 1f, "Explosion Force Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); FrictionMul = Cat.CreateEntry("FrictionMul", 1f, "Surface Friction Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); BouncinessAdd = Cat.CreateEntry("BouncinessAdd", 0f, "Bounciness Added (0-1)", (string)null, false, false, (ValueValidator)null, (string)null); StatsOverlay = Cat.CreateEntry("StatsOverlay", false, "On-screen Stats Overlay", (string)null, false, false, (ValueValidator)null, (string)null); HasPositionMarker = Cat.CreateEntry("HasPositionMarker", false, "Position marker set", (string)null, false, false, (ValueValidator)null, (string)null); MarkerX = Cat.CreateEntry("MarkerX", 0f, "Marker X", (string)null, false, false, (ValueValidator)null, (string)null); MarkerY = Cat.CreateEntry("MarkerY", 0f, "Marker Y", (string)null, false, false, (ValueValidator)null, (string)null); MarkerZ = Cat.CreateEntry("MarkerZ", 0f, "Marker Z", (string)null, false, false, (ValueValidator)null, (string)null); for (int j = 0; j < 3; j++) { char value2 = (char)(65 + j); MarkerHas[j] = Cat.CreateEntry($"Marker{value2}_Has", false, $"Marker {value2} set", (string)null, false, false, (ValueValidator)null, (string)null); MarkerXs[j] = Cat.CreateEntry($"Marker{value2}_X", 0f, $"Marker {value2} X", (string)null, false, false, (ValueValidator)null, (string)null); MarkerYs[j] = Cat.CreateEntry($"Marker{value2}_Y", 0f, $"Marker {value2} Y", (string)null, false, false, (ValueValidator)null, (string)null); MarkerZs[j] = Cat.CreateEntry($"Marker{value2}_Z", 0f, $"Marker {value2} Z", (string)null, false, false, (ValueValidator)null, (string)null); } AutoSaveOnLevelEnd = Cat.CreateEntry("AutoSaveOnLevelEnd", false, "Auto-Save Loadout on Level End", (string)null, false, false, (ValueValidator)null, (string)null); StripEmptyHolsters = Cat.CreateEntry("StripEmptyHolsters", true, "Don't restore empty holsters", (string)null, false, false, (ValueValidator)null, (string)null); PerLevelLoadouts = Cat.CreateEntry("PerLevelLoadouts", false, "Auto-pick loadout slot by level", (string)null, false, false, (ValueValidator)null, (string)null); LevelSlotMap = Cat.CreateEntry("LevelSlotMap", "", "level barcode:slot pairs, ;-separated", (string)null, false, false, (ValueValidator)null, (string)null); ScaleOnPickup = Cat.CreateEntry("ScaleOnPickup", false, "Scale objects automatically on pickup", (string)null, false, false, (ValueValidator)null, (string)null); RememberBarcodeScales = Cat.CreateEntry("RememberBarcodeScales", false, "Remember scales per barcode (session)", (string)null, false, false, (ValueValidator)null, (string)null); AutoPerception = Cat.CreateEntry("AutoPerception", false, "Identify items automatically on pickup", (string)null, false, false, (ValueValidator)null, (string)null); PhotoSupersize = Cat.CreateEntry("PhotoSupersize", false, "Capture screenshots at 2x resolution", (string)null, false, false, (ValueValidator)null, (string)null); WristHudEnabled = Cat.CreateEntry("WristHudEnabled", false, "In-VR wrist HUD (FPS / state flags)", (string)null, false, false, (ValueValidator)null, (string)null); for (int k = 0; k < 5; k++) { int value3 = k + 1; FavoriteName[k] = Cat.CreateEntry($"FavName{value3}", $"Favorite {value3}", $"Favorite lobby {value3} display name", (string)null, false, false, (ValueValidator)null, (string)null); FavoriteCode[k] = Cat.CreateEntry($"FavCode{value3}", "", $"Favorite lobby {value3} join code", (string)null, false, false, (ValueValidator)null, (string)null); } LastLobbyCode = Cat.CreateEntry("LastLobbyCode", "", "Last lobby code seen while in a server", (string)null, false, false, (ValueValidator)null, (string)null); for (int l = 0; l < 4; l++) { int value4 = l + 1; HotkeyTrigger[l] = Cat.CreateEntry($"HotkeyTrigger{value4}", 0, $"Hotkey {value4} trigger code", (string)null, false, false, (ValueValidator)null, (string)null); HotkeyAction[l] = Cat.CreateEntry($"HotkeyAction{value4}", 0, $"Hotkey {value4} action code", (string)null, false, false, (ValueValidator)null, (string)null); } for (int m = 0; m < 8; m++) { HolsterVisibility[m] = Cat.CreateEntry($"Holster{m}_Vis", 0, $"Holster slot {m} visibility (0/1/2)", (string)null, false, false, (ValueValidator)null, (string)null); } for (int n = 0; n < 3; n++) { int value5 = n + 1; ProfileName[n] = Cat.CreateEntry($"Profile{value5}_Name", $"Profile {value5}", $"Profile {value5} display name", (string)null, false, false, (ValueValidator)null, (string)null); ProfileData[n] = Cat.CreateEntry($"Profile{value5}_Data", "", $"Profile {value5} serialized data", (string)null, false, false, (ValueValidator)null, (string)null); } FreecamEnabled = Cat.CreateEntry("FreecamEnabled", false, "Director freecam active", (string)null, false, false, (ValueValidator)null, (string)null); FreecamSpeed = Cat.CreateEntry("FreecamSpeed", 4f, "Freecam fly speed (m/s)", (string)null, false, false, (ValueValidator)null, (string)null); PhotoHideHud = Cat.CreateEntry("PhotoHideHud", true, "Auto-hide HUD on countdown", (string)null, false, false, (ValueValidator)null, (string)null); PhotoCountdownSecs = Cat.CreateEntry("PhotoCountdownSecs", 3, "Default photo countdown (s)", (string)null, false, false, (ValueValidator)null, (string)null); PhotoBurstCount = Cat.CreateEntry("PhotoBurstCount", 3, "Default burst count", (string)null, false, false, (ValueValidator)null, (string)null); TimeScale = Cat.CreateEntry("TimeScale", 1f, "Time scale (0.05..3.0)", (string)null, false, false, (ValueValidator)null, (string)null); TimeScaleActive = Cat.CreateEntry("TimeScaleActive", false, "Apply Quality Of Lab time scale (off = vanilla)", (string)null, false, false, (ValueValidator)null, (string)null); SlowMoFactor = Cat.CreateEntry("SlowMoFactor", 0.35f, "Factor used by the Slow-Mo toggle / hotkey", (string)null, false, false, (ValueValidator)null, (string)null); PauseAffectsAudio = Cat.CreateEntry("PauseAffectsAudio", true, "Time scale affects audio pitch", (string)null, false, false, (ValueValidator)null, (string)null); try { if (TimeScale.Value < 0.05f || TimeScale.Value > 3f) { TimeScale.Value = 1f; TimeScaleActive.Value = false; } } catch { } for (int num = 0; num < 5; num++) { int value6 = num + 1; CheckpointHas[num] = Cat.CreateEntry($"Checkpoint{value6}_Has", false, $"Checkpoint {value6} populated", (string)null, false, false, (ValueValidator)null, (string)null); CheckpointX[num] = Cat.CreateEntry($"Checkpoint{value6}_X", 0f, $"Checkpoint {value6} X", (string)null, false, false, (ValueValidator)null, (string)null); CheckpointY[num] = Cat.CreateEntry($"Checkpoint{value6}_Y", 0f, $"Checkpoint {value6} Y", (string)null, false, false, (ValueValidator)null, (string)null); CheckpointZ[num] = Cat.CreateEntry($"Checkpoint{value6}_Z", 0f, $"Checkpoint {value6} Z", (string)null, false, false, (ValueValidator)null, (string)null); CheckpointHp[num] = Cat.CreateEntry($"Checkpoint{value6}_Hp", 1f, $"Checkpoint {value6} health ratio", (string)null, false, false, (ValueValidator)null, (string)null); CheckpointLevel[num] = Cat.CreateEntry($"Checkpoint{value6}_Level", "", $"Checkpoint {value6} level barcode", (string)null, false, false, (ValueValidator)null, (string)null); CheckpointName[num] = Cat.CreateEntry($"Checkpoint{value6}_Name", $"Checkpoint {value6}", $"Checkpoint {value6} display name", (string)null, false, false, (ValueValidator)null, (string)null); } Cat.SaveToFile(false); } public static void Save() { MelonPreferences_Category cat = Cat; if (cat != null) { cat.SaveToFile(false); } } } } namespace Quality_Lab.Features { public static class Avatars { public static readonly (string Name, string Barcode)[] Presets = new(string, string)[7] { ("Ford", "SLZ.BONELAB.Content.Avatar.FordBW"), ("Jimmy", "SLZ.BONELAB.Content.Avatar.CharJimmy"), ("Anime", "SLZ.BONELAB.Content.Avatar.Anime"), ("Skeleton Pirate", "SLZ.BONELAB.Content.Avatar.SkeletonPirate"), ("Null Body", "SLZ.BONELAB.Content.Avatar.Nullbody"), ("Dog (Duck Season)", "SLZ.BONELAB.Content.Avatar.DogDuckSeason"), ("Peasant Female", "SLZ.BONELAB.Core.Avatar.PeasantFemaleA") }; public static void SwapToBarcode(string barcodeId) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown if (string.IsNullOrEmpty(barcodeId)) { Notifications.Warn("Avatar swap: empty barcode."); return; } RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { Notifications.Warn("Avatar swap: no rig (load into a level first)."); return; } try { AssetWarehouse instance = AssetWarehouse.Instance; AvatarCrate val = default(AvatarCrate); if (instance != null && !instance.TryGetCrate(new Barcode(barcodeId), ref val)) { Notifications.Warn("Avatar not found: " + ShortName(barcodeId)); return; } rigManager.SwapAvatarCrate(new Barcode(barcodeId), false, (Action)null); Notifications.Success("Swapped to " + ShortName(barcodeId)); } catch (Exception ex) { Notifications.Error("Avatar swap failed: " + ex.Message); } } public static void RandomVanilla() { if (Presets.Length != 0) { int num = Random.Range(0, Presets.Length); SwapToBarcode(Presets[num].Barcode); } } public static void ResetToDefault() { SwapToBarcode(Presets[0].Barcode); } private static string ShortName(string barcode) { if (string.IsNullOrEmpty(barcode)) { return "?"; } int num = barcode.LastIndexOf('.'); if (num <= 0 || num >= barcode.Length - 1) { return barcode; } return barcode.Substring(num + 1); } } public static class AvatarScaling { private static GameObject _avatarObject; public static void Apply() { ApplyInternal(Settings.AvatarScale.Value); } public static void Reset() { ApplyInternal(1f); } private static void ApplyInternal(float scale) { RigManager rm = Player.RigManager; if ((Object)(object)rm == (Object)null) { ModMain.Log.Warning("Avatar Scale: no rig."); } else { AvatarCrate val = default(AvatarCrate); if (!AssetWarehouse.Instance.TryGetCrate(((ScannableReference)rm._avatarCrate)._barcode, ref val)) { return; } Action action = delegate(GameObject prefab) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) _avatarObject = Object.Instantiate(prefab); _avatarObject.transform.localScale = new Vector3(scale, scale, scale); _avatarObject.transform.parent = ((Component)rm).transform; _avatarObject.transform.localPosition = Vector3.zero; Avatar componentInChildren = _avatarObject.GetComponentInChildren(); foreach (SkinnedMeshRenderer item in (Il2CppArrayBase)(object)componentInChildren.hairMeshes) { ((Renderer)item).enabled = false; } componentInChildren.PrecomputeAvatar(); componentInChildren.RefreshBodyMeasurements(); rm.SwitchAvatar(componentInChildren); PlayerRefs.Instance._bodyVitals.PROPEGATE(); PullCordDevice componentInChildren2 = ((Component)Player.GetPhysicsRig()).GetComponentInChildren(); if ((Object)(object)componentInChildren2 != (Object)null) { ((Component)componentInChildren2).transform.localScale = new Vector3(scale, scale, scale); } foreach (SlotContainer item2 in (Il2CppArrayBase)(object)rm.inventory.bodySlots) { ((Component)item2).transform.localScale = new Vector3(scale, scale, scale); if (((Object)item2).name.Equals("BeltLf1")) { InventoryAmmoReceiver componentInChildren3 = ((Component)item2).GetComponentInChildren(); if ((Object)(object)componentInChildren3 != (Object)null) { Enumerator enumerator3 = componentInChildren3._magazineArts.GetEnumerator(); while (enumerator3.MoveNext()) { ((Component)enumerator3.Current).transform.localScale = new Vector3(scale, scale, scale); } } } } }; ((CrateT)(object)val).LoadAsset(Action.op_Implicit(action)); } } } public static class Checkpoints { public static void Save(int slot) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (slot < 0 || slot >= 5) { return; } RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { Notifications.Warn("No rig — can't snapshot."); return; } Vector3 position = ((Component)rigManager).transform.position; float num = 1f; try { Health health = rigManager.health; Player_Health val = ((health != null) ? ((Il2CppObjectBase)health).TryCast() : null); if ((Object)(object)val != (Object)null && ((Health)val).max_Health > 0.01f) { num = Mathf.Clamp01(((Health)val).curr_Health / ((Health)val).max_Health); } } catch { } string value = ""; try { StreamSession session = SceneStreamer.Session; object obj2; if (session == null) { obj2 = null; } else { LevelCrate level = session.Level; if (level == null) { obj2 = null; } else { Barcode barcode = ((Scannable)level).Barcode; obj2 = ((barcode != null) ? barcode._id : null); } } if (obj2 == null) { obj2 = ""; } value = (string)obj2; } catch { } Settings.CheckpointHas[slot].Value = true; Settings.CheckpointX[slot].Value = position.x; Settings.CheckpointY[slot].Value = position.y; Settings.CheckpointZ[slot].Value = position.z; Settings.CheckpointHp[slot].Value = num; Settings.CheckpointLevel[slot].Value = value; Settings.Save(); Notifications.Success($"Checkpoint {slot + 1} saved ({position.x:F1}, {position.y:F1}, {position.z:F1}) @ {num * 100f:F0}% HP."); ModMain.Log.Msg($"Checkpoint {slot + 1} saved at ({position.x:F1}, {position.y:F1}, {position.z:F1}) HP={num:F2} lvl={value}"); } public static void Restore(int slot) { //IL_013c: Unknown result type (might be due to invalid IL or missing references) if (slot < 0 || slot >= 5) { return; } if (!Settings.CheckpointHas[slot].Value) { Notifications.Warn($"Checkpoint {slot + 1} is empty — save first."); return; } RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { Notifications.Warn("No rig — can't restore."); return; } string text = Settings.CheckpointLevel[slot].Value ?? ""; string text2 = ""; try { StreamSession session = SceneStreamer.Session; object obj; if (session == null) { obj = null; } else { LevelCrate level = session.Level; if (level == null) { obj = null; } else { Barcode barcode = ((Scannable)level).Barcode; obj = ((barcode != null) ? barcode._id : null); } } if (obj == null) { obj = ""; } text2 = (string)obj; } catch { } if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text2) && text != text2) { Notifications.Warn($"Checkpoint {slot + 1}: saved on a different level — skipping."); return; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Settings.CheckpointX[slot].Value, Settings.CheckpointY[slot].Value, Settings.CheckpointZ[slot].Value); rigManager.Teleport(val, true); Stats.BumpTeleport(); try { Health health = rigManager.health; Player_Health val2 = ((health != null) ? ((Il2CppObjectBase)health).TryCast() : null); if ((Object)(object)val2 != (Object)null) { float num = Mathf.Clamp01(Settings.CheckpointHp[slot].Value); ((Health)val2).curr_Health = ((Health)val2).max_Health * num; } } catch { } Notifications.Success($"Checkpoint {slot + 1} restored."); ModMain.Log.Msg($"Checkpoint {slot + 1} restored."); } public static void Clear(int slot) { if (slot >= 0 && slot < 5) { Settings.CheckpointHas[slot].Value = false; Settings.Save(); Notifications.Info($"Checkpoint {slot + 1} cleared."); } } public static void ClearAll() { for (int i = 0; i < 5; i++) { Settings.CheckpointHas[i].Value = false; } Settings.Save(); Notifications.Info("All checkpoints cleared."); } public static string Label(int slot) { if (slot < 0 || slot >= 5) { return "?"; } string text = Settings.CheckpointName[slot].Value; if (string.IsNullOrWhiteSpace(text)) { text = $"Checkpoint {slot + 1}"; } if (!Settings.CheckpointHas[slot].Value) { return text + " (empty)"; } return $"{text} @ ({Settings.CheckpointX[slot].Value:F0},{Settings.CheckpointY[slot].Value:F0},{Settings.CheckpointZ[slot].Value:F0}) {Settings.CheckpointHp[slot].Value * 100f:F0}%"; } public static int CountPopulated() { int num = 0; for (int i = 0; i < 5; i++) { if (Settings.CheckpointHas[i].Value) { num++; } } return num; } } public static class ClearItems { public enum Filter { All, Guns, Melees, Npcs, Props } private static int _cachedCount; private static float _cachedAt; public static void ClearAll() { Clear(Filter.All); } public static void ClearGuns() { Clear(Filter.Guns); } public static void ClearMelees() { Clear(Filter.Melees); } public static void ClearNpcs() { Clear(Filter.Npcs); } public static void ClearProps() { Clear(Filter.Props); } public static int CountScene() { float unscaledTime = Time.unscaledTime; if (unscaledTime - _cachedAt < 0.5f) { return _cachedCount; } int num = 0; try { bool flag = false; try { flag = NetworkInfo.HasServer; } catch { } if (flag) { Dictionary dictionary = NetworkEntityManager.IDManager?.RegisteredEntities?.EntityIDLookup; if (dictionary != null) { foreach (KeyValuePair item in dictionary) { NetworkEntity key = item.Key; if (key != null) { MarrowEntity marrowEntity = GetMarrowEntity(key); if (!((Object)(object)marrowEntity == (Object)null) && !IsNetPlayer(marrowEntity)) { num++; } } } } } else { Transform val = null; RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager != (Object)null) { val = ((Component)rigManager).transform; } Il2CppArrayBase val2 = Object.FindObjectsOfType(); for (int i = 0; i < val2.Length; i++) { Poolee val3 = val2[i]; if (!((Object)(object)val3 == (Object)null)) { GameObject gameObject; try { gameObject = ((Component)val3).gameObject; } catch { continue; } if (!((Object)(object)gameObject == (Object)null) && (!((Object)(object)val != (Object)null) || !((Object)(object)gameObject.transform != (Object)null) || !gameObject.transform.IsChildOf(val))) { num++; } } } } } catch { } _cachedCount = num; _cachedAt = unscaledTime; return num; } public static void Clear(Filter f) { try { bool flag = false; try { flag = NetworkInfo.HasServer; } catch { } if (flag) { if (!Fusion.IsHost) { Notifications.Warn("Clear Items: host only in a Fusion lobby."); return; } int value = ClearNetworked(f); Notifications.Success($"Cleared {value} {Label(f)} (Fusion)."); ModMain.Log.Msg($"Clear Items ({f}): {value} entities despawned via Fusion."); } else { int value2 = ClearLocal(f); Notifications.Success($"Cleared {value2} {Label(f)}."); ModMain.Log.Msg($"Clear Items ({f}): {value2} pooled objects despawned locally."); } } catch (Exception ex) { Notifications.Error("Clear Items failed: " + ex.Message); ModMain.Log.Warning($"Clear Items ({f}) failed: {ex}"); } } private static int ClearNetworked(Filter f) { //IL_00c0: 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) int num = 0; EntityIDManager iDManager = NetworkEntityManager.IDManager; if (iDManager == null) { return 0; } EntityIDList registeredEntities = iDManager.RegisteredEntities; if (registeredEntities == null) { return 0; } Dictionary entityIDLookup = registeredEntities.EntityIDLookup; if (entityIDLookup == null) { return 0; } List list = new List(); foreach (KeyValuePair item in entityIDLookup) { list.Add(item.Key); } foreach (NetworkEntity item2 in list) { if (item2 == null) { continue; } MarrowEntity marrowEntity = GetMarrowEntity(item2); if ((Object)(object)marrowEntity == (Object)null || IsNetPlayer(marrowEntity)) { continue; } GameObject gameObject = ((Component)marrowEntity).gameObject; if (!((Object)(object)gameObject == (Object)null) && PassesFilter(gameObject, f)) { try { NetworkAssetSpawner.Despawn(new DespawnRequestInfo { EntityID = item2.ID, DespawnEffect = false }); num++; } catch (Exception ex) { ModMain.Log.Warning("ClearNetworked: per-entity failure: " + ex.Message); } } } return num; } private static MarrowEntity GetMarrowEntity(NetworkEntity entity) { try { IMarrowEntityExtender extender = entity.GetExtender(); return (extender != null) ? extender.MarrowEntity : null; } catch { return null; } } private static bool IsNetPlayer(MarrowEntity entity) { try { GameObject gameObject = ((Component)entity).gameObject; if ((Object)(object)gameObject == (Object)null) { return false; } Transform val = (((Object)(object)gameObject.transform != (Object)null) ? gameObject.transform.root : null); if ((Object)(object)val == (Object)null) { return false; } return (Object)(object)((Component)val).GetComponent() != (Object)null; } catch { return false; } } private static int ClearLocal(Filter f) { int num = 0; Transform val = null; RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager != (Object)null) { val = ((Component)rigManager).transform; } Il2CppArrayBase val2 = Object.FindObjectsOfType(); for (int i = 0; i < val2.Length; i++) { Poolee val3 = val2[i]; if ((Object)(object)val3 == (Object)null) { continue; } GameObject gameObject; try { gameObject = ((Component)val3).gameObject; } catch { continue; } if (!((Object)(object)gameObject == (Object)null) && (!((Object)(object)val != (Object)null) || !((Object)(object)gameObject.transform != (Object)null) || !gameObject.transform.IsChildOf(val)) && PassesFilter(gameObject, f)) { try { val3.Despawn(); num++; } catch (Exception ex) { ModMain.Log.Warning("ClearLocal: per-poolee failure: " + ex.Message); } } } return num; } private static bool PassesFilter(GameObject go, Filter f) { switch (f) { case Filter.All: return true; case Filter.Guns: return (Object)(object)go.GetComponent() != (Object)null; case Filter.Melees: return (Object)(object)go.GetComponent() != (Object)null; case Filter.Npcs: return (Object)(object)go.GetComponent() != (Object)null; case Filter.Props: if ((Object)(object)go.GetComponent() == (Object)null && (Object)(object)go.GetComponent() == (Object)null) { return (Object)(object)go.GetComponent() == (Object)null; } return false; default: return false; } } private static string Label(Filter f) { return f switch { Filter.All => "items", Filter.Guns => "guns", Filter.Melees => "melees", Filter.Npcs => "NPCs", Filter.Props => "props", _ => "items", }; } } public static class Combat { private const int AmmoTopUpTo = 999; private const float AmmoCheckInterval = 0.5f; private static float _nextAmmoCheck; public static void Tick() { TickAutoHeal(); TickInfiniteAmmo(); } private static void TickAutoHeal() { if (!Settings.AutoHeal.Value) { return; } RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { return; } Health health = rigManager.health; Player_Health val = ((health != null) ? ((Il2CppObjectBase)health).TryCast() : null); if (!((Object)(object)val == (Object)null)) { float num = Mathf.Clamp01(Settings.AutoHealThreshold.Value); float num2 = ((Health)val).max_Health * num; if (((Health)val).curr_Health < num2) { ((Health)val).curr_Health = ((Health)val).max_Health; } } } private static void TickInfiniteAmmo() { if (Settings.InfiniteAmmo.Value && !(Time.unscaledTime < _nextAmmoCheck)) { _nextAmmoCheck = Time.unscaledTime + 0.5f; AmmoInventory instance = AmmoInventory.Instance; if (!((Object)(object)instance == (Object)null)) { TopUpGroup(instance, instance.lightAmmoGroup); TopUpGroup(instance, instance.mediumAmmoGroup); TopUpGroup(instance, instance.heavyAmmoGroup); } } } private static void TopUpGroup(AmmoInventory inv, AmmoGroup group) { if ((Object)(object)group == (Object)null) { return; } try { inv.AddCartridge(group, 999); } catch { } } public static void TopUpHealth() { RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { ModMain.Log.Warning("Top Up Health: no rig."); return; } Health health = rigManager.health; Player_Health val = ((health != null) ? ((Il2CppObjectBase)health).TryCast() : null); if (!((Object)(object)val == (Object)null)) { ((Health)val).curr_Health = ((Health)val).max_Health; ModMain.Log.Msg("Health topped up."); } } public static void TopUpAmmoOnce() { AmmoInventory instance = AmmoInventory.Instance; if ((Object)(object)instance == (Object)null) { ModMain.Log.Warning("Ammo Top-Up: no inventory."); return; } TopUpGroup(instance, instance.lightAmmoGroup); TopUpGroup(instance, instance.mediumAmmoGroup); TopUpGroup(instance, instance.heavyAmmoGroup); ModMain.Log.Msg("Ammo topped up."); } public static void ClearAmmo() { AmmoInventory instance = AmmoInventory.Instance; if ((Object)(object)instance == (Object)null) { return; } try { instance.ClearAmmo(); ModMain.Log.Msg("Ammo cleared."); } catch (Exception ex) { ModMain.Log.Warning("ClearAmmo failed: " + ex.Message); } } public static void MagicReload() { int num = 0; num += TryReloadHand(Player.LeftHand); num += TryReloadHand(Player.RightHand); if (num == 0) { Notifications.Warn("No firearm to reload."); return; } Notifications.Success($"Reloaded {num} firearm(s)."); } private static int TryReloadHand(Hand hand) { if ((Object)(object)hand == (Object)null) { return 0; } GameObject objectInHand = Player.GetObjectInHand(hand); if ((Object)(object)objectInHand == (Object)null) { return 0; } try { Gun componentInParent = objectInHand.GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || componentInParent._magState == null) { return 0; } componentInParent._magState.Refill(); return 1; } catch (Exception ex) { ModMain.Log.Warning("MagicReload failed: " + ex.Message); return 0; } } } [HarmonyPatch(typeof(Player_Health), "TAKEDAMAGE", new Type[] { typeof(float) })] public static class DamageResistance_Patch { public static void Prefix(ref float damage) { float num = Mathf.Clamp01(Settings.DamageResistance.Value); if (num > 0f) { damage *= 1f - num; } } } [HarmonyPatch(typeof(ImpactProperties), "ReceiveAttack")] public static class Combat_ReceiveAttack_Patch { private const float MinDamageForKill = 0.5f; private const float MinDamageForStats = 1f; public static void Prefix(ImpactProperties __instance, ref Attack attack) { if ((Object)(object)__instance == (Object)null || attack == null) { return; } try { AIBrain componentInParent = ((Component)__instance).gameObject.GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { return; } float damage = attack.damage; bool flag = false; if (Settings.OneHitKill.Value && damage >= 0.5f) { try { BehaviourBaseNav behaviour = componentInParent.behaviour; SubBehaviourHealth val = (((Object)(object)behaviour != (Object)null) ? behaviour.health : null); if (val != null) { val.Kill(); } } catch { } attack.damage = 99999f; flag = true; } else { float num = Mathf.Max(0f, Settings.DamageMultiplier.Value); if (!Mathf.Approximately(num, 1f)) { Attack obj2 = attack; obj2.damage *= num; } } if (!(damage >= 1f)) { return; } float damage2 = attack.damage; Stats.BumpDamageDealt(damage2); if (!flag) { try { BehaviourBaseNav behaviour2 = componentInParent.behaviour; SubBehaviourHealth val2 = (((Object)(object)behaviour2 != (Object)null) ? behaviour2.health : null); if (val2 != null && damage2 >= val2.cur_hp - 0.01f) { flag = true; } } catch { } } if (flag) { Stats.BumpKill(); } } catch { } } } public static class Freecam { private static Vector3 _pos; private static float _yaw; private static float _pitch; private static Vector3 _lastApplied; public static bool IsActive => Settings.FreecamEnabled.Value; public static void Toggle() { if (IsActive) { Stop(); } else { Start(); } } public static void Start() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) try { Transform head = Player.Head; if ((Object)(object)head != (Object)null) { _pos = ((Component)head).transform.position; Quaternion rotation = ((Component)head).transform.rotation; Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; _yaw = eulerAngles.y; _pitch = NormalisePitch(eulerAngles.x); } } catch { } Settings.FreecamEnabled.Value = true; Settings.Save(); Notifications.Info("Freecam ON. Right stick: move, L stick: rotate, A: up, B: down."); } public static void Stop() { Settings.FreecamEnabled.Value = false; Settings.Save(); Notifications.Info("Freecam OFF."); } public static void Tick() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0076: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) if (!IsActive) { return; } BaseController leftController = Player.LeftController; BaseController rightController = Player.RightController; if ((Object)(object)leftController == (Object)null && (Object)(object)rightController == (Object)null) { return; } float unscaledDeltaTime = Time.unscaledDeltaTime; float num = Mathf.Max(0.5f, Settings.FreecamSpeed.Value); float num2 = 90f; try { if ((Object)(object)rightController != (Object)null) { Vector2 thumbStickAxis = rightController.GetThumbStickAxis(); Vector3 val = Quaternion.Euler(_pitch, _yaw, 0f) * Vector3.forward; Vector3 val2 = Quaternion.Euler(0f, _yaw, 0f) * Vector3.right; _pos += (val * thumbStickAxis.y + val2 * thumbStickAxis.x) * (num * unscaledDeltaTime); if (rightController.GetAButton()) { _pos += Vector3.up * (num * unscaledDeltaTime); } if (rightController.GetBButton()) { _pos += Vector3.down * (num * unscaledDeltaTime); } } if ((Object)(object)leftController != (Object)null) { Vector2 thumbStickAxis2 = leftController.GetThumbStickAxis(); _yaw += thumbStickAxis2.x * num2 * unscaledDeltaTime; _pitch -= thumbStickAxis2.y * num2 * unscaledDeltaTime; _pitch = Mathf.Clamp(_pitch, -85f, 85f); if (leftController.GetAButton()) { _pos += Vector3.up * (num * unscaledDeltaTime); } if (leftController.GetBButton()) { _pos += Vector3.down * (num * unscaledDeltaTime); } } } catch { } ApplyPose(force: false); } private static void ApplyPose(bool force) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0019: Unknown result type (might be due to invalid IL or missing references) try { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null) && (force || !(Vector3.Distance(_pos, _lastApplied) < 0.001f))) { rigManager.Teleport(_pos, true); _lastApplied = _pos; } } catch { } } private static float NormalisePitch(float x) { return Mathf.Clamp((x > 180f) ? (x - 360f) : x, -85f, 85f); } } public static class Fusion { public struct PlayerEntry { public byte SmallID; public string Username; public string Nickname; public bool IsLocal; public bool IsHost; } private static int _cycleIndex; private static readonly int[] _maxPlayersTable = new int[5] { 2, 4, 8, 16, 32 }; public static bool HasServer { get { try { return NetworkInfo.HasServer; } catch { return false; } } } public static bool IsHost { get { try { return NetworkInfo.IsHost; } catch { return false; } } } public static int PlayerCount { get { try { return PlayerIDManager.PlayerIDs?.Count ?? 0; } catch { return 0; } } } public static string LobbySummary() { if (!HasServer) { return "Offline"; } try { int playerCount = PlayerCount; string value = (IsHost ? "Host" : "Client"); return $"{value} - {playerCount} player{((playerCount == 1) ? "" : "s")}"; } catch { return "Online"; } } public static string LobbyCode() { if (!HasServer) { return "(offline)"; } try { return LobbyInfoManager.LobbyInfo.LobbyCode ?? "(none)"; } catch { return "(unavailable)"; } } public static string LobbyName() { if (!HasServer) { return "(offline)"; } try { return LobbyInfoManager.LobbyInfo.LobbyName ?? "(none)"; } catch { return "(unavailable)"; } } public static string LobbyHostName() { if (!HasServer) { return "(offline)"; } try { return LobbyInfoManager.LobbyInfo.LobbyHostName ?? "(none)"; } catch { return "(unavailable)"; } } public static int MaxPlayers() { if (!HasServer) { return 0; } try { return LobbyInfoManager.LobbyInfo.MaxPlayers; } catch { return 0; } } public static string PrivacyString() { //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) if (!HasServer) { return "(offline)"; } try { return ((object)LobbyInfoManager.LobbyInfo.Privacy/*cast due to .constrained prefix*/).ToString(); } catch { return "(unavailable)"; } } public static string LevelTitle() { if (!HasServer) { return "(offline)"; } try { return LobbyInfoManager.LobbyInfo.LevelTitle ?? "(none)"; } catch { return "(unavailable)"; } } public static List GetPlayers() { List list = new List(); if (!HasServer) { return list; } try { byte localSmallID = PlayerIDManager.LocalSmallID; PlayerID hostID = PlayerIDManager.GetHostID(); byte b = (byte)((hostID != null) ? hostID.SmallID : 0); foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { if (playerID != null) { string username = "?"; string nickname = ""; try { username = playerID.Metadata.Username.GetValue() ?? "?"; } catch { } try { nickname = playerID.Metadata.Nickname.GetValue() ?? ""; } catch { } list.Add(new PlayerEntry { SmallID = playerID.SmallID, Username = username, Nickname = nickname, IsLocal = (playerID.SmallID == localSmallID), IsHost = (playerID.SmallID == b) }); } } } catch (Exception ex) { ModMain.Log.Warning("Fusion player list failed: " + ex.Message); } return list; } public static string FormatPlayerLabel(PlayerEntry p) { string text = p.Username; if (!string.IsNullOrEmpty(p.Nickname) && p.Nickname != p.Username) { text = text + " (" + p.Nickname + ")"; } if (p.IsHost) { text = "[Host] " + text; } if (p.IsLocal) { text += " *"; } return text; } public static void TeleportToHost() { if (!HasServer) { Warn("Not in a lobby."); return; } if (IsHost) { Warn("You are the host."); return; } try { PlayerID hostID = PlayerIDManager.GetHostID(); if (hostID == null) { Warn("Host not found."); } else { TeleportToPlayer(hostID.SmallID); } } catch (Exception ex) { ModMain.Log.Warning("TeleportToHost: " + ex.Message); } } public static void TeleportToPlayer(byte smallId) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (!HasServer) { Warn("Not in a lobby."); return; } try { PlayerID playerID = PlayerIDManager.GetPlayerID(smallId); if (playerID == null) { Warn("Player not found."); return; } NetworkPlayer val = default(NetworkPlayer); if (!NetworkPlayerManager.TryGetPlayer(smallId, ref val) || val == null) { Warn("Could not resolve remote player rig."); return; } RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { return; } Vector3 val2 = Vector3.zero; bool flag = false; try { val2 = ((Component)val.RigRefs.RigManager).transform.position; flag = true; } catch { } if (!flag) { Warn("Could not read remote position."); return; } rigManager.Teleport(val2 + Vector3.up * 0.1f, true); string text = "player"; try { text = playerID.Metadata.Username.GetValue() ?? "player"; } catch { } ModMain.Log.Msg("Teleported to " + text + "."); } catch (Exception ex) { ModMain.Log.Warning("TeleportToPlayer: " + ex.Message); } } public static void TeleportToNextPlayer() { if (CycleNavGuard()) { _cycleIndex++; TeleportToCycleTarget(); } } public static void TeleportToPreviousPlayer() { if (CycleNavGuard()) { _cycleIndex--; TeleportToCycleTarget(); } } private static bool CycleNavGuard() { if (!HasServer) { Warn("Not in a lobby."); return false; } if (PlayerCount <= 1) { Warn("No other players in lobby."); return false; } return true; } private static void TeleportToCycleTarget() { try { List list = new List(); byte localSmallID = PlayerIDManager.LocalSmallID; foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { if (playerID != null && playerID.SmallID != localSmallID) { list.Add(playerID.SmallID); } } if (list.Count == 0) { Warn("No other players."); } else { TeleportToPlayer(list[_cycleIndex = (_cycleIndex % list.Count + list.Count) % list.Count]); } } catch (Exception ex) { ModMain.Log.Warning("Cycle TP: " + ex.Message); } } public static void TeleportAllToMe() { if (!HasServer) { Warn("Not in a lobby."); return; } if (!IsHost) { Warn("Host only."); return; } try { int num = 0; byte localSmallID = PlayerIDManager.LocalSmallID; foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { if (playerID != null && playerID.SmallID != localSmallID) { PermissionSender.SendPermissionRequest((PermissionCommandType)4, (byte?)playerID.SmallID); num++; } } ModMain.Log.Msg($"Teleport request sent to {num} player(s)."); } catch (Exception ex) { ModMain.Log.Warning("TeleportAllToMe: " + ex.Message); } } public static void BringPlayer(byte smallId) { if (!RequireHost("Bring player")) { return; } try { if (smallId == PlayerIDManager.LocalSmallID) { Warn("That's you."); return; } PermissionSender.SendPermissionRequest((PermissionCommandType)4, (byte?)smallId); ModMain.Log.Msg($"Bring request sent to {smallId}."); } catch (Exception ex) { ModMain.Log.Warning("BringPlayer: " + ex.Message); } } public static void ToggleNameTags() { if (!RequireHost("NameTags toggle")) { return; } try { LobbyInfoManager.LobbyInfo.NameTags = !LobbyInfoManager.LobbyInfo.NameTags; Info($"NameTags -> {LobbyInfoManager.LobbyInfo.NameTags}"); } catch (Exception ex) { ModMain.Log.Warning("NameTags: " + ex.Message); } } public static void ToggleMortality() { if (!RequireHost("Mortality toggle")) { return; } try { LobbyInfoManager.LobbyInfo.Mortality = !LobbyInfoManager.LobbyInfo.Mortality; Info($"Mortality -> {LobbyInfoManager.LobbyInfo.Mortality}"); } catch (Exception ex) { ModMain.Log.Warning("Mortality: " + ex.Message); } } public static void ToggleFriendlyFire() { if (!RequireHost("FriendlyFire toggle")) { return; } try { LobbyInfoManager.LobbyInfo.FriendlyFire = !LobbyInfoManager.LobbyInfo.FriendlyFire; Info($"FriendlyFire -> {LobbyInfoManager.LobbyInfo.FriendlyFire}"); } catch (Exception ex) { ModMain.Log.Warning("FriendlyFire: " + ex.Message); } } public static void ToggleKnockout() { if (!RequireHost("Knockout toggle")) { return; } try { LobbyInfoManager.LobbyInfo.Knockout = !LobbyInfoManager.LobbyInfo.Knockout; Info($"Knockout -> {LobbyInfoManager.LobbyInfo.Knockout}"); } catch (Exception ex) { ModMain.Log.Warning("Knockout: " + ex.Message); } } public static void TogglePlayerConstraining() { if (!RequireHost("PlayerConstraining toggle")) { return; } try { LobbyInfoManager.LobbyInfo.PlayerConstraining = !LobbyInfoManager.LobbyInfo.PlayerConstraining; Info($"PlayerConstraining -> {LobbyInfoManager.LobbyInfo.PlayerConstraining}"); } catch (Exception ex) { ModMain.Log.Warning("PlayerConstraining: " + ex.Message); } } public static void CycleMaxPlayers() { if (!RequireHost("MaxPlayers cycle")) { return; } try { int maxPlayers = LobbyInfoManager.LobbyInfo.MaxPlayers; int num = Array.IndexOf(_maxPlayersTable, maxPlayers); int num2 = _maxPlayersTable[(num >= 0) ? ((num + 1) % _maxPlayersTable.Length) : 0]; LobbyInfoManager.LobbyInfo.MaxPlayers = num2; Info($"MaxPlayers -> {num2}"); } catch (Exception ex) { ModMain.Log.Warning("MaxPlayers: " + ex.Message); } } public static void CyclePrivacy() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (!RequireHost("Privacy cycle")) { return; } try { Array values = Enum.GetValues(typeof(ServerPrivacy)); if (values.Length == 0) { Warn("ServerPrivacy has no values."); return; } ServerPrivacy privacy = LobbyInfoManager.LobbyInfo.Privacy; int num = -1; for (int i = 0; i < values.Length; i++) { if (values.GetValue(i).Equals(privacy)) { num = i; break; } } ServerPrivacy val = (ServerPrivacy)values.GetValue((num + 1) % values.Length); LobbyInfoManager.LobbyInfo.Privacy = val; Info($"Privacy -> {val}"); } catch (Exception ex) { ModMain.Log.Warning("Privacy: " + ex.Message); } } public static void CycleTeleportationPermission() { CycleLobbyPermission("Teleportation"); } public static void CycleKickingPermission() { CycleLobbyPermission("Kicking"); } public static void CycleDevToolsPermission() { CycleLobbyPermission("DevTools"); } private static void CycleLobbyPermission(string propName) { if (!RequireHost(propName + " cycle")) { return; } try { LobbyInfo lobbyInfo = LobbyInfoManager.LobbyInfo; PropertyInfo property = ((object)lobbyInfo).GetType().GetProperty(propName); if (property == null) { Warn("LobbyInfo." + propName + " not found."); return; } Type propertyType = property.PropertyType; if (!propertyType.IsEnum) { Warn("LobbyInfo." + propName + " is not an enum."); return; } Array values = Enum.GetValues(propertyType); if (values.Length == 0) { Warn(propertyType.Name + " has no values."); return; } object value = property.GetValue(lobbyInfo); int num = -1; for (int i = 0; i < values.Length; i++) { if (values.GetValue(i).Equals(value)) { num = i; break; } } object value2 = values.GetValue((num + 1) % values.Length); property.SetValue(lobbyInfo, value2); Info($"{propName} -> {value2}"); } catch (Exception ex) { ModMain.Log.Warning(propName + ": " + ex.Message); } } public static void ResetLobbyDefaults() { if (!RequireHost("Lobby reset (vanilla)")) { return; } try { LobbyInfo lobbyInfo = LobbyInfoManager.LobbyInfo; lobbyInfo.NameTags = true; lobbyInfo.Mortality = true; lobbyInfo.FriendlyFire = false; lobbyInfo.Knockout = true; Info("Lobby restored to vanilla defaults."); } catch (Exception ex) { ModMain.Log.Warning("Lobby reset: " + ex.Message); } } public static void ResetLobbySandboxFriendly() { if (!RequireHost("Lobby reset (sandbox)")) { return; } try { LobbyInfo lobbyInfo = LobbyInfoManager.LobbyInfo; lobbyInfo.NameTags = true; lobbyInfo.Mortality = false; lobbyInfo.FriendlyFire = false; lobbyInfo.Knockout = false; Info("Lobby set to sandbox-friendly preset."); } catch (Exception ex) { ModMain.Log.Warning("Lobby reset (sandbox): " + ex.Message); } } public static void ResetLobbyPvP() { if (!RequireHost("Lobby reset (PvP)")) { return; } try { LobbyInfo lobbyInfo = LobbyInfoManager.LobbyInfo; lobbyInfo.NameTags = true; lobbyInfo.Mortality = true; lobbyInfo.FriendlyFire = true; lobbyInfo.Knockout = true; Info("Lobby set to PvP preset."); } catch (Exception ex) { ModMain.Log.Warning("Lobby reset (PvP): " + ex.Message); } } public static void PrintLobbySettings() { //IL_0173: Unknown result type (might be due to invalid IL or missing references) if (!HasServer) { Warn("Not in a lobby."); return; } try { LobbyInfo lobbyInfo = LobbyInfoManager.LobbyInfo; ModMain.Log.Msg("---- Lobby Settings ----"); ModMain.Log.Msg($" NameTags : {lobbyInfo.NameTags}"); ModMain.Log.Msg($" Mortality : {lobbyInfo.Mortality}"); ModMain.Log.Msg($" FriendlyFire : {lobbyInfo.FriendlyFire}"); ModMain.Log.Msg($" Knockout : {lobbyInfo.Knockout}"); TryLogProp(lobbyInfo, "PlayerConstraining"); TryLogProp(lobbyInfo, "Teleportation"); TryLogProp(lobbyInfo, "Kicking"); TryLogProp(lobbyInfo, "DevTools"); ModMain.Log.Msg($" MaxPlayers : {lobbyInfo.MaxPlayers}"); ModMain.Log.Msg($" Privacy : {lobbyInfo.Privacy}"); ModMain.Log.Msg("------------------------"); } catch (Exception ex) { ModMain.Log.Warning("PrintLobbySettings: " + ex.Message); } } public static void PrintFullLobbyInfo() { if (!HasServer) { Warn("Not in a lobby."); return; } try { ModMain.Log.Msg("==== Lobby Info ===="); ModMain.Log.Msg(" Name : " + LobbyName()); ModMain.Log.Msg(" Host Name : " + LobbyHostName()); ModMain.Log.Msg(" Code : " + LobbyCode()); ModMain.Log.Msg(" Level : " + LevelTitle()); ModMain.Log.Msg($" Players : {PlayerCount} / {MaxPlayers()}"); ModMain.Log.Msg(" Privacy : " + PrivacyString()); ModMain.Log.Msg(" Role : " + (IsHost ? "Host" : "Client")); ModMain.Log.Msg("===================="); } catch (Exception ex) { ModMain.Log.Warning("PrintFullLobbyInfo: " + ex.Message); } } private static void TryLogProp(object obj, string propName) { try { PropertyInfo property = obj.GetType().GetProperty(propName); if (!(property == null)) { ModMain.Log.Msg($" {propName,-12} : {property.GetValue(obj)}"); } } catch { } } public static void CloneHeldLeft() { CloneHeld(leftHand: true); } public static void CloneHeldRight() { CloneHeld(leftHand: false); } private static void CloneHeld(bool leftHand) { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) try { Hand val = (leftHand ? Player.LeftHand : Player.RightHand); GameObject objectInHand = Player.GetObjectInHand(val); if ((Object)(object)objectInHand == (Object)null) { Warn("Nothing in " + (leftHand ? "left" : "right") + " hand."); return; } Poolee componentInParent = objectInHand.GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent.SpawnableCrate == (Object)null) { Warn("Held item has no spawnable barcode."); return; } Barcode barcode = ((Scannable)componentInParent.SpawnableCrate).Barcode; string text = ((barcode != null) ? barcode._id : null); if (string.IsNullOrEmpty(text)) { Warn("Spawnable barcode missing."); return; } RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null)) { Vector3 origin = (((Object)(object)val != (Object)null) ? (((Component)val).transform.position + ((Component)val).transform.forward * 0.3f) : (((Component)rigManager).transform.position + ((Component)rigManager).transform.forward * 1f)); SpawnByBarcode(text, origin, ((Object)(object)val != (Object)null) ? ((Component)val).transform.rotation : Quaternion.identity); } } catch (Exception ex) { ModMain.Log.Warning("Clone failed: " + ex.Message); } } private static void SpawnByBarcode(string barcodeId, Vector3 origin, Quaternion rotation) { //IL_0013: 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) NetSpawn.Spawn(barcodeId, origin, rotation, delegate(GameObject inst) { if ((Object)(object)inst != (Object)null) { Stats.BumpClone(); ModMain.Log.Msg("Cloned " + barcodeId + "."); } }); } private static bool RequireHost(string what) { if (!HasServer) { Warn(what + ": not in a lobby."); return false; } if (!IsHost) { Warn(what + ": host only."); return false; } return true; } private static void Info(string msg) { ModMain.Log.Msg("Fusion: " + msg); } private static void Warn(string msg) { ModMain.Log.Warning("Fusion: " + msg); } } public class ObjectScaleData : INetSerializable { public byte SenderSmallId; public ushort EntityId; public Vector3 Scale; public int? GetSize() { return 15; } public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref SenderSmallId); serializer.SerializeValue(ref EntityId); NetSerializerUnityExtensions.SerializeValue(serializer, ref Scale); } public static ObjectScaleData Create(byte sender, ushort entityId, Vector3 scale) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) return new ObjectScaleData { SenderSmallId = sender, EntityId = entityId, Scale = scale }; } } public class ObjectScaleHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) try { ObjectScaleData objectScaleData = ((ReceivedMessage)(ref received)).ReadData(); if (objectScaleData == null || (((ReceivedMessage)(ref received)).Sender.HasValue && objectScaleData.SenderSmallId != ((ReceivedMessage)(ref received)).Sender.Value)) { return; } NetworkEntityReference val = default(NetworkEntityReference); ((NetworkEntityReference)(ref val))..ctor(objectScaleData.EntityId); NetworkEntity val2 = default(NetworkEntity); if (((NetworkEntityReference)(ref val)).TryGetEntity(ref val2) && val2 != null) { IMarrowEntityExtender extender = val2.GetExtender(); MarrowEntity val3 = ((extender != null) ? extender.MarrowEntity : null); if (!((Object)(object)val3 == (Object)null)) { ((Component)val3).transform.localScale = objectScaleData.Scale; } } } catch (Exception ex) { ModMain.Log.Warning("ObjectScale handler failed: " + ex.Message); } } } public class QualityLabFusionModule : Module { public override string Name => "Quality Of Lab"; public override string Author => "Dynamic Team"; public override Version Version => new Version(1, 0, 1); protected override void OnModuleRegistered() { ModuleMessageManager.RegisterHandler(); ModMain.Log.Msg("Quality Of Lab: Fusion module registered (object scale sync)."); } } public static class FusionScaleSync { public static bool Online { get { try { return NetworkInfo.HasServer; } catch { return false; } } } public static bool TryResolve(GameObject go, out MarrowEntity marrow, out ushort entityId) { marrow = null; entityId = 0; if ((Object)(object)go == (Object)null) { return false; } try { marrow = go.GetComponentInParent(); if ((Object)(object)marrow == (Object)null) { return false; } NetworkEntity val = default(NetworkEntity); if (!IMarrowEntityExtender.Cache.TryGet(marrow, ref val) || val == null) { return false; } entityId = val.ID; return true; } catch { return false; } } public static void BroadcastObjectScale(GameObject go) { //IL_0023: 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) try { if (Online && TryResolve(go, out var marrow, out var entityId)) { MessageRelay.RelayModule(ObjectScaleData.Create(PlayerIDManager.LocalSmallID, entityId, ((Component)marrow).transform.localScale), CommonMessageRoutes.ReliableToOtherClients); } } catch (Exception ex) { ModMain.Log.Warning("ObjectScale broadcast failed: " + ex.Message); } } } public static class GodMode { public static void Tick() { if (!Settings.GodMode.Value) { return; } RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null)) { Health health = rigManager.health; Player_Health val = ((health != null) ? ((Il2CppObjectBase)health).TryCast() : null); if (!((Object)(object)val == (Object)null) && ((Health)val).curr_Health < ((Health)val).max_Health) { ((Health)val).curr_Health = ((Health)val).max_Health; } } } } [HarmonyPatch(typeof(Player_Health), "TAKEDAMAGE", new Type[] { typeof(float) })] public static class GodMode_TakeDamage_Patch { public static bool Prefix() { return !Settings.GodMode.Value; } } public static class Helpers { public static void Identify() { string text = Inspect(Player.LeftHand, "Left"); string text2 = Inspect(Player.RightHand, "Right"); Notifications.Severity sev = Notifications.Severity.Info; string body; if (text != null || text2 != null) { body = ((text == null || text2 == null) ? ((text != null) ? ("Left: " + text) : ("Right: " + text2)) : ("L: " + text + "\nR: " + text2)); } else { body = "Hands are empty."; sev = Notifications.Severity.Warning; } Notifications.Popup("Item Perception", body, sev, 3.5f); Stats.BumpIdentify(); } private static string Inspect(Hand hand, string label) { if ((Object)(object)hand == (Object)null) { return null; } GameObject objectInHand = Player.GetObjectInHand(hand); if ((Object)(object)objectInHand == (Object)null) { ModMain.Log.Msg(label + " hand: empty."); return null; } string text = "?"; string text2 = "?"; try { Poolee componentInParent = objectInHand.GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.SpawnableCrate != (Object)null) { SpawnableCrate spawnableCrate = componentInParent.SpawnableCrate; try { text = ((Scannable)spawnableCrate).Title ?? text; } catch { } try { Barcode barcode = ((Scannable)spawnableCrate).Barcode; text2 = ((barcode != null) ? barcode._id : null) ?? text2; } catch { } } } catch { } string text3 = ((Object)objectInHand).name ?? "?"; ModMain.Log.Msg($"{label} hand: {text} [{text2}] (obj: {text3})"); if (!(text != "?")) { return text3; } return text; } public static void DespawnNearestNpc() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { return; } Vector3 position = ((Component)rigManager).transform.position; float num = 900f; AIBrain val = null; Il2CppArrayBase val2 = Object.FindObjectsOfType(); for (int i = 0; i < val2.Length; i++) { AIBrain val3 = val2[i]; if (!((Object)(object)val3 == (Object)null)) { Vector3 position2; try { position2 = ((Component)val3).transform.position; } catch { continue; } Vector3 val4 = position2 - position; float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; val = val3; } } } if ((Object)(object)val == (Object)null) { Hud.Flash("No NPC nearby", 1.5f); return; } try { Poolee componentInParent = ((Component)val).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { componentInParent.Despawn(); ModMain.Log.Msg($"Despawned NPC at {Mathf.Sqrt(num):F1}m."); } else { ModMain.Log.Warning("NPC has no Poolee to despawn."); } } catch (Exception ex) { ModMain.Log.Warning("Despawn failed: " + ex.Message); } } public static void KillAllNpcsInRange(float range = 30f) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { return; } Vector3 position = ((Component)rigManager).transform.position; float num = range * range; int num2 = 0; Il2CppArrayBase val = Object.FindObjectsOfType(); for (int i = 0; i < val.Length; i++) { AIBrain val2 = val[i]; if ((Object)(object)val2 == (Object)null) { continue; } Vector3 position2; try { position2 = ((Component)val2).transform.position; } catch { continue; } Vector3 val3 = position2 - position; if (((Vector3)(ref val3)).sqrMagnitude > num) { continue; } try { BehaviourBaseNav behaviour = val2.behaviour; SubBehaviourHealth val4 = (((Object)(object)behaviour != (Object)null) ? behaviour.health : null); if (val4 != null) { val4.Kill(); num2++; } } catch { } } ModMain.Log.Msg($"Kill All: {num2} NPC(s) within {range:F0}m."); Notifications.Success($"Killed {num2} NPC(s)."); } public static void DespawnAllNpcsInRange(float range = 30f) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { return; } Vector3 position = ((Component)rigManager).transform.position; float num = range * range; int num2 = 0; Il2CppArrayBase val = Object.FindObjectsOfType(); for (int i = 0; i < val.Length; i++) { AIBrain val2 = val[i]; if ((Object)(object)val2 == (Object)null) { continue; } Vector3 position2; try { position2 = ((Component)val2).transform.position; } catch { continue; } Vector3 val3 = position2 - position; if (((Vector3)(ref val3)).sqrMagnitude > num) { continue; } try { Poolee componentInParent = ((Component)val2).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { componentInParent.Despawn(); num2++; } } catch { } } ModMain.Log.Msg($"Despawn All: {num2} NPC(s) within {range:F0}m."); Notifications.Success($"Despawned {num2} NPC(s)."); } public static void PullObjectToHand() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_003d: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: 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_0194: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) Hand rightHand = Player.RightHand; Transform head = Player.Head; if ((Object)(object)rightHand == (Object)null || (Object)(object)head == (Object)null) { return; } Vector3 position = ((Component)head).transform.position; Vector3 forward = ((Component)head).transform.forward; Vector3 position2 = ((Component)rightHand).transform.position; Rigidbody val = null; float num = float.MaxValue; Il2CppReferenceArray val2 = Physics.OverlapSphere(position + forward * 3f, 5f, -1, (QueryTriggerInteraction)1); for (int i = 0; i < ((Il2CppArrayBase)(object)val2).Length; i++) { Collider val3 = ((Il2CppArrayBase)(object)val2)[i]; if ((Object)(object)val3 == (Object)null) { continue; } Rigidbody attachedRigidbody = val3.attachedRigidbody; if ((Object)(object)attachedRigidbody == (Object)null || attachedRigidbody.isKinematic) { continue; } int layer = ((Component)attachedRigidbody).gameObject.layer; if (layer == 13 || layer == 17 || (Object)(object)((Component)attachedRigidbody).GetComponentInParent() != (Object)null) { continue; } Vector3 val4 = attachedRigidbody.worldCenterOfMass - position; float num2 = Vector3.Dot(((Vector3)(ref val4)).normalized, forward); if (!(num2 < 0.3f)) { float num3 = ((Vector3)(ref val4)).magnitude - num2 * 2f; if (num3 < num) { num = num3; val = attachedRigidbody; } } } if ((Object)(object)val == (Object)null) { Hud.Flash("Nothing to pull", 1.2f); return; } Vector3 val5 = position2 - val.worldCenterOfMass; float magnitude = ((Vector3)(ref val5)).magnitude; if (!(magnitude < 0.05f)) { Vector3 val6 = val5 / magnitude; float num4 = Mathf.Clamp(magnitude * 3.5f, 5f, 25f); val.velocity = val6 * num4; ModMain.Log.Msg($"Pulled {((Object)val).name} ({magnitude:F1}m)."); } } public static void PrintSettingsSnapshot() { try { ModMain.Log.Msg("---- Quality Of Lab settings ----"); ModMain.Log.Msg($" God Mode: {Settings.GodMode.Value}"); ModMain.Log.Msg($" Auto-Heal: {Settings.AutoHeal.Value} @ {Settings.AutoHealThreshold.Value:F2}"); ModMain.Log.Msg($" Damage Mult: {Settings.DamageMultiplier.Value:F2}"); ModMain.Log.Msg($" Damage Resist: {Settings.DamageResistance.Value:F2}"); ModMain.Log.Msg($" One-Hit Kill: {Settings.OneHitKill.Value}"); ModMain.Log.Msg($" Infinite Ammo: {Settings.InfiniteAmmo.Value}"); ModMain.Log.Msg($" Jump Mult: {Settings.JumpMultiplier.Value:F2}"); ModMain.Log.Msg($" Gravity Y: {Settings.GravityY.Value:F2}"); ModMain.Log.Msg($" Ragdoll Force: {Settings.RagdollForceMul.Value:F2}"); ModMain.Log.Msg($" Explosion Mult: {Settings.ExplosionForceMul.Value:F2}"); ModMain.Log.Msg($" NPC Scale: {Settings.NpcScale.Value:F2}"); ModMain.Log.Msg($" Avatar Scale: {Settings.AvatarScale.Value:F2}"); ModMain.Log.Msg($" Object Scale: {Settings.ObjectScale.Value:F2}"); ModMain.Log.Msg($" Scale on Pickup: {Settings.ScaleOnPickup.Value}"); ModMain.Log.Msg($" Auto Perception: {Settings.AutoPerception.Value}"); ModMain.Log.Msg($" Crosshair: {Settings.Crosshair.Value}"); ModMain.Log.Msg($" Stats Overlay: {Settings.StatsOverlay.Value}"); ModMain.Log.Msg($" Lobby Info: {Settings.ShowLobbyInfo.Value}"); ModMain.Log.Msg($" Keep Inventory: Between={Settings.KeepBetweenLevels.Value} Startup={Settings.KeepOnStartup.Value} Slot={Settings.SelectedSlot.Value}"); ModMain.Log.Msg($" Strip Holsters: {Settings.StripEmptyHolsters.Value}"); ModMain.Log.Msg($" Auto-Save Lvl: {Settings.AutoSaveOnLevelEnd.Value}"); for (int i = 0; i < 4; i++) { int value = Settings.HotkeyTrigger[i].Value; int value2 = Settings.HotkeyAction[i].Value; ModMain.Log.Msg($" Hotkey {i + 1}: trig={value} ({Hotkeys.TriggerName(value)}) act={value2} ({Hotkeys.ActionName(value2)})"); } ModMain.Log.Msg("---- end snapshot ----"); } catch (Exception ex) { ModMain.Log.Warning("Snapshot failed: " + ex.Message); } } public static void PanicResetAll() { try { Settings.AutoHeal.Value = false; Settings.InfiniteAmmo.Value = false; Settings.OneHitKill.Value = false; Settings.GodMode.Value = false; Settings.AutoPerception.Value = false; Settings.ScaleOnPickup.Value = false; Settings.GravityY.Value = -9.81f; Settings.JumpMultiplier.Value = 1f; Settings.DamageMultiplier.Value = 1f; Settings.DamageResistance.Value = 0f; Settings.RagdollForceMul.Value = 1f; Settings.ExplosionForceMul.Value = 1f; Settings.TimeScaleActive.Value = false; Settings.TimeScale.Value = 1f; try { Time.timeScale = 1f; } catch { } Settings.Save(); Notifications.Success("Panic Stop: all mod effects disabled."); ModMain.Log.Msg("Quality Of Lab: panic reset complete."); } catch (Exception ex) { Notifications.Error("Panic reset failed: " + ex.Message); } } } public static class HolsterHider { private class Group { public Transform Root; public Vector3 OriginalScale; public MeshRenderer[] Renderers; public bool Cached; } public const int GroupCount = 8; public static readonly string[] GroupNames; private static readonly Group[] _groups; static HolsterHider() { GroupNames = new string[8] { "Head", "Right Shoulder", "Left Shoulder", "Right Underarm", "Left Underarm", "Back", "Ammo Pouch", "BodyLog" }; _groups = new Group[8]; for (int i = 0; i < 8; i++) { _groups[i] = new Group(); } } public static string VisibilityName(int v) { return v switch { 0 => "Default", 1 => "Invisible", 2 => "Disabled", _ => "?", }; } public static void OnLevelLoaded() { for (int i = 0; i < 8; i++) { _groups[i].Cached = false; } MelonCoroutines.Start(CacheRetryRoutine()); } private static IEnumerator CacheRetryRoutine() { yield return (object)new WaitForSeconds(1.25f); for (int attempt = 1; attempt <= 6; attempt++) { bool flag = false; try { CacheReferences(); flag = AnyCached(); if (flag) { ApplyAll(); } } catch (Exception ex) { ModMain.Log.Warning($"HolsterHider cache attempt {attempt}: {ex.Message}"); } if (flag) { yield break; } yield return (object)new WaitForSeconds(1f); } ModMain.Log.Warning("HolsterHider: gave up caching after 6 attempts."); } private static bool AnyCached() { for (int i = 0; i < 8; i++) { if (_groups[i].Cached) { return true; } } return false; } public static void CacheReferences() { RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.inventory == (Object)null || (Object)(object)rigManager.physicsRig == (Object)null) { return; } Il2CppReferenceArray bodySlots = rigManager.inventory.bodySlots; try { InventorySlotReceiver componentInChildren = ((Component)((Rig)rigManager.physicsRig).m_head).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { CacheSlotReceiver(0, componentInChildren); } } catch { } CacheSlotContainer(1, ((Il2CppArrayBase)(object)bodySlots)[3]); CacheSlotContainer(2, ((Il2CppArrayBase)(object)bodySlots)[2]); CacheSlotContainer(3, ((Il2CppArrayBase)(object)bodySlots)[5]); CacheSlotContainer(4, ((Il2CppArrayBase)(object)bodySlots)[0]); CacheSlotContainer(5, ((Il2CppArrayBase)(object)bodySlots)[4]); try { InventoryAmmoReceiver componentInChildren2 = ((Component)rigManager).GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null) { CacheAmmoReceiver(6, componentInChildren2); } } catch { } try { if (rigManager.inventory.specialItems != null && ((Il2CppArrayBase)(object)rigManager.inventory.specialItems).Count > 0) { PullCordDevice componentInChildren3 = ((Component)((Il2CppArrayBase)(object)rigManager.inventory.specialItems)[0]).GetComponentInChildren(true); if ((Object)(object)componentInChildren3 != (Object)null) { CachePullCord(7, componentInChildren3); } } } catch { } } private static void CacheSlotContainer(int idx, SlotContainer slot) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)slot == (Object)null)) { Transform transform = ((Component)slot).transform; _groups[idx].Root = transform; _groups[idx].OriginalScale = transform.localScale; _groups[idx].Renderers = Il2CppArrayBase.op_Implicit(((Component)transform).GetComponentsInChildren(true)); _groups[idx].Cached = true; } } private static void CacheSlotReceiver(int idx, InventorySlotReceiver recv) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)recv == (Object)null)) { Transform parent = ((Component)recv).transform.parent; if (!((Object)(object)parent == (Object)null)) { _groups[idx].Root = parent; _groups[idx].OriginalScale = parent.localScale; _groups[idx].Renderers = Il2CppArrayBase.op_Implicit(((Component)parent).GetComponentsInChildren(true)); _groups[idx].Cached = true; } } } private static void CacheAmmoReceiver(int idx, InventoryAmmoReceiver recv) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)recv == (Object)null)) { Transform parent = ((Component)recv).transform.parent; if (!((Object)(object)parent == (Object)null)) { _groups[idx].Root = parent; _groups[idx].OriginalScale = parent.localScale; _groups[idx].Renderers = Il2CppArrayBase.op_Implicit(((Component)parent).GetComponentsInChildren(true)); _groups[idx].Cached = true; } } } private static void CachePullCord(int idx, PullCordDevice pullCord) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)pullCord == (Object)null)) { Transform transform = ((Component)pullCord).transform; _groups[idx].Root = transform; _groups[idx].OriginalScale = transform.localScale; Transform val = transform.Find("BodyLog"); _groups[idx].Renderers = Il2CppArrayBase.op_Implicit(((Object)(object)val != (Object)null) ? ((Component)val).GetComponentsInChildren(true) : ((Component)transform).GetComponentsInChildren(true)); _groups[idx].Cached = true; } } public static void ApplyAll() { for (int i = 0; i < 8; i++) { ApplyOne(i, Settings.HolsterVisibility[i].Value); } } public static void Set(int idx, int visibility) { if (idx >= 0 && idx < 8) { visibility = Mathf.Clamp(visibility, 0, 2); Settings.HolsterVisibility[idx].Value = visibility; Settings.Save(); ApplyOne(idx, visibility); ModMain.Log.Msg($"Holster '{GroupNames[idx]}' -> {VisibilityName(visibility)}."); } } private static void ApplyOne(int idx, int visibility) { Group obj = _groups[idx]; if (!obj.Cached || (Object)(object)obj.Root == (Object)null) { return; } switch (visibility) { case 1: { ((Component)obj.Root).gameObject.SetActive(true); if (obj.Renderers == null) { return; } for (int i = 0; i < obj.Renderers.Length; i++) { if ((Object)(object)obj.Renderers[i] != (Object)null) { ((Renderer)obj.Renderers[i]).enabled = false; } } return; } case 2: ((Component)obj.Root).gameObject.SetActive(false); return; } ((Component)obj.Root).gameObject.SetActive(true); if (obj.Renderers == null) { return; } for (int j = 0; j < obj.Renderers.Length; j++) { if ((Object)(object)obj.Renderers[j] != (Object)null) { ((Renderer)obj.Renderers[j]).enabled = true; } } } public static void ResetAll() { for (int i = 0; i < 8; i++) { Settings.HolsterVisibility[i].Value = 0; } Settings.Save(); ApplyAll(); ModMain.Log.Msg("All holsters reset to Default."); } public static void HideAll() { for (int i = 0; i < 8; i++) { Settings.HolsterVisibility[i].Value = 1; } Settings.Save(); ApplyAll(); ModMain.Log.Msg("All holsters set to Invisible."); } } public enum HotkeyTriggerKind { Off, LeftThumbClick, RightThumbClick, LeftAB_Hold, RightAB_Hold } public enum HotkeyActionKind { None = 0, ToggleGodMode = 1, SaveCurrentSlot = 4, ApplyCurrentSlot = 5, ResetAvatarScale = 6, ToggleOneHitKill = 7, ToggleInfiniteAmmo = 8, TeleportToReticle = 9, SaveMarker = 10, TeleportToMarker = 11, TopUpHealth = 14, TopUpAmmo = 15, StopVelocity = 16, QuickRespawn = 17, ExplodeReticle = 18, PushNpcsAway = 19, TeleportToHost = 20, CloneHeldLeft = 21, CloneHeldRight = 22, IdentifyHeld = 23, SpawnLastHeld = 24, MagicReload = 25, FreezeHeld = 26, UnfreezeAll = 27, RandomAvatar = 28, ResetAvatar = 29, TakeScreenshot = 30, RejoinLastLobby = 36, PanicStop = 38, ToggleFreecam = 39, PhotoCountdown = 44, PhotoBurst = 45, ToggleSlowMo = 48, RestoreTimeScale = 49, SaveCheckpoint1 = 50, LoadCheckpoint1 = 51, SaveCheckpoint2 = 52, LoadCheckpoint2 = 53 } public static class Hotkeys { public const int TriggerCount = 5; public const int ActionCount = 58; private static readonly float[] _heldSince = new float[5]; private static readonly float[] _lockoutAt = new float[5]; private static readonly bool[] _prevDown = new bool[5]; private const float ChordHoldSeconds = 0.5f; private const float ChordLockoutSeconds = 1f; public static string TriggerName(int code) { return code switch { 0 => "Off", 1 => "L Thumb Click", 2 => "R Thumb Click", 3 => "L A+B (hold 0.5s)", 4 => "R A+B (hold 0.5s)", _ => "?", }; } public static string ActionName(int code) { return code switch { 0 => "None", 1 => "Toggle God Mode", 4 => "Save Current Slot", 5 => "Apply Current Slot", 6 => "Reset Avatar Scale", 7 => "Toggle One-Hit Kill", 8 => "Toggle Infinite Ammo", 9 => "Teleport to Reticle", 10 => "Save Position Marker", 11 => "Teleport to Marker", 14 => "Top Up Health", 15 => "Top Up Ammo", 16 => "Stop Velocity", 17 => "Quick Respawn", 18 => "Explode at Reticle", 19 => "Push NPCs Away", 20 => "Teleport to Host", 21 => "Clone Held Left", 22 => "Clone Held Right", 23 => "Identify Held Item", 24 => "Spawn Last Held", 25 => "Magic Reload", 26 => "Freeze Held Object", 27 => "Unfreeze All", 28 => "Random Vanilla Avatar", 29 => "Reset Avatar", 30 => "Take Screenshot", 36 => "Rejoin Last Lobby", 38 => "Panic Stop (kill effects)", 39 => "Toggle Freecam", 44 => "Photo Countdown", 45 => "Photo Burst", 48 => "Toggle Slow-Mo", 49 => "Restore Time Scale (1x)", 50 => "Save Checkpoint 1", 51 => "Restore Checkpoint 1", 52 => "Save Checkpoint 2", 53 => "Restore Checkpoint 2", _ => "?", }; } public static void Tick() { BaseController leftController = Player.LeftController; BaseController rightController = Player.RightController; if ((Object)(object)leftController == (Object)null && (Object)(object)rightController == (Object)null) { return; } for (int i = 0; i < 4; i++) { int value = Settings.HotkeyTrigger[i].Value; int value2 = Settings.HotkeyAction[i].Value; if (value != 0 && value2 != 0 && CheckTrigger(value, leftController, rightController)) { Execute(value2); } } } private static bool CheckTrigger(int code, BaseController l, BaseController r) { return code switch { 1 => EdgeDown(code, (Object)(object)l != (Object)null && l.GetThumbStickDown()), 2 => EdgeDown(code, (Object)(object)r != (Object)null && r.GetThumbStickDown()), 3 => ChordHeld(code, (Object)(object)l != (Object)null && l.GetAButton() && l.GetBButton()), 4 => ChordHeld(code, (Object)(object)r != (Object)null && r.GetAButton() && r.GetBButton()), _ => false, }; } private static bool EdgeDown(int code, bool isDown) { bool flag = _prevDown[code]; _prevDown[code] = isDown; if (isDown) { return !flag; } return false; } private static bool ChordHeld(int code, bool isHeld) { float unscaledTime = Time.unscaledTime; if (unscaledTime < _lockoutAt[code]) { if (!isHeld) { _heldSince[code] = 0f; } return false; } if (!isHeld) { _heldSince[code] = 0f; return false; } if (_heldSince[code] <= 0f) { _heldSince[code] = unscaledTime; } if (unscaledTime - _heldSince[code] >= 0.5f) { _lockoutAt[code] = unscaledTime + 1f; _heldSince[code] = 0f; return true; } return false; } private static void Execute(int action) { switch (action) { case 1: Settings.GodMode.Value = !Settings.GodMode.Value; ModMain.Log.Msg($"Hotkey: God Mode -> {Settings.GodMode.Value}"); break; case 4: KeepInventory.SaveCurrent(); break; case 5: KeepInventory.ApplyCurrent(); break; case 6: Settings.AvatarScale.Value = 1f; AvatarScaling.Reset(); Settings.Save(); ModMain.Log.Msg("Hotkey: Avatar Scale reset."); break; case 7: Settings.OneHitKill.Value = !Settings.OneHitKill.Value; Settings.Save(); ModMain.Log.Msg($"Hotkey: One-Hit Kill -> {Settings.OneHitKill.Value}"); break; case 8: Settings.InfiniteAmmo.Value = !Settings.InfiniteAmmo.Value; Settings.Save(); ModMain.Log.Msg($"Hotkey: Infinite Ammo -> {Settings.InfiniteAmmo.Value}"); break; case 9: Movement.TeleportToReticle(); break; case 10: Movement.SavePositionMarker(); break; case 11: Movement.TeleportToMarker(); break; case 14: Combat.TopUpHealth(); break; case 15: Combat.TopUpAmmoOnce(); break; case 16: Movement.StopVelocity(); break; case 17: Movement.QuickRespawn(); break; case 18: World.ExplodeAtReticle(); break; case 19: World.PushAllNpcsAway(); break; case 20: Fusion.TeleportToHost(); break; case 21: Fusion.CloneHeldLeft(); break; case 22: Fusion.CloneHeldRight(); break; case 23: Helpers.Identify(); break; case 24: Spawning.SpawnLastHeld(); break; case 25: Combat.MagicReload(); break; case 26: ObjectScaling.FreezeHeld(); break; case 27: ObjectScaling.UnfreezeAll(); break; case 28: Avatars.RandomVanilla(); break; case 29: Avatars.ResetToDefault(); break; case 30: Photo.TakeScreenshot(); break; case 36: ServerBrowser.RejoinLast(); break; case 38: Helpers.PanicResetAll(); break; case 39: Freecam.Toggle(); break; case 44: Photo.StartCountdown(Settings.PhotoCountdownSecs.Value); break; case 45: Photo.StartBurst(Settings.PhotoBurstCount.Value); break; case 48: TimeScale.ToggleSlowMo(); break; case 49: TimeScale.Restore(); break; case 50: Checkpoints.Save(0); break; case 51: Checkpoints.Restore(0); break; case 52: Checkpoints.Save(1); break; case 53: Checkpoints.Restore(1); break; case 2: case 3: case 12: case 13: case 31: case 32: case 33: case 34: case 35: case 37: case 40: case 41: case 42: case 43: case 46: case 47: break; } } } public static class Hud { private static float _smoothedFps; private const float FpsSmoothing = 0.92f; private static Vector3 _lastHeadPos; private static bool _lastHeadValid; private static string _flashText; private static float _flashUntil; private static readonly GUIStyle _style; private static readonly GUIStyle _crosshairStyle; private static readonly GUIStyle _flashStyle; private static readonly GUIStyle _flashShadow; public static void Tick() { float unscaledDeltaTime = Time.unscaledDeltaTime; if (unscaledDeltaTime > 0f) { float num = 1f / unscaledDeltaTime; _smoothedFps = _smoothedFps * 0.92f + num * 0.07999998f; } } public static void OnLevelLoaded() { _lastHeadValid = false; } public static void Flash(string text, float seconds = 3f) { _flashText = text ?? ""; _flashUntil = Time.unscaledTime + Mathf.Max(0.5f, seconds); } public static void OnGUI() { //IL_0031: 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_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_025f: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_019d: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) DrawCrosshair(); DrawFlash(); if (!Settings.StatsOverlay.Value) { return; } float num = 16f; float num2 = 16f; float num3 = 22f; GUI.Label(new Rect(num, num2, 600f, num3), $"FPS {_smoothedFps:F0}", _style); num2 += num3; Transform head = Player.Head; if ((Object)(object)head != (Object)null) { Vector3 position = ((Component)head).transform.position; Vector3 val = Vector3.zero; if (_lastHeadValid && Time.unscaledDeltaTime > 0f) { val = (position - _lastHeadPos) / Time.unscaledDeltaTime; } _lastHeadPos = position; _lastHeadValid = true; GUI.Label(new Rect(num, num2, 600f, num3), $"Pos {position.x:F1}, {position.y:F1}, {position.z:F1}", _style); num2 += num3; GUI.Label(new Rect(num, num2, 600f, num3), $"Speed {((Vector3)(ref val)).magnitude:F1} m/s Vy {val.y:+0.0;-0.0;0.0}", _style); num2 += num3; } GUI.Label(new Rect(num, num2, 600f, num3), $"Gravity {Physics.gravity.y:F1}", _style); num2 += num3; if (Settings.ShowLobbyInfo.Value) { string text = "Offline"; try { text = Fusion.LobbySummary(); } catch { } GUI.Label(new Rect(num, num2, 600f, num3), "Lobby " + text, _style); num2 += num3; } GUI.Label(new Rect(num, num2, 900f, num3), Stats.FormatSummary(), _style); num2 += num3; } private static void DrawCrosshair() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (Settings.Crosshair.Value) { float num = (float)Screen.width * 0.5f; float num2 = (float)Screen.height * 0.5f; GUI.Label(new Rect(num - 20f, num2 - 20f, 40f, 40f), "+", _crosshairStyle); } } public static void DrawFlash() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(_flashText)) { if (Time.unscaledTime > _flashUntil) { _flashText = null; return; } float num = Mathf.Min(700f, (float)Screen.width * 0.6f); float num2 = 90f; float num3 = ((float)Screen.width - num) * 0.5f; float num4 = (float)Screen.height * 0.18f; GUI.Label(new Rect(num3 + 2f, num4 + 2f, num, num2), _flashText, _flashShadow); GUI.Label(new Rect(num3, num4, num, num2), _flashText, _flashStyle); } } static Hud() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown GUIStyle val = new GUIStyle { fontSize = 18 }; val.normal.textColor = Color.white; val.richText = true; _style = val; GUIStyle val2 = new GUIStyle { fontSize = 26, alignment = (TextAnchor)4 }; val2.normal.textColor = new Color(1f, 1f, 1f, 0.85f); val2.richText = true; _crosshairStyle = val2; GUIStyle val3 = new GUIStyle { fontSize = 22, alignment = (TextAnchor)4 }; val3.normal.textColor = new Color(1f, 0.95f, 0.6f, 1f); val3.richText = true; val3.wordWrap = true; _flashStyle = val3; GUIStyle val4 = new GUIStyle { fontSize = 22, alignment = (TextAnchor)4 }; val4.normal.textColor = new Color(0f, 0f, 0f, 0.85f); val4.richText = true; val4.wordWrap = true; _flashShadow = val4; } } public static class KeepInventory { private static bool _firstLoadDone; public static int CurrentSlot() { int num = Settings.SelectedSlot.Value; if (num < 1) { num = 1; } if (num > 5) { num = 5; } return num; } public static string GetSlotName(int slot) { int num = slot - 1; if (num < 0 || num >= 5) { return $"Slot {slot}"; } return Settings.SlotName[num].Value ?? $"Slot {slot}"; } public static bool SlotHasData(int slot) { int num = slot - 1; if (num < 0 || num >= 5) { return false; } return !string.IsNullOrEmpty(Settings.SlotData[num].Value); } public static void SetSlotName(int slot, string name) { int num = slot - 1; if (num >= 0 && num < 5) { Settings.SlotName[num].Value = (string.IsNullOrWhiteSpace(name) ? $"Slot {slot}" : name); Settings.Save(); } } public static void SaveCurrent() { SaveTo(CurrentSlot()); } public static void SaveTo(int slot) { int num = slot - 1; if (num < 0 || num >= 5) { return; } try { RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.inventory == (Object)null) { ModMain.Log.Warning("Keep Inventory: no rig — load into a level first."); return; } List list = new List(); Il2CppReferenceArray bodySlots = rigManager.inventory.bodySlots; for (int i = 0; i < ((Il2CppArrayBase)(object)bodySlots).Count; i++) { SlotContainer val = ((Il2CppArrayBase)(object)bodySlots)[i]; if ((Object)(object)val == (Object)null) { continue; } InventorySlotReceiver componentInChildren = ((Component)val).GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { continue; } IGrippable weaponHost = componentInChildren._weaponHost; if (weaponHost == null) { continue; } GameObject hostGameObject = weaponHost.GetHostGameObject(); if ((Object)(object)hostGameObject == (Object)null) { continue; } Poolee componentInParent = hostGameObject.GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.SpawnableCrate == (Object)null)) { Barcode barcode = ((Scannable)componentInParent.SpawnableCrate).Barcode; string text = ((barcode != null) ? barcode._id : null); if (!string.IsNullOrEmpty(text)) { list.Add(((Object)val).name + "|" + text); } } } Settings.SlotData[num].Value = string.Join(";", list); Settings.Save(); ModMain.Log.Msg($"Keep Inventory: saved {list.Count} item(s) to {GetSlotName(slot)}."); } catch (Exception value) { ModMain.Log.Error($"Keep Inventory save failed: {value}"); } } public static void ClearCurrent() { ClearSlot(CurrentSlot()); } public static void ClearSlot(int slot) { int num = slot - 1; if (num >= 0 && num < 5) { Settings.SlotData[num].Value = ""; Settings.Save(); ModMain.Log.Msg("Keep Inventory: cleared " + GetSlotName(slot) + "."); } } public static void OnLevelLoaded(LevelInfo info) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (Settings.PerLevelLoadouts.Value) { string barcode = info.barcode; int num = SlotForLevel(barcode); if (num > 0) { Settings.SelectedSlot.Value = num; Settings.Save(); ModMain.Log.Msg($"Per-level: switched to slot {num} for {barcode}"); } } bool flag = false; if (Settings.KeepBetweenLevels.Value) { flag = true; } else if (Settings.KeepOnStartup.Value && !_firstLoadDone) { flag = true; } _firstLoadDone = true; if (flag) { int slot = CurrentSlot(); if (SlotHasData(slot)) { MelonCoroutines.Start(ApplyAfterDelay(1.25f, slot)); } } } public static int SlotForLevel(string levelBarcode) { if (string.IsNullOrEmpty(levelBarcode)) { return 0; } string value = Settings.LevelSlotMap.Value; if (string.IsNullOrEmpty(value)) { return 0; } string[] array = value.Split(';'); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { string[] array2 = text.Split(':'); if (array2.Length == 2 && array2[0] == levelBarcode && int.TryParse(array2[1], out var result)) { return result; } } } return 0; } public static void BindCurrentLevelToCurrentSlot() { if ((Object)(object)Player.RigManager == (Object)null) { ModMain.Log.Warning("Need to be in a level first."); return; } string text = null; try { StreamSession session = SceneStreamer.Session; object obj; if (session == null) { obj = null; } else { LevelCrate level = session.Level; if (level == null) { obj = null; } else { Barcode barcode = ((Scannable)level).Barcode; obj = ((barcode != null) ? barcode._id : null); } } text = (string)obj; } catch { } if (string.IsNullOrEmpty(text)) { ModMain.Log.Warning("Couldn't read current level barcode."); return; } int num = CurrentSlot(); UpdateMapping(text, num); ModMain.Log.Msg($"Bound slot {num} to current level: {text}."); } public static void ClearPerLevelBindings() { Settings.LevelSlotMap.Value = ""; Settings.Save(); ModMain.Log.Msg("Per-level bindings cleared."); } private static void UpdateMapping(string levelBarcode, int slot) { string obj = Settings.LevelSlotMap.Value ?? ""; List list = new List(); string[] array = obj.Split(';'); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { string[] array2 = text.Split(':'); if (array2.Length != 2 || !(array2[0] == levelBarcode)) { list.Add(text); } } } list.Add($"{levelBarcode}:{slot}"); Settings.LevelSlotMap.Value = string.Join(";", list); Settings.Save(); } public static void OnLevelUnloaded() { if (Settings.AutoSaveOnLevelEnd.Value) { SaveCurrent(); } } private static IEnumerator ApplyAfterDelay(float seconds, int slot) { yield return (object)new WaitForSeconds(seconds); ApplySlot(slot); } public static void ApplyCurrent() { ApplySlot(CurrentSlot()); } public static void ApplySlot(int slot) { //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown int num = slot - 1; if (num < 0 || num >= 5) { return; } try { RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.inventory == (Object)null) { return; } Il2CppReferenceArray bodySlots = rigManager.inventory.bodySlots; string value = Settings.SlotData[num].Value; if (string.IsNullOrEmpty(value)) { return; } if (Settings.StripEmptyHolsters.Value) { for (int i = 0; i < ((Il2CppArrayBase)(object)bodySlots).Count; i++) { SlotContainer val = ((Il2CppArrayBase)(object)bodySlots)[i]; if ((Object)(object)val == (Object)null) { continue; } InventorySlotReceiver componentInChildren = ((Component)val).GetComponentInChildren(); try { if (componentInChildren != null) { componentInChildren.DestroyContents(); } } catch { } } } int num2 = 0; string[] array = value.Split(';'); foreach (string text in array) { if (string.IsNullOrEmpty(text)) { continue; } string[] array2 = text.Split('|'); if (array2.Length != 2) { continue; } string text2 = array2[0]; string text3 = array2[1]; SlotContainer val2 = null; for (int k = 0; k < ((Il2CppArrayBase)(object)bodySlots).Count; k++) { if ((Object)(object)((Il2CppArrayBase)(object)bodySlots)[k] != (Object)null && ((Object)((Il2CppArrayBase)(object)bodySlots)[k]).name == text2) { val2 = ((Il2CppArrayBase)(object)bodySlots)[k]; break; } } if ((Object)(object)val2 == (Object)null) { continue; } InventorySlotReceiver componentInChildren2 = ((Component)val2).GetComponentInChildren(); if (!((Object)(object)componentInChildren2 == (Object)null)) { try { componentInChildren2.SpawnInSlotAsync(new Barcode(text3)); num2++; } catch (Exception ex) { ModMain.Log.Warning($"Keep Inventory: failed to spawn {text3} -> {text2}: {ex.Message}"); } } } ModMain.Log.Msg($"Keep Inventory: applied {num2} item(s) from {GetSlotName(slot)}."); } catch (Exception value2) { ModMain.Log.Error($"Keep Inventory apply failed: {value2}"); } } } public static class LoadoutSync { private const string CodePrefix = "QL1:"; public static string FolderPath { get { try { return Path.Combine(MelonEnvironment.UserDataDirectory ?? "UserData", "QualityLab"); } catch { return "UserData/QualityLab"; } } } public static string FilePathFor(int slot) { return Path.Combine(FolderPath, $"Slot{slot}.qlloadout"); } private static string ReadClipboard() { try { return GUIUtility.systemCopyBuffer ?? ""; } catch { return ""; } } private static void WriteClipboard(string s) { try { GUIUtility.systemCopyBuffer = s ?? ""; } catch { } } private static string Encode(string slotData) { if (string.IsNullOrEmpty(slotData)) { return "QL1:"; } try { byte[] bytes = Encoding.UTF8.GetBytes(slotData); return "QL1:" + Convert.ToBase64String(bytes); } catch { return ""; } } private static bool TryDecode(string code, out string slotData) { slotData = null; if (string.IsNullOrEmpty(code)) { return false; } string text = (code.StartsWith("QL1:") ? code.Substring("QL1:".Length) : code); try { byte[] bytes = Convert.FromBase64String(text.Trim()); slotData = Encoding.UTF8.GetString(bytes); return true; } catch { return false; } } public static void ExportToClipboard(int slot) { int num = slot - 1; if (num >= 0 && num < 5) { string value = Settings.SlotData[num].Value; if (string.IsNullOrEmpty(value)) { Notifications.Warn($"Slot {slot} is empty."); return; } string text = Encode(value); WriteClipboard(text); ModMain.Log.Msg($"Loadout Sync: Slot {slot} -> clipboard ({text.Length} chars)."); Notifications.Success($"Slot {slot} copied to clipboard."); } } public static void ExportToFile(int slot) { int num = slot - 1; if (num < 0 || num >= 5) { return; } string value = Settings.SlotData[num].Value; if (string.IsNullOrEmpty(value)) { Notifications.Warn($"Slot {slot} is empty."); return; } try { Directory.CreateDirectory(FolderPath); File.WriteAllText(FilePathFor(slot), Encode(value)); ModMain.Log.Msg($"Loadout Sync: Slot {slot} -> {FilePathFor(slot)}"); Notifications.Success($"Slot {slot} saved to file."); } catch (Exception ex) { Notifications.Error("Export failed: " + ex.Message); } } public static void ImportFromClipboard(int slot) { int num = slot - 1; if (num >= 0 && num < 5) { string text = ReadClipboard(); if (string.IsNullOrEmpty(text)) { Notifications.Warn("Clipboard is empty."); return; } if (!TryDecode(text, out var slotData)) { Notifications.Error("Clipboard isn't a valid loadout code."); return; } Settings.SlotData[num].Value = slotData; Settings.Save(); Notifications.Success($"Imported -> Slot {slot}."); } } public static void ImportFromFile(int slot) { int num = slot - 1; if (num < 0 || num >= 5) { return; } string text = FilePathFor(slot); if (!File.Exists(text)) { Notifications.Warn("No file at " + text); return; } try { if (!TryDecode(File.ReadAllText(text), out var slotData)) { Notifications.Error("File isn't a valid loadout code."); return; } Settings.SlotData[num].Value = slotData; Settings.Save(); Notifications.Success($"Loaded file -> Slot {slot}."); } catch (Exception ex) { Notifications.Error("Import failed: " + ex.Message); } } public static void OpenFolder() { try { Directory.CreateDirectory(FolderPath); Process.Start(new ProcessStartInfo { FileName = FolderPath, UseShellExecute = true }); } catch (Exception ex) { Notifications.Error("Open folder failed: " + ex.Message); } } public static void AnnounceExport(int slot) { string slotName = KeepInventory.GetSlotName(slot); Notifications.Info("Loadout '" + slotName + "' ready to share."); } } public static class Movement { private static float? _baselineJumpVelocity; public static void OnLevelLoaded() { _baselineJumpVelocity = null; } public static void Tick() { if (!((Object)(object)Player.RigManager == (Object)null)) { TickJump(); } } private static void TickJump() { RemapRig remapRig = Player.RemapRig; if (!((Object)(object)remapRig == (Object)null)) { if (!_baselineJumpVelocity.HasValue) { _baselineJumpVelocity = remapRig.jumpVelocity; } remapRig.jumpVelocity = _baselineJumpVelocity.Value * Mathf.Max(0f, Settings.JumpMultiplier.Value); } } public static void TeleportToReticle() { //IL_0025: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) RigManager rigManager = Player.RigManager; Transform head = Player.Head; if (!((Object)(object)rigManager == (Object)null) && !((Object)(object)head == (Object)null)) { RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Ray(((Component)head).transform.position, ((Component)head).transform.forward), ref val, 200f, -1, (QueryTriggerInteraction)1)) { rigManager.Teleport(((RaycastHit)(ref val)).point + Vector3.up * 0.1f, true); Stats.BumpTeleport(); ModMain.Log.Msg($"Teleported to reticle ({((RaycastHit)(ref val)).point.x:F1}, {((RaycastHit)(ref val)).point.y:F1}, {((RaycastHit)(ref val)).point.z:F1})."); } else { ModMain.Log.Warning("Teleport to reticle: nothing in front of you."); } } } public static void SavePositionMarker() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0131: Unknown result type (might be due to invalid IL or missing references) RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null)) { Vector3 position = ((Component)rigManager).transform.position; Settings.MarkerX.Value = position.x; Settings.MarkerY.Value = position.y; Settings.MarkerZ.Value = position.z; Settings.HasPositionMarker.Value = true; Settings.Save(); ModMain.Log.Msg($"Marker saved ({position.x:F1}, {position.y:F1}, {position.z:F1})."); Notifications.Success($"Marker saved at ({position.x:F1}, {position.y:F1}, {position.z:F1})."); } } public static void TeleportToMarker() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!Settings.HasPositionMarker.Value) { ModMain.Log.Warning("No marker set yet. Use Save Position Marker first."); Notifications.Warn("No marker set. Save one first."); return; } RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null)) { Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Settings.MarkerX.Value, Settings.MarkerY.Value, Settings.MarkerZ.Value); rigManager.Teleport(val, true); Stats.BumpTeleport(); ModMain.Log.Msg("Teleported to marker."); Notifications.Info("Teleported to marker."); } } public static void ClearMarker() { Settings.HasPositionMarker.Value = false; Settings.Save(); ModMain.Log.Msg("Marker cleared."); Notifications.Info("Marker cleared."); } public static void SaveMarkerSlot(int slot) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (slot >= 0 && slot < 3) { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null)) { Vector3 position = ((Component)rigManager).transform.position; Settings.MarkerXs[slot].Value = position.x; Settings.MarkerYs[slot].Value = position.y; Settings.MarkerZs[slot].Value = position.z; Settings.MarkerHas[slot].Value = true; Settings.Save(); ModMain.Log.Msg($"Marker {(ushort)(65 + slot)} saved ({position.x:F1}, {position.y:F1}, {position.z:F1})."); } } } public static void TeleportMarkerSlot(int slot) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (slot < 0 || slot >= 3) { return; } if (!Settings.MarkerHas[slot].Value) { ModMain.Log.Warning($"Marker {(ushort)(65 + slot)}: not set."); return; } RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null)) { Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Settings.MarkerXs[slot].Value, Settings.MarkerYs[slot].Value, Settings.MarkerZs[slot].Value); rigManager.Teleport(val, true); Stats.BumpTeleport(); ModMain.Log.Msg($"Teleported to marker {(ushort)(65 + slot)}."); } } public static void ClearMarkerSlot(int slot) { if (slot >= 0 && slot < 3) { Settings.MarkerHas[slot].Value = false; Settings.Save(); ModMain.Log.Msg($"Marker {(ushort)(65 + slot)} cleared."); } } public static void StopVelocity() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) PhysicsRig physicsRig = Player.PhysicsRig; if (!((Object)(object)physicsRig == (Object)null) && !((Object)(object)physicsRig.torso == (Object)null)) { Rigidbody pelvisRb = physicsRig.torso._pelvisRb; if (!((Object)(object)pelvisRb == (Object)null)) { pelvisRb.velocity = Vector3.zero; pelvisRb.angularVelocity = Vector3.zero; ModMain.Log.Msg("Velocity cleared."); } } } public static void QuickRespawn() { RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { return; } Health health = rigManager.health; Player_Health val = ((health != null) ? ((Il2CppObjectBase)health).TryCast() : null); if ((Object)(object)val == (Object)null) { return; } try { ((Health)val).Death(); ModMain.Log.Msg("Respawning."); } catch (Exception ex) { ModMain.Log.Warning("Respawn failed: " + ex.Message); } } } public static class NetSpawn { public static void Spawn(string barcodeId, Vector3 position, Quaternion rotation, Action onSpawned = null) { //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_001a: 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) if (!string.IsNullOrEmpty(barcodeId)) { bool flag = false; try { flag = NetworkInfo.HasServer; } catch { } if (!flag || !TrySpawnNetworked(barcodeId, position, rotation, onSpawned)) { SpawnLocal(barcodeId, position, rotation, onSpawned); } } } private static bool TrySpawnNetworked(string barcodeId, Vector3 position, Quaternion rotation, Action onSpawned) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_001e: Expected O, but got Unknown //IL_001f: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0062: Unknown result type (might be due to invalid IL or missing references) try { Spawnable spawnable = new Spawnable { crateRef = new SpawnableCrateReference(barcodeId) }; NetworkAssetSpawner.Spawn(new SpawnRequestInfo { Spawnable = spawnable, Position = position, Rotation = rotation, SpawnEffect = false, SpawnSource = (EntitySource)2, SpawnCallback = delegate(SpawnCallbackInfo info) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) onSpawned?.Invoke(info.Spawned); } }); ModMain.Log.Msg("Fusion spawn: " + barcodeId); return true; } catch (Exception ex) { ModMain.Log.Warning($"NetSpawn networked path failed for {barcodeId}: {ex.Message}. Falling back to local."); return false; } } private static void SpawnLocal(string barcodeId, Vector3 position, Quaternion rotation, Action onSpawned) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown try { AssetWarehouse instance = AssetWarehouse.Instance; if (instance == null) { ModMain.Log.Warning("Spawn: warehouse not ready."); return; } SpawnableCrate val = default(SpawnableCrate); if (!instance.TryGetCrate(new Barcode(barcodeId), ref val) || (Object)(object)val == (Object)null) { ModMain.Log.Warning("Spawn: no crate for " + barcodeId + "."); return; } Action action = delegate(GameObject prefab) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)prefab == (Object)null)) { GameObject obj = Object.Instantiate(prefab, position, rotation); onSpawned?.Invoke(obj); } }; ((CrateT)(object)val).LoadAsset(Action.op_Implicit(action)); } catch (Exception ex) { ModMain.Log.Warning("Local spawn failed for " + barcodeId + ": " + ex.Message); } } } public static class Notifications { public enum Severity { Info, Success, Warning, Error } public struct Entry { public float TimeUnscaled; public Severity Severity; public string Text; } private const int RingCapacity = 20; private static readonly Queue _ring = new Queue(); public static IReadOnlyCollection Recent => _ring; public static void Info(string text) { Push(Severity.Info, text, 2.5f); } public static void Success(string text) { Push(Severity.Success, text, 2.5f); } public static void Warn(string text) { Push(Severity.Warning, text, 3.5f); } public static void Error(string text) { Push(Severity.Error, text, 4.5f); } public static void Popup(string title, string body, Severity sev = Severity.Info, float seconds = 2.5f) { SendNotifier(title, body, sev, seconds); Hud.Flash(title + "\n" + body, seconds); Record(sev, title + " — " + body); } private static void Push(Severity sev, string text, float seconds) { if (!string.IsNullOrEmpty(text)) { SendNotifier("Quality Of Lab", text, sev, seconds); Hud.Flash(text, seconds); Record(sev, text); } } private static void SendNotifier(string title, string message, Severity sev, float length) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //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_001d: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown try { Notifier.Send(new Notification { Title = NotificationText.op_Implicit(title), Message = NotificationText.op_Implicit(message), PopupLength = Mathf.Max(0.5f, length), Type = MapType(sev) }); } catch (Exception ex) { ModMain.Log.Warning("Notifier send failed: " + ex.Message); } } private static NotificationType MapType(Severity sev) { //IL_0017: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) return (NotificationType)(sev switch { Severity.Success => 3, Severity.Warning => 1, Severity.Error => 2, _ => 0, }); } private static void Record(Severity sev, string text) { _ring.Enqueue(new Entry { TimeUnscaled = Time.unscaledTime, Severity = sev, Text = text }); while (_ring.Count > 20) { _ring.Dequeue(); } switch (sev) { case Severity.Warning: ModMain.Log.Warning(text); break; case Severity.Error: ModMain.Log.Error(text); break; default: ModMain.Log.Msg(text); break; } } public static void PrintRecentToLog() { ModMain.Log.Msg("---- Recent notifications ----"); foreach (Entry item in _ring) { string value = item.Severity switch { Severity.Success => "OK ", Severity.Warning => "WARN", Severity.Error => "ERR ", _ => " ", }; ModMain.Log.Msg($" +{item.TimeUnscaled:F1}s {value} {item.Text}"); } ModMain.Log.Msg("---- end ----"); } public static void Clear() { _ring.Clear(); ModMain.Log.Msg("Notification history cleared."); } } public static class ObjectScaling { private static GameObject _inLeft; private static GameObject _inRight; private static GameObject _lastLeft; private static GameObject _lastRight; private static readonly Dictionary _originalScales = new Dictionary(); private static readonly Dictionary _originalMass = new Dictionary(); private static readonly Dictionary _barcodeScales = new Dictionary(); private static readonly Dictionary _frozenWasKinematic = new Dictionary(); private static bool _pollPrimed; public static int RememberedCount => _barcodeScales.Count; public static void OnLevelLoaded() { _originalScales.Clear(); _originalMass.Clear(); _frozenWasKinematic.Clear(); _inLeft = (_inRight = (_lastLeft = (_lastRight = null))); _pollPrimed = false; } public static void RememberCurrentScale(string barcode) { if (!string.IsNullOrEmpty(barcode)) { _barcodeScales[barcode] = Settings.ObjectScale.Value; ModMain.Log.Msg($"Remembered scale {_barcodeScales[barcode]:F2} for {ShortBarcode(barcode)}."); } } public static void ForgetBarcodeScale(string barcode) { if (!string.IsNullOrEmpty(barcode)) { _barcodeScales.Remove(barcode); } } public static void ClearAllBarcodeScales() { int count = _barcodeScales.Count; _barcodeScales.Clear(); ModMain.Log.Msg($"Cleared {count} remembered scale(s)."); } public static bool TryGetRememberedScale(string barcode, out float scale) { scale = 1f; if (string.IsNullOrEmpty(barcode)) { return false; } return _barcodeScales.TryGetValue(barcode, out scale); } private static string ShortBarcode(string barcode) { if (string.IsNullOrEmpty(barcode)) { return "?"; } int num = barcode.LastIndexOf('.'); if (num <= 0 || num >= barcode.Length - 1) { return barcode; } return barcode.Substring(num + 1); } public static void ScaleLeft() { ScaleHand(leftHand: true); } public static void ScaleRight() { ScaleHand(leftHand: false); } public static void ScaleBoth() { ScaleHand(leftHand: true); ScaleHand(leftHand: false); } public static void FreezeHeld() { int num = 0; num += FreezeHand(Player.LeftHand); num += FreezeHand(Player.RightHand); if (num == 0) { Notifications.Warn("Nothing to freeze."); return; } Notifications.Success($"Froze {num} object(s)."); } public static void UnfreezeAll() { int count = _frozenWasKinematic.Count; foreach (KeyValuePair item in _frozenWasKinematic) { if (!((Object)(object)item.Key == (Object)null)) { item.Key.isKinematic = item.Value; } } _frozenWasKinematic.Clear(); if (count > 0) { Notifications.Success($"Unfroze {count} object(s)."); } else { Notifications.Info("Nothing was frozen."); } } private static int FreezeHand(Hand hand) { if ((Object)(object)hand == (Object)null) { return 0; } GameObject objectInHand = Player.GetObjectInHand(hand); if ((Object)(object)objectInHand == (Object)null) { return 0; } Rigidbody componentInParent = objectInHand.GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { return 0; } if (_frozenWasKinematic.ContainsKey(componentInParent)) { return 0; } _frozenWasKinematic[componentInParent] = componentInParent.isKinematic; componentInParent.isKinematic = true; return 1; } public static void Tick() { if (!Settings.ScaleOnPickup.Value) { _pollPrimed = false; return; } GameObject val = (((Object)(object)Player.LeftHand != (Object)null) ? Player.GetObjectInHand(Player.LeftHand) : null); GameObject val2 = (((Object)(object)Player.RightHand != (Object)null) ? Player.GetObjectInHand(Player.RightHand) : null); if (_pollPrimed) { if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)_lastLeft) { AutoScale(val, leftHand: true); } if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)_lastRight) { AutoScale(val2, leftHand: false); } } _pollPrimed = true; _lastLeft = val; _lastRight = val2; } private static void AutoScale(GameObject go, bool leftHand) { float value = Settings.ObjectScale.Value; float value2 = value; if (Settings.RememberBarcodeScales.Value) { try { Poolee componentInParent = go.GetComponentInParent(); object obj; if (componentInParent == null) { obj = null; } else { SpawnableCrate spawnableCrate = componentInParent.SpawnableCrate; if (spawnableCrate == null) { obj = null; } else { Barcode barcode = ((Scannable)spawnableCrate).Barcode; obj = ((barcode != null) ? barcode._id : null); } } string text = (string)obj; if (!string.IsNullOrEmpty(text) && _barcodeScales.TryGetValue(text, out var value3)) { value2 = value3; } } catch { } } Settings.ObjectScale.Value = value2; try { ScaleHand(leftHand); } finally { Settings.ObjectScale.Value = value; } } private static void ScaleHand(bool leftHand) { //IL_0146: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) GameObject objectInHand = Player.GetObjectInHand(leftHand ? Player.LeftHand : Player.RightHand); if ((Object)(object)objectInHand == (Object)null) { ModMain.Log.Warning("Object Scale: nothing in " + (leftHand ? "left" : "right") + " hand."); return; } Rigidbody componentInParent = ((Component)objectInHand.transform).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { return; } Transform transform = ((Component)componentInParent).transform; MarrowEntity componentInParent2 = objectInHand.GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null) { transform = ((Component)componentInParent2).transform; } GameObject gameObject = ((Component)transform).gameObject; if (!_originalScales.ContainsKey(gameObject)) { _originalScales[gameObject] = transform.localScale; } if (!_originalMass.ContainsKey(componentInParent)) { _originalMass[componentInParent] = componentInParent.mass; } Vector3 val = _originalScales[gameObject]; Vector3 val2 = (transform.localScale = val * Settings.ObjectScale.Value); if (Settings.RememberBarcodeScales.Value) { try { Poolee componentInParent3 = ((Component)componentInParent).GetComponentInParent(); object obj; if (componentInParent3 == null) { obj = null; } else { SpawnableCrate spawnableCrate = componentInParent3.SpawnableCrate; if (spawnableCrate == null) { obj = null; } else { Barcode barcode = ((Scannable)spawnableCrate).Barcode; obj = ((barcode != null) ? barcode._id : null); } } string text = (string)obj; if (!string.IsNullOrEmpty(text)) { _barcodeScales[text] = Settings.ObjectScale.Value; } } catch { } } float num = val.x * val.y * val.z; float num2 = val2.x * val2.y * val2.z; float num3 = _originalMass[componentInParent]; if (num > 0f) { componentInParent.mass = num3 / num * num2; } if (leftHand) { _inLeft = objectInHand; } else { _inRight = objectInHand; } FusionScaleSync.BroadcastObjectScale(objectInHand); } public static void ResetHeld() { ResetOne(_inLeft); ResetOne(_inRight); } private static void ResetOne(GameObject obj) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)obj == (Object)null) { return; } Rigidbody componentInParent = obj.GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { return; } Transform transform = ((Component)componentInParent).transform; MarrowEntity componentInParent2 = obj.GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null) { transform = ((Component)componentInParent2).transform; } if (_originalScales.TryGetValue(((Component)transform).gameObject, out var value)) { transform.localScale = value; if (_originalMass.TryGetValue(componentInParent, out var value2)) { componentInParent.mass = value2; } FusionScaleSync.BroadcastObjectScale(obj); } } } public static class Photo { private static float _countdownEnds; private static int _countdownLast = -1; private static int _burstRemaining; private static float _nextBurstAt; public static bool IsCountingDown => _countdownEnds > Time.unscaledTime; public static bool IsBursting => _burstRemaining > 0; private static string FolderPath() { string path; try { path = MelonEnvironment.UserDataDirectory; } catch { path = "UserData"; } string text = Path.Combine(path, "QualityLab", "Photos"); try { Directory.CreateDirectory(text); } catch { } return text; } public static void TakeScreenshot() { try { string path = FolderPath(); string text = $"QL_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png"; string text2 = Path.Combine(path, text); int num = ((!Settings.PhotoSupersize.Value) ? 1 : 2); ScreenCapture.CaptureScreenshot(text2, num); Notifications.Success("Screenshot saved: " + text); ModMain.Log.Msg("Screenshot -> " + text2); } catch (Exception ex) { Notifications.Error("Screenshot failed: " + ex.Message); } } public static void StartCountdown(int seconds) { if (seconds < 1) { seconds = 3; } _countdownEnds = Time.unscaledTime + (float)seconds; _countdownLast = -1; Notifications.Info($"Photo countdown {seconds}s — pose!"); if (Settings.PhotoHideHud.Value) { Settings.StatsOverlay.Value = false; Settings.Crosshair.Value = false; } } public static void StartBurst(int count) { if (count < 2) { count = 3; } _burstRemaining = count; _nextBurstAt = Time.unscaledTime; Notifications.Info($"Burst x{count}"); } public static void Tick() { float unscaledTime = Time.unscaledTime; if (_countdownEnds > 0f) { float num = _countdownEnds - unscaledTime; if (num <= 0f) { _countdownEnds = 0f; _countdownLast = -1; TakeScreenshot(); } else { int num2 = Mathf.CeilToInt(num); if (num2 != _countdownLast && num2 > 0) { _countdownLast = num2; Notifications.Info($"{num2}..."); } } } if (_burstRemaining > 0 && unscaledTime >= _nextBurstAt) { TakeScreenshot(); _burstRemaining--; _nextBurstAt = unscaledTime + 0.7f; if (_burstRemaining == 0) { Notifications.Success("Burst complete."); } } } public static void OpenPhotoFolder() { try { string fileName = FolderPath(); Process.Start(new ProcessStartInfo { FileName = fileName, UseShellExecute = true }); Notifications.Info("Opened photo folder."); } catch (Exception ex) { Notifications.Error("Open folder failed: " + ex.Message); } } } public static class Profiles { private static readonly CultureInfo Inv = CultureInfo.InvariantCulture; public static string GetName(int slot) { int num = slot - 1; if (num < 0 || num >= 3) { return $"Profile {slot}"; } string value = Settings.ProfileName[num].Value; if (!string.IsNullOrEmpty(value)) { return value; } return $"Profile {slot}"; } public static bool HasData(int slot) { int num = slot - 1; if (num < 0 || num >= 3) { return false; } return !string.IsNullOrEmpty(Settings.ProfileData[num].Value); } public static void Rename(int slot, string newName) { int num = slot - 1; if (num >= 0 && num < 3) { Settings.ProfileName[num].Value = (string.IsNullOrWhiteSpace(newName) ? $"Profile {slot}" : newName); Settings.Save(); } } public static void SaveTo(int slot) { int num = slot - 1; if (num < 0 || num >= 3) { Notifications.Warn($"Invalid profile slot: {slot}"); return; } try { StringBuilder stringBuilder = new StringBuilder(); AppendBool(stringBuilder, "GodMode", Settings.GodMode.Value); AppendBool(stringBuilder, "KeepBetweenLevels", Settings.KeepBetweenLevels.Value); AppendBool(stringBuilder, "KeepOnStartup", Settings.KeepOnStartup.Value); AppendBool(stringBuilder, "AutoSaveOnLevelEnd", Settings.AutoSaveOnLevelEnd.Value); AppendBool(stringBuilder, "StripEmptyHolsters", Settings.StripEmptyHolsters.Value); AppendBool(stringBuilder, "PerLevelLoadouts", Settings.PerLevelLoadouts.Value); AppendBool(stringBuilder, "ScaleOnPickup", Settings.ScaleOnPickup.Value); AppendBool(stringBuilder, "RememberBarcodeScales", Settings.RememberBarcodeScales.Value); AppendBool(stringBuilder, "AutoPerception", Settings.AutoPerception.Value); AppendBool(stringBuilder, "OneHitKill", Settings.OneHitKill.Value); AppendBool(stringBuilder, "AutoHeal", Settings.AutoHeal.Value); AppendBool(stringBuilder, "InfiniteAmmo", Settings.InfiniteAmmo.Value); AppendBool(stringBuilder, "StatsOverlay", Settings.StatsOverlay.Value); AppendBool(stringBuilder, "Crosshair", Settings.Crosshair.Value); AppendBool(stringBuilder, "ShowLobbyInfo", Settings.ShowLobbyInfo.Value); AppendFloat(stringBuilder, "JumpMultiplier", Settings.JumpMultiplier.Value); AppendFloat(stringBuilder, "AvatarScale", Settings.AvatarScale.Value); AppendFloat(stringBuilder, "ObjectScale", Settings.ObjectScale.Value); AppendFloat(stringBuilder, "GravityY", Settings.GravityY.Value); AppendFloat(stringBuilder, "RagdollForceMul", Settings.RagdollForceMul.Value); AppendFloat(stringBuilder, "NpcScale", Settings.NpcScale.Value); AppendFloat(stringBuilder, "ExplosionForceMul", Settings.ExplosionForceMul.Value); AppendFloat(stringBuilder, "DamageMultiplier", Settings.DamageMultiplier.Value); AppendFloat(stringBuilder, "DamageResistance", Settings.DamageResistance.Value); AppendFloat(stringBuilder, "AutoHealThreshold", Settings.AutoHealThreshold.Value); AppendInt(stringBuilder, "SelectedSlot", Settings.SelectedSlot.Value); for (int i = 0; i < 4; i++) { AppendInt(stringBuilder, $"HotkeyTrig{i}", Settings.HotkeyTrigger[i].Value); AppendInt(stringBuilder, $"HotkeyAct{i}", Settings.HotkeyAction[i].Value); } for (int j = 0; j < 8; j++) { AppendInt(stringBuilder, $"HolsterVis{j}", Settings.HolsterVisibility[j].Value); } Settings.ProfileData[num].Value = stringBuilder.ToString(); Settings.Save(); Notifications.Success("Saved settings to " + GetName(slot)); } catch (Exception ex) { Notifications.Error("Profile save failed: " + ex.Message); } } public static void LoadFrom(int slot) { int num = slot - 1; if (num < 0 || num >= 3) { Notifications.Warn($"Invalid profile slot: {slot}"); return; } string value = Settings.ProfileData[num].Value; if (string.IsNullOrEmpty(value)) { Notifications.Warn(GetName(slot) + ": empty."); return; } try { Dictionary m = Parse(value); ReadBool(m, "GodMode", Settings.GodMode); ReadBool(m, "KeepBetweenLevels", Settings.KeepBetweenLevels); ReadBool(m, "KeepOnStartup", Settings.KeepOnStartup); ReadBool(m, "AutoSaveOnLevelEnd", Settings.AutoSaveOnLevelEnd); ReadBool(m, "StripEmptyHolsters", Settings.StripEmptyHolsters); ReadBool(m, "PerLevelLoadouts", Settings.PerLevelLoadouts); ReadBool(m, "ScaleOnPickup", Settings.ScaleOnPickup); ReadBool(m, "RememberBarcodeScales", Settings.RememberBarcodeScales); ReadBool(m, "AutoPerception", Settings.AutoPerception); ReadBool(m, "OneHitKill", Settings.OneHitKill); ReadBool(m, "AutoHeal", Settings.AutoHeal); ReadBool(m, "InfiniteAmmo", Settings.InfiniteAmmo); ReadBool(m, "StatsOverlay", Settings.StatsOverlay); ReadBool(m, "Crosshair", Settings.Crosshair); ReadBool(m, "ShowLobbyInfo", Settings.ShowLobbyInfo); ReadFloat(m, "JumpMultiplier", Settings.JumpMultiplier); ReadFloat(m, "AvatarScale", Settings.AvatarScale); ReadFloat(m, "ObjectScale", Settings.ObjectScale); ReadFloat(m, "GravityY", Settings.GravityY); ReadFloat(m, "RagdollForceMul", Settings.RagdollForceMul); ReadFloat(m, "NpcScale", Settings.NpcScale); ReadFloat(m, "ExplosionForceMul", Settings.ExplosionForceMul); ReadFloat(m, "DamageMultiplier", Settings.DamageMultiplier); ReadFloat(m, "DamageResistance", Settings.DamageResistance); ReadFloat(m, "AutoHealThreshold", Settings.AutoHealThreshold); ReadInt(m, "SelectedSlot", Settings.SelectedSlot); for (int i = 0; i < 4; i++) { ReadInt(m, $"HotkeyTrig{i}", Settings.HotkeyTrigger[i]); ReadInt(m, $"HotkeyAct{i}", Settings.HotkeyAction[i]); } for (int j = 0; j < 8; j++) { ReadInt(m, $"HolsterVis{j}", Settings.HolsterVisibility[j]); } Settings.Save(); Notifications.Success("Loaded " + GetName(slot)); } catch (Exception ex) { Notifications.Error("Profile load failed: " + ex.Message); } } public static void Clear(int slot) { int num = slot - 1; if (num >= 0 && num < 3) { Settings.ProfileData[num].Value = ""; Settings.Save(); Notifications.Info("Cleared " + GetName(slot)); } } private static void AppendBool(StringBuilder sb, string key, bool v) { sb.Append(key).Append('=').Append(v ? '1' : '0') .Append(';'); } private static void AppendFloat(StringBuilder sb, string key, float v) { sb.Append(key).Append('=').Append(v.ToString(Inv)) .Append(';'); } private static void AppendInt(StringBuilder sb, string key, int v) { sb.Append(key).Append('=').Append(v.ToString(Inv)) .Append(';'); } private static Dictionary Parse(string raw) { Dictionary dictionary = new Dictionary(); string[] array = raw.Split(';'); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { int num = text.IndexOf('='); if (num >= 0) { dictionary[text.Substring(0, num)] = text.Substring(num + 1); } } } return dictionary; } private static void ReadBool(Dictionary m, string key, MelonPreferences_Entry entry) { if (m.TryGetValue(key, out var value)) { entry.Value = value == "1" || value == "true" || value == "True"; } } private static void ReadFloat(Dictionary m, string key, MelonPreferences_Entry entry) { if (m.TryGetValue(key, out var value) && float.TryParse(value, NumberStyles.Float, Inv, out var result)) { entry.Value = result; } } private static void ReadInt(Dictionary m, string key, MelonPreferences_Entry entry) { if (m.TryGetValue(key, out var value) && int.TryParse(value, NumberStyles.Integer, Inv, out var result)) { entry.Value = result; } } } public static class ServerBrowser { private const float AutoSnapshotInterval = 4f; private static float _nextSnapshot; public static void Tick() { if (!Fusion.HasServer || Time.unscaledTime < _nextSnapshot) { return; } _nextSnapshot = Time.unscaledTime + 4f; try { string text = Fusion.LobbyCode(); if (!string.IsNullOrEmpty(text) && !text.StartsWith("(") && !(Settings.LastLobbyCode.Value == text)) { Settings.LastLobbyCode.Value = text; Settings.Save(); } } catch { } } public static void SaveCurrentTo(int slotIdx) { if (slotIdx < 0 || slotIdx >= 5) { return; } if (!Fusion.HasServer) { Notifications.Warn("Not in a lobby."); return; } string text = Fusion.LobbyCode(); if (string.IsNullOrEmpty(text) || text.StartsWith("(")) { Notifications.Warn("Couldn't read lobby code."); return; } string text2 = Fusion.LobbyName(); if (string.IsNullOrEmpty(text2) || text2.StartsWith("(")) { text2 = Fusion.LobbyHostName(); } if (string.IsNullOrEmpty(text2) || text2.StartsWith("(")) { text2 = $"Lobby {slotIdx + 1}"; } Settings.FavoriteCode[slotIdx].Value = text; Settings.FavoriteName[slotIdx].Value = text2; Settings.Save(); Notifications.Success($"Saved '{text2}' to Favorite {slotIdx + 1}."); } public static void ClearSlot(int slotIdx) { if (slotIdx >= 0 && slotIdx < 5) { Settings.FavoriteCode[slotIdx].Value = ""; Settings.FavoriteName[slotIdx].Value = $"Favorite {slotIdx + 1}"; Settings.Save(); Notifications.Info($"Cleared Favorite {slotIdx + 1}."); } } public static void PrintFavoritesToLog() { ModMain.Log.Msg("---- Quality Of Lab favorite lobby codes ----"); for (int i = 0; i < 5; i++) { string value = Settings.FavoriteName[i].Value ?? $"Favorite {i + 1}"; string text = Settings.FavoriteCode[i].Value ?? ""; string value2 = (string.IsNullOrEmpty(text) ? "(empty)" : text); ModMain.Log.Msg($" {i + 1}. {value} — {value2}"); } ModMain.Log.Msg(" Last seen: " + Settings.LastLobbyCode.Value); ModMain.Log.Msg("------------------------------------------"); } public static void JoinSlot(int slotIdx) { if (slotIdx >= 0 && slotIdx < 5) { string value = Settings.FavoriteCode[slotIdx].Value; if (string.IsNullOrEmpty(value)) { Notifications.Warn($"Favorite {slotIdx + 1} is empty."); } else { JoinByCode(value); } } } public static void RejoinLast() { string value = Settings.LastLobbyCode.Value; if (string.IsNullOrEmpty(value)) { Notifications.Warn("No previously seen lobby."); } else { JoinByCode(value); } } public static void JoinByCode(string code) { if (string.IsNullOrEmpty(code)) { Notifications.Warn("Empty code."); return; } try { MethodInfo method = typeof(NetworkHelper).GetMethod("JoinServerByCode", BindingFlags.Static | BindingFlags.Public); if (method == null) { Notifications.Error("Fusion: JoinServerByCode not found."); return; } method.Invoke(null, new object[1] { code }); Notifications.Info("Joining lobby '" + code + "'..."); } catch (Exception ex) { Notifications.Error("Join failed: " + ex.Message); } } } public static class Spawning { public const int RecentCapacity = 10; private static readonly List _recent = new List(); private static readonly HashSet _seen = new HashSet(); private static string _lastSeenLeft; private static string _lastSeenRight; public static readonly (string Name, string Barcode)[] Presets = new(string, string)[32] { ("Eder 22 Pistol", "SLZ.BONELAB.Content.Spawnable.HandgunEder22training"), ("M1 Garand", "SLZ.BONELAB.Content.Spawnable.RifleM1Garand"), ("MK18 Rifle", "SLZ.BONELAB.Content.Spawnable.RifleMK18HoloForegrip"), ("Ice Axe (Melee)", "SLZ.BONELAB.Content.Spawnable.MeleeIceAxe"), ("Cultist", "SLZ.BONELAB.Content.Spawnable.NPCCultist"), ("Security Guard", "SLZ.BONELAB.Content.Spawnable.NPCSecurityGuard"), ("Peasant (M Large)", "SLZ.BONELAB.Content.Spawnable.NPCPeasantMaleL"), ("Peasant (M Med)", "SLZ.BONELAB.Content.Spawnable.NPCPeasantMaleM"), ("Peasant (M Small)", "SLZ.BONELAB.Content.Spawnable.NPCPeasantMaleS"), ("Peasant (F Large)", "SLZ.BONELAB.Content.Spawnable.NPCPeasantFemL"), ("Peasant (F Med)", "SLZ.BONELAB.Content.Spawnable.NPCPeasantFemM"), ("Peasant (F Small)", "SLZ.BONELAB.Content.Spawnable.NPCPeasantFemS"), ("Peasant (Null)", "SLZ.BONELAB.Content.Spawnable.NPCPeasantNull"), ("Apollo Giant", "SLZ.BONELAB.Content.Spawnable.ApolloGiant"), ("Apollo Gold", "SLZ.BONELAB.Content.Spawnable.ApolloGold"), ("Apollo Blue", "SLZ.BONELAB.Content.Spawnable.BlueApollo"), ("Banker", "SLZ.BONELAB.Content.Spawnable.BulletBanker"), ("Bowling Ball", "SLZ.BONELAB.Content.Spawnable.BowlingBall"), ("Bowling Pin", "SLZ.BONELAB.Content.Spawnable.BowlingPin"), ("Weighted Cube", "SLZ.BONELAB.Content.Spawnable.WeightedCube"), ("Watermelon", "SLZ.BONELAB.Content.Spawnable.BottleMelon"), ("Pill Bottle", "SLZ.BONELAB.Content.Spawnable.BottlePill"), ("Soda Can", "SLZ.BONELAB.Content.Spawnable.SodaCanB"), ("Donut Box", "SLZ.BONELAB.Content.Spawnable.DonutBox"), ("Health Pickup", "SLZ.BONELAB.Content.Spawnable.PropHealthPickup"), ("Combat Crate", "SLZ.BONELAB.Content.Spawnable.CombatCrate"), ("Electric Guitar", "SLZ.BONELAB.Content.Spawnable.ElectricGuitar"), ("Destructible Barrel", "SLZ.BONELAB.Content.Spawnable.DestructibleBarrel"), ("Skeleton Skull", "SLZ.BONELAB.Content.Spawnable.SkeletonSkull"), ("Target Snake", "SLZ.BONELAB.Content.Spawnable.TargetSnake"), ("Target Bat", "SLZ.BONELAB.Content.Spawnable.TargetBat"), ("Box Turret", "SLZ.BONELAB.Content.Spawnable.BoxTurret") }; public static IReadOnlyList RecentList => _recent; public static void Tick() { try { string text = SampleHand(Player.LeftHand); string text2 = SampleHand(Player.RightHand); if (!string.IsNullOrEmpty(text) && text != _lastSeenLeft) { Push(text); _lastSeenLeft = text; if (Settings.AutoPerception.Value) { AutoFlash(text, "L"); } } if (!string.IsNullOrEmpty(text2) && text2 != _lastSeenRight) { Push(text2); _lastSeenRight = text2; if (Settings.AutoPerception.Value) { AutoFlash(text2, "R"); } } } catch { } } private static void AutoFlash(string barcodeId, string handLabel) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown string text = ShortName(barcodeId); try { AssetWarehouse instance = AssetWarehouse.Instance; SpawnableCrate val = default(SpawnableCrate); if (instance != null && instance.TryGetCrate(new Barcode(barcodeId), ref val) && (Object)(object)val != (Object)null) { string title = ((Scannable)val).Title; if (!string.IsNullOrEmpty(title)) { text = title; } } } catch { } Notifications.Info(handLabel + ": " + text); } private static string ShortName(string barcode) { if (string.IsNullOrEmpty(barcode)) { return "?"; } int num = barcode.LastIndexOf('.'); if (num <= 0 || num >= barcode.Length - 1) { return barcode; } return barcode.Substring(num + 1); } private static string SampleHand(Hand hand) { if ((Object)(object)hand == (Object)null) { return null; } GameObject objectInHand = Player.GetObjectInHand(hand); if ((Object)(object)objectInHand == (Object)null) { return null; } Poolee componentInParent = objectInHand.GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent.SpawnableCrate == (Object)null) { return null; } Barcode barcode = ((Scannable)componentInParent.SpawnableCrate).Barcode; if (barcode == null) { return null; } return barcode._id; } private static void Push(string barcodeId) { if (_seen.Contains(barcodeId)) { _recent.Remove(barcodeId); _recent.Insert(0, barcodeId); return; } _recent.Insert(0, barcodeId); _seen.Add(barcodeId); while (_recent.Count > 10) { string item = _recent[_recent.Count - 1]; _recent.RemoveAt(_recent.Count - 1); _seen.Remove(item); } } public static void ClearRecent() { int count = _recent.Count; _recent.Clear(); _seen.Clear(); _lastSeenLeft = null; _lastSeenRight = null; ModMain.Log.Msg("Recent spawn list cleared."); Notifications.Info((count > 0) ? $"Cleared {count} recent item(s)." : "Recent list already empty."); } public static void SpawnLastHeld() { if (_recent.Count == 0) { ModMain.Log.Warning("No recent items to spawn."); } else { SpawnAtOffset(_recent[0], 0.7f); } } public static void SpawnAtReticle(string barcodeId) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(barcodeId)) { Transform head = Player.Head; if (!((Object)(object)head == (Object)null)) { RaycastHit val = default(RaycastHit); Vector3 position = ((!Physics.Raycast(((Component)head).transform.position, ((Component)head).transform.forward, ref val, 50f, -1, (QueryTriggerInteraction)1)) ? (((Component)head).transform.position + ((Component)head).transform.forward * 3f) : (((RaycastHit)(ref val)).point + Vector3.up * 0.2f)); SpawnAtPosition(barcodeId, position); } } } public static void SpawnAtOffset(string barcodeId, float forwardDistance) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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) if (!string.IsNullOrEmpty(barcodeId)) { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null)) { Transform head = Player.Head; Vector3 position = (((Object)(object)head != (Object)null) ? (((Component)head).transform.position + ((Component)head).transform.forward * forwardDistance) : ((Component)rigManager).transform.position); SpawnAtPosition(barcodeId, position); } } } public static void SpawnAtPosition(string barcodeId, Vector3 position) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(barcodeId)) { return; } NetSpawn.Spawn(barcodeId, position, Quaternion.identity, delegate(GameObject inst) { if ((Object)(object)inst != (Object)null) { Stats.BumpSpawn(); ModMain.Log.Msg("Spawned " + barcodeId + "."); } }); } } public static class Stats { private static Vector3 _lastPos; private static bool _havePos; public static float StartedAt { get; private set; } public static float DistanceMeters { get; private set; } public static int TeleportCount { get; private set; } public static int SpawnCount { get; private set; } public static int CloneCount { get; private set; } public static int IdentifyCount { get; private set; } public static float DamageDealt { get; private set; } public static int HitCount { get; private set; } public static int KillCount { get; private set; } public static void Init() { StartedAt = Time.unscaledTime; } public static void Tick() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) Transform head = Player.Head; if ((Object)(object)head == (Object)null) { _havePos = false; return; } Vector3 position = ((Component)head).transform.position; if (_havePos) { Vector3 val = position - _lastPos; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 0.5f) { DistanceMeters += magnitude; } } _lastPos = position; _havePos = true; } public static void BumpTeleport() { TeleportCount++; } public static void BumpSpawn() { SpawnCount++; } public static void BumpClone() { CloneCount++; } public static void BumpIdentify() { IdentifyCount++; } public static void BumpDamageDealt(float amount) { DamageDealt += Mathf.Max(0f, amount); HitCount++; } public static void BumpKill() { KillCount++; } public static void Reset() { StartedAt = Time.unscaledTime; DistanceMeters = 0f; TeleportCount = 0; SpawnCount = 0; CloneCount = 0; IdentifyCount = 0; DamageDealt = 0f; HitCount = 0; KillCount = 0; _havePos = false; ModMain.Log.Msg("Session stats reset."); } public static string FormatSummary() { float num = Time.unscaledTime - StartedAt; int num2 = Mathf.FloorToInt(num / 60f); int value = Mathf.FloorToInt(num - (float)num2 * 60f); return $"Session {num2:D2}:{value:D2} Dist {DistanceMeters:F0}m TP {TeleportCount} Spawn {SpawnCount} Clone {CloneCount} ID {IdentifyCount}"; } public static string FormatCombatSummary() { return $"Dmg {DamageDealt:F0} Hits {HitCount} Kills {KillCount}"; } } public static class Templates { public struct Template { public string Name; public string[] Barcodes; } public static readonly Template[] All = new Template[8] { new Template { Name = "Pistol Pair", Barcodes = new string[2] { "SLZ.BONELAB.Content.Spawnable.M1911", "SLZ.BONELAB.Content.Spawnable.M1911" } }, new Template { Name = "Rifle + Pistol", Barcodes = new string[2] { "SLZ.BONELAB.Content.Spawnable.AKM", "SLZ.BONELAB.Content.Spawnable.M1911" } }, new Template { Name = "Melee Set", Barcodes = new string[3] { "SLZ.BONELAB.Content.Spawnable.Sword", "SLZ.BONELAB.Content.Spawnable.CombatKnife", "SLZ.BONELAB.Content.Spawnable.Crowbar" } }, new Template { Name = "Heavy", Barcodes = new string[4] { "SLZ.BONELAB.Content.Spawnable.Mossberg590", "SLZ.BONELAB.Content.Spawnable.DesertEagle", "SLZ.BONELAB.Content.Spawnable.FragGrenade", "SLZ.BONELAB.Content.Spawnable.FragGrenade" } }, new Template { Name = "Throwables", Barcodes = new string[5] { "SLZ.BONELAB.Content.Spawnable.FragGrenade", "SLZ.BONELAB.Content.Spawnable.FragGrenade", "SLZ.BONELAB.Content.Spawnable.FragGrenade", "SLZ.BONELAB.Content.Spawnable.FlashGrenade", "SLZ.BONELAB.Content.Spawnable.FlashGrenade" } }, new Template { Name = "SMG Loadout", Barcodes = new string[3] { "SLZ.BONELAB.Content.Spawnable.MP5", "SLZ.BONELAB.Content.Spawnable.Uzi", "SLZ.BONELAB.Content.Spawnable.CombatKnife" } }, new Template { Name = "Stealth", Barcodes = new string[2] { "SLZ.BONELAB.Content.Spawnable.M1911", "SLZ.BONELAB.Content.Spawnable.CombatKnife" } }, new Template { Name = "Chaos Bag", Barcodes = new string[5] { "SLZ.BONELAB.Content.Spawnable.AKM", "SLZ.BONELAB.Content.Spawnable.Sword", "SLZ.BONELAB.Content.Spawnable.FragGrenade", "SLZ.BONELAB.Content.Spawnable.M1911", "SLZ.BONELAB.Content.Spawnable.Crowbar" } } }; public static void Drop(Template t) { if (t.Barcodes != null && t.Barcodes.Length != 0) { MelonCoroutines.Start(DropRoutine(t)); } } private static IEnumerator DropRoutine(Template t) { Transform head = Player.Head; if (!((Object)(object)head == (Object)null)) { Vector3 origin = ((Component)head).transform.position + ((Component)head).transform.forward * 1.2f; Vector3 right = ((Component)head).transform.right; float spacing = 0.4f; int count = t.Barcodes.Length; float startOffset = (0f - (float)(count - 1) * spacing) * 0.5f; for (int i = 0; i < count; i++) { Vector3 position = origin + right * (startOffset + (float)i * spacing); Spawning.SpawnAtPosition(t.Barcodes[i], position); yield return (object)new WaitForSeconds(0.15f); } Notifications.Success($"Dropped: {t.Name} ({count} items)"); } } } public static class TimeScale { private static float? _baselineFixedDt; private static float _pulseFactor = 1f; private static float _pulseUntil; private static bool _pulsing; public const float Min = 0.05f; public const float Max = 3f; public static readonly (string Label, float Factor)[] Presets = new(string, float)[8] { ("0.10x (Bullet Time)", 0.1f), ("0.25x", 0.25f), ("0.50x", 0.5f), ("0.75x", 0.75f), ("1.00x (Normal)", 1f), ("1.25x", 1.25f), ("1.50x", 1.5f), ("2.00x", 2f) }; public static void Tick() { if (!_baselineFixedDt.HasValue) { _baselineFixedDt = Time.fixedDeltaTime; } if (Settings.TimeScaleActive.Value) { _pulsing = false; ApplyClock(Mathf.Clamp(Settings.TimeScale.Value, 0.05f, 3f)); } else { if (!_pulsing) { if (_baselineFixedDt.HasValue && !Mathf.Approximately(Time.fixedDeltaTime, _baselineFixedDt.Value)) { Time.fixedDeltaTime = _baselineFixedDt.Value; } return; } if (Time.unscaledTime < _pulseUntil) { ApplyClock(_pulseFactor); } else { _pulsing = false; RestoreClock(); } } if (!Settings.PauseAffectsAudio.Value && AudioListener.pause) { AudioListener.pause = false; } } public static void Pulse(float factor, float seconds) { if (!Settings.TimeScaleActive.Value) { _pulseFactor = Mathf.Clamp(factor, 0.05f, 1f); _pulseUntil = Time.unscaledTime + Mathf.Max(0.05f, seconds); _pulsing = true; } } private static void ApplyClock(float ts) { if (!Mathf.Approximately(Time.timeScale, ts)) { Time.timeScale = ts; } float num = (_baselineFixedDt ?? 0.0111f) * Mathf.Clamp(ts, 0.05f, 1f); if (!Mathf.Approximately(Time.fixedDeltaTime, num)) { Time.fixedDeltaTime = num; } } private static void RestoreClock() { Time.timeScale = 1f; if (_baselineFixedDt.HasValue) { Time.fixedDeltaTime = _baselineFixedDt.Value; } } public static void SetFactor(float factor) { float num = Mathf.Clamp(factor, 0.05f, 3f); Settings.TimeScale.Value = num; Settings.TimeScaleActive.Value = !Mathf.Approximately(num, 1f); Settings.Save(); Notifications.Info($"Time scale: {num:F2}x"); } public static void ToggleSlowMo() { if (Settings.TimeScaleActive.Value && Settings.TimeScale.Value < 0.95f) { Settings.TimeScale.Value = 1f; Settings.TimeScaleActive.Value = false; Settings.Save(); RestoreClock(); Notifications.Success("Slow-Mo: off (1.00x)"); } else { float value = Mathf.Clamp(Settings.SlowMoFactor.Value, 0.05f, 1f); Settings.TimeScale.Value = value; Settings.TimeScaleActive.Value = true; Settings.Save(); Notifications.Success($"Slow-Mo: on ({value:F2}x)"); } } public static void Restore() { Settings.TimeScale.Value = 1f; Settings.TimeScaleActive.Value = false; Settings.Save(); _pulsing = false; RestoreClock(); Notifications.Info("Time scale restored to 1.00x."); } public static string Status() { if (!Settings.TimeScaleActive.Value) { return "1.00x (vanilla)"; } return $"{Settings.TimeScale.Value:F2}x{((Settings.TimeScale.Value < 0.95f) ? " (slow-mo)" : ((Settings.TimeScale.Value > 1.05f) ? " (fast)" : ""))}"; } } public static class WarehouseTools { private static List _allSpawnables; private static float _lastScanAt; private const float ScanCacheSeconds = 30f; public static void ScanCountsToLog() { try { AssetWarehouse instance = AssetWarehouse.Instance; if (instance == null) { Notifications.Warn("Warehouse not ready."); return; } int value = 0; int num = 0; int num2 = 0; int num3 = 0; int value2 = 0; try { value2 = instance.GetPallets()?.Count ?? 0; } catch { } try { List crates = instance.GetCrates(); value = crates?.Count ?? 0; if (crates != null) { Enumerator enumerator = crates.GetEnumerator(); while (enumerator.MoveNext()) { Crate current = enumerator.Current; if (!((Object)(object)current == (Object)null)) { switch (((object)current).GetType()?.Name ?? "") { case "SpawnableCrate": num++; break; case "LevelCrate": num2++; break; case "AvatarCrate": num3++; break; } } } } } catch { } ModMain.Log.Msg("---- Warehouse contents ----"); ModMain.Log.Msg($" Pallets: {value2}"); ModMain.Log.Msg($" Crates: {value}"); ModMain.Log.Msg($" Spawnable: {num}"); ModMain.Log.Msg($" Avatar: {num3}"); ModMain.Log.Msg($" Level: {num2}"); ModMain.Log.Msg("----------------------------"); Notifications.Info($"Warehouse: {value} crates ({num} spawnable)."); } catch (Exception ex) { ModMain.Log.Warning("Warehouse scan failed: " + ex.Message); } } public static List GetAllSpawnableBarcodes(bool force = false) { if (_allSpawnables != null && !force && Time.unscaledTime - _lastScanAt < 30f) { return _allSpawnables; } List list = new List(); try { AssetWarehouse instance = AssetWarehouse.Instance; if (instance == null) { return list; } List crates = instance.GetCrates(); if (crates == null) { return list; } Enumerator enumerator = crates.GetEnumerator(); while (enumerator.MoveNext()) { Crate current = enumerator.Current; if (!((Object)(object)current == (Object)null) && !(((object)current).GetType()?.Name != "SpawnableCrate")) { string text = null; try { Barcode barcode = ((Scannable)current).Barcode; text = ((barcode != null) ? barcode._id : null); } catch { } if (!string.IsNullOrEmpty(text)) { list.Add(text); } } } } catch (Exception ex) { ModMain.Log.Warning("Spawnable enumeration failed: " + ex.Message); } _allSpawnables = list; _lastScanAt = Time.unscaledTime; return list; } public static void PrintAllSpawnableBarcodes(int max = 200) { List allSpawnableBarcodes = GetAllSpawnableBarcodes(force: true); ModMain.Log.Msg($"---- All spawnable barcodes ({allSpawnableBarcodes.Count}) ----"); int num = Mathf.Min(allSpawnableBarcodes.Count, max); for (int i = 0; i < num; i++) { ModMain.Log.Msg(" " + allSpawnableBarcodes[i]); } if (allSpawnableBarcodes.Count > max) { ModMain.Log.Msg($" ...and {allSpawnableBarcodes.Count - max} more (raise the limit to see all)."); } ModMain.Log.Msg("---------------------------------------"); Notifications.Info($"Logged {num}/{allSpawnableBarcodes.Count} barcodes."); } public static void SpawnRandomPreset() { (string, string)[] presets = Spawning.Presets; if (presets != null && presets.Length != 0) { int num = Random.Range(0, presets.Length); Spawning.SpawnAtReticle(presets[num].Item2); Notifications.Info("Random: " + presets[num].Item1); } } public static void SpawnRandomFromWarehouse() { List allSpawnableBarcodes = GetAllSpawnableBarcodes(); if (allSpawnableBarcodes.Count == 0) { Notifications.Warn("No spawnables loaded."); return; } int index = Random.Range(0, allSpawnableBarcodes.Count); string text = allSpawnableBarcodes[index]; Spawning.SpawnAtReticle(text); Notifications.Info("Random: " + ShortName(text)); } private static string ShortName(string barcode) { if (string.IsNullOrEmpty(barcode)) { return "?"; } int num = barcode.LastIndexOf('.'); if (num <= 0 || num >= barcode.Length - 1) { return barcode; } return barcode.Substring(num + 1); } } public static class World { private static readonly List _trackedRbs = new List(); private static readonly List _trackedBrains = new List(); private static readonly Dictionary _lastVel = new Dictionary(); private static float _nextScan; private static bool _npcScaleApplied; public static void Tick() { ApplyGravity(); ApplyNpcScale(); MaybeRescan(); } private static void ApplyGravity() { //IL_000b: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) float value = Settings.GravityY.Value; Vector3 gravity = Physics.gravity; if (!Mathf.Approximately(gravity.y, value) || gravity.x != 0f || gravity.z != 0f) { Physics.gravity = new Vector3(0f, value, 0f); } } private static void ApplyNpcScale() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(Settings.NpcScale.Value, 0.1f, 10f); bool flag = Mathf.Approximately(num, 1f); if (flag && !_npcScaleApplied) { return; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(num, num, num); for (int num2 = _trackedBrains.Count - 1; num2 >= 0; num2--) { Transform val2 = _trackedBrains[num2]; if ((Object)(object)val2 == (Object)null) { _trackedBrains.RemoveAt(num2); } else if (val2.localScale != val) { val2.localScale = val; } } _npcScaleApplied = !flag; } private static void MaybeRescan() { if (!(Time.unscaledTime < _nextScan)) { _nextScan = Time.unscaledTime + 2f; ScanAIBodies(); } } public static void OnLevelLoaded() { _trackedRbs.Clear(); _trackedBrains.Clear(); _lastVel.Clear(); _nextScan = 0f; } private static void ScanAIBodies() { _trackedRbs.Clear(); _trackedBrains.Clear(); _lastVel.Clear(); Il2CppArrayBase val = Object.FindObjectsOfType(); for (int i = 0; i < val.Length; i++) { AIBrain val2 = val[i]; if ((Object)(object)val2 == (Object)null) { continue; } _trackedBrains.Add(((Component)val2).transform); Il2CppArrayBase componentsInChildren = ((Component)val2).GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null) { _trackedRbs.Add(componentsInChildren[j]); } } } } public static void FixedTick() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00b9: 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_00fc: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) float value = Settings.RagdollForceMul.Value; if (Mathf.Approximately(value, 1f) || value < 0f) { _lastVel.Clear(); return; } float num = Mathf.Abs(Settings.GravityY.Value) * Time.fixedDeltaTime * 1.5f + 0.4f; float num2 = value - 1f; for (int num3 = _trackedRbs.Count - 1; num3 >= 0; num3--) { Rigidbody val = _trackedRbs[num3]; if ((Object)(object)val == (Object)null) { _trackedRbs.RemoveAt(num3); } else { int instanceID = ((Object)val).GetInstanceID(); Vector3 velocity = val.velocity; Vector3 value2; Vector3 val2 = (_lastVel.TryGetValue(instanceID, out value2) ? value2 : velocity); Vector3 val3 = velocity - val2; if (((Vector3)(ref val3)).magnitude > num) { val.velocity = velocity + val3 * num2; _lastVel[instanceID] = val.velocity; } else { _lastVel[instanceID] = velocity; } } } } public static void ExplodeAtReticle() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) Transform head = Player.Head; if (!((Object)(object)head == (Object)null)) { Vector3 position = ((Component)head).transform.position; Vector3 forward = ((Component)head).transform.forward; RaycastHit val2 = default(RaycastHit); Vector3 val = ((!Physics.Raycast(position, forward, ref val2, 200f, -1, (QueryTriggerInteraction)1)) ? (position + forward * 5f) : ((RaycastHit)(ref val2)).point); ApplyExplosion(val, 800f * Mathf.Max(0.1f, Settings.ExplosionForceMul.Value), 6f); ModMain.Log.Msg($"Boom at ({val.x:F1}, {val.y:F1}, {val.z:F1})."); } } public static void ExplodeAt(Vector3 center) { //IL_0000: 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_0060: 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) ApplyExplosion(center, 800f * Mathf.Max(0.1f, Settings.ExplosionForceMul.Value), 6f); ModMain.Log.Msg($"Boom at ({center.x:F1}, {center.y:F1}, {center.z:F1})."); } public static void PushAllNpcsAway() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Transform head = Player.Head; if (!((Object)(object)head == (Object)null)) { ApplyOutwardFromPoint(((Component)head).transform.position, 25f * Settings.ExplosionForceMul.Value, aiOnly: true); ModMain.Log.Msg("Pushed NPCs outward."); } } public static void PullAllNpcsToMe() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Transform head = Player.Head; if (!((Object)(object)head == (Object)null)) { ApplyOutwardFromPoint(((Component)head).transform.position, -15f * Settings.ExplosionForceMul.Value, aiOnly: true); ModMain.Log.Msg("Pulled NPCs in."); } } private static void ApplyExplosion(Vector3 center, float force, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) Il2CppReferenceArray val = Physics.OverlapSphere(center, radius, -1, (QueryTriggerInteraction)1); HashSet hashSet = new HashSet(); for (int i = 0; i < ((Il2CppArrayBase)(object)val).Length; i++) { Collider val2 = ((Il2CppArrayBase)(object)val)[i]; if (!((Object)(object)val2 == (Object)null)) { Rigidbody attachedRigidbody = val2.attachedRigidbody; if (!((Object)(object)attachedRigidbody == (Object)null) && !hashSet.Contains(attachedRigidbody)) { hashSet.Add(attachedRigidbody); attachedRigidbody.AddExplosionForce(force, center, radius, 1.5f, (ForceMode)1); } } } } private static void ApplyOutwardFromPoint(Vector3 origin, float force, bool aiOnly) { //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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) for (int num = _trackedRbs.Count - 1; num >= 0; num--) { Rigidbody val = _trackedRbs[num]; if ((Object)(object)val == (Object)null) { _trackedRbs.RemoveAt(num); } else { Vector3 val2 = val.worldCenterOfMass - origin; float magnitude = ((Vector3)(ref val2)).magnitude; val2 = ((!(magnitude < 0.01f)) ? (val2 / magnitude) : Vector3.up); val.AddForce(val2 * force, (ForceMode)1); } } } } public static class WristHud { private static GameObject _root; private static TextMesh _tm; private static float _smoothedFps; private const float FpsSmoothing = 0.92f; private const float TextInterval = 0.2f; private static float _nextTextAt; private static bool _cleared = true; public static void OnLevelLoaded() { EnsureRoot(); TryParentToWrist(); } public static void Tick() { if (!Settings.WristHudEnabled.Value) { if (!_cleared) { if ((Object)(object)_tm != (Object)null) { _tm.text = ""; } _cleared = true; } return; } EnsureRoot(); if ((Object)(object)_root.transform.parent == (Object)null) { TryParentToWrist(); } UpdateFps(); if (Time.unscaledTime >= _nextTextAt) { _nextTextAt = Time.unscaledTime + 0.2f; RenderText(); _cleared = false; } } private static void EnsureRoot() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("QualityLab_WristHud"); Object.DontDestroyOnLoad((Object)(object)_root); _tm = _root.AddComponent(); _tm.fontSize = 60; _tm.characterSize = 0.004f; _tm.anchor = (TextAnchor)4; _tm.alignment = (TextAlignment)0; _tm.color = new Color(0.85f, 1f, 0.85f); _tm.richText = true; } } private static void TryParentToWrist() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { Hand leftHand = Player.LeftHand; if (!((Object)(object)leftHand == (Object)null)) { _root.transform.SetParent(((Component)leftHand).transform, false); _root.transform.localPosition = new Vector3(0.04f, 0.04f, 0f); _root.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); } } } private static void UpdateFps() { float unscaledDeltaTime = Time.unscaledDeltaTime; if (unscaledDeltaTime > 0f) { float num = 1f / unscaledDeltaTime; _smoothedFps = _smoothedFps * 0.92f + num * 0.07999998f; } } private static void RenderText() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("Quality Of Lab\n"); stringBuilder.Append("FPS ").Append(_smoothedFps.ToString("F0")).Append('\n'); stringBuilder.Append("Grav ").Append(Physics.gravity.y.ToString("F1")).Append('\n'); if (Settings.GodMode.Value) { stringBuilder.Append("[GOD]\n"); } if (Settings.OneHitKill.Value) { stringBuilder.Append("[1HK]\n"); } if (Settings.InfiniteAmmo.Value) { stringBuilder.Append("[AMMO]\n"); } stringBuilder.Append("D ").Append(Stats.DistanceMeters.ToString("F0")).Append("m TP ") .Append(Stats.TeleportCount); _tm.text = stringBuilder.ToString(); } } }