using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using AudioImportLib; using BONESQUAD; using BONESQUAD.Modules.BulletWhiz; using BONESQUAD.Modules.Compass; using BONESQUAD.Modules.FusionCompat; using BONESQUAD.Modules.HUD; using BONESQUAD.Modules.RadialMenu; using BONESQUAD.Modules.Regeneration; using BONESQUAD.Modules.SlowRegen; using BONESQUAD.Modules.SlowWalk; using BONESQUAD.Modules.SoundFalloff; using BONESQUAD.Modules.Spawning; using BONESQUAD.Modules.Visual; using BONESQUAD.Modules.Voice; using BoneLib; using BoneLib.BoneMenu; using BoneLib.Notifications; using HarmonyLib; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSLZ.VFX; using Il2CppSLZ.VRMK; using LabFusion.Data; using LabFusion.Entities; using LabFusion.Extensions; using LabFusion.Marrow.Extenders; using LabFusion.Math; using LabFusion.Network; using LabFusion.Network.Serialization; using LabFusion.Player; using LabFusion.RPC; using LabFusion.SDK.Modules; using LabFusion.Senders; using LabFusion.Utilities; using LabFusion.Voice; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(BonesquadMod), "BONESQUAD", "11.1.0", "lunobe", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonOptionalDependencies(new string[] { "LabFusion" })] [assembly: HarmonyDontPatchAll] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyVersion("0.0.0.0")] namespace BONESQUAD { internal static class BonesquadMenu { private static BoolElement _swEnabled; private static FloatElement _swMultiplier; private static BoolElement _bwEnabled; private static FloatElement _bwVolume; private static FloatElement _bwMinDistance; private static FloatElement _bwPassDistance; private static BoolElement _sfEnabled; private static FloatElement _sfLocalRadius; private static FloatElement _sfQuietMaxDist; private static FloatElement _sfMediumMaxDist; private static FloatElement _sfLoudMaxDist; private static BoolElement _rgEnabled; private static FloatElement _rgSlowFactor; private static BoolElement _rgBleedingEnabled; private static FloatElement _rgBleedingModifier; private static BoolElement _spKoRespawn; private static BoolElement _vlEnabled; private static BoolElement _vlAlwaysOnTop; private static BoolElement _vlShowHpText; private static FloatElement _vlHpTextSize; private static FloatElement _vlIconSize; private static FloatElement _vlPosX; private static FloatElement _vlPosY; private static FloatElement _vlDepth; private static BoolElement _vlSmoothFollow; private static FloatElement _vlFollowSpeedX; private static FloatElement _vlFollowSpeedY; private static BoolElement _cmEnabled; private static BoolElement _cmAlwaysOnTop; private static BoolElement _cmRussian; private static BoolElement _cmShowArrow; private static FloatElement _cmScale; private static FloatElement _cmPosY; private static FloatElement _cmDepth; private static FloatElement _cmSmooth; private static FloatElement _cmBgAlpha; private static FloatElement _cmBgHeight; private static FloatElement _cmFadeEdge; private static FloatElement _cmFadeEdgeH; private static FloatElement _cmFadeSpread; private static FloatElement _cmFontCard; private static FloatElement _cmFontLarge; private static FloatElement _cmFontSmall; private static FloatElement _cmArrowSize; private static FloatElement _cmArrowHeight; private static BoolElement _cmSmoothFollow; private static FloatElement _cmFollowSpeedX; private static FloatElement _cmFollowSpeedY; private static BoolElement _cpEnabled; private static BoolElement _cpShowNames; private static BoolElement _cpShowDist; private static BoolElement _cpShowBehind; private static FloatElement _cpIconSize; private static FloatElement _cpNameSize; private static FloatElement _cpDistSize; private static FloatElement _cpHeight; private static BoolElement _ptEnabled; private static BoolElement _ptShowDist; private static BoolElement _ptShowBehind; private static FloatElement _ptLetterSize; private static FloatElement _ptDistSize; private static FloatElement _ptHeight; private static BoolElement _pgShowPings; private static BoolElement _pgShowDistance; private static BoolElement _pgShowOwnerLabel; private static FloatElement _pgIconSize; private static FloatElement _pgDistSize; private static FloatElement _pgOwnerSize; private static BoolElement _pgUseRightHand; private static BoolElement _pgMarkersDie; private static FloatElement _pgLifetime; private static BoolElement _ntEnabled; private static FloatElement _ntSize; private static FloatElement _ntDepth; private static FloatElement _ntPosY; private static BoolElement _ntSmoothFollow; private static FloatElement _ntFollowSpeedX; private static FloatElement _ntFollowSpeedY; private static BoolElement _mpRequireBonesquad; internal static void Init(MelonPreferences_Category prefs) { //IL_0017: 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_0072: 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_010f: 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) Page val = Page.Root.CreatePage("BONESQUAD", Color.cyan, 0, true); BuildFaqPage(val); val.CreateFunction("─── GAMEPLAY ───", Color.gray, (Action)null); BuildMovementPage(val, prefs); BuildBulletWhizPage(val, prefs); BuildSoundFalloffPage(val, prefs); BuildRegenerationPage(val, prefs); val.CreateFunction("─── HUD ───", Color.gray, (Action)null); BuildHpPage(val, prefs); BuildCompassPage(val, prefs); Page val2 = BuildPingMarkersPage(val, prefs); ((Element)val.CreatePageLink(val2)).SetTooltip("Markers you place are visible to all other players who have BONESQUAD installed."); Page val3 = BuildCaptureNotifsPage(val, prefs); ((Element)val.CreatePageLink(val3)).SetTooltip("Requires a BONESQUAD server (see FAQ above). Outside of a server session these notifications will never appear. All capture points, the capture system and point ownership are implemented server-side."); if (FusionCompat.IsAvailable) { val.CreateFunction("─── MULTIPLAYER ───", Color.gray, (Action)null); BuildMultiplayerPage(val, prefs); } val.CreateFunction("──────────────────", Color.gray, (Action)null); val.CreateFunction("Reset All to Defaults", Color.red, (Action)delegate { SlowWalkModule.ResetToDefaults(prefs); BulletWhizModule.ResetToDefaults(prefs); SoundFalloffModule.ResetToDefaults(prefs); RegenerationModule.ResetToDefaults(prefs); VisualModule.ResetToDefaults(prefs); CompassModule.ResetToDefaults(prefs); CaptureEventHandler.ResetToDefaults(prefs); PingMarkerModule.ResetToDefaults(prefs); RefreshMovementElements(); RefreshBulletWhizElements(); RefreshSoundFalloffElements(); RefreshRegenerationElements(); RefreshHpElements(); RefreshCompassElements(); RefreshCompassPingsElements(); RefreshCompassPointsElements(); RefreshPingMarkersElements(); RefreshCaptureNotifsElements(); }); } private static void BuildFaqPage(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_0033: 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_0068: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("FAQ", Color.white, 0, true); ((Element)obj.CreateFunction("What is this mod?", Color.white, (Action)null)).SetTooltip("This mod was developed for our RP project BONESQUAD RP. The project specializes in military theme. The core idea is to bring SQUAD into virtual reality. I — Lunobe (Code) — and my friend Kikelap (SDK) develop incredible mods for maximum immersion. BONESQUAD mod is the best RP code mod in BONELAB."); ((Element)obj.CreateFunction("Server-side?", Color.white, (Action)null)).SetTooltip("Some features need a server-side component and only work on our 24/7 BONESQUAD server. This part is not public and won't be released soon. Server-dependent: Capture Points · Admin Voice · groups/factions · Rally Points/HABs · ping group filtering · Clear Debris/Decals."); ((Element)obj.CreateFunction("Server-locked?", Color.white, (Action)null)).SetTooltip("To keep things fair, the server forces certain settings on join, preventing anyone from tweaking them for an advantage. Locked while connected, restored to your own values on disconnect. Locked: Slow Walk (enabled, speed) · Sound Falloff (ranges) · Regeneration (enabled, slow factor, bleeding enabled, bleed rate)."); ((Element)obj.CreateFunction("Join us!!", Color.white, (Action)null)).SetTooltip("We are actively looking for new people to play with. We have exciting and realistic sessions. You are welcome to join us! Discord invite code: 6KHRhw5Vk3 | Short Discord Link: https://dc.gg/bq | Our website: bonesquad.club"); } private static void BuildMovementPage(Page parent, MelonPreferences_Category prefs) { //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_005f: 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("Movement", Color.cyan, 0, true); _swEnabled = obj.CreateBool("Slow Walk", Color.cyan, SlowWalkModule.Enabled.Value, (Action)delegate(bool val) { if (SlowWalkModule.ServerLocked) { _swEnabled.Value = SlowWalkModule.Enabled.Value; } else { SlowWalkModule.OnToggle(val); prefs.SaveToFile(true); } }); ((Element)_swEnabled).SetTooltip("Server-controlled. The server forces Slow Walk on or off for all players to standardize movement pace. When you join, the server pushes its Enabled and Speed Multiplier values."); _swMultiplier = obj.CreateFloat("Speed Multiplier", Color.white, SlowWalkModule.SpeedMultiplier.Value, 0.05f, 0.1f, 2f, (Action)delegate(float val) { if (SlowWalkModule.ServerLocked) { _swMultiplier.Value = SlowWalkModule.SpeedMultiplier.Value; } else { SlowWalkModule.OnSpeedMultiplierChanged(val); prefs.SaveToFile(true); } }); ((Element)_swMultiplier).SetTooltip("Server-controlled. The server sets a fixed multiplier for all players. Your local value is overwritten on join and cannot be changed while connected."); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { if (!SlowWalkModule.ServerLocked) { SlowWalkModule.ResetToDefaults(prefs); RefreshMovementElements(); } }); } private static void RefreshMovementElements() { _swEnabled.Value = SlowWalkModule.Enabled.Value; _swMultiplier.Value = SlowWalkModule.SpeedMultiplier.Value; } private static void BuildBulletWhizPage(Page parent, MelonPreferences_Category prefs) { //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_0050: 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_00c4: 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) Page obj = parent.CreatePage("Bullet Whiz", Color.yellow, 0, true); _bwEnabled = obj.CreateBool("Enabled", Color.yellow, BulletWhizModule.Enabled.Value, (Action)delegate(bool val) { BulletWhizModule.OnToggle(val); prefs.SaveToFile(true); }); _bwVolume = obj.CreateFloat("Volume", Color.white, BulletWhizModule.Volume.Value, 5f, 0f, 200f, (Action)delegate(float val) { BulletWhizModule.Volume.Value = val; prefs.SaveToFile(true); }); _bwMinDistance = obj.CreateFloat("Min Distance", Color.white, BulletWhizModule.MinDistance.Value, 5f, 0f, 500f, (Action)delegate(float val) { BulletWhizModule.MinDistance.Value = val; prefs.SaveToFile(true); }); _bwPassDistance = obj.CreateFloat("Pass Distance", Color.white, BulletWhizModule.PassDistance.Value, 0.5f, 0.5f, 20f, (Action)delegate(float val) { BulletWhizModule.PassDistance.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { BulletWhizModule.ResetToDefaults(prefs); RefreshBulletWhizElements(); }); } private static void RefreshBulletWhizElements() { _bwEnabled.Value = BulletWhizModule.Enabled.Value; _bwVolume.Value = BulletWhizModule.Volume.Value; _bwMinDistance.Value = BulletWhizModule.MinDistance.Value; _bwPassDistance.Value = BulletWhizModule.PassDistance.Value; } private static void BuildSoundFalloffPage(Page parent, MelonPreferences_Category prefs) { //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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_014c: 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) Page obj = parent.CreatePage("Sound Falloff", Color.green, 0, true); _sfEnabled = obj.CreateBool("Enabled", Color.green, SoundFalloffModule.Enabled.Value, (Action)delegate(bool val) { if (SoundFalloffModule.ServerLocked) { _sfEnabled.Value = SoundFalloffModule.Enabled.Value; } else { SoundFalloffModule.OnToggle(val); prefs.SaveToFile(true); } }); ((Element)_sfEnabled).SetTooltip("Server-controlled. The server enforces Sound Falloff on or off so all players hear gunfire at the same distances. On join, the server pushes all six falloff parameters: Enabled, Local Radius, Quiet/Medium/Loud Max."); _sfLocalRadius = obj.CreateFloat("Local Radius", Color.white, SoundFalloffModule.LocalRadius.Value, 0.5f, 0f, 20f, (Action)delegate(float val) { if (SoundFalloffModule.ServerLocked) { _sfLocalRadius.Value = SoundFalloffModule.LocalRadius.Value; } else { SoundFalloffModule.LocalRadius.Value = val; prefs.SaveToFile(true); } }); ((Element)_sfLocalRadius).SetTooltip("Server-controlled. Sounds within this radius are always heard at full volume regardless of category. Set by the server to match its range limits."); obj.CreateFunction("─── Range Limits ───", Color.gray, (Action)null); _sfQuietMaxDist = obj.CreateFloat("Quiet Max", Color.white, SoundFalloffModule.QuietMaxDist.Value, 5f, 5f, 200f, (Action)delegate(float val) { if (SoundFalloffModule.ServerLocked) { _sfQuietMaxDist.Value = SoundFalloffModule.QuietMaxDist.Value; } else { SoundFalloffModule.QuietMaxDist.Value = val; prefs.SaveToFile(true); } }); ((Element)_sfQuietMaxDist).SetTooltip("Server-controlled. Max range for quiet sounds (reloads, footsteps). Set by the server."); _sfMediumMaxDist = obj.CreateFloat("Medium Max", Color.white, SoundFalloffModule.MediumMaxDist.Value, 10f, 20f, 500f, (Action)delegate(float val) { if (SoundFalloffModule.ServerLocked) { _sfMediumMaxDist.Value = SoundFalloffModule.MediumMaxDist.Value; } else { SoundFalloffModule.MediumMaxDist.Value = val; prefs.SaveToFile(true); } }); ((Element)_sfMediumMaxDist).SetTooltip("Server-controlled. Max range for medium sounds (gunshots, impacts). Set by the server."); _sfLoudMaxDist = obj.CreateFloat("Loud Max", Color.white, SoundFalloffModule.LoudMaxDist.Value, 50f, 100f, 2000f, (Action)delegate(float val) { if (SoundFalloffModule.ServerLocked) { _sfLoudMaxDist.Value = SoundFalloffModule.LoudMaxDist.Value; } else { SoundFalloffModule.LoudMaxDist.Value = val; prefs.SaveToFile(true); } }); ((Element)_sfLoudMaxDist).SetTooltip("Server-controlled. Max range for loud sounds (explosions, cannons). Set by the server."); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { if (!SoundFalloffModule.ServerLocked) { SoundFalloffModule.ResetToDefaults(prefs); RefreshSoundFalloffElements(); } }); } private static void RefreshSoundFalloffElements() { _sfEnabled.Value = SoundFalloffModule.Enabled.Value; _sfLocalRadius.Value = SoundFalloffModule.LocalRadius.Value; _sfQuietMaxDist.Value = SoundFalloffModule.QuietMaxDist.Value; _sfMediumMaxDist.Value = SoundFalloffModule.MediumMaxDist.Value; _sfLoudMaxDist.Value = SoundFalloffModule.LoudMaxDist.Value; } private static void BuildRegenerationPage(Page parent, MelonPreferences_Category prefs) { //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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Regeneration", Color.red, 0, true); _rgEnabled = obj.CreateBool("Slow Regen", Color.red, RegenerationModule.Enabled.Value, (Action)delegate(bool val) { if (RegenerationModule.ServerLocked) { _rgEnabled.Value = RegenerationModule.Enabled.Value; } else { RegenerationModule.OnToggle(val); prefs.SaveToFile(true); } }); ((Element)_rgEnabled).SetTooltip("Server-controlled. The server forces Slow Regen on or off for all players. On join, the server pushes four regen parameters: Slow Regen Enabled, Slow Factor, Bleeding Enabled, Bleed Rate."); _rgSlowFactor = obj.CreateFloat("Slow Factor", Color.white, RegenerationModule.SlowFactor.Value, 0.5f, 1f, 20f, (Action)delegate(float val) { if (RegenerationModule.ServerLocked) { _rgSlowFactor.Value = RegenerationModule.SlowFactor.Value; } else { RegenerationModule.OnSlowFactorChanged(val); prefs.SaveToFile(true); } }); ((Element)_rgSlowFactor).SetTooltip("Server-controlled. How many times slower than vanilla regen rate. Set by the server to balance the session's medical system."); obj.CreateFunction("─── Bleeding ───", Color.gray, (Action)null); _rgBleedingEnabled = obj.CreateBool("Bleeding", Color.yellow, RegenerationModule.BleedingEnabled.Value, (Action)delegate(bool val) { if (RegenerationModule.ServerLocked) { _rgBleedingEnabled.Value = RegenerationModule.BleedingEnabled.Value; } else { RegenerationModule.OnBleedingToggle(val); prefs.SaveToFile(true); } }); ((Element)_rgBleedingEnabled).SetTooltip("Server-controlled. The server forces the bleeding system on or off. Usually matches Slow Regen state."); _rgBleedingModifier = obj.CreateFloat("Bleed Rate", Color.white, RegenerationModule.BleedingModifier.Value, 0.1f, 0.5f, 3f, (Action)delegate(float val) { if (RegenerationModule.ServerLocked) { _rgBleedingModifier.Value = RegenerationModule.BleedingModifier.Value; } else { RegenerationModule.OnBleedingModifierChanged(val); prefs.SaveToFile(true); } }); ((Element)_rgBleedingModifier).SetTooltip("Server-controlled. Multiplier for bleed drain speed. Set by the server — higher values make bleeding more lethal."); obj.CreateFunction("─── Knockout ───", Color.gray, (Action)null); _spKoRespawn = obj.CreateBool("Auto Respawn", Color.white, RespawnModule.KnockoutTimerEnabled.Value, (Action)delegate(bool val) { RespawnModule.OnKnockoutTimerToggle(val); prefs.SaveToFile(true); }); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { if (!RegenerationModule.ServerLocked) { RegenerationModule.ResetToDefaults(prefs); RefreshRegenerationElements(); } }); } private static void RefreshRegenerationElements() { _rgEnabled.Value = RegenerationModule.Enabled.Value; _rgSlowFactor.Value = RegenerationModule.SlowFactor.Value; _rgBleedingEnabled.Value = RegenerationModule.BleedingEnabled.Value; _rgBleedingModifier.Value = RegenerationModule.BleedingModifier.Value; _spKoRespawn.Value = RespawnModule.KnockoutTimerEnabled.Value; } private static void BuildHpPage(Page parent, MelonPreferences_Category prefs) { //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_0050: 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_00a6: 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_00f2: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("HP Indicator", Color.red, 0, true); _vlEnabled = obj.CreateBool("Enabled", Color.red, VisualModule.Enabled.Value, (Action)delegate(bool val) { VisualModule.OnToggle(val); prefs.SaveToFile(true); }); _vlAlwaysOnTop = obj.CreateBool("Always on Top", Color.white, VisualModule.AlwaysOnTop.Value, (Action)delegate(bool val) { VisualModule.AlwaysOnTop.Value = val; VisualModule.Invalidate(); prefs.SaveToFile(true); }); _vlShowHpText = obj.CreateBool("HP Text", Color.white, VisualModule.ShowHpText.Value, (Action)delegate(bool val) { VisualModule.OnShowHpTextChanged(val); prefs.SaveToFile(true); }); _vlHpTextSize = obj.CreateFloat("HP Text Size", Color.white, VisualModule.HpTextSize.Value, 0.001f, 0.003f, 0.04f, (Action)delegate(float val) { VisualModule.OnHpTextSizeChanged(val); prefs.SaveToFile(true); }); obj.CreateFunction("─── Position ───", Color.gray, (Action)null); _vlIconSize = obj.CreateFloat("Icon Size", Color.white, VisualModule.IconSize.Value, 0.005f, 0.005f, 0.15f, (Action)delegate(float val) { VisualModule.OnSizeChanged(val); prefs.SaveToFile(true); }); _vlPosX = obj.CreateFloat("Position X", Color.white, VisualModule.PosX.Value, 0.01f, -0.5f, 0.5f, (Action)delegate(float val) { VisualModule.OnPosXChanged(val); prefs.SaveToFile(true); }); _vlPosY = obj.CreateFloat("Position Y", Color.white, VisualModule.PosY.Value, 0.01f, -0.5f, 0.5f, (Action)delegate(float val) { VisualModule.OnPosYChanged(val); prefs.SaveToFile(true); }); _vlDepth = obj.CreateFloat("Depth", Color.white, VisualModule.Depth.Value, 0.05f, 0.3f, 2f, (Action)delegate(float val) { VisualModule.OnDepthChanged(val); prefs.SaveToFile(true); }); obj.CreateFunction("─── Follow ───", Color.gray, (Action)null); _vlSmoothFollow = obj.CreateBool("Smooth Follow", Color.white, VisualModule.SmoothFollow.Value, (Action)delegate(bool val) { VisualModule.SmoothFollow.Value = val; prefs.SaveToFile(true); }); _vlFollowSpeedX = obj.CreateFloat("Speed X", Color.white, VisualModule.FollowSpeedX.Value, 1f, 1f, 30f, (Action)delegate(float val) { VisualModule.FollowSpeedX.Value = val; prefs.SaveToFile(true); }); _vlFollowSpeedY = obj.CreateFloat("Speed Y", Color.white, VisualModule.FollowSpeedY.Value, 1f, 1f, 30f, (Action)delegate(float val) { VisualModule.FollowSpeedY.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { VisualModule.ResetToDefaults(prefs); RefreshHpElements(); }); } private static void RefreshHpElements() { _vlEnabled.Value = VisualModule.Enabled.Value; _vlAlwaysOnTop.Value = VisualModule.AlwaysOnTop.Value; _vlShowHpText.Value = VisualModule.ShowHpText.Value; _vlHpTextSize.Value = VisualModule.HpTextSize.Value; _vlIconSize.Value = VisualModule.IconSize.Value; _vlPosX.Value = VisualModule.PosX.Value; _vlPosY.Value = VisualModule.PosY.Value; _vlDepth.Value = VisualModule.Depth.Value; _vlSmoothFollow.Value = VisualModule.SmoothFollow.Value; _vlFollowSpeedX.Value = VisualModule.FollowSpeedX.Value; _vlFollowSpeedY.Value = VisualModule.FollowSpeedY.Value; } private static void BuildCompassPage(Page parent, MelonPreferences_Category prefs) { //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_0050: 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_00a6: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: 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_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_0513: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Compass", Color.yellow, 0, true); _cmEnabled = obj.CreateBool("Enabled", Color.yellow, CompassModule.Enabled.Value, (Action)delegate(bool enabled) { CompassModule.OnToggle(enabled); prefs.SaveToFile(true); }); _cmAlwaysOnTop = obj.CreateBool("Always on Top", Color.white, CompassModule.AlwaysOnTop.Value, (Action)delegate(bool value) { CompassModule.AlwaysOnTop.Value = value; CompassModule.Invalidate(); prefs.SaveToFile(true); }); _cmRussian = obj.CreateBool("Russian Labels", Color.white, CompassModule.UseRussian.Value, (Action)delegate(bool value) { CompassModule.UseRussian.Value = value; prefs.SaveToFile(true); }); _cmShowArrow = obj.CreateBool("Show Arrow", Color.white, CompassModule.ShowArrow.Value, (Action)delegate(bool value) { CompassModule.ShowArrow.Value = value; prefs.SaveToFile(true); }); obj.CreateFunction("─── Layout ───", Color.gray, (Action)null); _cmScale = obj.CreateFloat("Scale", Color.white, CompassModule.Scale.Value, 0.1f, 0.3f, 3f, (Action)delegate(float value) { CompassModule.Scale.Value = value; prefs.SaveToFile(true); }); _cmPosY = obj.CreateFloat("Position Y", Color.white, CompassModule.PosY.Value, 0.01f, -0.5f, 0.5f, (Action)delegate(float value) { CompassModule.PosY.Value = value; prefs.SaveToFile(true); }); _cmDepth = obj.CreateFloat("Depth", Color.white, CompassModule.Depth.Value, 0.05f, 0.3f, 2f, (Action)delegate(float value) { CompassModule.Depth.Value = value; prefs.SaveToFile(true); }); _cmSmooth = obj.CreateFloat("Smoothing", Color.white, 31f - CompassModule.SmoothFactor.Value, 0.5f, 1f, 30f, (Action)delegate(float num) { CompassModule.SmoothFactor.Value = 31f - num; prefs.SaveToFile(true); }); obj.CreateFunction("─── Background ───", Color.gray, (Action)null); _cmBgAlpha = obj.CreateFloat("BG Alpha", Color.white, CompassModule.BgAlpha.Value, 0.05f, 0f, 0.8f, (Action)delegate(float value) { CompassModule.BgAlpha.Value = value; prefs.SaveToFile(true); }); _cmBgHeight = obj.CreateFloat("BG Height", Color.white, CompassModule.BgHeightMult.Value, 0.1f, 0.2f, 4f, (Action)delegate(float value) { CompassModule.BgHeightMult.Value = value; prefs.SaveToFile(true); }); _cmFadeEdge = obj.CreateFloat("Fade V", Color.white, CompassModule.FadeEdge.Value, 0.05f, 0f, 1f, (Action)delegate(float value) { CompassModule.FadeEdge.Value = value; prefs.SaveToFile(true); }); _cmFadeEdgeH = obj.CreateFloat("Fade H", Color.white, CompassModule.FadeEdgeH.Value, 0.05f, 0f, 1f, (Action)delegate(float value) { CompassModule.FadeEdgeH.Value = value; prefs.SaveToFile(true); }); _cmFadeSpread = obj.CreateFloat("Fade Shape", Color.white, CompassModule.FadeSpread.Value, 0.1f, 0.2f, 4f, (Action)delegate(float value) { CompassModule.FadeSpread.Value = value; prefs.SaveToFile(true); }); obj.CreateFunction("─── Fonts ───", Color.gray, (Action)null); _cmFontCard = obj.CreateFloat("Cardinals", Color.white, CompassModule.FontScaleCard.Value, 0.05f, 0.3f, 3f, (Action)delegate(float value) { CompassModule.FontScaleCard.Value = value; prefs.SaveToFile(true); }); _cmFontLarge = obj.CreateFloat("Large Numbers", Color.white, CompassModule.FontScaleLarge.Value, 0.05f, 0.3f, 3f, (Action)delegate(float value) { CompassModule.FontScaleLarge.Value = value; prefs.SaveToFile(true); }); _cmFontSmall = obj.CreateFloat("Small Numbers", Color.white, CompassModule.FontScaleSmall.Value, 0.05f, 0.3f, 3f, (Action)delegate(float value) { CompassModule.FontScaleSmall.Value = value; prefs.SaveToFile(true); }); _cmArrowSize = obj.CreateFloat("Arrow Size", Color.white, CompassModule.ArrowSize.Value, 0.001f, 0.001f, 0.03f, (Action)delegate(float value) { CompassModule.ArrowSize.Value = value; prefs.SaveToFile(true); }); _cmArrowHeight = obj.CreateFloat("Arrow Height", Color.white, CompassModule.ArrowHeight.Value, 0.001f, 0f, 0.03f, (Action)delegate(float value) { CompassModule.ArrowHeight.Value = value; prefs.SaveToFile(true); }); obj.CreateFunction("─── Follow ───", Color.gray, (Action)null); _cmSmoothFollow = obj.CreateBool("Smooth Follow", Color.white, CompassModule.SmoothFollow.Value, (Action)delegate(bool value) { CompassModule.SmoothFollow.Value = value; prefs.SaveToFile(true); }); _cmFollowSpeedX = obj.CreateFloat("Speed X", Color.white, CompassModule.FollowSpeedX.Value, 1f, 1f, 30f, (Action)delegate(float value) { CompassModule.FollowSpeedX.Value = value; prefs.SaveToFile(true); }); _cmFollowSpeedY = obj.CreateFloat("Speed Y", Color.white, CompassModule.FollowSpeedY.Value, 1f, 1f, 30f, (Action)delegate(float value) { CompassModule.FollowSpeedY.Value = value; prefs.SaveToFile(true); }); BuildCompassPingsPage(obj, prefs); Page val = BuildCompassPointsPage(obj, prefs); ((Element)obj.CreatePageLink(val)).SetTooltip("Requires a BONESQUAD server (see FAQ above). Outside of a server session capture points do not exist. All capture points, the capture system and point ownership are implemented server-side."); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { CompassModule.ResetToDefaults(prefs); RefreshCompassElements(); RefreshCompassPingsElements(); RefreshCompassPointsElements(); }); } private static void RefreshCompassElements() { _cmEnabled.Value = CompassModule.Enabled.Value; _cmAlwaysOnTop.Value = CompassModule.AlwaysOnTop.Value; _cmRussian.Value = CompassModule.UseRussian.Value; _cmShowArrow.Value = CompassModule.ShowArrow.Value; _cmScale.Value = CompassModule.Scale.Value; _cmPosY.Value = CompassModule.PosY.Value; _cmDepth.Value = CompassModule.Depth.Value; _cmSmooth.Value = 31f - CompassModule.SmoothFactor.Value; _cmBgAlpha.Value = CompassModule.BgAlpha.Value; _cmBgHeight.Value = CompassModule.BgHeightMult.Value; _cmFadeEdge.Value = CompassModule.FadeEdge.Value; _cmFadeEdgeH.Value = CompassModule.FadeEdgeH.Value; _cmFadeSpread.Value = CompassModule.FadeSpread.Value; _cmFontCard.Value = CompassModule.FontScaleCard.Value; _cmFontLarge.Value = CompassModule.FontScaleLarge.Value; _cmFontSmall.Value = CompassModule.FontScaleSmall.Value; _cmArrowSize.Value = CompassModule.ArrowSize.Value; _cmArrowHeight.Value = CompassModule.ArrowHeight.Value; _cmSmoothFollow.Value = CompassModule.SmoothFollow.Value; _cmFollowSpeedX.Value = CompassModule.FollowSpeedX.Value; _cmFollowSpeedY.Value = CompassModule.FollowSpeedY.Value; } private static void BuildCompassPingsPage(Page parent, MelonPreferences_Category prefs) { //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_0050: 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_00a6: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Pings on Compass", Color.cyan, 0, true); _cpEnabled = obj.CreateBool("Enabled", Color.cyan, CompassModule.PingsEnabled.Value, (Action)delegate(bool val) { CompassModule.PingsEnabled.Value = val; prefs.SaveToFile(true); }); _cpShowNames = obj.CreateBool("Show Names", Color.white, CompassModule.PingsShowNames.Value, (Action)delegate(bool val) { CompassModule.PingsShowNames.Value = val; prefs.SaveToFile(true); }); _cpShowDist = obj.CreateBool("Show Distance", Color.white, CompassModule.PingsShowDistance.Value, (Action)delegate(bool val) { CompassModule.PingsShowDistance.Value = val; prefs.SaveToFile(true); }); _cpShowBehind = obj.CreateBool("Show Behind", Color.white, CompassModule.PingsShowBehind.Value, (Action)delegate(bool val) { CompassModule.PingsShowBehind.Value = val; prefs.SaveToFile(true); }); _cpIconSize = obj.CreateFloat("Icon Size", Color.white, CompassModule.PingsIconSize.Value, 0.002f, 0.002f, 0.04f, (Action)delegate(float val) { CompassModule.PingsIconSize.Value = val; prefs.SaveToFile(true); }); _cpNameSize = obj.CreateFloat("Name Size", Color.white, CompassModule.PingsNameSize.Value, 0.0005f, 0.001f, 0.01f, (Action)delegate(float val) { CompassModule.PingsNameSize.Value = val; prefs.SaveToFile(true); }); _cpDistSize = obj.CreateFloat("Distance Size", Color.white, CompassModule.PingsDistSize.Value, 0.0005f, 0.001f, 0.01f, (Action)delegate(float val) { CompassModule.PingsDistSize.Value = val; prefs.SaveToFile(true); }); _cpHeight = obj.CreateFloat("Height", Color.white, CompassModule.PingsHeight.Value, 0.003f, 0.005f, 0.1f, (Action)delegate(float val) { CompassModule.PingsHeight.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { CompassModule.PingsEnabled.Value = true; CompassModule.PingsShowNames.Value = true; CompassModule.PingsShowDistance.Value = true; CompassModule.PingsShowBehind.Value = true; CompassModule.PingsIconSize.Value = 0.012f; CompassModule.PingsNameSize.Value = 0.003f; CompassModule.PingsDistSize.Value = 0.003f; CompassModule.PingsHeight.Value = 0.028f; prefs.SaveToFile(true); RefreshCompassPingsElements(); }); } private static void RefreshCompassPingsElements() { _cpEnabled.Value = CompassModule.PingsEnabled.Value; _cpShowNames.Value = CompassModule.PingsShowNames.Value; _cpShowDist.Value = CompassModule.PingsShowDistance.Value; _cpShowBehind.Value = CompassModule.PingsShowBehind.Value; _cpIconSize.Value = CompassModule.PingsIconSize.Value; _cpNameSize.Value = CompassModule.PingsNameSize.Value; _cpDistSize.Value = CompassModule.PingsDistSize.Value; _cpHeight.Value = CompassModule.PingsHeight.Value; } private static Page BuildCompassPointsPage(Page parent, MelonPreferences_Category prefs) { //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_0050: 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_00a6: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Points on Compass", Color.yellow, 0, false); _ptEnabled = obj.CreateBool("Enabled", Color.cyan, CompassModule.PointsEnabled.Value, (Action)delegate(bool val) { CompassModule.PointsEnabled.Value = val; prefs.SaveToFile(true); }); _ptShowDist = obj.CreateBool("Show Distance", Color.white, CompassModule.PointsShowDist.Value, (Action)delegate(bool val) { CompassModule.PointsShowDist.Value = val; prefs.SaveToFile(true); }); _ptShowBehind = obj.CreateBool("Show Behind", Color.white, CompassModule.PointsShowBehind.Value, (Action)delegate(bool val) { CompassModule.PointsShowBehind.Value = val; prefs.SaveToFile(true); }); _ptLetterSize = obj.CreateFloat("Letter Size", Color.white, CompassModule.PointsLetterSize.Value, 0.001f, 0.001f, 0.02f, (Action)delegate(float val) { CompassModule.PointsLetterSize.Value = val; prefs.SaveToFile(true); }); _ptDistSize = obj.CreateFloat("Distance Size", Color.white, CompassModule.PointsDistSize.Value, 0.0005f, 0.001f, 0.01f, (Action)delegate(float val) { CompassModule.PointsDistSize.Value = val; prefs.SaveToFile(true); }); _ptHeight = obj.CreateFloat("Height", Color.white, CompassModule.PointsHeight.Value, 0.003f, 0.005f, 0.1f, (Action)delegate(float val) { CompassModule.PointsHeight.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { CompassModule.PointsEnabled.Value = true; CompassModule.PointsShowDist.Value = true; CompassModule.PointsShowBehind.Value = true; CompassModule.PointsLetterSize.Value = 0.005f; CompassModule.PointsDistSize.Value = 0.003f; CompassModule.PointsHeight.Value = 0.028f; prefs.SaveToFile(true); RefreshCompassPointsElements(); }); return obj; } private static void RefreshCompassPointsElements() { _ptEnabled.Value = CompassModule.PointsEnabled.Value; _ptShowDist.Value = CompassModule.PointsShowDist.Value; _ptShowBehind.Value = CompassModule.PointsShowBehind.Value; _ptLetterSize.Value = CompassModule.PointsLetterSize.Value; _ptDistSize.Value = CompassModule.PointsDistSize.Value; _ptHeight.Value = CompassModule.PointsHeight.Value; } private static Page BuildPingMarkersPage(Page parent, MelonPreferences_Category prefs) { //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_0050: 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_008d: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Ping Markers", Color.yellow, 0, false); _pgShowPings = obj.CreateBool("Show Markers", Color.yellow, PingMarkerModule.ShowPings.Value, (Action)delegate(bool val) { PingMarkerModule.ShowPings.Value = val; prefs.SaveToFile(true); }); _pgUseRightHand = obj.CreateBool("Right Hand Placement", Color.white, PingMarkerModule.UseRightHand.Value, (Action)delegate(bool val) { PingMarkerModule.UseRightHand.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("─── Display ───", Color.gray, (Action)null); _pgShowDistance = obj.CreateBool("Show Distance", Color.white, PingMarkerModule.ShowDistance.Value, (Action)delegate(bool val) { PingMarkerModule.ShowDistance.Value = val; prefs.SaveToFile(true); }); _pgShowOwnerLabel = obj.CreateBool("Show Owner", Color.white, PingMarkerModule.ShowOwnerLabel.Value, (Action)delegate(bool val) { PingMarkerModule.ShowOwnerLabel.Value = val; prefs.SaveToFile(true); }); _pgIconSize = obj.CreateFloat("Icon Size", Color.white, PingMarkerModule.IconSize.Value, 0.002f, 0.004f, 0.08f, (Action)delegate(float val) { PingMarkerModule.IconSize.Value = val; prefs.SaveToFile(true); }); _pgDistSize = obj.CreateFloat("Distance Size", Color.white, PingMarkerModule.DistSize.Value, 0.001f, 0.001f, 0.03f, (Action)delegate(float val) { PingMarkerModule.DistSize.Value = val; prefs.SaveToFile(true); }); _pgOwnerSize = obj.CreateFloat("Owner Size", Color.white, PingMarkerModule.OwnerSize.Value, 0.001f, 0.001f, 0.03f, (Action)delegate(float val) { PingMarkerModule.OwnerSize.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("─── Lifetime ───", Color.gray, (Action)null); _pgMarkersDie = obj.CreateBool("Markers Die", Color.white, PingMarkerModule.MarkersDie.Value, (Action)delegate(bool val) { PingMarkerModule.MarkersDie.Value = val; prefs.SaveToFile(true); }); _pgLifetime = obj.CreateFloat("Lifetime (sec)", Color.white, PingMarkerModule.MarkerLifetime.Value, 5f, 5f, 300f, (Action)delegate(float val) { if (PingMarkerModule.ServerLocked) { _pgLifetime.Value = PingMarkerModule.MarkerLifetime.Value; } else { PingMarkerModule.MarkerLifetime.Value = val; prefs.SaveToFile(true); } }); ((Element)_pgLifetime).SetTooltip("Server-controlled. The server sets a fixed marker lifetime so all players' marks expire at the same time. Your local value is overwritten on join."); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { if (!PingMarkerModule.ServerLocked) { PingMarkerModule.ResetToDefaults(prefs); RefreshPingMarkersElements(); } }); return obj; } private static void RefreshPingMarkersElements() { _pgShowPings.Value = PingMarkerModule.ShowPings.Value; _pgShowDistance.Value = PingMarkerModule.ShowDistance.Value; _pgShowOwnerLabel.Value = PingMarkerModule.ShowOwnerLabel.Value; _pgIconSize.Value = PingMarkerModule.IconSize.Value; _pgDistSize.Value = PingMarkerModule.DistSize.Value; _pgOwnerSize.Value = PingMarkerModule.OwnerSize.Value; _pgUseRightHand.Value = PingMarkerModule.UseRightHand.Value; _pgMarkersDie.Value = PingMarkerModule.MarkersDie.Value; _pgLifetime.Value = PingMarkerModule.MarkerLifetime.Value; } private static Page BuildCaptureNotifsPage(Page parent, MelonPreferences_Category prefs) { //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_0050: 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_009c: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) Page obj = parent.CreatePage("Capture Notifs", Color.white, 0, false); _ntEnabled = obj.CreateBool("Enabled", Color.white, CaptureEventHandler.NotifEnabled.Value, (Action)delegate(bool val) { CaptureEventHandler.NotifEnabled.Value = val; prefs.SaveToFile(true); }); _ntSize = obj.CreateFloat("Text Size", Color.white, CaptureEventHandler.NotifSize.Value, 0.1f, 0.3f, 5f, (Action)delegate(float val) { CaptureEventHandler.NotifSize.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("─── Position ───", Color.gray, (Action)null); _ntDepth = obj.CreateFloat("Depth", Color.white, CaptureEventHandler.NotifDepth.Value, 0.05f, 0.3f, 2f, (Action)delegate(float val) { CaptureEventHandler.NotifDepth.Value = val; prefs.SaveToFile(true); }); _ntPosY = obj.CreateFloat("Position Y", Color.white, CaptureEventHandler.NotifPosY.Value, 0.01f, -0.5f, 0.5f, (Action)delegate(float val) { CaptureEventHandler.NotifPosY.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("─── Follow ───", Color.gray, (Action)null); _ntSmoothFollow = obj.CreateBool("Smooth Follow", Color.white, CaptureEventHandler.NotifSmoothFollow.Value, (Action)delegate(bool val) { CaptureEventHandler.NotifSmoothFollow.Value = val; prefs.SaveToFile(true); }); _ntFollowSpeedX = obj.CreateFloat("Speed X", Color.white, CaptureEventHandler.NotifFollowSpeedX.Value, 1f, 1f, 30f, (Action)delegate(float val) { CaptureEventHandler.NotifFollowSpeedX.Value = val; prefs.SaveToFile(true); }); _ntFollowSpeedY = obj.CreateFloat("Speed Y", Color.white, CaptureEventHandler.NotifFollowSpeedY.Value, 1f, 1f, 30f, (Action)delegate(float val) { CaptureEventHandler.NotifFollowSpeedY.Value = val; prefs.SaveToFile(true); }); obj.CreateFunction("Reset to Defaults", Color.red, (Action)delegate { CaptureEventHandler.ResetToDefaults(prefs); RefreshCaptureNotifsElements(); }); return obj; } private static void RefreshCaptureNotifsElements() { _ntEnabled.Value = CaptureEventHandler.NotifEnabled.Value; _ntSize.Value = CaptureEventHandler.NotifSize.Value; _ntDepth.Value = CaptureEventHandler.NotifDepth.Value; _ntPosY.Value = CaptureEventHandler.NotifPosY.Value; _ntSmoothFollow.Value = CaptureEventHandler.NotifSmoothFollow.Value; _ntFollowSpeedX.Value = CaptureEventHandler.NotifFollowSpeedX.Value; _ntFollowSpeedY.Value = CaptureEventHandler.NotifFollowSpeedY.Value; } private static void BuildMultiplayerPage(Page parent, MelonPreferences_Category prefs) { //IL_0013: 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) _mpRequireBonesquad = parent.CreatePage("Multiplayer", Color.magenta, 0, true).CreateBool("Require BONESQUAD (Host Only)", Color.white, FusionCompat.RequireBonesquad.Value, (Action)delegate(bool val) { FusionCompat.RequireBonesquad.Value = val; prefs.SaveToFile(true); }); } } public class BonesquadMod : MelonMod { public static BonesquadMod Instance; internal static MelonPreferences_Entry VerboseLogging; public override void OnInitializeMelon() { Instance = this; MelonPreferences_Category prefs = MelonPreferences.CreateCategory("BONESQUAD"); VerboseLogging = prefs.CreateEntry("Debug_VerboseLogging", false, (string)null, "--- Debug --- (hand-edit only, not in BoneMenu)", false, false, (ValueValidator)null, (string)null); Log("=== BONESQUAD Initializing ==="); PatchAllIsolated(); TryInit("SlowWalk", delegate { SlowWalkModule.Init(prefs); }); TryInit("SoundFalloff", delegate { SoundFalloffModule.Init(prefs); }); TryInit("BulletWhiz", delegate { BulletWhizModule.Init(prefs); }); TryInit("Regeneration", delegate { RegenerationModule.Init(prefs); }); TryInit("Visual", delegate { VisualModule.Init(prefs); }); TryInit("Compass", delegate { CompassModule.Init(prefs); }); TryInit("PingMarker", delegate { PingMarkerModule.Init(prefs); }); TryInit("RadialMenu", delegate { RadialMenuModule.Init(prefs); }); TryInit("Respawn", delegate { RespawnModule.Init(prefs); }); TryInit("Notifications", delegate { CaptureEventHandler.Init(prefs); }); FusionCompat.InitPrefs(prefs); RallyPointTracker.Init(); TryInit("BoneMenu", delegate { BonesquadMenu.Init(prefs); }); if (FusionCompat.IsAvailable) { FusionCompat.Init(); } Log("=== BONESQUAD Ready ==="); } private static void TryInit(string name, Action init) { try { init(); } catch (Exception ex) { BonesquadMod instance = Instance; if (instance != null) { ((MelonBase)instance).LoggerInstance.Warning("[Init] " + name + " failed: " + ex.Message); } } } private void PatchAllIsolated() { IEnumerable enumerable = from t in ((object)this).GetType().Assembly.GetTypes() where t.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0 select t; int num = 0; int num2 = 0; foreach (Type item in enumerable) { try { ((MelonBase)this).HarmonyInstance.CreateClassProcessor(item).Patch(); num++; } catch (Exception ex) { num2++; LogWarning("[Harmony] Failed to patch '" + item.FullName + "': " + ex.Message); } } Log($"[Harmony] Patched {num} class(es), {num2} failed"); } public override void OnUpdate() { HudLayer.Update(); RegenerationModule.Update(); RespawnModule.Update(); VisualModule.Update(); CompassModule.Update(); PingMarkerModule.Update(); RadialMenuModule.Update(); CaptureEventHandler.Update(); } public override void OnDeinitializeMelon() { Log("=== BONESQUAD Unloaded ==="); } public static void Log(string msg) { MelonPreferences_Entry verboseLogging = VerboseLogging; if (verboseLogging != null && verboseLogging.Value) { BonesquadMod instance = Instance; if (instance != null) { ((MelonBase)instance).LoggerInstance.Msg(msg); } } } public static void LogWarning(string msg) { BonesquadMod instance = Instance; if (instance != null) { ((MelonBase)instance).LoggerInstance.Warning(msg); } } public static void LogError(string msg) { BonesquadMod instance = Instance; if (instance != null) { ((MelonBase)instance).LoggerInstance.Error(msg); } } } } namespace BONESQUAD.Modules.Voice { [RegisterTypeInIl2Cpp] internal class AdminVoiceFilter : MonoBehaviour { private static readonly ConcurrentQueue _queue = new ConcurrentQueue(); private static bool _didLog; internal static int QueueCount => _queue.Count; public AdminVoiceFilter(IntPtr ptr) : base(ptr) { } [HideFromIl2Cpp] internal static void Enqueue(float[] samples) { while (_queue.Count > 24000) { _queue.TryDequeue(out var _); } foreach (float item in samples) { _queue.Enqueue(item); } } [HideFromIl2Cpp] internal static void Clear() { float result; while (_queue.TryDequeue(out result)) { } } private void OnAudioFilterRead(Il2CppStructArray data, int channels) { if (!_didLog) { _didLog = true; BonesquadMod.Log($"[Voice] OnAudioFilterRead firing (len={((Il2CppArrayBase)(object)data).Length}, ch={channels})."); } int num = ((Il2CppArrayBase)(object)data).Length / channels; for (int i = 0; i < num; i++) { float result; float num2 = (_queue.TryDequeue(out result) ? result : 0f); for (int j = 0; j < channels; j++) { ((Il2CppArrayBase)(object)data)[i * channels + j] = num2; } } } } public class BroadcastAudioData : INetSerializable { public byte[] Bytes = Array.Empty(); public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref Bytes); } } public class BroadcastAudioHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { if (NetworkInfo.IsHost) { return; } try { BroadcastAudioData broadcastAudioData = new BroadcastAudioData(); NetReader val = NetReader.Create(((ReceivedMessage)(ref received)).Bytes); try { broadcastAudioData.Serialize((INetSerializer)(object)val); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(48, 1); defaultInterpolatedStringHandler.AppendLiteral("[Voice] BroadcastAudio received: "); byte[] bytes = broadcastAudioData.Bytes; defaultInterpolatedStringHandler.AppendFormatted((bytes != null) ? bytes.Length : 0); defaultInterpolatedStringHandler.AppendLiteral(" encoded bytes."); BonesquadMod.Log(defaultInterpolatedStringHandler.ToStringAndClear()); VoiceModule.PlayAdminVoice(broadcastAudioData.Bytes); } finally { ((IDisposable)val)?.Dispose(); } } catch (Exception ex) { BonesquadMod.LogWarning("BroadcastAudio: " + ex.Message); } } } internal static class VoiceModule { private static AudioSource _source; private static int _playLogCount; internal static void Init() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_source)) { GameObject val = new GameObject("BONESQUAD_AdminVoice"); Object.DontDestroyOnLoad((Object)val); _source = val.AddComponent(); _source.spatialBlend = 0f; _source.priority = 128; _source.loop = true; int num = AudioSettings.outputSampleRate; if (num <= 0) { num = 48000; } _source.clip = AudioClip.Create("adm_dummy", num, 1, num, false); val.AddComponent(); _source.Play(); BonesquadMod.Log($"[Voice] AdminVoice source initialised (outputSampleRate={num}, isPlaying={_source.isPlaying})."); } } internal static void PlayAdminVoice(byte[] encodedPcm) { try { short[] array = VoiceConverter.Decode(encodedPcm); float[] array2 = new float[array.Length]; for (int i = 0; i < array.Length; i++) { array2[i] = (float)array[i] / 32768f; } AdminVoiceFilter.Enqueue(array2); if (++_playLogCount <= 3) { BonesquadMod.Log($"[Voice] PlayAdminVoice: {array.Length} samples decoded, queue≈{AdminVoiceFilter.QueueCount}."); } } catch (Exception ex) { BonesquadMod.LogWarning("AdminVoice: " + ex.Message); } } } internal static class VoicePatches { internal static void Register(Harmony harmony) { } } } namespace BONESQUAD.Modules.Visual { internal static class VisualModule { internal static MelonPreferences_Entry Enabled; internal static MelonPreferences_Entry AlwaysOnTop; internal static MelonPreferences_Entry IconSize; internal static MelonPreferences_Entry PosX; internal static MelonPreferences_Entry PosY; internal static MelonPreferences_Entry Depth; internal static MelonPreferences_Entry ShowHpText; internal static MelonPreferences_Entry HpTextSize; internal static MelonPreferences_Entry SmoothFollow; internal static MelonPreferences_Entry FollowSpeedX; internal static MelonPreferences_Entry FollowSpeedY; private const float DefaultSize = 0.035f; private const float DefaultPosX = 0.2f; private const float DefaultPosY = -0.09f; private const float DefaultDepth = 0.5f; private const float DefaultHpTextSize = 0.01f; private const float DefaultFollowSpeedX = 6f; private const float DefaultFollowSpeedY = 16f; private static byte[] _iconBytes; private static Texture2D _iconTex; private static GameObject _rootGo; private static GameObject _overlayGo; private static SpriteRenderer _sr; private static GameObject _textGo; private static SpriteRenderer _textSr; private static Material _textMat; private static Texture2D _textTex; private static int _lastHpDisplayed = -1; private static Vector3 _smoothPos; private static float _smoothYaw; private static float _nextTick; internal static void Init(MelonPreferences_Category prefs) { Enabled = prefs.CreateEntry("Visual_Enabled", true, (string)null, "--- Visual ---", false, false, (ValueValidator)null, (string)null); AlwaysOnTop = prefs.CreateEntry("Visual_AlwaysOnTop", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); IconSize = prefs.CreateEntry("Visual_IconSize", 0.035f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PosX = prefs.CreateEntry("Visual_PosX", 0.2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PosY = prefs.CreateEntry("Visual_PosY", -0.09f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); Depth = prefs.CreateEntry("Visual_Depth", 0.5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); ShowHpText = prefs.CreateEntry("Visual_ShowHpText", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); HpTextSize = prefs.CreateEntry("Visual_HpTextSize", 0.01f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); SmoothFollow = prefs.CreateEntry("Visual_SmoothFollow", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FollowSpeedX = prefs.CreateEntry("Visual_FollowSpeedX", 6f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FollowSpeedY = prefs.CreateEntry("Visual_FollowSpeedY", 16f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); string text = Path.Combine(MelonEnvironment.UserDataDirectory, "BONESQUAD", "UI", "Icons", "stanceindicator_stand.png"); if (File.Exists(text)) { _iconBytes = File.ReadAllBytes(text); BonesquadMod.Log("[Visual] HP icon loaded."); } else { BonesquadMod.LogWarning("[Visual] HP icon not found: " + text); } } internal static void Invalidate() { if (Object.op_Implicit((Object)(object)_rootGo)) { Object.Destroy((Object)(object)_rootGo); _rootGo = null; } _overlayGo = null; _sr = null; _iconTex = null; _textGo = null; _textSr = null; _textMat = null; if (Object.op_Implicit((Object)(object)_textTex)) { Object.Destroy((Object)(object)_textTex); _textTex = null; } _lastHpDisplayed = -1; } internal static void OnToggle(bool enabled) { Enabled.Value = enabled; if (Object.op_Implicit((Object)(object)_overlayGo)) { _overlayGo.SetActive(enabled); } if (Object.op_Implicit((Object)(object)_textGo)) { _textGo.SetActive(enabled && ShowHpText.Value); } } internal static void OnShowHpTextChanged(bool show) { ShowHpText.Value = show; if (Object.op_Implicit((Object)(object)_textGo)) { _textGo.SetActive(show && Enabled.Value); } } internal static void OnHpTextSizeChanged(float size) { HpTextSize.Value = size; ApplyTextTransform(); } internal static void OnSizeChanged(float size) { IconSize.Value = size; ApplyTransform(); } internal static void OnPosXChanged(float x) { PosX.Value = x; ApplyTransform(); } internal static void OnPosYChanged(float y) { PosY.Value = y; ApplyTransform(); } internal static void OnDepthChanged(float d) { Depth.Value = d; ApplyTransform(); } internal static void ResetToDefaults(MelonPreferences_Category prefs) { Enabled.Value = true; IconSize.Value = 0.035f; PosX.Value = 0.2f; PosY.Value = -0.09f; Depth.Value = 0.5f; ShowHpText.Value = true; HpTextSize.Value = 0.01f; SmoothFollow.Value = false; FollowSpeedX.Value = 6f; FollowSpeedY.Value = 16f; prefs.SaveToFile(true); if (Object.op_Implicit((Object)(object)_overlayGo)) { _overlayGo.SetActive(true); } if (Object.op_Implicit((Object)(object)_textGo)) { _textGo.SetActive(ShowHpText.Value); } ApplyTransform(); } internal static void Update() { //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_0081: Unknown result type (might be due to invalid IL or missing references) UpdatePosition(); float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup < _nextTick) { return; } _nextTick = realtimeSinceStartup + 0.1f; EnsureOverlay(); if ((Object)(object)_sr == (Object)null) { return; } Player_Health health = RegenerationModule.Health; float num = (((Object)(object)health != (Object)null && Object.op_Implicit((Object)(object)health) && ((Health)health).max_Health > 0f) ? Mathf.Clamp01(((Health)health).curr_Health / ((Health)health).max_Health) : 1f); _sr.color = Color.Lerp(Color.red, Color.white, num); if ((Object)(object)_textSr != (Object)null && ShowHpText.Value) { int num2 = Mathf.Clamp(Mathf.RoundToInt(num * 100f), 0, 100); if (num2 != _lastHpDisplayed) { _lastHpDisplayed = num2; UpdateHpText(num2); } } } private static void UpdatePosition() { //IL_0050: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_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_011b: 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) if (!Object.op_Implicit((Object)(object)_rootGo)) { return; } Transform head = Player.Head; if (Object.op_Implicit((Object)(object)head)) { float value = Depth.Value; float num = value / 0.5f; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(PosX.Value * num, PosY.Value * num, value); float y = head.eulerAngles.y; Vector3 val2 = head.TransformPoint(val); if (SmoothFollow.Value) { float num2 = 1f - Mathf.Exp((0f - FollowSpeedX.Value) * Time.deltaTime); float num3 = 1f - Mathf.Exp((0f - FollowSpeedY.Value) * Time.deltaTime); _smoothYaw = Mathf.LerpAngle(_smoothYaw, y, num2); Vector3 val3 = head.InverseTransformPoint(_smoothPos); float num4 = Mathf.Lerp(val3.x, val.x, num2); float num5 = Mathf.Lerp(val3.y, val.y, num3); _smoothPos = head.TransformPoint(new Vector3(num4, num5, val.z)); _rootGo.transform.SetPositionAndRotation(_smoothPos, Quaternion.Euler(0f, _smoothYaw, 0f)); } else { _smoothPos = val2; _smoothYaw = y; _rootGo.transform.SetPositionAndRotation(val2, head.rotation); } } } private static void ApplyTransform() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_overlayGo)) { float num = Depth.Value / 0.5f; _overlayGo.transform.localPosition = Vector3.zero; if (Object.op_Implicit((Object)(object)_iconTex)) { float num2 = IconSize.Value * num; float num3 = num2 * (float)((Texture)_iconTex).width / Mathf.Max(1f, (float)((Texture)_iconTex).height); _overlayGo.transform.localScale = new Vector3(num3, num2, 1f); } ApplyTextTransform(); } } private static void ApplyTextTransform() { //IL_0066: 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) if (Object.op_Implicit((Object)(object)_textGo)) { float num = Depth.Value / 0.5f; float num2 = IconSize.Value * num; float num3 = HpTextSize.Value * num; float num4 = 0.004f * num; _textGo.transform.localPosition = new Vector3(0f, 0f - (num2 * 0.5f + num4 + num3 * 0.5f), 0f); _textGo.transform.localScale = new Vector3(num3, num3, 1f); } } private static void UpdateHpText(int hp) { //IL_007c: 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) if (!Object.op_Implicit((Object)(object)_textSr)) { return; } if (Object.op_Implicit((Object)(object)_textTex)) { Object.Destroy((Object)(object)_textTex); _textTex = null; } Texture2D val = BitmapFont.Render($"{hp}/100"); if (!((Object)(object)val == (Object)null)) { _textTex = val; Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 7f); ((Object)val2).hideFlags = (HideFlags)61; _textSr.sprite = val2; if (Object.op_Implicit((Object)(object)_textMat)) { _textMat.mainTexture = (Texture)(object)val; } } } private static void EnsureOverlay() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00c7: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Expected O, but got Unknown //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)_rootGo) && Object.op_Implicit((Object)(object)_overlayGo) && Object.op_Implicit((Object)(object)_textGo)) { return; } Invalidate(); Transform head = Player.Head; if (!Object.op_Implicit((Object)(object)head)) { return; } float value = Depth.Value; float num = value / 0.5f; _rootGo = new GameObject("BONESQUAD_HpRoot"); Object.DontDestroyOnLoad((Object)(object)_rootGo); _smoothPos = head.TransformPoint(new Vector3(PosX.Value * num, PosY.Value * num, value)); _smoothYaw = head.eulerAngles.y; _rootGo.transform.SetPositionAndRotation(_smoothPos, head.rotation); _overlayGo = new GameObject("BONESQUAD_HpOverlay"); _overlayGo.transform.SetParent(_rootGo.transform, false); _overlayGo.transform.localPosition = Vector3.zero; _overlayGo.transform.localRotation = Quaternion.identity; if (_iconBytes != null) { _iconTex = new Texture2D(2, 2); ((Object)_iconTex).hideFlags = (HideFlags)61; ImageConversion.LoadImage(_iconTex, Il2CppStructArray.op_Implicit(_iconBytes)); float num2 = Mathf.Max(1f, (float)((Texture)_iconTex).height); Sprite val = Sprite.Create(_iconTex, new Rect(0f, 0f, (float)((Texture)_iconTex).width, (float)((Texture)_iconTex).height), new Vector2(0.5f, 0.5f), num2); ((Object)val).hideFlags = (HideFlags)61; float num3 = IconSize.Value * num; float num4 = num3 * (float)((Texture)_iconTex).width / Mathf.Max(1f, (float)((Texture)_iconTex).height); _overlayGo.transform.localScale = new Vector3(num4, num3, 1f); _sr = _overlayGo.AddComponent(); _sr.sprite = val; _sr.color = Color.white; ((Renderer)_sr).sortingOrder = 5; Shader hudShader = HudLayer.GetHudShader(AlwaysOnTop.Value); if (Object.op_Implicit((Object)(object)hudShader)) { Material val2 = new Material(hudShader); val2.mainTexture = (Texture)(object)_iconTex; ((Object)val2).hideFlags = (HideFlags)61; ((Renderer)_sr).material = val2; } } HudLayer.ApplyHp(_overlayGo); if (!Enabled.Value) { _overlayGo.SetActive(false); } _textGo = new GameObject("BONESQUAD_HpText"); _textGo.transform.SetParent(_rootGo.transform, false); _textGo.transform.localRotation = Quaternion.identity; _textSr = _textGo.AddComponent(); ((Renderer)_textSr).sortingOrder = 5; _textSr.color = Color.white; Shader hudShader2 = HudLayer.GetHudShader(AlwaysOnTop.Value); if (Object.op_Implicit((Object)(object)hudShader2)) { _textMat = new Material(hudShader2) { hideFlags = (HideFlags)61 }; ((Renderer)_textSr).sharedMaterial = _textMat; } _lastHpDisplayed = -1; ApplyTextTransform(); if (!ShowHpText.Value || !Enabled.Value) { _textGo.SetActive(false); } BonesquadMod.Log("[Visual] HP overlay created."); } } } namespace BONESQUAD.Modules.VersionCheck { internal static class VersionCheckModule { internal const string CurrentVersion = "11.1.0"; } } namespace BONESQUAD.Modules.Spawning { internal class CaptureEventData : INetSerializable { internal byte EventType; internal string GroupName = ""; internal string PointLetter = ""; internal byte TimerSecond; internal byte[] GroupMemberSmallIds = Array.Empty(); internal byte SpawnFlagSmallId; internal string FlagBarcode = ""; internal float FlagX; internal float FlagY; internal float FlagZ; internal float PointX; internal float PointZ; internal string GroupColor = ""; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref EventType); serializer.SerializeValue(ref GroupName); serializer.SerializeValue(ref PointLetter); serializer.SerializeValue(ref TimerSecond); serializer.SerializeValue(ref GroupMemberSmallIds); serializer.SerializeValue(ref SpawnFlagSmallId); serializer.SerializeValue(ref FlagBarcode); serializer.SerializeValue(ref FlagX); serializer.SerializeValue(ref FlagY); serializer.SerializeValue(ref FlagZ); serializer.SerializeValue(ref PointX); serializer.SerializeValue(ref PointZ); serializer.SerializeValue(ref GroupColor); } } [SkipHandleWhileLoading] internal class CaptureEventHandler : ModuleMessageHandler { private struct CaptureCompassPoint { internal string Letter; internal Vector3 WorldPos; internal Texture2D IconTex; internal string ColorHex; } internal struct CompassCaptureEntry { internal Vector3 WorldPos; internal string Letter; internal string ColorHex; } private static readonly HashSet _allFlagBarcodes = new HashSet { "Kikelap.SQUADPROPS.Spawnable.RUFlag", "Kikelap.SQUADPROPS.Spawnable.UAFlag01", "Kikelap.SQUADPROPS.Spawnable.USAFlag", "Kikelap.SQUADPROPS.Spawnable.WPMCFlag" }; private static readonly Dictionary _compassPoints = new Dictionary(); private static readonly Dictionary _iconCache = new Dictionary(); private static GameObject _hudGo; private static TextMesh _hudTm; private static object _hudCoroutine; private static float _quietUntil; internal static MelonPreferences_Entry NotifEnabled; internal static MelonPreferences_Entry NotifSize; internal static MelonPreferences_Entry NotifDepth; internal static MelonPreferences_Entry NotifPosY; internal static MelonPreferences_Entry NotifSmoothFollow; internal static MelonPreferences_Entry NotifFollowSpeedX; internal static MelonPreferences_Entry NotifFollowSpeedY; private static Vector3 _smoothPos; private static float _smoothYaw; private const float DefaultNotifSize = 1f; private const float DefaultNotifDepth = 0.45f; private const float DefaultNotifPosY = -0.1f; private const float DefaultFollowSpeedX = 6f; private const float DefaultFollowSpeedY = 16f; private static readonly HashSet _prewarmedBarcodes = new HashSet(); private static MethodInfo _spawnAsyncMethod; private static readonly Dictionary _glyphs = new Dictionary { ['A'] = new byte[7] { 14, 17, 17, 31, 17, 17, 17 }, ['B'] = new byte[7] { 30, 17, 17, 30, 17, 17, 30 }, ['C'] = new byte[7] { 14, 17, 16, 16, 16, 17, 14 }, ['D'] = new byte[7] { 30, 17, 17, 17, 17, 17, 30 }, ['E'] = new byte[7] { 31, 16, 16, 30, 16, 16, 31 }, ['F'] = new byte[7] { 31, 16, 16, 30, 16, 16, 16 }, ['G'] = new byte[7] { 14, 17, 16, 23, 17, 17, 14 }, ['H'] = new byte[7] { 17, 17, 17, 31, 17, 17, 17 }, ['I'] = new byte[7] { 14, 4, 4, 4, 4, 4, 14 }, ['J'] = new byte[7] { 7, 1, 1, 1, 17, 17, 14 }, ['K'] = new byte[7] { 17, 18, 20, 24, 20, 18, 17 }, ['L'] = new byte[7] { 16, 16, 16, 16, 16, 16, 31 }, ['M'] = new byte[7] { 17, 27, 21, 17, 17, 17, 17 }, ['N'] = new byte[7] { 17, 25, 21, 19, 17, 17, 17 }, ['O'] = new byte[7] { 14, 17, 17, 17, 17, 17, 14 }, ['P'] = new byte[7] { 30, 17, 17, 30, 16, 16, 16 }, ['Q'] = new byte[7] { 14, 17, 17, 17, 21, 18, 13 }, ['R'] = new byte[7] { 30, 17, 17, 30, 20, 18, 17 }, ['S'] = new byte[7] { 15, 16, 16, 14, 1, 1, 30 }, ['T'] = new byte[7] { 31, 4, 4, 4, 4, 4, 4 }, ['U'] = new byte[7] { 17, 17, 17, 17, 17, 17, 14 }, ['V'] = new byte[7] { 17, 17, 17, 17, 17, 10, 4 }, ['W'] = new byte[7] { 17, 17, 17, 17, 21, 27, 17 }, ['X'] = new byte[7] { 17, 17, 10, 4, 10, 17, 17 }, ['Y'] = new byte[7] { 17, 17, 10, 4, 4, 4, 4 }, ['Z'] = new byte[7] { 31, 1, 2, 4, 8, 16, 31 } }; private const string PointColor = "#FFE04D"; internal static void ClearPoints() { _compassPoints.Clear(); _iconCache.Clear(); } internal static void Init(MelonPreferences_Category prefs) { NotifEnabled = prefs.CreateEntry("Notif_Enabled", true, (string)null, "--- Notifications ---", false, false, (ValueValidator)null, (string)null); NotifSize = prefs.CreateEntry("Notif_Size", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); NotifDepth = prefs.CreateEntry("Notif_Depth", 0.45f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); NotifPosY = prefs.CreateEntry("Notif_PosY", -0.1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); NotifSmoothFollow = prefs.CreateEntry("Notif_SmoothFollow", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); NotifFollowSpeedX = prefs.CreateEntry("Notif_FollowSpeedX", 6f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); NotifFollowSpeedY = prefs.CreateEntry("Notif_FollowSpeedY", 16f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); } internal static void ResetToDefaults(MelonPreferences_Category prefs) { NotifEnabled.Value = true; NotifSize.Value = 1f; NotifDepth.Value = 0.45f; NotifPosY.Value = -0.1f; NotifSmoothFollow.Value = false; NotifFollowSpeedX.Value = 6f; NotifFollowSpeedY.Value = 16f; prefs.SaveToFile(true); } internal static void Update() { //IL_006c: 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_007a: 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) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_hudGo) || !Object.op_Implicit((Object)(object)_hudTm)) { return; } Transform head; try { head = Player.Head; } catch { return; } if (Object.op_Implicit((Object)(object)head)) { float num = NotifDepth?.Value ?? 0.45f; float num2 = NotifPosY?.Value ?? (-0.1f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, num2, num); float y = head.eulerAngles.y; Vector3 val2 = head.TransformPoint(val); MelonPreferences_Entry notifSmoothFollow = NotifSmoothFollow; if (notifSmoothFollow != null && notifSmoothFollow.Value) { float num3 = NotifFollowSpeedX?.Value ?? 6f; float num4 = NotifFollowSpeedY?.Value ?? 16f; float num5 = 1f - Mathf.Exp((0f - num3) * Time.deltaTime); float num6 = 1f - Mathf.Exp((0f - num4) * Time.deltaTime); _smoothYaw = Mathf.LerpAngle(_smoothYaw, y, num5); Vector3 val3 = head.InverseTransformPoint(_smoothPos); float num7 = Mathf.Lerp(val3.x, 0f, num5); float num8 = Mathf.Lerp(val3.y, val.y, num6); _smoothPos = head.TransformPoint(new Vector3(num7, num8, val.z)); _hudGo.transform.SetPositionAndRotation(_smoothPos, Quaternion.Euler(0f, _smoothYaw, 0f)); } else { _smoothPos = val2; _smoothYaw = y; _hudGo.transform.SetPositionAndRotation(val2, head.rotation); } } } internal static void OnLevelUnloaded() { ClearPoints(); _prewarmedBarcodes.Clear(); ClearHud(); } private static void EnsureHud() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_013c: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_hudGo) || !Object.op_Implicit((Object)(object)_hudTm)) { if (Object.op_Implicit((Object)(object)_hudGo)) { Object.Destroy((Object)(object)_hudGo); } _hudGo = null; _hudTm = null; _hudGo = new GameObject("BONESQUAD_CaptureHUD"); Object.DontDestroyOnLoad((Object)(object)_hudGo); _hudTm = _hudGo.AddComponent(); _hudTm.fontSize = 48; _hudTm.characterSize = 0.005f * (NotifSize?.Value ?? 1f); _hudTm.anchor = (TextAnchor)4; _hudTm.color = Color.white; _hudTm.richText = true; _hudTm.text = ""; Transform val = null; try { val = Player.Head; } catch { } if (Object.op_Implicit((Object)(object)val)) { _smoothPos = val.TransformPoint(new Vector3(0f, NotifPosY?.Value ?? (-0.1f), NotifDepth?.Value ?? 0.45f)); _smoothYaw = val.eulerAngles.y; _hudGo.transform.SetPositionAndRotation(_smoothPos, val.rotation); } } } private static void ShowHud(string text, float duration) { if (NotifEnabled != null && !NotifEnabled.Value) { return; } EnsureHud(); if (!Object.op_Implicit((Object)(object)_hudTm)) { return; } _hudTm.text = text; _hudTm.characterSize = 0.005f * (NotifSize?.Value ?? 1f); if (_hudCoroutine != null) { try { MelonCoroutines.Stop(_hudCoroutine); } catch { } _hudCoroutine = null; } _hudCoroutine = MelonCoroutines.Start(HudClearAfter(duration)); } private static void ClearHud() { if (_hudCoroutine != null) { try { MelonCoroutines.Stop(_hudCoroutine); } catch { } _hudCoroutine = null; } if (Object.op_Implicit((Object)(object)_hudTm)) { _hudTm.text = ""; } } private static IEnumerator HudClearAfter(float delay) { yield return (object)new WaitForSeconds(delay); if (Object.op_Implicit((Object)(object)_hudTm)) { _hudTm.text = ""; } _hudCoroutine = null; } private static MethodInfo FindSpawnAsync() { MethodInfo[] methods = typeof(AssetSpawner).GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "SpawnAsync" && methodInfo.GetParameters().Length >= 6) { return methodInfo; } } return null; } private static void PrewarmBundle(string barcode) { if (_allFlagBarcodes.Contains(barcode) && _prewarmedBarcodes.Add(barcode)) { if (_spawnAsyncMethod == null) { _spawnAsyncMethod = FindSpawnAsync(); } if (!(_spawnAsyncMethod == null)) { MelonCoroutines.Start(LocalSpawnForBundleLoad(barcode)); } } } private static IEnumerator LocalSpawnForBundleLoad(string barcode) { yield return (object)new WaitForSeconds(1f); try { Spawnable val = new Spawnable(); val.crateRef = new SpawnableCrateReference(barcode); AssetSpawner.Register(val); BonesquadMod.Log("[Capture] Pre-warming bundle: " + barcode); _spawnAsyncMethod.Invoke(null, new object[7] { val, (object)new Vector3(0f, -5000f, 0f), Quaternion.identity, null, false, null, null }); } catch (Exception ex) { BonesquadMod.LogWarning("[Capture] PrewarmBundle " + barcode + ": " + ex.Message); } } internal static void FillCompassPoints(List dest) { //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) foreach (CaptureCompassPoint value in _compassPoints.Values) { dest.Add(new CompassCaptureEntry { WorldPos = value.WorldPos, Letter = value.Letter, ColorHex = value.ColorHex }); } } private static Texture2D GetOrCreateIcon(string letter) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_00af: 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) //IL_00df: 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_00cd: Unknown result type (might be due to invalid IL or missing references) if (_iconCache.TryGetValue(letter, out var value) && Object.op_Implicit((Object)(object)value)) { return value; } Texture2D val = new Texture2D(24, 24, (TextureFormat)4, false); ((Object)val).hideFlags = (HideFlags)61; Color32 val2 = default(Color32); ((Color32)(ref val2))..ctor(byte.MaxValue, (byte)216, (byte)26, byte.MaxValue); Color32 val3 = default(Color32); ((Color32)(ref val3))..ctor((byte)180, (byte)120, (byte)0, byte.MaxValue); float num = 12f; float num2 = 12f; float num3 = 11.5f; for (int i = 0; i < 24; i++) { for (int j = 0; j < 24; j++) { float num4 = (float)j - num + 0.5f; float num5 = (float)i - num2 + 0.5f; float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5); if (num6 > num3) { val.SetPixel(j, i, Color.clear); } else if (num6 > num3 - 1.5f) { val.SetPixel(j, i, Color32.op_Implicit(val3)); } else { val.SetPixel(j, i, Color32.op_Implicit(val2)); } } } DrawGlyph(val, letter, 24); val.Apply(); _iconCache[letter] = val; return val; } private static void DrawGlyph(Texture2D tex, string letter, int S) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(letter)) { return; } char key = char.ToUpper(letter[0]); if (!_glyphs.TryGetValue(key, out var value)) { return; } int num = (S - 5) / 2; int num2 = (S - 7) / 2; for (int i = 0; i < 7; i++) { byte b = value[i]; int num3 = S - 1 - (num2 + i); for (int j = 0; j < 5; j++) { if ((b & (1 << 4 - j)) != 0) { tex.SetPixel(num + j, num3, Color.black); } } } } private static void StorePoint(string letter, float px, float pz) { //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) if (!string.IsNullOrEmpty(letter) && (px != 0f || pz != 0f)) { Texture2D orCreateIcon = GetOrCreateIcon(letter); CaptureCompassPoint value; string colorHex = (_compassPoints.TryGetValue(letter, out value) ? value.ColorHex : ""); _compassPoints[letter] = new CaptureCompassPoint { Letter = letter, WorldPos = new Vector3(px, 0f, pz), IconTex = orCreateIcon, ColorHex = colorHex }; } } private static void SetPointColor(string letter, string colorHex) { if (!string.IsNullOrEmpty(letter) && _compassPoints.TryGetValue(letter, out var value)) { value.ColorHex = colorHex; _compassPoints[letter] = value; } } protected override void OnHandleMessage(ReceivedMessage received) { //IL_01ce: Unknown result type (might be due to invalid IL or missing references) try { CaptureEventData captureEventData = ((ReceivedMessage)(ref received)).ReadData(); byte localSmallID = PlayerIDManager.LocalSmallID; bool flag = IsInGroup(localSmallID, captureEventData.GroupMemberSmallIds); StorePoint(captureEventData.PointLetter, captureEventData.PointX, captureEventData.PointZ); switch (captureEventData.EventType) { case 0: ShowStarted(captureEventData.GroupName, captureEventData.PointLetter, flag, captureEventData.GroupColor); if (!string.IsNullOrEmpty(captureEventData.FlagBarcode)) { PrewarmBundle(captureEventData.FlagBarcode); } break; case 1: BonesquadMod.Log($"[Capture] Tick {captureEventData.TimerSecond}/{60} — Point {captureEventData.PointLetter} ({captureEventData.GroupName})"); if (flag) { ShowTimer(captureEventData.GroupName, captureEventData.PointLetter, captureEventData.TimerSecond); } break; case 2: ShowCaptured(captureEventData.GroupName, captureEventData.PointLetter, flag, captureEventData.GroupColor); SetPointColor(captureEventData.PointLetter, captureEventData.GroupColor); if (captureEventData.SpawnFlagSmallId == localSmallID && !string.IsNullOrEmpty(captureEventData.FlagBarcode)) { BonesquadMod.Log($"[Capture] I am the spawner (SmallID={localSmallID}), scheduling flag spawn in 0.5s."); string flagBarcode = captureEventData.FlagBarcode; Vector3 pos = default(Vector3); ((Vector3)(ref pos))..ctor(captureEventData.FlagX, captureEventData.FlagY + 0.5f, captureEventData.FlagZ); MelonCoroutines.Start(SpawnFlagDelayed(flagBarcode, pos)); } else { BonesquadMod.Log($"[Capture] Not the spawner (my={localSmallID} spawner={captureEventData.SpawnFlagSmallId}), waiting for Fusion replication."); } break; case 3: if (flag) { ShowEnemyInZone(captureEventData.PointLetter); } break; case 4: SetPointColor(captureEventData.PointLetter, captureEventData.GroupColor); break; } } catch (Exception ex) { BonesquadMod.LogWarning("[Capture] CaptureEventHandler: " + ex.Message); } } private static IEnumerator SpawnFlagDelayed(string barcode, Vector3 pos) { //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) yield return (object)new WaitForSeconds(0.5f); SpawnFlag(barcode, pos); } private static void SpawnFlag(string barcode, Vector3 pos) { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_008d: 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_00b6: 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_00c2: 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_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) if (!_allFlagBarcodes.Contains(barcode)) { BonesquadMod.LogWarning("[Capture] Unknown flag barcode: " + barcode); return; } Spawnable val = new Spawnable(); val.crateRef = new SpawnableCrateReference(barcode); AssetSpawner.Register(val); BonesquadMod.Log($"[Capture] NetworkAssetSpawner.Spawn called at {DateTime.Now:HH:mm:ss.fff} — {barcode} at {pos}"); try { NetworkAssetSpawner.Spawn(new SpawnRequestInfo { Spawnable = val, Position = pos, Rotation = Quaternion.identity, SpawnEffect = false, SpawnCallback = delegate(SpawnCallbackInfo info) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(36, 2); defaultInterpolatedStringHandler.AppendLiteral("[Capture] Flag spawned at "); defaultInterpolatedStringHandler.AppendFormatted(DateTime.Now, "HH:mm:ss.fff"); defaultInterpolatedStringHandler.AppendLiteral(" EntityID="); NetworkEntity entity = info.Entity; defaultInterpolatedStringHandler.AppendFormatted((entity != null) ? new ushort?(entity.ID) : ((ushort?)null)); BonesquadMod.Log(defaultInterpolatedStringHandler.ToStringAndClear()); PinFlagToWorld(info.Spawned, pos); }, SpawnSource = (EntitySource)2 }); } catch (Exception ex) { BonesquadMod.LogWarning("[Capture] SpawnFlag failed: " + ex.Message); } } private static void PinFlagToWorld(GameObject go, Vector3 targetPos) { //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_0039: 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_0080: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)go)) { return; } try { go.transform.SetPositionAndRotation(targetPos, Quaternion.identity); foreach (Rigidbody componentsInChild in go.GetComponentsInChildren()) { if (Object.op_Implicit((Object)(object)componentsInChild)) { componentsInChild.velocity = Vector3.zero; componentsInChild.angularVelocity = Vector3.zero; componentsInChild.isKinematic = true; } } BonesquadMod.Log($"[Capture] Flag pinned to world at {targetPos}"); } catch (Exception ex) { BonesquadMod.LogWarning("[Capture] PinFlagToWorld failed: " + ex.Message); } } private static bool IsInGroup(byte localId, byte[] memberIds) { for (int i = 0; i < memberIds.Length; i++) { if (memberIds[i] == localId) { return true; } } return false; } private static string PT(string letter) { return $"Point {letter}"; } private static string GN(string name, string colorHex) { if (!string.IsNullOrEmpty(colorHex)) { return $"{name}"; } return name; } private static void ShowStarted(string groupName, string letter, bool isMyGroup, string groupColor) { string text = (isMyGroup ? GN("Your group", groupColor) : GN(groupName, groupColor)); _quietUntil = Time.time + 2f; ShowHud(PT(letter) + " | " + text + " started capturing", 2f); } private static void ShowEnemyInZone(string letter) { ShowHud(PT(letter) + " | Enemy in zone — capture blocked", 5f); } private static void ShowTimer(string groupName, string letter, byte second) { if (!(Time.time < _quietUntil)) { ShowHud($"{PT(letter)} | Capturing ({second}/{60} sec)", 1.3f); } } private static void ShowCaptured(string groupName, string letter, bool isMyGroup, string groupColor) { _quietUntil = 0f; ShowHud(isMyGroup ? (PT(letter) + " | CAPTURED!") : (PT(letter) + " | Captured by " + GN(groupName, groupColor)), 5.3f); } } internal static class CaptureTracker { internal const int CaptureDuration = 60; } internal class DespawnRallyData : INetSerializable { internal byte MarkerType; internal float X; internal float Z; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref MarkerType); serializer.SerializeValue(ref X); serializer.SerializeValue(ref Z); } } internal class DespawnRallyHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { try { DespawnRallyData despawnRallyData = ((ReceivedMessage)(ref received)).ReadData(); RallyPointTracker.DespawnByPosition(despawnRallyData.MarkerType, despawnRallyData.X, despawnRallyData.Z); } catch (Exception ex) { BonesquadMod.LogWarning("[SpawnPoint] DespawnRallyHandler error: " + ex.Message); } } } internal class KnockoutStateData : INetSerializable { internal bool IsKnockedOut; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref IsKnockedOut); } } internal class KnockoutStateMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { } } internal class MainBaseData : INetSerializable { internal byte TargetSmallId; internal float X; internal float Z; internal bool HasBase; internal float Y; internal bool HasCustomY; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref TargetSmallId); serializer.SerializeValue(ref X); serializer.SerializeValue(ref Z); serializer.SerializeValue(ref HasBase); serializer.SerializeValue(ref Y); serializer.SerializeValue(ref HasCustomY); } } [SkipHandleWhileLoading] internal class MainBaseHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { try { MainBaseData mainBaseData = ((ReceivedMessage)(ref received)).ReadData(); BonesquadMod.Log($"[MainBase] Msg received: target={mainBaseData.TargetSmallId} local={PlayerIDManager.LocalSmallID} hasBase={mainBaseData.HasBase}"); if (mainBaseData.TargetSmallId == PlayerIDManager.LocalSmallID) { if (mainBaseData.HasBase) { float? y = (mainBaseData.HasCustomY ? new float?(mainBaseData.Y) : ((float?)null)); MainBaseModule.SetBase(mainBaseData.X, mainBaseData.Z, y); BonesquadMod.Log($"[MainBase] Received base coords: X={mainBaseData.X:F1} Z={mainBaseData.Z:F1}" + (mainBaseData.HasCustomY ? $" Y={mainBaseData.Y:F1} (custom)" : " Y=auto (raycast)")); } else { MainBaseModule.ClearBase(); BonesquadMod.Log("[MainBase] No base assigned to this player's group."); } } } catch (Exception ex) { BonesquadMod.LogWarning("[MainBase] Handler error: " + ex.Message); } } } internal static class MainBaseModule { private static float? _x; private static float? _z; private static float? _y; internal static bool HasBase => _x.HasValue; internal static void SetBase(float x, float z, float? y = null) { _x = x; _z = z; _y = y; BonesquadMod.Log($"[MainBase] SetBase({x:F1}, {z:F1}{(y.HasValue ? $", y={y:F1}" : "")})"); } internal static void ClearBase() { bool hasValue = _x.HasValue; _x = null; _z = null; _y = null; if (hasValue) { BonesquadMod.Log("[MainBase] ClearBase (had base)."); } } internal static Vector3? ResolvePosition() { //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_0044: 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_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) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!_x.HasValue) { return null; } float value = _x.Value; float value2 = _z.Value; if (_y.HasValue) { return new Vector3(value, _y.Value, value2); } RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Vector3(value, 200f, value2), Vector3.down, ref val, 300f)) { return ((RaycastHit)(ref val)).point + Vector3.up * 0.15f; } return new Vector3(value, 0f, value2); } } internal class RallyOwnerData : INetSerializable { internal byte MarkerType; internal float X; internal float Z; internal string GroupId = ""; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref MarkerType); serializer.SerializeValue(ref X); serializer.SerializeValue(ref Z); serializer.SerializeValue(ref GroupId); } } [SkipHandleWhileLoading] internal class RallyOwnerHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { try { RallyOwnerData rallyOwnerData = ((ReceivedMessage)(ref received)).ReadData(); RallyPointTracker.SetOwner(rallyOwnerData.MarkerType, rallyOwnerData.X, rallyOwnerData.Z, rallyOwnerData.GroupId); } catch { } } } internal static class RallyPointTracker { private class SpawnEntry { internal Transform Transform; internal Poolee Poolee; internal float SpawnTime; } private const string SquadpropsPrefix = "Kikelap.SQUADPROPS.Spawnable."; private static readonly List _activeRallies = new List(); private static readonly List _activeHabs = new List(); private static readonly Dictionary _ownerMap = new Dictionary(); private const int OwnerCheckMaxFrames = 10; private static bool IsRallyPoint(string barcode) { if (barcode.StartsWith("Kikelap.SQUADPROPS.Spawnable.", StringComparison.OrdinalIgnoreCase)) { return barcode.IndexOf("rally", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static bool IsHab(string barcode) { if (barcode.StartsWith("Kikelap.SQUADPROPS.Spawnable.", StringComparison.OrdinalIgnoreCase)) { return barcode.IndexOf("HAB", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } internal static void Init() { Hooking.OnLevelUnloaded += OnLevelUnloaded; } internal static Transform GetLatestRally() { return GetLatestFrom(_activeRallies, 0); } internal static Transform GetLatestHab() { return GetLatestFrom(_activeHabs, 1); } private static string OwnerKey(byte markerType, float x, float z) { return $"{markerType}:{Math.Round(x, 0):F0}:{Math.Round(z, 0):F0}"; } internal static void SetOwner(byte markerType, float x, float z, string groupId) { _ownerMap[OwnerKey(markerType, x, z)] = groupId ?? ""; BonesquadMod.Log($"[SpawnPoint] Owner set: type={markerType} ({x:F1},{z:F1}) → group={groupId}"); } internal static void ClearOwners() { _ownerMap.Clear(); } private static Transform GetLatestFrom(List list, byte markerType) { //IL_007a: 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) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) for (int num = list.Count - 1; num >= 0; num--) { if (!Object.op_Implicit((Object)(object)list[num].Transform)) { list.RemoveAt(num); } } if (list.Count == 0) { return null; } if (_ownerMap.Count > 0 && BONESQUAD.Modules.FusionCompat.FusionCompat.IsAvailable) { SpawnEntry spawnEntry = null; foreach (SpawnEntry item in list) { if (Object.op_Implicit((Object)(object)item.Transform)) { Vector3 position = item.Transform.position; string key = OwnerKey(markerType, position.x, position.z); if ((!_ownerMap.TryGetValue(key, out var value) || PingMarkerModule.SharesGroupId(value)) && (spawnEntry == null || item.SpawnTime > spawnEntry.SpawnTime)) { spawnEntry = item; } } } return spawnEntry?.Transform; } SpawnEntry spawnEntry2 = list[0]; for (int i = 1; i < list.Count; i++) { if (list[i].SpawnTime > spawnEntry2.SpawnTime) { spawnEntry2 = list[i]; } } return spawnEntry2.Transform; } internal static void DespawnByPosition(byte markerType, float x, float z) { //IL_006d: 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) try { List list = ((markerType == 0) ? _activeRallies : _activeHabs); string value = ((markerType == 0) ? "rally" : "hab"); int num = (int)Math.Round(x); int num2 = (int)Math.Round(z); for (int num3 = list.Count - 1; num3 >= 0; num3--) { SpawnEntry spawnEntry = list[num3]; if (!Object.op_Implicit((Object)(object)spawnEntry.Transform)) { list.RemoveAt(num3); } else { int num4 = (int)Math.Round(spawnEntry.Transform.position.x); int num5 = (int)Math.Round(spawnEntry.Transform.position.z); if (num4 == num && num5 == num2) { BonesquadMod.Log($"[SpawnPoint] Server-forced despawn: {value} at ({x:F1},{z:F1})"); if (Object.op_Implicit((Object)(object)spawnEntry.Poolee)) { ((Component)spawnEntry.Poolee).gameObject.SetActive(false); } list.RemoveAt(num3); _ownerMap.Remove(OwnerKey(markerType, x, z)); return; } } } BonesquadMod.LogWarning($"[SpawnPoint] DespawnByPosition: no {value} found at ({x:F1},{z:F1})"); } catch (Exception ex) { BonesquadMod.LogWarning("[SpawnPoint] DespawnByPosition error: " + ex.Message); } } private static void OnLevelUnloaded() { _activeRallies.Clear(); _activeHabs.Clear(); ClearOwners(); BonesquadMod.Log("[SpawnPoint] Level unloaded — cleared."); } internal static void OnPooleeSpawned(Poolee poolee) { //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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) try { SpawnableCrate spawnableCrate = poolee.SpawnableCrate; if ((Object)(object)spawnableCrate == (Object)null) { return; } string iD = ((Scannable)spawnableCrate).Barcode.ID; if (IsRallyPoint(iD)) { _activeRallies.Add(new SpawnEntry { Transform = ((Component)poolee).transform, Poolee = poolee, SpawnTime = Time.time }); Vector3 position = ((Component)poolee).transform.position; BonesquadMod.Log($"[SpawnPoint] Rally Point spawned at ({position.x:F1}, {position.y:F1}, {position.z:F1}) — rallies: {_activeRallies.Count}"); if (BONESQUAD.Modules.FusionCompat.FusionCompat.IsAvailable && !BONESQUAD.Modules.FusionCompat.FusionCompat.IsHost()) { MelonCoroutines.Start(ReportOwnedSpawn(poolee, 0, position.x, position.z)); } } else if (IsHab(iD)) { _activeHabs.Add(new SpawnEntry { Transform = ((Component)poolee).transform, Poolee = poolee, SpawnTime = Time.time }); Vector3 position2 = ((Component)poolee).transform.position; BonesquadMod.Log($"[SpawnPoint] HAB spawned at ({position2.x:F1}, {position2.y:F1}, {position2.z:F1}) — habs: {_activeHabs.Count}"); if (BONESQUAD.Modules.FusionCompat.FusionCompat.IsAvailable && !BONESQUAD.Modules.FusionCompat.FusionCompat.IsHost()) { MelonCoroutines.Start(ReportOwnedSpawn(poolee, 1, position2.x, position2.z)); } } } catch (Exception ex) { BonesquadMod.LogWarning("[SpawnPoint] OnSpawn error: " + ex.Message); } } private static IEnumerator ReportOwnedSpawn(Poolee poolee, byte markerType, float x, float z) { for (int i = 0; i < 10; i++) { if (!Object.op_Implicit((Object)(object)poolee)) { yield break; } if (BONESQUAD.Modules.FusionCompat.FusionCompat.TryIsPooleeOwner(poolee, out var isOwner)) { if (isOwner) { BONESQUAD.Modules.FusionCompat.FusionCompat.SendRallyEvent(markerType, 0, x, z); } yield break; } yield return null; } BonesquadMod.LogWarning($"[SpawnPoint] Ownership never resolved for spawn at ({x:F1},{z:F1}) — not reporting."); } internal static void OnPooleeDespawned(Poolee poolee) { //IL_0034: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_01af: 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) try { SpawnableCrate spawnableCrate = poolee.SpawnableCrate; if ((Object)(object)spawnableCrate == (Object)null) { return; } string iD = ((Scannable)spawnableCrate).Barcode.ID; Transform transform = ((Component)poolee).transform; if (IsRallyPoint(iD)) { Vector3 position = transform.position; for (int num = _activeRallies.Count - 1; num >= 0; num--) { if ((Object)(object)_activeRallies[num].Transform == (Object)(object)transform) { _activeRallies.RemoveAt(num); break; } } _ownerMap.Remove(OwnerKey(0, position.x, position.z)); BonesquadMod.Log($"[SpawnPoint] Rally Point removed — rallies: {_activeRallies.Count}"); if (BONESQUAD.Modules.FusionCompat.FusionCompat.IsAvailable && !BONESQUAD.Modules.FusionCompat.FusionCompat.IsHost()) { BONESQUAD.Modules.FusionCompat.FusionCompat.SendRallyEvent(0, 1, position.x, position.z); } } else { if (!IsHab(iD)) { return; } Vector3 position2 = transform.position; for (int num2 = _activeHabs.Count - 1; num2 >= 0; num2--) { if ((Object)(object)_activeHabs[num2].Transform == (Object)(object)transform) { _activeHabs.RemoveAt(num2); break; } } _ownerMap.Remove(OwnerKey(1, position2.x, position2.z)); BonesquadMod.Log($"[SpawnPoint] HAB removed — habs: {_activeHabs.Count}"); if (BONESQUAD.Modules.FusionCompat.FusionCompat.IsAvailable && !BONESQUAD.Modules.FusionCompat.FusionCompat.IsHost()) { BONESQUAD.Modules.FusionCompat.FusionCompat.SendRallyEvent(1, 1, position2.x, position2.z); } } } catch (Exception ex) { BonesquadMod.LogWarning("[SpawnPoint] OnDespawn error: " + ex.Message); } } } [HarmonyPatch(typeof(Poolee), "OnSpawnEvent")] internal static class RallyPointSpawnPatch { internal static void Postfix(Poolee __instance) { RallyPointTracker.OnPooleeSpawned(__instance); } } [HarmonyPatch(typeof(Poolee), "OnDespawnEvent")] internal static class RallyPointDespawnPatch { internal static void Postfix(Poolee __instance) { RallyPointTracker.OnPooleeDespawned(__instance); } } internal class RallyReportData : INetSerializable { internal byte EventType; internal byte MarkerType; internal float X; internal float Z; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref EventType); serializer.SerializeValue(ref MarkerType); serializer.SerializeValue(ref X); serializer.SerializeValue(ref Z); } } internal class RallyReportMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { } } internal class RallyStatusData : INetSerializable { internal byte TargetSmallId; internal byte MarkerType; internal int SpawnCount; internal int MaxCount; internal bool IsDestroyed; internal bool IsNotLeader; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref TargetSmallId); serializer.SerializeValue(ref MarkerType); serializer.SerializeValue(ref SpawnCount); serializer.SerializeValue(ref MaxCount); serializer.SerializeValue(ref IsDestroyed); serializer.SerializeValue(ref IsNotLeader); } } internal class RallyStatusHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { //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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_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_005a: 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_0071: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown try { RallyStatusData rallyStatusData = ((ReceivedMessage)(ref received)).ReadData(); if (rallyStatusData.TargetSmallId != PlayerIDManager.LocalSmallID) { return; } if (rallyStatusData.IsNotLeader) { Notifier.Send(new Notification { Title = new NotificationText("Rally Point", Color.red, false), Message = new NotificationText("You are not a group leader", Color.red, false), ShowTitleOnPopup = true, Type = (NotificationType)1, PopupLength = 5f }); return; } string text = ((rallyStatusData.MarkerType == 0) ? "Rally Point" : "HAB"); int num = ((rallyStatusData.MaxCount > 0) ? (rallyStatusData.MaxCount - rallyStatusData.SpawnCount) : (-1)); string value = ((num >= 0) ? $"{num} left" : "unlimited"); string text2 = ((rallyStatusData.MaxCount > 0) ? $"{rallyStatusData.SpawnCount}/{rallyStatusData.MaxCount} respawns used ({value})" : $"{rallyStatusData.SpawnCount} respawns used"); if (rallyStatusData.IsDestroyed) { Notifier.Send(new Notification { Title = new NotificationText(text, Color.red, false), Message = new NotificationText(text2 + " — " + text + " destroyed", Color.red, false), ShowTitleOnPopup = true, Type = (NotificationType)1, PopupLength = 6f }); } else { Color val = (Color)((num == 1) ? new Color(1f, 0.5f, 0.1f) : Color.white); Notifier.Send(new Notification { Title = new NotificationText(text, Color.cyan, false), Message = new NotificationText(text2, val, false), ShowTitleOnPopup = true, Type = (NotificationType)0, PopupLength = 4f }); } } catch (Exception ex) { BonesquadMod.LogWarning("[SpawnPoint] RallyStatusHandler error: " + ex.Message); } } } internal static class RespawnModule { internal static MelonPreferences_Entry KnockoutTimerEnabled; private static bool _pendingRespawn; private static Vector3? _savedSpawnPos; private static Vector3? _savedRallyPos; private static byte _savedRallyType = byte.MaxValue; private static bool _wasFusionKnockedOut; internal static void Init(MelonPreferences_Category prefs) { KnockoutTimerEnabled = prefs.CreateEntry("Regeneration_KnockoutTimerEnabled", false, (string)null, "--- Spawn Points ---", false, false, (ValueValidator)null, (string)null); } internal static void OnKnockoutTimerToggle(bool enabled) { KnockoutTimerEnabled.Value = enabled; } internal static void OnPlayerDied() { //IL_0087: 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) if (!_pendingRespawn && KnockoutTimerEnabled.Value && BONESQUAD.Modules.FusionCompat.FusionCompat.IsAvailable && BONESQUAD.Modules.FusionCompat.FusionCompat.GetKnockoutLength() > 0) { _pendingRespawn = true; (_savedSpawnPos, _savedRallyPos, _savedRallyType) = ResolveSpawn(RadialMenuModule.SelectedSpawn?.Value ?? ""); BonesquadMod.Log("[Respawn] Fusion knockout — spawn saved: " + (_savedSpawnPos.HasValue ? ((object)_savedSpawnPos.Value/*cast due to .constrained prefix*/).ToString() : "none") + "."); } } internal static void Update() { if (!KnockoutTimerEnabled.Value) { _wasFusionKnockedOut = false; return; } bool flag = BONESQUAD.Modules.FusionCompat.FusionCompat.IsLocalPlayerKnockedOut(); if (_wasFusionKnockedOut && !flag) { var (savedPos, savedRallyPos, savedRallyType) = ResolveSpawn(RadialMenuModule.SelectedSpawn?.Value ?? ""); MelonCoroutines.Start(TeleportAfterRespawn(savedPos, savedRallyPos, savedRallyType)); } _wasFusionKnockedOut = flag; } internal static void OnPlayerRevived() { if (_pendingRespawn) { Trigger(); } } internal static void OnHealthAwake() { if (_pendingRespawn) { Trigger(); } } private static void Trigger() { _pendingRespawn = false; Vector3? savedSpawnPos = _savedSpawnPos; Vector3? savedRallyPos = _savedRallyPos; byte savedRallyType = _savedRallyType; _savedSpawnPos = null; _savedRallyPos = null; _savedRallyType = byte.MaxValue; MelonCoroutines.Start(TeleportAfterRespawn(savedSpawnPos, savedRallyPos, savedRallyType)); } private static (Transform t, byte markerType) ResolveSpawnPoint(string selected) { if (selected == "deployable_hab.png") { Transform latestHab = RallyPointTracker.GetLatestHab(); if (Object.op_Implicit((Object)(object)latestHab)) { return (t: latestHab, markerType: 1); } return (t: RallyPointTracker.GetLatestRally(), markerType: 0); } Transform latestRally = RallyPointTracker.GetLatestRally(); if (Object.op_Implicit((Object)(object)latestRally)) { return (t: latestRally, markerType: 0); } return (t: RallyPointTracker.GetLatestHab(), markerType: 1); } private static (Vector3? spawnPos, Vector3? rallyPos, byte rallyType) ResolveSpawn(string selected) { //IL_0042: 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_0052: 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_0062: Unknown result type (might be due to invalid IL or missing references) if (selected == "mainbase.png") { return (spawnPos: MainBaseModule.ResolvePosition(), rallyPos: null, rallyType: byte.MaxValue); } var (val, item) = ResolveSpawnPoint(selected); if (Object.op_Implicit((Object)(object)val)) { return (spawnPos: val.position + val.forward * 1f, rallyPos: val.position, rallyType: item); } return (spawnPos: MainBaseModule.ResolvePosition(), rallyPos: null, rallyType: byte.MaxValue); } private static IEnumerator TeleportAfterRespawn(Vector3? savedPos, Vector3? savedRallyPos, byte savedRallyType) { yield return (object)new WaitForSecondsRealtime(0.5f); if (!savedPos.HasValue) { BonesquadMod.Log("[Respawn] No spawn point available — staying in place."); yield break; } RigManager rigManager = Player.RigManager; if (!Object.op_Implicit((Object)(object)rigManager)) { yield break; } try { rigManager.Teleport(savedPos.Value, true); BonesquadMod.Log($"[Respawn] Teleported to {savedPos.Value}."); if (savedRallyType != byte.MaxValue && savedRallyPos.HasValue) { BONESQUAD.Modules.FusionCompat.FusionCompat.SendRallyEvent(savedRallyType, 2, savedRallyPos.Value.x, savedRallyPos.Value.z); } } catch (Exception ex) { BonesquadMod.LogWarning("[Respawn] Teleport failed: " + ex.Message); } } } } namespace BONESQUAD.Modules.SoundFalloff { internal enum SoundCategory { Quiet, Medium, Loud } internal static class SoundFalloffModule { internal static MelonPreferences_Entry Enabled; internal static MelonPreferences_Entry LocalRadius; internal static MelonPreferences_Entry QuietMaxDist; internal static MelonPreferences_Entry MediumMaxDist; internal static MelonPreferences_Entry LoudMaxDist; private static readonly string[] LoudWords = new string[38] { "explo", "boom", "blast", "detonate", "bomb", "grenade", "missile", "rocket", "mortar", "artillery", "nuke", "c4", "tnt", "dynamite", "cannon", "tank", "50cal", "50_cal", ".50", "turret", "minigun", "gatling", "lmg", "hmg", "sniper_fire", "barrett", "crash", "vehicle", "car_", "truck", "helicopter", "jet", "engine_loud", "thunder", "collapse", "avalanche", "earthquake", "siren" }; private static readonly string[] QuietWords = new string[52] { "reload", "mag", "magazine", "bolt", "slide", "chamber", "cock", "rack", "insert", "eject", "click", "latch", "lock", "unlock", "safety", "foot", "step", "walk", "run", "land", "jump", "grab", "grip", "hold", "pickup", "drop", "rub", "scrape", "handle", "touch", "interact", "cloth", "leather", "fabric", "rustle", "ui", "menu", "button", "beep", "tick", "pop", "creak", "squeak", "hinge", "door_open", "door_close", "drawer", "breath", "gulp", "swallow", "eat", "drink" }; internal static bool ServerLocked { get; private set; } internal static void Init(MelonPreferences_Category prefs) { Enabled = prefs.CreateEntry("SoundFalloff_Enabled", true, (string)null, "--- SoundFalloff ---", false, false, (ValueValidator)null, (string)null); LocalRadius = prefs.CreateEntry("SoundFalloff_LocalRadius", 3f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); QuietMaxDist = prefs.CreateEntry("SoundFalloff_QuietMaxDistance", 40f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); MediumMaxDist = prefs.CreateEntry("SoundFalloff_MediumMaxDistance", 150f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); LoudMaxDist = prefs.CreateEntry("SoundFalloff_LoudMaxDistance", 800f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); BonesquadMod.Log($"SoundFalloff ready — Q:{QuietMaxDist.Value}m M:{MediumMaxDist.Value}m L:{LoudMaxDist.Value}m"); } internal static void OnToggle(bool enabled) { if (!ServerLocked) { Enabled.Value = enabled; } } internal static void ResetToDefaults(MelonPreferences_Category prefs) { if (!ServerLocked) { Enabled.Value = true; LocalRadius.Value = 3f; QuietMaxDist.Value = 40f; MediumMaxDist.Value = 150f; LoudMaxDist.Value = 800f; prefs.SaveToFile(true); } } internal static void OnServerConfig(bool enabled, float localRadius, float quietMax, float mediumMax, float loudMax) { ServerLocked = true; Enabled.Value = enabled; LocalRadius.Value = localRadius; QuietMaxDist.Value = quietMax; MediumMaxDist.Value = mediumMax; LoudMaxDist.Value = loudMax; BonesquadMod.Log("[SoundFalloff] Server lock applied."); } internal static void ClearServerLock() { if (ServerLocked) { ServerLocked = false; BonesquadMod.Log("[SoundFalloff] Server lock cleared."); } } internal static bool TryProcess(AudioSource source) { //IL_0044: 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_004f: 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) if (!Enabled.Value || (Object)(object)source == (Object)null) { return true; } if (source.spatialBlend < 0.5f) { return true; } try { Transform head = Player.Head; if ((Object)(object)head == (Object)null) { return true; } Vector3 val = ((Component)source).transform.position - head.position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; float value = LocalRadius.Value; if (sqrMagnitude <= value * value) { return true; } AudioClip clip = source.clip; SoundCategory cat = Categorize(((clip != null) ? ((Object)clip).name : null) ?? ((Object)((Component)source).gameObject).name); float num = MaxDist(cat); if (sqrMagnitude > num * num) { return false; } if (source.maxDistance > num) { source.minDistance = MinDist(cat); source.maxDistance = num; source.rolloffMode = (AudioRolloffMode)0; } return true; } catch { return true; } } private static SoundCategory Categorize(string clipName) { if (string.IsNullOrEmpty(clipName)) { return SoundCategory.Medium; } string text = clipName.ToLowerInvariant(); string[] loudWords = LoudWords; foreach (string value in loudWords) { if (text.Contains(value)) { return SoundCategory.Loud; } } loudWords = QuietWords; foreach (string value2 in loudWords) { if (text.Contains(value2)) { return SoundCategory.Quiet; } } return SoundCategory.Medium; } private static float MaxDist(SoundCategory cat) { return cat switch { SoundCategory.Quiet => QuietMaxDist.Value, SoundCategory.Loud => LoudMaxDist.Value, _ => MediumMaxDist.Value, }; } private static float MinDist(SoundCategory cat) { return cat switch { SoundCategory.Quiet => 1f, SoundCategory.Loud => 5f, _ => 2f, }; } } [HarmonyPatch(typeof(AudioSource))] internal static class AudioSourcePatches { [HarmonyPatch("Play", new Type[] { })] [HarmonyPrefix] internal static bool OnPlay(AudioSource __instance) { return SoundFalloffModule.TryProcess(__instance); } [HarmonyPatch("Play", new Type[] { typeof(double) })] [HarmonyPrefix] internal static bool OnPlayDouble(AudioSource __instance) { return SoundFalloffModule.TryProcess(__instance); } [HarmonyPatch("PlayOneShot", new Type[] { typeof(AudioClip) })] [HarmonyPrefix] internal static bool OnPlayOneShot(AudioSource __instance) { return SoundFalloffModule.TryProcess(__instance); } [HarmonyPatch("PlayOneShot", new Type[] { typeof(AudioClip), typeof(float) })] [HarmonyPrefix] internal static bool OnPlayOneShotVolume(AudioSource __instance) { return SoundFalloffModule.TryProcess(__instance); } [HarmonyPatch("PlayDelayed")] [HarmonyPrefix] internal static bool OnPlayDelayed(AudioSource __instance) { return SoundFalloffModule.TryProcess(__instance); } [HarmonyPatch("PlayScheduled")] [HarmonyPrefix] internal static bool OnPlayScheduled(AudioSource __instance) { return SoundFalloffModule.TryProcess(__instance); } } } namespace BONESQUAD.Modules.SlowWalk { internal static class SlowWalkModule { internal static MelonPreferences_Entry Enabled; internal static MelonPreferences_Entry SpeedMultiplier; private static Avatar _currentAvatar; private static bool _isSwapping; internal static bool ServerLocked { get; private set; } internal static void Init(MelonPreferences_Category prefs) { Enabled = prefs.CreateEntry("SlowWalk_Enabled", true, (string)null, "--- SlowWalk ---", false, false, (ValueValidator)null, (string)null); SpeedMultiplier = prefs.CreateEntry("SlowWalk_SpeedMultiplier", 0.7f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); Hooking.OnSwitchAvatarPostfix += OnAvatarSwitched; BonesquadMod.Log($"SlowWalk initialized. speed multiplier: {SpeedMultiplier.Value}"); } internal static void OnToggle(bool enabled) { if (!ServerLocked) { Enabled.Value = enabled; ReapplyToCurrentAvatar(); } } internal static void OnSpeedMultiplierChanged(float value) { if (!ServerLocked) { SpeedMultiplier.Value = value; ReapplyToCurrentAvatar(); } } internal static void ResetToDefaults(MelonPreferences_Category prefs) { if (!ServerLocked) { Enabled.Value = true; SpeedMultiplier.Value = 0.7f; prefs.SaveToFile(true); ReapplyToCurrentAvatar(); } } internal static void OnServerConfig(bool enabled, float multiplier) { ServerLocked = true; Enabled.Value = enabled; SpeedMultiplier.Value = multiplier; ReapplyToCurrentAvatar(); BonesquadMod.Log($"[SlowWalk] Server lock applied: enabled={enabled}, multiplier={multiplier}"); } internal static void ClearServerLock() { if (ServerLocked) { ServerLocked = false; BonesquadMod.Log("[SlowWalk] Server lock cleared."); } } private static void OnAvatarSwitched(Avatar avatar) { if ((Object)(object)avatar != (Object)null && ((Object)avatar).name != "[RealHeptaRig (Marrow1)]") { _currentAvatar = avatar; _isSwapping = false; } } private static void ReapplyToCurrentAvatar() { if (_isSwapping || (Object)(object)_currentAvatar == (Object)null) { return; } try { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null)) { _isSwapping = true; rigManager.SwapAvatar(_currentAvatar); } } catch (Exception ex) { _isSwapping = false; BonesquadMod.LogWarning("[SlowWalk] ReapplyToCurrentAvatar: " + ex.Message); } } } [HarmonyPatch(typeof(Avatar), "ComputeBaseStats")] internal static class AvatarComputeBaseStatsPatch { internal static void Postfix(Avatar __instance) { if (!((Object)(object)__instance == (Object)null) && !(((Object)__instance).name == "[RealHeptaRig (Marrow1)]") && SlowWalkModule.Enabled.Value) { __instance._speed *= SlowWalkModule.SpeedMultiplier.Value; } } } } namespace BONESQUAD.Modules.SlowRegen { public class ServerConfigData : INetSerializable { public bool SlowRegenEnabled = true; public float SlowRegenFactor = 5f; public bool SlowWalkEnabled = true; public float SlowWalkMultiplier = 0.7f; public bool SoundFalloffEnabled = true; public float SoundFalloffLocalRadius = 3f; public float SoundFalloffQuietMax = 40f; public float SoundFalloffMediumMax = 150f; public float SoundFalloffLoudMax = 800f; public bool BleedingEnabled = true; public float BleedingModifier = 1f; public float PingLifetime = 30f; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref SlowRegenEnabled); serializer.SerializeValue(ref SlowRegenFactor); serializer.SerializeValue(ref SlowWalkEnabled); serializer.SerializeValue(ref SlowWalkMultiplier); serializer.SerializeValue(ref SoundFalloffEnabled); serializer.SerializeValue(ref SoundFalloffLocalRadius); serializer.SerializeValue(ref SoundFalloffQuietMax); serializer.SerializeValue(ref SoundFalloffMediumMax); serializer.SerializeValue(ref SoundFalloffLoudMax); serializer.SerializeValue(ref BleedingEnabled); serializer.SerializeValue(ref BleedingModifier); serializer.SerializeValue(ref PingLifetime); } } [SkipHandleWhileLoading] public class ServerConfigHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { if (!((ReceivedMessage)(ref received)).Sender.HasValue || ((ReceivedMessage)(ref received)).Sender.Value != 0) { return; } try { ServerConfigData serverConfigData = ((ReceivedMessage)(ref received)).ReadData(); BonesquadMod.Log($"[ServerConfig] Received: SlowRegen={serverConfigData.SlowRegenEnabled}/{serverConfigData.SlowRegenFactor}, SlowWalk={serverConfigData.SlowWalkEnabled}/{serverConfigData.SlowWalkMultiplier}, SoundFalloff={serverConfigData.SoundFalloffEnabled}, Bleeding={serverConfigData.BleedingEnabled}/{serverConfigData.BleedingModifier}"); RegenerationModule.OnServerConfig(serverConfigData.SlowRegenEnabled, serverConfigData.SlowRegenFactor, serverConfigData.BleedingEnabled, serverConfigData.BleedingModifier); SlowWalkModule.OnServerConfig(serverConfigData.SlowWalkEnabled, serverConfigData.SlowWalkMultiplier); SoundFalloffModule.OnServerConfig(serverConfigData.SoundFalloffEnabled, serverConfigData.SoundFalloffLocalRadius, serverConfigData.SoundFalloffQuietMax, serverConfigData.SoundFalloffMediumMax, serverConfigData.SoundFalloffLoudMax); PingMarkerModule.OnServerConfig(serverConfigData.PingLifetime); } catch (Exception ex) { BonesquadMod.LogWarning("[ServerConfig] Failed to handle: " + ex.Message); } } } } namespace BONESQUAD.Modules.Regeneration { internal enum BleedState { None, Light, Heavy } internal static class RegenerationModule { internal static MelonPreferences_Entry Enabled; internal static MelonPreferences_Entry SlowFactor; internal static MelonPreferences_Entry BleedingEnabled; internal static MelonPreferences_Entry BleedingModifier; private static Player_Health _health; private static float _baseWait = -1f; private static float _baseTotal = -1f; private static float _prevHp = -1f; private static float _bleedTargetHp = -1f; private static BleedState _bleedState = BleedState.None; private static float _damageAccum = 0f; private static float _damageWindowStart = 0f; private const float DamageWindow = 3f; private static int _lightWoundCount = 0; private static float _lightWoundWindowStart = 0f; private const float LightWoundWindow = 30f; private static bool _isKnockout; private static bool _thumbstickPressed; private static bool _isBleedRagdoll = false; private static bool _captureBlocked = false; private static AudioSource _bleedSource; private static AudioClip _bleedClip; private static IEnumerator _bleedCoroutine; private static IEnumerator _recoveryCoroutine; private static int _bleedGeneration = 0; internal static bool ServerLocked { get; private set; } internal static Player_Health Health => _health; internal static BleedState CurrentBleedState => _bleedState; internal static bool IsKnockout => _isKnockout; private static void SetCaptureBlocked(bool blocked) { if (blocked != _captureBlocked) { _captureBlocked = blocked; BONESQUAD.Modules.FusionCompat.FusionCompat.SendKnockoutState(blocked); } } internal static void Init(MelonPreferences_Category prefs) { MelonPreferences_Entry entry = prefs.GetEntry("SlowRegen_Enabled"); MelonPreferences_Entry entry2 = prefs.GetEntry("SlowRegen_SlowFactor"); bool flag = entry?.Value ?? true; float num = entry2?.Value ?? 5f; Enabled = prefs.CreateEntry("Regeneration_Enabled", flag, (string)null, "--- Regeneration ---", false, false, (ValueValidator)null, (string)null); SlowFactor = prefs.CreateEntry("Regeneration_SlowFactor", num, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); BleedingEnabled = prefs.CreateEntry("Regeneration_BleedingEnabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); BleedingModifier = prefs.CreateEntry("Regeneration_BleedingModifier", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); BonesquadMod.Log($"Regeneration initialized. SlowFactor={SlowFactor.Value}, Bleeding={BleedingEnabled.Value}"); } internal static void OnToggle(bool enabled) { if (!ServerLocked) { Enabled.Value = enabled; ApplyToLive(); } } internal static void OnSlowFactorChanged(float value) { if (!ServerLocked) { SlowFactor.Value = value; ApplyToLive(); } } internal static void OnBleedingToggle(bool enabled) { if (!ServerLocked) { BleedingEnabled.Value = enabled; if (!enabled) { StopBleeding(); } } } internal static void OnBleedingModifierChanged(float value) { if (!ServerLocked) { BleedingModifier.Value = value; } } internal static void ResetToDefaults(MelonPreferences_Category prefs) { if (!ServerLocked) { Enabled.Value = true; SlowFactor.Value = 5f; BleedingEnabled.Value = true; BleedingModifier.Value = 1f; prefs.SaveToFile(true); ApplyToLive(); StopBleeding(); } } internal static void OnServerConfig(bool enabled, float factor, bool bleedingEnabled, float bleedingModifier) { ServerLocked = true; Enabled.Value = enabled; SlowFactor.Value = factor; BleedingEnabled.Value = bleedingEnabled; BleedingModifier.Value = bleedingModifier; ApplyToLive(); BonesquadMod.Log($"[Regeneration] Server lock: regen={enabled}/{factor}, bleeding={bleedingEnabled}/{bleedingModifier}"); } internal static void ClearServerLock() { if (ServerLocked) { ServerLocked = false; BonesquadMod.Log("[Regeneration] Server lock cleared."); } } internal static void OnHealthAwake(Player_Health health) { if (Object.op_Implicit((Object)(object)_bleedSource)) { _bleedSource.Stop(); _bleedSource.clip = null; } _health = health; _baseWait = health.wait_Regen_t; _baseTotal = health.totalRegenDuration; RespawnModule.OnHealthAwake(); if (Enabled.Value) { health.wait_Regen_t = _baseWait * SlowFactor.Value; health.totalRegenDuration = _baseTotal * SlowFactor.Value; } _prevHp = -1f; StopBleeding(); if ((Object)(object)_bleedClip == (Object)null) { TryLoadBleedAudio(); } BonesquadMod.Log($"[Regeneration] Health captured: curr={((Health)health).curr_Health:F1} max={((Health)health).max_Health:F1}"); } internal static void Update() { if (_isKnockout) { BaseController leftController = Player.LeftController; BaseController rightController = Player.RightController; if (((Object)(object)leftController != (Object)null && leftController.GetThumbStickDown()) || ((Object)(object)rightController != (Object)null && rightController.GetThumbStickDown())) { _thumbstickPressed = true; } } if ((Object)(object)_health == (Object)null || !Object.op_Implicit((Object)(object)_health) || !BleedingEnabled.Value) { return; } float num = ((Health)_health).curr_Health; bool flag = _prevHp >= 0f && num > _prevHp + ((Health)_health).max_Health * 0.15f; if (_bleedState != BleedState.None && _bleedTargetHp >= 0f && num > _bleedTargetHp && !flag) { num = _bleedTargetHp; ((Health)_health).curr_Health = num; } if (_prevHp < 0f) { _prevHp = num; } else if (num <= 0f) { if (_bleedState != BleedState.None) { StopBleeding(); } if (_prevHp > 0f) { RespawnModule.OnPlayerDied(); } _prevHp = 0f; } else if (num >= _prevHp) { if (_prevHp <= 0f && num > 0f) { RespawnModule.OnPlayerRevived(); } if (_bleedState != BleedState.None && num > _prevHp + ((Health)_health).max_Health * 0.15f) { BonesquadMod.Log($"[Regeneration] Bandage applied {_prevHp:F1}→{num:F1}, stopping bleed."); StopBleeding(); } _prevHp = num; } else { float num2 = _prevHp - num; _prevHp = num; if (!(num2 < 0.1f) && !(num >= ((Health)_health).max_Health - 0.1f)) { BonesquadMod.Log($"[Regeneration] Damage detected: -{num2:F2} HP (curr={num:F1}, max={((Health)_health).max_Health:F1})"); OnPlayerDamage(num2); } } } private static void OnPlayerDamage(float damage) { float max_Health = ((Health)_health).max_Health; if (max_Health <= 0f) { return; } if (_bleedTargetHp >= 0f) { _bleedTargetHp -= damage; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - _damageWindowStart > 3f) { _damageAccum = 0f; _damageWindowStart = realtimeSinceStartup; } _damageAccum += damage; float num = damage / max_Health; float num2 = _damageAccum / max_Health; BonesquadMod.Log($"[Regeneration] Damage eval: single={num:P0} accum={num2:P0} bleedState={_bleedState}"); if (num > 0.25f || num2 > 0.25f) { SetBleeding(BleedState.Heavy); } else { if (!(num2 >= 0.08f) || _bleedState == BleedState.Heavy) { return; } if (_bleedState == BleedState.None) { if (realtimeSinceStartup - _lightWoundWindowStart > 30f) { _lightWoundCount = 0; _lightWoundWindowStart = realtimeSinceStartup; } _lightWoundCount++; BonesquadMod.Log($"[Regeneration] Light wound #{_lightWoundCount}"); if (_lightWoundCount >= 3) { SetBleeding(BleedState.Heavy); return; } } SetBleeding(BleedState.Light); } } private static void SetBleeding(BleedState state) { if (_bleedState == state) { return; } BonesquadMod.Log($"[Regeneration] Bleed state: {_bleedState} → {state} (woundCount={_lightWoundCount}, isKnockout={_isKnockout})"); BleedState bleedState = _bleedState; _bleedState = state; if (state != BleedState.None && bleedState == BleedState.None && (Object)(object)_health != (Object)null && Object.op_Implicit((Object)(object)_health) && _baseWait >= 0f) { _health.wait_Regen_t = 99999f; _health.totalRegenDuration = 99999f; } if (_bleedCoroutine != null) { try { MelonCoroutines.Stop((object)_bleedCoroutine); } catch { } _bleedCoroutine = null; } _bleedGeneration++; if (state != BleedState.None) { StartBleedAudio(); _bleedCoroutine = BleedTick(_bleedGeneration); MelonCoroutines.Start(_bleedCoroutine); } else { StopBleedAudio(); } } private static IEnumerator BleedTick(int generation) { while (_bleedState != BleedState.None && generation == _bleedGeneration) { yield return (object)new WaitForSecondsRealtime(1f); if (_bleedState == BleedState.None || generation != _bleedGeneration) { break; } if ((Object)(object)_health == (Object)null || !Object.op_Implicit((Object)(object)_health) || !BleedingEnabled.Value) { _bleedCoroutine = null; _bleedState = BleedState.None; _damageAccum = 0f; _bleedTargetHp = -1f; ApplyToLive(); StopBleedAudio(); break; } float num = ((_bleedState == BleedState.Heavy) ? 0.0692f : 0.0253f) * BleedingModifier.Value; if (_bleedTargetHp < 0f) { _bleedTargetHp = ((Health)_health).curr_Health; } _bleedTargetHp -= num; float bleedTargetHp = _bleedTargetHp; BonesquadMod.Log($"[Regeneration] Bleed tick ({_bleedState}): -{num:F2} HP → {bleedTargetHp:F1}"); if (bleedTargetHp <= 1f) { ((Health)_health).curr_Health = 1f; _prevHp = 1f; _bleedTargetHp = -1f; _bleedCoroutine = null; _bleedState = BleedState.None; _damageAccum = 0f; ApplyToLive(); StopBleedAudio(); TriggerKnockout(); break; } ((Health)_health).curr_Health = bleedTargetHp; _prevHp = bleedTargetHp; } } private static void TriggerKnockout() { if (_isKnockout) { return; } RigManager rigManager = Player.RigManager; if (!Object.op_Implicit((Object)(object)rigManager)) { return; } _isKnockout = true; _thumbstickPressed = false; PhysicsRig physicsRig = rigManager.physicsRig; physicsRig.ShutdownRig(); physicsRig.RagdollRig(); SetCaptureBlocked(blocked: true); BonesquadMod.Log("[Regeneration] Player knocked out by bleeding."); if (_recoveryCoroutine != null) { try { MelonCoroutines.Stop((object)_recoveryCoroutine); } catch { } _recoveryCoroutine = null; } _recoveryCoroutine = RecoveryWatch(); MelonCoroutines.Start(_recoveryCoroutine); } private static IEnumerator RecoveryWatch() { float elapsed = 0f; while (_isKnockout) { yield return (object)new WaitForSecondsRealtime(0.2f); elapsed += 0.2f; if ((Object)(object)_health == (Object)null || !Object.op_Implicit((Object)(object)_health)) { _isKnockout = false; break; } if (((Health)_health).curr_Health > ((Health)_health).max_Health * 0.5f) { BonesquadMod.Log($"[Regeneration] Auto-recovery (HP {((Health)_health).curr_Health:F1} > 50% max)."); ExitKnockout(); break; } if (_thumbstickPressed) { _thumbstickPressed = false; BonesquadMod.Log("[Regeneration] Manual recovery (thumbstick)."); ExitKnockout(giveHp: true); break; } if (RespawnModule.KnockoutTimerEnabled.Value) { int knockoutLength = BONESQUAD.Modules.FusionCompat.FusionCompat.GetKnockoutLength(); float num = ((knockoutLength > 0) ? ((float)knockoutLength) : 60f); if (elapsed >= num) { BonesquadMod.Log($"[Regeneration] Knockout timer expired ({elapsed:F0}s / server={knockoutLength}s)."); ExitKnockout(giveHp: true); break; } } } } private static void ExitKnockout(bool giveHp = false, Vector3? teleportTo = null) { //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0183: 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_018f: 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_0110: Unknown result type (might be due to invalid IL or missing references) if (!_isKnockout) { return; } _isKnockout = false; _isBleedRagdoll = false; SetCaptureBlocked(blocked: false); if (giveHp && (Object)(object)_health != (Object)null && Object.op_Implicit((Object)(object)_health)) { float num = ((Health)_health).max_Health * 0.3f; ((Health)_health).curr_Health = num; _prevHp = num; BonesquadMod.Log($"[Regeneration] HP restored to {num:F1}."); } RigManager rigManager = Player.RigManager; if (!Object.op_Implicit((Object)(object)rigManager)) { return; } PhysicsRig physicsRig = rigManager.physicsRig; Transform transform = physicsRig.feet.transform; Transform transform2 = physicsRig.knee.transform; Transform transform3 = ((Component)((Rig)physicsRig).m_pelvis).transform; physicsRig.TurnOnRig(); physicsRig.UnRagdollRig(); if (teleportTo.HasValue) { try { rigManager.Teleport(teleportTo.Value, true); BonesquadMod.Log($"[Regeneration] Teleported to rally point {teleportTo.Value}."); } catch (Exception ex) { BonesquadMod.LogWarning("[Regeneration] Teleport failed, staying in place: " + ex.Message); Vector3 position = transform3.position; Quaternion rotation = transform3.rotation; transform2.SetPositionAndRotation(position, rotation); transform.SetPositionAndRotation(position, rotation); } } else { Vector3 position2 = transform3.position; Quaternion rotation2 = transform3.rotation; transform2.SetPositionAndRotation(position2, rotation2); transform.SetPositionAndRotation(position2, rotation2); } BonesquadMod.Log("[Regeneration] Exited knockout."); } internal static void OnBleedRagdoll(bool isRagdolled) { if (isRagdolled) { _isBleedRagdoll = true; SetCaptureBlocked(blocked: true); } else if (_isBleedRagdoll) { _isBleedRagdoll = false; SetCaptureBlocked(_isKnockout); } } internal static void StopBleeding() { if (_bleedCoroutine != null) { try { MelonCoroutines.Stop((object)_bleedCoroutine); } catch { } _bleedCoroutine = null; } _bleedState = BleedState.None; _damageAccum = 0f; _bleedTargetHp = -1f; _prevHp = (((Object)(object)_health != (Object)null && Object.op_Implicit((Object)(object)_health)) ? ((Health)_health).curr_Health : (-1f)); _isBleedRagdoll = false; SetCaptureBlocked(_isKnockout); ApplyToLive(); StopBleedAudio(); } private static void TryLoadBleedAudio() { string text = Path.Combine(MelonEnvironment.UserDataDirectory, "BONESQUAD", "Regeneration"); string[] obj = new string[3] { "bleeding.mp3", "bleeding.ogg", "bleeding.wav" }; string text2 = null; string[] array = obj; foreach (string path in array) { string text3 = Path.Combine(text, path); if (File.Exists(text3)) { text2 = text3; break; } } if (text2 == null) { BonesquadMod.LogWarning("[Regeneration] Bleed audio not found in: " + text); return; } try { _bleedClip = API.LoadAudioClip(text2, true); BonesquadMod.Log("[Regeneration] Bleed audio loaded: " + Path.GetFileName(text2)); } catch (Exception ex) { BonesquadMod.LogWarning("[Regeneration] Failed to load bleed audio: " + ex.Message); } } private static void EnsureBleedSource() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_bleedSource)) { GameObject val = new GameObject("BONESQUAD_BleedAudio"); Object.DontDestroyOnLoad((Object)val); _bleedSource = val.AddComponent(); _bleedSource.spatialBlend = 0f; _bleedSource.loop = true; _bleedSource.playOnAwake = false; _bleedSource.volume = 0.5f; } } private static void StartBleedAudio() { if ((Object)(object)_bleedClip == (Object)null) { BonesquadMod.LogWarning("[Regeneration] StartBleedAudio: clip is null."); return; } EnsureBleedSource(); if (!Object.op_Implicit((Object)(object)_bleedSource)) { BonesquadMod.LogWarning("[Regeneration] StartBleedAudio: source is null."); } else if (!_bleedSource.isPlaying) { _bleedSource.clip = _bleedClip; _bleedSource.Play(); BonesquadMod.Log("[Regeneration] Bleed audio started."); } } private static void StopBleedAudio() { if (Object.op_Implicit((Object)(object)_bleedSource)) { _bleedSource.Stop(); _bleedSource.clip = null; BonesquadMod.Log("[Regeneration] Bleed audio stopped."); } } private static void ApplyToLive() { if ((Object)(object)_health == (Object)null || !Object.op_Implicit((Object)(object)_health) || _baseWait < 0f) { return; } try { float num = (Enabled.Value ? SlowFactor.Value : 1f); _health.wait_Regen_t = _baseWait * num; _health.totalRegenDuration = _baseTotal * num; } catch (Exception ex) { BonesquadMod.LogWarning("[Regeneration] ApplyToLive: " + ex.Message); } } } [HarmonyPatch(typeof(Player_Health), "Awake")] internal static class PlayerHealthAwakePatch { internal static void Postfix(Player_Health __instance) { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager != (Object)null) || ((Component)__instance).transform.IsChildOf(((Component)rigManager).transform)) { RegenerationModule.OnHealthAwake(__instance); } } } [HarmonyPatch(typeof(PhysicsRig), "RagdollRig")] internal static class PhysicsRigRagdollPatch { internal static void Postfix(PhysicsRig __instance) { try { if (RegenerationModule.CurrentBleedState != BleedState.None && !RegenerationModule.IsKnockout) { RigManager rigManager = Player.RigManager; if (Object.op_Implicit((Object)(object)rigManager) && !((Object)(object)rigManager.physicsRig != (Object)(object)__instance)) { RegenerationModule.OnBleedRagdoll(isRagdolled: true); } } } catch { } } } [HarmonyPatch(typeof(PhysicsRig), "UnRagdollRig")] internal static class PhysicsRigUnRagdollPatch { internal static void Postfix(PhysicsRig __instance) { try { RigManager rigManager = Player.RigManager; if (Object.op_Implicit((Object)(object)rigManager) && !((Object)(object)rigManager.physicsRig != (Object)(object)__instance)) { RegenerationModule.OnBleedRagdoll(isRagdolled: false); } } catch { } } } } namespace BONESQUAD.Modules.RadialMenu { public class PingMarkerData : INetSerializable { public byte SenderId; public string FileName; public float PosX; public float PosY; public float PosZ; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref SenderId); serializer.SerializeValue(ref FileName); serializer.SerializeValue(ref PosX); serializer.SerializeValue(ref PosY); serializer.SerializeValue(ref PosZ); } public static PingMarkerData Create(byte senderId, string fileName, Vector3 pos) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) return new PingMarkerData { SenderId = senderId, FileName = fileName, PosX = pos.x, PosY = pos.y, PosZ = pos.z }; } } [SkipHandleWhileLoading] public class PingMarkerMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) try { PingMarkerData pingMarkerData = ((ReceivedMessage)(ref received)).ReadData(); if (pingMarkerData.SenderId != PlayerIDManager.LocalSmallID && PingMarkerModule.SharesGroup(pingMarkerData.SenderId)) { string ownerLabel = "by ???"; NetworkPlayer val = default(NetworkPlayer); string text = default(string); if (NetworkPlayerManager.TryGetPlayer(pingMarkerData.SenderId, ref val) && MetadataHelper.TryGetDisplayName(val.PlayerID, ref text)) { ownerLabel = "by " + text; } PingMarkerModule.Place(new Vector3(pingMarkerData.PosX, pingMarkerData.PosY, pingMarkerData.PosZ), RadialMenuModule.GetPingBytes(pingMarkerData.FileName), ownerLabel); } } catch (Exception ex) { BonesquadMod.LogWarning("[PingMarker] Failed to handle message: " + ex.Message); } } } internal static class PingMarkerModule { private class PingMarker { internal GameObject Root; internal SpriteRenderer IconSr; internal Material IconMat; internal Texture2D Tex; internal TextMesh DistTm; internal Transform LabelT; internal TextMesh OwnerTm; internal Transform OwnerT; internal float SpawnTime; } internal struct CompassPingEntry { internal Vector3 WorldPos; internal Texture2D Tex; internal string OwnerLabel; } internal static MelonPreferences_Entry ShowPings; internal static MelonPreferences_Entry ShowDistance; internal static MelonPreferences_Entry IconSize; internal static MelonPreferences_Entry DistSize; internal static MelonPreferences_Entry OwnerSize; internal static MelonPreferences_Entry ShowOwnerLabel; internal static MelonPreferences_Entry OwnLabel; internal static MelonPreferences_Entry UseRightHand; internal static MelonPreferences_Entry MarkersDie; internal static MelonPreferences_Entry MarkerLifetime; private const float DefaultIconSize = 0.02f; private const float DefaultDistSize = 0.007f; private const float DefaultOwnerSize = 0.007f; private const float DefaultMarkerLifetime = 30f; private static readonly List _markers = new List(); private static string _soundPath; private static AudioClip _placeSound; private static AudioSource _uiAudio; private static readonly Dictionary _playerGroupsRaw = new Dictionary(); internal static bool ServerLocked { get; private set; } internal static void FillCompassPings(List dest) { //IL_003e: 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) dest.Clear(); foreach (PingMarker marker in _markers) { if (Object.op_Implicit((Object)(object)marker.Root)) { dest.Add(new CompassPingEntry { WorldPos = marker.Root.transform.position, Tex = marker.Tex, OwnerLabel = (Object.op_Implicit((Object)(object)marker.OwnerTm) ? marker.OwnerTm.text : "") }); } } } internal static void Init(MelonPreferences_Category prefs) { ShowPings = prefs.CreateEntry("Pings_ShowPings", true, (string)null, "--- Pings ---", false, false, (ValueValidator)null, (string)null); ShowDistance = prefs.CreateEntry("Pings_ShowDistance", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); ShowOwnerLabel = prefs.CreateEntry("Pings_ShowOwnerLabel", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); OwnLabel = prefs.CreateEntry("Pings_OwnLabel", "by you", (string)null, (string)null, false, false, (ValueValidator)null, (string)null); IconSize = prefs.CreateEntry("Pings_IconSize", 0.02f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); DistSize = prefs.CreateEntry("Pings_DistSize", 0.007f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); OwnerSize = prefs.CreateEntry("Pings_OwnerSize", 0.007f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); UseRightHand = prefs.CreateEntry("Pings_UseRightHand", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); MarkersDie = prefs.CreateEntry("Pings_MarkersDie", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); MarkerLifetime = prefs.CreateEntry("Pings_Lifetime", 30f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _soundPath = Path.Combine(MelonEnvironment.UserDataDirectory, "BONESQUAD", "UI", "Pings", "menu_deploy_accept_button_01.wav"); if (!File.Exists(_soundPath)) { BonesquadMod.LogWarning("[Pings] Place sound not found: " + _soundPath); _soundPath = null; } } internal static void OnServerConfig(float lifetime) { ServerLocked = true; MarkerLifetime.Value = lifetime; } internal static void ClearServerLock() { if (ServerLocked) { ServerLocked = false; } } internal static void SetPlayerGroups(byte id, string groupIdsJoined) { _playerGroupsRaw[id] = groupIdsJoined; } internal static void ClearPlayerGroups(byte id) { _playerGroupsRaw.Remove(id); } internal static void ClearAllPlayerGroups() { _playerGroupsRaw.Clear(); } internal static bool SharesGroup(byte otherId) { if (!_playerGroupsRaw.TryGetValue(PlayerIDManager.LocalSmallID, out var value)) { return true; } if (!_playerGroupsRaw.TryGetValue(otherId, out var value2)) { return true; } if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(value2)) { return true; } string[] array = value.Split('|'); foreach (string value3 in array) { if (value2.Contains(value3)) { return true; } } return false; } internal static bool SharesGroupId(string groupId) { if (string.IsNullOrEmpty(groupId)) { return true; } if (!_playerGroupsRaw.TryGetValue(PlayerIDManager.LocalSmallID, out var value)) { return true; } if (string.IsNullOrEmpty(value)) { return true; } string[] array = value.Split('|'); for (int i = 0; i < array.Length; i++) { if (array[i] == groupId) { return true; } } return false; } internal static void ResetToDefaults(MelonPreferences_Category prefs) { ShowPings.Value = true; ShowDistance.Value = true; ShowOwnerLabel.Value = true; OwnLabel.Value = "by you"; IconSize.Value = 0.02f; DistSize.Value = 0.007f; OwnerSize.Value = 0.007f; UseRightHand.Value = false; MarkersDie.Value = true; MarkerLifetime.Value = 30f; prefs.SaveToFile(true); } private static void EnsureAudioSource() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_uiAudio)) { GameObject val = new GameObject("BONESQUAD_PingAudio"); Object.DontDestroyOnLoad((Object)val); _uiAudio = val.AddComponent(); _uiAudio.spatialBlend = 0f; _uiAudio.playOnAwake = false; BonesquadMod.Log("[Pings] AudioSource created."); } } private static void EnsurePlaceSound() { if (Object.op_Implicit((Object)(object)_placeSound)) { BonesquadMod.Log($"[Pings] Sound already loaded: '{((Object)_placeSound).name}' length={_placeSound.length:F2}s"); return; } if (_soundPath == null) { BonesquadMod.LogWarning("[Pings] EnsurePlaceSound: _soundPath is null, skipping load."); return; } BonesquadMod.Log("[Pings] Loading sound from: " + _soundPath); try { _placeSound = API.LoadAudioClip(_soundPath, true); if (Object.op_Implicit((Object)(object)_placeSound)) { BonesquadMod.Log($"[Pings] Sound loaded OK: '{((Object)_placeSound).name}' length={_placeSound.length:F2}s channels={_placeSound.channels} freq={_placeSound.frequency}"); } else { BonesquadMod.LogWarning("[Pings] API.LoadAudioClip returned null."); } } catch (Exception ex) { BonesquadMod.LogWarning("[Pings] Failed to load place sound: " + ex.Message); _soundPath = null; } } internal static void Place(Vector3 worldPos, byte[] pngData, string ownerLabel = "") { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0021: 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_003f: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown //IL_01a5: 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_006b: Expected O, but got Unknown //IL_00b2: 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_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) PingMarker pingMarker = new PingMarker(); pingMarker.Root = new GameObject("BONESQUAD_PingMarker"); pingMarker.Root.transform.position = worldPos; ((Object)pingMarker.Root).hideFlags = (HideFlags)61; GameObject val = new GameObject("Icon"); val.transform.SetParent(pingMarker.Root.transform, false); Sprite val2 = null; if (pngData != null) { pingMarker.Tex = new Texture2D(2, 2); ((Object)pingMarker.Tex).hideFlags = (HideFlags)61; ImageConversion.LoadImage(pingMarker.Tex, Il2CppStructArray.op_Implicit(pngData)); val2 = Sprite.Create(pingMarker.Tex, new Rect(0f, 0f, (float)((Texture)pingMarker.Tex).width, (float)((Texture)pingMarker.Tex).height), new Vector2(0.5f, 0.5f), (float)((Texture)pingMarker.Tex).width); ((Object)val2).hideFlags = (HideFlags)61; } pingMarker.IconMat = new Material(Shader.Find("UI/Default")) { hideFlags = (HideFlags)61 }; pingMarker.IconMat.SetInt("unity_GUIZTestMode", 8); pingMarker.IconSr = val.AddComponent(); pingMarker.IconSr.sprite = val2; ((Renderer)pingMarker.IconSr).material = pingMarker.IconMat; pingMarker.IconSr.color = Color.white; ((Renderer)pingMarker.IconSr).sortingOrder = 10; GameObject val3 = new GameObject("Dist"); val3.transform.SetParent(pingMarker.Root.transform, false); pingMarker.DistTm = val3.AddComponent(); pingMarker.DistTm.text = ""; pingMarker.DistTm.fontSize = 40; pingMarker.DistTm.color = Color.white; pingMarker.DistTm.anchor = (TextAnchor)1; pingMarker.DistTm.alignment = (TextAlignment)1; pingMarker.DistTm.fontStyle = (FontStyle)1; ((Renderer)val3.GetComponent()).sortingOrder = 10; pingMarker.LabelT = val3.transform; if (!string.IsNullOrEmpty(ownerLabel)) { GameObject val4 = new GameObject("Owner"); val4.transform.SetParent(pingMarker.Root.transform, false); pingMarker.OwnerTm = val4.AddComponent(); pingMarker.OwnerTm.text = ownerLabel; pingMarker.OwnerTm.fontSize = 40; pingMarker.OwnerTm.color = ((ownerLabel == OwnLabel.Value) ? new Color(0.5f, 1f, 0.5f) : new Color(1f, 1f, 0.6f)); pingMarker.OwnerTm.anchor = (TextAnchor)7; pingMarker.OwnerTm.alignment = (TextAlignment)1; pingMarker.OwnerTm.fontStyle = (FontStyle)1; ((Renderer)val4.GetComponent()).sortingOrder = 10; pingMarker.OwnerT = val4.transform; } pingMarker.SpawnTime = Time.time; _markers.Add(pingMarker); EnsurePlaceSound(); EnsureAudioSource(); BonesquadMod.Log($"[Pings] Play check — _placeSound={Object.op_Implicit((Object)(object)_placeSound)} _uiAudio={Object.op_Implicit((Object)(object)_uiAudio)}"); if (Object.op_Implicit((Object)(object)_placeSound) && Object.op_Implicit((Object)(object)_uiAudio)) { BonesquadMod.Log($"[Pings] Calling PlayOneShot. volume={_uiAudio.volume} mute={_uiAudio.mute} enabled={((Behaviour)_uiAudio).enabled} gameObject.active={((Component)_uiAudio).gameObject.activeSelf}"); _uiAudio.PlayOneShot(_placeSound); BonesquadMod.Log("[Pings] PlayOneShot called."); } else { BonesquadMod.LogWarning($"[Pings] Cannot play: _placeSound={Object.op_Implicit((Object)(object)_placeSound)} _uiAudio={Object.op_Implicit((Object)(object)_uiAudio)}"); } } internal static void Update() { //IL_00f0: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) Transform val = null; try { val = Player.Head; } catch { } float value = MarkerLifetime.Value; float time = Time.time; for (int num = _markers.Count - 1; num >= 0; num--) { PingMarker pingMarker = _markers[num]; if (!Object.op_Implicit((Object)(object)pingMarker.Root)) { _markers.RemoveAt(num); } else if (MarkersDie.Value && time - pingMarker.SpawnTime >= value) { Object.Destroy((Object)(object)pingMarker.Root); if (Object.op_Implicit((Object)(object)pingMarker.IconMat)) { Object.Destroy((Object)(object)pingMarker.IconMat); } if (Object.op_Implicit((Object)(object)pingMarker.Tex)) { Object.Destroy((Object)(object)pingMarker.Tex); } _markers.RemoveAt(num); } else { bool value2 = ShowPings.Value; pingMarker.Root.SetActive(value2); if (value2 && Object.op_Implicit((Object)(object)val)) { Vector3 val2 = val.position - pingMarker.Root.transform.position; if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { pingMarker.Root.transform.rotation = Quaternion.LookRotation(-val2); } float magnitude = ((Vector3)(ref val2)).magnitude; float num2 = IconSize.Value * magnitude; ((Component)pingMarker.IconSr).transform.localScale = Vector3.one * num2; bool value3 = ShowDistance.Value; if (Object.op_Implicit((Object)(object)pingMarker.LabelT)) { ((Component)pingMarker.LabelT).gameObject.SetActive(value3); } if (value3 && Object.op_Implicit((Object)(object)pingMarker.DistTm)) { pingMarker.DistTm.text = $"{magnitude:F1} M"; pingMarker.DistTm.characterSize = DistSize.Value * magnitude; pingMarker.LabelT.localPosition = new Vector3(0f, 0f - num2 * 0.55f, 0f); } if (Object.op_Implicit((Object)(object)pingMarker.OwnerT) && Object.op_Implicit((Object)(object)pingMarker.OwnerTm)) { bool value4 = ShowOwnerLabel.Value; ((Component)pingMarker.OwnerT).gameObject.SetActive(value4); if (value4) { pingMarker.OwnerTm.characterSize = OwnerSize.Value * magnitude; pingMarker.OwnerT.localPosition = new Vector3(0f, num2 * 0.6f, 0f); } } } } } } internal static void ClearAll() { foreach (PingMarker marker in _markers) { if (Object.op_Implicit((Object)(object)marker.Root)) { Object.Destroy((Object)(object)marker.Root); } if (Object.op_Implicit((Object)(object)marker.IconMat)) { Object.Destroy((Object)(object)marker.IconMat); } if (Object.op_Implicit((Object)(object)marker.Tex)) { Object.Destroy((Object)(object)marker.Tex); } } _markers.Clear(); } } internal static class RadialMenuModule { private enum MenuState { Closed, MainMenu, PingsMenu, SpawnPointMenu } private struct SpriteAsset { internal byte[] Data; internal float Scale; } private static MenuState _state; private static bool _xPrev; private static float _xHoldTimer; private static int _highlightedIdx = -1; private static float _rightTrigPrev; private const float HoldThreshold = 0.8f; private static GameObject _menuRayGo; private static LineRenderer _menuRayLr; private static Material _menuRayMat; private static GameObject _menuDotGo; private static SpriteRenderer _menuDotSr; private static Texture2D _menuDotTex; private static Material _menuDotMat; private static float _heartbeatTimer; private static float _xLogTimer; private static string _selectedPing = ""; private static Texture2D _selectedTex; private static Sprite _selectedSprite; private static bool _rayActive; private static GameObject _rayGo; private static LineRenderer _rayLr; private static Material _rayMat; private static GameObject _rayLabelGo; private static TextMesh _rayLabelTm; private static GameObject _rayIconGo; private static SpriteRenderer _rayIconSr; private static Material _rayIconMat; private static float _triggerPrev; private static Vector3 _rayHitPoint; private static bool _rayHasHit; private static GameObject _root; private static Sprite _whitePixel; private static Sprite _circleSprite; private static readonly List _itemBgs = new List(); private static readonly List _itemLabels = new List(); private static readonly List _sectorHighlightGos = new List(); private static readonly List _sectorMeshes = new List(); private static Material _sectorMat; private static Texture2D _sectorTex; private static readonly Dictionary _assets = new Dictionary(); private static readonly List _buildTextures = new List(); private static byte[] _logoData; private static bool[] _spawnDisabled; private static string[] _spawnDisabledMsg; private static GameObject _tooltipGo; private static TextMesh _tooltipTm; internal static readonly string[] PingOrder = new string[6] { "known_obj_attack.png", "T_role_category_directcombat.png", "T_role_crewman.png", "known_obj_defend.png", "T_role_medic.png", "T_LineOfSight.png" }; internal static readonly string[] SpawnOrder = new string[3] { "mainbase.png", "RadialRallyPointIcon.png", "deployable_hab.png" }; private static readonly Dictionary SpawnLabels = new Dictionary { ["mainbase.png"] = "Main Base", ["RadialRallyPointIcon.png"] = "Rally Point", ["deployable_hab.png"] = "HAB" }; private static readonly Color NormalBg = new Color(0.12f, 0.12f, 0.12f, 0.92f); private static readonly Color HighlightBg = new Color(0.85f, 0.65f, 0.05f, 1f); internal static MelonPreferences_Entry SelectedSpawn; internal static bool IsOpen => _state != MenuState.Closed; internal static void Init(MelonPreferences_Category prefs) { //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_0027: 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_0037: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00a6: 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_00da: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) SelectedSpawn = prefs.CreateEntry("SpawnPoint_Selected", SpawnOrder[0], (string)null, (string)null, false, false, (ValueValidator)null, (string)null); Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, Color.white); val.Apply(); ((Object)val).hideFlags = (HideFlags)61; _whitePixel = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 1f); ((Object)_whitePixel).hideFlags = (HideFlags)61; _circleSprite = CreateCircleSprite(512); _sectorTex = new Texture2D(1, 1, (TextureFormat)4, false); _sectorTex.SetPixel(0, 0, Color.white); _sectorTex.Apply(); ((Object)_sectorTex).hideFlags = (HideFlags)61; _sectorMat = new Material(Shader.Find("Sprites/Default")); _sectorMat.mainTexture = (Texture)(object)_sectorTex; _sectorMat.color = new Color(1f, 1f, 1f, 0.18f); ((Object)_sectorMat).hideFlags = (HideFlags)61; string text = Path.Combine(MelonEnvironment.UserDataDirectory, "BONESQUAD", "UI"); BonesquadMod.Log("[RadialMenu] UI base path: " + text); BonesquadMod.Log($"[RadialMenu] UI base exists: {Directory.Exists(text)}"); LoadDir(Path.Combine(text, "Pings"), PingOrder); LoadDir(Path.Combine(text, "SpawnPoints"), SpawnOrder); string path = Path.Combine(text, "bonesquad.png"); if (File.Exists(path)) { _logoData = File.ReadAllBytes(path); BonesquadMod.Log($"[RadialMenu] Logo loaded: {_logoData.Length} bytes"); } BonesquadMod.Log($"[RadialMenu] Init done. Assets loaded: {_assets.Count}"); if (PingOrder.Length != 0) { SelectPing(PingOrder[0]); } Hooking.OnLevelUnloaded += OnLevelUnloaded; } private static void OnLevelUnloaded() { if (IsOpen) { Close(); } DestroyRay(); DestroyMenuRay(); PingMarkerModule.ClearAll(); } private static void SelectPing(string file) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0098: 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) _selectedPing = file; if (Object.op_Implicit((Object)(object)_selectedTex)) { Object.Destroy((Object)(object)_selectedTex); } _selectedSprite = null; _selectedTex = null; if (_assets.TryGetValue(file, out var value) && value.Data != null) { _selectedTex = new Texture2D(2, 2); ((Object)_selectedTex).hideFlags = (HideFlags)61; ImageConversion.LoadImage(_selectedTex, Il2CppStructArray.op_Implicit(value.Data)); _selectedSprite = Sprite.Create(_selectedTex, new Rect(0f, 0f, (float)((Texture)_selectedTex).width, (float)((Texture)_selectedTex).height), new Vector2(0.5f, 0.5f), (float)((Texture)_selectedTex).width); ((Object)_selectedSprite).hideFlags = (HideFlags)61; } if (_rayActive && Object.op_Implicit((Object)(object)_rayIconSr)) { _rayIconSr.sprite = _selectedSprite; } } internal static byte[] GetPingBytes(string fileName) { if (_assets.TryGetValue(fileName, out var value)) { return value.Data; } return null; } private static void LoadDir(string dir, string[] files) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown BonesquadMod.Log($"[RadialMenu] LoadDir: {dir} | exists={Directory.Exists(dir)}"); if (!Directory.Exists(dir)) { return; } foreach (string text in files) { string path = Path.Combine(dir, text); bool flag = File.Exists(path); BonesquadMod.Log($"[RadialMenu] {text} exists={flag}"); if (flag) { try { byte[] array = File.ReadAllBytes(path); BonesquadMod.Log($"[RadialMenu] {text} bytes={array.Length}"); Texture2D val = new Texture2D(2, 2); bool value = ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(array)); int width = ((Texture)val).width; int height = ((Texture)val).height; BonesquadMod.Log($"[RadialMenu] {text} LoadImage={value} size={width}x{height}"); Object.Destroy((Object)val); int num = Math.Max(width, height); float num2 = ((num > 0) ? (4.4f / (float)num) : 0.044f); _assets[text] = new SpriteAsset { Data = array, Scale = num2 }; BonesquadMod.Log($"[RadialMenu] {text} scale={num2:F4}"); } catch (Exception value2) { BonesquadMod.LogWarning($"[RadialMenu] Load FAILED {text}: {value2}"); } } } } internal static void Update() { //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) _heartbeatTimer += Time.unscaledDeltaTime; if (_heartbeatTimer >= 10f) { _heartbeatTimer = 0f; BonesquadMod.Log($"[RadialMenu] Heartbeat — state={_state}"); } BaseController leftController = Player.LeftController; bool flag = Object.op_Implicit((Object)(object)leftController) && leftController.GetAButton(); _xLogTimer += Time.unscaledDeltaTime; if (_xLogTimer >= 3f) { _xLogTimer = 0f; BonesquadMod.Log($"[RadialMenu] XInput — lc={(Object.op_Implicit((Object)(object)leftController) ? "OK" : "NULL")} xDown={flag} state={_state}"); } if (flag) { if (!_xPrev) { _xHoldTimer = 0f; BonesquadMod.Log($"[RadialMenu] X pressed. Hold {0.8f}s to open."); } _xHoldTimer += Time.unscaledDeltaTime; if (!IsOpen && _xHoldTimer >= 0.8f) { Open(MenuState.MainMenu); } } else if (_xPrev) { BonesquadMod.Log($"[RadialMenu] X released — timer={_xHoldTimer:F2}"); if (IsOpen && _xHoldTimer < 0.8f) { Close(); } else if (!IsOpen && _xHoldTimer < 0.8f) { TogglePointerRay(); } _xHoldTimer = 0f; } _xPrev = flag; UpdateRay(); if (!IsOpen) { return; } if (Object.op_Implicit((Object)(object)_root) && Object.op_Implicit((Object)(object)Player.Head)) { Vector3 val = _root.transform.position - Player.Head.position; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { _root.transform.rotation = Quaternion.LookRotation(val, Vector3.up); } } UpdateMenuHover(); BaseController rightController = Player.RightController; float num = (Object.op_Implicit((Object)(object)rightController) ? rightController.GetIndexCurlAxis() : 0f); bool num2 = num > 0.8f && _rightTrigPrev <= 0.8f; _rightTrigPrev = num; if (num2 && _highlightedIdx >= 0) { Confirm(_highlightedIdx); } } private static void TogglePointerRay() { if (_rayActive) { DestroyRay(); } else { CreateRay(); } } private static void CreateRay() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_00ac: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) _rayActive = true; _rayGo = new GameObject("BONESQUAD_PingRay"); ((Object)_rayGo).hideFlags = (HideFlags)61; _rayMat = new Material(Shader.Find("Sprites/Default")); ((Object)_rayMat).hideFlags = (HideFlags)61; _rayLr = _rayGo.AddComponent(); ((Renderer)_rayLr).material = _rayMat; _rayLr.useWorldSpace = true; _rayLr.positionCount = 2; _rayLr.startWidth = 0.004f; _rayLr.endWidth = 0.002f; _rayLr.startColor = new Color(1f, 0.5f, 0f, 0.95f); _rayLr.endColor = new Color(1f, 0.5f, 0f, 0.85f); _rayLabelGo = new GameObject("BONESQUAD_PingLabel"); ((Object)_rayLabelGo).hideFlags = (HideFlags)61; _rayLabelTm = _rayLabelGo.AddComponent(); _rayLabelTm.text = "— M"; _rayLabelTm.fontSize = 40; _rayLabelTm.characterSize = 0.003f; _rayLabelTm.color = new Color(1f, 0.5f, 0f, 1f); _rayLabelTm.anchor = (TextAnchor)1; _rayLabelTm.alignment = (TextAlignment)1; _rayLabelTm.fontStyle = (FontStyle)1; ((Renderer)_rayLabelGo.GetComponent()).sortingOrder = 10; _rayIconGo = new GameObject("BONESQUAD_PingIcon"); ((Object)_rayIconGo).hideFlags = (HideFlags)61; _rayIconMat = new Material(Shader.Find("Sprites/Default")) { hideFlags = (HideFlags)61 }; _rayIconSr = _rayIconGo.AddComponent(); ((Renderer)_rayIconSr).material = _rayIconMat; _rayIconSr.sprite = _selectedSprite; _rayIconSr.color = Color.white; ((Renderer)_rayIconSr).sortingOrder = 10; _rayIconGo.transform.localScale = Vector3.one * 0.016f; _triggerPrev = 0f; _rayHasHit = false; BonesquadMod.Log("[RadialMenu] Pointer ray ON"); } private static void DestroyRay() { _rayActive = false; if (Object.op_Implicit((Object)(object)_rayGo)) { Object.Destroy((Object)(object)_rayGo); } if (Object.op_Implicit((Object)(object)_rayMat)) { Object.Destroy((Object)(object)_rayMat); } if (Object.op_Implicit((Object)(object)_rayLabelGo)) { Object.Destroy((Object)(object)_rayLabelGo); } if (Object.op_Implicit((Object)(object)_rayIconGo)) { Object.Destroy((Object)(object)_rayIconGo); } if (Object.op_Implicit((Object)(object)_rayIconMat)) { Object.Destroy((Object)(object)_rayIconMat); } _rayGo = null; _rayLr = null; _rayMat = null; _rayLabelGo = null; _rayLabelTm = null; _rayIconGo = null; _rayIconSr = null; _rayIconMat = null; _rayHasHit = false; BonesquadMod.Log("[RadialMenu] Pointer ray OFF"); } private static void UpdateRay() { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00ce: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: 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) if (!_rayActive) { return; } if (!Object.op_Implicit((Object)(object)_rayLr)) { DestroyRay(); return; } BaseController val = (PingMarkerModule.UseRightHand.Value ? Player.RightController : Player.LeftController); if (!Object.op_Implicit((Object)(object)val)) { return; } float indexCurlAxis = val.GetIndexCurlAxis(); bool num = indexCurlAxis > 0.8f && _triggerPrev <= 0.8f; _triggerPrev = indexCurlAxis; if (num && _rayHasHit) { byte[] pingBytes = GetPingBytes(_selectedPing); PingMarkerModule.Place(_rayHitPoint, pingBytes, PingMarkerModule.OwnLabel.Value); BONESQUAD.Modules.FusionCompat.FusionCompat.BroadcastPing(_selectedPing, _rayHitPoint); DestroyRay(); return; } Vector3 position = ((Component)val).transform.position; Vector3 forward = ((Component)val).transform.forward; _rayLr.SetPosition(0, position); _rayLr.SetPosition(1, position + forward * 1000f); if (!Object.op_Implicit((Object)(object)_rayLabelGo) || !Object.op_Implicit((Object)(object)_rayLabelTm)) { return; } RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(position + forward * 0.5f, forward, ref val2, 999.5f, -5, (QueryTriggerInteraction)1)) { float value = ((RaycastHit)(ref val2)).distance + 0.5f; _rayHitPoint = ((RaycastHit)(ref val2)).point; _rayHasHit = true; _rayLabelTm.text = $"{value:F1} M"; } else { _rayHasHit = false; _rayLabelTm.text = "∞ M"; } Vector3 val3 = position + ((Component)val).transform.up * 0.12f; _rayLabelGo.transform.position = val3; Transform head = Player.Head; if (Object.op_Implicit((Object)(object)head)) { Vector3 val4 = head.position - val3; if (((Vector3)(ref val4)).sqrMagnitude > 0.001f) { _rayLabelGo.transform.rotation = Quaternion.LookRotation(val3 - head.position); } } if (Object.op_Implicit((Object)(object)_rayIconGo)) { _rayIconGo.transform.position = val3 + ((Component)val).transform.up * 0.022f; _rayIconGo.transform.rotation = _rayLabelGo.transform.rotation; } } private static void CreateMenuRay() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //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_0037: Expected O, but got Unknown //IL_00a2: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Expected O, but got Unknown //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Expected O, but got Unknown //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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) _menuRayGo = new GameObject("BONESQUAD_MenuRay"); ((Object)_menuRayGo).hideFlags = (HideFlags)61; _menuRayMat = new Material(Shader.Find("Sprites/Default")) { hideFlags = (HideFlags)61 }; _menuRayLr = _menuRayGo.AddComponent(); ((Renderer)_menuRayLr).material = _menuRayMat; _menuRayLr.useWorldSpace = true; _menuRayLr.positionCount = 2; _menuRayLr.startWidth = 0.004f; _menuRayLr.endWidth = 0.002f; _menuRayLr.startColor = new Color(0.6f, 0.8f, 1f, 0.95f); _menuRayLr.endColor = new Color(0.6f, 0.8f, 1f, 0.7f); _menuDotTex = new Texture2D(32, 32, (TextureFormat)4, false); ((Object)_menuDotTex).hideFlags = (HideFlags)61; Color val = default(Color); ((Color)(ref val))..ctor(0.6f, 0.8f, 1f); for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num = ((float)j - 15.5f) / 16f; float num2 = ((float)i - 15.5f) / 16f; float num3 = Mathf.Clamp01(1f - Mathf.Sqrt(num * num + num2 * num2) / 0.85f); _menuDotTex.SetPixel(j, i, new Color(val.r, val.g, val.b, num3)); } } _menuDotTex.Apply(); Sprite sprite = Sprite.Create(_menuDotTex, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 32f); _menuDotMat = new Material(Shader.Find("Sprites/Default")) { hideFlags = (HideFlags)61 }; _menuDotGo = new GameObject("BONESQUAD_MenuDot"); ((Object)_menuDotGo).hideFlags = (HideFlags)61; _menuDotSr = _menuDotGo.AddComponent(); _menuDotSr.sprite = sprite; ((Renderer)_menuDotSr).material = _menuDotMat; _menuDotSr.color = new Color(0.6f, 0.8f, 1f, 0.9f); ((Renderer)_menuDotSr).sortingOrder = 20; _menuDotGo.transform.localScale = Vector3.one * 0.012f; } private static void DestroyMenuRay() { if (Object.op_Implicit((Object)(object)_menuRayGo)) { Object.Destroy((Object)(object)_menuRayGo); } if (Object.op_Implicit((Object)(object)_menuRayMat)) { Object.Destroy((Object)(object)_menuRayMat); } if (Object.op_Implicit((Object)(object)_menuDotGo)) { Object.Destroy((Object)(object)_menuDotGo); } if (Object.op_Implicit((Object)(object)_menuDotMat)) { Object.Destroy((Object)(object)_menuDotMat); } if (Object.op_Implicit((Object)(object)_menuDotTex)) { Object.Destroy((Object)(object)_menuDotTex); } _menuRayGo = null; _menuRayLr = null; _menuRayMat = null; _menuDotGo = null; _menuDotSr = null; _menuDotMat = null; _menuDotTex = null; } private static void UpdateMenuHover() { //IL_0024: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00b4: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_root)) { return; } BaseController rightController = Player.RightController; if (!Object.op_Implicit((Object)(object)rightController)) { return; } Ray val = default(Ray); ((Ray)(ref val))..ctor(((Component)rightController).transform.position, ((Component)rightController).transform.forward); Plane val2 = default(Plane); ((Plane)(ref val2))..ctor(-_root.transform.forward, _root.transform.position); float num = default(float); int num2; Vector3 val3; if (((Plane)(ref val2)).Raycast(val, ref num) && num > 0f) { num2 = ((num < 15f) ? 1 : 0); if (num2 != 0) { val3 = ((Ray)(ref val)).GetPoint(num); goto IL_00b4; } } else { num2 = 0; } val3 = ((Component)rightController).transform.position + ((Component)rightController).transform.forward * 3f; goto IL_00b4; IL_00b4: Vector3 val4 = val3; if (Object.op_Implicit((Object)(object)_menuRayLr)) { _menuRayLr.SetPosition(0, ((Component)rightController).transform.position); _menuRayLr.SetPosition(1, val4); } if (Object.op_Implicit((Object)(object)_menuDotGo)) { _menuDotGo.transform.position = val4; Transform head = Player.Head; if (Object.op_Implicit((Object)(object)head)) { _menuDotGo.transform.rotation = Quaternion.LookRotation(val4 - head.position); } } if (num2 == 0) { if (_highlightedIdx >= 0) { _highlightedIdx = -1; RefreshHighlight(); } return; } Vector3 val5 = _root.transform.InverseTransformPoint(val4); if (Mathf.Sqrt(val5.x * val5.x + val5.y * val5.y) > 0.13f) { if (_highlightedIdx >= 0) { _highlightedIdx = -1; RefreshHighlight(); } return; } int num3 = LocalHitToIndex(new Vector2(val5.x, val5.y)); if (num3 != _highlightedIdx) { _highlightedIdx = num3; RefreshHighlight(); } } private static int LocalHitToIndex(Vector2 local) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (_state == MenuState.MainMenu) { if (!(local.x < 0f)) { return 1; } return 0; } int num = ((_state == MenuState.PingsMenu) ? PingOrder.Length : SpawnOrder.Length); float num2 = 360f / (float)num; float num3 = Mathf.Atan2(local.x, local.y) * 57.29578f + num2 * 0.5f; if (num3 < 0f) { num3 += 360f; } if (num3 >= 360f) { num3 -= 360f; } return Mathf.Clamp(Mathf.FloorToInt(num3 / num2), 0, num - 1); } private static void Confirm(int idx) { BonesquadMod.Log($"[RadialMenu] Confirm idx={idx} state={_state}"); switch (_state) { case MenuState.MainMenu: Open((idx == 0) ? MenuState.SpawnPointMenu : MenuState.PingsMenu); break; case MenuState.PingsMenu: if (idx < PingOrder.Length) { OnPingChosen(PingOrder[idx]); } Close(); break; case MenuState.SpawnPointMenu: if (idx < SpawnOrder.Length && (_spawnDisabled == null || idx >= _spawnDisabled.Length || !_spawnDisabled[idx])) { OnSpawnChosen(SpawnOrder[idx]); Close(); } break; } } private static void OnPingChosen(string file) { SelectPing(file); BonesquadMod.Log("[RadialMenu] Ping selected: " + Path.GetFileNameWithoutExtension(file)); } private static void OnSpawnChosen(string file) { SelectedSpawn.Value = file; MelonPreferences.GetCategory("BONESQUAD").SaveToFile(true); BonesquadMod.Log("[RadialMenu] Spawn selected: " + Path.GetFileNameWithoutExtension(file)); } private static void Open(MenuState state) { BonesquadMod.Log($"[RadialMenu] Open {state}"); _state = state; _highlightedIdx = -1; BaseController rightController = Player.RightController; _rightTrigPrev = (Object.op_Implicit((Object)(object)rightController) ? rightController.GetIndexCurlAxis() : 0f); DestroyMenuRay(); Build(); CreateMenuRay(); } private static void Close() { BonesquadMod.Log("[RadialMenu] Close"); _state = MenuState.Closed; Teardown(); DestroyMenuRay(); } private static void Build() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00a7: 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_00bb: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) Teardown(); Hand leftHand = Player.LeftHand; BonesquadMod.Log($"[RadialMenu] Build state={_state} hand={(Object.op_Implicit((Object)(object)leftHand) ? "OK" : "NULL")}"); if (Object.op_Implicit((Object)(object)leftHand)) { _root = new GameObject("BONESQUAD_RadialMenu"); _root.transform.SetParent(((Component)leftHand).transform, false); _root.transform.localPosition = new Vector3(0f, 0.18f, 0f); GameObject val = new GameObject("BG"); val.transform.SetParent(_root.transform, false); val.transform.localPosition = Vector3.zero; val.transform.localScale = new Vector3(0.26f, 0.26f, 1f); SpriteRenderer obj = val.AddComponent(); obj.sprite = _circleSprite; obj.color = new Color(0.04f, 0.04f, 0.04f, 0.88f); ((Renderer)obj).sortingOrder = 0; if (_logoData != null) { Texture2D val2 = new Texture2D(2, 2, (TextureFormat)4, false); ((Object)val2).hideFlags = (HideFlags)61; ImageConversion.LoadImage(val2, Il2CppStructArray.op_Implicit(_logoData)); ApplyCircularMask(val2); _buildTextures.Add(val2); Sprite val3 = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), (float)((Texture)val2).width); ((Object)val3).hideFlags = (HideFlags)61; GameObject val4 = new GameObject("Logo"); val4.transform.SetParent(_root.transform, false); val4.transform.localPosition = new Vector3(0f, 0f, -0.001f); val4.transform.localScale = new Vector3(0.26f, 0.26f, 1f); SpriteRenderer obj2 = val4.AddComponent(); obj2.sprite = val3; obj2.color = new Color(0.3f, 0.3f, 0.3f, 0.85f); ((Renderer)obj2).sortingOrder = 1; } _itemBgs.Clear(); _itemLabels.Clear(); if (_state == MenuState.SpawnPointMenu) { ComputeSpawnAvailability(); BuildSpawnCenter(); } int num; switch (_state) { case MenuState.MainMenu: BuildMainMenu(); num = 0; break; case MenuState.PingsMenu: BuildRadial(PingOrder, 6); num = 6; break; default: BuildRadial(SpawnOrder, 3); num = 3; break; } BonesquadMod.Log($"[RadialMenu] Build done: {_itemBgs.Count} items, {num} sectors"); if (num > 0) { AddDividers(num); } CreateSectorHighlights((_state == MenuState.MainMenu) ? 2 : num); if (_state == MenuState.SpawnPointMenu) { CreateTooltip(); } } } private static void ComputeSpawnAvailability() { _spawnDisabled = new bool[SpawnOrder.Length]; _spawnDisabledMsg = new string[SpawnOrder.Length]; for (int i = 0; i < SpawnOrder.Length; i++) { switch (SpawnOrder[i]) { case "mainbase.png": if (!MainBaseModule.HasBase) { _spawnDisabled[i] = true; _spawnDisabledMsg[i] = "No main base assigned to your group"; } break; case "RadialRallyPointIcon.png": if (!Object.op_Implicit((Object)(object)RallyPointTracker.GetLatestRally())) { _spawnDisabled[i] = true; _spawnDisabledMsg[i] = "There is no rally point on the map"; } break; case "deployable_hab.png": if (!Object.op_Implicit((Object)(object)RallyPointTracker.GetLatestHab())) { _spawnDisabled[i] = true; _spawnDisabledMsg[i] = "There is no HAB on the map"; } break; } } } private static void CreateTooltip() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_004e: 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) _tooltipGo = new GameObject("BONESQUAD_Tooltip"); ((Object)_tooltipGo).hideFlags = (HideFlags)61; _tooltipGo.transform.SetParent(_root.transform, false); _tooltipGo.transform.localPosition = new Vector3(0f, -0.1f, -0.005f); _tooltipTm = _tooltipGo.AddComponent(); _tooltipTm.text = ""; _tooltipTm.fontSize = 28; _tooltipTm.characterSize = 0.0025f; _tooltipTm.color = new Color(1f, 0.55f, 0.15f, 1f); _tooltipTm.anchor = (TextAnchor)1; _tooltipTm.alignment = (TextAlignment)1; ((Renderer)_tooltipGo.GetComponent()).sortingOrder = 10; _tooltipGo.SetActive(false); } private static void BuildSpawnCenter() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0054: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_0197: 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("SpawnCenter"); val.transform.SetParent(_root.transform, false); val.transform.localPosition = new Vector3(0f, 0f, -0.005f); val.transform.localScale = new Vector3(0.065f, 0.065f, 1f); SpriteRenderer obj = val.AddComponent(); obj.sprite = _circleSprite; obj.color = new Color(0.04f, 0.04f, 0.04f, 0.97f); ((Renderer)obj).sortingOrder = 6; AddLabel(_root.transform, "Selected:", new Vector3(0f, 0.012f, -0.006f), 40, 0.0012f); string value = SelectedSpawn.Value; if (_assets.TryGetValue(value, out var value2) && value2.Data != null) { Texture2D val2 = new Texture2D(2, 2); ((Object)val2).hideFlags = (HideFlags)61; ImageConversion.LoadImage(val2, Il2CppStructArray.op_Implicit(value2.Data)); _buildTextures.Add(val2); Sprite val3 = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f); ((Object)val3).hideFlags = (HideFlags)61; GameObject val4 = new GameObject("SelectedIcon"); val4.transform.SetParent(_root.transform, false); val4.transform.localPosition = new Vector3(0f, -0.006f, -0.006f); val4.transform.localScale = Vector3.one * 0.022f; SpriteRenderer obj2 = val4.AddComponent(); obj2.sprite = val3; obj2.color = Color.white; ((Renderer)obj2).sortingOrder = 7; } } private static void BuildMainMenu() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) AddTextItem(_root.transform, "Spawn Point", new Vector3(-0.065f, 0f, 0f), 0); AddTextItem(_root.transform, "Pings", new Vector3(0.065f, 0f, 0f), 1); AddVerticalDivider(); } private static void BuildRadial(string[] files, int count) { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) BonesquadMod.Log($"[RadialMenu] BuildRadial count={count} assetsLoaded={_assets.Count}"); float num = 0.082f; float num2 = 360f / (float)count; Vector3 localPos = default(Vector3); for (int i = 0; i < count; i++) { float num3 = (float)i * num2; float num4 = (90f - num3) * ((float)Math.PI / 180f); ((Vector3)(ref localPos))..ctor(Mathf.Cos(num4) * num, Mathf.Sin(num4) * num, 0f); string text = ((i < files.Length) ? files[i] : ""); Sprite val = null; float num5 = 0f; if (_assets.TryGetValue(text, out var value) && value.Data != null) { Texture2D val2 = new Texture2D(2, 2); ((Object)val2).hideFlags = (HideFlags)61; ImageConversion.LoadImage(val2, Il2CppStructArray.op_Implicit(value.Data)); _buildTextures.Add(val2); val = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f); ((Object)val).hideFlags = (HideFlags)61; num5 = value.Scale; BonesquadMod.Log($"[RadialMenu] item[{i}] {text} sprite fresh scale={num5:F4}"); } else { BonesquadMod.Log($"[RadialMenu] item[{i}] {text} NO ASSET"); } bool disabled = _state == MenuState.SpawnPointMenu && _spawnDisabled != null && i < _spawnDisabled.Length && _spawnDisabled[i]; string value2; string sublabel = ((_state == MenuState.SpawnPointMenu && SpawnLabels.TryGetValue(text, out value2)) ? value2 : ""); AddIconItem(_root.transform, val, num5, localPos, i, text, sublabel, disabled); } } private static void AddTextItem(Transform parent, string label, Vector3 localPos, int idx) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0062: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"Item_{idx}"); val.transform.SetParent(parent, false); val.transform.localPosition = localPos; _itemBgs.Add(null); Transform item = AddLabel(val.transform, label, new Vector3(0f, 0f, -0.004f), 60, 0.002304f); _itemLabels.Add(item); } private static void AddIconItem(Transform parent, Sprite icon, float scale, Vector3 localPos, int idx, string debugFile, string sublabel = "", bool disabled = false) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0097: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0175: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"Item_{idx}"); val.transform.SetParent(parent, false); val.transform.localPosition = localPos; _itemBgs.Add(null); _itemLabels.Add(null); if (Object.op_Implicit((Object)(object)icon)) { GameObject val2 = new GameObject("Icon"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = new Vector3(0f, 0f, -0.004f); SpriteRenderer obj = val2.AddComponent(); obj.sprite = icon; obj.color = (Color)(disabled ? new Color(0.45f, 0.45f, 0.45f, 0.5f) : Color.white); ((Renderer)obj).sortingOrder = 3; if (scale > 0f) { val2.transform.localScale = Vector3.one * scale; } BonesquadMod.Log($"[RadialMenu] item[{idx}] SpriteRenderer created scale={scale:F4}"); } else { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(debugFile); AddLabel(val.transform, (fileNameWithoutExtension.Length > 0) ? fileNameWithoutExtension : idx.ToString(), new Vector3(0f, 0f, -0.004f), 30, 0.002f); BonesquadMod.Log($"[RadialMenu] item[{idx}] icon=NULL, showing fallback text '{fileNameWithoutExtension}'"); } if (string.IsNullOrEmpty(sublabel)) { return; } Transform val3 = AddLabel(val.transform, sublabel, new Vector3(0f, -0.028f, -0.004f), 30, 0.0032f); if (disabled) { TextMesh component = ((Component)val3).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.color = new Color(0.5f, 0.5f, 0.5f, 1f); } } } private static void CreateSectorHighlights(int count) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) _sectorHighlightGos.Clear(); _sectorMeshes.Clear(); if (count > 0 && Object.op_Implicit((Object)(object)_root)) { float num = 360f / (float)count; float radius = 0.13f; for (int i = 0; i < count; i++) { float num2 = ((count != 2) ? ((float)i * num) : ((i == 0) ? 270f : 90f)); float cwStart = num2 - num * 0.5f; float cwEnd = num2 + num * 0.5f; GameObject val = new GameObject($"Sector_{i}"); val.transform.SetParent(_root.transform, false); val.transform.localPosition = new Vector3(0f, 0f, -0.001f); ((Object)val).hideFlags = (HideFlags)61; MeshFilter obj = val.AddComponent(); MeshRenderer obj2 = val.AddComponent(); ((Renderer)obj2).material = _sectorMat; ((Renderer)obj2).sortingOrder = 1; Mesh val2 = CreateSectorMesh(cwStart, cwEnd, radius, 24); ((Object)val2).hideFlags = (HideFlags)61; obj.mesh = val2; _sectorMeshes.Add(val2); val.SetActive(false); _sectorHighlightGos.Add(val); } } } private static Mesh CreateSectorMesh(float cwStart, float cwEnd, float radius, int subs) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown Vector3[] array = (Vector3[])(object)new Vector3[subs + 2]; int[] array2 = new int[subs * 3]; array[0] = Vector3.zero; for (int i = 0; i <= subs; i++) { float num = (float)i / (float)subs; float num2 = Mathf.Lerp(cwStart, cwEnd, num); float num3 = (90f - num2) * ((float)Math.PI / 180f); array[i + 1] = new Vector3(Mathf.Cos(num3) * radius, Mathf.Sin(num3) * radius, 0f); } for (int j = 0; j < subs; j++) { int num4 = j * 3; array2[num4] = 0; array2[num4 + 1] = j + 1; array2[num4 + 2] = j + 2; } return new Mesh { vertices = Il2CppStructArray.op_Implicit(array), triangles = Il2CppStructArray.op_Implicit(array2) }; } private static SpriteRenderer AddColorPanel(Transform parent, string name, Vector3 localPos, float w, float h, Color color, int sortOrder) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = localPos; val.transform.localScale = new Vector3(w, h, 1f); SpriteRenderer obj = val.AddComponent(); obj.sprite = _whitePixel; obj.color = color; ((Renderer)obj).sortingOrder = sortOrder; return obj; } private static Transform AddLabel(Transform parent, string text, Vector3 localPos, int fontSize, float characterSize) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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) GameObject val = new GameObject("Label"); val.transform.SetParent(parent, false); val.transform.localPosition = localPos; TextMesh obj = val.AddComponent(); obj.text = text; obj.fontSize = fontSize; obj.characterSize = characterSize; obj.color = Color.white; obj.anchor = (TextAnchor)4; obj.alignment = (TextAlignment)1; obj.fontStyle = (FontStyle)1; ((Renderer)val.GetComponent()).sortingOrder = 10; return val.transform; } private static Sprite CreateCircleSprite(int res) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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) Texture2D val = new Texture2D(res, res, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)61; float num = (float)res * 0.5f; float num2 = 2f; for (int i = 0; i < res; i++) { for (int j = 0; j < res; j++) { float num3 = (float)j - num + 0.5f; float num4 = (float)i - num + 0.5f; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); float num6 = Mathf.Clamp01((num - num5 + num2) / (2f * num2)); val.SetPixel(j, i, new Color(1f, 1f, 1f, num6)); } } val.Apply(); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)res, (float)res), new Vector2(0.5f, 0.5f), (float)res); ((Object)obj).hideFlags = (HideFlags)61; return obj; } private static void ApplyCircularMask(Texture2D tex) { //IL_0087: 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_0090: 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) int width = ((Texture)tex).width; int height = ((Texture)tex).height; Il2CppStructArray pixels = tex.GetPixels(); float num = (float)width * 0.5f; float num2 = (float)height * 0.5f; float num3 = Mathf.Min(num, num2); float num4 = num3 * 0.04f; for (int i = 0; i < ((Il2CppArrayBase)(object)pixels).Length; i++) { int num5 = i % width; int num6 = i / width; float num7 = (float)num5 - num + 0.5f; float num8 = (float)num6 - num2 + 0.5f; float num9 = Mathf.Sqrt(num7 * num7 + num8 * num8); float num10 = Mathf.Clamp01((num3 - num9 + num4) / (2f * num4)); Color val = ((Il2CppArrayBase)(object)pixels)[i]; val.a *= num10; ((Il2CppArrayBase)(object)pixels)[i] = val; } tex.SetPixels(pixels); tex.Apply(); } private static void AddVerticalDivider() { //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) float num = 0.09f; GameObject val = new GameObject("Div_V"); val.transform.SetParent(_root.transform, false); val.transform.localPosition = new Vector3(0f, 0f, -0.002f); val.transform.localRotation = Quaternion.identity; val.transform.localScale = new Vector3(0.001f, num, 1f); SpriteRenderer obj = val.AddComponent(); obj.sprite = _whitePixel; obj.color = new Color(1f, 1f, 1f, 0.55f); ((Renderer)obj).sortingOrder = 2; } private static void AddDividers(int n) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_003b: 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) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) float num = 0.118f; float num2 = 360f / (float)n; for (int i = 0; i < n; i++) { float num3 = ((float)i + 0.5f) * num2; Quaternion val = Quaternion.Euler(0f, 0f, 0f - num3); Vector3 val2 = val * Vector3.up; GameObject val3 = new GameObject($"Div_{i}"); val3.transform.SetParent(_root.transform, false); val3.transform.localPosition = new Vector3(val2.x * num * 0.5f, val2.y * num * 0.5f, -0.002f); val3.transform.localRotation = val; val3.transform.localScale = new Vector3(0.001f, num, 1f); SpriteRenderer obj = val3.AddComponent(); obj.sprite = _whitePixel; obj.color = new Color(1f, 1f, 1f, 0.55f); ((Renderer)obj).sortingOrder = 2; } } private static void RefreshHighlight() { //IL_004a: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _itemBgs.Count; i++) { bool flag = i == _highlightedIdx; if ((Object)(object)_itemBgs[i] != (Object)null && Object.op_Implicit((Object)(object)_itemBgs[i])) { _itemBgs[i].color = (flag ? HighlightBg : NormalBg); } if (i < _itemLabels.Count && (Object)(object)_itemLabels[i] != (Object)null) { _itemLabels[i].localScale = (flag ? (Vector3.one * 1.25f) : Vector3.one); } } for (int j = 0; j < _sectorHighlightGos.Count; j++) { GameObject val = _sectorHighlightGos[j]; if (Object.op_Implicit((Object)(object)val)) { val.SetActive(j == _highlightedIdx); } } if (Object.op_Implicit((Object)(object)_tooltipGo) && (Object)(object)_tooltipTm != (Object)null) { bool flag2 = _state == MenuState.SpawnPointMenu && _highlightedIdx >= 0 && _spawnDisabled != null && _highlightedIdx < _spawnDisabled.Length && _spawnDisabled[_highlightedIdx]; if (flag2) { _tooltipTm.text = _spawnDisabledMsg[_highlightedIdx]; } _tooltipGo.SetActive(flag2); } } private static void Teardown() { if (Object.op_Implicit((Object)(object)_root)) { Object.Destroy((Object)(object)_root); } _root = null; _itemBgs.Clear(); _itemLabels.Clear(); _buildTextures.Clear(); foreach (Mesh sectorMesh in _sectorMeshes) { if (Object.op_Implicit((Object)(object)sectorMesh)) { Object.Destroy((Object)(object)sectorMesh); } } _sectorMeshes.Clear(); _sectorHighlightGos.Clear(); _highlightedIdx = -1; _tooltipGo = null; _tooltipTm = null; _spawnDisabled = null; _spawnDisabledMsg = null; } } } namespace BONESQUAD.Modules.HUD { internal static class HudLayer { internal static Shader GetHudShader(bool alwaysOnTop) { if (!alwaysOnTop) { return Shader.Find("Sprites/Default"); } return Shader.Find("GUI/Text Shader"); } internal static void ApplyTextZTest(Material mat, bool alwaysOnTop) { if (!alwaysOnTop) { mat.SetInt("unity_GUIZTestMode", 4); } } internal static void ApplyHp(GameObject go) { } internal static void ApplyCompass(GameObject go) { } internal static void ApplyAlwaysOnTop(Material mat) { } internal static void SetShowHpOnPc(bool show) { } internal static void SetShowCompassOnPc(bool show) { } internal static void Update() { } } } namespace BONESQUAD.Modules.FusionCompat { public class ClearDebrisHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { if (NetworkInfo.IsHost) { return; } try { foreach (FirearmCartridge item in Object.FindObjectsOfType()) { if (!((Object)(object)item == (Object)null)) { try { item.Despawn(); } catch { } } } } catch (Exception ex) { BonesquadMod.LogError("ClearDebris client failed: " + ex.Message); } } } public class ClearDecalsHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { try { int num = 0; foreach (DecalProjector item in Object.FindObjectsOfType()) { if (!((Object)(object)item == (Object)null)) { Object.Destroy((Object)(object)((Component)item).gameObject); num++; } } BonesquadMod.Log($"ClearDecals: destroyed {num} decal(s)."); } catch (Exception ex) { BonesquadMod.LogError("ClearDecals client failed: " + ex.Message); } } } internal static class FusionCompat { internal static MelonPreferences_Entry RequireBonesquad; internal static bool IsAvailable => AppDomain.CurrentDomain.GetAssemblies().Any((Assembly a) => a.GetName().Name == "LabFusion"); internal static void InitPrefs(MelonPreferences_Category prefs) { RequireBonesquad = prefs.CreateEntry("FusionCompat_RequireBonesquad", false, (string)null, "--- Multiplayer ---", false, false, (ValueValidator)null, (string)null); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void Init() { FusionCompatImpl.Register(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void BroadcastPing(string fileName, Vector3 pos) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (IsAvailable) { FusionCompatImpl.BroadcastPing(fileName, pos); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static int GetKnockoutLength() { if (!IsAvailable) { return -1; } return FusionCompatImpl.GetKnockoutLength(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static bool IsHost() { if (!IsAvailable) { return false; } return FusionCompatImpl.IsHost; } [MethodImpl(MethodImplOptions.NoInlining)] internal static void SendRallyEvent(byte markerType, byte eventType, float x, float z) { if (IsAvailable) { FusionCompatImpl.SendRallyEvent(markerType, eventType, x, z); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static bool TryIsPooleeOwner(Poolee poolee, out bool isOwner) { isOwner = false; if (!IsAvailable) { return false; } return FusionCompatImpl.TryIsPooleeOwner(poolee, out isOwner); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void SendKnockoutState(bool isKnockedOut) { if (IsAvailable) { FusionCompatImpl.SendKnockoutState(isKnockedOut); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static bool IsLocalPlayerKnockedOut() { if (!IsAvailable) { return false; } return FusionCompatImpl.IsLocalPlayerKnockedOut(); } } internal static class FusionCompatImpl { private static readonly HashSet _confirmed = new HashSet(); private const string HeadlessAssembly = "HeadlessServer"; private const string ClearDebrisTypeName = "HeadlessServer.ClearDebrisClientMessage"; private const string ClearDecalsTypeName = "HeadlessServer.ClearDecalsClientMessage"; private const string BroadcastAudioTypeName = "HeadlessServer.BroadcastAudioClientMessage"; private const string ServerConfigTypeName = "HeadlessServer.ServerConfigClientMessage"; private const string MainBaseTypeName = "HeadlessServer.MainBaseClientMessage"; private const string DespawnRallyTypeName = "HeadlessServer.DespawnRallyClientMessage"; private const string RallyStatusTypeName = "HeadlessServer.RallyStatusClientMessage"; private const string RallyReportTypeName = "BONESQUAD.Modules.Spawning.RallyReportMessage"; private const string CaptureEventTypeName = "HeadlessServer.CaptureEventClientMessage"; private const string PlayerGroupsTypeName = "HeadlessServer.PlayerGroupsClientMessage"; private const string RallyOwnerTypeName = "HeadlessServer.RallyOwnerClientMessage"; internal static bool IsHost => NetworkInfo.IsHost; internal static void Register() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown ModuleMessageManager.RegisterHandler(); ModuleMessageManager.RegisterHandler(); RegisterClearDebrisHandler(); RegisterClearDecalsHandler(); RegisterBroadcastAudioHandler(); RegisterServerConfigHandler(); RegisterMainBaseHandler(); RegisterDespawnRallyHandler(); RegisterRallyStatusHandler(); RegisterCaptureEventHandler(); RegisterPlayerGroupsHandler(); RegisterRallyOwnerHandler(); RegisterRallyReportMessage(); RegisterKnockoutStateMessage(); VoiceModule.Init(); MultiplayerHooking.OnTargetLevelLoaded += new UpdateEvent(OnLevelLoaded); MultiplayerHooking.OnPlayerJoined += new PlayerUpdate(OnPlayerJoined); MultiplayerHooking.OnPlayerLeft += new PlayerUpdate(OnPlayerLeft); MultiplayerHooking.OnDisconnected += new ServerEvent(OnDisconnected); BonesquadMod.Log("Fusion compat registered."); } private static void RegisterWithTag(string typeName, string logLabel) where T : ModuleMessageHandler { try { ModuleMessageManager.RegisterHandler(); } catch { } try { long num = BitMath.MakeLong(StringExtensions.GetDeterministicHashCode("HeadlessServer"), StringExtensions.GetDeterministicHashCode(typeName)); ModuleMessageHandler handlerByType = ModuleMessageManager.GetHandlerByType(typeof(T)); if (handlerByType != null) { ModuleMessageManager.TagToHandlerLookup[num] = handlerByType; BonesquadMod.Log($"[FusionCompat] {logLabel} tag mapped ({num})."); } else { BonesquadMod.LogWarning("[FusionCompat] " + logLabel + ": handler not found after registration."); } } catch (Exception ex) { BonesquadMod.LogError("[FusionCompat] " + logLabel + " tag mapping failed: " + ex.Message); } } private static void RegisterClearDebrisHandler() { RegisterWithTag("HeadlessServer.ClearDebrisClientMessage", "ClearDebris"); } private static void RegisterClearDecalsHandler() { RegisterWithTag("HeadlessServer.ClearDecalsClientMessage", "ClearDecals"); } private static void RegisterBroadcastAudioHandler() { RegisterWithTag("HeadlessServer.BroadcastAudioClientMessage", "BroadcastAudio"); } private static void RegisterServerConfigHandler() { RegisterWithTag("HeadlessServer.ServerConfigClientMessage", "ServerConfig"); } private static void RegisterMainBaseHandler() { RegisterWithTag("HeadlessServer.MainBaseClientMessage", "MainBase"); } private static void RegisterDespawnRallyHandler() { RegisterWithTag("HeadlessServer.DespawnRallyClientMessage", "DespawnRally"); } private static void RegisterRallyStatusHandler() { RegisterWithTag("HeadlessServer.RallyStatusClientMessage", "RallyStatus"); } private static void RegisterCaptureEventHandler() { RegisterWithTag("HeadlessServer.CaptureEventClientMessage", "CaptureEvent"); } private static void RegisterPlayerGroupsHandler() { RegisterWithTag("HeadlessServer.PlayerGroupsClientMessage", "PlayerGroups"); } private static void RegisterRallyOwnerHandler() { RegisterWithTag("HeadlessServer.RallyOwnerClientMessage", "RallyOwner"); } private static void OnLevelLoaded() { VoiceModule.Init(); MainBaseModule.ClearBase(); CaptureEventHandler.OnLevelUnloaded(); RegisterClearDebrisHandler(); RegisterClearDecalsHandler(); RegisterBroadcastAudioHandler(); RegisterServerConfigHandler(); RegisterMainBaseHandler(); RegisterDespawnRallyHandler(); RegisterRallyStatusHandler(); RegisterCaptureEventHandler(); RegisterPlayerGroupsHandler(); RegisterRallyOwnerHandler(); PingMarkerModule.ClearAllPlayerGroups(); if (!NetworkInfo.IsHost) { MelonCoroutines.Start(SendVersionPingWhenReady()); } } private static IEnumerator SendVersionPingWhenReady() { for (int i = 0; i < 20; i++) { if (PlayerIDManager.LocalSmallID != 0) { break; } yield return (object)new WaitForSecondsRealtime(0.5f); } byte localSmallID = PlayerIDManager.LocalSmallID; BonesquadMod.Log($"[MainBase] Sending VersionPing (localSmallId={localSmallID})"); MessageRelay.RelayModule(VersionPingData.Create(localSmallID, "11.1.0"), CommonMessageRoutes.ReliableToServer); } private static void OnPlayerJoined(PlayerID playerId) { if (NetworkInfo.IsHost) { byte smallID = playerId.SmallID; if (!_confirmed.Contains(smallID)) { MelonCoroutines.Start(EnforceCheck(smallID)); } } } private static IEnumerator EnforceCheck(byte smallId) { yield return (object)new WaitForSecondsRealtime(60f); NetworkPlayer val = default(NetworkPlayer); if (!_confirmed.Contains(smallId) && NetworkPlayerManager.TryGetPlayer(smallId, ref val)) { string text = default(string); if (!MetadataHelper.TryGetDisplayName(val.PlayerID, ref text)) { text = $"Player {smallId}"; } if (FusionCompat.RequireBonesquad.Value) { ConnectionSender.SendDisconnect(val.PlayerID.PlatformID, "You have not installed BONESQUAD Code Mod. Go to bonesquad.club/discord"); Notifier.Send(new Notification { Title = new NotificationText("[BONESQUAD]", Color.white, false), Message = new NotificationText(text + " was kicked — BONESQUAD is not installed", Color.red, false), ShowTitleOnPopup = true, Type = (NotificationType)1, PopupLength = 6f }); } else { Notifier.Send(new Notification { Title = new NotificationText("[BONESQUAD]", Color.white, false), Message = new NotificationText(text + " — I have no BONESQUAD mod", Color.red, false), ShowTitleOnPopup = true, Type = (NotificationType)1, PopupLength = 6f }); } } } private static void OnPlayerLeft(PlayerID playerId) { _confirmed.Remove(playerId.SmallID); PingMarkerModule.ClearPlayerGroups(playerId.SmallID); } private static void OnDisconnected() { _confirmed.Clear(); RegenerationModule.ClearServerLock(); SlowWalkModule.ClearServerLock(); SoundFalloffModule.ClearServerLock(); PingMarkerModule.ClearServerLock(); PingMarkerModule.ClearAllPlayerGroups(); } internal static void ConfirmPlayer(byte smallId) { _confirmed.Add(smallId); } internal static void BroadcastPing(string fileName, Vector3 pos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) MessageRelay.RelayModule(PingMarkerData.Create(PlayerIDManager.LocalSmallID, fileName, pos), CommonMessageRoutes.ReliableToOtherClients); } internal static void SendRallyEvent(byte markerType, byte eventType, float x, float z) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) MessageRelay.RelayModule(new RallyReportData { MarkerType = markerType, EventType = eventType, X = x, Z = z }, CommonMessageRoutes.ReliableToServer); } internal static bool TryIsPooleeOwner(Poolee poolee, out bool isOwner) { isOwner = false; if (!Object.op_Implicit((Object)(object)poolee)) { return false; } NetworkEntity val = default(NetworkEntity); if (!PooleeExtender.Cache.TryGet(poolee, ref val)) { return false; } isOwner = val.IsOwner; return true; } internal static void SendKnockoutState(bool isKnockedOut) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (NetworkInfo.HasServer) { MessageRelay.RelayModule(new KnockoutStateData { IsKnockedOut = isKnockedOut }, CommonMessageRoutes.ReliableToServer); } } private static void RegisterRallyReportMessage() { try { ModuleMessageManager.RegisterHandler(); BonesquadMod.Log("RallyReportMessage registered."); } catch (Exception ex) { BonesquadMod.LogError("RallyReportMessage registration failed: " + ex.Message); } } private static void RegisterKnockoutStateMessage() { try { ModuleMessageManager.RegisterHandler(); BonesquadMod.Log("KnockoutStateMessage registered."); } catch (Exception ex) { BonesquadMod.LogError("KnockoutStateMessage registration failed: " + ex.Message); } } internal static int GetKnockoutLength() { LobbyInfo lobbyInfo = LobbyInfoManager.LobbyInfo; if (!lobbyInfo.Knockout) { return -1; } return lobbyInfo.KnockoutLength; } internal static bool IsLocalPlayerKnockedOut() { return LocalRagdoll.KnockedOut; } } public class PlayerGroupsData : INetSerializable { public byte SmallId; public string GroupIdsJoined = ""; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref SmallId); serializer.SerializeValue(ref GroupIdsJoined); } } [SkipHandleWhileLoading] public class PlayerGroupsHandler : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { try { PlayerGroupsData playerGroupsData = ((ReceivedMessage)(ref received)).ReadData(); PingMarkerModule.SetPlayerGroups(playerGroupsData.SmallId, playerGroupsData.GroupIdsJoined); BonesquadMod.Log($"[PlayerGroups] Player {playerGroupsData.SmallId} groups: '{playerGroupsData.GroupIdsJoined}'"); } catch (Exception ex) { BonesquadMod.LogWarning("[PlayerGroups] Failed: " + ex.Message); } } } public class VersionPingData : INetSerializable { public byte SmallId; public string Version; public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref SmallId); serializer.SerializeValue(ref Version); } public static VersionPingData Create(byte smallId, string version) { return new VersionPingData { SmallId = smallId, Version = version }; } } [SkipHandleWhileLoading] public class VersionPingMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ff: Expected O, but got Unknown VersionPingData versionPingData = ((ReceivedMessage)(ref received)).ReadData(); NetworkPlayer val = default(NetworkPlayer); if (versionPingData.SmallId == ((ReceivedMessage)(ref received)).Sender.Value && Version.TryParse(versionPingData.Version, out Version result) && Version.TryParse("11.1.0", out Version result2) && NetworkPlayerManager.TryGetPlayer(versionPingData.SmallId, ref val)) { FusionCompatImpl.ConfirmPlayer(versionPingData.SmallId); string text = default(string); if (!MetadataHelper.TryGetDisplayName(val.PlayerID, ref text)) { text = $"Player {versionPingData.SmallId}"; } if (result < result2) { Notifier.Send(new Notification { Title = new NotificationText("[BONESQUAD]", Color.white, false), Message = new NotificationText(text + " — old version of BONESQUAD (v" + versionPingData.Version + ")", Color.yellow, false), ShowTitleOnPopup = true, Type = (NotificationType)1, PopupLength = 6f }); } else { Notifier.Send(new Notification { Title = new NotificationText("[BONESQUAD]", Color.white, false), Message = new NotificationText(text + " — BONESQUAD is up to date", Color.green, false), ShowTitleOnPopup = true, Type = (NotificationType)0, PopupLength = 5f }); } } } } } namespace BONESQUAD.Modules.Compass { internal static class BitmapFont { internal const int CharW = 5; internal const int CharH = 7; internal const int GapX = 1; private static readonly Dictionary Glyphs = new Dictionary { ['0'] = new byte[7] { 14, 17, 17, 17, 17, 17, 14 }, ['1'] = new byte[7] { 4, 12, 4, 4, 4, 4, 14 }, ['2'] = new byte[7] { 14, 17, 1, 2, 4, 8, 31 }, ['3'] = new byte[7] { 14, 17, 1, 6, 1, 17, 14 }, ['4'] = new byte[7] { 17, 17, 17, 31, 1, 1, 1 }, ['5'] = new byte[7] { 31, 16, 30, 1, 1, 17, 14 }, ['6'] = new byte[7] { 14, 16, 16, 30, 17, 17, 14 }, ['7'] = new byte[7] { 31, 1, 2, 4, 8, 8, 8 }, ['8'] = new byte[7] { 14, 17, 17, 14, 17, 17, 14 }, ['9'] = new byte[7] { 14, 17, 17, 15, 1, 2, 12 }, ['N'] = new byte[7] { 17, 25, 21, 19, 17, 17, 17 }, ['E'] = new byte[7] { 31, 16, 16, 30, 16, 16, 31 }, ['S'] = new byte[7] { 15, 16, 16, 14, 1, 1, 30 }, ['W'] = new byte[7] { 17, 17, 17, 21, 21, 27, 17 }, ['С'] = new byte[7] { 14, 17, 16, 16, 16, 17, 14 }, ['В'] = new byte[7] { 30, 17, 17, 30, 17, 17, 30 }, ['Ю'] = new byte[7] { 23, 21, 21, 29, 21, 21, 23 }, ['З'] = new byte[7] { 14, 17, 1, 6, 1, 17, 14 }, ['/'] = new byte[7] { 1, 2, 2, 4, 8, 8, 16 } }; internal static Texture2D Render(string text) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_00a5: 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) int length = text.Length; if (length == 0) { return null; } int num = length * 5 + (length - 1); Texture2D val = new Texture2D(num, 7, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Object)val).hideFlags = (HideFlags)61; Color32[] array = (Color32[])(object)new Color32[num * 7]; for (int i = 0; i < length; i++) { if (!Glyphs.TryGetValue(text[i], out var value)) { continue; } int num2 = i * 6; for (int j = 0; j < 7; j++) { int num3 = 6 - j; byte b = value[j]; for (int k = 0; k < 5; k++) { if ((b & (1 << 4 - k)) != 0) { array[num3 * num + num2 + k] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); } } } } val.SetPixels32(Il2CppStructArray.op_Implicit(array)); val.Apply(false, true); return val; } } internal static class CompassModule { private class PingIndicator { internal GameObject Root; internal SpriteRenderer IconSr; internal Material IconMat; internal TextMesh BehindLabelTm; internal TextMesh NameTm; internal TextMesh DistTm; internal Texture2D LastIconTex; internal Sprite LastSprite; internal int LastDistM = int.MinValue; } private readonly struct PingEntry { internal readonly PingMarkerModule.CompassPingEntry E; internal readonly float Offset; internal readonly float Dist; internal PingEntry(PingMarkerModule.CompassPingEntry e, float offset, float dist) { E = e; Offset = offset; Dist = dist; } } private class PointIndicator { internal GameObject Root; internal TextMesh LetterTm; internal TextMesh DistTm; internal TextMesh BehindLabelTm; internal int LastDistM = int.MinValue; } private readonly struct PointEntry { internal readonly CaptureEventHandler.CompassCaptureEntry E; internal readonly float Offset; internal readonly float Dist; internal PointEntry(CaptureEventHandler.CompassCaptureEntry e, float offset, float dist) { E = e; Offset = offset; Dist = dist; } } internal static MelonPreferences_Entry Enabled; internal static MelonPreferences_Entry AlwaysOnTop; internal static MelonPreferences_Entry SmoothFactor; internal static MelonPreferences_Entry PosY; internal static MelonPreferences_Entry Scale; internal static MelonPreferences_Entry UseRussian; internal static MelonPreferences_Entry BgAlpha; internal static MelonPreferences_Entry BgHeightMult; internal static MelonPreferences_Entry FadeEdge; internal static MelonPreferences_Entry FadeSpread; internal static MelonPreferences_Entry FadeEdgeH; internal static MelonPreferences_Entry FontScaleCard; internal static MelonPreferences_Entry FontScaleLarge; internal static MelonPreferences_Entry FontScaleSmall; internal static MelonPreferences_Entry Depth; internal static MelonPreferences_Entry ShowArrow; internal static MelonPreferences_Entry ArrowSize; internal static MelonPreferences_Entry ArrowHeight; internal static MelonPreferences_Entry SmoothFollow; internal static MelonPreferences_Entry FollowSpeedX; internal static MelonPreferences_Entry FollowSpeedY; internal static MelonPreferences_Entry PingsEnabled; internal static MelonPreferences_Entry PingsShowNames; internal static MelonPreferences_Entry PingsShowDistance; internal static MelonPreferences_Entry PingsShowBehind; internal static MelonPreferences_Entry PingsIconSize; internal static MelonPreferences_Entry PingsNameSize; internal static MelonPreferences_Entry PingsDistSize; internal static MelonPreferences_Entry PingsHeight; internal static MelonPreferences_Entry PointsEnabled; internal static MelonPreferences_Entry PointsShowDist; internal static MelonPreferences_Entry PointsShowBehind; internal static MelonPreferences_Entry PointsLetterSize; internal static MelonPreferences_Entry PointsDistSize; internal static MelonPreferences_Entry PointsHeight; private const int HalfWin = 45; private const float DegW = 0.005f; private const float SmallH = 0.005f; private const float MedH = 0.009f; private const float LargeH = 0.015f; private const float TickW = 0.0007f; private const float LabelGap = 0.002f; private const float DefaultSmooth = 8f; private const float DefaultPosY = -0.22f; private const float DefaultScale = 1f; private const float DefaultBgAlpha = 0.45f; private const float DefaultBgHeightMult = 1.6f; private const float DefaultFade = 0.45f; private const float DefaultSpread = 0.8f; private const float DefaultFadeH = 0.25f; private const float DefaultFontScale = 1f; private const float DefaultDepth = 0.5f; private const float DefaultArrowSize = 0.007f; private const float DefaultArrowHeight = 0.003f; private const float DefaultFollowSpeedX = 6f; private const float DefaultFollowSpeedY = 16f; private const float DefaultPingsIconSize = 0.012f; private const float DefaultPingsTextSize = 0.003f; private const float DefaultPingsHeight = 0.028f; private const float DefaultPointsLetterSize = 0.005f; private const float DefaultPointsDistSize = 0.003f; private const float DefaultPointsHeight = 0.028f; private const float BaseLabelCharSize = 0.0017f; private const float BaseSubCharSize = 0.0012f; private const float LabelFontFactor = 4f; private const int FadeSubdiv = 16; private const float BgZ = 0.001f; private const float ElemZ = 0f; private static float _smooth; private static Transform _lastHead; private static Vector3 _smoothPos; private static float _smoothYaw; private static GameObject _root; private static Transform _bgT; private static MeshRenderer _bgMr; private static MeshFilter _bgMf; private static Mesh _bgMesh; private static Material _bgMat; private static SpriteRenderer[] _ticks; private static SpriteRenderer[] _cardLabels; private static SpriteRenderer[] _numLabels; private static SpriteRenderer[] _subLabels; private static Dictionary _labelCache; private static List _labelTextures; private static List _labelMats; private static Texture2D _whiteTex; private static Sprite _white; private static Material _tickMat; private static GameObject _arrowGo; private static MeshFilter _arrowMf; private static MeshRenderer _arrowMr; private static Mesh _arrowMesh; private static readonly List _visPingPool = new List(); private static readonly List _pingEntries = new List(); private static GameObject _moreLabelGo; private static TextMesh _moreLabelTm; private static readonly List _visEntries = new List(); private static readonly List _leftBehind = new List(); private static readonly List _rightBehind = new List(); private static readonly List _visPointPool = new List(); private static readonly List _pointEntries = new List(); private static readonly List _visPointEntries = new List(); private static readonly List _leftBehindPt = new List(); private static readonly List _rightBehindPt = new List(); private static readonly string[,] Cardinals = new string[2, 8] { { "N", "NE", "E", "SE", "S", "SW", "W", "NW" }, { "С", "СВ", "В", "ЮВ", "Ю", "ЮЗ", "З", "СЗ" } }; private static readonly string[] DegStrings = BuildDegStrings(); private static readonly Color DefaultPointColor = new Color(1f, 0.88f, 0.3f); private const int BgCols = 16; private static bool _bgMeshBuilt; private static float _lastBgW; private static float _lastBgH; private static float _lastBgAlpha; private static float _lastBgEdge; private static float _lastBgSpread; private static float _lastBgDw; private static float _lastBgEdgeH; private static int[] _bgTris; private static string[] BuildDegStrings() { string[] array = new string[360]; for (int i = 0; i < 360; i++) { array[i] = i.ToString(); } return array; } internal static void Init(MelonPreferences_Category prefs) { //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Expected O, but got Unknown //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) Enabled = prefs.CreateEntry("Compass_Enabled", true, (string)null, "--- Compass ---", false, false, (ValueValidator)null, (string)null); AlwaysOnTop = prefs.CreateEntry("Compass_AlwaysOnTop", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); SmoothFactor = prefs.CreateEntry("Compass_SmoothFactor", 8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PosY = prefs.CreateEntry("Compass_PosY", -0.22f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); Scale = prefs.CreateEntry("Compass_Scale", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); UseRussian = prefs.CreateEntry("Compass_Russian", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); BgAlpha = prefs.CreateEntry("Compass_BgAlpha", 0.45f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); BgHeightMult = prefs.CreateEntry("Compass_BgHeightMult", 1.6f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FadeEdge = prefs.CreateEntry("Compass_FadeEdge", 0.45f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FadeSpread = prefs.CreateEntry("Compass_FadeSpread", 0.8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FadeEdgeH = prefs.CreateEntry("Compass_FadeEdgeH", 0.25f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FontScaleCard = prefs.CreateEntry("Compass_FontScaleCard", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FontScaleLarge = prefs.CreateEntry("Compass_FontScaleLarge", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FontScaleSmall = prefs.CreateEntry("Compass_FontScaleSmall", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); Depth = prefs.CreateEntry("Compass_Depth", 0.5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); ShowArrow = prefs.CreateEntry("Compass_ShowArrow", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); ArrowSize = prefs.CreateEntry("Compass_ArrowSize", 0.007f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); ArrowHeight = prefs.CreateEntry("Compass_ArrowHeight", 0.003f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); SmoothFollow = prefs.CreateEntry("Compass_SmoothFollow", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FollowSpeedX = prefs.CreateEntry("Compass_FollowSpeedX", 6f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); FollowSpeedY = prefs.CreateEntry("Compass_FollowSpeedY", 16f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PingsEnabled = prefs.CreateEntry("Compass_Pings_Enabled", true, (string)null, "--- Compass Pings ---", false, false, (ValueValidator)null, (string)null); PingsShowNames = prefs.CreateEntry("Compass_Pings_ShowNames", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PingsShowDistance = prefs.CreateEntry("Compass_Pings_ShowDist", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PingsShowBehind = prefs.CreateEntry("Compass_Pings_ShowBehind", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PingsIconSize = prefs.CreateEntry("Compass_Pings_IconSize", 0.012f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PingsNameSize = prefs.CreateEntry("Compass_Pings_NameSize", 0.003f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PingsDistSize = prefs.CreateEntry("Compass_Pings_DistSize", 0.003f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PingsHeight = prefs.CreateEntry("Compass_Pings_Height", 0.028f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PointsEnabled = prefs.CreateEntry("Compass_Points_Enabled", true, (string)null, "--- Compass Points ---", false, false, (ValueValidator)null, (string)null); PointsShowDist = prefs.CreateEntry("Compass_Points_ShowDist", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PointsShowBehind = prefs.CreateEntry("Compass_Points_ShowBehind", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PointsLetterSize = prefs.CreateEntry("Compass_Points_LetterSize", 0.005f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PointsDistSize = prefs.CreateEntry("Compass_Points_DistSize", 0.003f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PointsHeight = prefs.CreateEntry("Compass_Points_Height", 0.028f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _whiteTex = new Texture2D(1, 1, (TextureFormat)4, false); _whiteTex.SetPixel(0, 0, Color.white); _whiteTex.Apply(); ((Object)_whiteTex).hideFlags = (HideFlags)61; _white = Sprite.Create(_whiteTex, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 1f); ((Object)_white).hideFlags = (HideFlags)61; } internal static void Invalidate() { TearDown(); } internal static void OnToggle(bool enabled) { Enabled.Value = enabled; if (Object.op_Implicit((Object)(object)_root)) { _root.SetActive(enabled); } } internal static void ResetToDefaults(MelonPreferences_Category prefs) { Enabled.Value = true; SmoothFactor.Value = 8f; PosY.Value = -0.22f; Scale.Value = 1f; UseRussian.Value = false; BgAlpha.Value = 0.45f; BgHeightMult.Value = 1.6f; FadeEdge.Value = 0.45f; FadeSpread.Value = 0.8f; FadeEdgeH.Value = 0.25f; FontScaleCard.Value = 1f; FontScaleLarge.Value = 1f; FontScaleSmall.Value = 1f; Depth.Value = 0.5f; ShowArrow.Value = true; ArrowSize.Value = 0.007f; ArrowHeight.Value = 0.003f; SmoothFollow.Value = false; FollowSpeedX.Value = 6f; FollowSpeedY.Value = 16f; PingsEnabled.Value = true; PingsShowNames.Value = true; PingsShowDistance.Value = true; PingsShowBehind.Value = true; PingsIconSize.Value = 0.012f; PingsNameSize.Value = 0.003f; PingsDistSize.Value = 0.003f; PingsHeight.Value = 0.028f; PointsEnabled.Value = true; PointsShowDist.Value = true; PointsShowBehind.Value = true; PointsLetterSize.Value = 0.005f; PointsDistSize.Value = 0.003f; PointsHeight.Value = 0.028f; prefs.SaveToFile(true); if (Object.op_Implicit((Object)(object)_root)) { _root.SetActive(true); } } internal static void Update() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_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) EnsureBuilt(); if (!Object.op_Implicit((Object)(object)_root) || !Enabled.Value) { return; } Transform head = Player.Head; if (!Object.op_Implicit((Object)(object)head)) { return; } Vector3 forward = head.forward; forward.y = 0f; if (!(((Vector3)(ref forward)).sqrMagnitude < 0.0001f)) { float num = Mathf.Atan2(forward.x, forward.z) * 57.29578f; if (num < 0f) { num += 360f; } _smooth = Mathf.Repeat(Mathf.LerpAngle(_smooth, num, Time.deltaTime * SmoothFactor.Value), 360f); Refresh(); } } private static void EnsureBuilt() { Transform head = Player.Head; if (Object.op_Implicit((Object)(object)head) && (!Object.op_Implicit((Object)(object)_root) || !((Object)(object)_lastHead == (Object)(object)head))) { TearDown(); Build(head); } } private static Sprite GetOrCreateSprite(string text) { //IL_0046: 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) if (_labelCache.TryGetValue(text, out var value)) { return value; } Texture2D val = BitmapFont.Render(text); if (!Object.op_Implicit((Object)(object)val)) { return null; } _labelTextures.Add(val); value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 1f), 7f); ((Object)value).hideFlags = (HideFlags)61; _labelCache[text] = value; return value; } private static SpriteRenderer MakeLabelSr(string goName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown GameObject val = new GameObject(goName); val.transform.SetParent(_root.transform, false); SpriteRenderer obj = val.AddComponent(); ((Renderer)obj).sortingOrder = 3; obj.color = Color.clear; Material item = (((Renderer)obj).material = new Material(HudLayer.GetHudShader(AlwaysOnTop.Value)) { hideFlags = (HideFlags)61 }); _labelMats.Add(item); return obj; } private static void Build(Transform head) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_001f: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0092: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Expected O, but got Unknown //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) _lastHead = head; _root = new GameObject("BONESQUAD_Compass"); _root.transform.localScale = Vector3.one; float value = Depth.Value; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, PosY.Value * (value / 0.5f), value); float num = (0f - Mathf.Atan2(val.y, val.z)) * 57.29578f; _smoothPos = head.TransformPoint(val); _smoothYaw = head.eulerAngles.y; _root.transform.SetPositionAndRotation(_smoothPos, Quaternion.Euler(num, _smoothYaw, 0f)); Shader hudShader = HudLayer.GetHudShader(AlwaysOnTop.Value); _bgMat = new Material(hudShader); _bgMat.mainTexture = (Texture)(object)_whiteTex; ((Object)_bgMat).hideFlags = (HideFlags)61; _tickMat = new Material(hudShader); _tickMat.mainTexture = (Texture)(object)_whiteTex; ((Object)_tickMat).hideFlags = (HideFlags)61; GameObject val2 = new GameObject("CmpBG"); val2.transform.SetParent(_root.transform, false); _bgT = val2.transform; _bgMf = val2.AddComponent(); _bgMr = val2.AddComponent(); _bgMesh = new Mesh(); ((Object)_bgMesh).hideFlags = (HideFlags)61; _bgMf.mesh = _bgMesh; _bgMeshBuilt = false; ((Renderer)_bgMr).material = _bgMat; ((Renderer)_bgMr).sortingOrder = 0; int num2 = 91; _ticks = (SpriteRenderer[])(object)new SpriteRenderer[num2]; for (int i = 0; i < num2; i++) { GameObject val3 = new GameObject($"CT{i}"); val3.transform.SetParent(_root.transform, false); SpriteRenderer val4 = val3.AddComponent(); val4.sprite = _white; ((Renderer)val4).sharedMaterial = _tickMat; ((Renderer)val4).sortingOrder = 2; _ticks[i] = val4; } _labelCache = new Dictionary(); _labelTextures = new List(); _labelMats = new List(); _cardLabels = (SpriteRenderer[])(object)new SpriteRenderer[4]; for (int j = 0; j < _cardLabels.Length; j++) { _cardLabels[j] = MakeLabelSr($"CCard{j}"); } _numLabels = (SpriteRenderer[])(object)new SpriteRenderer[6]; for (int k = 0; k < _numLabels.Length; k++) { _numLabels[k] = MakeLabelSr($"CNum{k}"); } _subLabels = (SpriteRenderer[])(object)new SpriteRenderer[14]; for (int l = 0; l < _subLabels.Length; l++) { _subLabels[l] = MakeLabelSr($"CS{l}"); } _arrowGo = new GameObject("CmpArrow"); _arrowGo.transform.SetParent(_root.transform, false); _arrowMf = _arrowGo.AddComponent(); _arrowMr = _arrowGo.AddComponent(); _arrowMesh = new Mesh(); ((Object)_arrowMesh).hideFlags = (HideFlags)61; _arrowMesh.vertices = Il2CppStructArray.op_Implicit((Vector3[])(object)new Vector3[3] { new Vector3(0f, 0f, 0f), new Vector3(-0.5f, 1f, 0f), new Vector3(0.5f, 1f, 0f) }); _arrowMesh.colors = Il2CppStructArray.op_Implicit((Color[])(object)new Color[3] { Color.white, Color.white, Color.white }); _arrowMesh.uv = Il2CppStructArray.op_Implicit((Vector2[])(object)new Vector2[3] { Vector2.zero, Vector2.zero, Vector2.zero }); _arrowMesh.triangles = Il2CppStructArray.op_Implicit(new int[3] { 0, 1, 2 }); _arrowMesh.RecalculateBounds(); _arrowMf.mesh = _arrowMesh; ((Renderer)_arrowMr).sharedMaterial = _tickMat; ((Renderer)_arrowMr).sortingOrder = 3; _arrowGo.SetActive(ShowArrow.Value); HudLayer.ApplyCompass(_root); if (!Enabled.Value) { _root.SetActive(false); } BonesquadMod.Log("[Compass] Built."); } private static void Refresh() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) float value = Depth.Value; float num = value / 0.5f; float num2 = Scale.Value * num; float num3 = 0.005f * num2; float num4 = 0.015f * num2; float num5 = 0.0007f * num2; float num6 = 0.002f * num2; float num7 = 0.0068000006f * num2; Transform head = Player.Head; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, PosY.Value * num, value); float num8 = (0f - Mathf.Atan2(val.y, val.z)) * 57.29578f; Vector3 val2 = head.TransformPoint(val); float y = head.eulerAngles.y; if (SmoothFollow.Value) { float num9 = 1f - Mathf.Exp((0f - FollowSpeedX.Value) * Time.deltaTime); float num10 = 1f - Mathf.Exp((0f - FollowSpeedY.Value) * Time.deltaTime); _smoothYaw = Mathf.LerpAngle(_smoothYaw, y, num9); Vector3 val3 = head.InverseTransformPoint(_smoothPos); float num11 = Mathf.Lerp(val3.x, 0f, num9); float num12 = Mathf.Lerp(val3.y, val.y, num10); _smoothPos = head.TransformPoint(new Vector3(num11, num12, val.z)); _root.transform.SetPositionAndRotation(_smoothPos, Quaternion.Euler(num8, _smoothYaw, 0f)); } else { _smoothYaw = y; _smoothPos = val2; _root.transform.SetPositionAndRotation(val2, head.rotation * Quaternion.Euler(num8, 0f, 0f)); } float bgW = 90f * num3 + num3 * 2f; float bgH = (num4 + num6 + num7 + 0.004f * num2) * BgHeightMult.Value; float num13 = (num4 - (num6 + num7)) * 0.5f; _bgT.localPosition = new Vector3(0f, num13, 0.001f); _bgT.localScale = Vector3.one; UpdateBgMesh(bgW, bgH, BgAlpha.Value, FadeEdge.Value, FadeSpread.Value, num3, FadeEdgeH.Value); int num14 = Mathf.FloorToInt(_smooth); float num15 = _smooth - (float)num14; for (int i = 0; i < _cardLabels.Length; i++) { _cardLabels[i].color = Color.clear; } for (int j = 0; j < _numLabels.Length; j++) { _numLabels[j].color = Color.clear; } for (int k = 0; k < _subLabels.Length; k++) { _subLabels[k].color = Color.clear; } int num16 = 0; int num17 = 0; int num18 = 0; float num19 = 0.0017f * FontScaleCard.Value; float num20 = 0.0017f * FontScaleLarge.Value; float num21 = 0.0012f * FontScaleSmall.Value; float num22 = num19 * 4f * num2; float num23 = num20 * 4f * num2; float num24 = num21 * 4f * num2; Vector3 localPosition = default(Vector3); Color color = default(Color); for (int l = 0; l <= 90; l++) { int num25 = ((num14 - 45 + l) % 360 + 360) % 360; float num26 = ((float)(l - 45) - num15) * num3; float num27 = Mathf.Abs((float)(l - 45) - num15); float num28 = Mathf.SmoothStep(1f, 0f, num27 / 45f); float num29 = ((num25 % 15 == 0) ? num4 : ((num25 % 5 == 0) ? (0.009f * num2) : (0.005f * num2))); SpriteRenderer obj = _ticks[l]; ((Component)obj).transform.localPosition = new Vector3(num26, num29 * 0.5f, 0f); ((Component)obj).transform.localScale = new Vector3(num5, num29, 1f); obj.color = new Color(1f, 1f, 1f, num28); ((Vector3)(ref localPosition))..ctor(num26, 0f - num6, 0f); ((Color)(ref color))..ctor(1f, 1f, 1f, num28); if (num25 % 45 == 0 && num16 < _cardLabels.Length) { SpriteRenderer obj2 = _cardLabels[num16++]; obj2.sprite = GetOrCreateSprite(GetLabel(num25)); obj2.color = color; ((Component)obj2).transform.localScale = new Vector3(num22, num22, 1f); ((Component)obj2).transform.localPosition = localPosition; } else if (num25 % 15 == 0 && num17 < _numLabels.Length) { SpriteRenderer obj3 = _numLabels[num17++]; obj3.sprite = GetOrCreateSprite(DegStrings[num25]); obj3.color = color; ((Component)obj3).transform.localScale = new Vector3(num23, num23, 1f); ((Component)obj3).transform.localPosition = localPosition; } else if (num25 % 5 == 0 && num18 < _subLabels.Length) { SpriteRenderer obj4 = _subLabels[num18++]; obj4.sprite = GetOrCreateSprite(DegStrings[num25]); obj4.color = color; ((Component)obj4).transform.localScale = new Vector3(num24, num24, 1f); ((Component)obj4).transform.localPosition = localPosition; } } if (Object.op_Implicit((Object)(object)_arrowGo)) { bool value2 = ShowArrow.Value; _arrowGo.SetActive(value2); if (value2) { float num30 = ArrowSize.Value * num2; float num31 = num4 + ArrowHeight.Value * num2; _arrowGo.transform.localPosition = new Vector3(0f, num31, 0f); _arrowGo.transform.localScale = new Vector3(num30, num30, 1f); } } if (PingsEnabled.Value) { RefreshCompassPings(num3, num2, num4); } else { HideAllPingPools(); } if (PointsEnabled.Value) { RefreshCompassPoints(num3, num2, num4); } else { HideAllPointPool(); } } private static void HideAllPingPools() { foreach (PingIndicator item in _visPingPool) { if (Object.op_Implicit((Object)(object)item.Root)) { item.Root.SetActive(false); } } if (Object.op_Implicit((Object)(object)_moreLabelGo)) { _moreLabelGo.SetActive(false); } } private static PingIndicator GetOrCreateIndicator(List pool, int idx, string prefix) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Expected O, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) while (pool.Count <= idx) { PingIndicator pingIndicator = new PingIndicator(); pingIndicator.Root = new GameObject($"{prefix}{pool.Count}"); pingIndicator.Root.transform.SetParent(_root.transform, false); ((Object)pingIndicator.Root).hideFlags = (HideFlags)61; GameObject val = new GameObject("Icon"); val.transform.SetParent(pingIndicator.Root.transform, false); pingIndicator.IconMat = new Material(HudLayer.GetHudShader(AlwaysOnTop.Value)) { hideFlags = (HideFlags)61 }; HudLayer.ApplyTextZTest(pingIndicator.IconMat, AlwaysOnTop.Value); pingIndicator.IconSr = val.AddComponent(); ((Renderer)pingIndicator.IconSr).material = pingIndicator.IconMat; ((Renderer)pingIndicator.IconSr).sortingOrder = 5; GameObject val2 = new GameObject("BehindLabel"); val2.transform.SetParent(pingIndicator.Root.transform, false); pingIndicator.BehindLabelTm = val2.AddComponent(); pingIndicator.BehindLabelTm.text = "BEHIND"; pingIndicator.BehindLabelTm.fontSize = 40; pingIndicator.BehindLabelTm.color = new Color(1f, 0.75f, 0.3f); pingIndicator.BehindLabelTm.anchor = (TextAnchor)7; pingIndicator.BehindLabelTm.alignment = (TextAlignment)1; ((Renderer)val2.GetComponent()).sortingOrder = 5; val2.SetActive(false); GameObject val3 = new GameObject("Name"); val3.transform.SetParent(pingIndicator.Root.transform, false); pingIndicator.NameTm = val3.AddComponent(); pingIndicator.NameTm.fontSize = 40; pingIndicator.NameTm.color = Color.white; pingIndicator.NameTm.anchor = (TextAnchor)7; pingIndicator.NameTm.alignment = (TextAlignment)1; ((Renderer)val3.GetComponent()).sortingOrder = 5; GameObject val4 = new GameObject("Dist"); val4.transform.SetParent(pingIndicator.Root.transform, false); pingIndicator.DistTm = val4.AddComponent(); pingIndicator.DistTm.fontSize = 40; pingIndicator.DistTm.color = new Color(1f, 1f, 0.7f); pingIndicator.DistTm.anchor = (TextAnchor)1; pingIndicator.DistTm.alignment = (TextAlignment)1; ((Renderer)val4.GetComponent()).sortingOrder = 5; pool.Add(pingIndicator); } return pool[idx]; } private static void UpdateIndicatorIcon(PingIndicator p, Texture2D iconTex) { //IL_0057: 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) if (!((Object)(object)p.LastIconTex == (Object)(object)iconTex)) { p.LastIconTex = iconTex; if (Object.op_Implicit((Object)(object)p.LastSprite)) { Object.Destroy((Object)(object)p.LastSprite); } p.LastSprite = null; if (Object.op_Implicit((Object)(object)iconTex)) { p.LastSprite = Sprite.Create(iconTex, new Rect(0f, 0f, (float)((Texture)iconTex).width, (float)((Texture)iconTex).height), new Vector2(0.5f, 0.5f), (float)((Texture)iconTex).width); ((Object)p.LastSprite).hideFlags = (HideFlags)61; } p.IconSr.sprite = p.LastSprite; } } private static void RefreshCompassPings(float dw, float sc, float largeH) { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) PingMarkerModule.FillCompassPings(_pingEntries); Transform head = Player.Head; if (!Object.op_Implicit((Object)(object)head)) { HideAllPingPools(); return; } bool value = PingsShowNames.Value; bool value2 = PingsShowDistance.Value; bool value3 = PingsShowBehind.Value; float num = PingsIconSize.Value * sc; float iconHalf = num * 0.5f; float num2 = PingsNameSize.Value * sc; float num3 = PingsDistSize.Value * sc; float pingY = largeH + PingsHeight.Value * sc; float num4 = 0f - PingsHeight.Value * sc; float gap = 0.001f * sc; float num5 = 45f * dw; float num6 = (value ? (7f * num2 * 2f) : 0f); float num7 = (value2 ? (4.2f * num3 * 2f) : 0f); float num8 = Mathf.Max(num, Mathf.Max(num6, num7)) + 0.0014f * sc; _visEntries.Clear(); _leftBehind.Clear(); _rightBehind.Clear(); foreach (PingMarkerModule.CompassPingEntry pingEntry in _pingEntries) { Vector3 val = pingEntry.WorldPos - head.position; val.y = 0f; float num9 = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? (Mathf.Atan2(val.x, val.z) * 57.29578f) : _smooth); float num10 = Mathf.DeltaAngle(_smooth, num9); float magnitude = ((Vector3)(ref val)).magnitude; if (Mathf.Abs(num10) <= 55f) { _visEntries.Add(new PingEntry(pingEntry, num10, magnitude)); } else if (value3) { if (num10 <= 0f) { _leftBehind.Add(new PingEntry(pingEntry, num10, magnitude)); } else { _rightBehind.Add(new PingEntry(pingEntry, num10, magnitude)); } } } int poolIdx = 0; foreach (PingEntry visEntry in _visEntries) { PlacePingIndicator(ref poolIdx, visEntry.E, visEntry.Dist, visEntry.Offset * dw, pingY, isBehind: false, num, iconHalf, num2, num3, gap, value, value2, sc); } int num11 = Mathf.Min(_leftBehind.Count, 5); int num12 = Mathf.Min(_rightBehind.Count, 5); int num13 = _leftBehind.Count - num11 + (_rightBehind.Count - num12); for (int i = 0; i < num11; i++) { PlacePingIndicator(ref poolIdx, _leftBehind[i].E, _leftBehind[i].Dist, 0f - num5 + (float)i * num8, num4, isBehind: true, num, iconHalf, num2, num3, gap, value, value2, sc); } for (int j = 0; j < num12; j++) { PlacePingIndicator(ref poolIdx, _rightBehind[j].E, _rightBehind[j].Dist, num5 - (float)j * num8, num4, isBehind: true, num, iconHalf, num2, num3, gap, value, value2, sc); } for (int k = poolIdx; k < _visPingPool.Count; k++) { if (Object.op_Implicit((Object)(object)_visPingPool[k].Root)) { _visPingPool[k].Root.SetActive(false); } } if (num13 > 0) { if (!Object.op_Implicit((Object)(object)_moreLabelGo)) { _moreLabelGo = new GameObject("CmpMoreLabel"); _moreLabelGo.transform.SetParent(_root.transform, false); ((Object)_moreLabelGo).hideFlags = (HideFlags)61; _moreLabelTm = _moreLabelGo.AddComponent(); _moreLabelTm.fontSize = 40; _moreLabelTm.color = new Color(1f, 0.75f, 0.3f); _moreLabelTm.anchor = (TextAnchor)3; _moreLabelTm.alignment = (TextAlignment)0; ((Renderer)_moreLabelGo.GetComponent()).sortingOrder = 5; } _moreLabelGo.SetActive(true); _moreLabelTm.text = $"and {num13} more"; _moreLabelTm.characterSize = num2; float num14 = ((num12 > 0) ? (num5 - (float)num12 * num8) : num5) - num8 * 1f; _moreLabelGo.transform.localPosition = new Vector3(num14, num4, 0f); } else if (Object.op_Implicit((Object)(object)_moreLabelGo)) { _moreLabelGo.SetActive(false); } } private static void PlacePingIndicator(ref int poolIdx, PingMarkerModule.CompassPingEntry e, float dist3d, float x, float pingY, bool isBehind, float iconSc, float iconHalf, float nameCharSz, float distCharSz, float gap, bool showNames, bool showDist, float sc) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) PingIndicator orCreateIndicator = GetOrCreateIndicator(_visPingPool, poolIdx++, "CmpPing"); UpdateIndicatorIcon(orCreateIndicator, e.Tex); orCreateIndicator.Root.SetActive(true); orCreateIndicator.Root.transform.localPosition = new Vector3(x, pingY, 0f); ((Component)orCreateIndicator.IconSr).transform.localPosition = Vector3.zero; ((Component)orCreateIndicator.IconSr).transform.localScale = Vector3.one * iconSc; if (Object.op_Implicit((Object)(object)orCreateIndicator.BehindLabelTm)) { ((Component)orCreateIndicator.BehindLabelTm).gameObject.SetActive(isBehind); if (isBehind) { orCreateIndicator.BehindLabelTm.characterSize = nameCharSz * 0.85f; ((Component)orCreateIndicator.BehindLabelTm).transform.localPosition = new Vector3(0f, iconHalf + gap, 0f); } } orCreateIndicator.NameTm.anchor = (TextAnchor)(isBehind ? 1 : 7); ((Component)orCreateIndicator.NameTm).gameObject.SetActive(showNames); if (showNames) { orCreateIndicator.NameTm.text = e.OwnerLabel; orCreateIndicator.NameTm.characterSize = nameCharSz; ((Component)orCreateIndicator.NameTm).transform.localPosition = new Vector3(0f, isBehind ? (0f - (iconHalf + gap)) : (iconHalf + gap), 0f); } ((Component)orCreateIndicator.DistTm).gameObject.SetActive(showDist); if (showDist) { int num = Mathf.RoundToInt(dist3d); if (num != orCreateIndicator.LastDistM) { orCreateIndicator.DistTm.text = $"{num}M"; orCreateIndicator.LastDistM = num; } orCreateIndicator.DistTm.characterSize = distCharSz; float num2 = (showNames ? (4f * nameCharSz + gap) : 0f); float num3 = (isBehind ? (0f - (iconHalf + gap + num2)) : (0f - (iconHalf + gap))); ((Component)orCreateIndicator.DistTm).transform.localPosition = new Vector3(0f, num3, 0f); } } private static void HideAllPointPool() { foreach (PointIndicator item in _visPointPool) { if (Object.op_Implicit((Object)(object)item.Root)) { item.Root.SetActive(false); } } } private static Color ParsePointColor(string hex) { //IL_0012: 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) Color result = default(Color); if (string.IsNullOrEmpty(hex) || !ColorUtility.TryParseHtmlString(hex, ref result)) { return DefaultPointColor; } return result; } private static void RefreshCompassPoints(float dw, float sc, float largeH) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_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_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) _pointEntries.Clear(); CaptureEventHandler.FillCompassPoints(_pointEntries); Transform head = Player.Head; if (!Object.op_Implicit((Object)(object)head)) { HideAllPointPool(); return; } bool value = PointsShowDist.Value; bool value2 = PointsShowBehind.Value; float num = PointsLetterSize.Value * sc; float num2 = PointsDistSize.Value * sc; float pingY = largeH + PointsHeight.Value * sc; float pingY2 = 0f - PointsHeight.Value * sc; float gap = 0.001f * sc; float num3 = 45f * dw; float num4 = 1.5f * num * 2f; float num5 = (value ? (4.2f * num2 * 2f) : 0f); float num6 = Mathf.Max(num4, num5) + 0.001f * sc; _visPointEntries.Clear(); _leftBehindPt.Clear(); _rightBehindPt.Clear(); foreach (CaptureEventHandler.CompassCaptureEntry pointEntry in _pointEntries) { Vector3 val = pointEntry.WorldPos - head.position; val.y = 0f; float num7 = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? (Mathf.Atan2(val.x, val.z) * 57.29578f) : _smooth); float num8 = Mathf.DeltaAngle(_smooth, num7); float magnitude = ((Vector3)(ref val)).magnitude; if (Mathf.Abs(num8) <= 55f) { _visPointEntries.Add(new PointEntry(pointEntry, num8, magnitude)); } else if (value2) { if (num8 <= 0f) { _leftBehindPt.Add(new PointEntry(pointEntry, num8, magnitude)); } else { _rightBehindPt.Add(new PointEntry(pointEntry, num8, magnitude)); } } } int poolIdx = 0; foreach (PointEntry visPointEntry in _visPointEntries) { PlacePointIndicator(ref poolIdx, visPointEntry.E, visPointEntry.Dist, visPointEntry.Offset * dw, pingY, isBehind: false, num, num2, gap, value); } int num9 = Mathf.Min(_leftBehindPt.Count, 5); int num10 = Mathf.Min(_rightBehindPt.Count, 5); for (int i = 0; i < num9; i++) { PlacePointIndicator(ref poolIdx, _leftBehindPt[i].E, _leftBehindPt[i].Dist, 0f - num3 + (float)i * num6, pingY2, isBehind: true, num, num2, gap, value); } for (int j = 0; j < num10; j++) { PlacePointIndicator(ref poolIdx, _rightBehindPt[j].E, _rightBehindPt[j].Dist, num3 - (float)j * num6, pingY2, isBehind: true, num, num2, gap, value); } for (int k = poolIdx; k < _visPointPool.Count; k++) { if (Object.op_Implicit((Object)(object)_visPointPool[k].Root)) { _visPointPool[k].Root.SetActive(false); } } } private static PointIndicator GetOrCreatePointIndicator(int idx) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) while (_visPointPool.Count <= idx) { PointIndicator pointIndicator = new PointIndicator(); pointIndicator.Root = new GameObject($"CmpPoint{_visPointPool.Count}"); pointIndicator.Root.transform.SetParent(_root.transform, false); ((Object)pointIndicator.Root).hideFlags = (HideFlags)61; GameObject val = new GameObject("Letter"); val.transform.SetParent(pointIndicator.Root.transform, false); pointIndicator.LetterTm = val.AddComponent(); pointIndicator.LetterTm.fontSize = 40; pointIndicator.LetterTm.color = new Color(1f, 0.88f, 0.3f); pointIndicator.LetterTm.anchor = (TextAnchor)4; pointIndicator.LetterTm.alignment = (TextAlignment)1; ((Renderer)val.GetComponent()).sortingOrder = 5; GameObject val2 = new GameObject("BehindLabel"); val2.transform.SetParent(pointIndicator.Root.transform, false); pointIndicator.BehindLabelTm = val2.AddComponent(); pointIndicator.BehindLabelTm.text = "BEHIND"; pointIndicator.BehindLabelTm.fontSize = 40; pointIndicator.BehindLabelTm.color = new Color(1f, 0.75f, 0.3f); pointIndicator.BehindLabelTm.anchor = (TextAnchor)7; pointIndicator.BehindLabelTm.alignment = (TextAlignment)1; ((Renderer)val2.GetComponent()).sortingOrder = 5; val2.SetActive(false); GameObject val3 = new GameObject("Dist"); val3.transform.SetParent(pointIndicator.Root.transform, false); pointIndicator.DistTm = val3.AddComponent(); pointIndicator.DistTm.fontSize = 40; pointIndicator.DistTm.color = new Color(1f, 1f, 0.7f); pointIndicator.DistTm.anchor = (TextAnchor)1; pointIndicator.DistTm.alignment = (TextAlignment)1; ((Renderer)val3.GetComponent()).sortingOrder = 5; _visPointPool.Add(pointIndicator); } return _visPointPool[idx]; } private static void PlacePointIndicator(ref int poolIdx, CaptureEventHandler.CompassCaptureEntry e, float dist3d, float x, float pingY, bool isBehind, float letterSz, float distSz, float gap, bool showDist) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0172: Unknown result type (might be due to invalid IL or missing references) PointIndicator orCreatePointIndicator = GetOrCreatePointIndicator(poolIdx++); orCreatePointIndicator.Root.SetActive(true); orCreatePointIndicator.Root.transform.localPosition = new Vector3(x, pingY, 0f); float num = 40f * letterSz * 0.1f * 0.5f; orCreatePointIndicator.LetterTm.text = e.Letter; orCreatePointIndicator.LetterTm.color = ParsePointColor(e.ColorHex); orCreatePointIndicator.LetterTm.characterSize = letterSz; ((Component)orCreatePointIndicator.LetterTm).transform.localPosition = Vector3.zero; if (Object.op_Implicit((Object)(object)orCreatePointIndicator.BehindLabelTm)) { ((Component)orCreatePointIndicator.BehindLabelTm).gameObject.SetActive(isBehind); if (isBehind) { orCreatePointIndicator.BehindLabelTm.characterSize = letterSz * 0.8f; ((Component)orCreatePointIndicator.BehindLabelTm).transform.localPosition = new Vector3(0f, num + gap, 0f); } } ((Component)orCreatePointIndicator.DistTm).gameObject.SetActive(showDist); if (showDist) { int num2 = Mathf.RoundToInt(dist3d); if (num2 != orCreatePointIndicator.LastDistM) { orCreatePointIndicator.DistTm.text = $"{num2}M"; orCreatePointIndicator.LastDistM = num2; } orCreatePointIndicator.DistTm.characterSize = distSz; ((Component)orCreatePointIndicator.DistTm).transform.localPosition = new Vector3(0f, 0f - (num + gap), 0f); } } private static void UpdateBgMesh(float bgW, float bgH, float alpha, float edge, float spread, float dw, float edgeH) { //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) if (_bgMeshBuilt && bgW == _lastBgW && bgH == _lastBgH && alpha == _lastBgAlpha && edge == _lastBgEdge && spread == _lastBgSpread && dw == _lastBgDw && edgeH == _lastBgEdgeH) { return; } _bgMeshBuilt = true; _lastBgW = bgW; _lastBgH = bgH; _lastBgAlpha = alpha; _lastBgEdge = edge; _lastBgSpread = spread; _lastBgDw = dw; _lastBgEdgeH = edgeH; float num = bgW * 0.5f; float num2 = bgH * 0.5f; float num3 = num2 * Mathf.Clamp01(edge); float num4 = num * Mathf.Clamp01(edgeH); int num5 = 16; int num6 = 2 * num5 + 2; int num7 = 17; Vector3[] array = (Vector3[])(object)new Vector3[num6 * num7]; Color[] array2 = (Color[])(object)new Color[num6 * num7]; Vector2[] array3 = (Vector2[])(object)new Vector2[num6 * num7]; for (int i = 0; i < num6; i++) { float num9; float num10; if (i <= num5) { float num8 = (float)i / (float)num5; num9 = num2 - num3 * num8; num10 = 1f - Mathf.Pow(1f - num8, spread); } else { int num11 = i - (num5 + 1); float num12 = 1f - (float)num11 / (float)num5; num9 = 0f - num2 + num3 * num12; num10 = 1f - Mathf.Pow(1f - num12, spread); } for (int j = 0; j < num7; j++) { float num13 = 0f - num + bgW * ((float)j / 16f); float num14 = num - Mathf.Abs(num13); float num15 = ((num4 > 0f) ? Mathf.Clamp01(num14 / num4) : 1f); float num16 = 1f - Mathf.Pow(1f - num15, spread); int num17 = i * num7 + j; array[num17] = new Vector3(num13, num9, 0f); array2[num17] = new Color(0f, 0f, 0f, Mathf.Clamp01(alpha * num10 * num16)); array3[num17] = Vector2.zero; } } if (_bgTris == null) { _bgTris = new int[(num6 - 1) * 16 * 6]; int num18 = 0; for (int k = 0; k < num6 - 1; k++) { for (int l = 0; l < 16; l++) { int num19 = k * num7 + l; _bgTris[num18++] = num19; _bgTris[num18++] = num19 + 1; _bgTris[num18++] = num19 + num7; _bgTris[num18++] = num19 + num7; _bgTris[num18++] = num19 + 1; _bgTris[num18++] = num19 + num7 + 1; } } } _bgMesh.Clear(); _bgMesh.vertices = Il2CppStructArray.op_Implicit(array); _bgMesh.colors = Il2CppStructArray.op_Implicit(array2); _bgMesh.uv = Il2CppStructArray.op_Implicit(array3); _bgMesh.triangles = Il2CppStructArray.op_Implicit(_bgTris); _bgMesh.RecalculateBounds(); } private static string GetLabel(int deg) { int num = (UseRussian.Value ? 1 : 0); return deg switch { 0 => Cardinals[num, 0], 45 => Cardinals[num, 1], 90 => Cardinals[num, 2], 135 => Cardinals[num, 3], 180 => Cardinals[num, 4], 225 => Cardinals[num, 5], 270 => Cardinals[num, 6], 315 => Cardinals[num, 7], _ => deg.ToString(), }; } private static void TearDown() { if (Object.op_Implicit((Object)(object)_root)) { Object.Destroy((Object)(object)_root); } if (Object.op_Implicit((Object)(object)_bgMesh)) { Object.Destroy((Object)(object)_bgMesh); } if (Object.op_Implicit((Object)(object)_bgMat)) { Object.Destroy((Object)(object)_bgMat); } if (Object.op_Implicit((Object)(object)_tickMat)) { Object.Destroy((Object)(object)_tickMat); } if (_labelTextures != null) { foreach (Texture2D labelTexture in _labelTextures) { if (Object.op_Implicit((Object)(object)labelTexture)) { Object.Destroy((Object)(object)labelTexture); } } _labelTextures = null; } if (_labelMats != null) { foreach (Material labelMat in _labelMats) { if (Object.op_Implicit((Object)(object)labelMat)) { Object.Destroy((Object)(object)labelMat); } } _labelMats = null; } _labelCache = null; if (Object.op_Implicit((Object)(object)_arrowMesh)) { Object.Destroy((Object)(object)_arrowMesh); } foreach (PingIndicator item in _visPingPool) { if (Object.op_Implicit((Object)(object)item.IconMat)) { Object.Destroy((Object)(object)item.IconMat); } if (Object.op_Implicit((Object)(object)item.LastSprite)) { Object.Destroy((Object)(object)item.LastSprite); } } _visPingPool.Clear(); _pingEntries.Clear(); _moreLabelGo = null; _moreLabelTm = null; _visPointPool.Clear(); _pointEntries.Clear(); _lastHead = null; _root = null; _bgT = null; _bgMr = null; _bgMf = null; _bgMesh = null; _bgMat = null; _tickMat = null; _ticks = null; _cardLabels = null; _numLabels = null; _subLabels = null; _arrowGo = null; _arrowMf = null; _arrowMr = null; _arrowMesh = null; } } } namespace BONESQUAD.Modules.BulletWhiz { internal static class BulletWhizModule { private static readonly List _whizSounds = new List(); private static string _audioFolder; internal static MelonPreferences_Entry Enabled; internal static MelonPreferences_Entry Volume; internal static MelonPreferences_Entry MinDistance; internal static MelonPreferences_Entry PassDistance; internal static void Init(MelonPreferences_Category prefs) { Enabled = prefs.CreateEntry("BulletWhiz_Enabled", true, (string)null, "--- BulletWhiz ---", false, false, (ValueValidator)null, (string)null); Volume = prefs.CreateEntry("BulletWhiz_Volume", 50f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); MinDistance = prefs.CreateEntry("BulletWhiz_MinDistance", 100f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); PassDistance = prefs.CreateEntry("BulletWhiz_PassDistance", 5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _audioFolder = Path.Combine(MelonEnvironment.UserDataDirectory, "BONESQUAD", "BulletWhiz"); if (!Directory.Exists(_audioFolder)) { Directory.CreateDirectory(_audioFolder); } LoadAudioFiles(); BonesquadMod.Log($"BulletWhiz ready — {_whizSounds.Count} clip(s) MinDist:{MinDistance.Value}m PassDist:{PassDistance.Value}m"); } internal static void OnToggle(bool enabled) { Enabled.Value = enabled; } internal static void ResetToDefaults(MelonPreferences_Category prefs) { Enabled.Value = true; Volume.Value = 50f; MinDistance.Value = 100f; PassDistance.Value = 5f; prefs.SaveToFile(true); } internal static void OnGunFired(Gun gun, Vector3 muzzlePos, Vector3 direction, bool isLocalPlayer) { //IL_00c0: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: 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_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) BonesquadMod.Log($"[BulletWhiz] OnGunFired: Enabled={Enabled.Value} isLocalPlayer={isLocalPlayer} clips={_whizSounds.Count}"); if (!Enabled.Value) { BonesquadMod.Log("[BulletWhiz] OnGunFired: abort — module disabled"); return; } if (isLocalPlayer) { BonesquadMod.Log("[BulletWhiz] OnGunFired: abort — gun belongs to local player"); return; } if (_whizSounds.Count == 0) { BonesquadMod.Log("[BulletWhiz] OnGunFired: abort — no whiz clips loaded"); return; } try { Transform head = Player.Head; if ((Object)(object)head == (Object)null) { BonesquadMod.Log("[BulletWhiz] OnGunFired: abort — Player.Head is null"); return; } Vector3 position = head.position; float value = MinDistance.Value; Vector3 val = position - muzzlePos; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; BonesquadMod.Log($"[BulletWhiz] OnGunFired: muzzleDist={Mathf.Sqrt(sqrMagnitude):F2}m MinDistance={value}m"); if (sqrMagnitude < value * value) { BonesquadMod.Log("[BulletWhiz] OnGunFired: abort — muzzle too close (< MinDistance)"); return; } float num = Vector3.Dot(position - muzzlePos, direction); if (num < 0f) { BonesquadMod.Log("[BulletWhiz] OnGunFired: abort — head is behind the muzzle (proj < 0)"); return; } Vector3 val2 = muzzlePos + direction * num; float value2 = PassDistance.Value; val = val2 - position; float sqrMagnitude2 = ((Vector3)(ref val)).sqrMagnitude; BonesquadMod.Log($"[BulletWhiz] OnGunFired: closestDist={Mathf.Sqrt(sqrMagnitude2):F2}m PassDistance={value2}m"); if (sqrMagnitude2 > value2 * value2) { BonesquadMod.Log("[BulletWhiz] OnGunFired: abort — trajectory missed head by more than PassDistance"); return; } BonesquadMod.Log($"[BulletWhiz] OnGunFired: conditions met, playing whiz sound at {val2}"); PlayWhizSound(val2); } catch (Exception ex) { BonesquadMod.LogError("[BulletWhiz] OnGunFired: " + ex.Message); } } internal static bool IsLocalPlayerGun(Gun gun) { //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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gun == (Object)null) { BonesquadMod.Log("[BulletWhiz] IsLocalPlayerGun: gun is null -> true"); return true; } try { Vector3 position = ((Component)gun).transform.position; Transform head = Player.Head; if ((Object)(object)head == (Object)null) { BonesquadMod.Log("[BulletWhiz] IsLocalPlayerGun: Player.Head is null -> true"); return true; } Vector3 val = position - head.position; if (((Vector3)(ref val)).sqrMagnitude < 4f) { BonesquadMod.Log("[BulletWhiz] IsLocalPlayerGun: gun within 2m of head -> true"); return true; } Hand leftHand = Player.LeftHand; if ((Object)(object)leftHand != (Object)null && (Object)(object)((Component)leftHand).transform != (Object)null) { val = position - ((Component)leftHand).transform.position; if (((Vector3)(ref val)).sqrMagnitude < 4f) { BonesquadMod.Log("[BulletWhiz] IsLocalPlayerGun: gun within 2m of left hand -> true"); return true; } } Hand rightHand = Player.RightHand; if ((Object)(object)rightHand != (Object)null && (Object)(object)((Component)rightHand).transform != (Object)null) { val = position - ((Component)rightHand).transform.position; if (((Vector3)(ref val)).sqrMagnitude < 4f) { BonesquadMod.Log("[BulletWhiz] IsLocalPlayerGun: gun within 2m of right hand -> true"); return true; } } BonesquadMod.Log("[BulletWhiz] IsLocalPlayerGun: gun is remote -> false"); return false; } catch (Exception ex) { BonesquadMod.LogWarning("[BulletWhiz] IsLocalPlayerGun: exception (" + ex.Message + ") -> true"); return true; } } private static void PlayWhizSound(Vector3 position) { //IL_0067: 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) int index = Random.Range(0, _whizSounds.Count); float num = Mathf.Max(0f, Volume.Value) / 5f; BonesquadMod.Log($"[BulletWhiz] PlayWhizSound: clip='{((Object)_whizSounds[index]).name}' pos={position} volume={num:F2}"); AudioSource.PlayClipAtPoint(_whizSounds[index], position, num); } private static void LoadAudioFiles() { BonesquadMod.Log("[BulletWhiz] LoadAudioFiles: scanning '" + _audioFolder + "'"); string[] files = Directory.GetFiles(_audioFolder); foreach (string text in files) { try { AudioClip val = API.LoadAudioClip(text, true); if ((Object)(object)val != (Object)null) { _whizSounds.Add(val); BonesquadMod.Log("[BulletWhiz] LoadAudioFiles: loaded '" + Path.GetFileName(text) + "'"); } else { BonesquadMod.LogWarning("[BulletWhiz] Skipped (null clip): " + Path.GetFileName(text)); } } catch (Exception ex) { BonesquadMod.LogWarning("[BulletWhiz] Failed to load '" + Path.GetFileName(text) + "': " + ex.Message); } } } } [HarmonyPatch(typeof(Gun))] internal static class GunPatches { [HarmonyPatch("OnFire")] [HarmonyPostfix] internal static void OnFirePostfix(Gun __instance) { //IL_005a: 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) BonesquadMod.Log("[BulletWhiz] OnFire patch triggered"); if ((Object)(object)__instance == (Object)null) { BonesquadMod.Log("[BulletWhiz] OnFire: __instance is null, abort"); return; } try { Transform firePointTransform = __instance.firePointTransform; if ((Object)(object)firePointTransform == (Object)null) { BonesquadMod.Log("[BulletWhiz] OnFire: firePointTransform is null, abort"); return; } bool flag = BulletWhizModule.IsLocalPlayerGun(__instance); BonesquadMod.Log($"[BulletWhiz] OnFire: firePoint={firePointTransform.position} isLocal={flag}"); BulletWhizModule.OnGunFired(__instance, firePointTransform.position, firePointTransform.forward, flag); } catch (Exception ex) { BonesquadMod.LogError("[BulletWhiz] OnFire patch: " + ex.Message); } } } }