Decompiled source of FusionKillerMode v0.3.11
Mods/BONELABFusionKillerMode.dll
Decompiled an hour ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json; using FusionKillerMode; 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.VRMK; using Il2CppTMPro; using LabFusion.Data; using LabFusion.Downloading; using LabFusion.Entities; using LabFusion.Extensions; using LabFusion.Marrow; using LabFusion.Marrow.Extenders; using LabFusion.Marrow.Integration; using LabFusion.Marrow.Pool; using LabFusion.Menu.Data; using LabFusion.Network; using LabFusion.Player; using LabFusion.Preferences.Client; using LabFusion.RPC; using LabFusion.SDK.Gamemodes; using LabFusion.SDK.Metadata; using LabFusion.SDK.Modules; using LabFusion.SDK.MonoBehaviours; using LabFusion.SDK.Triggers; using LabFusion.Scene; using LabFusion.Senders; using LabFusion.UI.Popups; using LabFusion.Utilities; using LabFusion.Voice; using MelonLoader; using MelonLoader.Preferences; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("BONELAB Fusion Killer Mode")] [assembly: AssemblyFileVersion("0.3.11")] [assembly: MelonInfo(typeof(KillerModeMod), "BONELAB Fusion Killer Mode", "0.3.11", "Fusion Killer Mode Team", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonOptionalDependencies(new string[] { "LabFusion" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.11.0")] [module: UnverifiableCode] namespace FusionKillerMode; internal static class EmbeddedWavLoader { private const string ResourcePrefix = "FusionKillerMode.Assets.Audio."; public static AudioClip Load(string fileName) { try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FusionKillerMode.Assets.Audio." + fileName); if (stream == null) { return null; } using BinaryReader binaryReader = new BinaryReader(stream); if (ReadFourCc(binaryReader) != "RIFF") { return null; } binaryReader.ReadUInt32(); if (ReadFourCc(binaryReader) != "WAVE") { return null; } ushort num = 0; ushort num2 = 0; int num3 = 0; ushort num4 = 0; byte[] array = null; while (stream.Position + 8 <= stream.Length) { string text = ReadFourCc(binaryReader); uint num5 = binaryReader.ReadUInt32(); long val = stream.Position + num5 + (num5 & 1); if (text == "fmt ") { num = binaryReader.ReadUInt16(); num2 = binaryReader.ReadUInt16(); num3 = binaryReader.ReadInt32(); binaryReader.ReadUInt32(); binaryReader.ReadUInt16(); num4 = binaryReader.ReadUInt16(); } else if (text == "data") { array = binaryReader.ReadBytes(checked((int)num5)); } stream.Position = Math.Min(val, stream.Length); } if (num != 1 || num4 != 16 || num2 == 0 || num3 <= 0 || array == null) { return null; } int num6 = array.Length / 2; float[] array2 = new float[num6]; for (int i = 0; i < num6; i++) { array2[i] = (float)BitConverter.ToInt16(array, i * 2) / 32768f; } int num7 = num6 / num2; AudioClip obj = AudioClip.Create("KillerMode_" + Path.GetFileNameWithoutExtension(fileName), num7, (int)num2, num3, false); obj.SetData(Il2CppStructArray<float>.op_Implicit(array2), 0); MelonLogger.Msg($"[Killer Mode audio] Loaded {fileName} ({num2}ch, {num3} Hz, {num7} frames)."); return obj; } catch (Exception ex) { MelonLogger.Warning("[Killer Mode] Could not load embedded sound " + fileName + ": " + ex.Message); return null; } } private static string ReadFourCc(BinaryReader reader) { return new string(reader.ReadChars(4)); } } public static class KillerContentReferences { public const string DefaultCombatKnife = "c1534c5a-1fb8-477c-afbe-2a95436f6d62"; public const string BowieKnife = "BurntLettuce.BowieKnife.Spawnable.BowieKnife"; public const string GiantCleaver = "HorrorLab.GiantCleaver2.Spawnable.GiantCleaver"; public const string DeathloopMachete = "Frictic.DeathloopMachete.Spawnable.DeathloopMachete"; public const string Flashlight = "Blueberrycat.BONEWORKSFlashlight.Spawnable.FlashlightBoneworks"; public const string FlashlightBrighter = "Blueberrycat.BONEWORKSFlashlight.Spawnable.FlashlightBoneworksBrighter"; public const string PolyBlankAvatar = "c3534c5a-94b2-40a4-912a-24a8506f6c79"; public const string StrongAvatar = "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong"; public const string HeavyAvatar = "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Heavy"; public const string FastAvatar = "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Fast"; public static string GetWeaponBarcode(KillerWeaponChoice choice) { return choice switch { KillerWeaponChoice.DefaultCombatKnife => "c1534c5a-1fb8-477c-afbe-2a95436f6d62", KillerWeaponChoice.GiantCleaver => "HorrorLab.GiantCleaver2.Spawnable.GiantCleaver", KillerWeaponChoice.DeathloopMachete => "Frictic.DeathloopMachete.Spawnable.DeathloopMachete", KillerWeaponChoice.BowieKnife => "BurntLettuce.BowieKnife.Spawnable.BowieKnife", _ => string.Empty, }; } public static string GetKillerAvatarBarcode(KillerSkinChoice choice) { return choice switch { KillerSkinChoice.Strong => "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong", KillerSkinChoice.Heavy => "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Heavy", KillerSkinChoice.Fast => "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Fast", KillerSkinChoice.PolyBlank => "c3534c5a-94b2-40a4-912a-24a8506f6c79", _ => string.Empty, }; } public static bool IsInstalled(string barcode) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (string.IsNullOrWhiteSpace(barcode) || !AssetWarehouse.ready) { return false; } return CrateFilterer.HasCrate<SpawnableCrate>(new Barcode(barcode)); } public static bool IsAvatarInstalled(string barcode) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (string.IsNullOrWhiteSpace(barcode) || !AssetWarehouse.ready) { return false; } return CrateFilterer.HasCrate<AvatarCrate>(new Barcode(barcode)); } public static bool IsAnyCrateInstalled(string barcode) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (string.IsNullOrWhiteSpace(barcode) || !AssetWarehouse.ready) { return false; } return CrateFilterer.HasCrate<Crate>(new Barcode(barcode)); } } public static class KillerEnvironmentEffects { private static bool _captured; private static float _ambientIntensity; private static float _reflectionIntensity; private static Color _ambientLight; private static bool _fog; private static Color _fogColor; private static FogMode _fogMode; private static float _fogDensity; private static float _fogStartDistance; private static float _fogEndDistance; private static GameObject _overlayRoot; private static Image _overlayImage; public static void Apply(bool darkMap, int darknessStrength, bool darkFog, int fogStrength) { //IL_005d: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) Capture(); RestoreCapturedValues(); if (darkMap) { float num = Mathf.Lerp(1f, 0.08f, Mathf.Clamp01((float)darknessStrength / 100f)); RenderSettings.ambientIntensity = _ambientIntensity * num; RenderSettings.reflectionIntensity = _reflectionIntensity * Mathf.Lerp(1f, 0.18f, Mathf.Clamp01((float)darknessStrength / 100f)); RenderSettings.ambientLight = _ambientLight * num; } if (darkFog) { float num2 = Mathf.Clamp01((float)fogStrength / 100f); RenderSettings.fog = true; RenderSettings.fogMode = (FogMode)1; RenderSettings.fogColor = Color.Lerp(new Color(0.025f, 0.03f, 0.04f, 1f), Color.black, num2 * 0.75f); RenderSettings.fogStartDistance = Mathf.Lerp(15f, 2f, num2); RenderSettings.fogEndDistance = Mathf.Lerp(70f, 12f, num2); RenderSettings.fogDensity = Mathf.Max(_fogDensity, Mathf.Lerp(0.008f, 0.055f, num2)); } ApplyReliableOverlay(darkMap, darknessStrength, darkFog, fogStrength); } public static void Restore() { if (_captured) { RestoreCapturedValues(); if ((Object)(object)_overlayRoot != (Object)null) { _overlayRoot.SetActive(false); } _captured = false; } } private static void Capture() { //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_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_0045: Unknown result type (might be due to invalid IL or missing references) if (!_captured) { _captured = true; _ambientIntensity = RenderSettings.ambientIntensity; _reflectionIntensity = RenderSettings.reflectionIntensity; _ambientLight = RenderSettings.ambientLight; _fog = RenderSettings.fog; _fogColor = RenderSettings.fogColor; _fogMode = RenderSettings.fogMode; _fogDensity = RenderSettings.fogDensity; _fogStartDistance = RenderSettings.fogStartDistance; _fogEndDistance = RenderSettings.fogEndDistance; } } private static void RestoreCapturedValues() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) RenderSettings.ambientIntensity = _ambientIntensity; RenderSettings.reflectionIntensity = _reflectionIntensity; RenderSettings.ambientLight = _ambientLight; RenderSettings.fog = _fog; RenderSettings.fogColor = _fogColor; RenderSettings.fogMode = _fogMode; RenderSettings.fogDensity = _fogDensity; RenderSettings.fogStartDistance = _fogStartDistance; RenderSettings.fogEndDistance = _fogEndDistance; } private static void ApplyReliableOverlay(bool darkMap, int darknessStrength, bool darkFog, int fogStrength) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) float num = (darkMap ? (Mathf.Clamp01((float)darknessStrength / 100f) * 0.48f) : 0f); float num2 = (darkFog ? Mathf.Lerp(0.04f, 0.22f, Mathf.Clamp01((float)fogStrength / 100f)) : 0f); float num3 = 1f - (1f - num) * (1f - num2); if (!(num3 <= 0.001f) && RigData.HasPlayer) { RigRefs refs = RigData.Refs; if (!((Object)(object)((refs != null) ? refs.Headset : null) == (Object)null)) { EnsureOverlay(); _overlayRoot.SetActive(true); ((Graphic)_overlayImage).color = new Color(0.005f, 0.008f, 0.012f, Mathf.Clamp01(num3)); return; } } if ((Object)(object)_overlayRoot != (Object)null) { _overlayRoot.SetActive(false); } } private static void EnsureOverlay() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0076: 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_009e: 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_00dd: 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_00f1: 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_0132: 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_0147: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_overlayRoot != (Object)null) { _overlayRoot.transform.SetParent(RigData.Refs.Headset, false); return; } _overlayRoot = new GameObject("Killer Mode Synchronized Darkness"); ((Object)_overlayRoot).hideFlags = (HideFlags)52; _overlayRoot.transform.SetParent(RigData.Refs.Headset, false); _overlayRoot.transform.localPosition = new Vector3(0f, 0f, 0.5f); _overlayRoot.transform.localRotation = Quaternion.identity; _overlayRoot.transform.localScale = Vector3.one * 0.45f; Canvas obj = _overlayRoot.AddComponent<Canvas>(); obj.renderMode = (RenderMode)2; obj.sortingOrder = -32768; ((Component)obj).GetComponent<RectTransform>().sizeDelta = new Vector2(8f, 8f); GameObject val = new GameObject("Dark Atmosphere Panel"); val.transform.SetParent(_overlayRoot.transform, false); _overlayImage = val.AddComponent<Image>(); ((Graphic)_overlayImage).raycastTarget = false; RectTransform rectTransform = ((Graphic)_overlayImage).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; } } public static class KillerFlashEffect { private static GameObject _root; private static Image _image; private static float _remaining; private static float _duration; private static float _intensity; public static void Trigger(float duration, float intensity) { if (RigData.HasPlayer) { EnsureVisual(); _duration = Mathf.Max(0.25f, duration); _remaining = _duration; _intensity = Mathf.Clamp01(intensity); _root.SetActive(true); SetAlpha(_intensity); } } public static void Tick() { if (!((Object)(object)_root == (Object)null) && !(_remaining <= 0f)) { _remaining = Mathf.Max(0f, _remaining - Time.deltaTime); float num = ((_duration <= 0f) ? 0f : (_remaining / _duration)); SetAlpha(_intensity * num * num); if (_remaining <= 0f) { _root.SetActive(false); } } } public static void Clear() { _remaining = 0f; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _image = null; } private static void EnsureVisual() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0076: 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_009e: 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_00dd: 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_00f1: 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_0127: 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_013c: 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) if ((Object)(object)_root != (Object)null) { _root.transform.SetParent(RigData.Refs.Headset, false); return; } _root = new GameObject("Killer Mode Flashbang Whiteout"); ((Object)_root).hideFlags = (HideFlags)52; _root.transform.SetParent(RigData.Refs.Headset, false); _root.transform.localPosition = new Vector3(0f, 0f, 0.45f); _root.transform.localRotation = Quaternion.identity; _root.transform.localScale = Vector3.one * 0.45f; Canvas obj = _root.AddComponent<Canvas>(); obj.renderMode = (RenderMode)2; obj.sortingOrder = 32767; ((Component)obj).GetComponent<RectTransform>().sizeDelta = new Vector2(8f, 8f); GameObject val = new GameObject("White Panel"); val.transform.SetParent(_root.transform, false); _image = val.AddComponent<Image>(); RectTransform rectTransform = ((Graphic)_image).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; ((Graphic)_image).color = Color.white; } private static void SetAlpha(float alpha) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_image != (Object)null) { ((Graphic)_image).color = new Color(1f, 1f, 1f, Mathf.Clamp01(alpha)); } } } [RegisterTypeInIl2Cpp] public sealed class KillerFlashbangRuntime : MonoBehaviour { private GamemodeItem _item; private NetworkEntity _entity; private float _releasedTimer; private bool _detonated; public KillerFlashbangRuntime(IntPtr ptr) : base(ptr) { } [HideFromIl2Cpp] public void Initialize(NetworkEntity entity, GamemodeItem item) { _entity = entity; _item = item; } private void Update() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (_detonated || (Object)(object)_item == (Object)null || _entity == null || !_entity.IsOwner || !_item.HasBeenInteracted) { return; } if (_item.IsHeld) { _releasedTimer = 0f; return; } _releasedTimer += Time.deltaTime; if (!(_releasedTimer < 1.2f)) { _detonated = true; KillerModeGamemode.RequestFlashbangDetonation(((Component)this).transform.position); } } } public static class KillerModeAudio { private const int SampleRate = 44100; private static AudioClip _roundStart; private static AudioClip _roundEnd; private static AudioClip _lastSurvivor; private static AudioClip _countdownTick; private static AudioClip _heartbeatSlow; private static AudioClip _heartbeatFast; private static AudioSource _heartbeatSource; private static AudioSource _oneShotSource; private static bool _heartbeatIsFast; public static void PlayRoundStart() { Play(_roundStart ?? (_roundStart = Load("round_start.wav", CreateRoundStart)), 0.72f); } public static void PlayCountdownTick(int remaining) { remaining = Mathf.Clamp(remaining, 1, 10); Play(_countdownTick ?? (_countdownTick = Load("countdown_tick.wav", () => CreateCountdownTick(remaining))), (remaining <= 3) ? 0.82f : 0.58f); } public static void PlayLastSurvivor() { Play(_lastSurvivor ?? (_lastSurvivor = Load("last_survivor.wav", CreateLastSurvivor)), 0.64f); } public static void PlayRoundEnd(bool survivorsWin) { Play(_roundEnd ?? (_roundEnd = Load("round_end.wav", () => CreateRoundEnd(survivorsWin))), 0.76f); } public static void SetHeartbeat(bool enabled, bool fast) { if (!enabled) { StopHeartbeat(); return; } AudioClip val = (fast ? (_heartbeatFast ?? (_heartbeatFast = Load("heartbeat_fast.wav", () => CreateHeartbeat(fast: true)))) : (_heartbeatSlow ?? (_heartbeatSlow = Load("heartbeat_slow.wav", () => CreateHeartbeat(fast: false))))); if (!((Object)(object)val == (Object)null)) { EnsureHeartbeatSource(); if ((Object)(object)_heartbeatSource.clip != (Object)(object)val || _heartbeatIsFast != fast) { _heartbeatSource.Stop(); _heartbeatSource.clip = val; _heartbeatIsFast = fast; } _heartbeatSource.volume = (fast ? 0.34f : 0.27f); if (!_heartbeatSource.isPlaying) { _heartbeatSource.Play(); } } } public static void StopHeartbeat() { if (!((Object)(object)_heartbeatSource == (Object)null)) { _heartbeatSource.Stop(); _heartbeatSource.clip = null; } } private static void Play(AudioClip clip, float volume) { if (!((Object)(object)clip == (Object)null)) { EnsureOneShotSource(); _oneShotSource.PlayOneShot(clip, Mathf.Clamp01(volume)); MelonLogger.Msg("[Killer Mode audio] Playing " + ((Object)clip).name + "."); } } private static AudioClip Load(string fileName, Func<AudioClip> fallback) { return EmbeddedWavLoader.Load(fileName) ?? fallback(); } private static void EnsureHeartbeatSource() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_heartbeatSource != (Object)null)) { GameObject val = new GameObject("KillerMode_LastSurvivorHeartbeat"); Object.DontDestroyOnLoad((Object)val); _heartbeatSource = val.AddComponent<AudioSource>(); _heartbeatSource.playOnAwake = false; _heartbeatSource.loop = true; _heartbeatSource.spatialBlend = 0f; _heartbeatSource.bypassReverbZones = true; _heartbeatSource.outputAudioMixerGroup = LocalAudioPlayer.InHead; } } private static void EnsureOneShotSource() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_oneShotSource != (Object)null)) { GameObject val = new GameObject("KillerMode_OneShotAudio"); Object.DontDestroyOnLoad((Object)val); _oneShotSource = val.AddComponent<AudioSource>(); _oneShotSource.playOnAwake = false; _oneShotSource.loop = false; _oneShotSource.spatialBlend = 0f; _oneShotSource.bypassReverbZones = true; _oneShotSource.outputAudioMixerGroup = LocalAudioPlayer.InHead; } } private static AudioClip CreateRoundStart() { return Create("KillerMode_RoundStart", 1.25f, delegate(float time, Random random) { float num = Mathf.Sin((float)Math.PI * 2f * (58f + 34f * time) * time) * Mathf.Exp(-3.4f * time); float num2 = Mathf.Sin((float)Math.PI * 2f * (310f + 520f * time) * time) * Mathf.Exp(-4.5f * time); float num3 = ((float)random.NextDouble() * 2f - 1f) * Mathf.Exp(-8f * time); return 0.62f * num + 0.18f * num2 + 0.1f * num3; }); } private static AudioClip CreateCountdownTick(int remaining) { float frequency = 520f + (float)(10 - remaining) * 38f; return Create($"KillerMode_Countdown_{remaining}", 0.16f, (float time, Random _) => Mathf.Exp(-24f * time) * (0.72f * Mathf.Sin((float)Math.PI * 2f * frequency * time) + 0.18f * Mathf.Sin((float)Math.PI * 2f * frequency * 2.01f * time))); } private static AudioClip CreateLastSurvivor() { return Create("KillerMode_LastSurvivor", 2.35f, delegate(float time, Random random) { float num = Mathf.Clamp01(time * 3f); float num2 = Mathf.Clamp01((2.35f - time) * 1.2f); float num3 = num * num2; float num4 = Mathf.Sin((float)Math.PI * 108f * time) + 0.7f * Mathf.Sin((float)Math.PI * 115f * time); float num5 = Mathf.Sin((float)Math.PI * 2f * (1.7f + time * 0.5f) * time); float num6 = ((float)random.NextDouble() * 2f - 1f) * 0.08f; return num3 * (0.3f * num4 * (0.75f + 0.25f * num5) + num6); }); } private static AudioClip CreateRoundEnd(bool survivorsWin) { return Create(survivorsWin ? "KillerMode_SurvivorsWin" : "KillerMode_KillerWins", 1.8f, delegate(float time, Random random) { float num = (survivorsWin ? 1f : (-1f)); float num2 = 150f + num * 42f * time; float num3 = Mathf.Clamp01(time * 8f) * Mathf.Clamp01((1.8f - time) * 1.5f); float num4 = Mathf.Sin((float)Math.PI * 2f * num2 * time) + 0.42f * Mathf.Sin((float)Math.PI * 2f * num2 * 1.5f * time); float num5 = Mathf.Sin((float)Math.PI * 108f * time) * Mathf.Exp(-5f * time); float num6 = ((float)random.NextDouble() * 2f - 1f) * Mathf.Exp(-7f * time); return num3 * 0.28f * num4 + 0.48f * num5 + 0.06f * num6; }); } private static AudioClip CreateHeartbeat(bool fast) { float seconds = (fast ? 0.82f : 1.45f); return Create(fast ? "KillerMode_HeartbeatFast" : "KillerMode_HeartbeatSlow", seconds, delegate(float time, Random _) { float num = Mathf.Exp(-42f * time) * Mathf.Sin((float)Math.PI * 116f * time); float num2 = Mathf.Max(0f, time - (fast ? 0.22f : 0.34f)); float num3 = Mathf.Exp(-48f * num2) * Mathf.Sin((float)Math.PI * 104f * num2); return 0.72f * num + 0.54f * num3; }); } private static AudioClip Create(string name, float seconds, Func<float, Random, float> sample) { int num = Mathf.CeilToInt(seconds * 44100f); float[] array = new float[num]; Random arg = new Random(name.GetHashCode()); for (int i = 0; i < num; i++) { array[i] = Mathf.Clamp(sample((float)i / 44100f, arg), -0.95f, 0.95f); } AudioClip obj = AudioClip.Create(name, num, 1, 44100, false); obj.SetData(Il2CppStructArray<float>.op_Implicit(array), 0); return obj; } } public static class KillerModeBranding { private const string LogoResource = "FusionKillerMode.Assets.KillerModeLogo.png"; private static Texture2D _logo; public static Texture Logo { get { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown if ((Object)(object)_logo != (Object)null) { return (Texture)(object)_logo; } try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FusionKillerMode.Assets.KillerModeLogo.png"); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } _logo = new Texture2D(2, 2, (TextureFormat)4, false) { name = "Killer Mode Logo", wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; ImageConversion.LoadImage(_logo, Il2CppStructArray<byte>.op_Implicit(array)); } catch (Exception ex) { MelonLogger.Warning("[Killer Mode] Could not load the embedded logo: " + ex.Message); } return (Texture)(object)_logo; } } } public static class KillerModeHud { private static GameObject _root; private static TextMeshProUGUI _text; private static Image _background; private static string _lastText; private static Color _lastColor; public static void Update(KillerRoundState state, int remainingSeconds, KillerPlayerState localRole, bool enabled) { //IL_00ae: 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_0110: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0131: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if (!enabled || state == KillerRoundState.Lobby || state == KillerRoundState.Ending) { SetVisible(visible: false); } else if (EnsureCreated()) { object obj = state switch { KillerRoundState.Preparing => "ROUND STARTING", KillerRoundState.SurvivorHeadStart => (localRole != KillerPlayerState.Killer) ? "HEAD START" : "SURVIVORS HIDING", KillerRoundState.ExitOpen => "EXIT OPEN • ROUND TIME", _ => "ROUND TIME", }; string text = ((state == KillerRoundState.Preparing) ? Math.Max(0, remainingSeconds).ToString() : FormatTime(remainingSeconds)); string text2 = (string?)obj + " • " + text; Color val = (Color)(state switch { KillerRoundState.Preparing => new Color(1f, 0.78f, 0.18f, 1f), KillerRoundState.ExitOpen => new Color(0.3f, 1f, 0.45f, 1f), _ => (localRole != KillerPlayerState.Killer) ? new Color(0.4f, 1f, 0.55f, 1f) : new Color(1f, 0.3f, 0.3f, 1f), }); if (_lastText != text2) { _lastText = text2; ((TMP_Text)_text).text = text2; } if (_lastColor != val) { _lastColor = val; ((Graphic)_text).color = val; } SetVisible(visible: true); } } public static void Destroy() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _text = null; _background = null; _lastText = null; _lastColor = default(Color); } private static bool EnsureCreated() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_009b: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null && (Object)(object)_text != (Object)null) { return true; } if (RigData.HasPlayer) { RigRefs refs = RigData.Refs; if (!((Object)(object)((refs != null) ? refs.Headset : null) == (Object)null)) { _root = new GameObject("KillerMode_RoundTimerHUD"); Canvas obj = _root.AddComponent<Canvas>(); obj.renderMode = (RenderMode)2; obj.overrideSorting = true; obj.sortingOrder = 32760; Transform transform = _root.transform; transform.SetParent(RigData.Refs.Headset, false); transform.localPosition = new Vector3(0f, -0.19f, 0.58f); transform.localRotation = Quaternion.identity; transform.localScale = Vector3.one * 0.00065f; RectTransform component = _root.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(500f, 58f); } GameObject val = new GameObject("Background"); val.transform.SetParent(transform, false); _background = val.AddComponent<Image>(); ((Graphic)_background).color = new Color(0.015f, 0.015f, 0.02f, 0.72f); ((Graphic)_background).raycastTarget = false; Stretch(val.GetComponent<RectTransform>()); GameObject val2 = new GameObject("Time"); val2.transform.SetParent(transform, false); _text = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_text).alignment = (TextAlignmentOptions)514; ((TMP_Text)_text).fontSize = 27f; ((TMP_Text)_text).fontStyle = (FontStyles)1; ((TMP_Text)_text).enableWordWrapping = false; ((Graphic)_text).raycastTarget = false; ((TMP_Text)_text).outlineWidth = 0.16f; ((TMP_Text)_text).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)230); Stretch(val2.GetComponent<RectTransform>()); return true; } } return false; } private static void Stretch(RectTransform rect) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0040: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null)) { rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = new Vector2(12f, 4f); rect.offsetMax = new Vector2(-12f, -4f); } } private static void SetVisible(bool visible) { if ((Object)(object)_root != (Object)null && _root.activeSelf != visible) { _root.SetActive(visible); } } private static string FormatTime(int totalSeconds) { totalSeconds = Math.Max(0, totalSeconds); return $"{totalSeconds / 60:00}:{totalSeconds % 60:00}"; } } public static class KillerModePreferences { private static MelonPreferences_Category _category; private static MelonPreferences_Entry<string> _settingsJson; public static KillerModeSettings Current { get; private set; } = new KillerModeSettings(); public static void Initialize() { _category = MelonPreferences.CreateCategory("BONELAB Fusion Killer Mode"); _settingsJson = _category.CreateEntry<string>("HostSettings", string.Empty, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); if (!string.IsNullOrWhiteSpace(_settingsJson.Value)) { try { Current = JsonSerializer.Deserialize<KillerModeSettings>(_settingsJson.Value) ?? new KillerModeSettings(); } catch (Exception ex) { MelonLogger.Warning("[Killer Mode] Could not load saved host settings: " + ex.Message); Current = new KillerModeSettings(); } } } public static void Save(KillerModeSettings settings) { Current.CopyFrom(settings); _settingsJson.Value = JsonSerializer.Serialize(Current); _category.SaveToFile(false); } } public sealed class KillerModeSettings { public int MinimumPlayers { get; set; } = 2; public int StartCountdownSeconds { get; set; } = 10; public int RoundSeconds { get; set; } = 600; public int HeadStartSeconds { get; set; } = 30; public int ExitOpenTimeRemaining { get; set; } = 60; public float KillerVitality { get; set; } = 3f; public float SurvivorVitality { get; set; } = 1f; public float KillerSpeedMultiplier { get; set; } = 1.1f; public float SurvivorSpeedMultiplier { get; set; } = 1f; public bool KillerCanDie { get; set; } public bool SurvivorsCanDamageKiller { get; set; } public bool PreventSameKillerTwice { get; set; } = true; public bool LastSurvivorRevealEnabled { get; set; } = true; public int LastSurvivorRevealInterval { get; set; } = 10; public int LastSurvivorRevealDuration { get; set; } = 2; public bool ClearStartingInventory { get; set; } = true; public bool GiveSurvivorsWeapon { get; set; } public bool SpawnSurvivorFlashlights { get; set; } = true; public bool EnableModeSounds { get; set; } = true; public bool ShowRoundTimer { get; set; } = true; public bool DarkMapEnabled { get; set; } public int DarknessStrength { get; set; } = 70; public bool DarkFogEnabled { get; set; } public int FogStrength { get; set; } = 35; public bool FlashbangBrightEffect { get; set; } = true; public float FlashbangRadius { get; set; } = 18f; public float FlashbangDuration { get; set; } = 3f; public bool GiveSurvivorsFlashbangs { get; set; } public KillerMapModeOverride MapModeOverride { get; set; } public KillerGameplayPreset GameplayPreset { get; set; } public KillerSelectionMode SelectionMode { get; set; } public KillerWeaponChoice WeaponChoice { get; set; } = KillerWeaponChoice.GiantCleaver; public KillerSkinChoice SkinChoice { get; set; } public string KillerAvatarBarcode { get; set; } = string.Empty; public string CustomKillerWeaponBarcode { get; set; } = string.Empty; public string SurvivorWeaponBarcode { get; set; } = string.Empty; public string FlashlightBarcode { get; set; } = "Blueberrycat.BONEWORKSFlashlight.Spawnable.FlashlightBoneworks"; public string FlashbangBarcode { get; set; } = string.Empty; public void CopyFrom(KillerModeSettings other) { if (other != null) { MinimumPlayers = other.MinimumPlayers; StartCountdownSeconds = other.StartCountdownSeconds; RoundSeconds = other.RoundSeconds; HeadStartSeconds = other.HeadStartSeconds; ExitOpenTimeRemaining = other.ExitOpenTimeRemaining; KillerVitality = other.KillerVitality; SurvivorVitality = other.SurvivorVitality; KillerSpeedMultiplier = other.KillerSpeedMultiplier; SurvivorSpeedMultiplier = other.SurvivorSpeedMultiplier; KillerCanDie = other.KillerCanDie; SurvivorsCanDamageKiller = other.SurvivorsCanDamageKiller; PreventSameKillerTwice = other.PreventSameKillerTwice; LastSurvivorRevealEnabled = other.LastSurvivorRevealEnabled; LastSurvivorRevealInterval = other.LastSurvivorRevealInterval; LastSurvivorRevealDuration = other.LastSurvivorRevealDuration; ClearStartingInventory = other.ClearStartingInventory; GiveSurvivorsWeapon = other.GiveSurvivorsWeapon; SpawnSurvivorFlashlights = other.SpawnSurvivorFlashlights; EnableModeSounds = other.EnableModeSounds; ShowRoundTimer = other.ShowRoundTimer; DarkMapEnabled = other.DarkMapEnabled; DarknessStrength = other.DarknessStrength; DarkFogEnabled = other.DarkFogEnabled; FogStrength = other.FogStrength; FlashbangBrightEffect = other.FlashbangBrightEffect; FlashbangRadius = other.FlashbangRadius; FlashbangDuration = other.FlashbangDuration; GiveSurvivorsFlashbangs = other.GiveSurvivorsFlashbangs; MapModeOverride = other.MapModeOverride; GameplayPreset = other.GameplayPreset; SelectionMode = other.SelectionMode; WeaponChoice = other.WeaponChoice; SkinChoice = other.SkinChoice; KillerAvatarBarcode = other.KillerAvatarBarcode ?? string.Empty; CustomKillerWeaponBarcode = other.CustomKillerWeaponBarcode ?? string.Empty; SurvivorWeaponBarcode = other.SurvivorWeaponBarcode ?? string.Empty; FlashlightBarcode = (string.IsNullOrWhiteSpace(other.FlashlightBarcode) ? "Blueberrycat.BONEWORKSFlashlight.Spawnable.FlashlightBoneworks" : other.FlashlightBarcode); FlashbangBarcode = other.FlashbangBarcode ?? string.Empty; } } public void ApplyPreset(KillerGameplayPreset preset) { GameplayPreset = preset; switch (preset) { case KillerGameplayPreset.Classic: RoundSeconds = 600; HeadStartSeconds = 30; KillerVitality = 3f; SurvivorVitality = 1f; KillerSpeedMultiplier = 1.1f; SurvivorSpeedMultiplier = 1f; KillerCanDie = false; SurvivorsCanDamageKiller = false; LastSurvivorRevealEnabled = true; DarkMapEnabled = false; DarkFogEnabled = false; break; case KillerGameplayPreset.Casual: RoundSeconds = 720; HeadStartSeconds = 45; KillerVitality = 2f; SurvivorVitality = 1.25f; KillerSpeedMultiplier = 1.02f; SurvivorSpeedMultiplier = 1.05f; KillerCanDie = true; SurvivorsCanDamageKiller = true; LastSurvivorRevealEnabled = false; DarkMapEnabled = false; DarkFogEnabled = false; break; case KillerGameplayPreset.Hardcore: RoundSeconds = 480; HeadStartSeconds = 20; KillerVitality = 5f; SurvivorVitality = 0.8f; KillerSpeedMultiplier = 1.2f; SurvivorSpeedMultiplier = 0.95f; KillerCanDie = false; SurvivorsCanDamageKiller = false; LastSurvivorRevealEnabled = true; DarkMapEnabled = true; DarknessStrength = 78; DarkFogEnabled = true; FogStrength = 32; break; } } } public enum KillerRoundState { Lobby, Preparing, SurvivorHeadStart, Hunt, ExitOpen, Ending } public enum KillerPlayerState { None, Killer, SurvivorAlive, SurvivorEliminated, SurvivorEscaped, Spectator, Disconnected } public enum KillerMapMode { Survival, Escape } public enum KillerMapModeOverride { Auto, Survival, Escape } public enum KillerSelectionMode { Random, Host, Rotation } public enum SoloTestRole { Killer, Survivor } public enum KillerWeaponChoice { MapDefined, DefaultCombatKnife, GiantCleaver, DeathloopMachete, BowieKnife, CustomBarcode, Random } public enum KillerGameplayPreset { Custom, Classic, Casual, Hardcore } public enum KillerSkinChoice { PlayerAvatar, SelectedDownloadedAvatar, Strong, Heavy, Fast, PolyBlank } public enum KillerSpawnRole { Lobby, Killer, Survivor, Spectator } public enum KillerItemAudience { Everyone, KillerOnly, SurvivorsOnly } public enum KillerDoorRule { LockedUntilHunt, LockedUntilExitOpen, AlwaysUnlocked } public enum KillerDoorAnimation { None, SlideUp, Swing } public enum KillerWinReason { None, KillerEliminatedSurvivors, SurvivorsOutlastedTimer, SurvivorEscaped, KillerDisconnected, KillerDied, NotEnoughPlayers, SoloTestComplete } public static class KillerRoundRules { public static bool IsSpectator(KillerPlayerState state) { if (state != KillerPlayerState.Spectator && state != KillerPlayerState.SurvivorEliminated) { return state == KillerPlayerState.SurvivorEscaped; } return true; } public static bool CanHearVoice(KillerPlayerState listener, KillerPlayerState speaker) { bool num = listener == KillerPlayerState.Killer || listener == KillerPlayerState.SurvivorAlive; bool flag = speaker == KillerPlayerState.Killer || speaker == KillerPlayerState.SurvivorAlive; bool flag2 = IsSpectator(listener); bool flag3 = IsSpectator(speaker); if (!(num && flag)) { return flag2 && flag3; } return true; } public static bool CanAttack(KillerPlayerState attacker, KillerPlayerState target, KillerRoundState round, bool survivorsCanDamageKiller) { if (round != KillerRoundState.Hunt && round != KillerRoundState.ExitOpen) { return false; } switch (attacker) { case KillerPlayerState.Killer: return target == KillerPlayerState.SurvivorAlive; case KillerPlayerState.SurvivorAlive: if (survivorsCanDamageKiller) { return target == KillerPlayerState.Killer; } return false; default: return false; } } public static bool ShouldOpenExit(KillerMapMode mode, KillerRoundState state, int remainingSeconds, int openTimeRemaining) { if (mode != KillerMapMode.Escape || state == KillerRoundState.ExitOpen) { return false; } return remainingSeconds <= Math.Max(0, openTimeRemaining); } public static KillerWinReason TimerExpired(KillerMapMode mode, bool anyEscaped) { if (mode != KillerMapMode.Survival) { if (!anyEscaped) { return KillerWinReason.KillerEliminatedSurvivors; } return KillerWinReason.SurvivorEscaped; } return KillerWinReason.SurvivorsOutlastedTimer; } public static bool ShouldEndForNoLivingSurvivors(bool soloTest, int livingSurvivors) { if (!soloTest) { return livingSurvivors <= 0; } return false; } public static bool CanStartRoundNow(bool isHost, bool roundStarted, bool requirementsMet) { return isHost && !roundStarted && requirementsMet; } public static bool ShouldDeferAutomaticPause(bool roundStarted) { return roundStarted; } public static bool ShouldWaitForSelectedAvatarBarcode(bool isKiller, KillerSkinChoice choice, string barcode) { if (isKiller && choice == KillerSkinChoice.SelectedDownloadedAvatar) { return string.IsNullOrWhiteSpace(barcode); } return false; } } public class KillerModeGamemode : Gamemode { private sealed class SpawnedRoundItem { public ushort EntityId; public GameObject GameObject; public bool DestroyOnRoundEnd; public KillerItemSpawnPoint Source; } private sealed class ItemSpawnerState { public KillerItemSpawnPoint Point; public GamemodeItem CurrentItem; public float Cooldown; public int Uses; } private const string InGameMapSetupMetadataKey = "InGameMapSetupProfile"; public readonly KillerModeSettings Settings = new KillerModeSettings(); private readonly TeamManager _teams = new TeamManager(); private readonly Team _killerTeam = new Team("Killer"); private readonly Team _survivorTeam = new Team("Survivors"); private readonly Team _spectatorTeam = new Team("Spectators"); private readonly MetadataPlayerDictionary<MetadataInt> _playerStates = new MetadataPlayerDictionary<MetadataInt>(); private readonly Dictionary<ulong, KillerPlayerState> _hostPlayerStates = new Dictionary<ulong, KillerPlayerState>(); private MetadataInt _roundState; private MetadataInt _remainingSeconds; private MetadataInt _winReason; private MetadataInt _effectiveMapMode; private MetadataInt _effectiveKillerVitality; private MetadataInt _effectiveSurvivorVitality; private MetadataInt _effectiveKillerSpeed; private MetadataInt _effectiveSurvivorSpeed; private MetadataBool _effectiveKillerCanDie; private MetadataBool _effectiveSurvivorDamage; private MetadataBool _effectiveClearStartingInventory; private MetadataBool _effectiveModeSounds; private MetadataBool _effectiveShowRoundTimer; private MetadataInt _effectiveWeapon; private MetadataInt _effectiveSkin; private MetadataVariable _effectiveSkinBarcode; private MetadataBool _effectiveRevealEnabled; private MetadataInt _effectiveRevealInterval; private MetadataInt _effectiveRevealDuration; private MetadataVariable _effectiveWeaponBarcode; private MetadataVariable _effectiveFlashlightBarcode; private MetadataVariable _effectiveFlashbangBarcode; private MetadataBool _effectiveDarkMap; private MetadataInt _effectiveDarknessStrength; private MetadataBool _effectiveDarkFog; private MetadataInt _effectiveFogStrength; private MetadataBool _effectiveFlashbangEffect; private MetadataInt _effectiveFlashbangRadius; private MetadataInt _effectiveFlashbangDuration; private TriggerEvent _escapeRequest; private TriggerEvent _lastSurvivorEvent; private TriggerEvent _timeExpiredEvent; private TriggerEvent _flashbangRequestEvent; private TriggerEvent _flashbangDetonationEvent; private float _hostTimer; private float _endingTimer; private float _weaponRecoveryCooldown; private float _soloLastSurvivorTriggerDelay; private float _flashbangRequestCooldown; private int _lastPublishedSecond = -1; private ulong _killerPlatformId; private byte _previousKillerSmallId = byte.MaxValue; private bool _ending; private bool _spawnedItems; private bool _killerWeaponSpawned; private bool _localInventoryCleared; private bool _localRoundStartSoundPlayed; private bool _localRoundEndSoundPlayed; private bool _localRoleMessageShown; private bool _localLastSurvivorHeartbeatActive; private bool _localAvatarLockApplied; private bool _localKillerSkinFallbackNotified; private string _localRoundAvatarBarcode; private bool _killerAvatarDownloadPending; private string _pendingKillerAvatarBarcode; private string _failedKillerAvatarBarcode; private int _lastLocalStartCountdownSecond = -1; private int _lastLocalCountdownSecond = -1; private bool _showInGameSetupMarkers = true; private bool _inGameSetupEditing; private bool _automaticRoundsPaused; private bool _pauseAutomaticRoundsAfterCurrentRound; private bool _localEscapeRequested; private float _localEscapeRetry; private float _environmentRefreshTimer; private float _revealCycle; private float _revealVisible; private byte? _revealedPlayerId; private Texture2D _revealTexture; private float? _baseAvatarSpeed; private float? _baseAvatarAgility; private string _roundWeaponBarcode; private string _roundFlashlightBarcode = "Blueberrycat.BONEWORKSFlashlight.Spawnable.FlashlightBoneworks"; private string _roundFlashbangBarcode = string.Empty; private bool _roundModeSoundsEnabled; private bool _roundClearStartingInventory; private readonly List<SpawnedRoundItem> _spawnedRoundItems = new List<SpawnedRoundItem>(); private readonly Dictionary<KillerItemSpawnPoint, ItemSpawnerState> _itemSpawnerStates = new Dictionary<KillerItemSpawnPoint, ItemSpawnerState>(); public override string Title => "Killer Mode"; public override string Author => "Fusion Killer Mode Team"; public override string Barcode => "FusionKillerMode.Gamemode.KillerMode"; public override string Description => "One killer hunts the survivors. Outlast the timer, or escape if the map has an exit."; public override Texture Logo => KillerModeBranding.Logo; public override bool DisableDevTools => true; public override bool DisableSpawnGun => true; public override bool DisableManualUnragdoll => true; public override bool AutoStopOnSceneLoad => true; protected virtual bool IsSoloTest => false; protected virtual bool FlashbangFeatureEnabled => IsSoloTest; protected virtual bool SavePreferencesOnStart => true; protected virtual KillerPlayerState SoloPlayerState => KillerPlayerState.Killer; private KillerRoundState RoundState => (KillerRoundState)((MetadataVariableT<int>)(object)_roundState).GetValue(); private KillerMapMode EffectiveMapMode => (KillerMapMode)((MetadataVariableT<int>)(object)_effectiveMapMode).GetValue(); protected virtual string ResolveKillerWeaponBarcode() { if (Settings.WeaponChoice == KillerWeaponChoice.MapDefined) { return (from point in KillerMapRegistry.ItemSpawns.OfType<KillerWeaponSpawn>() where (Object)(object)point != (Object)null && ((Behaviour)point).isActiveAndEnabled select point.SpawnableBarcode).FirstOrDefault((string barcode) => !string.IsNullOrWhiteSpace(barcode)) ?? string.Empty; } if (Settings.WeaponChoice == KillerWeaponChoice.CustomBarcode) { return Settings.CustomKillerWeaponBarcode?.Trim() ?? string.Empty; } if (Settings.WeaponChoice == KillerWeaponChoice.Random) { string[] array = new string[5] { "c1534c5a-1fb8-477c-afbe-2a95436f6d62", "HorrorLab.GiantCleaver2.Spawnable.GiantCleaver", "Frictic.DeathloopMachete.Spawnable.DeathloopMachete", "BurntLettuce.BowieKnife.Spawnable.BowieKnife", Settings.CustomKillerWeaponBarcode?.Trim() }.Where(KillerContentReferences.IsInstalled).ToArray(); if (array.Length != 0) { return array[Random.Range(0, array.Length)]; } return "c1534c5a-1fb8-477c-afbe-2a95436f6d62"; } return KillerContentReferences.GetWeaponBarcode(Settings.WeaponChoice); } public KillerModeGamemode() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Settings.CopyFrom(KillerModePreferences.Current); } public override GroupElementData CreateSettingsGroup() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_010c: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_002b: 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_0040: Expected O, but got Unknown //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Expected O, but got Unknown //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Expected O, but got Unknown //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Expected O, but got Unknown //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Expected O, but got Unknown //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Expected O, but got Unknown //IL_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Expected O, but got Unknown //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04f1: Unknown result type (might be due to invalid IL or missing references) //IL_0501: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Expected O, but got Unknown //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0556: Expected O, but got Unknown //IL_0705: Unknown result type (might be due to invalid IL or missing references) //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_0715: Unknown result type (might be due to invalid IL or missing references) //IL_072c: Expected O, but got Unknown //IL_077b: Unknown result type (might be due to invalid IL or missing references) //IL_0780: Unknown result type (might be due to invalid IL or missing references) //IL_078b: Unknown result type (might be due to invalid IL or missing references) //IL_07a2: Expected O, but got Unknown //IL_09cc: Unknown result type (might be due to invalid IL or missing references) //IL_09d1: Unknown result type (might be due to invalid IL or missing references) //IL_09dc: Unknown result type (might be due to invalid IL or missing references) //IL_09f3: Expected O, but got Unknown //IL_09f5: Unknown result type (might be due to invalid IL or missing references) //IL_09fa: Unknown result type (might be due to invalid IL or missing references) //IL_0a05: Unknown result type (might be due to invalid IL or missing references) //IL_0a1c: Expected O, but got Unknown //IL_0a1e: Unknown result type (might be due to invalid IL or missing references) //IL_0a23: Unknown result type (might be due to invalid IL or missing references) //IL_0a2e: Unknown result type (might be due to invalid IL or missing references) //IL_0a45: Expected O, but got Unknown //IL_0a8d: Unknown result type (might be due to invalid IL or missing references) //IL_0a92: Unknown result type (might be due to invalid IL or missing references) //IL_0a9d: Unknown result type (might be due to invalid IL or missing references) //IL_0ab4: Expected O, but got Unknown //IL_0ab6: Unknown result type (might be due to invalid IL or missing references) //IL_0abb: Unknown result type (might be due to invalid IL or missing references) //IL_0ac6: Unknown result type (might be due to invalid IL or missing references) //IL_0add: Expected O, but got Unknown //IL_0adf: Unknown result type (might be due to invalid IL or missing references) //IL_0ae4: Unknown result type (might be due to invalid IL or missing references) //IL_0aef: Unknown result type (might be due to invalid IL or missing references) //IL_0b06: Expected O, but got Unknown //IL_07fc: Unknown result type (might be due to invalid IL or missing references) //IL_0801: Unknown result type (might be due to invalid IL or missing references) //IL_080c: Unknown result type (might be due to invalid IL or missing references) //IL_0823: Expected O, but got Unknown //IL_08b5: Unknown result type (might be due to invalid IL or missing references) //IL_08ba: Unknown result type (might be due to invalid IL or missing references) //IL_08c5: Unknown result type (might be due to invalid IL or missing references) //IL_08dc: Expected O, but got Unknown GroupElementData val = ((Gamemode)this).CreateSettingsGroup(); if (!IsSoloTest && NetworkInfo.HasServer && !NetworkInfo.IsHost) { GroupElementData val2 = new GroupElementData("Host settings"); val2.AddElement<LabelElementData>(new LabelElementData { Title = "Only the Fusion host can configure Killer Mode or control rounds." }); val.AddElement<GroupElementData>(val2); return val; } GroupElementData val3 = new GroupElementData("Host controls"); GroupElementData val4 = new GroupElementData("Round"); GroupElementData val5 = new GroupElementData("Roles and equipment"); GroupElementData val6 = new GroupElementData("Presets and atmosphere"); GroupElementData val7 = new GroupElementData("In-game map setup"); if (!IsSoloTest) { val.AddElement<GroupElementData>(val3); } val.AddElement<GroupElementData>(val4); val.AddElement<GroupElementData>(val5); val.AddElement<GroupElementData>(val6); val.AddElement<GroupElementData>(val7); if (!IsSoloTest) { val3.AddElement<FunctionElementData>(new FunctionElementData { Title = "START ROUND NOW", OnPressed = StartRoundNow }); val3.AddElement<FunctionElementData>(new FunctionElementData { Title = "PAUSE AUTO-START AFTER THIS ROUND", OnPressed = PauseAutomaticRounds }); val3.AddElement<FunctionElementData>(new FunctionElementData { Title = "RESUME AUTOMATIC ROUNDS", OnPressed = ResumeAutomaticRounds }); val3.AddElement<LabelElementData>(new LabelElementData { Title = "Start never interrupts an active round. Pause lets the current round finish first." }); } val6.AddElement<EnumElementData>(new EnumElementData { Title = "Gameplay Preset", EnumType = typeof(KillerGameplayPreset), Value = Settings.GameplayPreset, OnValueChanged = delegate(Enum value) { ApplyGameplayPreset((KillerGameplayPreset)(object)value); } }); val6.AddElement<FunctionElementData>(new FunctionElementData { Title = "APPLY MAP RECOMMENDATIONS", OnPressed = ApplyMapRecommendations }); val6.AddElement<BoolElementData>(BoolSetting("Make Map Darker", Settings.DarkMapEnabled, delegate(bool v) { Settings.DarkMapEnabled = v; SyncEnvironmentSettingsIfStarted(); })); val6.AddElement<IntElementData>(IntSetting("Darkness Strength", Settings.DarknessStrength, 0, 100, delegate(int v) { Settings.DarknessStrength = v; SyncEnvironmentSettingsIfStarted(); }, 5)); val6.AddElement<BoolElementData>(BoolSetting("Dark Fog", Settings.DarkFogEnabled, delegate(bool v) { Settings.DarkFogEnabled = v; SyncEnvironmentSettingsIfStarted(); })); val6.AddElement<IntElementData>(IntSetting("Fog Strength", Settings.FogStrength, 0, 100, delegate(int v) { Settings.FogStrength = v; SyncEnvironmentSettingsIfStarted(); }, 5)); val4.AddElement<IntElementData>(IntSetting("Minimum Players", Settings.MinimumPlayers, IsSoloTest ? 1 : 2, 32, delegate(int v) { Settings.MinimumPlayers = v; })); val4.AddElement<IntElementData>(IntSetting("Start Countdown", Settings.StartCountdownSeconds, 3, 30, delegate(int v) { Settings.StartCountdownSeconds = v; })); val4.AddElement<IntElementData>(IntSetting("Round Seconds", Settings.RoundSeconds, 60, 3600, delegate(int v) { Settings.RoundSeconds = v; }, 30)); val4.AddElement<IntElementData>(IntSetting("Killer Head Start", Settings.HeadStartSeconds, 0, 180, delegate(int v) { Settings.HeadStartSeconds = v; }, 5)); val4.AddElement<IntElementData>(IntSetting("Exit Opens With Time Left", Settings.ExitOpenTimeRemaining, 0, 600, delegate(int v) { Settings.ExitOpenTimeRemaining = v; }, 15)); val4.AddElement<FunctionElementData>(new FunctionElementData { Title = "STOP KILLER MODE (STAY STOPPED)", OnPressed = StopKillerModeManually }); val4.AddElement<EnumElementData>(new EnumElementData { Title = "Map Mode", EnumType = typeof(KillerMapModeOverride), Value = Settings.MapModeOverride, OnValueChanged = delegate(Enum v) { Settings.MapModeOverride = (KillerMapModeOverride)(object)v; } }); val5.AddElement<EnumElementData>(new EnumElementData { Title = "Killer Selection", EnumType = typeof(KillerSelectionMode), Value = Settings.SelectionMode, OnValueChanged = delegate(Enum v) { Settings.SelectionMode = (KillerSelectionMode)(object)v; } }); val5.AddElement<EnumElementData>(new EnumElementData { Title = "Killer Weapon", EnumType = typeof(KillerWeaponChoice), Value = Settings.WeaponChoice, OnValueChanged = delegate(Enum v) { Settings.WeaponChoice = (KillerWeaponChoice)(object)v; } }); val5.AddElement<StringElementData>(StringSetting("Custom Killer Weapon Barcode", Settings.CustomKillerWeaponBarcode, delegate(string v) { Settings.CustomKillerWeaponBarcode = v; })); val5.AddElement<FunctionElementData>(new FunctionElementData { Title = "USE RIGHT-HAND ITEM AS KILLER WEAPON", OnPressed = SelectRightHandAsKillerWeapon }); val5.AddElement<FunctionElementData>(new FunctionElementData { Title = "RECOVER LOST KILLER WEAPON", OnPressed = RecoverLostKillerWeapon }); val5.AddElement<EnumElementData>(new EnumElementData { Title = "Killer Skin", EnumType = typeof(KillerSkinChoice), Value = Settings.SkinChoice, OnValueChanged = delegate(Enum v) { Settings.SkinChoice = (KillerSkinChoice)(object)v; } }); val5.AddElement<FunctionElementData>(new FunctionElementData { Title = "USE MY CURRENT AVATAR AS KILLER SKIN", OnPressed = SelectCurrentAvatarForKiller }); val5.AddElement<FloatElementData>(FloatSetting("Killer Vitality", Settings.KillerVitality, 0.2f, 20f, delegate(float v) { Settings.KillerVitality = v; })); val5.AddElement<FloatElementData>(FloatSetting("Survivor Vitality", Settings.SurvivorVitality, 0.2f, 20f, delegate(float v) { Settings.SurvivorVitality = v; })); val5.AddElement<FloatElementData>(FloatSetting("Killer Speed", Settings.KillerSpeedMultiplier, 0.5f, 2f, delegate(float v) { Settings.KillerSpeedMultiplier = v; })); val5.AddElement<FloatElementData>(FloatSetting("Survivor Speed", Settings.SurvivorSpeedMultiplier, 0.5f, 2f, delegate(float v) { Settings.SurvivorSpeedMultiplier = v; })); val5.AddElement<BoolElementData>(BoolSetting("Survivors Can Damage Killer", Settings.SurvivorsCanDamageKiller, delegate(bool v) { Settings.SurvivorsCanDamageKiller = v; })); val5.AddElement<BoolElementData>(BoolSetting("Killer Can Die", Settings.KillerCanDie, delegate(bool v) { Settings.KillerCanDie = v; })); val5.AddElement<BoolElementData>(BoolSetting("Prevent Same Killer Twice", Settings.PreventSameKillerTwice, delegate(bool v) { Settings.PreventSameKillerTwice = v; })); val5.AddElement<BoolElementData>(BoolSetting("Clear Starting Inventory", Settings.ClearStartingInventory, delegate(bool v) { Settings.ClearStartingInventory = v; })); val5.AddElement<BoolElementData>(BoolSetting("Give Survivors Selected Weapon", Settings.GiveSurvivorsWeapon, delegate(bool v) { Settings.GiveSurvivorsWeapon = v; })); val5.AddElement<StringElementData>(StringSetting("Survivor Weapon Barcode", Settings.SurvivorWeaponBarcode, delegate(string v) { Settings.SurvivorWeaponBarcode = v; })); val5.AddElement<FunctionElementData>(new FunctionElementData { Title = "USE RIGHT-HAND ITEM AS SURVIVOR WEAPON", OnPressed = SelectRightHandAsSurvivorWeapon }); val5.AddElement<BoolElementData>(BoolSetting("Give Survivors Flashlights", Settings.SpawnSurvivorFlashlights, delegate(bool v) { Settings.SpawnSurvivorFlashlights = v; })); val5.AddElement<StringElementData>(StringSetting("Flashlight Barcode", Settings.FlashlightBarcode, delegate(string v) { Settings.FlashlightBarcode = v; })); val5.AddElement<FunctionElementData>(new FunctionElementData { Title = "USE RIGHT-HAND ITEM AS SURVIVOR FLASHLIGHT", OnPressed = SelectRightHandAsSurvivorFlashlight }); if (FlashbangFeatureEnabled) { val5.AddElement<BoolElementData>(BoolSetting("Give Survivors Flashbangs", Settings.GiveSurvivorsFlashbangs, delegate(bool v) { Settings.GiveSurvivorsFlashbangs = v; })); val5.AddElement<StringElementData>(StringSetting("Flashbang Barcode", Settings.FlashbangBarcode, delegate(string v) { Settings.FlashbangBarcode = v; })); val5.AddElement<FunctionElementData>(new FunctionElementData { Title = "USE RIGHT-HAND ITEM AS SURVIVOR FLASHBANG", OnPressed = SelectRightHandAsSurvivorFlashbang }); val5.AddElement<BoolElementData>(BoolSetting("Flashbang Bright Effect", Settings.FlashbangBrightEffect, delegate(bool v) { Settings.FlashbangBrightEffect = v; })); val5.AddElement<FloatElementData>(FloatSetting("Flashbang Radius", Settings.FlashbangRadius, 5f, 40f, delegate(float v) { Settings.FlashbangRadius = v; })); val5.AddElement<FloatElementData>(FloatSetting("Flashbang Whiteout Seconds", Settings.FlashbangDuration, 0.5f, 8f, delegate(float v) { Settings.FlashbangDuration = v; })); if (IsSoloTest) { val5.AddElement<FunctionElementData>(new FunctionElementData { Title = "TEST FLASHBANG WHITEOUT (LOCAL)", OnPressed = delegate { KillerFlashEffect.Trigger(Settings.FlashbangDuration, 1f); } }); } } val5.AddElement<BoolElementData>(BoolSetting("Mode Sounds", Settings.EnableModeSounds, delegate(bool v) { Settings.EnableModeSounds = v; })); val5.AddElement<BoolElementData>(BoolSetting("Visible Round Timer", Settings.ShowRoundTimer, delegate(bool v) { Settings.ShowRoundTimer = v; })); val5.AddElement<BoolElementData>(BoolSetting("Last Survivor Reveal", Settings.LastSurvivorRevealEnabled, delegate(bool v) { Settings.LastSurvivorRevealEnabled = v; })); val5.AddElement<IntElementData>(IntSetting("Reveal Interval", Settings.LastSurvivorRevealInterval, 3, 60, delegate(int v) { Settings.LastSurvivorRevealInterval = v; })); val5.AddElement<IntElementData>(IntSetting("Reveal Duration", Settings.LastSurvivorRevealDuration, 1, 10, delegate(int v) { Settings.LastSurvivorRevealDuration = v; })); val7.AddElement<BoolElementData>(BoolSetting("Show Colored Circles", _showInGameSetupMarkers, delegate(bool value) { _showInGameSetupMarkers = value; KillerInGameMapSetup.SetVisuals(value && !((Gamemode)this).IsStarted); })); val7.AddElement<FunctionElementData>(new FunctionElementData { Title = "VALIDATE CURRENT MAP", OnPressed = ValidateCurrentMapForHost }); val7.AddElement<FunctionElementData>(new FunctionElementData { Title = "BEGIN SETUP / PAUSE AUTO-START", OnPressed = BeginInGameMapSetupEditing }); val7.AddElement<FunctionElementData>(new FunctionElementData { Title = "FINISH SETUP / ALLOW ROUND START", OnPressed = FinishInGameMapSetupEditing }); AddMapSetupButton(val7, "Set Lobby Spawn Here", InGameSetupPoint.Lobby); AddMapSetupButton(val7, "Set Killer Spawn Here", InGameSetupPoint.Killer); AddMapSetupButton(val7, "Add Survivor Spawn Here", InGameSetupPoint.Survivor); AddMapSetupButton(val7, "Set Spectator Spawn Here", InGameSetupPoint.Spectator); AddMapSetupButton(val7, "Set Escape Door Ahead", InGameSetupPoint.Escape); val7.AddElement<FunctionElementData>(new FunctionElementData { Title = "Undo Most Recent Survivor Spawn", OnPressed = RemoveLastSurvivorSetupPoint }); val7.AddElement<FunctionElementData>(new FunctionElementData { Title = "Remove Escape Zone", OnPressed = RemoveEscapeSetupPoint }); val7.AddElement<FunctionElementData>(new FunctionElementData { Title = "Clear This Map Setup", OnPressed = ClearCurrentMapSetup }); return val; } private void ApplyGameplayPreset(KillerGameplayPreset preset) { Settings.ApplyPreset(preset); if (preset != KillerGameplayPreset.Custom) { Notify("Preset Applied", $"{preset} settings are ready. Reopen this page to see every updated value.", (NotificationType)3); } } private void ApplyMapRecommendations() { if (!NetworkInfo.IsHost) { Notify("Map Recommendations", "Only the Fusion host can apply map recommendations.", (NotificationType)1); return; } KillerMapConfig activeConfig = KillerMapRegistry.ActiveConfig; if ((Object)(object)activeConfig == (Object)null) { Notify("Map Recommendations", "This map does not provide Killer Mode recommendations.", (NotificationType)1); return; } Settings.GameplayPreset = KillerGameplayPreset.Custom; Settings.MinimumPlayers = Math.Clamp(activeConfig.RecommendedPlayersMin, IsSoloTest ? 1 : 2, 32); Settings.RoundSeconds = Math.Clamp(activeConfig.RecommendedRoundSeconds, 60, 3600); Settings.DarkMapEnabled = activeConfig.RecommendDarkMap; Settings.DarkFogEnabled = activeConfig.RecommendDarkFog; Notify("Map Recommendations Applied", "Player count, round time, darkness, and fog recommendations are ready.", (NotificationType)3); } private void SelectRightHandAsKillerWeapon() { SelectRightHandItem("Killer weapon", delegate(string barcode) { Settings.CustomKillerWeaponBarcode = barcode; Settings.WeaponChoice = KillerWeaponChoice.CustomBarcode; }); } private void SelectRightHandAsSurvivorWeapon() { SelectRightHandItem("Survivor weapon", delegate(string barcode) { Settings.SurvivorWeaponBarcode = barcode; Settings.GiveSurvivorsWeapon = true; }); } private void SelectRightHandAsSurvivorFlashlight() { SelectRightHandItem("Survivor flashlight", delegate(string barcode) { Settings.FlashlightBarcode = barcode; Settings.SpawnSurvivorFlashlights = true; }); } private void SelectRightHandAsSurvivorFlashbang() { SelectRightHandItem("Survivor flashbang", delegate(string barcode) { Settings.FlashbangBarcode = barcode; Settings.GiveSurvivorsFlashbangs = true; }); } private void SelectRightHandItem(string destination, Action<string> apply) { if (!NetworkInfo.IsHost) { Notify("Right-Hand Item", "Only the Fusion host can choose shared round equipment.", (NotificationType)1); return; } if (RigData.HasPlayer) { RigRefs refs = RigData.Refs; if (!((Object)(object)((refs != null) ? refs.RightHand : null) == (Object)null)) { GameObject currentAttachedGO = RigData.Refs.RightHand.m_CurrentAttachedGO; if ((Object)(object)currentAttachedGO == (Object)null) { Notify("Right-Hand Item", "Hold the item in your right hand, then press this button with your left hand.", (NotificationType)1, 6f); return; } Poolee obj = currentAttachedGO.GetComponentInParent<Poolee>() ?? Poolee.Cache.Get(currentAttachedGO); object obj2; if (obj == null) { obj2 = null; } else { SpawnableCrate spawnableCrate = obj.SpawnableCrate; if (spawnableCrate == null) { obj2 = null; } else { Barcode barcode = ((Scannable)spawnableCrate).Barcode; obj2 = ((barcode != null) ? barcode.ID : null); } } string text = (string)obj2; if (string.IsNullOrWhiteSpace(text) || !KillerContentReferences.IsInstalled(text)) { Notify("Right-Hand Item", "That held object does not expose a usable Spawnable barcode.", (NotificationType)1, 6f); return; } apply(text); KillerModePreferences.Save(Settings); Notify("Right-Hand Item Saved", destination + ": " + text + "\nIt will be used next round. Reopen settings to see the updated selection.", (NotificationType)3, 8f); return; } } Notify("Right-Hand Item", "Your player rig is not ready yet.", (NotificationType)1); } private void SelectCurrentAvatarForKiller() { if (!NetworkInfo.IsHost) { Notify("Killer Skin", "Only the Fusion host can choose the shared Killer skin.", (NotificationType)1); return; } string avatarBarcode = LocalAvatar.AvatarBarcode; if (string.IsNullOrWhiteSpace(avatarBarcode) && RigData.HasPlayer) { avatarBarcode = RigData.GetAvatarBarcode(); } if (string.IsNullOrWhiteSpace(avatarBarcode) || !KillerContentReferences.IsAvatarInstalled(avatarBarcode)) { Notify("Killer Skin", "Wear the downloaded avatar first, then press this button again.", (NotificationType)1); return; } Settings.KillerAvatarBarcode = avatarBarcode; Settings.SkinChoice = KillerSkinChoice.SelectedDownloadedAvatar; Notify("Killer Skin Saved", "Your currently worn avatar will be used for the Killer next round.", (NotificationType)3); } private void AddMapSetupButton(GroupElementData group, string title, InGameSetupPoint point) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown group.AddElement<FunctionElementData>(new FunctionElementData { Title = title, OnPressed = delegate { PlaceInGameSetupPoint(point); } }); } private void ValidateCurrentMapForHost() { KillerMapModeOverride killerMapModeOverride = KillerMapRegistry.ActiveConfig?.ModeOverride ?? Settings.MapModeOverride; IReadOnlyList<string> readOnlyList = KillerMapValidator.Validate((killerMapModeOverride == KillerMapModeOverride.Escape || (killerMapModeOverride == KillerMapModeOverride.Auto && KillerMapRegistry.EscapeZones.Any((KillerEscapeZone zone) => (Object)(object)zone != (Object)null && ((Behaviour)zone).isActiveAndEnabled))) ? KillerMapMode.Escape : KillerMapMode.Survival); if (readOnlyList.Count == 0 && ((Gamemode)this).CheckReadyConditions()) { Notify("Map Validation Passed", "This map and the selected required content are ready.", (NotificationType)3); return; } string message = readOnlyList.FirstOrDefault() ?? "Check minimum players and required host barcode settings."; Notify("Map Cannot Start", message, (NotificationType)1, 7f); } private static IntElementData IntSetting(string title, int value, int min, int max, Action<int> changed, int increment = 1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown return new IntElementData { Title = title, Value = value, MinValue = min, MaxValue = max, Increment = increment, OnValueChanged = changed }; } private static FloatElementData FloatSetting(string title, float value, float min, float max, Action<float> changed) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_001a: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown return new FloatElementData { Title = title, Value = value, MinValue = min, MaxValue = max, Increment = 0.2f, OnValueChanged = changed }; } private static BoolElementData BoolSetting(string title, bool value, Action<bool> changed) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_001b: Expected O, but got Unknown return new BoolElementData { Title = title, Value = value, OnValueChanged = changed }; } private static StringElementData StringSetting(string title, string value, Action<string> changed) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown return new StringElementData { Title = title, Value = (value ?? string.Empty), OnValueChanged = changed }; } public override bool CheckReadyConditions() { if (_inGameSetupEditing || _automaticRoundsPaused) { return false; } int num = (IsSoloTest ? 1 : Math.Clamp(Settings.MinimumPlayers, 2, 32)); if (PlayerIDManager.PlayerCount < num) { return false; } if ((KillerMapRegistry.ActiveConfig?.ModeOverride ?? Settings.MapModeOverride) == KillerMapModeOverride.Escape && !KillerMapRegistry.EscapeZones.Any((KillerEscapeZone z) => (Object)(object)z != (Object)null && ((Behaviour)z).isActiveAndEnabled)) { return false; } KillerMapConfig activeConfig = KillerMapRegistry.ActiveConfig; if ((Object)(object)activeConfig != (Object)null) { if (activeConfig.SdkCompatibilityVersion > 3) { return false; } if ((activeConfig.RequiredSpawnableBarcodes ?? Array.Empty<string>()).Any((string text) => !string.IsNullOrWhiteSpace(text) && !KillerContentReferences.IsAnyCrateInstalled(text))) { return false; } } foreach (KillerItemSpawnPoint item in KillerMapRegistry.ItemSpawns.Where((KillerItemSpawnPoint point) => (Object)(object)point != (Object)null && point.RequiredContent)) { if (!KillerContentReferences.IsInstalled((item is KillerFlashlightSpawner { UseHostBarcode: not false }) ? Settings.FlashlightBarcode : ((item is KillerFlashbangSpawner { UseHostBarcode: not false }) ? Settings.FlashbangBarcode : item.SpawnableBarcode))) { return false; } } string barcode = ResolveKillerWeaponBarcode(); KillerWeaponChoice weaponChoice = Settings.WeaponChoice; if ((weaponChoice == KillerWeaponChoice.CustomBarcode || weaponChoice == KillerWeaponChoice.MapDefined) && !KillerContentReferences.IsInstalled(barcode)) { return false; } if (IsSoloTest) { return true; } bool flag = GamemodeMarker.FilterMarkers((BoneTagReference)null).Count > 0; bool num2 = KillerMapRegistry.GetSpawns(KillerSpawnRole.Killer).Any() || flag; bool flag2 = KillerMapRegistry.GetSpawns(KillerSpawnRole.Survivor).Any() || flag; if (!num2 || !flag2) { return false; } return true; } public override void OnGamemodeSelected() { _inGameSetupEditing = false; _automaticRoundsPaused = false; _pauseAutomaticRoundsAfterCurrentRound = false; LoadAndPublishInGameMapSetup(); TeleportLocalToRole(KillerSpawnRole.Lobby); } public override void OnGamemodeDeselected() { KillerInGameMapSetup.ClearRuntimeObjects(); GamemodeHelper.ResetSpawnPoints(); } public override void OnGamemodeRegistered() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Expected O, but got Unknown //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Expected O, but got Unknown //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Expected O, but got Unknown //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Expected O, but got Unknown //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Expected O, but got Unknown //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Expected O, but got Unknown //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Expected O, but got Unknown //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Expected O, but got Unknown //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Expected O, but got Unknown //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Expected O, but got Unknown //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Expected O, but got Unknown _roundState = new MetadataInt("KillerRoundState", ((Gamemode)this).Metadata); _remainingSeconds = new MetadataInt("RemainingSeconds", ((Gamemode)this).Metadata); _winReason = new MetadataInt("KillerWinReason", ((Gamemode)this).Metadata); _effectiveMapMode = new MetadataInt("EffectiveMapMode", ((Gamemode)this).Metadata); _effectiveKillerVitality = new MetadataInt("KillerVitalityX100", ((Gamemode)this).Metadata); _effectiveSurvivorVitality = new MetadataInt("SurvivorVitalityX100", ((Gamemode)this).Metadata); _effectiveKillerSpeed = new MetadataInt("KillerSpeedX100", ((Gamemode)this).Metadata); _effectiveSurvivorSpeed = new MetadataInt("SurvivorSpeedX100", ((Gamemode)this).Metadata); _effectiveKillerCanDie = new MetadataBool("KillerCanDie", ((Gamemode)this).Metadata); _effectiveSurvivorDamage = new MetadataBool("SurvivorsCanDamageKiller", ((Gamemode)this).Metadata); _effectiveClearStartingInventory = new MetadataBool("ClearStartingInventory", ((Gamemode)this).Metadata); _effectiveModeSounds = new MetadataBool("ModeSounds", ((Gamemode)this).Metadata); _effectiveShowRoundTimer = new MetadataBool("ShowRoundTimer", ((Gamemode)this).Metadata); _effectiveWeapon = new MetadataInt("KillerWeapon", ((Gamemode)this).Metadata); _effectiveSkin = new MetadataInt("KillerSkin", ((Gamemode)this).Metadata); _effectiveSkinBarcode = new MetadataVariable("KillerSkinBarcode", ((Gamemode)this).Metadata); _effectiveRevealEnabled = new MetadataBool("LastSurvivorRevealEnabled", ((Gamemode)this).Metadata); _effectiveRevealInterval = new MetadataInt("LastSurvivorRevealInterval", ((Gamemode)this).Metadata); _effectiveRevealDuration = new MetadataInt("LastSurvivorRevealDuration", ((Gamemode)this).Metadata); _effectiveWeaponBarcode = new MetadataVariable("KillerWeaponBarcode", ((Gamemode)this).Metadata); _effectiveFlashlightBarcode = new MetadataVariable("FlashlightBarcode", ((Gamemode)this).Metadata); _effectiveFlashbangBarcode = new MetadataVariable("FlashbangBarcode", ((Gamemode)this).Metadata); _effectiveDarkMap = new MetadataBool("DarkMap", ((Gamemode)this).Metadata); _effectiveDarknessStrength = new MetadataInt("DarknessStrength", ((Gamemode)this).Metadata); _effectiveDarkFog = new MetadataBool("DarkFog", ((Gamemode)this).Metadata); _effectiveFogStrength = new MetadataInt("FogStrength", ((Gamemode)this).Metadata); _effectiveFlashbangEffect = new MetadataBool("FlashbangBrightEffect", ((Gamemode)this).Metadata); _effectiveFlashbangRadius = new MetadataInt("FlashbangRadiusX100", ((Gamemode)this).Metadata); _effectiveFlashbangDuration = new MetadataInt("FlashbangDurationX100", ((Gamemode)this).Metadata); ((MetadataDictionary<byte, MetadataInt>)(object)_playerStates).Register(((Gamemode)this).Metadata, "KillerPlayerState"); _playerStates.OnPlayerVariableChanged += OnPlayerStateChanged; _teams.Register((Gamemode)(object)this); _teams.AddTeam(_killerTeam); _teams.AddTeam(_survivorTeam); _teams.AddTeam(_spectatorTeam); _teams.OnAssignedToTeam += OnAssignedToTeam; _escapeRequest = new TriggerEvent("EscapeRequest", ((Gamemode)this).Relay, false); _escapeRequest.OnTriggeredWithValue += OnEscapeRequest; _lastSurvivorEvent = new TriggerEvent("LastSurvivor", ((Gamemode)this).Relay, true); _lastSurvivorEvent.OnTriggered += delegate { switch ((PlayerIDManager.LocalID != null) ? GetPlayerState(PlayerIDManager.LocalID) : KillerPlayerState.None) { case KillerPlayerState.SurvivorAlive: { _localLastSurvivorHeartbeatActive = true; string message2 = (IsSoloTest ? "Solo test: the Last Survivor cue and private heartbeat are active." : (((MetadataVariableT<bool>)(object)_effectiveRevealEnabled).GetValue() ? "You are the last Survivor. Your location will be periodically revealed to the Killer." : "You are the last Survivor. Stay alive.")); Notify("YOU'RE THE LAST SURVIVOR", message2, (NotificationType)1); break; } case KillerPlayerState.Killer: { _localLastSurvivorHeartbeatActive = false; string message = (((MetadataVariableT<bool>)(object)_effectiveRevealEnabled).GetValue() ? "Only one Survivor remains. Their location will be revealed." : "Only one Survivor remains."); Notify("LAST SURVIVOR", message, (NotificationType)1); break; } default: _localLastSurvivorHeartbeatActive = false; Notify("Last Survivor", "Only one living Survivor remains.", (NotificationType)1); break; } if (ModeSoundsEnabled()) { KillerModeAudio.PlayLastSurvivor(); } KillerMapRegistry.InvokeEvents(delegate(KillerMapEvents e) { e.InvokeLastSurvivor(); }); }; _timeExpiredEvent = new TriggerEvent("TimeExpired", ((Gamemode)this).Relay, true); _timeExpiredEvent.OnTriggered += delegate { KillerMapRegistry.InvokeEvents(delegate(KillerMapEvents e) { e.InvokeTimeExpired(); }); }; _flashbangRequestEvent = new TriggerEvent("FlashbangRequest", ((Gamemode)this).Relay, false); _flashbangRequestEvent.OnTriggeredWithValue += OnFlashbangRequest; _flashbangDetonationEvent = new TriggerEvent("FlashbangDetonation", ((Gamemode)this).Relay, true); _flashbangDetonationEvent.OnTriggeredWithValue += OnFlashbangDetonation; MultiplayerHooking.OnPlayerAction += new PlayerAction(OnPlayerAction); FusionOverrides.OnValidateNametag += new UserOverride(OnValidateNametag); LocalHealth.OnRespawn += OnLocalRespawn; LocalAvatar.OnAvatarChanged += new PlayerAvatarDelegate(OnLocalAvatarChanged); } public override void OnGamemodeUnregistered() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown RestoreLocalAvatarLock(); MultiplayerHooking.OnPlayerAction -= new PlayerAction(OnPlayerAction); FusionOverrides.OnValidateNametag -= new UserOverride(OnValidateNametag); LocalHealth.OnRespawn -= OnLocalRespawn; LocalAvatar.OnAvatarChanged -= new PlayerAvatarDelegate(OnLocalAvatarChanged); _playerStates.OnPlayerVariableChanged -= OnPlayerStateChanged; ((MetadataDictionary<byte, MetadataInt>)(object)_playerStates).Unregister(); _teams.OnAssignedToTeam -= OnAssignedToTeam; _teams.Unregister(); _escapeRequest.UnregisterEvent(); _lastSurvivorEvent.UnregisterEvent(); _timeExpiredEvent.UnregisterEvent(); _flashbangRequestEvent.UnregisterEvent(); _flashbangDetonationEvent.UnregisterEvent(); KillerEnvironmentEffects.Restore(); KillerFlashEffect.Clear(); } public override void OnGamemodeStarted() { _localRoundAvatarBarcode = LocalAvatar.AvatarBarcode; if (string.IsNullOrWhiteSpace(_localRoundAvatarBarcode) && RigData.HasPlayer) { _localRoundAvatarBarcode = RigData.GetAvatarBarcode(); } _ending = false; _weaponRecoveryCooldown = 0f; _flashbangRequestCooldown = 0f; _soloLastSurvivorTriggerDelay = 0f; _spawnedItems = false; _killerWeaponSpawned = false; _localInventoryCleared = false; _localRoundStartSoundPlayed = false; _localRoundEndSoundPlayed = false; _localRoleMessageShown = false; _localLastSurvivorHeartbeatActive = false; _localKillerSkinFallbackNotified = false; _failedKillerAvatarBarcode = null; KillerModeAudio.StopHeartbeat(); _lastLocalStartCountdownSecond = -1; _lastLocalCountdownSecond = -1; KillerInGameMapSetup.SetVisuals(visible: false); _localEscapeRequested = false; _localEscapeRetry = 0f; _environmentRefreshTimer = 0f; _revealCycle = 0f; _revealVisible = 0f; _revealedPlayerId = null; _spawnedRoundItems.Clear(); _itemSpawnerStates.Clear(); _hostPlayerStates.Clear(); LocalControls.DisableSlowMo = true; KillerEnvironmentEffects.Restore(); KillerFlashEffect.Clear(); if (NetworkInfo.IsHost) { if (SavePreferencesOnStart) { KillerModePreferences.Save(Settings); } BeginHostRound(); } ApplyLocalEnvironment(); } private void BeginHostRound() { KillerMapConfig activeConfig = KillerMapRegistry.ActiveConfig; KillerMapMode value = (((Object)(object)activeConfig != (Object)null) ? activeConfig.ModeOverride : Settings.MapModeOverride) switch { KillerMapModeOverride.Survival => KillerMapMode.Survival, KillerMapModeOverride.Escape => KillerMapMode.Escape, _ => KillerMapRegistry.EscapeZones.Any((KillerEscapeZone z) => (Object)(object)z != (Object)null && ((Behaviour)z).isActiveAndEnabled) ? KillerMapMode.Escape : KillerMapMode.Survival, }; int val = (((Object)(object)activeConfig != (Object)null) ? activeConfig.ExitOpenTimeRemaining : Settings.ExitOpenTimeRemaining); ((MetadataVariableT<int>)(object)_effectiveMapMode).SetValue((int)value); ((MetadataVariableT<int>)(object)_effectiveKillerVitality).SetValue(Mathf.RoundToInt(Settings.KillerVitality * 100f)); ((MetadataVariableT<int>)(object)_effectiveSurvivorVitality).SetValue(Mathf.RoundToInt(Settings.SurvivorVitality * 100f)); ((MetadataVariableT<int>)(object)_effectiveKillerSpeed).SetValue(Mathf.RoundToInt(Mathf.Clamp(Settings.KillerSpeedMultiplier, 0.5f, 2f) * 100f)); ((MetadataVariableT<int>)(object)_effectiveSurvivorSpeed).SetValue(Mathf.RoundToInt(Mathf.Clamp(Settings.SurvivorSpeedMultiplier, 0.5f, 2f) * 100f)); ((MetadataVariableT<bool>)(object)_effectiveKillerCanDie).SetValue(Settings.KillerCanDie); ((MetadataVariableT<bool>)(object)_effectiveSurvivorDamage).SetValue(Settings.SurvivorsCanDamageKiller); _roundClearStartingInventory = Settings.ClearStartingInventory; ((MetadataVariableT<bool>)(object)_effectiveClearStartingInventory).SetValue(_roundClearStartingInventory); _roundModeSoundsEnabled = Settings.EnableModeSounds; _roundFlashlightBarcode = (string.IsNullOrWhiteSpace(Settings.FlashlightBarcode) ? "Blueberrycat.BONEWORKSFlashlight.Spawnable.FlashlightBoneworks" : Settings.FlashlightBarcode.Trim()); _roundFlashbangBarcode = ((!FlashbangFeatureEnabled) ? string.Empty : (Settings.FlashbangBarcode?.Trim() ?? string.Empty)); ((MetadataVariableT<bool>)(object)_effectiveModeSounds).SetValue(_roundModeSoundsEnabled); ((MetadataVariableT<bool>)(object)_effectiveShowRoundTimer).SetValue(Settings.ShowRoundTimer); ((MetadataVariableT<int>)(object)_effectiveWeapon).SetValue((int)Settings.WeaponChoice); ((MetadataVariableT<int>)(object)_effectiveSkin).SetValue((int)Settings.SkinChoice); _effectiveSkinBarcode.SetValue(Settings.KillerAvatarBarcode ?? string.Empty); ((MetadataVariableT<bool>)(object)_effectiveRevealEnabled).SetValue(Settings.LastSurvivorRevealEnabled); ((MetadataVariableT<int>)(object)_effectiveRevealInterval).SetValue(Math.Clamp(Settings.LastSurvivorRevealInterval, 3, 60)); ((MetadataVariableT<int>)(object)_effectiveRevealDuration).SetValue(Math.Clamp(Settings.LastSurvivorRevealDuration, 1, 10)); _roundWeaponBarcode = ResolveKillerWeaponBarcode(); if (!KillerContentReferences.IsInstalled(_roundWeaponBarcode)) { KillerWeaponChoice weaponChoice = Settings.WeaponChoice; if (weaponChoice != KillerWeaponChoice.CustomBarcode && weaponChoice != KillerWeaponChoice.MapDefined) { MelonLogger.Warning("[Killer Mode] Selected weapon is missing; using BONELAB's Combat Knife instead: " + _roundWeaponBarcode); _roundWeaponBarcode = "c1534c5a-1fb8-477c-afbe-2a95436f6d62"; } } _effectiveWeaponBarcode.SetValue(_roundWeaponBarcode ?? string.Empty); _effectiveFlashlightBarcode.SetValue(_roundFlashlightBarcode); _effectiveFlashbangBarcode.SetValue(_roundFlashbangBarcode); ((MetadataVariableT<bool>)(object)_effectiveDarkMap).SetValue(Settings.DarkMapEnabled); ((MetadataVariableT<int>)(object)_effectiveDarknessStrength).SetValue(Math.Clamp(Settings.DarknessStrength, 0, 100)); ((MetadataVariableT<bool>)(object)_effectiveDarkFog).SetValue(Settings.DarkFogEnabled); ((MetadataVariableT<int>)(object)_effectiveFogStrength).SetValue(Math.Clamp(Settings.FogStrength, 0, 100)); ((MetadataVariableT<bool>)(object)_effectiveFlashbangEffect).SetValue(FlashbangFeatureEnabled && Settings.FlashbangBrightEffect); ((MetadataVariableT<int>)(object)_effectiveFlashbangRadius).SetValue(Mathf.RoundToInt(Mathf.Clamp(Settings.FlashbangRadius, 5f, 40f) * 100f)); ((MetadataVariableT<int>)(object)_effectiveFlashbangDuration).SetValue(Mathf.RoundToInt(Mathf.Clamp(Settings.FlashbangDuration, 0.5f, 8f) * 100f)); ((MetadataVariableT<int>)(object)_winReason).SetValue(0); ApplyLocalEnvironment(); SelectAndAssignRoles(); _hostTimer = Math.Clamp(Settings.StartCountdownSeconds, 3, 30); _lastPublishedSecond = -1; SetRoundState(KillerRoundState.Preparing); ((Gamemode)this).Metadata.TrySetMetadata("RoundDuration", Math.Max(60, Settings.RoundSeconds).ToString()); ((Gamemode)this).Metadata.TrySetMetadata("ExitOpenTimeRemaining", Math.Max(0, val).ToString()); PublishRemaining(); } private void SelectAndAssignRoles() { PlayerID[] array = PlayerIDManager.PlayerIDs.OrderBy((PlayerID p) => p.