using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ContentWarningDoom.ActionMode; using ContentWarningDoom.Audio; using ContentWarningDoom.Combat; using ContentWarningDoom.Config; using ContentWarningDoom.Core; using ContentWarningDoom.Debug; using ContentWarningDoom.FX; using ContentWarningDoom.Items; using ContentWarningDoom.Monsters; using ContentWarningDoom.Networking; using ContentWarningDoom.PlayerLogic; using ContentWarningDoom.Shop; using ContentWarningDoom.UI; using ContentWarningDoom.Weapons; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.AI; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ContentWarningDoom")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.2.0")] [assembly: AssemblyInformationalVersion("0.3.2")] [assembly: AssemblyProduct("ContentWarningDoom")] [assembly: AssemblyTitle("ContentWarningDoom")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ContentWarningDoom { public class DoomController : MonoBehaviour { public static bool ShowDebugOverlay; private float _bannerUntil; private bool _droppedShotgun; private bool _droppedSsg; private bool _droppedBfg; public bool BannerVisible => Time.time < _bannerUntil; private void OnEnable() { DoomNet.OnModeState += HandleModeState; DoomNet.OnMonsterDeath += HandleMonsterDeath; DoomNet.OnKills += HandleKills; DoomNet.OnHostPlayerJoined += HandleHostPlayerJoined; } private void OnDisable() { DoomNet.OnModeState -= HandleModeState; DoomNet.OnMonsterDeath -= HandleMonsterDeath; DoomNet.OnKills -= HandleKills; DoomNet.OnHostPlayerJoined -= HandleHostPlayerJoined; } private void Update() { Keyboard current = Keyboard.current; if (current == null || (!((ButtonControl)current.leftAltKey).isPressed && !((ButtonControl)current.rightAltKey).isPressed)) { return; } if (((ButtonControl)current.oKey).wasPressedThisFrame) { ShowDebugOverlay = !ShowDebugOverlay; } if (((ButtonControl)current.kKey).wasPressedThisFrame) { if (!DoomNet.InRoom) { Plugin.LogMode("Alt+K ignored — not in a room yet."); } else if (!DoomNet.IsHost) { Plugin.LogMode("Alt+K ignored — only the host can toggle Doom Mode."); } else { SetDoomMode(!Plugin.DoomModeActive, broadcast: true); } } if (((ButtonControl)current.mKey).wasPressedThisFrame && DoomNet.IsHost && Plugin.DoomModeActive) { DebugSpawnMonster(); } if (((ButtonControl)current.uKey).wasPressedThisFrame && DoomNet.IsHost && Plugin.DoomModeActive) { WeaponManager.Instance?.UnlockAll(); WeaponManager.Instance?.GiveAmmoAll(1f); } if (((ButtonControl)current.bKey).wasPressedThisFrame && Plugin.DoomModeActive) { BuyNextSpecialWeapon(); } if (((ButtonControl)current.gKey).wasPressedThisFrame && Plugin.DoomModeActive) { ReviveTeammates(); } if (((ButtonControl)current.jKey).wasPressedThisFrame && Plugin.DoomModeActive) { ScrapEconomy.Add(DoomNet.LocalActor, 1000); Plugin.LogMode($"[Debug] +1000 scrap (now {ScrapEconomy.Local})"); } if (((ButtonControl)current.pKey).wasPressedThisFrame) { WeaponShop.Instance?.PinHere(); } if (((ButtonControl)current.lKey).wasPressedThisFrame) { WeaponShop.Instance?.ClearPin(); } if (((ButtonControl)current.eKey).wasPressedThisFrame) { ActionRoundManager.Instance?.RequestLocalSubmit(); } if (((ButtonControl)current.nKey).wasPressedThisFrame && Plugin.DoomModeActive) { EpicMusic.Instance?.Toggle(); } if (((ButtonControl)current.equalsKey).wasPressedThisFrame || ((ButtonControl)current.numpadPlusKey).wasPressedThisFrame) { EpicMusic.AdjustVolume(0.05f); } else if (((ButtonControl)current.minusKey).wasPressedThisFrame || ((ButtonControl)current.numpadMinusKey).wasPressedThisFrame) { EpicMusic.AdjustVolume(-0.05f); } } private static void ReviveTeammates() { PlayerHandler instance = PlayerHandler.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { Plugin.LogMode("[Revive] no PlayerHandler"); return; } Player localPlayer = Player.localPlayer; int num = 0; for (int i = 0; i < instance.players.Count; i++) { Player val = instance.players[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)localPlayer) && val.data != null && val.data.dead) { try { val.CallRevive(); num++; } catch (Exception ex) { Plugin.LogMode("[Revive] " + ((Object)val).name + ": " + ex.Message); } } } Plugin.LogMode((num > 0) ? $"[Revive] revived {num} teammate(s)" : "[Revive] no downed teammates"); } private void BuyNextSpecialWeapon() { int localActor = DoomNet.LocalActor; WeaponId[] array = new WeaponId[2] { WeaponId.Minigun, WeaponId.GrenadeLauncher }; foreach (WeaponId weaponId in array) { if (ActionEconomy.Purchased(localActor).Contains(weaponId)) { continue; } if (ActionEconomy.TryBuy(localActor, weaponId)) { Plugin.Log.LogInfo((object)$"[Shop] bought {weaponId} — carried into the next dive. Credits left: {ActionEconomy.GetCredits(localActor)}"); if (Plugin.DoomModeActive && ActionRoundManager.Phase == ActionRoundPhase.Action) { ActionEconomy.ApplyPurchasesToLocalPlayer(localActor); } } else { Plugin.Log.LogInfo((object)$"[Shop] not enough ActionCredits for {weaponId} (need {ActionEconomy.PriceOf(weaponId)}, have {ActionEconomy.GetCredits(localActor)})"); } return; } Plugin.Log.LogInfo((object)"[Shop] all special weapons already owned."); } public void SetDoomMode(bool on, bool broadcast) { if (Plugin.DoomModeActive != on || broadcast) { Plugin.DoomModeActive = on; Plugin.CurrentSpawnMultiplier = (on ? Mathf.Max(1f, DoomConfig.MonsterSpawnMultiplier.Value) : 1f); if (on) { Plugin.DoomEverActivated = true; KillCounter.ResetAll(); ResetDrops(); MonsterRegistry.Instance?.Clear(); WeaponManager.Instance?.RebuildWeapons(); WeaponManager.Instance?.OnDoomModeEnabled(); _bannerUntil = Time.time + 2.5f; Plugin.Log.LogInfo((object)"========== DOOM MODE ENABLED =========="); ViralityCompat.Detect(); int num = ViralityCompat.RoomMaxPlayers(); Plugin.Log.LogInfo((object)($"[DoomMode] session: {DoomNet.PlayerCount} player(s) in room" + ((num > 0) ? $" (room cap {num})" : "") + ", virality=" + (ViralityCompat.Present ? "yes" : "no") + " — no player limit is imposed by this mod.")); Plugin.LogMode($"spawn x{Plugin.CurrentSpawnMultiplier}, monster HP layer active, starting weapon: PISTOL"); } else { WeaponManager.Instance?.OnDoomModeDisabled(); Plugin.Log.LogInfo((object)"========== DOOM MODE DISABLED =========="); } if (broadcast && DoomNet.IsHost) { DoomNet.SendModeState(on, Plugin.CurrentSpawnMultiplier); } } } private void HandleModeState(bool enabled, float spawnMult, int hostActor) { if (DoomNet.IsHost) { return; } Plugin.CurrentSpawnMultiplier = spawnMult; if (enabled != Plugin.DoomModeActive) { Plugin.DoomModeActive = enabled; if (enabled) { Plugin.DoomEverActivated = true; KillCounter.ResetAll(); ResetDrops(); MonsterRegistry.Instance?.Clear(); WeaponManager.Instance?.RebuildWeapons(); WeaponManager.Instance?.OnDoomModeEnabled(); _bannerUntil = Time.time + 2.5f; Plugin.LogMode("host enabled DOOM MODE — mirroring."); } else { WeaponManager.Instance?.OnDoomModeDisabled(); Plugin.LogMode("host disabled DOOM MODE — mirroring."); } } } private void HandleHostPlayerJoined() { if (DoomNet.IsHost) { DoomNet.SendModeState(Plugin.DoomModeActive, Plugin.CurrentSpawnMultiplier); } } private void HandleKills(int teamKills) { KillCounter.SetTeamKillsFromNetwork(teamKills); } public void ResetDrops() { _droppedShotgun = (_droppedSsg = (_droppedBfg = false)); } private void HandleMonsterDeath(int viewId, Vector3 dir, int killerActor) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) Plugin.HudKillMarker(); if (killerActor == DoomNet.LocalActor) { Plugin.HudLocalKill(); ScrapEconomy.AwardForKill(viewId); } KillCounter.NoteLocalCredit(killerActor); WeaponManager instance = WeaponManager.Instance; if ((Object)(object)instance != (Object)null && instance.HasWeapon) { instance.GiveAmmo(instance.CurrentDef.Id, Mathf.Max(1, instance.CurrentDef.MagSize / 3)); } Vector3 val = ((Component)this).transform.position; int num; if ((Object)(object)MonsterRegistry.Instance != (Object)null && MonsterRegistry.Instance.TryGet(viewId, out var h)) { num = (((Object)(object)h.Root != (Object)null) ? 1 : 0); if (num != 0) { MonsterRegistry.Instance.TryGet(viewId, out var h2); val = h2.CenterPos; } } else { num = 0; } if (num == 0) { return; } if (killerActor == DoomNet.LocalActor && (Object)(object)instance != (Object)null) { instance.GiveAmmoAll(0.06f); ImpactEffects.AmmoPickupFx(val); Plugin.LogWeapon("kill ammo bonus +6% all weapons"); } if (Random.value < 0.4f) { AmmoPickup.Spawn(val); } if ((Object)(object)instance == (Object)null) { return; } int teamKills = KillCounter.TeamKills; WeaponId? weaponId = null; if (!_droppedShotgun && !instance.IsUnlocked(WeaponId.Shotgun) && teamKills >= 2) { weaponId = WeaponId.Shotgun; _droppedShotgun = true; } else if (!_droppedSsg && !instance.IsUnlocked(WeaponId.SuperShotgun) && teamKills >= 8) { weaponId = WeaponId.SuperShotgun; _droppedSsg = true; } else if (!_droppedBfg && !instance.IsUnlocked(WeaponId.BFG) && teamKills >= 18) { weaponId = WeaponId.BFG; _droppedBfg = true; } else if (Random.value < 0.12f) { if (!instance.IsUnlocked(WeaponId.Shotgun)) { weaponId = WeaponId.Shotgun; } else if (!instance.IsUnlocked(WeaponId.SuperShotgun)) { weaponId = WeaponId.SuperShotgun; } else if (!instance.IsUnlocked(WeaponId.BFG)) { weaponId = WeaponId.BFG; } } if (weaponId.HasValue) { WeaponPickup.Spawn(val + Random.insideUnitSphere * 1.2f, weaponId.Value); } } private void DebugSpawnMonster() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MainCamera.instance == (Object)null) { return; } string[] obj = new string[6] { "Zombe", "Zombie", "Snatcho", "Larva", "Spider", "BarnacleBall" }; Transform transform = ((Component)MainCamera.instance).transform; Vector3 val = transform.position + transform.forward * 8f; string[] array = obj; foreach (string text in array) { try { if ((Object)(object)MonsterSpawner.SpawnMonster(text, val) != (Object)null) { Plugin.LogSpawn("F9 spawned '" + text + "'"); return; } } catch { } } Plugin.LogSpawn("F9 spawn failed — no known monster prefab name resolved."); } } [BepInPlugin("SchetnikovMods.ContentWarningDoom", "ContentWarningDoom", "0.3.2")] public class Plugin : BaseUnityPlugin { public const string Guid = "SchetnikovMods.ContentWarningDoom"; private Harmony _harmony; public static bool DoomEverActivated; public static MonsterHealth GloryTarget; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } public static bool DoomModeActive { get; internal set; } public static float CurrentSpawnMultiplier { get; internal set; } = 1f; private void Awake() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; DoomConfig.Init(((BaseUnityPlugin)this).Config); if (!DoomConfig.Enabled.Value) { Log.LogWarning((object)"[DoomMode] disabled via config (General.Enabled = false)."); return; } _harmony = new Harmony("SchetnikovMods.ContentWarningDoom"); try { _harmony.PatchAll(typeof(Plugin).Assembly); } catch (Exception arg) { Log.LogError((object)$"[DoomMode] Harmony patch failed: {arg}"); } DoomNet.Create(); ActionNet.Create(); MonsterRegistry.Create(); WeaponManager.Create(); RemotePlayerWeapons.Create(); WeaponShop.Create(); PvpRespawn.Create(); HeldItemPose.Create(); EpicMusic.Create(); DamageSystem.HookHost(); BfgProjectile.HookNet(); GrenadeProjectile.HookNet(); ActionCameraSpawner.Create(); ActionVideoRecorder.Create(); ActionCamera.Create(); ActionRoundManager.Create(); ActionContentTracker.Create(); GameObject val = new GameObject("ContentWarningDoom.Hub"); Object.DontDestroyOnLoad((Object)val); val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); SceneManager.sceneLoaded += OnSceneLoaded; PluginInfo info = ((BaseUnityPlugin)this).Info; object obj; if (info == null) { obj = null; } else { BepInPlugin metadata = info.Metadata; obj = ((metadata == null) ? null : metadata.Version?.ToString()); } if (obj == null) { obj = "?"; } string text = (string)obj; Log.LogInfo((object)("[DoomMode] ContentWarningDoom " + text + " loaded. Alt+K = Doom Mode (host), Alt+O = debug overlay.")); ViralityCompat.LogStatus(); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { MonsterRegistry.Instance?.Clear(); if (DoomModeActive) { CurrentSpawnMultiplier = Mathf.Max(1f, DoomConfig.MonsterSpawnMultiplier.Value); WeaponManager.Instance?.OnSceneReloaded(); LogMode("scene '" + ((Scene)(ref scene)).name + "' loaded — Doom Mode stays ON, re-arming."); } } public static void LogMode(string m) { if (DoomConfig.DebugLogging.Value) { Log.LogInfo((object)("[DoomMode] " + m)); } } public static void LogWeapon(string m) { if (DoomConfig.DebugLogging.Value) { Log.LogInfo((object)("[DoomWeapon] " + m)); } } public static void LogDamage(string m) { if (DoomConfig.DebugLogging.Value) { Log.LogInfo((object)("[DoomDamage] " + m)); } } public static void LogMonster(string m) { if (DoomConfig.DebugLogging.Value) { Log.LogInfo((object)("[DoomMonster] " + m)); } } public static void LogNetwork(string m) { if (DoomConfig.DebugLogging.Value) { Log.LogInfo((object)("[DoomNetwork] " + m)); } } public static void LogSpawn(string m) { if (DoomConfig.DebugLogging.Value) { Log.LogInfo((object)("[DoomSpawn] " + m)); } } public static void HudHitMarker() { DoomHUD.Instance?.PingHit(); } public static void HudHeadshot() { DoomHUD.Instance?.PingHeadshot(); } public static void HudKillMarker() { DoomHUD.Instance?.PingKill(); } public static void HudLocalKill() { DoomHUD.Instance?.PingLocalKill(); } } } namespace ContentWarningDoom.Weapons { public class GrenadeProjectile : MonoBehaviour { private Vector3 _vel; private int _ownerActor; private bool _authoritative; private float _fuse; private int _bounces; private static bool _hooked; public static void HookNet() { if (_hooked) { return; } _hooked = true; DoomNet.OnGrenadeSpawn += delegate(int actor, Vector3 pos, Vector3 vel) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (actor != DoomNet.LocalActor) { SpawnLocal(pos, vel, actor); } }; } public static GrenadeProjectile SpawnLocal(Vector3 pos, Vector3 vel, int ownerActor) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "DoomGrenade"; Collider component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } obj.transform.position = pos; obj.transform.localScale = Vector3.one * 0.25f; MeshRenderer component2 = obj.GetComponent(); Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"); ((Renderer)component2).material = new Material(val) { color = new Color(0.15f, 0.35f, 0.1f) }; ((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0; TrailRenderer obj2 = obj.AddComponent(); obj2.time = 0.2f; obj2.startWidth = 0.12f; obj2.endWidth = 0f; ((Renderer)obj2).material = new Material(val) { color = new Color(1f, 0.6f, 0.2f, 0.5f) }; GrenadeProjectile grenadeProjectile = obj.AddComponent(); grenadeProjectile._vel = vel; grenadeProjectile._ownerActor = ownerActor; grenadeProjectile._authoritative = DoomNet.IsHost; grenadeProjectile._fuse = DoomConfig.GrenadeFuse.Value; return grenadeProjectile; } private void Update() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) float deltaTime = Time.deltaTime; _vel += Physics.gravity * deltaTime; float num = ((Vector3)(ref _vel)).magnitude * deltaTime; Vector3 val = ((((Vector3)(ref _vel)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref _vel)).normalized : Vector3.down); RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(((Component)this).transform.position, val, ref val2, num + 0.2f, -1, (QueryTriggerInteraction)1)) { if ((Object)(object)MonsterRegistry.Instance != (Object)null && MonsterRegistry.Instance.TryGetByCollider(((RaycastHit)(ref val2)).collider, out var h) && h.Alive) { Detonate(((RaycastHit)(ref val2)).point); return; } if (_bounces >= 1) { Detonate(((RaycastHit)(ref val2)).point); return; } _bounces++; ((Component)this).transform.position = ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.1f; _vel = Vector3.Reflect(_vel, ((RaycastHit)(ref val2)).normal) * 0.45f; } else { Transform transform = ((Component)this).transform; transform.position += _vel * deltaTime; } _fuse -= deltaTime; if (_fuse <= 0f) { Detonate(((Component)this).transform.position); } } private void Detonate(Vector3 at) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (_authoritative) { MonsterRegistry instance = MonsterRegistry.Instance; if ((Object)(object)instance != (Object)null) { MonsterHealth monsterHealth = instance.Nearest(at, 1.4f); if (monsterHealth != null) { DamageSystem.ApplyToHealth(monsterHealth, DoomConfig.GrenadeDirectDamage.Value, ((Vector3)(ref _vel)).normalized, DamageType.Explosion, _ownerActor); } DamageSystem.ApplyRadius(at, DoomConfig.GrenadeRadius.Value, DoomConfig.GrenadeExplosionDamage.Value, DamageType.Explosion, _ownerActor); } Plugin.LogWeapon($"grenade detonated at {at} (r={DoomConfig.GrenadeRadius.Value})"); } GrenadeBlast.Play(at, DoomConfig.GrenadeRadius.Value); Object.Destroy((Object)(object)((Component)this).gameObject); } } internal static class GrenadeBlast { public static void Play(Vector3 at, float radius) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown GameObject val = new GameObject("DoomGrenadeBlast"); val.transform.position = at; Light obj = val.AddComponent(); obj.type = (LightType)2; obj.range = radius * 3f; obj.intensity = 20f; obj.color = new Color(1f, 0.6f, 0.25f); ImpactEffects.SpawnWorld(at, Vector3.up); BloodEffects.SpawnDeath(at); val.AddComponent().life = 0.4f; CameraKick.Shake(3.5f, 0.25f, 18f); GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj2).name = "DoomGrenadeFireball"; Collider component = obj2.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } obj2.transform.position = at; obj2.transform.localScale = Vector3.one * 0.15f; MeshRenderer component2 = obj2.GetComponent(); Shader val2 = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"); Material val3 = new Material(val2) { color = new Color(1f, 0.55f, 0.15f) }; if (val3.HasProperty("_EmissionColor")) { val3.EnableKeyword("_EMISSION"); val3.SetColor("_EmissionColor", new Color(1f, 0.5f, 0.1f) * 3f); } ((Renderer)component2).material = val3; ((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0; obj2.AddComponent().Init(radius * 0.85f, 0.28f); GameObject obj3 = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj3).name = "DoomGrenadeShockwave"; Collider component3 = obj3.GetComponent(); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } obj3.transform.position = at; obj3.transform.localScale = new Vector3(0.15f, 0.03f, 0.15f); MeshRenderer component4 = obj3.GetComponent(); Material material = new Material(val2) { color = new Color(1f, 0.8f, 0.5f, 0.6f) }; ((Renderer)component4).material = material; ((Renderer)component4).shadowCastingMode = (ShadowCastingMode)0; obj3.AddComponent().Init(radius * 1.6f, 0.35f, flattenY: true); } } internal class GrenadeBlastAnim : MonoBehaviour { public float life = 0.4f; private float _t; private Light _l; private void Awake() { _l = ((Component)this).GetComponent(); } private void Update() { _t += Time.deltaTime; if ((Object)(object)_l != (Object)null) { _l.intensity = Mathf.Lerp(20f, 0f, _t / life); } if (_t >= life) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } internal class FireballAnim : MonoBehaviour { private float _maxScale; private float _life; private float _t; private bool _flattenY; private MeshRenderer _mr; private Color _startColor; public void Init(float maxScale, float life, bool flattenY = false) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) _maxScale = Mathf.Max(0.05f, maxScale); _life = Mathf.Max(0.05f, life); _flattenY = flattenY; _mr = ((Component)this).GetComponent(); if ((Object)(object)_mr != (Object)null) { _startColor = ((Renderer)_mr).material.color; } } private void Update() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_0104: Unknown result type (might be due to invalid IL or missing references) _t += Time.deltaTime; float num = Mathf.Clamp01(_t / _life); float num2 = 1f - (1f - num) * (1f - num); float num3 = Mathf.Lerp(0.15f, _maxScale, num2); ((Component)this).transform.localScale = (Vector3)(_flattenY ? new Vector3(num3, num3 * 0.2f, num3) : (Vector3.one * num3)); if ((Object)(object)_mr != (Object)null) { Color startColor = _startColor; startColor.a = Mathf.Lerp(_startColor.a, 0f, num); ((Renderer)_mr).material.color = startColor; if (((Renderer)_mr).material.HasProperty("_EmissionColor")) { ((Renderer)_mr).material.SetColor("_EmissionColor", ((Renderer)_mr).material.GetColor("_EmissionColor") * (1f - num)); } } if (_t >= _life) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } public static class ObjModelLoader { public sealed class Model { public Mesh mesh; public Material[] materials; } private static readonly Dictionary _cache = new Dictionary(); private static string _dir; public static string ModelsDir { get { if (_dir != null) { return _dir; } try { _dir = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? ".", "models"); } catch { _dir = "models"; } return _dir; } } public static bool Exists(string objFileNameNoExt) { return File.Exists(Path.Combine(ModelsDir, objFileNameNoExt + ".obj")); } public static Model Load(string objFileNameNoExt) { if (_cache.TryGetValue(objFileNameNoExt, out var value)) { return value; } value = null; try { string path = Path.Combine(ModelsDir, objFileNameNoExt + ".obj"); if (!File.Exists(path)) { _cache[objFileNameNoExt] = null; return null; } value = Parse(File.ReadAllLines(path), ModelsDir); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[DoomWeapon] OBJ load failed for " + objFileNameNoExt + ": " + ex.Message)); value = null; } _cache[objFileNameNoExt] = value; return value; } private static Model Parse(string[] lines, string dir) { //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Expected O, but got Unknown //IL_012f: 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_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Expected O, but got Unknown //IL_03b7: 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) List pos = new List(); List nrm = new List(); List matNames = new List(); Dictionary matIndexByName = new Dictionary(); List> tris = new List>(); Dictionary vmap = new Dictionary(); List outPos = new List(); List outNrm = new List(); int num = -1; string text = null; foreach (string text2 in lines) { if (string.IsNullOrEmpty(text2) || text2[0] == '#') { continue; } string[] array = text2.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { continue; } switch (array[0]) { case "mtllib": text = text2.Substring(7).Trim(); break; case "v": pos.Add(new Vector3(F(array[1]), F(array[2]), F(array[3]))); break; case "vn": nrm.Add(new Vector3(F(array[1]), F(array[2]), F(array[3]))); break; case "usemtl": num = EnsureSub((array.Length > 1) ? array[1] : "default"); break; case "f": { if (num < 0) { num = EnsureSub("default"); } int num2 = array.Length - 1; if (num2 >= 3) { int[] array2 = new int[num2]; for (int j = 0; j < num2; j++) { string[] array3 = array[j + 1].Split('/'); int p = int.Parse(array3[0], CultureInfo.InvariantCulture); int n = ((array3.Length >= 3 && array3[2].Length > 0) ? int.Parse(array3[2], CultureInfo.InvariantCulture) : int.MinValue); array2[j] = Vert(p, n); } List list = tris[num]; for (int k = 1; k < num2 - 1; k++) { list.Add(array2[0]); list.Add(array2[k]); list.Add(array2[k + 1]); } } break; } } } if (outPos.Count == 0) { return null; } Mesh val = new Mesh { name = "DoomGunMesh" }; if (outPos.Count > 65000) { val.indexFormat = (IndexFormat)1; } val.SetVertices(outPos); val.SetNormals(outNrm); val.subMeshCount = matNames.Count; for (int l = 0; l < matNames.Count; l++) { val.SetTriangles(tris[l], l, true); } val.RecalculateBounds(); Dictionary dictionary = ((text != null) ? LoadMtl(Path.Combine(dir, text)) : new Dictionary()); Material[] array4 = (Material[])(object)new Material[matNames.Count]; Shader val2 = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"); for (int m = 0; m < matNames.Count; m++) { Color value; Color val3 = (dictionary.TryGetValue(matNames[m], out value) ? value : Color.gray); Material val4 = new Material(val2) { name = "DoomGunMat_" + matNames[m] }; val4.color = val3; if (val4.HasProperty("_BaseColor")) { val4.SetColor("_BaseColor", val3); } if (val4.HasProperty("_Metallic")) { val4.SetFloat("_Metallic", 0.5f); } if (val4.HasProperty("_Smoothness")) { val4.SetFloat("_Smoothness", 0.45f); } if (val4.HasProperty("_Glossiness")) { val4.SetFloat("_Glossiness", 0.45f); } array4[m] = val4; } return new Model { mesh = val, materials = array4 }; int EnsureSub(string name) { if (!matIndexByName.TryGetValue(name, out var value2)) { value2 = matNames.Count; matIndexByName[name] = value2; matNames.Add(name); tris.Add(new List()); } return value2; } int Vert(int num3, int num4) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) num3 = ((num3 >= 0) ? (num3 - 1) : (pos.Count + num3)); if (num4 != int.MinValue) { num4 = ((num4 >= 0) ? (num4 - 1) : (nrm.Count + num4)); } long key = ((long)(num3 & 0xFFFFF) << 20) | (uint)((num4 == int.MinValue) ? 1048575 : (num4 & 0xFFFFF)); if (vmap.TryGetValue(key, out var value2)) { return value2; } value2 = outPos.Count; outPos.Add((num3 >= 0 && num3 < pos.Count) ? pos[num3] : Vector3.zero); outNrm.Add((num4 != int.MinValue && num4 >= 0 && num4 < nrm.Count) ? nrm[num4] : Vector3.up); vmap[key] = value2; return value2; } } private static Dictionary LoadMtl(string path) { //IL_00bc: 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) Dictionary dictionary = new Dictionary(); try { if (!File.Exists(path)) { return dictionary; } string text = null; string[] array = File.ReadAllLines(path); foreach (string text2 in array) { string[] array2 = text2.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 0 || text2[0] == '#') { continue; } if (array2[0] == "newmtl") { text = ((array2.Length > 1) ? array2[1] : "default"); if (!dictionary.ContainsKey(text)) { dictionary[text] = Color.gray; } } else if (array2[0] == "Kd" && text != null && array2.Length >= 4) { dictionary[text] = new Color(F(array2[1]), F(array2[2]), F(array2[3])); } } } catch { } return dictionary; } private static float F(string s) { return float.Parse(s, NumberStyles.Float, CultureInfo.InvariantCulture); } } public class BfgProjectile : MonoBehaviour { private Vector3 _dir; private int _ownerActor; private bool _authoritative; private float _life = 6f; private float _trackTimer; private static bool _netHooked; public static void HookNet() { if (_netHooked) { return; } _netHooked = true; DoomNet.OnBfgSpawn += delegate(int actor, Vector3 pos, Vector3 dir) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (actor != DoomNet.LocalActor) { SpawnLocal(pos, dir, actor, isOwner: false); } }; DoomNet.OnBfgExplode += delegate(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Explosion.Play(pos); BfgProjectile[] array = Object.FindObjectsOfType(); foreach (BfgProjectile bfgProjectile in array) { if (!bfgProjectile._authoritative) { Object.Destroy((Object)(object)((Component)bfgProjectile).gameObject); } } }; } public static BfgProjectile SpawnLocal(Vector3 pos, Vector3 dir, int ownerActor, bool isOwner) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0139: 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) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "DoomBFGOrb"; Collider component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } obj.transform.position = pos; obj.transform.localScale = Vector3.one * 1.4f; MeshRenderer component2 = obj.GetComponent(); Shader val = Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard"); ((Renderer)component2).material = new Material(val) { color = new Color(0.4f, 1f, 0.35f, 1f) }; Light obj2 = obj.AddComponent(); obj2.type = (LightType)2; obj2.range = 14f; obj2.intensity = 6f; obj2.color = new Color(0.4f, 1f, 0.4f); TrailRenderer obj3 = obj.AddComponent(); obj3.time = 0.35f; obj3.startWidth = 1.1f; obj3.endWidth = 0f; ((Renderer)obj3).material = new Material(val) { color = new Color(0.4f, 1f, 0.4f, 0.6f) }; BfgProjectile bfgProjectile = obj.AddComponent(); bfgProjectile._dir = ((Vector3)(ref dir)).normalized; bfgProjectile._ownerActor = ownerActor; bfgProjectile._authoritative = DoomNet.IsHost; return bfgProjectile; } private void Update() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) float deltaTime = Time.deltaTime; float num = DoomConfig.BFGProjectileSpeed.Value * deltaTime; RaycastHit val = default(RaycastHit); if (Physics.Raycast(((Component)this).transform.position, _dir, ref val, num + 0.7f, -1, (QueryTriggerInteraction)1)) { Detonate(((RaycastHit)(ref val)).point); return; } Transform transform = ((Component)this).transform; transform.position += _dir * num; _life -= deltaTime; if (_life <= 0f) { Detonate(((Component)this).transform.position); } else if (_authoritative) { _trackTimer += deltaTime; if (_trackTimer >= 0.25f) { DamageSystem.ApplyRadius(((Component)this).transform.position, DoomConfig.BFGRadius.Value * 0.6f, DoomConfig.BFGTrackingDamage.Value * _trackTimer, DamageType.BFG, _ownerActor); _trackTimer = 0f; } } } private void Detonate(Vector3 at) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (_authoritative) { MonsterRegistry instance = MonsterRegistry.Instance; if ((Object)(object)instance != (Object)null) { MonsterHealth monsterHealth = instance.Nearest(at, 3.5f); if (monsterHealth != null) { DamageSystem.ApplyToHealth(monsterHealth, DoomConfig.BFGDirectDamage.Value, _dir, DamageType.BFG, _ownerActor); } DamageSystem.ApplyRadius(at, DoomConfig.BFGRadius.Value, DoomConfig.BFGExplosionDamage.Value, DamageType.Explosion, _ownerActor); } DoomNet.SendBfgExplode(at); Plugin.LogWeapon($"BFG detonated at {at} (r={DoomConfig.BFGRadius.Value})"); } Explosion.Play(at); Object.Destroy((Object)(object)((Component)this).gameObject); } } internal static class Explosion { public static void Play(Vector3 at) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown GameObject val = new GameObject("DoomBFGBlast"); val.transform.position = at; Light obj = val.AddComponent(); obj.type = (LightType)2; obj.range = DoomConfig.BFGRadius.Value * 2.5f; obj.intensity = 18f; obj.color = new Color(0.5f, 1f, 0.5f); GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)0); Collider component = obj2.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } obj2.transform.SetParent(val.transform, false); obj2.transform.localScale = Vector3.one * 0.5f; Shader val2 = Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard"); ((Renderer)obj2.GetComponent()).material = new Material(val2) { color = new Color(0.6f, 1f, 0.6f, 1f) }; val.AddComponent().radius = DoomConfig.BFGRadius.Value; CameraKick.Shake(6f, 0.5f, 25f); } } internal class BlastAnim : MonoBehaviour { public float radius = 15f; private float _t; private Light _l; private Transform _ball; private void Awake() { _l = ((Component)this).GetComponent(); if (((Component)this).transform.childCount > 0) { _ball = ((Component)this).transform.GetChild(0); } } private void Update() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) _t += Time.deltaTime * 2.2f; float num = Mathf.Clamp01(_t); if ((Object)(object)_ball != (Object)null) { _ball.localScale = Vector3.one * Mathf.Lerp(0.5f, radius * 2f, num); } if ((Object)(object)_l != (Object)null) { _l.intensity = Mathf.Lerp(18f, 0f, num); } if (_t >= 1f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } public class RemotePlayerWeapons : MonoBehaviour { private sealed class Entry { public Player player; public GameObject go; public int weaponId = -1; } private readonly Dictionary _byActor = new Dictionary(); private readonly List _scratch = new List(); public static RemotePlayerWeapons Instance { get; private set; } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.RemotePlayerWeapons"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void OnEnable() { DoomNet.OnWeaponEquip += HandleEquip; DoomNet.OnWeaponFire += HandleFire; } private void OnDisable() { DoomNet.OnWeaponEquip -= HandleEquip; DoomNet.OnWeaponFire -= HandleFire; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void HandleEquip(int actor, byte weaponId) { Apply(actor, weaponId); } private void HandleFire(int actor, byte weaponId, Vector3 origin, Vector3 dir) { //IL_000b: 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) Apply(actor, weaponId); SpawnRemoteShotFx(actor, weaponId, origin, dir); } private void SpawnRemoteShotFx(int actor, int weaponId, Vector3 origin, Vector3 dir) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (DoomConfig.ShowRemotePlayerWeapons.Value && Plugin.DoomModeActive && actor != DoomNet.LocalActor && weaponId != 3 && weaponId != 5 && !(((Vector3)(ref dir)).sqrMagnitude < 0.0001f)) { dir = ((Vector3)(ref dir)).normalized; Vector3 val = origin + dir * 0.5f; if (_byActor.TryGetValue(actor, out var value) && (Object)(object)value.go != (Object)null) { val = value.go.transform.position + dir * 0.25f; } float num = 120f; Vector3 to = origin + dir * num; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(origin + dir * 0.3f, dir, ref val2, num, -1, (QueryTriggerInteraction)1)) { to = ((RaycastHit)(ref val2)).point; } ImpactEffects.RemoteMuzzle(val); ImpactEffects.Tracer(val, to); } } private void Apply(int actor, int weaponId) { //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Expected O, but got Unknown //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (!DoomConfig.ShowRemotePlayerWeapons.Value || !Plugin.DoomModeActive || actor == 0 || actor == DoomNet.LocalActor || weaponId < 0 || weaponId >= 11) { return; } if (!_byActor.TryGetValue(actor, out var value)) { value = new Entry(); _byActor[actor] = value; } if ((Object)(object)value.player == (Object)null) { value.player = ActionRoundManager.FindPlayerByActor(actor); } if ((Object)(object)value.player == (Object)null || ((Object)(object)value.go != (Object)null && value.weaponId == weaponId)) { return; } if ((Object)(object)value.go != (Object)null) { Object.Destroy((Object)(object)value.go); } value.go = null; value.weaponId = -1; Transform val = null; Vector3 zero = Vector3.zero; string text = "?"; try { if (value.player.refs != null && (Object)(object)value.player.refs.animator != (Object)null && value.player.refs.animator.isHuman) { val = value.player.refs.animator.GetBoneTransform((HumanBodyBones)18); if ((Object)(object)val != (Object)null) { text = "Animator.RightHand"; } } } catch { } if ((Object)(object)val == (Object)null && value.player.refs != null && (Object)(object)value.player.refs.bodyMeshRenderer != (Object)null) { Transform[] bones = value.player.refs.bodyMeshRenderer.bones; if (bones != null) { Transform[] array = bones; foreach (Transform val2 in array) { if (!((Object)(object)val2 == (Object)null)) { string text2 = ((Object)val2).name.ToLowerInvariant(); bool num = text2.Contains("hand") || text2.Contains("wrist"); bool flag = text2.EndsWith("_r") || text2.EndsWith(".r") || text2.EndsWith("_r_") || text2.Contains("right"); if (num && flag) { val = val2; text = "bone:" + ((Object)val2).name; break; } } } } } if ((Object)(object)val == (Object)null && value.player.refs != null) { try { val = value.player.refs.IK_Hand_R; } catch { } if ((Object)(object)val != (Object)null) { text = "IK_Hand_R"; } } if ((Object)(object)val == (Object)null) { val = PlayerHands.RightOf(value.player); if ((Object)(object)val != (Object)null) { text = "ragdoll.Hand_R"; } } if ((Object)(object)val == (Object)null && value.player.refs != null && (Object)(object)value.player.refs.headPos != (Object)null) { val = value.player.refs.headPos; ((Vector3)(ref zero))..ctor(0.24f, -0.34f, 0.22f); text = "headPos(fallback)"; } if ((Object)(object)val == (Object)null) { Plugin.LogWeapon($"remote gun for actor {actor}: no anchor, skipped"); return; } float muzzleForward; GameObject val3 = WeaponVisual.BuildGunMeshGO((WeaponId)weaponId, DoomConfig.GunModelScaleMul.Value * Mathf.Max(0.05f, DoomConfig.RemoteWeaponScaleMul.Value), out muzzleForward); if ((Object)(object)val3 == (Object)null) { Plugin.LogWeapon($"remote gun for actor {actor}: model {(WeaponId)weaponId} failed to load"); return; } GameObject val4 = new GameObject("DoomRemoteGun"); val4.transform.SetParent(val, false); val4.transform.localPosition = ParseVec(DoomConfig.RemoteWeaponOffset.Value) + zero; val4.transform.localRotation = Quaternion.Euler(ParseVec(DoomConfig.RemoteWeaponEuler.Value)); float x = val.lossyScale.x; if (x > 0.0001f) { val4.transform.localScale = Vector3.one * (1f / x); } val3.transform.SetParent(val4.transform, false); WeaponVisual.SetLayer(val4, 0); value.go = val4; value.weaponId = weaponId; Plugin.LogWeapon($"remote gun for actor {actor}: {(WeaponId)weaponId} on {text} (handScale {x:0.###}, gunScale {val4.transform.localScale.x:0.###})"); } private void Update() { if (!Plugin.DoomModeActive || !DoomConfig.ShowRemotePlayerWeapons.Value) { if (_byActor.Count > 0) { ClearAll(); } return; } _scratch.Clear(); foreach (KeyValuePair item in _byActor) { Entry value = item.Value; if ((Object)(object)value.player == (Object)null || (Object)(object)value.go == (Object)null || (Object)(object)value.go.transform.parent == (Object)null) { _scratch.Add(item.Key); } } for (int i = 0; i < _scratch.Count; i++) { if (_byActor.TryGetValue(_scratch[i], out var value2) && (Object)(object)value2.go != (Object)null) { Object.Destroy((Object)(object)value2.go); } _byActor.Remove(_scratch[i]); } } private void ClearAll() { foreach (KeyValuePair item in _byActor) { if ((Object)(object)item.Value.go != (Object)null) { Object.Destroy((Object)(object)item.Value.go); } } _byActor.Clear(); } private static Vector3 ParseVec(string s) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(s)) { return Vector3.zero; } string[] array = s.Split(','); if (array.Length != 3) { return Vector3.zero; } float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result); float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2); float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3); return new Vector3(result, result2, result3); } } public enum WeaponId : byte { Pistol, Shotgun, SuperShotgun, BFG, Minigun, GrenadeLauncher, Smg, AssaultRifle, Marksman, AutoShotgun, Crossbow } public class WeaponDef { public WeaponId Id; public string Name; public int MagSize; public int Reserve; public float ReloadTime; public float FireDelay; public float Range; public int Pellets; public float DamagePerShot; public float SpreadDeg; public DamageType DamageType; public float RecoilKick; public float HandRecoilForce; public bool Automatic; } public static class WeaponTable { public static WeaponDef Get(WeaponId id) { return id switch { WeaponId.Pistol => new WeaponDef { Id = id, Name = "PISTOL", MagSize = DoomConfig.PistolMagazine.Value, Reserve = DoomConfig.PistolReserve.Value, ReloadTime = DoomConfig.PistolReload.Value, FireDelay = 1f / Mathf.Max(0.1f, DoomConfig.PistolFireRate.Value), Range = DoomConfig.PistolRange.Value, Pellets = 1, DamagePerShot = DoomConfig.PistolDamage.Value, SpreadDeg = 0.4f, DamageType = DamageType.Bullet, RecoilKick = 1f, HandRecoilForce = 7f }, WeaponId.Shotgun => new WeaponDef { Id = id, Name = "SHOTGUN", MagSize = DoomConfig.ShotgunMagazine.Value, Reserve = DoomConfig.ShotgunReserve.Value, ReloadTime = DoomConfig.ShotgunReload.Value, FireDelay = DoomConfig.ShotgunFireDelay.Value, Range = DoomConfig.ShotgunRange.Value, Pellets = DoomConfig.ShotgunPellets.Value, DamagePerShot = DoomConfig.ShotgunDamagePerPellet.Value, SpreadDeg = DoomConfig.ShotgunSpread.Value, DamageType = DamageType.Pellet, RecoilKick = 2.4f, HandRecoilForce = 20f }, WeaponId.SuperShotgun => new WeaponDef { Id = id, Name = "SUPER SHOTGUN", MagSize = DoomConfig.SuperShotgunMagazine.Value, Reserve = DoomConfig.SuperShotgunReserve.Value, ReloadTime = DoomConfig.SuperShotgunReload.Value, FireDelay = DoomConfig.SuperShotgunFireDelay.Value, Range = DoomConfig.SuperShotgunRange.Value, Pellets = DoomConfig.SuperShotgunPellets.Value, DamagePerShot = DoomConfig.SuperShotgunDamagePerPellet.Value, SpreadDeg = DoomConfig.SuperShotgunSpread.Value, DamageType = DamageType.Pellet, RecoilKick = 4.5f, HandRecoilForce = 32f }, WeaponId.Minigun => new WeaponDef { Id = id, Name = "MINIGUN", MagSize = DoomConfig.MinigunMagazine.Value, Reserve = DoomConfig.MinigunReserve.Value, ReloadTime = DoomConfig.MinigunReload.Value, FireDelay = 1f / Mathf.Max(1f, DoomConfig.MinigunFireRate.Value), Range = DoomConfig.MinigunRange.Value, Pellets = 1, DamagePerShot = DoomConfig.MinigunDamage.Value, SpreadDeg = DoomConfig.MinigunSpread.Value, DamageType = DamageType.Bullet, RecoilKick = 1.6f, HandRecoilForce = 5f }, WeaponId.GrenadeLauncher => new WeaponDef { Id = id, Name = "GRENADE LAUNCHER", MagSize = DoomConfig.GrenadeMagazine.Value, Reserve = DoomConfig.GrenadeReserve.Value, ReloadTime = DoomConfig.GrenadeReload.Value, FireDelay = DoomConfig.GrenadeFireDelay.Value, Range = 400f, Pellets = 0, DamagePerShot = DoomConfig.GrenadeDirectDamage.Value, SpreadDeg = 0f, DamageType = DamageType.Explosion, RecoilKick = 3.2f, HandRecoilForce = 18f }, WeaponId.Smg => new WeaponDef { Id = id, Name = "SMG", MagSize = 30, Reserve = 240, ReloadTime = 1.7f, FireDelay = 1f / 12f, Range = 60f, Pellets = 1, DamagePerShot = 13f, SpreadDeg = 2.4f, DamageType = DamageType.Bullet, RecoilKick = 1.1f, HandRecoilForce = 5f, Automatic = true }, WeaponId.AssaultRifle => new WeaponDef { Id = id, Name = "ASSAULT RIFLE", MagSize = 24, Reserve = 180, ReloadTime = 2.1f, FireDelay = 0.125f, Range = 95f, Pellets = 1, DamagePerShot = 22f, SpreadDeg = 1.1f, DamageType = DamageType.Bullet, RecoilKick = 1.9f, HandRecoilForce = 10f, Automatic = true }, WeaponId.Marksman => new WeaponDef { Id = id, Name = "MARKSMAN RIFLE", MagSize = 10, Reserve = 60, ReloadTime = 2.6f, FireDelay = 0.34f, Range = 160f, Pellets = 1, DamagePerShot = 68f, SpreadDeg = 0.12f, DamageType = DamageType.Bullet, RecoilKick = 3f, HandRecoilForce = 16f, Automatic = false }, WeaponId.AutoShotgun => new WeaponDef { Id = id, Name = "AUTO SHOTGUN", MagSize = 8, Reserve = 64, ReloadTime = 3f, FireDelay = 0.5f, Range = 24f, Pellets = 9, DamagePerShot = 11f, SpreadDeg = 6.5f, DamageType = DamageType.Pellet, RecoilKick = 3f, HandRecoilForce = 22f, Automatic = false }, WeaponId.Crossbow => new WeaponDef { Id = id, Name = "CROSSBOW", MagSize = 1, Reserve = 24, ReloadTime = 1.2f, FireDelay = 1f, Range = 130f, Pellets = 1, DamagePerShot = 130f, SpreadDeg = 0.05f, DamageType = DamageType.Bullet, RecoilKick = 2f, HandRecoilForce = 13f, Automatic = false }, _ => new WeaponDef { Id = WeaponId.BFG, Name = "BFG 9000", MagSize = DoomConfig.BFGMagazine.Value, Reserve = DoomConfig.BFGReserve.Value, ReloadTime = DoomConfig.BFGReload.Value, FireDelay = DoomConfig.BFGFireDelay.Value, Range = 500f, Pellets = 0, DamagePerShot = DoomConfig.BFGDirectDamage.Value, SpreadDeg = 0f, DamageType = DamageType.BFG, RecoilKick = 5f, HandRecoilForce = 38f }, }; } } public abstract class WeaponBase { public WeaponDef Def; public int Mag; public int Reserve; private float _cooldown; private float _reloadTimer; public bool Reloading => _reloadTimer > 0f; public float ReloadProgress { get { if (!(Def.ReloadTime <= 0f)) { return 1f - Mathf.Clamp01(_reloadTimer / Def.ReloadTime); } return 1f; } } public float RecoilImpulse { get; private set; } protected virtual bool IsAutomatic => false; protected WeaponBase(WeaponId id) { Def = WeaponTable.Get(id); Mag = Def.MagSize; Reserve = Def.Reserve; } public void Tick(float dt, bool firePressedThisFrame, bool fireHeld, bool reloadPressed, Vector3 origin, Vector3 dir) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (_cooldown > 0f) { _cooldown -= dt; } if (_reloadTimer > 0f) { _reloadTimer -= dt; if (_reloadTimer <= 0f) { FinishReload(); } return; } RecoilImpulse = Mathf.MoveTowards(RecoilImpulse, 0f, dt * 8f); if (reloadPressed) { TryStartReload(); } else if ((IsAutomatic ? fireHeld : firePressedThisFrame) && _cooldown <= 0f) { if (Mag <= 0) { TryStartReload(); } else { Fire(origin, dir); } } } private void Fire(Vector3 origin, Vector3 dir) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) Mag--; _cooldown = Def.FireDelay; RecoilImpulse = Mathf.Min(1f, RecoilImpulse + 1f); Plugin.LogWeapon($"{Def.Name} fired ({Mag}/{Reserve})"); DoomNet.SendWeaponFire((byte)Def.Id, origin, dir); WeaponAudio.PlayFire(Def.Id, origin); DoFire(origin, dir); } protected abstract void DoFire(Vector3 origin, Vector3 dir); public void TryStartReload() { if (!(_reloadTimer > 0f) && Mag < Def.MagSize && Reserve > 0) { _reloadTimer = Def.ReloadTime; WeaponAudio.PlayReload(Def.Id); Plugin.LogWeapon(Def.Name + " reloading"); } } private void FinishReload() { int num = Mathf.Min(Def.MagSize - Mag, Reserve); Mag += num; Reserve -= num; _reloadTimer = 0f; } public void AddReserve(int amount) { Reserve = Mathf.Min(Reserve + amount, Def.Reserve * 3); } } public class PistolWeapon : WeaponBase { public PistolWeapon() : base(WeaponId.Pistol) { } protected override void DoFire(Vector3 o, Vector3 d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) Hitscan.Shot(o, d, Def.Range, Def.DamagePerShot, Def.DamageType, (byte)Def.Id, Def.SpreadDeg, 1); } } public class ShotgunWeapon : WeaponBase { public ShotgunWeapon() : base(WeaponId.Shotgun) { } protected override void DoFire(Vector3 o, Vector3 d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) Hitscan.Shot(o, d, Def.Range, Def.DamagePerShot, Def.DamageType, (byte)Def.Id, Def.SpreadDeg, Def.Pellets); } } public class SuperShotgunWeapon : WeaponBase { public SuperShotgunWeapon() : base(WeaponId.SuperShotgun) { } protected override void DoFire(Vector3 o, Vector3 d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) Hitscan.Shot(o, d, Def.Range, Def.DamagePerShot, Def.DamageType, (byte)Def.Id, Def.SpreadDeg, Def.Pellets); } } public class BFGWeapon : WeaponBase { public BFGWeapon() : base(WeaponId.BFG) { } protected override void DoFire(Vector3 o, Vector3 d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) BfgProjectile.SpawnLocal(o + d * 1.2f, d, DoomNet.LocalActor, isOwner: true); DoomNet.SendBfgSpawn(o + d * 1.2f, d); } } public class MinigunWeapon : WeaponBase { protected override bool IsAutomatic => true; public MinigunWeapon() : base(WeaponId.Minigun) { } protected override void DoFire(Vector3 o, Vector3 d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) Hitscan.Shot(o, d, Def.Range, Def.DamagePerShot, Def.DamageType, (byte)Def.Id, Def.SpreadDeg, 1); } } public class GrenadeLauncherWeapon : WeaponBase { public GrenadeLauncherWeapon() : base(WeaponId.GrenadeLauncher) { } protected override void DoFire(Vector3 o, Vector3 d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) GrenadeProjectile.SpawnLocal(o + d * 1f, d * DoomConfig.GrenadeSpeed.Value, DoomNet.LocalActor); DoomNet.SendGrenadeSpawn(o + d * 1f, d * DoomConfig.GrenadeSpeed.Value); } } public class GenericHitscanWeapon : WeaponBase { private readonly bool _auto; protected override bool IsAutomatic => _auto; public GenericHitscanWeapon(WeaponId id) : base(id) { _auto = Def.Automatic; } protected override void DoFire(Vector3 o, Vector3 d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) Hitscan.Shot(o, d, Def.Range, Def.DamagePerShot, Def.DamageType, (byte)Def.Id, Def.SpreadDeg, Mathf.Max(1, Def.Pellets)); } } public static class Hitscan { private class HitComparer : IComparer { public static readonly HitComparer Instance = new HitComparer(); public int Compare(RaycastHit a, RaycastHit b) { float num = (((Object)(object)((RaycastHit)(ref a)).collider == (Object)null) ? float.MaxValue : ((RaycastHit)(ref a)).distance); float value = (((Object)(object)((RaycastHit)(ref b)).collider == (Object)null) ? float.MaxValue : ((RaycastHit)(ref b)).distance); return num.CompareTo(value); } } private static readonly RaycastHit[] _buf = (RaycastHit[])(object)new RaycastHit[24]; public static void Shot(Vector3 origin, Vector3 dir, float range, float damagePerPellet, DamageType type, byte weaponId, float spreadDeg, int pellets) { //IL_0019: 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_0016: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(1, pellets); for (int i = 0; i < num; i++) { Vector3 dir2 = ((spreadDeg > 0f) ? Cone(dir, spreadDeg) : dir); ResolveOne(origin, dir2, range, damagePerPellet, type, weaponId, i == 0); } } private static void ResolveOne(Vector3 camOrigin, Vector3 dir, float range, float damage, DamageType type, byte weaponId, bool log) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.localPlayer; Transform val = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).transform.root : null); Vector3 val2 = camOrigin + dir * 0.6f; int num = Physics.RaycastNonAlloc(val2, dir, _buf, range, -1, (QueryTriggerInteraction)2); if (num <= 0) { if (log) { Plugin.LogWeapon("shot hit nothing (open air)"); } ImpactEffects.Tracer(camOrigin, val2 + dir * range); return; } Array.Sort(_buf, 0, num, HitComparer.Instance); for (int i = 0; i < num; i++) { RaycastHit val3 = _buf[i]; Collider collider = ((RaycastHit)(ref val3)).collider; if ((Object)(object)collider == (Object)null) { continue; } Transform root = ((Component)collider).transform.root; if ((Object)(object)MonsterRegistry.Instance != (Object)null && MonsterRegistry.Instance.TryGetByCollider(collider, out var h)) { if (h.Alive) { HitZone hitZone = MonsterHitZoneResolver.Resolve(h, collider, ((RaycastHit)(ref val3)).point); float num2 = damage; if (hitZone == HitZone.Head) { num2 *= Mathf.Max(1f, DoomConfig.HeadshotDamageMultiplier.Value); ActionEvents.RaiseLocalHeadshot(); } ActionEvents.RaiseLocalHitDealt(h.ViewId, hitZone, (byte)type); if (log) { Plugin.LogWeapon($"shot hit {h.MonsterName} id={h.ViewId} zone={hitZone} @ {((RaycastHit)(ref val3)).distance:0.0}m"); } ImpactEffects.Tracer(camOrigin, ((RaycastHit)(ref val3)).point); DamageSystem.ReportHit(h, num2, ((RaycastHit)(ref val3)).point, ((RaycastHit)(ref val3)).normal, dir, type, weaponId, hitZone); return; } } else { if ((Object)(object)root == (Object)(object)val) { continue; } Player componentInParent = ((Component)collider).GetComponentInParent(); if (((Object)(object)componentInParent != (Object)null && ((Object)(object)componentInParent == (Object)(object)localPlayer || (componentInParent.refs != null && (Object)(object)componentInParent.refs.view != (Object)null && componentInParent.refs.view.IsMine))) || (Object)(object)((Component)collider).GetComponentInParent() != (Object)null || (Object)(object)((Component)collider).GetComponentInParent() != (Object)null || (Object)(object)((Component)root).GetComponentInChildren() != (Object)null || collider.isTrigger) { continue; } if ((Object)(object)componentInParent != (Object)null) { ImpactEffects.Tracer(camOrigin, ((RaycastHit)(ref val3)).point); if (!DamageSystem.FriendlyFireLive()) { if (log) { Plugin.LogWeapon("hit teammate '" + ((Object)componentInParent).name + "' — friendly fire not live yet (surface or pre-Action)"); } return; } int num3 = 0; try { if (componentInParent.refs != null && (Object)(object)componentInParent.refs.view != (Object)null && componentInParent.refs.view.Owner != null) { num3 = componentInParent.refs.view.Owner.ActorNumber; } } catch { } if (num3 == 0 && (Object)(object)((MonoBehaviourPun)componentInParent).photonView != (Object)null) { num3 = ((MonoBehaviourPun)componentInParent).photonView.OwnerActorNr; } float num4 = damage * Mathf.Max(0f, DoomConfig.FriendlyFireDamageMultiplier.Value); if (num3 != 0 && num4 > 0f) { BloodEffects.SpawnHit(((RaycastHit)(ref val3)).point, ((RaycastHit)(ref val3)).normal); DoomNet.SendFriendlyHit(num3, num4); if (log) { Plugin.LogWeapon($"friendly fire {num4:0} -> actor {num3} ('{((Object)componentInParent).name}') @ {((RaycastHit)(ref val3)).distance:0.0}m"); } } else if (log) { Plugin.LogWeapon($"friendly fire NOT sent: targetActor={num3} ff={num4:0.0} ('{((Object)componentInParent).name}')"); } } else { if (log) { Plugin.LogWeapon($"shot blocked by world: '{((Object)collider).name}' root='{((Object)root).name}' layer={LayerMask.LayerToName(((Component)collider).gameObject.layer)} @ {((RaycastHit)(ref val3)).distance:0.0}m"); } ImpactEffects.Tracer(camOrigin, ((RaycastHit)(ref val3)).point); DamageSystem.ReportWorldImpact(((RaycastHit)(ref val3)).point, ((RaycastHit)(ref val3)).normal); } return; } } if (log) { Plugin.LogWeapon("shot passed through everything (no solid hit)"); } ImpactEffects.Tracer(camOrigin, val2 + dir * range); } public static Vector3 Cone(Vector3 forward, float halfAngleDeg) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) float num = halfAngleDeg * (MathF.PI / 180f); Vector2 val = Random.insideUnitCircle * Mathf.Tan(num); Quaternion val2 = Quaternion.LookRotation(forward); Vector3 val3 = new Vector3(val.x, val.y, 1f); Vector3 normalized = ((Vector3)(ref val3)).normalized; return val2 * normalized; } } public class WeaponManager : MonoBehaviour { public const int Count = 6; public const int WeaponIdCount = 11; private static readonly WeaponId[] SlotDefaults = new WeaponId[6] { WeaponId.Pistol, WeaponId.Shotgun, WeaponId.SuperShotgun, WeaponId.BFG, WeaponId.Minigun, WeaponId.GrenadeLauncher }; private readonly WeaponBase[] _weapons = new WeaponBase[6]; private readonly bool[] _unlocked = new bool[6]; private readonly WeaponId[] _slot = (WeaponId[])SlotDefaults.Clone(); private readonly bool[] _slotBought = new bool[6]; private int _current = -1; private WeaponVisual _visual; private int _lastMag; private float _lastEquipBroadcast; public static WeaponManager Instance { get; private set; } public bool HasWeapon { get { if (_current >= 0) { return _weapons[_current] != null; } return false; } } public WeaponBase Current { get { if (!HasWeapon) { return null; } return _weapons[_current]; } } public WeaponDef CurrentDef { get { if (!HasWeapon) { return null; } return _weapons[_current].Def; } } public int Mag { get { if (!HasWeapon) { return 0; } return _weapons[_current].Mag; } } public int Reserve { get { if (!HasWeapon) { return 0; } return _weapons[_current].Reserve; } } public bool Reloading { get { if (HasWeapon) { return _weapons[_current].Reloading; } return false; } } public float ReloadProgress { get { if (!HasWeapon) { return 1f; } return _weapons[_current].ReloadProgress; } } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.WeaponManager"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private static WeaponBase Make(WeaponId id) { return id switch { WeaponId.Pistol => new PistolWeapon(), WeaponId.Shotgun => new ShotgunWeapon(), WeaponId.SuperShotgun => new SuperShotgunWeapon(), WeaponId.BFG => new BFGWeapon(), WeaponId.Minigun => new MinigunWeapon(), WeaponId.GrenadeLauncher => new GrenadeLauncherWeapon(), _ => new GenericHitscanWeapon(id), }; } private void Awake() { for (int i = 0; i < 6; i++) { _weapons[i] = Make(_slot[i]); } } public void OnDoomModeEnabled() { RebuildWeapons(); _unlocked[0] = true; for (int i = 1; i < 6; i++) { _unlocked[i] = _slotBought[i]; } Select(0); } public void OnDoomModeDisabled() { for (int i = 0; i < 6; i++) { _unlocked[i] = false; } _current = -1; DestroyVisual(); } public void RebuildWeapons() { for (int i = 0; i < 6; i++) { WeaponBase weaponBase = _weapons[i]; WeaponBase weaponBase2 = Make(_slot[i]); if (weaponBase != null && weaponBase.Def.Id == weaponBase2.Def.Id) { weaponBase2.Mag = Mathf.Min(weaponBase.Mag, weaponBase2.Def.MagSize); weaponBase2.Reserve = weaponBase.Reserve; } _weapons[i] = weaponBase2; } } public WeaponId SlotWeapon(int slot) { if (slot < 0 || slot >= 6) { return WeaponId.Pistol; } return _slot[slot]; } public WeaponId SlotDefault(int slot) { if (slot < 0 || slot >= 6) { return WeaponId.Pistol; } return SlotDefaults[slot]; } public bool SlotIsCustom(int slot) { if (slot >= 0 && slot < 6) { return _slot[slot] != SlotDefaults[slot]; } return false; } public void SetSlotWeapon(int slot, WeaponId id) { if (slot >= 0 && slot < 6) { _slot[slot] = id; bool flag = id != SlotDefaults[slot]; _slotBought[slot] = flag; WeaponBase weaponBase = Make(id); weaponBase.Reserve = weaponBase.Def.Reserve; _weapons[slot] = weaponBase; if (flag) { _unlocked[slot] = true; } if (_current == slot && Plugin.DoomModeActive) { _lastMag = weaponBase.Mag; BuildVisual(); BroadcastEquip(); } Plugin.LogWeapon(string.Format("slot {0} -> {1}{2}", slot + 1, id, flag ? " (bench)" : " (default)")); } } public void ResetSlot(int slot) { SetSlotWeapon(slot, SlotDefault(slot)); } public void UnlockAll() { for (int i = 0; i < 6; i++) { _unlocked[i] = true; } Plugin.LogWeapon("All weapons unlocked (debug)"); } public void Unlock(WeaponId id) { if ((int)id < 6) { _unlocked[(uint)id] = true; Plugin.LogWeapon($"{id} unlocked"); } } public bool IsUnlocked(WeaponId id) { if ((int)id < 6) { return _unlocked[(uint)id]; } return false; } public void SelectById(WeaponId id) { if ((int)id < 6 && _unlocked[(uint)id]) { Select((int)id); } } public void GiveAmmo(WeaponId id, int amount) { for (int i = 0; i < 6; i++) { if (_weapons[i] != null && _weapons[i].Def.Id == id) { _weapons[i].AddReserve(amount); break; } } } public void GiveAmmoAll(float frac) { WeaponBase[] weapons = _weapons; foreach (WeaponBase weaponBase in weapons) { weaponBase?.AddReserve(Mathf.RoundToInt((float)weaponBase.Def.Reserve * frac)); } } private void Select(int idx) { if (idx >= 0 && idx < 6 && _weapons[idx] != null && _unlocked[idx]) { _current = idx; _lastMag = _weapons[idx].Mag; BuildVisual(); BroadcastEquip(); Plugin.LogWeapon("Selected " + _weapons[idx].Def.Name); } } public void OnSceneReloaded() { _visual = null; if (_current < 0 || !_unlocked[_current]) { _current = -1; for (int i = 0; i < 6; i++) { if (_unlocked[i]) { _current = i; break; } } } if (_current < 0 && Plugin.DoomModeActive) { _unlocked[0] = true; _current = 0; } if (HasWeapon) { _lastMag = _weapons[_current].Mag; } } private void Update() { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Invalid comparison between Unknown and I4 //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.DoomModeActive) { DestroyVisual(); return; } Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.data == null || localPlayer.data.dead || (Object)(object)MainCamera.instance == (Object)null) { return; } if (!HasWeapon) { for (int i = 0; i < 6; i++) { if (_unlocked[i]) { _current = i; _lastMag = _weapons[i].Mag; break; } } if (!HasWeapon) { _unlocked[0] = true; _current = 0; _lastMag = _weapons[0].Mag; } } if ((Object)(object)_visual == (Object)null) { BuildVisual(); } else if (DoomConfig.AttachToRealHands.Value) { Transform val = PlayerHands.Right(); if ((Object)(object)val != (Object)null && (Object)(object)_visual.ParentedTo != (Object)(object)val) { BuildVisual(); } } bool num = (int)Cursor.lockState == 1; Keyboard current = Keyboard.current; Mouse current2 = Mouse.current; if (num && current != null) { if (((ButtonControl)current.digit1Key).wasPressedThisFrame) { Select(0); } else if (((ButtonControl)current.digit2Key).wasPressedThisFrame) { Select(1); } else if (((ButtonControl)current.digit3Key).wasPressedThisFrame) { Select(2); } else if (((ButtonControl)current.digit4Key).wasPressedThisFrame) { Select(3); } else if (((ButtonControl)current.digit5Key).wasPressedThisFrame) { Select(4); } else if (((ButtonControl)current.digit6Key).wasPressedThisFrame) { Select(5); } else if (((ButtonControl)current.leftBracketKey).wasPressedThisFrame) { Cycle(-1); } else if (((ButtonControl)current.rightBracketKey).wasPressedThisFrame) { Cycle(1); } } bool firePressedThisFrame = num && current2 != null && current2.leftButton.wasPressedThisFrame; bool fireHeld = num && current2 != null && current2.leftButton.isPressed; bool reloadPressed = num && current != null && ((ButtonControl)current.rKey).wasPressedThisFrame; Transform transform = ((Component)MainCamera.instance).transform; WeaponBase weaponBase = _weapons[_current]; weaponBase.Tick(Time.deltaTime, firePressedThisFrame, fireHeld, reloadPressed, transform.position, transform.forward); if (weaponBase.Mag < _lastMag) { WeaponDef def = weaponBase.Def; CameraKick.Shake(def.RecoilKick, 0.14f, 10f + def.RecoilKick * 3f); _visual?.OnFired(def.RecoilKick); HandRecoil.Kick(transform.forward, def.HandRecoilForce); } _lastMag = weaponBase.Mag; _visual?.Tick(weaponBase.RecoilImpulse, weaponBase.Reloading); if (Time.time - _lastEquipBroadcast > 2f) { BroadcastEquip(); } } private void BroadcastEquip() { if (HasWeapon) { _lastEquipBroadcast = Time.time; DoomNet.SendWeaponEquip((byte)_weapons[_current].Def.Id); } } private void Cycle(int step) { for (int i = 1; i <= 6; i++) { int num = ((_current + step * i) % 6 + 6) % 6; if (_unlocked[num]) { Select(num); break; } } } public void RefreshVisual() { if (Plugin.DoomModeActive && HasWeapon) { BuildVisual(); } } private void BuildVisual() { DestroyVisual(); if (!((Object)(object)MainCamera.instance == (Object)null) && CurrentDef != null) { Transform val = (DoomConfig.AttachToRealHands.Value ? PlayerHands.Right() : null); Transform parent = (((Object)(object)val != (Object)null) ? val : ((Component)MainCamera.instance).transform); _visual = WeaponVisual.Build(parent, CurrentDef.Id, (Object)(object)val != (Object)null); } } private void DestroyVisual() { if ((Object)(object)_visual != (Object)null) { Object.Destroy((Object)(object)((Component)_visual).gameObject); _visual = null; } } public bool[] UnlockedSnapshot() { return (bool[])_unlocked.Clone(); } } public class WeaponVisual : MonoBehaviour { private Transform _model; private Transform _muzzle; private Transform _grip; private MuzzleFlash _flash; private Vector3 _restPos; private Quaternion _restRot; private float _recoilPos; private float _recoilRot; private bool _handAttached; private static string _eulerSrc; private static readonly Dictionary _eulerMap = new Dictionary(); public Transform ParentedTo => ((Component)this).transform.parent; public static WeaponVisual Build(Transform parent, WeaponId id, bool handAttached) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DoomWeaponVisual"); val.transform.SetParent(parent, false); WeaponVisual weaponVisual = val.AddComponent(); weaponVisual._handAttached = handAttached; weaponVisual.Construct(id); return weaponVisual; } private static string ModelName(WeaponId id) { return id switch { WeaponId.Pistol => "Pistol_1", WeaponId.Shotgun => "AR_4", WeaponId.SuperShotgun => "AR_5", WeaponId.BFG => "Sniper_3", WeaponId.Minigun => "AR_3", WeaponId.GrenadeLauncher => "Grenade_1", WeaponId.Smg => "SMG_1", WeaponId.AssaultRifle => "AR_1", WeaponId.Marksman => "Sniper_1", WeaponId.AutoShotgun => "AR_6", WeaponId.Crossbow => "Crossbow_1", _ => "Pistol_1", }; } private static Color MainAccent(WeaponId id) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) return (Color)(id switch { WeaponId.Pistol => new Color(0.6f, 0.6f, 0.66f), WeaponId.Shotgun => new Color(0.55f, 0.35f, 0.15f), WeaponId.SuperShotgun => new Color(0.5f, 0.3f, 0.12f), WeaponId.BFG => new Color(0.2f, 0.95f, 0.4f), WeaponId.Minigun => new Color(0.36f, 0.38f, 0.42f), WeaponId.GrenadeLauncher => new Color(0.38f, 0.42f, 0.2f), WeaponId.Smg => new Color(0.45f, 0.47f, 0.52f), WeaponId.AssaultRifle => new Color(0.3f, 0.34f, 0.3f), WeaponId.Marksman => new Color(0.24f, 0.3f, 0.4f), WeaponId.AutoShotgun => new Color(0.42f, 0.26f, 0.14f), WeaponId.Crossbow => new Color(0.32f, 0.22f, 0.14f), _ => new Color(0.6f, 0.6f, 0.6f), }); } internal static Vector3 PerModelEulerFix(WeaponId id) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) string text = DoomConfig.PerWeaponEulerOverrides.Value ?? ""; if (text != _eulerSrc) { _eulerSrc = text; _eulerMap.Clear(); string[] array = text.Split(';'); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split('='); if (array2.Length == 2 && Enum.TryParse(array2[0].Trim(), ignoreCase: true, out var result)) { Vector3 value = ParseVecOr(array2[1].Trim(), Vector3.zero); _eulerMap[result] = value; } } } if (!_eulerMap.TryGetValue(id, out var value2)) { return Vector3.zero; } return value2; } private void Construct(WeaponId id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) Transform transform = new GameObject("model").transform; transform.SetParent(((Component)this).transform, false); _model = transform; if (_handAttached) { _restPos = ParseVec(DoomConfig.HandWeaponOffset.Value); _restRot = Quaternion.Euler(ParseVec(DoomConfig.HandWeaponEuler.Value)); } else { _restPos = new Vector3(0.17f, -0.12f, 0.4f); _restRot = Quaternion.Euler(2f, -4f, 2f); } ((Component)this).transform.localPosition = _restPos; ((Component)this).transform.localRotation = _restRot; if (DoomConfig.UseGunModels.Value && TryBuildModel(id, transform)) { Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } } else { BuildPrimitive(id, transform); } SetLayer(((Component)this).gameObject, 31); BuildGrip(); } private void BuildGrip() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!_handAttached && DoomConfig.ShowViewmodelArms.Value) { _grip = new GameObject("gripR").transform; _grip.SetParent(((Component)this).transform, false); _grip.localPosition = ParseVec(DoomConfig.RightGripOffset.Value); _grip.localRotation = Quaternion.Euler(ParseVec(DoomConfig.RightGripEuler.Value)); HeldItemPose.RightGrip = _grip; } } private void OnDestroy() { if ((Object)(object)_grip != (Object)null && (Object)(object)HeldItemPose.RightGrip == (Object)(object)_grip) { HeldItemPose.RightGrip = null; } } internal static void SetLayer(GameObject go, int layer) { go.layer = layer; for (int i = 0; i < go.transform.childCount; i++) { SetLayer(((Component)go.transform.GetChild(i)).gameObject, layer); } } private bool TryBuildModel(WeaponId id, Transform model) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) float muzzleForward; GameObject val = BuildGunMeshGO(id, DoomConfig.GunModelScaleMul.Value, out muzzleForward); if ((Object)(object)val == (Object)null) { return false; } val.transform.SetParent(model, false); _muzzle = new GameObject("muzzle").transform; _muzzle.SetParent(model, false); _muzzle.localPosition = new Vector3(0f, 0f, muzzleForward + 0.03f); GameObject val2 = ImpactEffects.MakeMuzzleFlash(_muzzle, Vector3.zero); _flash = val2.GetComponent(); Plugin.LogWeapon($"gun model '{ModelName(id)}' loaded (scale mul {DoomConfig.GunModelScaleMul.Value:0.00})"); return true; } internal static GameObject BuildGunMeshGO(WeaponId id, float scaleMul, out float muzzleForward) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00a1: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) muzzleForward = 0f; ObjModelLoader.Model model = ObjModelLoader.Load(ModelName(id)); if (model == null || (Object)(object)model.mesh == (Object)null) { return null; } GameObject val = new GameObject("gun"); val.AddComponent().sharedMesh = model.mesh; MeshRenderer val2 = val.AddComponent(); Material[] array = (Material[])model.materials.Clone(); Color val3 = MainAccent(id); for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null) && ((Object)array[i]).name.IndexOf("Main", StringComparison.OrdinalIgnoreCase) >= 0) { array[i] = new Material(array[i]); array[i].color = val3; if (array[i].HasProperty("_BaseColor")) { array[i].SetColor("_BaseColor", val3); } if (id == WeaponId.BFG && array[i].HasProperty("_EmissionColor")) { array[i].EnableKeyword("_EMISSION"); array[i].SetColor("_EmissionColor", val3 * 0.6f); } } } ((Renderer)val2).materials = array; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; Bounds bounds = model.mesh.bounds; Quaternion val4 = Quaternion.Euler(ParseVec(DoomConfig.GunModelEuler.Value)) * Quaternion.Euler(PerModelEulerFix(id)) * AutoOrient(bounds); float num = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); if (num < 0.0001f) { num = 1f; } float num2 = 0.3f / num * Mathf.Max(0.05f, scaleMul); val.transform.localRotation = val4; val.transform.localScale = Vector3.one * num2; val.transform.localPosition = -(val4 * ((Bounds)(ref bounds)).center * num2) + ParseVec(DoomConfig.GunModelOffset.Value); muzzleForward = Mathf.Abs((val4 * ((Bounds)(ref bounds)).extents).z) * num2; return val; } private static Quaternion AutoOrient(Bounds b) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_003a: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Vector3 size = ((Bounds)(ref b)).size; int num = ((!(size.x >= size.y) || !(size.x >= size.z)) ? ((size.y >= size.z) ? 1 : 2) : 0); int num2 = ((!(size.x <= size.y) || !(size.x <= size.z)) ? ((size.y <= size.z) ? 1 : 2) : 0); int num3 = 3 - num - num2; if (num3 == num || num3 == num2) { num3 = (num + 1) % 3; } Vector3 val = Axis(num); Vector3 val2 = Axis(num3); if (Vector3.Dot(((Bounds)(ref b)).center, val) < 0f) { val = -val; } if (val == val2 || val == -val2) { val2 = Axis((num3 + 1) % 3); } return Quaternion.Inverse(Quaternion.LookRotation(val, val2)); } private static Vector3 Axis(int i) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return (Vector3)(i switch { 1 => Vector3.up, 0 => Vector3.right, _ => Vector3.forward, }); } private static Vector3 ParseVec(string s) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return ParseVecOr(s, Vector3.zero); } private static Vector3 ParseVecOr(string s, Vector3 fallback) { //IL_0008: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(s)) { return fallback; } string[] array = s.Split(','); if (array.Length != 3) { return fallback; } if (float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { return new Vector3(result, result2, result3); } return fallback; } private void BuildPrimitive(WeaponId id, Transform model) { //IL_0023: 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_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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) Color val = (Color)(id switch { WeaponId.Pistol => new Color(0.2f, 0.2f, 0.22f), WeaponId.Shotgun => new Color(0.35f, 0.22f, 0.1f), WeaponId.SuperShotgun => new Color(0.4f, 0.28f, 0.12f), _ => new Color(0.15f, 0.45f, 0.2f), }); float num = ((id == WeaponId.Pistol) ? 0.22f : 0.5f); float num2 = id switch { WeaponId.BFG => 0.35f, WeaponId.Pistol => 0.16f, _ => 0.55f, }; float radius = ((id == WeaponId.BFG) ? 0.08f : 0.03f); Box(model, new Vector3(0.08f, 0.1f, num), new Vector3(0f, 0f, num * 0.4f), val); Box(model, new Vector3(0.06f, 0.16f, 0.09f), new Vector3(0f, -0.12f, (0f - num) * 0.1f), val * 0.7f).localRotation = Quaternion.Euler(20f, 0f, 0f); Cyl(model, radius, num2, new Vector3((id == WeaponId.SuperShotgun) ? 0.03f : 0f, 0.01f, num * 0.4f + num2), val * 0.85f); if (id == WeaponId.SuperShotgun) { Cyl(model, radius, num2, new Vector3(-0.03f, 0.01f, num * 0.4f + num2), val * 0.85f); } _muzzle = new GameObject("muzzle").transform; _muzzle.SetParent(model, false); _muzzle.localPosition = new Vector3(0f, 0.01f, num * 0.4f + num2 * 2f); GameObject val2 = ImpactEffects.MakeMuzzleFlash(_muzzle, Vector3.zero); _flash = val2.GetComponent(); _restPos = new Vector3(0.28f, -0.24f, 0.55f); _restRot = Quaternion.Euler(0f, -6f, 0f); ((Component)this).transform.localPosition = _restPos; ((Component)this).transform.localRotation = _restRot; Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } } public void OnFired(float kick) { _recoilPos = Mathf.Min(1.2f, _recoilPos + 0.4f + kick * 0.06f); _recoilRot = Mathf.Min(1.5f, _recoilRot + 0.5f + kick * 0.08f); _flash?.Pop(); } public void Tick(float recoilImpulse, bool reloading) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) _recoilPos = Mathf.MoveTowards(_recoilPos, 0f, Time.deltaTime * 6f); _recoilRot = Mathf.MoveTowards(_recoilRot, 0f, Time.deltaTime * 8f); float num = (_handAttached ? 0.0006f : 0.004f); float num2 = (_handAttached ? 0.05f : 0.12f); float num3 = Mathf.Sin(Time.time * 1.5f) * num; Vector3 val = _restPos + new Vector3(num3, num3 * 0.5f, (0f - _recoilPos) * num2); Quaternion val2 = _restRot * Quaternion.Euler((0f - _recoilRot) * 12f, 0f, 0f); if (reloading && !_handAttached) { val += new Vector3(0f, -0.12f, -0.05f); val2 *= Quaternion.Euler(35f, 0f, 0f); } ((Component)this).transform.localPosition = Vector3.Lerp(((Component)this).transform.localPosition, val, Time.deltaTime * 14f); ((Component)this).transform.localRotation = Quaternion.Slerp(((Component)this).transform.localRotation, val2, Time.deltaTime * 14f); } private static Transform Box(Transform parent, Vector3 size, Vector3 localPos, Color c) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3); obj.transform.SetParent(parent, false); obj.transform.localPosition = localPos; obj.transform.localScale = size; Paint(obj, c); return obj.transform; } private static Transform Cyl(Transform parent, float radius, float length, Vector3 localPos, Color c) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)2); obj.transform.SetParent(parent, false); obj.transform.localPosition = localPos; obj.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); obj.transform.localScale = new Vector3(radius * 2f, length, radius * 2f); Paint(obj, c); return obj.transform; } private static void Paint(GameObject go, Color c) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown MeshRenderer component = go.GetComponent(); Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"); ((Renderer)component).material = new Material(val) { color = c }; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; } } } namespace ContentWarningDoom.UI { public class DoomHUD : MonoBehaviour { private float _hitUntil; private float _killUntil; private GUIStyle _big; private GUIStyle _mid; private GUIStyle _small; private GUIStyle _center; private GUIStyle _hsStyle; private GUIStyle _killStyle; private float _musicToastUntil; private int _musicPct; private float _hsUntil; private int _hsCombo; private float _hsComboUntil; private float _killConfirmUntil; private int _killCombo; private float _killComboUntil; private string _killWord = "KILL"; private GUIStyle _sbHeader; private GUIStyle _sbCol; private GUIStyle _sbRow; private GUIStyle _sbRowMe; private static Texture2D _px; public static DoomHUD Instance { get; private set; } private void Awake() { Instance = this; } public void PingHit() { _hitUntil = Time.time + 0.18f; } public void PingKill() { _killUntil = Time.time + 0.45f; } public void PingHeadshot() { float num = Mathf.Max(1f, DoomConfig.MultiKillWindow.Value); _hsCombo = ((!(Time.time <= _hsComboUntil)) ? 1 : (_hsCombo + 1)); _hsComboUntil = Time.time + num; _hsUntil = Time.time + 0.85f; _hitUntil = Time.time + 0.18f; } public void PingMusicVolume(float v) { _musicPct = Mathf.RoundToInt(Mathf.Clamp01(v) * 100f); _musicToastUntil = Time.time + 1.4f; } public void PingLocalKill() { float num = Mathf.Max(1f, DoomConfig.MultiKillWindow.Value); _killCombo = ((!(Time.time <= _killComboUntil)) ? 1 : (_killCombo + 1)); _killComboUntil = Time.time + num; _killConfirmUntil = Time.time + 0.9f; _killWord = ((_killCombo >= 5) ? "MASSACRE" : ((_killCombo >= 3) ? "MULTI KILL" : ((_killCombo == 2) ? "DOUBLE KILL" : "KILL"))); } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00c7: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_01a5: 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_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Expected O, but got Unknown //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown if (_big == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 26, fontStyle = (FontStyle)1 }; val.normal.textColor = new Color(1f, 0.85f, 0.3f); _big = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 18, fontStyle = (FontStyle)1 }; val2.normal.textColor = Color.white; _mid = val2; GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 14 }; val3.normal.textColor = new Color(0.9f, 0.9f, 0.9f); _small = val3; GUIStyle val4 = new GUIStyle(GUI.skin.label) { fontSize = 22, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val4.normal.textColor = new Color(1f, 0.9f, 0.4f); _center = val4; GUIStyle val5 = new GUIStyle(GUI.skin.label) { fontSize = 20, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val5.normal.textColor = new Color(1f, 0.35f, 0.25f); _hsStyle = val5; GUIStyle val6 = new GUIStyle(GUI.skin.label) { fontSize = 24, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val6.normal.textColor = new Color(1f, 0.25f, 0.2f); _killStyle = val6; GUIStyle val7 = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1 }; val7.normal.textColor = new Color(1f, 0.85f, 0.3f); _sbHeader = val7; GUIStyle val8 = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)1 }; val8.normal.textColor = new Color(0.7f, 0.7f, 0.7f); _sbCol = val8; GUIStyle val9 = new GUIStyle(GUI.skin.label) { fontSize = 14 }; val9.normal.textColor = Color.white; _sbRow = val9; GUIStyle val10 = new GUIStyle(_sbRow) { fontStyle = (FontStyle)1 }; val10.normal.textColor = new Color(0.4f, 0.9f, 1f); _sbRowMe = val10; } } private void OnGUI() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_010a: 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_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0524: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Unknown result type (might be due to invalid IL or missing references) //IL_068b: Unknown result type (might be due to invalid IL or missing references) //IL_06cd: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_070c: Unknown result type (might be due to invalid IL or missing references) //IL_0740: Unknown result type (might be due to invalid IL or missing references) //IL_078c: Unknown result type (might be due to invalid IL or missing references) //IL_07f4: Unknown result type (might be due to invalid IL or missing references) //IL_07f9: Unknown result type (might be due to invalid IL or missing references) //IL_0800: Unknown result type (might be due to invalid IL or missing references) //IL_0817: Unknown result type (might be due to invalid IL or missing references) //IL_0823: Expected O, but got Unknown //IL_083f: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.DoomModeActive) { return; } EnsureStyles(); float num = (float)Screen.width * 0.5f; float num2 = (float)Screen.height * 0.5f; DrawRect(num - 1f, num2 - 8f, 2f, 6f, Color.white); DrawRect(num - 1f, num2 + 2f, 2f, 6f, Color.white); DrawRect(num - 8f, num2 - 1f, 6f, 2f, Color.white); DrawRect(num + 2f, num2 - 1f, 6f, 2f, Color.white); if (Time.time < _hitUntil) { Color c = default(Color); ((Color)(ref c))..ctor(1f, 1f, 1f, Mathf.InverseLerp(_hitUntil, _hitUntil - 0.18f, Time.time)); DrawRect(num - 12f, num2 - 12f, 8f, 2f, c); DrawRect(num - 12f, num2 - 12f, 2f, 8f, c); DrawRect(num + 4f, num2 - 12f, 8f, 2f, c); DrawRect(num + 10f, num2 - 12f, 2f, 8f, c); DrawRect(num - 12f, num2 + 10f, 8f, 2f, c); DrawRect(num - 12f, num2 + 4f, 2f, 8f, c); DrawRect(num + 4f, num2 + 10f, 8f, 2f, c); DrawRect(num + 10f, num2 + 4f, 2f, 8f, c); } if (Time.time < _killUntil) { Color c2 = default(Color); ((Color)(ref c2))..ctor(1f, 0.2f, 0.2f, Mathf.InverseLerp(_killUntil, _killUntil - 0.45f, Time.time)); DrawRect(num - 16f, num2 - 2f, 32f, 3f, c2); DrawRect(num - 2f, num2 - 16f, 3f, 32f, c2); } if (Time.time < _hsUntil) { float num3 = Mathf.InverseLerp(_hsUntil, _hsUntil - 0.85f, Time.time); Color val = default(Color); ((Color)(ref val))..ctor(1f, 0.35f, 0.25f, num3); DrawRect(num - 18f, num2 - 18f, 12f, 3f, val); DrawRect(num - 18f, num2 - 18f, 3f, 12f, val); DrawRect(num + 6f, num2 - 18f, 12f, 3f, val); DrawRect(num + 15f, num2 - 18f, 3f, 12f, val); DrawRect(num - 18f, num2 + 15f, 12f, 3f, val); DrawRect(num - 18f, num2 + 6f, 3f, 12f, val); DrawRect(num + 6f, num2 + 15f, 12f, 3f, val); DrawRect(num + 15f, num2 + 6f, 3f, 12f, val); bool flag = _hsCombo >= 2 && Time.time <= _hsComboUntil; Color textColor = _hsStyle.normal.textColor; _hsStyle.normal.textColor = val; GUI.Label(new Rect(num - 150f, num2 - 54f, 300f, 24f), flag ? $"HEADSHOT x{_hsCombo}" : "HEADSHOT", _hsStyle); _hsStyle.normal.textColor = textColor; } if (Time.time < _killConfirmUntil) { float num4 = Mathf.InverseLerp(_killConfirmUntil, _killConfirmUntil - 0.9f, Time.time); Color textColor2 = _killStyle.normal.textColor; _killStyle.normal.textColor = new Color(1f, 0.25f, 0.2f, num4); GUI.Label(new Rect(num - 200f, num2 + 44f, 400f, 30f), _killWord, _killStyle); _killStyle.normal.textColor = textColor2; } WeaponManager instance = WeaponManager.Instance; if ((Object)(object)instance != (Object)null && instance.HasWeapon) { float num5 = 24f; float num6 = Screen.height - 96; GUI.Label(new Rect(num5, num6, 400f, 34f), instance.CurrentDef.Name, _big); GUI.Label(new Rect(num5, num6 + 32f, 400f, 28f), $"{instance.Mag} / {instance.Reserve}", _mid); if (instance.Reloading) { DrawRect(num5, num6 + 60f, 160f, 6f, new Color(0f, 0f, 0f, 0.5f)); DrawRect(num5, num6 + 60f, 160f * instance.ReloadProgress, 6f, new Color(1f, 0.8f, 0.3f, 0.9f)); GUI.Label(new Rect(num5 + 168f, num6 + 52f, 200f, 20f), "RELOADING", _small); } } int num7 = (((Object)(object)MonsterRegistry.Instance != (Object)null) ? MonsterRegistry.Instance.AliveCount : 0); GUI.Label(new Rect(24f, 20f, 400f, 24f), $"MONSTERS: {num7}", _mid); GUI.Label(new Rect(24f, 44f, 400f, 24f), $"KILLS: {KillCounter.TeamKills} (you: {KillCounter.PersonalKills})", _small); GUI.Label(new Rect(24f, 62f, 400f, 20f), $"SCRAP: {ScrapEconomy.Local}", _small); if (!DoomNet.IsHost) { GUI.Label(new Rect(24f, 80f, 400f, 20f), "client — host is authoritative", _small); } if (Plugin.GloryTarget != null) { GUI.Label(new Rect(num - 120f, num2 + 40f, 240f, 30f), "[E] FINISH", _center); } DoomController component = ((Component)this).GetComponent(); if ((Object)(object)component != (Object)null && component.BannerVisible) { GUI.Label(new Rect(0f, (float)Screen.height * 0.25f, (float)Screen.width, 40f), "DOOM MODE ENABLED", _center); } Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current.tabKey).isPressed) { DrawScoreboard(); } if (Time.time < _musicToastUntil) { float num8 = Mathf.InverseLerp(_musicToastUntil, _musicToastUntil - 1.4f, Time.time); GUIStyle val2 = new GUIStyle(_mid) { alignment = (TextAnchor)4 }; val2.normal.textColor = new Color(1f, 0.9f, 0.5f, num8); GUIStyle val3 = val2; GUI.Label(new Rect(0f, (float)(Screen.height - 150), (float)Screen.width, 24f), $"MUSIC VOLUME: {_musicPct}% (Alt+ / Alt-)", val3); } } private void DrawScoreboard() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_013a: 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_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) List list = new List(ActionSessions.All); list.Sort((PlayerActionSession a, PlayerActionSession b) => b.ContentScore.CompareTo(a.ContentScore)); float num = 460f; float num2 = 22f; float h = 62f + num2 * (float)Mathf.Max(1, list.Count); float num3 = ((float)Screen.width - num) * 0.5f; float num4 = 90f; DrawRect(num3, num4, num, h, new Color(0f, 0f, 0f, 0.72f)); GUI.Label(new Rect(num3 + 12f, num4 + 8f, num - 24f, 24f), "SCOREBOARD (this round)", _sbHeader); GUI.Label(new Rect(num3 + 12f, num4 + 34f, 200f, 18f), "PLAYER", _sbCol); GUI.Label(new Rect(num3 + num - 220f, num4 + 34f, 70f, 18f), "SCORE", _sbCol); GUI.Label(new Rect(num3 + num - 150f, num4 + 34f, 70f, 18f), "KILLS", _sbCol); GUI.Label(new Rect(num3 + num - 80f, num4 + 34f, 70f, 18f), "HS", _sbCol); if (list.Count == 0) { GUI.Label(new Rect(num3 + 12f, num4 + 56f, num - 24f, num2), "no players yet", _sbRow); return; } float num5 = num4 + 58f; foreach (PlayerActionSession item in list) { GUIStyle val = ((item.ActorNumber == DoomNet.LocalActor) ? _sbRowMe : _sbRow); GUI.Label(new Rect(num3 + 12f, num5, 220f, num2), item.PlayerName, val); GUI.Label(new Rect(num3 + num - 220f, num5, 70f, num2), item.ContentScore.ToString(), val); GUI.Label(new Rect(num3 + num - 150f, num5, 70f, num2), item.Kills.ToString(), val); GUI.Label(new Rect(num3 + num - 80f, num5, 70f, num2), item.Headshots.ToString(), val); num5 += num2; } } private static void DrawRect(float x, float y, float w, float h, Color c) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_px == (Object)null) { _px = new Texture2D(1, 1); _px.SetPixel(0, 0, Color.white); _px.Apply(); } Color color = GUI.color; GUI.color = c; GUI.DrawTexture(new Rect(x, y, w, h), (Texture)(object)_px); GUI.color = color; } } } namespace ContentWarningDoom.Shop { public class WeaponShop : MonoBehaviour { private sealed class Display { public WeaponId id; public Transform t; } private class BenchSpin : MonoBehaviour { private void Update() { ((Component)this).transform.Rotate(0f, 40f * Time.deltaTime, 0f, (Space)1); } } private static readonly WeaponId[] BenchGuns = new WeaponId[5] { WeaponId.Smg, WeaponId.AssaultRifle, WeaponId.Marksman, WeaponId.AutoShotgun, WeaponId.Crossbow }; private GameObject _kiosk; private Vector3 _centre; private readonly List _displays = new List(); private Display _focus; private WeaponId? _awaitId; private int _selRow; private Camera _cam; private bool _near; private bool _open; private CursorLockMode _prevLock; private bool _prevVisible; private GUIStyle _title; private GUIStyle _row; private GUIStyle _btn; private GUIStyle _prompt; private GUIStyle _tag; private GUIStyle _tagHi; private string _flash; private float _flashUntil; private bool _builtThisVisit; private float _surfaceSince = -1f; public static WeaponShop Instance { get; private set; } private static string AnchorFile { get { try { return Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? ".", "bench_anchor.txt"); } catch { return "bench_anchor.txt"; } } } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.WeaponShop"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void Flash(string s) { _flash = s; _flashUntil = Time.time + 3f; } public void PinHere() { //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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null) { Flash("PIN FAILED — no player"); Plugin.LogMode("[Bench] pin failed — no local player"); return; } Vector3 val = ((Component)localPlayer).transform.position; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val + Vector3.up * 1.2f, Vector3.down, ref val2, 6f, -1, (QueryTriggerInteraction)1)) { val = ((RaycastHit)(ref val2)).point; } float y = ((Component)localPlayer).transform.eulerAngles.y; try { File.WriteAllText(AnchorFile, "# ContentWarningDoom weapon bench spawn point — x,y,z,yaw (world). Delete this file (or press Alt+L in game) to go back to auto placement.\n" + string.Format(CultureInfo.InvariantCulture, "{0:0.###},{1:0.###},{2:0.###},{3:0.#}\n", val.x, val.y, val.z, y)); Plugin.Log.LogInfo((object)$"[Bench] PINNED spawn point to {val:F2} yaw {y:0} -> {AnchorFile}"); Flash($"BENCH PINNED HERE ({val.x:0},{val.y:0},{val.z:0}) · Alt+L = remove"); } catch (Exception ex) { Flash("PIN WRITE FAILED"); Plugin.LogMode("[Bench] pin write failed: " + ex.Message); return; } _builtThisVisit = false; if (OnSurfaceScene()) { BuildKiosk(); _builtThisVisit = true; } } public void ClearPin() { try { if (File.Exists(AnchorFile)) { File.Delete(AnchorFile); } } catch { } Plugin.Log.LogInfo((object)"[Bench] pin cleared — bench removed (press Alt+P to place it again)"); Flash("BENCH REMOVED · Alt+P to place it again"); DestroyKiosk(); _builtThisVisit = true; } private static bool TryLoadAnchor(out Vector3 pos, out float yaw) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) pos = Vector3.zero; yaw = 0f; try { if (!File.Exists(AnchorFile)) { return false; } string[] array = File.ReadAllLines(AnchorFile); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0 || text[0] == '#') { continue; } string[] array2 = text.Split(','); if (array2.Length >= 3 && float.TryParse(array2[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { pos = new Vector3(result, result2, result3); if (array2.Length >= 4) { float.TryParse(array2[3], NumberStyles.Float, CultureInfo.InvariantCulture, out yaw); } return true; } } } catch { } return false; } private void OnEnable() { SceneManager.sceneLoaded += OnScene; } private void OnDisable() { SceneManager.sceneLoaded -= OnScene; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void OnScene(Scene scene, LoadSceneMode mode) { DestroyKiosk(); _builtThisVisit = false; _surfaceSince = -1f; } private static bool OnSurfaceScene() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)SurfaceNetworkHandler.Instance != (Object)null) { return true; } } catch { } Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (name != null) { return name.IndexOf("Surface", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private void BuildKiosk() { //IL_0024: 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_0029: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: 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_0397: Expected O, but got Unknown //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) DestroyKiosk(); Vector3 val = (((Object)(object)Player.localPlayer != (Object)null) ? ((Component)Player.localPlayer).transform.position : Vector3.zero); if (!TryLoadAnchor(out var pos, out var yaw)) { Plugin.LogMode("[Bench] no spawn point set — stand where you want the WEAPON BENCH and press Alt+P"); return; } Vector3 val2 = pos; Quaternion val3 = Quaternion.Euler(0f, yaw + 180f, 0f); _kiosk = new GameObject("ContentWarningDoom.WeaponBench"); _kiosk.transform.SetPositionAndRotation(val2, val3); _centre = val2 + Vector3.up * 1f; Color c = default(Color); ((Color)(ref c))..ctor(0.16f, 0.17f, 0.2f); Color c2 = default(Color); ((Color)(ref c2))..ctor(0.55f, 0.42f, 0.12f); MeshRenderer component = ((Component)Box(_kiosk.transform, new Vector3(0.18f, 6f, 0.18f), new Vector3(0f, 3f, -0.9f), new Color(1f, 0.72f, 0.2f), solid: false)).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).material != (Object)null) { ((Renderer)component).material.EnableKeyword("_EMISSION"); if (((Renderer)component).material.HasProperty("_EmissionColor")) { ((Renderer)component).material.SetColor("_EmissionColor", new Color(1f, 0.55f, 0.1f) * 2f); } } Light obj = new GameObject("benchLight").AddComponent(); ((Component)obj).transform.SetParent(_kiosk.transform, false); ((Component)obj).transform.localPosition = new Vector3(0f, 1.6f, 0f); obj.type = (LightType)2; obj.range = 4f; obj.intensity = 0.5f; obj.color = new Color(1f, 0.85f, 0.6f); Box(_kiosk.transform, new Vector3(3.2f, 1.6f, 0.15f), new Vector3(0f, 0.8f, -0.9f), c, solid: false); Box(_kiosk.transform, new Vector3(3.2f, 0.9f, 0.6f), new Vector3(0f, 0.45f, 0.5f), c, solid: false); Box(_kiosk.transform, new Vector3(3.2f, 0.1f, 0.6f), new Vector3(0f, 0.9f, 0.5f), c2, solid: false); Box(_kiosk.transform, new Vector3(3f, 0.4f, 0.06f), new Vector3(0f, 1.5f, -0.85f), c2, solid: false); _displays.Clear(); for (int i = 0; i < BenchGuns.Length; i++) { float num = -1.2f + (float)i * 0.6f; Box(_kiosk.transform, new Vector3(0.34f, 0.35f, 0.3f), new Vector3(num, 0.55f, -0.55f), c2, solid: false); float muzzleForward; GameObject val4 = WeaponVisual.BuildGunMeshGO(BenchGuns[i], 2.4f, out muzzleForward); if (!((Object)(object)val4 == (Object)null)) { GameObject val5 = new GameObject("display_" + BenchGuns[i]); val5.transform.SetParent(_kiosk.transform, false); val5.transform.localPosition = new Vector3(num, 1f, -0.55f); val4.transform.SetParent(val5.transform, false); Collider[] componentsInChildren = val4.GetComponentsInChildren(); for (int j = 0; j < componentsInChildren.Length; j++) { Object.Destroy((Object)(object)componentsInChildren[j]); } val5.AddComponent(); _displays.Add(new Display { id = BenchGuns[i], t = val5.transform }); } } WeaponVisual.SetLayer(_kiosk, 0); Plugin.Log.LogInfo((object)string.Format("[Bench] WEAPON BENCH built at {0:F1} ({1}, player feet {2:F1}). Alt+P to re-pin.", val2, File.Exists(AnchorFile) ? "pinned" : "auto", val)); } private void DestroyKiosk() { if ((Object)(object)_kiosk != (Object)null) { Object.Destroy((Object)(object)_kiosk); } _kiosk = null; _near = false; _displays.Clear(); _focus = null; _awaitId = null; ClosePanel(); } private static Camera ActiveCamera() { Camera main = Camera.main; if ((Object)(object)main != (Object)null) { return main; } Camera[] allCameras = Camera.allCameras; foreach (Camera val in allCameras) { if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled) { return val; } } return null; } private void Update() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) if (!OnSurfaceScene() || !DoomConfig.WeaponShopEnabled.Value) { if ((Object)(object)_kiosk != (Object)null) { DestroyKiosk(); } _builtThisVisit = false; _surfaceSince = -1f; } else { if (_surfaceSince < 0f) { _surfaceSince = Time.time; } if (!_builtThisVisit && (Object)(object)Player.localPlayer != (Object)null && Time.time - _surfaceSince > 1.5f) { if (TryLoadAnchor(out var _, out var _)) { BuildKiosk(); } _builtThisVisit = true; } } if ((Object)(object)_kiosk == (Object)null) { _near = false; return; } Player localPlayer = Player.localPlayer; _near = (Object)(object)localPlayer != (Object)null && Vector3.Distance(((Component)localPlayer).transform.position, _centre) <= Mathf.Max(1f, DoomConfig.ShopUseRange.Value); _cam = ActiveCamera(); _focus = (_near ? PickFocus() : null); if (!_near) { _awaitId = null; if (_open) { ClosePanel(); } return; } Keyboard current = Keyboard.current; if (current == null) { return; } bool flag = ((ButtonControl)current.leftAltKey).isPressed || ((ButtonControl)current.rightAltKey).isPressed; if (!flag && ((ButtonControl)current.bKey).wasPressedThisFrame) { if (_open) { ClosePanel(); } else { OpenPanel(); } } if (_open && ((ButtonControl)current.escapeKey).wasPressedThisFrame) { ClosePanel(); } if (_open && !flag) { if (((ButtonControl)current.upArrowKey).wasPressedThisFrame || ((ButtonControl)current.wKey).wasPressedThisFrame) { _selRow = (_selRow + 6 - 1) % 6; } else if (((ButtonControl)current.downArrowKey).wasPressedThisFrame || ((ButtonControl)current.sKey).wasPressedThisFrame) { _selRow = (_selRow + 1) % 6; } else if (((ButtonControl)current.rightArrowKey).wasPressedThisFrame || ((ButtonControl)current.dKey).wasPressedThisFrame) { CycleSlot(_selRow, 1); } else if (((ButtonControl)current.leftArrowKey).wasPressedThisFrame || ((ButtonControl)current.aKey).wasPressedThisFrame) { CycleSlot(_selRow, -1); } else if (((ButtonControl)current.digit1Key).wasPressedThisFrame) { _selRow = 0; CycleSlot(0, 1); } else if (((ButtonControl)current.digit2Key).wasPressedThisFrame) { _selRow = 1; CycleSlot(1, 1); } else if (((ButtonControl)current.digit3Key).wasPressedThisFrame) { _selRow = 2; CycleSlot(2, 1); } else if (((ButtonControl)current.digit4Key).wasPressedThisFrame) { _selRow = 3; CycleSlot(3, 1); } else if (((ButtonControl)current.digit5Key).wasPressedThisFrame) { _selRow = 4; CycleSlot(4, 1); } else if (((ButtonControl)current.digit6Key).wasPressedThisFrame) { _selRow = 5; CycleSlot(5, 1); } } else { if (flag) { return; } if (_awaitId.HasValue) { int num = -1; if (((ButtonControl)current.digit1Key).wasPressedThisFrame) { num = 0; } else if (((ButtonControl)current.digit2Key).wasPressedThisFrame) { num = 1; } else if (((ButtonControl)current.digit3Key).wasPressedThisFrame) { num = 2; } else if (((ButtonControl)current.digit4Key).wasPressedThisFrame) { num = 3; } else if (((ButtonControl)current.digit5Key).wasPressedThisFrame) { num = 4; } else if (((ButtonControl)current.digit6Key).wasPressedThisFrame) { num = 5; } if (num >= 0) { if (!TryEquip(num, _awaitId.Value)) { Plugin.LogMode($"[Bench] can't afford {_awaitId.Value} ({PriceOf(_awaitId.Value)} scrap, have {ScrapEconomy.Local})"); } _awaitId = null; } else if (((ButtonControl)current.eKey).wasPressedThisFrame || ((ButtonControl)current.escapeKey).wasPressedThisFrame) { _awaitId = null; } } else if (_focus != null && ((ButtonControl)current.eKey).wasPressedThisFrame) { if (ScrapEconomy.Owns(DoomNet.LocalActor, _focus.id) || ScrapEconomy.Local >= PriceOf(_focus.id)) { _awaitId = _focus.id; } else { Plugin.LogMode($"[Bench] not enough scrap for {_focus.id} (need {PriceOf(_focus.id)}, have {ScrapEconomy.Local})"); } } } } private Display PickFocus() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cam == (Object)null || _displays.Count == 0) { return null; } Display result = null; float num = float.MaxValue; Vector3 position = ((Component)_cam).transform.position; Vector3 forward = ((Component)_cam).transform.forward; foreach (Display display in _displays) { if ((Object)(object)display.t == (Object)null) { continue; } Vector3 val = display.t.position - position; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude > 4.5f) { continue; } float num2 = Vector3.Angle(forward, val); if (!(num2 > 32f)) { float num3 = num2 + magnitude * 3f; if (num3 < num) { num = num3; result = display; } } } return result; } private void OpenPanel() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) _open = true; _awaitId = null; _selRow = 0; _prevLock = Cursor.lockState; _prevVisible = Cursor.visible; Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } private void ClosePanel() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (_open) { _open = false; Cursor.lockState = _prevLock; Cursor.visible = _prevVisible; } } private void LateUpdate() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (_open) { if ((int)Cursor.lockState != 0) { Cursor.lockState = (CursorLockMode)0; } if (!Cursor.visible) { Cursor.visible = true; } } } private static int PriceOf(WeaponId id) { return id switch { WeaponId.Smg => DoomConfig.ShopPriceSMG.Value, WeaponId.AssaultRifle => DoomConfig.ShopPriceAssaultRifle.Value, WeaponId.Marksman => DoomConfig.ShopPriceMarksman.Value, WeaponId.AutoShotgun => DoomConfig.ShopPriceAutoShotgun.Value, WeaponId.Crossbow => DoomConfig.ShopPriceCrossbow.Value, _ => 0, }; } private void CycleSlot(int slot, int dir) { WeaponManager instance = WeaponManager.Instance; if ((Object)(object)instance == (Object)null) { return; } List list = new List { instance.SlotDefault(slot) }; list.AddRange(BenchGuns); int num = list.IndexOf(instance.SlotWeapon(slot)); if (num < 0) { num = 0; } int count = list.Count; int num2 = ((dir >= 0) ? 1 : (-1)); for (int i = 1; i <= count; i++) { WeaponId weaponId = list[((num + num2 * i) % count + count) % count]; if (weaponId == instance.SlotDefault(slot)) { instance.ResetSlot(slot); return; } if (TryEquip(slot, weaponId)) { return; } } instance.ResetSlot(slot); } private bool TryEquip(int slot, WeaponId id) { if (!ScrapEconomy.Buy(DoomNet.LocalActor, id, PriceOf(id))) { return false; } WeaponManager.Instance?.SetSlotWeapon(slot, id); return true; } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown //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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown if (_title == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 20, fontStyle = (FontStyle)1 }; val.normal.textColor = new Color(1f, 0.85f, 0.35f); _title = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 14 }; val2.normal.textColor = Color.white; _row = val2; _btn = new GUIStyle(GUI.skin.button) { fontSize = 12 }; GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val3.normal.textColor = new Color(1f, 0.9f, 0.5f); _prompt = val3; GUIStyle val4 = new GUIStyle(GUI.skin.label) { fontSize = 12, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val4.normal.textColor = new Color(0.95f, 0.95f, 0.95f); _tag = val4; GUIStyle val5 = new GUIStyle(_tag) { fontSize = 13 }; val5.normal.textColor = new Color(1f, 0.85f, 0.35f); _tagHi = val5; } } private void OnGUI() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) EnsureStyles(); if (Time.time < _flashUntil && _flash != null) { Color textColor = _prompt.normal.textColor; _prompt.normal.textColor = new Color(1f, 0.9f, 0.4f, Mathf.Clamp01(_flashUntil - Time.time)); GUI.Label(new Rect(0f, (float)Screen.height * 0.22f, (float)Screen.width, 30f), "▶ " + _flash, _prompt); _prompt.normal.textColor = textColor; } if ((Object)(object)_kiosk == (Object)null) { if (Plugin.DoomEverActivated && DoomConfig.WeaponShopEnabled.Value && OnSurfaceScene() && !File.Exists(AnchorFile) && Time.time > _flashUntil) { GUI.Label(new Rect(0f, (float)(Screen.height - 64), (float)Screen.width, 22f), "WEAPON BENCH: stand where you want it and press Alt+P", _prompt); } return; } int localActor = DoomNet.LocalActor; if (_near && !_open && (Object)(object)_cam != (Object)null) { foreach (Display display in _displays) { if (!((Object)(object)display.t == (Object)null)) { Vector3 val = _cam.WorldToScreenPoint(display.t.position + Vector3.up * 0.35f); if (!(val.z <= 0f)) { string text = (ScrapEconomy.Owns(localActor, display.id) ? (WeaponTable.Get(display.id).Name + "\nOWNED") : $"{WeaponTable.Get(display.id).Name}\n{PriceOf(display.id)} scrap"); GUI.Label(new Rect(val.x - 100f, (float)Screen.height - val.y - 40f, 200f, 36f), text, (_focus == display) ? _tagHi : _tag); } } } } if (_near && !_open) { GUI.Label(new Rect(0f, (float)(Screen.height - 96), (float)Screen.width, 24f), $"▸ WEAPON BENCH — [B] full list Scrap: {ScrapEconomy.Local}", _prompt); string text2 = null; if (_awaitId.HasValue) { WeaponManager instance = WeaponManager.Instance; string text3 = ""; if ((Object)(object)instance != (Object)null) { for (int i = 0; i < 6; i++) { text3 += $" {i + 1}:{WeaponTable.Get(instance.SlotWeapon(i)).Name}"; } } text2 = "ASSIGN " + WeaponTable.Get(_awaitId.Value).Name + " → press 1-6 [E] cancel (" + text3.Trim() + ")"; } else if (_focus != null) { WeaponId id = _focus.id; text2 = (ScrapEconomy.Owns(localActor, id) ? ("[E] assign " + WeaponTable.Get(id).Name + " to a slot") : ((ScrapEconomy.Local < PriceOf(id)) ? $"{WeaponTable.Get(id).Name} — need {PriceOf(id)} scrap (have {ScrapEconomy.Local})" : $"[E] buy {WeaponTable.Get(id).Name} — {PriceOf(id)} scrap")); } if (text2 != null) { GUI.Label(new Rect(0f, (float)(Screen.height - 70), (float)Screen.width, 22f), text2, _prompt); } } else { if (!_open) { return; } float num = ((float)Screen.width - 720f) * 0.5f; float num2 = ((float)Screen.height - 380f) * 0.5f; GUI.Box(new Rect(num, num2, 720f, 380f), GUIContent.none); GUILayout.BeginArea(new Rect(num + 16f, num2 + 12f, 688f, 356f)); GUILayout.Label($"WEAPON BENCH Scrap: {ScrapEconomy.Local}", _title, Array.Empty()); GUILayout.Label("KEYBOARD: ↑↓ pick slot ←→ change its gun 1-6 jump+cycle B/Esc close. (buys automatically if you can afford it)", _row, Array.Empty()); GUILayout.Space(6f); WeaponManager instance2 = WeaponManager.Instance; for (int j = 0; j < 6; j++) { GUILayout.BeginHorizontal(Array.Empty()); WeaponId id2 = (((Object)(object)instance2 != (Object)null) ? instance2.SlotWeapon(j) : ((WeaponId)j)); string arg = ((j == _selRow) ? "▶ " : " "); GUILayout.Label($"{arg}Slot {j + 1}: {WeaponTable.Get(id2).Name}", _row, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }); if (GUILayout.Button("Default", _btn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { instance2?.ResetSlot(j); } WeaponId[] benchGuns = BenchGuns; foreach (WeaponId id3 in benchGuns) { bool flag = ScrapEconomy.Owns(localActor, id3); string obj = (flag ? WeaponTable.Get(id3).Name : $"{WeaponTable.Get(id3).Name} {PriceOf(id3)}"); bool enabled = GUI.enabled; GUI.enabled = flag || ScrapEconomy.Local >= PriceOf(id3); if (GUILayout.Button(obj, _btn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(96f) })) { TryEquip(j, id3); } GUI.enabled = enabled; } GUILayout.EndHorizontal(); GUILayout.Space(2f); } GUILayout.FlexibleSpace(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button("Close [B / Esc]", _btn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) })) { ClosePanel(); } GUILayout.EndHorizontal(); GUILayout.EndArea(); } } private static Transform Box(Transform parent, Vector3 size, Vector3 localPos, Color c, bool solid) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); val.transform.SetParent(parent, false); val.transform.localPosition = localPos; val.transform.localScale = size; MeshRenderer component = val.GetComponent(); Shader val2 = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"); ((Renderer)component).material = new Material(val2) { color = c }; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; if (!solid) { Collider component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } } return val.transform; } } } namespace ContentWarningDoom.PlayerLogic { public class DoomPlayerMovement : MonoBehaviour { private Player _lp; private PlayerController _pc; private Rigidbody[] _rigs; private bool _applied; private float _oMove; private float _oSprint; private float _oJumpImp; private float _oJumpOT; private bool _oAnyDir; private float _baseMovementForce = 10f; private float _lastShiftTap = -10f; private float _dashReadyAt; private float _dashTimeLeft; private Vector3 _dashDir; public bool DashReady => Time.time >= _dashReadyAt; public float DashCooldownLeft => Mathf.Max(0f, _dashReadyAt - Time.time); private void OnDisable() { if (_applied) { Restore(_pc); } } private void Update() { Player localPlayer = Player.localPlayer; PlayerController val = (((Object)(object)localPlayer != (Object)null && localPlayer.refs != null) ? localPlayer.refs.controller : null); if (!Plugin.DoomModeActive) { if (_applied) { Restore(_pc); } _pc = null; _lp = null; _rigs = null; return; } if ((Object)(object)val != (Object)(object)_pc) { if (_applied) { Restore(_pc); } _pc = val; _lp = localPlayer; _rigs = null; if ((Object)(object)_pc != (Object)null) { Apply(_pc); } } if (!((Object)(object)_pc == (Object)null) && !((Object)(object)_lp == (Object)null) && _lp.data != null && !_lp.data.dead) { if (DoomConfig.DoomInfiniteStamina.Value) { _lp.data.currentStamina = _pc.maxStamina; _lp.data.staminaDepleated = false; } EnsureRigs(); HandleDashInput(); } } private void FixedUpdate() { //IL_00ac: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.DoomModeActive || (Object)(object)_pc == (Object)null || (Object)(object)_lp == (Object)null || _lp.data == null || _lp.data.dead || _rigs == null || _rigs.Length == 0) { return; } float fixedDeltaTime = Time.fixedDeltaTime; if (_dashTimeLeft > 0f) { float num = DoomConfig.DashForce.Value * (fixedDeltaTime / Mathf.Max(0.02f, DoomConfig.DashDuration.Value)); AddToAllRigs(_dashDir * num, (ForceMode)2); _dashTimeLeft -= fixedDeltaTime; } Vector3 val = MoveInputWorld(); bool isGrounded = _lp.data.isGrounded; if (!isGrounded && ((Vector3)(ref val)).sqrMagnitude > 0.01f && DoomConfig.DoomAirControlBonus.Value > 0f) { AddToAllRigs(((Vector3)(ref val)).normalized * (DoomConfig.DoomAirControlBonus.Value * _baseMovementForce), (ForceMode)5); } if (!isGrounded || !(_dashTimeLeft <= 0f) || !(DoomConfig.DoomBrakeAssist.Value > 0f)) { return; } Vector3 val2 = AvgVelFlat(); if (((Vector3)(ref val2)).magnitude > 1f) { float num2 = ((((Vector3)(ref val)).sqrMagnitude < 0.01f) ? 1f : Mathf.Clamp01(0f - Vector3.Dot(((Vector3)(ref val2)).normalized, ((Vector3)(ref val)).normalized))); if (num2 > 0.01f) { AddToAllRigs(-((Vector3)(ref val2)).normalized * (Mathf.Min(((Vector3)(ref val2)).magnitude, 8f) * DoomConfig.DoomBrakeAssist.Value * num2), (ForceMode)5); } } } private void Apply(PlayerController pc) { if (!_applied && !((Object)(object)pc == (Object)null)) { _oMove = pc.movementForce; _oSprint = pc.sprintMultiplier; _oJumpImp = pc.jumpImpulse; _oJumpOT = pc.jumpForceOverTime; _oAnyDir = pc.canSprintInAnyDirection; _baseMovementForce = _oMove; pc.movementForce = _oMove * DoomConfig.DoomMoveSpeedMultiplier.Value; pc.sprintMultiplier = _oSprint * DoomConfig.DoomSprintSpeedMultiplier.Value; pc.jumpImpulse = _oJumpImp * DoomConfig.DoomJumpMultiplier.Value; pc.jumpForceOverTime = _oJumpOT * DoomConfig.DoomJumpMultiplier.Value; if (DoomConfig.DoomSprintAnyDirection.Value) { pc.canSprintInAnyDirection = true; } _applied = true; Plugin.LogMode($"movement tuned: movementForce {_oMove:0.0}->{pc.movementForce:0.0}, " + $"sprintMultiplier {_oSprint:0.00}->{pc.sprintMultiplier:0.00}, " + $"jumpImpulse {_oJumpImp:0.0}->{pc.jumpImpulse:0.0}, canSprintInAnyDirection={pc.canSprintInAnyDirection}"); } } private void Restore(PlayerController pc) { if (_applied) { if ((Object)(object)pc != (Object)null) { pc.movementForce = _oMove; pc.sprintMultiplier = _oSprint; pc.jumpImpulse = _oJumpImp; pc.jumpForceOverTime = _oJumpOT; pc.canSprintInAnyDirection = _oAnyDir; } _applied = false; Plugin.LogMode("movement restored to vanilla."); } } private void EnsureRigs() { if ((_rigs == null || _rigs.Length == 0) && !((Object)(object)_lp == (Object)null) && _lp.refs != null) { GameObject val = (((Object)(object)_lp.refs.rigRoot != (Object)null) ? _lp.refs.rigRoot : (((Object)(object)_lp.refs.ragdoll != (Object)null) ? ((Component)_lp.refs.ragdoll).gameObject : null)); if ((Object)(object)val != (Object)null) { _rigs = val.GetComponentsInChildren(true); } } } private void HandleDashInput() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if (!DoomConfig.DashEnabled.Value) { return; } Keyboard current = Keyboard.current; if (current != null && (int)Cursor.lockState == 1 && ((ButtonControl)current.leftShiftKey).wasPressedThisFrame) { float time = Time.time; if (time - _lastShiftTap <= DoomConfig.DashDoubleTapWindow.Value && time >= _dashReadyAt) { StartDash(); } _lastShiftTap = time; } } private void StartDash() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Vector3 val = MoveInputWorld(); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Flat(_lp.data.lookDirection); } val = ((Vector3)(ref val)).normalized; if (!(((Vector3)(ref val)).sqrMagnitude < 0.01f)) { _dashDir = val; _dashTimeLeft = DoomConfig.DashDuration.Value; _dashReadyAt = Time.time + DoomConfig.DashCooldown.Value; CameraKick.Shake(2.5f, 0.12f, 12f); Plugin.LogMode($"dash ({val.x:0.0},{val.z:0.0})"); } } private Vector3 MoveInputWorld() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_lp == (Object)null || _lp.input == null || _lp.data == null) { return Vector3.zero; } Vector2 movementInput = _lp.input.movementInput; Vector3 val = Flat(_lp.data.lookDirection); Vector3 normalized = ((Vector3)(ref val)).normalized; val = Flat(_lp.data.lookDirectionRight); Vector3 normalized2 = ((Vector3)(ref val)).normalized; return normalized * movementInput.y + normalized2 * movementInput.x; } private Vector3 AvgVelFlat() { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; int num = 0; for (int i = 0; i < _rigs.Length; i++) { Rigidbody val2 = _rigs[i]; if (!((Object)(object)val2 == (Object)null)) { val += val2.linearVelocity; num++; } } if (num == 0) { return Vector3.zero; } Vector3 result = val / (float)num; result.y = 0f; return result; } private void AddToAllRigs(Vector3 force, ForceMode mode) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _rigs.Length; i++) { Rigidbody val = _rigs[i]; if (!((Object)(object)val == (Object)null) && !val.isKinematic) { val.AddForce(force, mode); } } } private static Vector3 Flat(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return new Vector3(v.x, 0f, v.z); } } public static class HandRecoil { private static float _nextAllowed; public static void Kick(Vector3 shotForward, float baseForce) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) float num = baseForce * Mathf.Max(0f, DoomConfig.HandRecoilForceMultiplier.Value); if (num <= 0.01f || Time.time < _nextAllowed) { return; } Player localPlayer = Player.localPlayer; if (!((Object)(object)localPlayer == (Object)null) && localPlayer.data != null && !localPlayer.data.dead && localPlayer.refs != null && !((Object)(object)localPlayer.refs.ragdoll == (Object)null)) { Vector3 val = ((((Vector3)(ref shotForward)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref shotForward)).normalized : Vector3.forward); int num2 = CwRagdollApi.BodyPartId(localPlayer.refs.ragdoll, (BodypartType)10); if (num2 >= 0 && CwRagdollApi.AddForceToBodyParts(localPlayer, new int[1] { num2 }, (Vector3[])(object)new Vector3[1] { -val * num })) { _nextAllowed = Time.time + 0.05f; } } } } public class HeldItemPose : MonoBehaviour { public static Transform RightGrip; public static Transform LeftGrip; private static FieldInfo _fRight; private static FieldInfo _fLeft; private static PropertyInfo _pWeight; private static bool _reflected; private static bool _warned; public static HeldItemPose Instance { get; private set; } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.HeldItemPose"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private static void Reflect() { if (_reflected) { return; } _reflected = true; try { Type obj = AccessTools.Inner(typeof(Player), "PlayerRefs") ?? typeof(Player).GetNestedType("PlayerRefs", BindingFlags.Public | BindingFlags.NonPublic); _fRight = AccessTools.Field(obj, "IK_Right"); _fLeft = AccessTools.Field(obj, "IK_Left"); Type type = _fRight?.FieldType; if (type != null) { _pWeight = type.GetProperty("weight", BindingFlags.Instance | BindingFlags.Public) ?? type.GetProperty("m_Weight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_fRight == null || _pWeight == null) { Plugin.Log.LogWarning((object)$"[HeldItemPose] IK reflection incomplete (field={_fRight != null}, weight={_pWeight != null}) — real-hand grip disabled"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[HeldItemPose] reflect failed: " + ex.Message)); } } private void Update() { Drive(); } private void FixedUpdate() { Drive(); } private void LateUpdate() { Drive(); } private void Drive() { if (!Plugin.DoomModeActive || !DoomConfig.ShowViewmodelArms.Value || DoomConfig.AttachToRealHands.Value) { return; } Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.refs == null || localPlayer.data == null || localPlayer.data.dead) { return; } Reflect(); if (_fRight == null || _pWeight == null) { if (!_warned) { _warned = true; Plugin.LogWeapon("[HeldItemPose] no IK access — arms will not follow the weapon"); } } else { DriveHand(localPlayer.refs.IK_Hand_R, _fRight, RightGrip, localPlayer); DriveHand(localPlayer.refs.IK_Hand_L, _fLeft, LeftGrip, localPlayer); } } private static void DriveHand(Transform target, FieldInfo constraintField, Transform grip, Player p) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || (Object)(object)grip == (Object)null || constraintField == null) { return; } target.SetPositionAndRotation(grip.position, grip.rotation); try { object value = constraintField.GetValue(p.refs); if (value != null) { _pWeight.SetValue(value, 1f); } } catch { } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } public static class PlayerHands { private static MethodInfo _getBodypart; private static bool _resolved; public static Transform Right() { return Hand(Player.localPlayer, (BodypartType)10); } public static Transform Left() { return Hand(Player.localPlayer, (BodypartType)7); } public static Transform RightOf(Player p) { return Hand(p, (BodypartType)10); } private static Transform Hand(Player lp, BodypartType type) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)lp == (Object)null || lp.refs == null || (Object)(object)lp.refs.ragdoll == (Object)null) { return null; } if (!_resolved) { _resolved = true; try { _getBodypart = AccessTools.Method(typeof(PlayerRagdoll), "GetBodypart", new Type[1] { typeof(BodypartType) }, (Type[])null); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[DoomWeapon] PlayerHands reflect failed: " + ex.Message)); } } if (_getBodypart == null) { return null; } try { object? obj = _getBodypart.Invoke(lp.refs.ragdoll, new object[1] { type }); Bodypart val = (Bodypart)((obj is Bodypart) ? obj : null); return ((Object)(object)val != (Object)null) ? ((Component)val).transform : null; } catch { return null; } } } public class PvpRespawn : MonoBehaviour { private float _deadSince = -1f; private Vector3 _deathPos; public static PvpRespawn Instance { get; private set; } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.PvpRespawn"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private static bool PvpLive() { if (!Plugin.DoomModeActive || !DoomConfig.PvpRespawnEnabled.Value) { return false; } if (DoomConfig.FriendlyFireDamageMultiplier.Value <= 0f) { return false; } return ActionRoundManager.Phase == ActionRoundPhase.Action; } private void Update() { //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.data == null) { _deadSince = -1f; } else if (!localPlayer.data.dead) { _deadSince = -1f; } else if (_deadSince < 0f) { if (PvpLive()) { _deadSince = Time.time; _deathPos = ((localPlayer.refs != null && (Object)(object)localPlayer.refs.headPos != (Object)null) ? localPlayer.refs.headPos.position : ((Component)localPlayer).transform.position); Plugin.LogMode($"[PvpRespawn] died at {_deathPos:F1} — reviving in {DoomConfig.PvpRespawnDelaySeconds.Value:0}s"); } } else if (!(Time.time - _deadSince < Mathf.Max(1f, DoomConfig.PvpRespawnDelaySeconds.Value))) { _deadSince = -1f; float num = Mathf.Max(1f, DoomConfig.PvpRespawnOffsetMeters.Value); Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized * num; Vector3 val2 = _deathPos + new Vector3(val.x, 0f, val.y); RaycastHit val3 = default(RaycastHit); val2 = ((!Physics.Raycast(val2 + Vector3.up * 5f, Vector3.down, ref val3, 30f, -1, (QueryTriggerInteraction)1)) ? (_deathPos + Vector3.up * 0.5f) : (((RaycastHit)(ref val3)).point + Vector3.up * 0.2f)); try { localPlayer.CallRevive(); } catch (Exception ex) { Plugin.LogMode("[PvpRespawn] CallRevive failed: " + ex.Message); } CwRagdollApi.Teleport(localPlayer, val2, Vector3.forward); Plugin.LogMode($"[PvpRespawn] revived at {val2:F1} (from death {_deathPos:F1})"); } } } public class PlayerCombatController : MonoBehaviour { private bool _pvpDeathReported; private void OnEnable() { DoomNet.OnFriendlyHit += HandleFriendlyHit; } private void OnDisable() { DoomNet.OnFriendlyHit -= HandleFriendlyHit; } private void HandleFriendlyHit(int targetActor, float damage, int fromActor) { //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) if (targetActor != DoomNet.LocalActor) { Plugin.LogNetwork($"friendly-hit ignored: target {targetActor} != me {DoomNet.LocalActor}"); } else { if (damage <= 0f) { return; } Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.data == null || localPlayer.data.dead) { Plugin.LogNetwork("friendly-hit: no live local player"); return; } float health = localPlayer.data.health; bool flag = false; try { localPlayer.CallTakeDamage(damage); flag = true; } catch (Exception ex) { Plugin.LogNetwork("friendly-hit: CallTakeDamage threw (" + ex.Message + "); applying to data.health directly"); try { localPlayer.data.health = Mathf.Max(0f, localPlayer.data.health - damage); } catch { } } Plugin.LogNetwork(string.Format("took friendly fire {0:0} from actor {1} — hp {2:0} -> {3:0} (via {4})", damage, fromActor, health, localPlayer.data.health, flag ? "CallTakeDamage" : "data.health")); if ((localPlayer.data.dead || localPlayer.data.health <= 0f) && !_pvpDeathReported && fromActor != 0 && fromActor != DoomNet.LocalActor) { _pvpDeathReported = true; Vector3 val = ((localPlayer.refs != null && (Object)(object)localPlayer.refs.headPos != (Object)null) ? localPlayer.refs.headPos.position : ((Component)localPlayer).transform.position); ActionNet.SendPvpKill(fromActor, DoomNet.LocalActor, val); Plugin.LogNetwork($"pvp-kill SEND -> killer {fromActor} killed me ({DoomNet.LocalActor}) @ {val}"); } } } private void Update() { //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Invalid comparison between Unknown and I4 //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) Plugin.GloryTarget = null; if (!Plugin.DoomModeActive) { return; } Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.data == null || localPlayer.data.dead || localPlayer.refs == null || (Object)(object)localPlayer.refs.headPos == (Object)null) { return; } _pvpDeathReported = false; if ((Object)(object)MonsterRegistry.Instance == (Object)null) { return; } Vector3 position = localPlayer.refs.headPos.position; float value = DoomConfig.GloryKillRange.Value; MonsterHealth monsterHealth = null; float num = value * value; foreach (MonsterHealth item in MonsterRegistry.Instance.All) { if (item.Alive && !((Object)(object)item.Root == (Object)null) && (item.Staggered || item.CurrentHP <= item.MaxHP * DoomConfig.GloryKillHealthFraction.Value)) { Vector3 val = item.CenterPos - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; monsterHealth = item; } } } Plugin.GloryTarget = monsterHealth; if (monsterHealth == null) { return; } Keyboard current2 = Keyboard.current; if (current2 == null || !((ButtonControl)current2.eKey).wasPressedThisFrame || (int)Cursor.lockState != 1) { return; } Plugin.LogWeapon($"Glory kill on {monsterHealth.MonsterName} id={monsterHealth.ViewId}"); if (DoomNet.IsHost) { DamageSystem.HostGloryKill(monsterHealth.ViewId, DoomNet.LocalActor); } else { DoomNet.SendGloryRequest(monsterHealth.ViewId); } float value2 = DoomConfig.GloryKillHealAmount.Value; if (value2 > 0f) { try { localPlayer.CallHeal(value2); } catch { localPlayer.data.health = Mathf.Min(PlayerData.maxHealth, localPlayer.data.health + value2); } Plugin.LogWeapon($"Glory heal +{value2:0} (hp now {localPlayer.data.health:0})"); } WeaponManager.Instance?.GiveAmmoAll(0.1f); CameraKick.Shake(5f, 0.3f, 22f); BloodEffects.SpawnDeath(monsterHealth.CenterPos); } } } namespace ContentWarningDoom.Networking { public class DoomNet : MonoBehaviour, IOnEventCallback, IInRoomCallbacks { public const byte EVT_MODE_STATE = 180; public const byte EVT_MONSTER_REGISTER = 181; public const byte EVT_MONSTER_HP = 182; public const byte EVT_MONSTER_DEATH = 183; public const byte EVT_HIT_REQUEST = 184; public const byte EVT_KILLS = 185; public const byte EVT_BFG_SPAWN = 186; public const byte EVT_BFG_EXPLODE = 187; public const byte EVT_WEAPON_FIRE = 188; public const byte EVT_GLORY_REQUEST = 189; public const byte EVT_GRENADE_SPAWN = 199; private static readonly RaiseEventOptions ToAll = new RaiseEventOptions { Receivers = (ReceiverGroup)1 }; private static readonly RaiseEventOptions ToOthers = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; private static readonly RaiseEventOptions ToMaster = new RaiseEventOptions { Receivers = (ReceiverGroup)2 }; public static DoomNet Instance { get; private set; } public static bool InRoom { get { if (!PhotonNetwork.InRoom) { return PhotonNetwork.OfflineMode; } return true; } } public static bool IsHost { get { if (!PhotonNetwork.OfflineMode) { return PhotonNetwork.IsMasterClient; } return true; } } public static int LocalActor { get { if (PhotonNetwork.LocalPlayer == null) { return 0; } return PhotonNetwork.LocalPlayer.ActorNumber; } } public static int PlayerCount { get { if (PhotonNetwork.CurrentRoom == null) { return 1; } return PhotonNetwork.CurrentRoom.PlayerCount; } } public static event Action OnModeState; public static event Action OnMonsterRegister; public static event Action OnMonsterHp; public static event Action OnMonsterDeath; public static event Action OnHitRequest; public static event Action OnKills; public static event Action OnBfgSpawn; public static event Action OnBfgExplode; public static event Action OnWeaponFire; public static event Action OnGloryRequest; public static event Action OnGrenadeSpawn; public static event Action OnHostPlayerJoined; public static event Action OnFriendlyHit; public static event Action OnWeaponEquip; public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.DoomNet"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void OnEnable() { PhotonNetwork.AddCallbackTarget((object)this); } private void OnDisable() { PhotonNetwork.RemoveCallbackTarget((object)this); } private static void Send(byte code, RaiseEventOptions opts, params object[] content) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (!InRoom) { return; } try { PhotonNetwork.RaiseEvent(code, (object)content, opts, SendOptions.SendReliable); } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[DoomNetwork] RaiseEvent {code} failed: {ex.Message}"); } } public static void SendModeState(bool enabled, float spawnMult) { Send(180, ToAll, enabled, spawnMult, LocalActor); } public static void SendMonsterRegister(int viewId, float maxHp, float curHp, string name) { Send(181, ToAll, viewId, maxHp, curHp, name ?? ""); } public static void SendMonsterHp(int viewId, float curHp, float maxHp, byte flags) { Send(182, ToAll, viewId, curHp, maxHp, flags); } public static void SendMonsterDeath(int viewId, Vector3 dir, int killerActor) { //IL_001b: 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_0037: Unknown result type (might be due to invalid IL or missing references) Send(183, ToAll, viewId, dir.x, dir.y, dir.z, killerActor); } public static void SendHitRequest(int viewId, float damage, Vector3 hitPoint, Vector3 normal, byte dmgType) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) Send(184, ToMaster, viewId, damage, hitPoint.x, hitPoint.y, hitPoint.z, normal.x, normal.y, normal.z, dmgType, LocalActor); } public static void SendKills(int teamKills) { Send(185, ToAll, teamKills); } public static void SendBfgSpawn(Vector3 pos, Vector3 dir) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Send(186, ToAll, LocalActor, pos.x, pos.y, pos.z, dir.x, dir.y, dir.z); } public static void SendBfgExplode(Vector3 pos) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Send(187, ToAll, pos.x, pos.y, pos.z); } public static void SendWeaponFire(byte weaponId, Vector3 origin, Vector3 dir) { //IL_0032: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Send(188, ToOthers, (byte)0, LocalActor, (int)weaponId, origin.x, origin.y, origin.z, dir.x, dir.y, dir.z); } public static void SendWeaponEquip(byte weaponId) { Send(188, ToOthers, (byte)1, LocalActor, (int)weaponId, 0f, 0f, 0f, 0f, 0f, 0f); } public static void SendFriendlyHit(int targetActor, float damage) { Plugin.LogNetwork($"friendly-hit SEND -> actor {targetActor} dmg {damage:0.0} (from {LocalActor})"); Send(188, ToAll, (byte)2, LocalActor, targetActor, damage, 0f, 0f, 0f, 0f, 0f); } public static void SendGloryRequest(int viewId) { Send(189, ToMaster, viewId, LocalActor); } public static void SendGrenadeSpawn(Vector3 pos, Vector3 vel) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Send(199, ToAll, LocalActor, pos.x, pos.y, pos.z, vel.x, vel.y, vel.z); } public void OnEvent(EventData e) { //IL_0178: 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_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) if (e.Code < 180 || (e.Code > 189 && e.Code != 199)) { return; } object[] array; try { array = (object[])e.CustomData; } catch { return; } if (array == null) { return; } try { switch (e.Code) { case 180: DoomNet.OnModeState?.Invoke((bool)array[0], Convert.ToSingle(array[1]), Convert.ToInt32(array[2])); break; case 181: DoomNet.OnMonsterRegister?.Invoke(Convert.ToInt32(array[0]), Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), (string)array[3]); break; case 182: DoomNet.OnMonsterHp?.Invoke(Convert.ToInt32(array[0]), Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), Convert.ToByte(array[3])); break; case 183: DoomNet.OnMonsterDeath?.Invoke(Convert.ToInt32(array[0]), new Vector3(Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), Convert.ToSingle(array[3])), Convert.ToInt32(array[4])); break; case 184: DoomNet.OnHitRequest?.Invoke(Convert.ToInt32(array[0]), Convert.ToSingle(array[1]), new Vector3(Convert.ToSingle(array[2]), Convert.ToSingle(array[3]), Convert.ToSingle(array[4])), new Vector3(Convert.ToSingle(array[5]), Convert.ToSingle(array[6]), Convert.ToSingle(array[7])), Convert.ToByte(array[8]), Convert.ToInt32(array[9])); break; case 185: DoomNet.OnKills?.Invoke(Convert.ToInt32(array[0])); break; case 186: DoomNet.OnBfgSpawn?.Invoke(Convert.ToInt32(array[0]), new Vector3(Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), Convert.ToSingle(array[3])), new Vector3(Convert.ToSingle(array[4]), Convert.ToSingle(array[5]), Convert.ToSingle(array[6]))); break; case 187: DoomNet.OnBfgExplode?.Invoke(new Vector3(Convert.ToSingle(array[0]), Convert.ToSingle(array[1]), Convert.ToSingle(array[2]))); break; case 188: { byte b = Convert.ToByte(array[0]); int num = Convert.ToInt32(array[1]); switch (b) { case 0: DoomNet.OnWeaponFire?.Invoke(num, Convert.ToByte(array[2]), new Vector3(Convert.ToSingle(array[3]), Convert.ToSingle(array[4]), Convert.ToSingle(array[5])), new Vector3(Convert.ToSingle(array[6]), Convert.ToSingle(array[7]), Convert.ToSingle(array[8]))); break; case 1: DoomNet.OnWeaponEquip?.Invoke(num, Convert.ToByte(array[2])); break; case 2: { int num2 = Convert.ToInt32(array[2]); float num3 = Convert.ToSingle(array[3]); Plugin.LogNetwork($"friendly-hit RECV -> target {num2} dmg {num3:0.0} (from {num}, me {LocalActor})"); DoomNet.OnFriendlyHit?.Invoke(num2, num3, num); break; } } break; } case 189: DoomNet.OnGloryRequest?.Invoke(Convert.ToInt32(array[0]), Convert.ToInt32(array[1])); break; case 199: DoomNet.OnGrenadeSpawn?.Invoke(Convert.ToInt32(array[0]), new Vector3(Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), Convert.ToSingle(array[3])), new Vector3(Convert.ToSingle(array[4]), Convert.ToSingle(array[5]), Convert.ToSingle(array[6]))); break; case 190: case 191: case 192: case 193: case 194: case 195: case 196: case 197: case 198: break; } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[DoomNetwork] bad event {e.Code}: {ex.Message}"); } } public void OnPlayerEnteredRoom(Player newPlayer) { ViralityCompat.Detect(); int num = ViralityCompat.RoomMaxPlayers(); Plugin.Log.LogInfo((object)($"[DoomNet] player joined: '{SafeNick(newPlayer)}' (actor {((newPlayer != null) ? new int?(newPlayer.ActorNumber) : ((int?)null))}) — " + $"room now {PlayerCount}" + ((num > 0) ? $"/{num}" : "") + string.Format(" host={0} virality={1}", IsHost, ViralityCompat.Present ? "yes" : "no"))); if (IsHost) { DoomNet.OnHostPlayerJoined?.Invoke(); } } public void OnPlayerLeftRoom(Player otherPlayer) { Plugin.Log.LogInfo((object)$"[DoomNet] player left: '{SafeNick(otherPlayer)}' (actor {((otherPlayer != null) ? new int?(otherPlayer.ActorNumber) : ((int?)null))}) — room now {PlayerCount}"); } public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { } public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { } public void OnMasterClientSwitched(Player newMasterClient) { Plugin.Log.LogInfo((object)($"[DoomNet] host (MasterClient) is now '{SafeNick(newMasterClient)}' (actor {((newMasterClient != null) ? new int?(newMasterClient.ActorNumber) : ((int?)null))}) — " + "I am " + (IsHost ? "the host" : "a client") + " now.")); } private static string SafeNick(Player p) { try { return string.IsNullOrEmpty((p != null) ? p.NickName : null) ? ("P" + ((p != null) ? new int?(p.ActorNumber) : ((int?)null))) : p.NickName; } catch { return "?"; } } } } namespace ContentWarningDoom.Monsters { public interface IMonsterDeathAdapter { bool Handles(string monsterName); void OnDeath(MonsterHealth health, Vector3 hitDir); } public static class MonsterAdapters { private static readonly List Registry = new List(); public static void Register(IMonsterDeathAdapter adapter) { if (adapter != null && !Registry.Contains(adapter)) { Registry.Add(adapter); } } public static bool TryHandleDeath(MonsterHealth health, Vector3 hitDir) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (health == null) { return false; } for (int i = 0; i < Registry.Count; i++) { if (Registry[i].Handles(health.MonsterName)) { try { Registry[i].OnDeath(health, hitDir); return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[DoomMonster] adapter failed: " + ex.Message)); } } } return false; } } public static class MonsterDeath { private static readonly string[] DisableContains = new string[18] { "Attack_", "Attacks_", "GenericAttack", "MonsterAnimationHandler", "Bot_Nav", "DamageOverTimeTrigger", "KillBox", "ItemKillbox", "Harpoon", "Bot_SimpleMovement", "Bot_SimpleFlying", "MonsterGroupClose", "Bot_LookY", "Spawner", "Projectile", "Ability", "Trigger_", "Puppetmonster" }; public static void KillLocal(MonsterHealth h, Vector3 dir) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (h == null || (Object)(object)h.Root == (Object)null || (Object)(object)h.Root.GetComponent() != (Object)null) { return; } h.Dead = true; GameObject root = h.Root; DoomCorpse doomCorpse = root.AddComponent(); doomCorpse.viewId = h.ViewId; bool num = MonsterAdapters.TryHandleDeath(h, dir); int num2 = (num ? (-1) : DisableBehaviours(root)); string text = "adapter"; if (!num) { DisableDamageColliders(root); FreezeNavigation(root); if (!CollapseRagdoll(root, dir)) { FreezePose(root, h); PhysicsFallback(root, dir); text = "physics-fallback"; } else { text = "ragdoll (fallTime)"; } } BloodEffects.SpawnDeath(h.CenterPos); Plugin.LogMonster($"{h.MonsterName} id={h.ViewId} -> corpse [{text}] (disabled {num2} components)"); if (DoomNet.IsHost && DoomConfig.CorpseLifetime.Value > 0f) { ((MonoBehaviour)doomCorpse).StartCoroutine(HostRemoveAfter(root, DoomConfig.CorpseLifetime.Value)); } } private static int DisableBehaviours(GameObject root) { int num = 0; MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Type type = ((object)val).GetType(); if ((type.Namespace != null && type.Namespace.StartsWith("ContentWarningDoom")) || val is DoomCorpse) { continue; } string name = type.Name; bool flag = name == "Bot" || name.StartsWith("Bot_"); if (!flag) { string[] disableContains = DisableContains; foreach (string value in disableContains) { if (name.IndexOf(value, StringComparison.Ordinal) >= 0) { flag = true; break; } } } if (name == "PhotonView" || name == "MonsterSyncer" || name.StartsWith("PhotonTransform") || name.StartsWith("PhotonAnimator") || name.StartsWith("PhotonRigidbody")) { flag = false; } if (flag && ((Behaviour)val).enabled) { ((Behaviour)val).enabled = false; num++; } } return num; } private static void DisableDamageColliders(GameObject root) { Collider[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && val.isTrigger && val.enabled) { val.enabled = false; } } } private static void FreezeNavigation(GameObject root) { NavMeshAgent[] componentsInChildren = root.GetComponentsInChildren(true); foreach (NavMeshAgent val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } try { if (val.isOnNavMesh) { val.isStopped = true; val.ResetPath(); } } catch { } ((Behaviour)val).enabled = false; } } private static void FreezePose(GameObject root, MonsterHealth h) { Animator[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Animator val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.speed = 0f; } } } private static bool CollapseRagdoll(GameObject root, Vector3 dir) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) Player componentInChildren = root.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null || componentInChildren.data == null) { return false; } componentInChildren.data.fallTime = 99999f; componentInChildren.data.tazeTime = 2f; componentInChildren.data.simplifiedRagdoll = false; ShoveRigs(root, dir); return true; } private static void PhysicsFallback(GameObject root, Vector3 dir) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ShoveRigs(root, dir); } private static void ShoveRigs(GameObject root, Vector3 dir) { //IL_0023: 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_000e: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) if (((Vector3)(ref dir)).sqrMagnitude < 0.001f) { dir = Random.onUnitSphere; } dir.y = 0.15f; dir = ((Vector3)(ref dir)).normalized; Rigidbody[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Rigidbody val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { if (val.isKinematic) { val.isKinematic = false; } val.useGravity = true; val.AddForce(dir * 4f + Vector3.down * 2f, (ForceMode)2); val.AddTorque(Random.insideUnitSphere * 3f, (ForceMode)2); } } } private static IEnumerator HostRemoveAfter(GameObject root, float delay) { yield return (object)new WaitForSeconds(delay); if ((Object)(object)root == (Object)null) { yield break; } PhotonView val = root.GetComponent() ?? root.GetComponentInChildren(); try { if ((Object)(object)val != (Object)null && val.IsMine) { PhotonNetwork.Destroy(((Component)val).gameObject); } else if ((Object)(object)val != (Object)null) { PhotonNetwork.Destroy(((Component)val).gameObject); } else { Object.Destroy((Object)(object)root); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[DoomMonster] corpse cleanup failed: " + ex.Message)); } } } public class DoomCorpse : MonoBehaviour { public int viewId; } [HarmonyPatch(typeof(PhotonNetwork), "Instantiate", new Type[] { typeof(string), typeof(Vector3), typeof(Quaternion), typeof(byte), typeof(object[]) })] internal static class MonsterSpawnerPatch { private static bool _reentry; private static void Postfix(string prefabName, Vector3 position, Quaternion rotation, byte group, object[] data, GameObject __result) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (_reentry || !Plugin.DoomModeActive || !DoomNet.IsHost || (DoomConfig.ActionModeEnabled.Value && DoomConfig.HoldHordeUntilAction.Value && !ActionRoundManager.SpawnsAllowed) || (Object)(object)__result == (Object)null || (Object)(object)__result.GetComponentInChildren() == (Object)null) { return; } float num = Mathf.Max(1f, Plugin.CurrentSpawnMultiplier); int num2 = Mathf.RoundToInt(num) - 1; if (num2 <= 0) { return; } int num3 = Mathf.Max(1, DoomConfig.MaxActiveMonsters.Value); int num4 = (((Object)(object)BotHandler.instance != (Object)null && BotHandler.instance.bots != null) ? BotHandler.instance.bots.Count : 0); int num5 = 0; _reentry = true; try { for (int i = 0; i < num2; i++) { if (num4 + num5 + 1 >= num3) { break; } Vector3 val = position + Random.insideUnitSphere * 3f; val.y = position.y; if ((Object)(object)PhotonNetwork.Instantiate(prefabName, val, rotation, group, data) != (Object)null) { num5++; } } } finally { _reentry = false; } if (num5 > 0) { Plugin.LogSpawn($"horde x{num}: '{prefabName}' +{num5} (live~{num4})"); } } } } namespace ContentWarningDoom.Items { public class AmmoPickup : MonoBehaviour { private float _life = 25f; public static void Spawn(Vector3 pos) { //IL_0017: 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_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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)obj).name = "DoomAmmoPickup"; obj.transform.position = pos + Vector3.up * 0.4f; obj.transform.localScale = new Vector3(0.35f, 0.2f, 0.5f); Collider component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { component.isTrigger = true; } MeshRenderer component2 = obj.GetComponent(); Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"); ((Renderer)component2).material = new Material(val) { color = new Color(1f, 0.8f, 0.15f) }; ((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0; obj.AddComponent(); } private void Update() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.Rotate(0f, 90f * Time.deltaTime, 0f, (Space)0); Transform transform = ((Component)this).transform; transform.position += Vector3.up * Mathf.Sin(Time.time * 2f) * 0.0016f; _life -= Time.deltaTime; if (_life <= 0f) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.data == null || localPlayer.data.dead || localPlayer.refs == null || (Object)(object)localPlayer.refs.headPos == (Object)null) { return; } Vector3 val = localPlayer.refs.headPos.position - ((Component)this).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 5.76f) { return; } WeaponManager instance = WeaponManager.Instance; if ((Object)(object)instance != (Object)null) { foreach (WeaponId value in Enum.GetValues(typeof(WeaponId))) { instance.GiveAmmo(value, (value == WeaponId.BFG) ? 1 : 8); } Plugin.LogWeapon("Ammo pickup collected"); } Object.Destroy((Object)(object)((Component)this).gameObject); } } internal static class WeaponItemRegistration { } public class WeaponPickup : MonoBehaviour { private WeaponId _id; private float _life = 120f; private Light _glow; public static void Spawn(Vector3 pos, WeaponId id) { //IL_002a: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "DoomWeaponPickup_" + id; val.transform.position = pos + Vector3.up * 0.6f; val.transform.localScale = new Vector3(0.6f, 0.35f, 0.9f); Collider component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.isTrigger = true; } Color val2 = (Color)(id switch { WeaponId.Shotgun => new Color(0.45f, 0.28f, 0.1f), WeaponId.SuperShotgun => new Color(0.55f, 0.32f, 0.12f), WeaponId.BFG => new Color(0.2f, 0.85f, 0.3f), _ => new Color(0.3f, 0.3f, 0.32f), }); MeshRenderer component2 = val.GetComponent(); Shader val3 = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"); ((Renderer)component2).material = new Material(val3) { color = val2 }; ((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0; WeaponPickup weaponPickup = val.AddComponent(); weaponPickup._id = id; Light val4 = val.AddComponent(); val4.type = (LightType)2; val4.range = 4f; val4.intensity = 2.5f; val4.color = val2 * 2f; weaponPickup._glow = val4; Plugin.LogWeapon($"{id} pickup spawned at {pos}"); } private void Update() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.Rotate(0f, 60f * Time.deltaTime, 0f, (Space)0); Transform transform = ((Component)this).transform; transform.position += Vector3.up * Mathf.Sin(Time.time * 2f) * 0.0016f; if ((Object)(object)_glow != (Object)null) { _glow.intensity = 2f + Mathf.Sin(Time.time * 4f) * 1f; } _life -= Time.deltaTime; if (_life <= 0f) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.data == null || localPlayer.data.dead || localPlayer.refs == null || (Object)(object)localPlayer.refs.headPos == (Object)null) { return; } Vector3 val = localPlayer.refs.headPos.position - ((Component)this).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > 6.7599993f)) { WeaponManager instance = WeaponManager.Instance; if ((Object)(object)instance != (Object)null) { instance.Unlock(_id); instance.GiveAmmo(_id, 9999); instance.SelectById(_id); Plugin.Log.LogInfo((object)$"========== PICKED UP {_id} =========="); } Object.Destroy((Object)(object)((Component)this).gameObject); } } } } namespace ContentWarningDoom.FX { public static class BloodEffects { private static int _live; private const int MaxLive = 40; private static Material _mat; private static Material Mat() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown if ((Object)(object)_mat != (Object)null) { return _mat; } _mat = new Material(Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard")) { color = new Color(0.55f, 0.02f, 0.02f, 1f) }; return _mat; } public static void SpawnHit(Vector3 point, Vector3 normal) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) Spawn(point, normal, 14, 0.1f, 3.2f, 0.9f); } public static void SpawnDeath(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) Spawn(point, Vector3.up, 46, 0.16f, 4.5f, 1.6f); } private static void Spawn(Vector3 point, Vector3 normal, int count, float size, float speed, float life) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if (_live < 40) { _live++; GameObject val = new GameObject("DoomBlood"); val.transform.position = point; val.transform.rotation = Quaternion.LookRotation((((Vector3)(ref normal)).sqrMagnitude > 0.001f) ? normal : Vector3.up); ParticleSystem val2 = val.AddComponent(); MainModule main = val2.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(life); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(speed); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(size); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.5f, 0.02f, 0.02f, 1f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(1.1f); ((MainModule)(ref main)).maxParticles = 80; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).enabled = false; ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape)).angle = 32f; ((ShapeModule)(ref shape)).radius = 0.05f; ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val3 = new Gradient(); val3.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(new Color(0.6f, 0.03f, 0.03f), 0f), new GradientColorKey(new Color(0.25f, 0f, 0f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val3); ParticleSystemRenderer component = ((Component)val2).GetComponent(); ((Renderer)component).material = Mat(); component.renderMode = (ParticleSystemRenderMode)0; val2.Emit(count); FxAutoKill fxAutoKill = val.AddComponent(); fxAutoKill.OnDone = delegate { _live--; }; fxAutoKill.life = life + 0.5f; } } } public static class CameraKick { private static bool _resolved; private static object _perlin; private static MethodInfo _addShake; private static void Resolve() { _resolved = true; try { Type type = Type.GetType("GamefeelHandler, Assembly-CSharp"); if (type == null) { return; } object obj = type.GetField("instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); if (obj != null) { _perlin = type.GetField("perlin", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); if (_perlin != null) { _addShake = _perlin.GetType().GetMethod("AddShake", new Type[3] { typeof(float), typeof(float), typeof(float) }); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[DoomWeapon] CameraKick reflection failed: " + ex.Message)); } } public static void Shake(float amount = 1.5f, float duration = 0.18f, float scale = 15f) { if (!_resolved || _perlin == null) { Resolve(); } if (_addShake == null || _perlin == null) { return; } try { _perlin.GetType(); _addShake.Invoke(_perlin, new object[3] { amount, duration, scale }); } catch { _resolved = false; } } } public static class ImpactEffects { private static int _live; private const int MaxLive = 40; private static Material _fxMat; private static Material FxMat() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown if ((Object)(object)_fxMat != (Object)null) { return _fxMat; } _fxMat = new Material(Shader.Find("Sprites/Default") ?? Shader.Find("Universal Render Pipeline/Particles/Unlit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard")) { name = "DoomFxMat" }; return _fxMat; } private static Gradient Grad(Color a, Color b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_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_0027: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Gradient val = new Gradient(); val.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(a, 0f), new GradientColorKey(b, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0.9f, 0.35f), new GradientAlphaKey(0f, 1f) }); return val; } public static void SpawnWorld(Vector3 point, Vector3 normal) { //IL_0030: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Expected O, but got Unknown //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (_live < 40) { _live++; if (((Vector3)(ref normal)).sqrMagnitude < 0.0001f) { normal = Vector3.up; } GameObject val = new GameObject("DoomImpact"); val.transform.position = point + normal * 0.02f; val.transform.rotation = Quaternion.LookRotation(normal); GameObject val2 = new GameObject("sparks"); val2.transform.SetParent(val.transform, false); ParticleSystem obj = val2.AddComponent(); EmissionModule emission = obj.emission; ((EmissionModule)(ref emission)).enabled = false; MainModule main = obj.main; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.1f, 0.3f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(3.5f, 8f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.015f, 0.04f); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(1.4f); ShapeModule shape = obj.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape)).angle = 32f; ((ShapeModule)(ref shape)).radius = 0.01f; ColorOverLifetimeModule colorOverLifetime = obj.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(Grad(new Color(1f, 0.95f, 0.7f), new Color(1f, 0.45f, 0.08f))); ParticleSystemRenderer component = ((Component)obj).GetComponent(); ((Renderer)component).material = FxMat(); component.renderMode = (ParticleSystemRenderMode)1; component.lengthScale = 2.5f; component.velocityScale = 0.06f; obj.Emit(Random.Range(8, 14)); GameObject val3 = new GameObject("dust"); val3.transform.SetParent(val.transform, false); ParticleSystem val4 = val3.AddComponent(); EmissionModule emission2 = val4.emission; ((EmissionModule)(ref emission2)).enabled = false; MainModule main2 = val4.main; ((MainModule)(ref main2)).playOnAwake = false; ((MainModule)(ref main2)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main2)).startLifetime = new MinMaxCurve(0.35f, 0.6f); ((MainModule)(ref main2)).startSpeed = new MinMaxCurve(0.3f, 1.1f); ((MainModule)(ref main2)).startSize = new MinMaxCurve(0.1f, 0.22f); ((MainModule)(ref main2)).gravityModifier = MinMaxCurve.op_Implicit(-0.05f); ShapeModule shape2 = val4.shape; ((ShapeModule)(ref shape2)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape2)).angle = 45f; ((ShapeModule)(ref shape2)).radius = 0.03f; SizeOverLifetimeModule sizeOverLifetime = val4.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, new AnimationCurve((Keyframe[])(object)new Keyframe[2] { new Keyframe(0f, 0.5f), new Keyframe(1f, 1.6f) })); ColorOverLifetimeModule colorOverLifetime2 = val4.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime2)).enabled = true; ((ColorOverLifetimeModule)(ref colorOverLifetime2)).color = MinMaxGradient.op_Implicit(Grad(new Color(0.62f, 0.6f, 0.56f), new Color(0.45f, 0.44f, 0.42f))); ParticleSystemRenderer component2 = ((Component)val4).GetComponent(); ((Renderer)component2).material = FxMat(); component2.renderMode = (ParticleSystemRenderMode)0; val4.Emit(Random.Range(5, 9)); Light obj2 = val.AddComponent(); obj2.type = (LightType)2; obj2.range = 3.5f; obj2.intensity = 0f; obj2.color = new Color(1f, 0.75f, 0.4f); val.AddComponent().Pop(); FxAutoKill fxAutoKill = val.AddComponent(); fxAutoKill.OnDone = delegate { _live--; }; fxAutoKill.life = 0.8f; } } public static void AmmoPickupFx(Vector3 pos) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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) if (_live < 40) { _live++; GameObject val = new GameObject("DoomAmmoFx"); val.transform.position = pos + Vector3.up * 0.3f; ParticleSystem obj = val.AddComponent(); MainModule main = obj.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.6f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(1f, 2.5f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.07f); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.15f); ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = obj.emission; ((EmissionModule)(ref emission)).enabled = false; ShapeModule shape = obj.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.15f; ColorOverLifetimeModule colorOverLifetime = obj.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(Grad(new Color(1f, 0.9f, 0.4f), new Color(1f, 0.7f, 0.1f))); ParticleSystemRenderer component = ((Component)obj).GetComponent(); ((Renderer)component).material = FxMat(); component.renderMode = (ParticleSystemRenderMode)0; obj.Emit(12); FxAutoKill fxAutoKill = val.AddComponent(); fxAutoKill.OnDone = delegate { _live--; }; fxAutoKill.life = 1f; } } public static void MonsterFlash(MonsterHealth h) { if (!((Object)(object)h?.Root == (Object)null)) { HitFlash hitFlash = h.Root.GetComponent(); if ((Object)(object)hitFlash == (Object)null) { hitFlash = h.Root.AddComponent(); } hitFlash.Flash(); } } public static GameObject MakeMuzzleFlash(Transform parent, Vector3 localPos) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown GameObject val = new GameObject("DoomMuzzle"); val.transform.SetParent(parent, false); val.transform.localPosition = localPos; Light obj = val.AddComponent(); obj.type = (LightType)2; obj.range = 6f; obj.intensity = 0f; obj.color = new Color(1f, 0.85f, 0.5f); val.AddComponent(); return val; } public static void RemoteMuzzle(Vector3 pos) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DoomRemoteMuzzle"); val.transform.position = pos; Light obj = val.AddComponent(); obj.type = (LightType)2; obj.range = 6f; obj.intensity = 0f; obj.color = new Color(1f, 0.85f, 0.5f); val.AddComponent().Pop(); val.AddComponent().life = 0.25f; } public static void Tracer(Vector3 from, Vector3 to) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DoomTracer"); LineRenderer obj = val.AddComponent(); obj.positionCount = 2; obj.SetPosition(0, from); obj.SetPosition(1, to); obj.widthMultiplier = 0.025f; ((Renderer)obj).material = new Material(Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color")); obj.startColor = new Color(1f, 0.9f, 0.6f, 0.9f); obj.endColor = new Color(1f, 0.8f, 0.4f, 0f); obj.numCapVertices = 0; val.AddComponent().life = 0.06f; } } public class FxAutoKill : MonoBehaviour { public float life = 1f; public Action OnDone; private float _t; private void Update() { _t += Time.deltaTime; if (_t >= life) { OnDone?.Invoke(); Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { } } public class MuzzleFlash : MonoBehaviour { private Light _l; private float _t = 1f; private void Awake() { _l = ((Component)this).GetComponent(); } public void Pop() { _t = 0f; } private void Update() { if (!((Object)(object)_l == (Object)null)) { _t += Time.deltaTime * 12f; _l.intensity = Mathf.Lerp(6f, 0f, Mathf.Clamp01(_t)); } } } public class HitFlash : MonoBehaviour { private readonly List _renderers = new List(); private readonly List _original = new List(); private static readonly int ColorId = Shader.PropertyToID("_Color"); private static readonly int BaseColorId = Shader.PropertyToID("_BaseColor"); private float _t = 2f; private bool _captured; private void Capture() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) _captured = true; ((Component)this).GetComponentsInChildren(true, _renderers); foreach (Renderer renderer in _renderers) { Material[] sharedMaterials = renderer.sharedMaterials; Color[] array = (Color[])(object)new Color[sharedMaterials.Length]; for (int i = 0; i < sharedMaterials.Length; i++) { if ((Object)(object)sharedMaterials[i] == (Object)null) { array[i] = Color.white; } else { array[i] = (sharedMaterials[i].HasProperty(BaseColorId) ? sharedMaterials[i].GetColor(BaseColorId) : (sharedMaterials[i].HasProperty(ColorId) ? sharedMaterials[i].GetColor(ColorId) : Color.white)); } } _original.Add(array); } } public void Flash() { if (!_captured) { Capture(); } _t = 0f; } private void Update() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if (!_captured || _t > 1f) { return; } _t += Time.deltaTime * 6f; float num = Mathf.Clamp01(_t); for (int i = 0; i < _renderers.Count; i++) { Renderer val = _renderers[i]; if ((Object)(object)val == (Object)null) { continue; } Material[] materials = val.materials; for (int j = 0; j < materials.Length && j < _original[i].Length; j++) { if (!((Object)(object)materials[j] == (Object)null)) { Color val2 = Color.Lerp(Color.white * 1.5f, _original[i][j], num); if (materials[j].HasProperty(BaseColorId)) { materials[j].SetColor(BaseColorId, val2); } else if (materials[j].HasProperty(ColorId)) { materials[j].SetColor(ColorId, val2); } } } } } } } namespace ContentWarningDoom.Debug { public class DoomDebugUI : MonoBehaviour { private GUIStyle _s; private void OnGUI() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) if (DoomController.ShowDebugOverlay) { if (_s == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 13 }; val.normal.textColor = Color.green; val.richText = false; _s = val; } int num = (((Object)(object)BotHandler.instance != (Object)null && BotHandler.instance.bots != null) ? BotHandler.instance.bots.Count : (-1)); int num2 = (((Object)(object)MonsterRegistry.Instance != (Object)null) ? MonsterRegistry.Instance.Count : (-1)); int num3 = (((Object)(object)MonsterRegistry.Instance != (Object)null) ? MonsterRegistry.Instance.AliveCount : (-1)); string text = (PhotonNetwork.OfflineMode ? "OFFLINE/HOST" : (PhotonNetwork.IsMasterClient ? "HOST" : "CLIENT")); WeaponManager instance = WeaponManager.Instance; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("== ContentWarningDoom debug (F8) =="); stringBuilder.AppendLine(string.Format("Doom mode : {0} spawn x{1:0.0}", Plugin.DoomModeActive ? "ON" : "off", Plugin.CurrentSpawnMultiplier)); stringBuilder.AppendLine($"Network role : {text} actor={DoomNet.LocalActor} players={DoomNet.PlayerCount} inRoom={DoomNet.InRoom}"); stringBuilder.AppendLine($"BotHandler.bots: {num}"); stringBuilder.AppendLine($"Registry : {num2} tracked / {num3} alive"); stringBuilder.AppendLine($"Kills : team={KillCounter.TeamKills} personal={KillCounter.PersonalKills}"); if ((Object)(object)instance != (Object)null && instance.HasWeapon) { stringBuilder.AppendLine("Weapon : " + instance.CurrentDef.Name); stringBuilder.AppendLine($"Ammo : {instance.Mag}/{instance.Reserve} reloading={instance.Reloading} ({instance.ReloadProgress:0.00})"); bool[] a = instance.UnlockedSnapshot(); stringBuilder.AppendLine("Unlocked : P" + Yes(a, 0) + " S" + Yes(a, 1) + " SS" + Yes(a, 2) + " B" + Yes(a, 3)); } stringBuilder.AppendLine("Glory target : " + ((Plugin.GloryTarget != null) ? Plugin.GloryTarget.MonsterName : "-")); DoomPlayerMovement doomPlayerMovement = Object.FindObjectOfType(); if ((Object)(object)doomPlayerMovement != (Object)null) { stringBuilder.AppendLine("Dash : " + (doomPlayerMovement.DashReady ? "READY" : $"cd {doomPlayerMovement.DashCooldownLeft:0.0}s") + " (double-tap LeftShift)"); } Player localPlayer = Player.localPlayer; object obj; if (!((Object)(object)localPlayer != (Object)null)) { obj = "no localPlayer"; } else { Vector3 position = ((Component)localPlayer).transform.position; obj = ((Vector3)(ref position)).ToString("F2"); } stringBuilder.AppendLine("Position : " + (string?)obj); if ((Object)(object)localPlayer != (Object)null && localPlayer.data != null && localPlayer.refs != null && (Object)(object)localPlayer.refs.controller != (Object)null) { stringBuilder.AppendLine($"Move/Sprint/HP : force {localPlayer.refs.controller.movementForce:0.0} / x{localPlayer.refs.controller.sprintMultiplier:0.0} / {localPlayer.data.health:0} stamina {localPlayer.data.currentStamina:0.0}"); } stringBuilder.AppendLine("Keys: Alt+K mode(host) Alt+U unlock+ammo Alt+O this Alt+M spawn(host) 2xLeftShift dash"); GUI.Box(new Rect((float)(Screen.width - 430), 10f, 420f, 270f), ""); GUI.Label(new Rect((float)(Screen.width - 422), 14f, 410f, 262f), stringBuilder.ToString(), _s); } } private static string Yes(bool[] a, int i) { if (a == null || i >= a.Length || !a[i]) { return "-"; } return "+"; } } } namespace ContentWarningDoom.Core { internal static class ActionModeGuard { public static bool On { get { if (Plugin.DoomModeActive) { return DoomConfig.ActionModeEnabled.Value; } return false; } } } [HarmonyPatch(typeof(PhotonGameLobbyHandler), "SetCurrentObjective")] internal static class CameraNagPatch { private static bool Prefix(Objective objective) { if (!ActionModeGuard.On) { return true; } if (objective is PickupTheCameraObjective) { Plugin.LogMode("suppressed 'pick up the camera' objective (Action Mode gives everyone a camera)"); return false; } return true; } } [HarmonyPatch(typeof(SurfaceNetworkHandler), "CheckIfCameraIsPresent")] internal static class CameraPresentPatch { private static bool Prefix(ref bool __result) { if (!ActionModeGuard.On) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(PhotonGameLobbyHandler), "CheckForIllegalItems")] internal static class IllegalItemsPatch { private static bool Prefix() { if (!ActionModeGuard.On) { return true; } return false; } } [HarmonyPatch(typeof(VideoCamera), "Update")] internal static class VideoCameraUpdateGuard { private static bool Prefix(VideoInfoEntry ___m_recorderInfoEntry) { return ___m_recorderInfoEntry != null; } } [HarmonyPatch(typeof(PersistentObjectsHolder), "AddPersistentObject", new Type[] { typeof(PersistantObject) })] internal static class PersistentObjectNullKeyGuard { private static bool Prefix(PersistantObject go) { if ((Object)(object)go != (Object)null) { return (Object)(object)((Component)go).GetComponentInParent() != (Object)null; } return false; } } public static class CwRagdollApi { private static bool _resolved; private static MethodInfo _getBodypartFromCollider; private static MethodInfo _getBodyPartId; private static MethodInfo _addForceToBodyParts; private static MethodInfo _takeDamageAddForceFall; private static MethodInfo _teleport; private static void Resolve() { _resolved = true; try { _getBodypartFromCollider = AccessTools.Method(typeof(PlayerRagdoll), "GetBodypartFromCollider", new Type[1] { typeof(Collider) }, (Type[])null); _getBodyPartId = AccessTools.Method(typeof(PlayerRagdoll), "GetBodyPartID", new Type[1] { typeof(BodypartType) }, (Type[])null); _addForceToBodyParts = AccessTools.Method(typeof(Player), "CallAddForceToBodyParts", new Type[2] { typeof(int[]), typeof(Vector3[]) }, (Type[])null); _takeDamageAddForceFall = AccessTools.Method(typeof(Player), "CallTakeDamageAndAddForceAndFall", new Type[3] { typeof(float), typeof(Vector3), typeof(float) }, (Type[])null); _teleport = AccessTools.Method(typeof(Player), "Teleport", new Type[2] { typeof(Vector3), typeof(Vector3) }, (Type[])null); if (_getBodypartFromCollider == null || _getBodyPartId == null || _addForceToBodyParts == null || _takeDamageAddForceFall == null) { Plugin.Log.LogWarning((object)"[CwRagdollApi] some ragdoll methods not found — precise headshot / physical reactions partially disabled"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CwRagdollApi] reflection failed: " + ex.Message)); } } public static Bodypart BodypartFromCollider(PlayerRagdoll ragdoll, Collider col) { if ((Object)(object)ragdoll == (Object)null || (Object)(object)col == (Object)null) { return null; } if (!_resolved) { Resolve(); } if (_getBodypartFromCollider == null) { return null; } try { object? obj = _getBodypartFromCollider.Invoke(ragdoll, new object[1] { col }); return (Bodypart)((obj is Bodypart) ? obj : null); } catch { return null; } } public static void Teleport(Player player, Vector3 pos, Vector3 lookOrVel) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } if (!_resolved) { Resolve(); } if (_teleport != null) { try { _teleport.Invoke(player, new object[2] { pos, lookOrVel }); return; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CwRagdollApi] Teleport failed: " + ex.Message)); } } try { ((Component)player).transform.position = pos; } catch { } } public static int BodyPartId(PlayerRagdoll ragdoll, BodypartType type) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ragdoll == (Object)null) { return -1; } if (!_resolved) { Resolve(); } if (_getBodyPartId == null) { return -1; } try { return (int)_getBodyPartId.Invoke(ragdoll, new object[1] { type }); } catch { return -1; } } public static bool AddForceToBodyParts(Player player, int[] bodyPartIds, Vector3[] forces) { if ((Object)(object)player == (Object)null || bodyPartIds == null || forces == null) { return false; } if (!_resolved) { Resolve(); } if (_addForceToBodyParts == null) { return false; } try { _addForceToBodyParts.Invoke(player, new object[2] { bodyPartIds, forces }); return true; } catch { return false; } } public static bool TakeDamageAndAddForceAndFall(Player player, float damage, Vector3 force, float fall) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } if (!_resolved) { Resolve(); } if (_takeDamageAddForceFall == null) { return false; } try { _takeDamageAddForceFall.Invoke(player, new object[3] { damage, force, fall }); return true; } catch { return false; } } } internal static class ViralityCompat { private static string _version = ""; public static bool Present { get; private set; } public static int ViralityMaxPlayers { get; private set; } = -1; public static void Detect() { if (Present) { return; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { string name = assembly.GetName().Name; if (name == null || name.IndexOf("Virality", StringComparison.OrdinalIgnoreCase) < 0) { continue; } Present = true; _version = assembly.GetName().Version?.ToString() ?? "?"; try { PropertyInfo propertyInfo = assembly.GetType("Virality.Virality", throwOnError: false)?.GetProperty("MaxPlayers", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (propertyInfo != null && propertyInfo.PropertyType == typeof(int)) { ViralityMaxPlayers = (int)propertyInfo.GetValue(null); } break; } catch { break; } } } catch { } } public static void LogStatus() { Detect(); if (Present) { Plugin.Log.LogInfo((object)("[DoomMode] Virality detected (asm v" + _version + ((ViralityMaxPlayers > 0) ? $", MaxPlayers={ViralityMaxPlayers}" : "") + ") — bigger lobbies + late join available.")); } else { Plugin.Log.LogInfo((object)"[DoomMode] Virality NOT detected — Content Warning's vanilla 4-player lobby limit applies. ContentWarningDoom does not add players by itself."); } } public static int RoomMaxPlayers() { try { return (PhotonNetwork.CurrentRoom != null) ? PhotonNetwork.CurrentRoom.MaxPlayers : 0; } catch { return 0; } } } } namespace ContentWarningDoom.Config { public static class DoomConfig { public static ConfigEntry Enabled; public static ConfigEntry DoomModeEnabledByDefault; public static ConfigEntry DebugLogging; public static ConfigEntry FriendlyFireDamageMultiplier; public static ConfigEntry PvpRespawnEnabled; public static ConfigEntry PvpRespawnDelaySeconds; public static ConfigEntry PvpRespawnOffsetMeters; public static ConfigEntry WeaponSoundFiles; public static ConfigEntry WeaponSoundVolume; public static ConfigEntry DefaultMonsterHP; public static ConfigEntry MonsterHealthMultiplier; public static ConfigEntry MonsterHealthOverrides; public static ConfigEntry PistolDamage; public static ConfigEntry PistolFireRate; public static ConfigEntry PistolMagazine; public static ConfigEntry PistolReserve; public static ConfigEntry PistolReload; public static ConfigEntry PistolRange; public static ConfigEntry ShotgunDamagePerPellet; public static ConfigEntry ShotgunPellets; public static ConfigEntry ShotgunSpread; public static ConfigEntry ShotgunMagazine; public static ConfigEntry ShotgunReserve; public static ConfigEntry ShotgunFireDelay; public static ConfigEntry ShotgunReload; public static ConfigEntry ShotgunRange; public static ConfigEntry ShotgunKnockback; public static ConfigEntry SuperShotgunDamagePerPellet; public static ConfigEntry SuperShotgunPellets; public static ConfigEntry SuperShotgunSpread; public static ConfigEntry SuperShotgunMagazine; public static ConfigEntry SuperShotgunReserve; public static ConfigEntry SuperShotgunFireDelay; public static ConfigEntry SuperShotgunReload; public static ConfigEntry SuperShotgunRange; public static ConfigEntry SuperShotgunKnockback; public static ConfigEntry BFGDirectDamage; public static ConfigEntry BFGExplosionDamage; public static ConfigEntry BFGRadius; public static ConfigEntry BFGProjectileSpeed; public static ConfigEntry BFGTrackingDamage; public static ConfigEntry BFGMagazine; public static ConfigEntry BFGReserve; public static ConfigEntry BFGFireDelay; public static ConfigEntry BFGReload; public static ConfigEntry MinigunDamage; public static ConfigEntry MinigunFireRate; public static ConfigEntry MinigunMagazine; public static ConfigEntry MinigunReserve; public static ConfigEntry MinigunReload; public static ConfigEntry MinigunRange; public static ConfigEntry MinigunSpread; public static ConfigEntry MinigunSpinUp; public static ConfigEntry GrenadeDirectDamage; public static ConfigEntry GrenadeExplosionDamage; public static ConfigEntry GrenadeRadius; public static ConfigEntry GrenadeSpeed; public static ConfigEntry GrenadeFuse; public static ConfigEntry GrenadeMagazine; public static ConfigEntry GrenadeReserve; public static ConfigEntry GrenadeFireDelay; public static ConfigEntry GrenadeReload; public static ConfigEntry GrenadeKnockback; public static ConfigEntry MonsterSpawnMultiplier; public static ConfigEntry MaxActiveMonsters; public static ConfigEntry CorpseLifetime; public static ConfigEntry GloryKillHealthFraction; public static ConfigEntry GloryKillRange; public static ConfigEntry GloryKillHealAmount; public static ConfigEntry RegistryScanInterval; public static ConfigEntry DoomMoveSpeedMultiplier; public static ConfigEntry DoomSprintSpeedMultiplier; public static ConfigEntry DoomJumpMultiplier; public static ConfigEntry DoomInfiniteStamina; public static ConfigEntry DoomSprintAnyDirection; public static ConfigEntry DoomBrakeAssist; public static ConfigEntry DoomAirControlBonus; public static ConfigEntry DashEnabled; public static ConfigEntry DashForce; public static ConfigEntry DashDuration; public static ConfigEntry DashCooldown; public static ConfigEntry DashDoubleTapWindow; public static ConfigEntry ActionModeEnabled; public static ConfigEntry PreparationDuration; public static ConfigEntry ActionDuration; public static ConfigEntry RecordingTime; public static ConfigEntry CameraSubmissionTimeout; public static ConfigEntry MaxFilmDistance; public static ConfigEntry MultiKillWindow; public static ConfigEntry MonsterVisibleCooldown; public static ConfigEntry CloseRangeDistance; public static ConfigEntry DashKillWindow; public static ConfigEntry HeadshotDamageMultiplier; public static ConfigEntry HeadTopFraction; public static ConfigEntry DangerHealthFraction; public static ConfigEntry DangerRadius; public static ConfigEntry DangerCooldown; public static ConfigEntry SpeechMicThreshold; public static ConfigEntry ViewsMultiplier; public static ConfigEntry ViewsRandomVariance; public static ConfigEntry ActionCreditsDivisor; public static ConfigEntry VarietyBonusPerType; public static ConfigEntry RepeatDiminishFactor; public static ConfigEntry RareMonsterMultiplier; public static ConfigEntry RareMonsterNames; public static ConfigEntry DangerMonsterMultiplierPerLevel; public static ConfigEntry HoldHordeUntilAction; public static ConfigEntry HandRecoilForceMultiplier; public static ConfigEntry MonsterHitReactionForceMultiplier; public static ConfigEntry MonsterHitReactionFallEnabled; public static ConfigEntry MonsterHitReactionFallCooldown; public static ConfigEntry MonsterHitReactionMaxFall; public static ConfigEntry WeaponShopEnabled; public static ConfigEntry ScrapPerKill; public static ConfigEntry ScrapPerDangerLevel; public static ConfigEntry ShopUseRange; public static ConfigEntry ShopPositionOffset; public static ConfigEntry ShopPriceSMG; public static ConfigEntry ShopPriceAssaultRifle; public static ConfigEntry ShopPriceMarksman; public static ConfigEntry ShopPriceAutoShotgun; public static ConfigEntry ShopPriceCrossbow; public static ConfigEntry SpawnHiddenActionCamera; public static ConfigEntry RealVideoRecording; public static ConfigEntry EncodeWaitTimeout; public static ConfigEntry ShareWaitTimeout; public static ConfigEntry AttemptTvPlayback; public static ConfigEntry MusicVolume; public static ConfigEntry ShowViewmodelArms; public static ConfigEntry AttachToRealHands; public static ConfigEntry HandWeaponOffset; public static ConfigEntry HandWeaponEuler; public static ConfigEntry HandCameraOffset; public static ConfigEntry HandCameraEuler; public static ConfigEntry ShowCameraViewmodel; public static ConfigEntry CameraModelEuler; public static ConfigEntry ShowViewfinder; public static ConfigEntry RequireCameraDeposit; public static ConfigEntry DepositRange; public static ConfigEntry UseGunModels; public static ConfigEntry GunModelEuler; public static ConfigEntry PerWeaponEulerOverrides; public static ConfigEntry GunModelScaleMul; public static ConfigEntry GunModelOffset; public static ConfigEntry RightGripOffset; public static ConfigEntry RightGripEuler; public static ConfigEntry LeftGripOffset; public static ConfigEntry LeftGripEuler; public static ConfigEntry ShowRemotePlayerWeapons; public static ConfigEntry RemoteWeaponOffset; public static ConfigEntry RemoteWeaponEuler; public static ConfigEntry RemoteWeaponScaleMul; public static ConfigEntry W_MonsterVisible; public static ConfigEntry W_MonsterKill; public static ConfigEntry W_Headshot; public static ConfigEntry W_HeadshotKill; public static ConfigEntry W_AirborneKill; public static ConfigEntry W_DashKill; public static ConfigEntry W_GloryKill; public static ConfigEntry W_MultiKill; public static ConfigEntry W_BFGMultiKill; public static ConfigEntry W_CloseRangeKill; public static ConfigEntry W_DangerMoment; public static ConfigEntry W_SpeechMoment; public static ConfigEntry W_PlayerCombat; public static ConfigEntry W_PlayerKill; private static Dictionary _overrides; public static void Init(ConfigFile cfg) { Enabled = cfg.Bind("General", "Enabled", true, "Master switch for the whole mod."); DoomModeEnabledByDefault = cfg.Bind("General", "DoomModeEnabledByDefault", false, "Turn Doom Mode on automatically when a level loads (host only)."); DebugLogging = cfg.Bind("General", "DebugLogging", true, "Verbose [Doom*] logging."); FriendlyFireDamageMultiplier = cfg.Bind("General", "FriendlyFireDamageMultiplier", 1f, "Friendly fire: fraction of normal weapon/explosion damage a teammate takes when you shoot them (1 = full, 0.5 = half, 0 = no friendly fire). Only the SHOOTER's value matters — a teammate is always hurt by your shots at your setting, no per-client sync needed."); PvpRespawnEnabled = cfg.Bind("General", "PvpRespawnEnabled", true, "During the ACTION phase (when friendly fire is live), a killed player auto-revives after a delay near where they died instead of staying down for the round."); PvpRespawnDelaySeconds = cfg.Bind("General", "PvpRespawnDelaySeconds", 15f, "Seconds between dying and the ACTION-phase auto-respawn."); PvpRespawnOffsetMeters = cfg.Bind("General", "PvpRespawnOffsetMeters", 4f, "How far from the death spot to place the respawn (a random horizontal direction, snapped to the ground)."); WeaponSoundFiles = cfg.Bind("Audio", "WeaponSoundFiles", "Pistol=fire_shot;Smg=fire_shot;AssaultRifle=fire_shot;Minigun=fire_shot;Marksman=fire_shot;Shotgun=fire_orb;SuperShotgun=fire_orb;AutoShotgun=fire_orb;GrenadeLauncher=fire_blast;Crossbow=fire_bow;BFG=fire_energy", "Which .wav (from the sounds/ folder, no extension) each weapon fires with. Format: 'Weapon=basename;Weapon=basename'. Shipped: fire_shot fire_blast fire_heavy fire_bow fire_orb fire_energy. A weapon with no entry, or a missing file, uses the built-in procedural sound."); WeaponSoundVolume = cfg.Bind("Audio", "WeaponSoundVolume", 0.6f, "Master volume (0..1) for weapon fire/reload SFX."); DefaultMonsterHP = cfg.Bind("Health", "DefaultMonsterHP", 120f, "HP used when a monster type is not in the override table."); MonsterHealthMultiplier = cfg.Bind("Health", "MonsterHealthMultiplier", 1f, "Global multiplier applied on top of every monster HP value."); MonsterHealthOverrides = cfg.Bind("Health", "MonsterHealthOverrides", "BigSlap=400,Barnacle Ball=90,BarnacleBall=90,Snatcho=140,Spider=100,Weeping=250,WeepingAngel=250,Zombe=90,Zombie=90,Larva=60,Jello=110,Jelly=110,Knifo=120,Mouth=150,Ear=70,Slurper=90,EyeGuy=130,Eye Guy=130,Dog=110,Ghost=200,Angler=500,Kicker=120,ToolkitBoy=120,Toolkit Boy=120,Wallo=180,Puffo=80,Mime=140,SnailSpawner=200,Streamer=120,Worm=90,FireMonster=160,CameraCreep=90,Skinny=140,Chaser=110", "Comma list of =. Name = networked prefab name without '(Clone)'. Unknown/mistyped names simply fall back to DefaultMonsterHP."); PistolDamage = cfg.Bind("Pistol", "PistolDamage", 25f, ""); PistolFireRate = cfg.Bind("Pistol", "PistolFireRate", 4f, "Shots per second."); PistolMagazine = cfg.Bind("Pistol", "PistolMagazine", 12, ""); PistolReserve = cfg.Bind("Pistol", "PistolReserve", 120, ""); PistolReload = cfg.Bind("Pistol", "PistolReload", 1.2f, "Seconds."); PistolRange = cfg.Bind("Pistol", "PistolRange", 100f, "Metres."); ShotgunDamagePerPellet = cfg.Bind("Shotgun", "ShotgunDamagePerPellet", 12f, ""); ShotgunPellets = cfg.Bind("Shotgun", "ShotgunPellets", 10, ""); ShotgunSpread = cfg.Bind("Shotgun", "ShotgunSpread", 5.5f, "Cone half-angle in degrees."); ShotgunMagazine = cfg.Bind("Shotgun", "ShotgunMagazine", 6, ""); ShotgunReserve = cfg.Bind("Shotgun", "ShotgunReserve", 48, ""); ShotgunFireDelay = cfg.Bind("Shotgun", "ShotgunFireDelay", 0.8f, "Seconds between shots."); ShotgunReload = cfg.Bind("Shotgun", "ShotgunReload", 2.2f, ""); ShotgunRange = cfg.Bind("Shotgun", "ShotgunRange", 60f, ""); ShotgunKnockback = cfg.Bind("Shotgun", "ShotgunKnockback", 6f, "Impulse applied to any Rigidbody on hit (small monsters only)."); SuperShotgunDamagePerPellet = cfg.Bind("SuperShotgun", "SuperShotgunDamagePerPellet", 14f, ""); SuperShotgunPellets = cfg.Bind("SuperShotgun", "SuperShotgunPellets", 20, ""); SuperShotgunSpread = cfg.Bind("SuperShotgun", "SuperShotgunSpread", 9f, ""); SuperShotgunMagazine = cfg.Bind("SuperShotgun", "SuperShotgunMagazine", 2, ""); SuperShotgunReserve = cfg.Bind("SuperShotgun", "SuperShotgunReserve", 32, ""); SuperShotgunFireDelay = cfg.Bind("SuperShotgun", "SuperShotgunFireDelay", 1.1f, ""); SuperShotgunReload = cfg.Bind("SuperShotgun", "SuperShotgunReload", 3f, ""); SuperShotgunRange = cfg.Bind("SuperShotgun", "SuperShotgunRange", 45f, ""); SuperShotgunKnockback = cfg.Bind("SuperShotgun", "SuperShotgunKnockback", 11f, ""); BFGDirectDamage = cfg.Bind("BFG", "BFGDirectDamage", 1000f, ""); BFGExplosionDamage = cfg.Bind("BFG", "BFGExplosionDamage", 500f, "Damage at the centre of the blast, falls off to 0 at BFGRadius."); BFGRadius = cfg.Bind("BFG", "BFGRadius", 15f, ""); BFGProjectileSpeed = cfg.Bind("BFG", "BFGProjectileSpeed", 22f, ""); BFGTrackingDamage = cfg.Bind("BFG", "BFGTrackingDamage", 60f, "Damage/second dealt to monsters within radius while the orb flies."); BFGMagazine = cfg.Bind("BFG", "BFGMagazine", 1, ""); BFGReserve = cfg.Bind("BFG", "BFGReserve", 4, ""); BFGFireDelay = cfg.Bind("BFG", "BFGFireDelay", 1.5f, ""); BFGReload = cfg.Bind("BFG", "BFGReload", 3.5f, ""); MinigunDamage = cfg.Bind("Minigun", "MinigunDamage", 9f, "Damage per bullet (low; it's a crowd shredder)."); MinigunFireRate = cfg.Bind("Minigun", "MinigunFireRate", 16f, "Bullets per second at full spin."); MinigunMagazine = cfg.Bind("Minigun", "MinigunMagazine", 150, ""); MinigunReserve = cfg.Bind("Minigun", "MinigunReserve", 450, ""); MinigunReload = cfg.Bind("Minigun", "MinigunReload", 4.5f, ""); MinigunRange = cfg.Bind("Minigun", "MinigunRange", 80f, ""); MinigunSpread = cfg.Bind("Minigun", "MinigunSpread", 3.5f, "Cone half-angle, degrees."); MinigunSpinUp = cfg.Bind("Minigun", "MinigunSpinUp", 0.7f, "Seconds of hold before it reaches full fire rate."); GrenadeDirectDamage = cfg.Bind("GrenadeLauncher", "GrenadeDirectDamage", 90f, "Damage to a monster the grenade hits directly."); GrenadeExplosionDamage = cfg.Bind("GrenadeLauncher", "GrenadeExplosionDamage", 140f, "Blast damage at the centre, falls off to 25% at the radius."); GrenadeRadius = cfg.Bind("GrenadeLauncher", "GrenadeRadius", 6f, ""); GrenadeSpeed = cfg.Bind("GrenadeLauncher", "GrenadeSpeed", 28f, "Muzzle speed. It arcs under gravity."); GrenadeFuse = cfg.Bind("GrenadeLauncher", "GrenadeFuse", 2.5f, "Seconds before it detonates if it hasn't hit anything."); GrenadeMagazine = cfg.Bind("GrenadeLauncher", "GrenadeMagazine", 4, ""); GrenadeReserve = cfg.Bind("GrenadeLauncher", "GrenadeReserve", 24, ""); GrenadeFireDelay = cfg.Bind("GrenadeLauncher", "GrenadeFireDelay", 0.9f, ""); GrenadeReload = cfg.Bind("GrenadeLauncher", "GrenadeReload", 2.6f, ""); GrenadeKnockback = cfg.Bind("GrenadeLauncher", "GrenadeKnockback", 12f, "Impulse to light monsters in the blast."); MonsterSpawnMultiplier = cfg.Bind("Horde", "MonsterSpawnMultiplier", 3f, "Each vanilla monster spawn is duplicated to this many (host only). 1 = vanilla."); MaxActiveMonsters = cfg.Bind("Horde", "MaxActiveMonsters", 40, "Hard cap on live monsters; the multiplier stops adding past this."); CorpseLifetime = cfg.Bind("Death", "CorpseLifetime", 12f, "Seconds a dead monster stays before the host removes it. <=0 keeps forever."); GloryKillHealthFraction = cfg.Bind("GloryKill", "GloryKillHealthFraction", 0.2f, "Monster becomes STAGGERED at/below this fraction of max HP."); GloryKillRange = cfg.Bind("GloryKill", "GloryKillRange", 2.5f, "Metres for the [E] FINISH prompt."); GloryKillHealAmount = cfg.Bind("GloryKill", "GloryKillHealAmount", 25f, "HP restored to the player on a successful Glory Kill (uses Player.CallHeal)."); RegistryScanInterval = cfg.Bind("Performance", "RegistryScanInterval", 0.5f, "Seconds between BotHandler.bots reconciliation passes."); DoomMoveSpeedMultiplier = cfg.Bind("Movement", "DoomMoveSpeedMultiplier", 1.5f, "Multiplies PlayerController.movementForce while Doom Mode is on."); DoomSprintSpeedMultiplier = cfg.Bind("Movement", "DoomSprintSpeedMultiplier", 1.5f, "Multiplies PlayerController.sprintMultiplier while Doom Mode is on."); DoomJumpMultiplier = cfg.Bind("Movement", "DoomJumpMultiplier", 1.15f, "Multiplies PlayerController.jumpImpulse and jumpForceOverTime. Keep modest — not flight."); DoomInfiniteStamina = cfg.Bind("Movement", "DoomInfiniteStamina", true, "Force currentStamina full / staminaDepleated=false every frame in Doom Mode."); DoomSprintAnyDirection = cfg.Bind("Movement", "DoomSprintAnyDirection", true, "Set PlayerController.canSprintInAnyDirection so strafe/backpedal run at sprint speed (snappier)."); DoomBrakeAssist = cfg.Bind("Movement", "DoomBrakeAssist", 0.35f, "0..1 extra counter-force when your input opposes your velocity — kills the 'ice skating' coast. 0 = off."); DoomAirControlBonus = cfg.Bind("Movement", "DoomAirControlBonus", 0.4f, "Fraction of base movementForce added while airborne for tighter air control. 0 = off."); DashEnabled = cfg.Bind("Dash", "DashEnabled", true, "Double-tap Left Shift = short dash in the current movement direction (any direction)."); DashForce = cfg.Bind("Dash", "DashForce", 11f, "Total dash speed (m/s) added to the body, spread over DashDuration. ~11 = a crisp step, not a launch."); DashDuration = cfg.Bind("Dash", "DashDuration", 0.18f, "Seconds the dash impulse is applied."); DashCooldown = cfg.Bind("Dash", "DashCooldown", 1.2f, "Seconds between dashes."); DashDoubleTapWindow = cfg.Bind("Dash", "DashDoubleTapWindow", 0.28f, "Max seconds between the two Left Shift taps to trigger a dash."); ActionModeEnabled = cfg.Bind("Action", "ActionModeEnabled", true, "Run the full Action loop (Preparation -> Action -> Submit -> Results). If false, Doom Mode behaves like before."); PreparationDuration = cfg.Bind("Action", "PreparationDuration", 30f, "Seconds of prep after dropping into the level before ACTION starts (monsters held until then)."); ActionDuration = cfg.Bind("Action", "ActionDuration", 210f, "Max seconds of the Action phase before it forces Returning."); RecordingTime = cfg.Bind("Action", "RecordingTime", 90f, "Seconds of recording film each player gets per run."); CameraSubmissionTimeout = cfg.Bind("Action", "CameraSubmissionTimeout", 60f, "Seconds the TV waits for all cameras before showing the winner anyway."); MaxFilmDistance = cfg.Bind("Action", "MaxFilmDistance", 45f, "Max metres between an operator's camera and an event for it to count as filmed."); MultiKillWindow = cfg.Bind("Action", "MultiKillWindow", 2f, "Seconds between kills to keep a multikill streak alive."); MonsterVisibleCooldown = cfg.Bind("Action", "MonsterVisibleCooldown", 4f, "Min seconds between MonsterVisible events for the same monster on the same camera."); CloseRangeDistance = cfg.Bind("Action", "CloseRangeDistance", 3f, "Kill within this range of the killer = CloseRangeKill."); DashKillWindow = cfg.Bind("Action", "DashKillWindow", 0.6f, "A kill within this long after a dash counts as a DashKill."); HeadshotDamageMultiplier = cfg.Bind("Action", "HeadshotDamageMultiplier", 1.5f, "Damage multiplier for hits resolved to the head zone."); HeadTopFraction = cfg.Bind("Action", "HeadTopFraction", 0.22f, "If no named head bone, a hit in the top this-fraction of the monster's bounds counts as a headshot."); DangerHealthFraction = cfg.Bind("Action", "DangerHealthFraction", 0.35f, "Operator HP at/below this fraction while filming near monsters = DangerousMoment."); DangerRadius = cfg.Bind("Action", "DangerRadius", 8f, "Alive monsters within this radius of the filming operator for a DangerousMoment."); DangerCooldown = cfg.Bind("Action", "DangerCooldown", 6f, "Min seconds between DangerousMoment events per operator."); SpeechMicThreshold = cfg.Bind("Action", "SpeechMicThreshold", 0.25f, "Player.data.microphoneValue above this near a combat event flags SpeechMoment."); ViewsMultiplier = cfg.Bind("Action", "ViewsMultiplier", 1f, "FinalViews = ContentScore * this * (1 +/- variance)."); ViewsRandomVariance = cfg.Bind("Action", "ViewsRandomVariance", 0.1f, "+/- fraction of random variance on FinalViews."); ActionCreditsDivisor = cfg.Bind("Action", "ActionCreditsDivisor", 20f, "ActionCredits earned next run = FinalViews / this."); VarietyBonusPerType = cfg.Bind("Action", "VarietyBonusPerType", 0.12f, "Score multiplier gains this per DISTINCT content-event type the operator has filmed."); RepeatDiminishFactor = cfg.Bind("Action", "RepeatDiminishFactor", 0.15f, "Each repeat of the same event type divides its value by (1 + factor*repeats)."); RareMonsterMultiplier = cfg.Bind("Action", "RareMonsterMultiplier", 2f, "Score multiplier for events involving a rare monster."); RareMonsterNames = cfg.Bind("Action", "RareMonsterNames", "BigSlap,Weeping,WeepingAngel,Angler,Ghost", "Comma list of monster names treated as rare (name/override fallback, independent of the game's danger level)."); DangerMonsterMultiplierPerLevel = cfg.Bind("Action", "DangerMonsterMultiplierPerLevel", 0.4f, "Extra ContentScore per danger level (Bot.jumpScareLevel) above 1 for FILMED monster events: mult = 1 + this*(tier-1). tier 2 = dangerous, tier 3 = very dangerous, level 0 (special/unknown) is treated as tier 2. Stacks with RareMonsterMultiplier. Set 0 to disable."); HoldHordeUntilAction = cfg.Bind("Action", "HoldHordeUntilAction", true, "Block the horde spawn multiplier / new monster spawns until the Action phase starts."); SpawnHiddenActionCamera = cfg.Bind("Video", "SpawnHiddenActionCamera", true, "Spawn one hidden per-player VideoCamera so every player records independently. If false, only the player holding the vanilla camera records for real."); RealVideoRecording = cfg.Bind("Video", "RealVideoRecording", true, "Master switch for driving Content Warning's real recorder (RecordingsHandler) so the winning disc actually has a video to play in the TV. If false, recording is logical-only (content score still works, but the disc is empty)."); EncodeWaitTimeout = cfg.Bind("Video", "EncodeWaitTimeout", 30f, "Max seconds to wait for the vanilla recorder to encode a player's clips after Action ends."); ShareWaitTimeout = cfg.Bind("Video", "ShareWaitTimeout", 120f, "Max seconds to wait for the winner's clips to transfer to the other clients (Photon 30KB chunks — can be slow)."); AttemptTvPlayback = cfg.Bind("Video", "AttemptTvPlayback", true, "Try to play the winner's real recording on the vanilla TV (UploadCompleteUI) once it is playable."); MusicVolume = cfg.Bind("Music", "MusicVolume", 0.35f, "Volume (0..1) of the procedural epic battle loop. Alt+N toggles it on/off; Alt+=/Alt+- adjust this live (saved here); purely local, every player starts/stops their own independently."); ShowCameraViewmodel = cfg.Bind("WeaponModel", "ShowCameraViewmodel", true, "Show a cosmetic camcorder in the left hand during Action Mode (raises with a red REC light while you hold RMB). Purely visual."); ShowViewmodelArms = cfg.Bind("WeaponModel", "ShowViewmodelArms", true, "Make your REAL body arms reach out and hold the weapon (right hand) and camcorder (left hand) using Content Warning's own held-item hand IK. No fake limbs. Turn off for a bare Doom-style floating gun."); AttachToRealHands = cfg.Bind("WeaponModel", "AttachToRealHands", false, "EXPERIMENTAL: hard-parent the weapon/camera to the ragdoll hand bones instead of the camera (and skip the hand IK). Usually looks worse, leave false."); HandWeaponOffset = cfg.Bind("WeaponModel", "HandWeaponOffset", "0.03,-0.02,0.06", "Weapon local position offset (x,y,z m) inside the right hand."); HandWeaponEuler = cfg.Bind("WeaponModel", "HandWeaponEuler", "0,90,0", "Weapon local rotation (x,y,z deg) inside the right hand."); HandCameraOffset = cfg.Bind("WeaponModel", "HandCameraOffset", "-0.02,-0.02,0.05", "Camera local position offset (x,y,z m) inside the left hand."); HandCameraEuler = cfg.Bind("WeaponModel", "HandCameraEuler", "0,90,0", "Camera local rotation (x,y,z deg) inside the left hand."); CameraModelEuler = cfg.Bind("WeaponModel", "CameraModelEuler", "0,0,0", "Local rotation (x,y,z deg) for the borrowed real camera mesh in the left hand. Tweak if the lens faces the wrong way."); ShowViewfinder = cfg.Bind("WeaponModel", "ShowViewfinder", true, "Show a live corner viewfinder of exactly what your camera is filming, with REC state and film time left."); RequireCameraDeposit = cfg.Bind("Action", "RequireCameraDeposit", true, "At the end of a run every player must deposit their camera in the recycler (ExtractVideoMachine) before the winner is decided. The highest-score player then gets a disc in their inventory."); DepositRange = cfg.Bind("Action", "DepositRange", 8f, "Metres from the recycler within which [E]/[F]/RMB deposits your camera. (Alt+E hands it in from anywhere.)"); UseGunModels = cfg.Bind("WeaponModel", "UseGunModels", true, "Use the .obj gun meshes in BepInEx/plugins/ContentWarningDoom/models/ as view-models (falls back to primitives if a file is missing)."); GunModelEuler = cfg.Bind("WeaponModel", "GunModelEuler", "0,0,0", "Additive rotation (x,y,z deg) on top of the automatic barrel-forward orientation, applied to ALL guns. Leave 0,0,0; set 0,180,0 if every gun points back at you."); PerWeaponEulerOverrides = cfg.Bind("WeaponModel", "PerWeaponEulerOverrides", "Shotgun=0,180,0;SuperShotgun=0,180,0;GrenadeLauncher=0,180,0;Smg=0,180,0;AutoShotgun=0,180,0;AssaultRifle=0,0,0;Marksman=0,0,0;Crossbow=0,90,0", "Per-weapon rotation fix (deg) on top of the auto orientation. Format: 'Weapon=x,y,z;Weapon=x,y,z'. Names: Pistol Shotgun SuperShotgun BFG Minigun GrenadeLauncher Smg AssaultRifle Marksman AutoShotgun Crossbow. x = pitch (nose up/down), y = yaw (turn left/right), z = roll. Points at you: add/remove 180 on y. Points up/down: set x to -90 or 90. Points sideways: set y to 90 or -90. Applies to the in-hand view-model and the shop display; re-read live, no restart."); GunModelScaleMul = cfg.Bind("WeaponModel", "GunModelScaleMul", 1f, "Multiplier on the auto-fit scale of the gun mesh."); GunModelOffset = cfg.Bind("WeaponModel", "GunModelOffset", "0,0,0", "Extra local position offset (x,y,z metres) for the gun mesh after centring."); RightGripOffset = cfg.Bind("WeaponModel", "RightGripOffset", "0,-0.06,-0.05", "Where your real right hand grips the weapon, local to the weapon view-model (x,y,z m). The arm bends to reach this via the game's hand IK."); RightGripEuler = cfg.Bind("WeaponModel", "RightGripEuler", "0,0,0", "Right-hand wrist rotation at the grip (x,y,z deg). Tweak if the hand rolls the wrong way."); LeftGripOffset = cfg.Bind("WeaponModel", "LeftGripOffset", "0,-0.05,-0.03", "Where your real left hand grips the camcorder, local to the camera view-model (x,y,z m)."); LeftGripEuler = cfg.Bind("WeaponModel", "LeftGripEuler", "0,0,0", "Left-hand wrist rotation at the camcorder grip (x,y,z deg)."); ShowRemotePlayerWeapons = cfg.Bind("WeaponModel", "ShowRemotePlayerWeapons", true, "Show every OTHER player's current gun in their right hand, so teammates can see what you are holding (the local first-person view-model is unchanged)."); RemoteWeaponOffset = cfg.Bind("WeaponModel", "RemoteWeaponOffset", "0,0,0", "Local position offset (x,y,z m) of another player's gun relative to their right-hand bone."); RemoteWeaponEuler = cfg.Bind("WeaponModel", "RemoteWeaponEuler", "0,0,0", "Local rotation (x,y,z deg) of another player's gun relative to their right-hand bone."); RemoteWeaponScaleMul = cfg.Bind("WeaponModel", "RemoteWeaponScaleMul", 1f, "Extra scale multiplier for another player's gun on top of GunModelScaleMul."); W_MonsterVisible = cfg.Bind("ContentWeights", "MonsterVisible", 10, ""); W_MonsterKill = cfg.Bind("ContentWeights", "MonsterKill", 100, ""); W_Headshot = cfg.Bind("ContentWeights", "Headshot", 50, ""); W_HeadshotKill = cfg.Bind("ContentWeights", "HeadshotKill", 200, ""); W_AirborneKill = cfg.Bind("ContentWeights", "AirborneKill", 150, ""); W_DashKill = cfg.Bind("ContentWeights", "DashKill", 150, ""); W_GloryKill = cfg.Bind("ContentWeights", "GloryKill", 300, ""); W_MultiKill = cfg.Bind("ContentWeights", "MultiKillPerTier", 200, "Score = this * (tier-1): double=200, triple=400, quad=600, massacre(5+)=800."); W_BFGMultiKill = cfg.Bind("ContentWeights", "BFGMultiKill", 1000, ""); W_CloseRangeKill = cfg.Bind("ContentWeights", "CloseRangeKill", 100, ""); W_DangerMoment = cfg.Bind("ContentWeights", "DangerMoment", 100, ""); W_SpeechMoment = cfg.Bind("ContentWeights", "SpeechMoment", 40, ""); W_PlayerCombat = cfg.Bind("ContentWeights", "PlayerCombat", 80, "Filming another player fighting."); W_PlayerKill = cfg.Bind("ContentWeights", "PlayerKill", 150, "Filming one player kill another during the PvP (Action) phase. Awarded to whoever's camera caught it — film your own frags to score."); HandRecoilForceMultiplier = cfg.Bind("HitFeel", "HandRecoilForceMultiplier", 1f, "Multiplier on the physical impulse pushed into the shooter's real right hand on every shot (CW Player.CallAddForceToBodyParts). This is ON TOP of the view-model recoil and camera kick, and other players can see the arm move. 0 disables it."); MonsterHitReactionForceMultiplier = cfg.Bind("HitFeel", "MonsterHitReactionForceMultiplier", 1f, "Multiplier on the knockback impulse of the native CW hit reaction for humanoid monsters (damage-free — real HP/death stay in our host-authoritative layer). 0 keeps only the plain Rigidbody flinch."); MonsterHitReactionFallEnabled = cfg.Bind("HitFeel", "MonsterHitReactionFallEnabled", true, "Allow the native reaction to briefly drop a humanoid monster (short CW fall) on strong / headshot / staggered hits. Disable to keep only force, never a knockdown."); MonsterHitReactionFallCooldown = cfg.Bind("HitFeel", "MonsterHitReactionFallCooldown", 0.6f, "Minimum seconds between two knockdown reactions on the same monster, so rapid fire cannot stun-lock it (a normal Rigidbody flinch still happens in between)."); MonsterHitReactionMaxFall = cfg.Bind("HitFeel", "MonsterHitReactionMaxFall", 1f, "Hard cap (seconds) on any single native fall reaction."); WeaponShopEnabled = cfg.Bind("Shop", "WeaponShopEnabled", true, "Spawn the WEAPON BENCH structure on the Surface (near the dive bell, marked by a tall orange light). Walk up to a gun on display and press E to buy it (then a digit 1-6 to assign it), or press B for the full panel. Scrap is earned from Doom-Mode kills."); ScrapPerKill = cfg.Bind("Shop", "ScrapPerKill", 6, "Scrap earned by the local player for each monster they kill in Doom Mode."); ScrapPerDangerLevel = cfg.Bind("Shop", "ScrapPerDangerLevel", 4, "Extra Scrap per danger level (Bot.jumpScareLevel) above 1: total = ScrapPerKill + this*(tier-1). tier 2/0 = dangerous, tier 3 = very dangerous."); ShopUseRange = cfg.Bind("Shop", "ShopUseRange", 4.5f, "Metres from the bench within which the [B] prompt appears."); ShopPositionOffset = cfg.Bind("Shop", "ShopPositionOffset", "0,0,0", "Optional nudge (x,y,z m) from the spot where you're standing when the bench spawns. 0,0,0 = right where you stand."); ShopPriceSMG = cfg.Bind("Shop", "ShopPriceSMG", 120, "Scrap price to unlock the SMG (one-time; re-assigning an owned gun to any slot is free)."); ShopPriceAssaultRifle = cfg.Bind("Shop", "ShopPriceAssaultRifle", 160, "Scrap price to unlock the Assault Rifle."); ShopPriceMarksman = cfg.Bind("Shop", "ShopPriceMarksman", 220, "Scrap price to unlock the Marksman Rifle."); ShopPriceAutoShotgun = cfg.Bind("Shop", "ShopPriceAutoShotgun", 200, "Scrap price to unlock the Auto Shotgun."); ShopPriceCrossbow = cfg.Bind("Shop", "ShopPriceCrossbow", 180, "Scrap price to unlock the Crossbow."); } public static float GetMonsterMaxHP(string monsterName) { if (_overrides == null) { ParseOverrides(); } float num = DefaultMonsterHP.Value; if (!string.IsNullOrEmpty(monsterName)) { if (_overrides.TryGetValue(monsterName, out var value)) { num = value; } else { foreach (KeyValuePair @override in _overrides) { if (monsterName.IndexOf(@override.Key, StringComparison.OrdinalIgnoreCase) >= 0) { num = @override.Value; break; } } } } return Mathf_Max(1f, num * MonsterHealthMultiplier.Value); } public static void ReparseOverrides() { ParseOverrides(); } private static void ParseOverrides() { _overrides = new Dictionary(StringComparer.OrdinalIgnoreCase); string[] array = (MonsterHealthOverrides.Value ?? "").Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0) { continue; } int num = text.LastIndexOf('='); if (num > 0) { string key = text.Substring(0, num).Trim(); if (float.TryParse(text.Substring(num + 1).Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { _overrides[key] = result; } } } } private static float Mathf_Max(float a, float b) { if (!(a > b)) { return b; } return a; } } } namespace ContentWarningDoom.Combat { public static class DamageSystem { private const float MaxHitDistance = 200f; private const float MaxSingleHit = 2000f; private static bool _hostHooked; public static bool FriendlyFireLive() { if (!Plugin.DoomModeActive) { return false; } if (DoomConfig.FriendlyFireDamageMultiplier.Value <= 0f) { return false; } try { if ((Object)(object)SurfaceNetworkHandler.Instance != (Object)null) { return false; } } catch { } if (DoomConfig.ActionModeEnabled.Value) { return ActionRoundManager.Phase == ActionRoundPhase.Action; } return true; } public static void HookHost() { if (!_hostHooked) { _hostHooked = true; DoomNet.OnHitRequest += HostHandleHitRequest; DoomNet.OnGloryRequest += HostHandleGloryRequest; DoomNet.OnKills += KillCounter.SetTeamKillsFromNetwork; } } public static void ReportHit(MonsterHealth h, float damage, Vector3 point, Vector3 normal, Vector3 shotDir, DamageType type, byte weapon, HitZone zone) { //IL_0004: 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_003e: 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_0037: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (h != null) { BloodEffects.SpawnHit(point, normal); ImpactEffects.MonsterFlash(h); if (zone == HitZone.Head) { Plugin.HudHeadshot(); } else { Plugin.HudHitMarker(); } bool headshot = zone == HitZone.Head; Vector3 dir = ((((Vector3)(ref shotDir)).sqrMagnitude > 0.0001f) ? shotDir : (-normal)); if (!TriggerHitReaction(h, dir, type, weapon, headshot)) { ApplyKnockback(h, -normal, type, weapon); } if (DoomNet.IsHost) { ApplyToHealth(h, damage, -normal, type, DoomNet.LocalActor); } else { DoomNet.SendHitRequest(h.ViewId, damage, point, normal, (byte)type); } } } public static bool TriggerHitReaction(MonsterHealth h, Vector3 dir, DamageType type, byte weapon, bool headshot) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) if (h == null || (Object)(object)h.Root == (Object)null || !h.Alive) { return false; } Player monsterPlayer = h.MonsterPlayer; if ((Object)(object)monsterPlayer == (Object)null || monsterPlayer.data == null || monsterPlayer.data.dead) { return false; } Vector3 val = ((((Vector3)(ref dir)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref dir)).normalized : Vector3.forward); val.y = Mathf.Clamp(val.y, 0.05f, 0.5f); val = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : Vector3.up); bool flag = h.MaxHP > 200f; float num; float num2; switch (type) { case DamageType.BFG: num = 14f; num2 = (flag ? 0.15f : 0.55f); break; case DamageType.Explosion: num = 11f; num2 = (flag ? 0.1f : 0.45f); break; case DamageType.GloryKill: num = 10f; num2 = 0.4f; break; case DamageType.Pellet: { bool flag2 = weapon == 2; num = (flag2 ? 9f : 6f); num2 = (flag ? 0f : (flag2 ? 0.3f : 0.16f)); break; } default: num = 3.5f; num2 = 0f; break; } if (headshot) { num *= 1.6f; num2 = Mathf.Max(num2, flag ? 0f : 0.18f); } if (h.Staggered) { num *= 1.4f; num2 += 0.15f; } num *= Mathf.Max(0f, DoomConfig.MonsterHitReactionForceMultiplier.Value); if (!DoomConfig.MonsterHitReactionFallEnabled.Value) { num2 = 0f; } if (num2 <= 0f || num <= 0.01f) { return false; } if (Time.time - h.LastReactionTime < Mathf.Max(0.05f, DoomConfig.MonsterHitReactionFallCooldown.Value)) { return false; } num2 = Mathf.Min(num2, Mathf.Max(0.05f, DoomConfig.MonsterHitReactionMaxFall.Value)); if (CwRagdollApi.TakeDamageAndAddForceAndFall(monsterPlayer, 0f, val * num, num2)) { h.LastReactionTime = Time.time; return true; } return false; } public static void ReportWorldImpact(Vector3 point, Vector3 normal) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) ImpactEffects.SpawnWorld(point, normal); } private static void HostHandleHitRequest(int viewId, float damage, Vector3 hitPoint, Vector3 normal, byte dmgType, int attackerActor) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!DoomNet.IsHost || !Plugin.DoomModeActive || (Object)(object)MonsterRegistry.Instance == (Object)null || !MonsterRegistry.Instance.TryGet(viewId, out var h) || !h.Alive || damage <= 0f || damage > 2000f) { return; } if ((Object)(object)h.Center != (Object)null) { Vector3 val = h.CenterPos - hitPoint; if (((Vector3)(ref val)).sqrMagnitude > 40000f) { return; } } ApplyAuthoritative(viewId, damage, hitPoint, -normal, (DamageType)dmgType, attackerActor); } private static void HostHandleGloryRequest(int viewId, int attackerActor) { HostGloryKill(viewId, attackerActor); } public static void HostGloryKill(int viewId, int attackerActor) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (DoomNet.IsHost && Plugin.DoomModeActive && !((Object)(object)MonsterRegistry.Instance == (Object)null) && MonsterRegistry.Instance.TryGet(viewId, out var h) && h.Alive && (h.Staggered || !(h.CurrentHP > h.MaxHP * DoomConfig.GloryKillHealthFraction.Value))) { HostKill(h, Vector3.zero, attackerActor, DamageType.GloryKill); } } public static void ApplyAuthoritative(int viewId, float damage, Vector3 hitPoint, Vector3 dir, DamageType type, int attackerActor) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (DoomNet.IsHost && !((Object)(object)MonsterRegistry.Instance == (Object)null) && MonsterRegistry.Instance.TryGet(viewId, out var h)) { ApplyToHealth(h, damage, dir, type, attackerActor); } } public static void ApplyToHealth(MonsterHealth h, float damage, Vector3 dir, DamageType type, int attackerActor) { //IL_011d: Unknown result type (might be due to invalid IL or missing references) if (DoomNet.IsHost && h != null && h.Alive) { h.CurrentHP = Mathf.Max(0f, h.CurrentHP - damage); h.LastDamageTime = Time.time; h.LastDamageActor = attackerActor; if (h.CurrentHP > 0f && h.CurrentHP <= h.MaxHP * DoomConfig.GloryKillHealthFraction.Value && !h.Staggered) { h.Staggered = true; Plugin.LogMonster($"{h.MonsterName} id={h.ViewId} STAGGERED ({h.CurrentHP:0}/{h.MaxHP:0})"); } Plugin.LogDamage($"{h.MonsterName} hit for {damage:0} HP={h.CurrentHP:0}/{h.MaxHP:0} ({type})"); if (h.CurrentHP <= 0f) { HostKill(h, dir, attackerActor, type); } else if (h.ViewId != 0) { DoomNet.SendMonsterHp(h.ViewId, h.CurrentHP, h.MaxHP, h.Flags); } } } private static bool HasLineOfSight(Vector3 from, Vector3 to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.6f) { return true; } return !Physics.Raycast(from, val / magnitude, magnitude - 0.6f, -1, (QueryTriggerInteraction)1); } public static void ApplyRadius(Vector3 center, float radius, float centerDamage, DamageType type, int attackerActor) { //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (!DoomNet.IsHost || (Object)(object)MonsterRegistry.Instance == (Object)null) { return; } foreach (MonsterHealth item in MonsterRegistry.Instance.All) { if (item.Alive) { float num = Vector3.Distance(item.CenterPos, center); if (!(num > radius) && HasLineOfSight(center, item.CenterPos)) { float damage = Mathf.Lerp(centerDamage, centerDamage * 0.25f, num / Mathf.Max(0.01f, radius)); Vector3 val = item.CenterPos - center; Vector3 normalized = ((Vector3)(ref val)).normalized; TriggerHitReaction(item, normalized, type, 0, headshot: false); ApplyToHealth(item, damage, normalized, type, attackerActor); } } } float num2 = Mathf.Max(0f, DoomConfig.FriendlyFireDamageMultiplier.Value); if (!(num2 > 0f) || !FriendlyFireLive()) { return; } PlayerHandler instance = PlayerHandler.instance; if (!((Object)(object)instance != (Object)null) || instance.players == null) { return; } for (int i = 0; i < instance.players.Count; i++) { Player val2 = instance.players[i]; if ((Object)(object)val2 == (Object)null || val2.data == null || val2.data.dead || val2.refs == null) { continue; } int num3 = 0; try { if ((Object)(object)val2.refs.view != (Object)null && val2.refs.view.Owner != null) { num3 = val2.refs.view.Owner.ActorNumber; } } catch { } if (num3 == 0 || num3 == attackerActor) { continue; } Vector3 val3 = (((Object)(object)val2.refs.headPos != (Object)null) ? val2.refs.headPos.position : ((Component)val2).transform.position); float num4 = Vector3.Distance(val3, center); if (!(num4 > radius) && HasLineOfSight(center, val3)) { float num5 = Mathf.Lerp(centerDamage, centerDamage * 0.25f, num4 / Mathf.Max(0.01f, radius)) * num2; if (!(num5 <= 0f)) { DoomNet.SendFriendlyHit(num3, num5); Plugin.LogDamage($"blast friendly fire {num5:0} -> actor {num3} ({type}, {num4:0.0}m)"); } } } } private static void HostKill(MonsterHealth h, Vector3 dir, int killerActor, DamageType type) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (!h.Dead) { h.Dead = true; h.CurrentHP = 0f; h.LastDamageActor = killerActor; Plugin.LogMonster($"{h.MonsterName} id={h.ViewId} killed by actor {killerActor} ({type})"); DoomNet.SendMonsterDeath(h.ViewId, dir, killerActor); KillCounter.HostRegisterKill(killerActor); MonsterDeath.KillLocal(h, dir); } } private static void ApplyKnockback(MonsterHealth h, Vector3 dir, DamageType type, byte weapon) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) float num = 0f; switch (type) { case DamageType.Pellet: num = ((weapon == 2) ? DoomConfig.SuperShotgunKnockback.Value : DoomConfig.ShotgunKnockback.Value); break; case DamageType.Explosion: case DamageType.BFG: num = 14f; break; case DamageType.GloryKill: num = 18f; break; } if (num <= 0f || (Object)(object)h.Root == (Object)null || (h.MaxHP > 200f && type == DamageType.Pellet)) { return; } Rigidbody[] componentsInChildren = h.Root.GetComponentsInChildren(); foreach (Rigidbody val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !val.isKinematic) { val.AddForce(((Vector3)(ref dir)).normalized * num, (ForceMode)2); } } } } public static class KillCounter { public static int PersonalKills { get; private set; } public static int TeamKills { get; private set; } public static void ResetAll() { PersonalKills = 0; TeamKills = 0; } public static void HostRegisterKill(int killerActor) { TeamKills++; if (killerActor == DoomNet.LocalActor) { PersonalKills++; } DoomNet.SendKills(TeamKills); } public static void SetTeamKillsFromNetwork(int value) { TeamKills = value; } public static void NoteLocalCredit(int killerActor) { if (killerActor == DoomNet.LocalActor && !DoomNet.IsHost) { PersonalKills++; } } } public enum DamageType : byte { Bullet, Pellet, Explosion, BFG, Melee, GloryKill } public struct DamageInfo { public MonsterHealth Target; public float Damage; public Vector3 HitPoint; public Vector3 HitNormal; public int AttackerActor; public byte Weapon; public DamageType Type; } public class MonsterHealth { public int ViewId; public Bot Bot; public GameObject Root; public Transform Center; public string MonsterName; public Player MonsterPlayer; public PlayerRagdoll Ragdoll; public float MaxHP; public float CurrentHP; public bool Dead; public bool Staggered; public float LastDamageTime; public int LastDamageActor; public float LastReactionTime; public int JumpScareLevel { get { if (!((Object)(object)Bot != (Object)null)) { return -1; } return Bot.jumpScareLevel; } } public bool Alive { get { if (!Dead && (Object)(object)Bot != (Object)null) { return (Object)(object)Root != (Object)null; } return false; } } public Vector3 CenterPos { get { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Center != (Object)null)) { if (!((Object)(object)Bot != (Object)null) || !((Object)(object)Bot.centerTransform != (Object)null)) { if (!((Object)(object)Root != (Object)null)) { return Vector3.zero; } return Root.transform.position + Vector3.up; } return Bot.centerTransform.position; } return Center.position; } } public byte Flags => Staggered ? ((byte)1) : ((byte)0); public void ResetHealth(float max) { MaxHP = Mathf.Max(1f, max); CurrentHP = MaxHP; Dead = false; Staggered = false; } } public class MonsterRegistry : MonoBehaviour { private readonly Dictionary _byView = new Dictionary(); private readonly Dictionary _byBot = new Dictionary(); private readonly Dictionary _byRoot = new Dictionary(); private readonly List _scratchRemove = new List(); private float _nextScan; public static MonsterRegistry Instance { get; private set; } public int Count => _byView.Count; public IEnumerable All => _byView.Values; public int AliveCount { get { int num = 0; foreach (MonsterHealth value in _byView.Values) { if (value.Alive) { num++; } } return num; } } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.MonsterRegistry"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void OnEnable() { DoomNet.OnMonsterRegister += HandleRegister; DoomNet.OnMonsterHp += HandleHp; DoomNet.OnMonsterDeath += HandleDeath; DoomNet.OnHostPlayerJoined += RebroadcastAll; } private void OnDisable() { DoomNet.OnMonsterRegister -= HandleRegister; DoomNet.OnMonsterHp -= HandleHp; DoomNet.OnMonsterDeath -= HandleDeath; DoomNet.OnHostPlayerJoined -= RebroadcastAll; } public void Clear() { _byView.Clear(); _byBot.Clear(); _byRoot.Clear(); } private void Update() { if (Plugin.DoomModeActive && !(Time.time < _nextScan)) { _nextScan = Time.time + Mathf.Max(0.1f, DoomConfig.RegistryScanInterval.Value); Reconcile(); } } private void Reconcile() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) BotHandler instance = BotHandler.instance; if ((Object)(object)instance == (Object)null || instance.bots == null) { return; } for (int i = 0; i < instance.bots.Count; i++) { Bot val = instance.bots[i]; if ((Object)(object)val == (Object)null || _byBot.ContainsKey(val)) { continue; } int num = ResolveViewId(val); string text = MonsterName(val); if (num != 0 && _byView.TryGetValue(num, out var value)) { BindComponents(value, val); value.MonsterName = text; _byBot[val] = value; _byRoot[((Component)val).transform.root] = value; if (value.Dead) { MonsterDeath.KillLocal(value, Vector3.zero); } continue; } value = new MonsterHealth { ViewId = num, MonsterName = text }; BindComponents(value, val); value.ResetHealth(DoomConfig.GetMonsterMaxHP(text)); _byBot[val] = value; _byRoot[((Component)val).transform.root] = value; if (num != 0) { _byView[num] = value; } if (DoomNet.IsHost) { DoomNet.SendMonsterRegister(num, value.MaxHP, value.CurrentHP, text); Plugin.LogMonster($"Registered {text} id={num} HP={value.MaxHP:0}"); } } _scratchRemove.Clear(); foreach (KeyValuePair item in _byView) { if ((Object)(object)item.Value.Root == (Object)null || (Object)(object)item.Value.Bot == (Object)null) { _scratchRemove.Add(item.Key); } } foreach (int item2 in _scratchRemove) { MonsterHealth monsterHealth = _byView[item2]; _byView.Remove(item2); if ((Object)(object)monsterHealth.Bot != (Object)null) { _byBot.Remove(monsterHealth.Bot); } } List list = new List(); foreach (KeyValuePair item3 in _byBot) { if ((Object)(object)item3.Key == (Object)null || (Object)(object)item3.Value.Root == (Object)null) { list.Add(item3.Key); } } foreach (Bot item4 in list) { if ((Object)(object)item4 != (Object)null) { _byBot.Remove(item4); } } List list2 = new List(); foreach (KeyValuePair item5 in _byRoot) { if ((Object)(object)item5.Key == (Object)null || (Object)(object)item5.Value.Root == (Object)null) { list2.Add(item5.Key); } } foreach (Transform item6 in list2) { _byRoot.Remove(item6); } } private static void BindComponents(MonsterHealth h, Bot bot) { h.Bot = bot; h.Root = ((Component)((Component)bot).transform.root).gameObject; h.Center = bot.centerTransform; h.MonsterPlayer = ((Component)((Component)bot).transform.root).GetComponentInChildren(true); h.Ragdoll = (((Object)(object)h.MonsterPlayer != (Object)null && h.MonsterPlayer.refs != null && (Object)(object)h.MonsterPlayer.refs.ragdoll != (Object)null) ? h.MonsterPlayer.refs.ragdoll : ((Component)((Component)bot).transform.root).GetComponentInChildren(true)); } public static int ResolveViewId(Bot bot) { if ((Object)(object)bot == (Object)null) { return 0; } PhotonView componentInParent = ((Component)bot).GetComponentInParent(); if (!((Object)(object)componentInParent != (Object)null)) { return 0; } return componentInParent.ViewID; } public static string MonsterName(Bot bot) { if ((Object)(object)bot == (Object)null) { return "Monster"; } string text = ((Object)((Component)((Component)bot).transform.root).gameObject).name; int num = text.IndexOf("(Clone)", StringComparison.Ordinal); if (num >= 0) { text = text.Substring(0, num); } return text.Trim(); } public bool TryGet(int viewId, out MonsterHealth h) { return _byView.TryGetValue(viewId, out h); } public bool TryGetByCollider(Collider col, out MonsterHealth h) { h = null; if ((Object)(object)col == (Object)null) { return false; } Bot componentInParent = ((Component)col).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && _byBot.TryGetValue(componentInParent, out h) && h != null) { return true; } Transform root = ((Component)col).transform.root; if ((Object)(object)root != (Object)null && _byRoot.TryGetValue(root, out h) && h != null) { return true; } if ((Object)(object)root != (Object)null) { Bot componentInChildren = ((Component)root).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null && _byBot.TryGetValue(componentInChildren, out h) && h != null) { return true; } } h = null; return false; } public bool IsMonsterCollider(Collider col) { MonsterHealth h; return TryGetByCollider(col, out h); } public MonsterHealth Nearest(Vector3 pos, float maxDist, bool aliveOnly = true) { //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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) MonsterHealth result = null; float num = maxDist * maxDist; foreach (MonsterHealth value in _byView.Values) { if ((!aliveOnly || value.Alive) && !((Object)(object)value.Root == (Object)null)) { Vector3 val = value.CenterPos - pos; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = value; } } } return result; } private void HandleRegister(int viewId, float maxHp, float curHp, string name) { if (!DoomNet.IsHost) { if (_byView.TryGetValue(viewId, out var value)) { value.MaxHP = maxHp; value.CurrentHP = curHp; value.MonsterName = name; return; } value = new MonsterHealth { ViewId = viewId, MonsterName = name, MaxHP = maxHp, CurrentHP = curHp }; _byView[viewId] = value; } } private void HandleHp(int viewId, float curHp, float maxHp, byte flags) { if (_byView.TryGetValue(viewId, out var value)) { value.CurrentHP = curHp; value.MaxHP = maxHp; value.Staggered = (flags & 1) != 0; } } private void HandleDeath(int viewId, Vector3 dir, int killerActor) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (_byView.TryGetValue(viewId, out var value)) { value.Dead = true; value.CurrentHP = 0f; value.LastDamageActor = killerActor; MonsterDeath.KillLocal(value, dir); } } private void RebroadcastAll() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (!DoomNet.IsHost) { return; } foreach (MonsterHealth value in _byView.Values) { DoomNet.SendMonsterRegister(value.ViewId, value.MaxHP, value.CurrentHP, value.MonsterName); if (value.Dead) { DoomNet.SendMonsterDeath(value.ViewId, Vector3.zero, value.LastDamageActor); } else { DoomNet.SendMonsterHp(value.ViewId, value.CurrentHP, value.MaxHP, value.Flags); } } } } public static class ScrapEconomy { private static readonly Dictionary _scrap = new Dictionary(); private static readonly Dictionary> _owned = new Dictionary>(); public static int Local => Get(DoomNet.LocalActor); public static int Get(int actor) { if (!_scrap.TryGetValue(actor, out var value)) { return 0; } return value; } public static void Add(int actor, int amount) { if (amount > 0) { _scrap[actor] = Get(actor) + amount; } } public static bool Spend(int actor, int amount) { if (amount < 0 || Get(actor) < amount) { return false; } _scrap[actor] = Get(actor) - amount; return true; } private static HashSet OwnedSet(int actor) { if (!_owned.TryGetValue(actor, out var value)) { value = new HashSet(); _owned[actor] = value; } return value; } public static bool Owns(int actor, WeaponId id) { return OwnedSet(actor).Contains(id); } public static bool Buy(int actor, WeaponId id, int price) { HashSet hashSet = OwnedSet(actor); if (hashSet.Contains(id)) { return true; } if (!Spend(actor, Mathf.Max(0, price))) { return false; } hashSet.Add(id); Plugin.LogWeapon($"[Bench] actor {actor} bought {id} for {price} scrap ({Get(actor)} left)"); return true; } public static void AwardForKill(int monsterViewId) { int num = -1; if ((Object)(object)MonsterRegistry.Instance != (Object)null && MonsterRegistry.Instance.TryGet(monsterViewId, out var h)) { num = h.JumpScareLevel; } int num2 = ((num >= 3) ? 3 : ((num != 2 && num != 0) ? 1 : 2)); int amount = Mathf.Max(0, DoomConfig.ScrapPerKill.Value) + Mathf.Max(0, DoomConfig.ScrapPerDangerLevel.Value) * (num2 - 1); Add(DoomNet.LocalActor, amount); } public static void Clear() { _scrap.Clear(); _owned.Clear(); } } } namespace ContentWarningDoom.Audio { public class EpicMusic : MonoBehaviour { private enum DoomTrack { CrimsonMarch, DoomBelow, LastStand, RipAndRun } private enum Wave { Square, Saw, Sine } private const int Sr = 44100; private const int Bars = 16; private AudioSource _src; private DoomTrack _lastTrack = (DoomTrack)(-1); private static readonly Dictionary NoteBase = new Dictionary { { "C", -9 }, { "C#", -8 }, { "D", -7 }, { "D#", -6 }, { "E", -5 }, { "F", -4 }, { "F#", -3 }, { "G", -2 }, { "G#", -1 }, { "A", 0 }, { "A#", 1 }, { "B", 2 } }; private static readonly int[] NaturalMinor = new int[7] { 0, 2, 3, 5, 7, 8, 10 }; private static readonly int[][] ChordsCrimson = new int[4][] { new int[3] { N("A", 3), N("C", 4), N("E", 4) }, new int[3] { N("F", 3), N("A", 3), N("C", 4) }, new int[3] { N("C", 4), N("E", 4), N("G", 4) }, new int[3] { N("G", 3), N("B", 3), N("D", 4) } }; private static readonly int[][] ChordsDoom = new int[4][] { new int[3] { N("D", 3), N("F", 3), N("A", 3) }, new int[3] { N("A#", 3), N("D", 4), N("F", 4) }, new int[3] { N("F", 3), N("A", 3), N("C", 4) }, new int[3] { N("C", 4), N("E", 4), N("G", 4) } }; private static readonly int[] TensionChordDoom = new int[3] { N("D", 3), N("G#", 3), N("C", 4) }; private static readonly int[][] ChordsLastStand = new int[4][] { new int[3] { N("E", 3), N("G", 3), N("B", 3) }, new int[3] { N("C", 4), N("E", 4), N("G", 4) }, new int[3] { N("G", 3), N("B", 3), N("D", 4) }, new int[3] { N("D", 4), N("F#", 4), N("A", 4) } }; private static readonly int[][] ChordsRipRun = new int[4][] { new int[3] { N("C", 4), N("D#", 4), N("G", 4) }, new int[3] { N("G#", 3), N("C", 4), N("D#", 4) }, new int[3] { N("D#", 4), N("G", 4), N("A#", 4) }, new int[3] { N("A#", 3), N("D", 4), N("F", 4) } }; private static readonly int[] MotifDegreesMarch = new int[5] { 1, 5, 4, 3, 1 }; private static readonly int[] MotifTicksMarch = new int[5] { 0, 4, 6, 8, 12 }; private static readonly int[] MotifLensMarch = new int[5] { 3, 2, 2, 3, 4 }; private static readonly int[] BassBuildMarch = new int[8] { 0, 0, -100, 12, 0, 7, 0, -100 }; private static readonly int[] BassClimaxMarch = new int[8] { 0, 12, 7, 12, 0, 12, 7, 12 }; private static readonly int[] KickNormalDoom = new int[4] { 0, 5, 11, 14 }; private static readonly int[] KickAggroDoom = new int[7] { 0, 3, 5, 8, 11, 13, 14 }; private static readonly int[] HatSparseDoom = new int[6] { 0, 4, 6, 8, 12, 14 }; private static readonly int[] HatDenseDoom = new int[11] { 0, 2, 4, 5, 6, 7, 8, 10, 12, 13, 15 }; private static readonly int[] BassMotifDoom = new int[8] { 0, 0, 0, 1, 0, -100, -2, 0 }; private static readonly int[] ThemeStepDegreesLastStand = new int[8] { 1, 3, 5, 6, 5, 3, 2, 1 }; private static readonly int[] BassGateRip = new int[10] { 0, 2, 4, 5, 7, 8, 10, 13, 14, 15 }; private static readonly int[] BassPitchCycleRip = new int[3] { 0, 7, 12 }; private static readonly int[] KickFourFloorRip = new int[4] { 0, 4, 8, 12 }; private static readonly int[] KickSyncoRip = new int[6] { 0, 3, 6, 8, 11, 14 }; private static readonly int[] LeadATicksRip = new int[4] { 0, 4, 8, 12 }; private static readonly int[] LeadADegsRip = new int[4] { 1, 5, 8, 5 }; private static readonly int[] LeadBTicksRip = new int[4] { 0, 4, 8, 12 }; private static readonly int[] LeadBDegsRip = new int[4] { 8, 5, 3, 1 }; private static readonly float[] MetalPartials = new float[3] { 1200f, 1730f, 2650f }; public static EpicMusic Instance { get; private set; } public bool Playing { get { if ((Object)(object)_src != (Object)null) { return _src.isPlaying; } return false; } } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.EpicMusic"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void Awake() { _src = ((Component)this).gameObject.AddComponent(); _src.loop = true; _src.playOnAwake = false; _src.spatialBlend = 0f; _src.priority = 64; } public void Toggle() { if (Playing) { Stop(); } else { Play(); } } public void Play() { int lastTrack = (int)_lastTrack; int num; do { num = Random.Range(0, 4); } while (num == lastTrack); DoomTrack doomTrack = (_lastTrack = (DoomTrack)num); _src.clip = Build(doomTrack); _src.volume = Mathf.Clamp01(DoomConfig.MusicVolume.Value); _src.Play(); Plugin.Log.LogInfo((object)$"[Music] track -> {doomTrack}"); } public void Stop() { if ((Object)(object)_src != (Object)null) { _src.Stop(); } Plugin.LogMode("[Music] epic loop OFF"); } public static void AdjustVolume(float delta) { float num = Mathf.Clamp01(DoomConfig.MusicVolume.Value + delta); DoomConfig.MusicVolume.Value = num; try { ((ConfigEntryBase)DoomConfig.MusicVolume).ConfigFile.Save(); } catch { } if ((Object)(object)Instance != (Object)null && (Object)(object)Instance._src != (Object)null) { Instance._src.volume = num; } DoomHUD.Instance?.PingMusicVolume(num); Plugin.LogMode($"[Music] volume -> {num:0.00}"); } private void Update() { if ((Object)(object)_src != (Object)null && Playing) { _src.volume = Mathf.Clamp01(DoomConfig.MusicVolume.Value); } if (!Plugin.DoomModeActive && Playing) { Stop(); } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private static int N(string note, int octave) { return NoteBase[note] + (octave - 4) * 12; } private static float HzOf(int semitoneFromA4) { return 440f * Mathf.Pow(2f, (float)semitoneFromA4 / 12f); } private static int ScaleDegreeSemi(int rootSemi, int degree1Based) { int num = degree1Based - 1; int num2 = num / 7; int num3 = num % 7; if (num3 < 0) { num3 += 7; num2--; } return rootSemi + NaturalMinor[num3] + num2 * 12; } private static float BpmOf(DoomTrack t) { return t switch { DoomTrack.CrimsonMarch => 140f, DoomTrack.DoomBelow => 148f, DoomTrack.LastStand => 132f, DoomTrack.RipAndRun => 162f, _ => 140f, }; } private static AudioClip Build(DoomTrack track) { float num = BpmOf(track); int num2 = Mathf.Max(1, Mathf.RoundToInt(661500f / num)); int num3 = num2 * 16 * 16; float[] array = new float[num3]; Random rng = new Random((Environment.TickCount * 397) ^ (int)track); switch (track) { case DoomTrack.CrimsonMarch: GenerateCrimsonMarch(array, num2, rng); break; case DoomTrack.DoomBelow: GenerateDoomBelow(array, num2, rng); break; case DoomTrack.LastStand: GenerateLastStand(array, num2, rng); break; case DoomTrack.RipAndRun: GenerateRipAndRun(array, num2, rng); break; } SoftClip(array, 0.85f); AudioClip obj = AudioClip.Create($"DoomTrack_{track}", num3, 1, 44100, false); obj.SetData(array, 0); return obj; } private static void GenerateCrimsonMarch(float[] buf, int spTick, Random rng) { int[][] chordsCrimson = ChordsCrimson; int num = rng.Next(3); for (int i = 0; i < 16; i++) { int[] array = chordsCrimson[i % chordsCrimson.Length]; int num2 = array[0]; bool flag = i < 2; bool flag2 = i >= 6 && i < 12; bool flag3 = i >= 8 && i < 12; bool flag4 = i >= 12 && i < 14; bool flag5 = i == 15; AddPad(buf, array, T(i, 0), Dur(16), flag ? 0.05f : 0.065f); if (!flag) { AddKick(buf, T(i, 0), 0.3f); AddKick(buf, T(i, 8), 0.3f); if (flag2 || flag5) { AddKick(buf, T(i, 6), 0.22f); } if (flag2 && !flag5) { AddKick(buf, T(i, 14), 0.22f); } int num3 = ((flag2 || flag5) ? 1 : 2); for (int j = 0; j < 16; j += num3) { AddHat(buf, T(i, j), rng, 0.045f); } int[] array2 = ((flag2 || flag5) ? BassClimaxMarch : BassBuildMarch); for (int k = 0; k < array2.Length; k++) { if (array2[k] > -100) { AddBassNote(buf, HzOf(num2 - 12 + array2[k]), T(i, k * 2), Dur(2), 0.16f); } } } else { AddKick(buf, T(i, 0), 0.18f); } if (flag2) { for (int l = 0; l < 16; l++) { AddArpNote(buf, HzOf(array[l % array.Length] + 12), T(i, l), Dur(1), 0.07f); } } if (flag3 || flag4) { int num4 = (flag4 ? 12 : 0); for (int m = 0; m < MotifDegreesMarch.Length; m++) { int semitoneFromA = ScaleDegreeSemi(num2, MotifDegreesMarch[m]) + num4; AddLeadNote(buf, HzOf(semitoneFromA), T(i, MotifTicksMarch[m]), Dur(MotifLensMarch[m]), 0.075f); } } if (!flag5) { continue; } switch (num) { case 0: AddKick(buf, T(i, 10), 0.22f); break; case 1: AddKick(buf, T(i, 12), 0.2f); AddKick(buf, T(i, 14), 0.24f); break; default: { for (int n = 12; n < 16; n++) { AddHat(buf, T(i, n), rng, 0.05f, 80f); } break; } } AddLeadNote(buf, HzOf(num2 + 3), T(i, 12), Dur(2), 0.06f); AddLeadNote(buf, HzOf(num2 + 7), T(i, 14), Dur(2), 0.06f); } int Dur(int ticks) { return ticks * spTick; } int T(int bar, int tick) { return (bar * 16 + tick) * spTick; } } private static void GenerateDoomBelow(float[] buf, int spTick, Random rng) { int[][] chordsDoom = ChordsDoom; int num = rng.Next(2); for (int i = 0; i < 16; i++) { bool flag = i < 2; bool flag2 = i >= 6 && i < 8; bool flag3 = i >= 8 && i < 12; bool flag4 = i == 12; bool flag5 = i == 15; int[] array = (flag2 ? TensionChordDoom : chordsDoom[i % chordsDoom.Length]); int num2 = array[0]; AddPad(buf, array, T(i, 0), Dur(16), flag2 ? 0.05f : 0.04f); int num3 = num2 - 12; float gain = (flag3 ? 0.2f : 0.15f); for (int j = 0; j < BassMotifDoom.Length; j++) { if (BassMotifDoom[j] > -100) { AddBassNote(buf, HzOf(num3 + BassMotifDoom[j]), T(i, j * 2), Dur(2), gain, Wave.Saw); } } if (!flag) { int[] array2 = ((flag3 || flag5) ? KickAggroDoom : KickNormalDoom); if (!flag4) { int[] array3 = array2; foreach (int tick in array3) { AddKick(buf, T(i, tick), 0.28f, 150f, 45f, 24f); } array3 = ((flag3 || flag5) ? HatDenseDoom : HatSparseDoom); foreach (int tick2 in array3) { AddHat(buf, T(i, tick2), rng, 0.04f, 140f); } } else { AddKick(buf, T(i, 0), 0.24f); AddKick(buf, T(i, 8), 0.24f); } } if (flag && i == 0) { AddMetalHit(buf, T(i, 0), rng, 0.1f); AddMetalHit(buf, T(i, 8), rng, 0.08f); } if (!flag && !flag5 && i % 4 == 3) { AddMetalHit(buf, T(i, 14), rng, 0.09f); } if (flag5) { AddMetalHit(buf, T(i, 0), rng, 0.1f); AddMetalHit(buf, T(i, 6), rng, 0.1f); if (num == 0) { AddMetalHit(buf, T(i, 11), rng, 0.1f); } else { AddKick(buf, T(i, 11), 0.26f, 150f, 45f, 24f); } } if (flag2 || flag3) { int num4 = num2 + 24; AddLeadNote(buf, HzOf(num4), T(i, 6), Dur(1), 0.06f); AddLeadNote(buf, HzOf(num4 - 1), T(i, 7), Dur(1), 0.05f); if (flag3) { AddLeadNote(buf, HzOf(num4 + 2), T(i, 13), Dur(1), 0.06f); AddLeadNote(buf, HzOf(num4 + 1), T(i, 14), Dur(1), 0.05f); } } } int Dur(int ticks) { return ticks * spTick; } int T(int bar, int num5) { return (bar * 16 + num5) * spTick; } } private static void GenerateLastStand(float[] buf, int spTick, Random rng) { int[][] chordsLastStand = ChordsLastStand; int rootSemi = N("E", 4); int num = rng.Next(2); for (int i = 0; i < 16; i++) { int[] array = chordsLastStand[i % chordsLastStand.Length]; int num2 = array[0]; bool num3 = i < 2; bool flag = i >= 4; bool flag2 = i >= 6 && i < 8; bool flag3 = i >= 8 && i < 12; bool flag4 = i >= 12 && i < 14; bool flag5 = i == 14; bool flag6 = i == 15; AddPad(buf, array, T(i, 0), Dur(16), 0.05f); if (!num3) { AddKick(buf, T(i, 0), 0.28f, 150f, 45f, 20f); AddKick(buf, T(i, 8), 0.28f, 150f, 45f, 20f); if (flag3 || flag6) { AddKick(buf, T(i, 12), 0.18f, 150f, 45f, 20f); } } if (i >= 2) { AddSnare(buf, T(i, 4), rng, 0.16f); AddSnare(buf, T(i, 12), rng, 0.16f); int num4 = ((flag3 || flag4) ? 2 : 4); for (int j = 0; j < 16; j += num4) { AddHat(buf, T(i, j), rng, 0.035f, 100f); } } if (flag) { AddBassNote(buf, HzOf(num2 - 12), T(i, 0), Dur(12), 0.15f); int num5 = chordsLastStand[(i + 1) % chordsLastStand.Length][0]; AddBassNote(buf, HzOf(num5 - 12), T(i, 14), Dur(2), 0.14f); } if (flag2) { int num6 = (i - 6) * 2; for (int k = 0; k < 2; k++) { int semitoneFromA = ScaleDegreeSemi(rootSemi, ThemeStepDegreesLastStand[num6 + k]); AddLeadNote(buf, HzOf(semitoneFromA), T(i, k * 8), Dur(6), 0.05f, Wave.Sine); } } else if (flag3) { int num7 = (i - 8) * 2; for (int l = 0; l < 2; l++) { int semitoneFromA2 = ScaleDegreeSemi(rootSemi, ThemeStepDegreesLastStand[num7 + l]); AddLeadNote(buf, HzOf(semitoneFromA2), T(i, l * 8), Dur(7), 0.075f); } } else if (flag4) { int num8 = (i - 12) * 2; for (int m = 0; m < 2; m++) { int semitoneFromA3 = ScaleDegreeSemi(rootSemi, ThemeStepDegreesLastStand[num8 + m]) + 12; AddLeadNote(buf, HzOf(semitoneFromA3), T(i, m * 8), Dur(7), 0.07f); } } else if (flag5 && num == 0) { AddLeadNote(buf, HzOf(ScaleDegreeSemi(rootSemi, 2)), T(i, 0), Dur(16), 0.05f); } else if (flag6) { AddLeadNote(buf, HzOf(ScaleDegreeSemi(rootSemi, 1)), T(i, 10), Dur(2), 0.06f); AddLeadNote(buf, HzOf(ScaleDegreeSemi(rootSemi, 2)), T(i, 12), Dur(2), 0.06f); AddLeadNote(buf, HzOf(ScaleDegreeSemi(rootSemi, 3)), T(i, 14), Dur(2), 0.07f); } } int Dur(int ticks) { return ticks * spTick; } int T(int bar, int tick) { return (bar * 16 + tick) * spTick; } } private static void GenerateRipAndRun(float[] buf, int spTick, Random rng) { int[][] chordsRipRun = ChordsRipRun; int rootSemi = N("C", 5); int num = rng.Next(2); for (int i = 0; i < 16; i++) { int[] array = chordsRipRun[i % chordsRipRun.Length]; int num2 = array[0]; bool flag = i == 0; bool flag2 = i == 4 || i == 5 || i == 8 || i == 10 || i == 13; bool flag3 = i == 6 || i == 7 || i == 9 || i == 11 || i == 14; bool flag4 = i == 12; bool flag5 = i == 15; bool flag6 = i >= 8 && i < 12; if (i >= 4) { AddPad(buf, array, T(i, 0), Dur(16), 0.03f); } int[] array2 = ((flag4 || flag5) ? KickSyncoRip : KickFourFloorRip); foreach (int tick in array2) { AddKick(buf, T(i, tick), 0.26f, 150f, 55f, 30f); } for (int k = 0; k < 16; k++) { bool flag7 = k % 4 == ((num != 0) ? 1 : 2); AddHat(buf, T(i, k), rng, flag7 ? 0.05f : 0.035f, flag7 ? 55f : 150f); } if (!flag4) { for (int l = 0; l < BassGateRip.Length; l++) { int tick2 = BassGateRip[l]; float hz = HzOf(num2 - 12 + BassPitchCycleRip[l % BassPitchCycleRip.Length]); AddBassNote(buf, hz, T(i, tick2), Dur(1), 0.15f, Wave.Saw); } } if (flag) { AddLeadNote(buf, HzOf(ScaleDegreeSemi(rootSemi, 1)), T(i, 0), Dur(2), 0.08f, Wave.Square); } if (flag2) { for (int m = 0; m < LeadATicksRip.Length; m++) { AddLeadNote(buf, HzOf(ScaleDegreeSemi(rootSemi, LeadADegsRip[m])), T(i, LeadATicksRip[m]), Dur(3), flag6 ? 0.08f : 0.065f, Wave.Square); } } if (flag3) { for (int n = 0; n < LeadBTicksRip.Length; n++) { AddLeadNote(buf, HzOf(ScaleDegreeSemi(rootSemi, LeadBDegsRip[n])), T(i, LeadBTicksRip[n]), Dur(3), flag6 ? 0.08f : 0.065f, Wave.Saw, 8f); } } if (flag5) { int[] array3 = new int[8] { 1, 2, 3, 4, 5, 6, 7, 8 }; for (int num3 = 0; num3 < array3.Length; num3++) { AddLeadNote(buf, HzOf(ScaleDegreeSemi(rootSemi, array3[num3])), T(i, num3 * 2), Dur(2), 0.07f, Wave.Square); } } } int Dur(int ticks) { return ticks * spTick; } int T(int bar, int num4) { return (bar * 16 + num4) * spTick; } } private static void AddPad(float[] buf, int[] chord, int startSample, int lenSamples, float gain) { int atkSamples = Mathf.RoundToInt(2646f); int relSamples = Mathf.RoundToInt(7938.0005f); foreach (int semitoneFromA in chord) { AddTone(buf, HzOf(semitoneFromA), startSample, lenSamples, Wave.Square, atkSamples, relSamples, gain, -6f); AddTone(buf, HzOf(semitoneFromA), startSample, lenSamples, Wave.Square, atkSamples, relSamples, gain, 6f); } } private static void AddBassNote(float[] buf, float hz, int startSample, int lenSamples, float gain, Wave wave = Wave.Square) { AddTone(buf, hz, startSample, lenSamples, wave, Mathf.RoundToInt(88.200005f), Mathf.RoundToInt(1323f), gain); } private static void AddLeadNote(float[] buf, float hz, int startSample, int lenSamples, float gain, Wave wave = Wave.Saw, float detune = 0f) { AddTone(buf, hz, startSample, lenSamples, wave, Mathf.RoundToInt(176.40001f), Mathf.RoundToInt(2205f), gain, detune); } private static void AddArpNote(float[] buf, float hz, int startSample, int lenSamples, float gain) { AddTone(buf, hz, startSample, lenSamples, Wave.Square, Mathf.RoundToInt(44.100002f), Mathf.RoundToInt(882f), gain); } private static void AddTone(float[] buf, float hz, int startSample, int lenSamples, Wave wave, int atkSamples, int relSamples, float gain, float detuneCents = 0f) { float num = hz * Mathf.Pow(2f, detuneCents / 1200f); int num2 = Mathf.Max(0, startSample); int num3 = Mathf.Min(buf.Length, num2 + Mathf.Max(1, lenSamples)); int num4 = Mathf.Max(1, atkSamples); int num5 = Mathf.Max(1, relSamples); double num6 = 0.0; double num7 = num / 44100f; for (int i = num2; i < num3; i++) { num6 += num7; if (num6 >= 1.0) { num6 -= 1.0; } float num8 = wave switch { Wave.Saw => (float)(2.0 * num6 - 1.0), Wave.Square => (num6 < 0.5) ? 1f : (-1f), _ => (float)Math.Sin(num6 * 2.0 * Math.PI), }; int num9 = i - num2; int num10 = num3 - i; float num11 = 1f; if (num9 < num4) { num11 = (float)num9 / (float)num4; } else if (num10 < num5) { num11 = (float)num10 / (float)num5; } buf[i] += num8 * num11 * gain; } } private static void AddKick(float[] buf, int startSample, float gain, float startHz = 150f, float endHz = 45f, float decay = 28f, int lenSamples = 0) { int num = Mathf.Max(0, startSample); int num2 = ((lenSamples > 0) ? lenSamples : Mathf.FloorToInt(6174f)); int num3 = Mathf.Min(buf.Length, num + num2); double num4 = 0.0; for (int i = num; i < num3; i++) { float num5 = (float)(i - num) / 44100f; float num6 = Mathf.Lerp(startHz, endHz, Mathf.Clamp01(num5 / 0.09f)); num4 += (double)(num6 / 44100f); float num7 = Mathf.Exp((0f - num5) * decay); buf[i] += (float)Math.Sin(num4 * 2.0 * Math.PI) * num7 * gain; } } private static void AddHat(float[] buf, int startSample, Random rng, float gain, float decay = 120f, int lenSamples = 0) { int num = Mathf.Max(0, startSample); int num2 = ((lenSamples > 0) ? lenSamples : Mathf.FloorToInt(1543.5f)); int num3 = Mathf.Min(buf.Length, num + num2); for (int i = num; i < num3; i++) { float num4 = Mathf.Exp((0f - (float)(i - num) / 44100f) * decay); buf[i] += ((float)rng.NextDouble() * 2f - 1f) * num4 * gain; } } private static void AddSnare(float[] buf, int startSample, Random rng, float gain) { int num = Mathf.Max(0, startSample); int num2 = Mathf.FloorToInt(5292f); int num3 = Mathf.Min(buf.Length, num + num2); double num4 = 0.0; double num5 = 2.0 / 441.0; for (int i = num; i < num3; i++) { float num6 = Mathf.Exp((0f - (float)(i - num) / 44100f) * 22f); num4 += num5; if (num4 >= 1.0) { num4 -= 1.0; } float num7 = (float)Math.Sin(num4 * 2.0 * Math.PI); float num8 = (float)rng.NextDouble() * 2f - 1f; buf[i] += (num7 * 0.5f + num8 * 0.5f) * num6 * gain; } } private static void AddMetalHit(float[] buf, int startSample, Random rng, float gain) { int num = Mathf.Max(0, startSample); int num2 = Mathf.FloorToInt(3969.0002f); int num3 = Mathf.Min(buf.Length, num + num2); for (int i = num; i < num3; i++) { float num4 = (float)(i - num) / 44100f; float num5 = Mathf.Exp((0f - num4) * 55f); float num6 = 0f; for (int j = 0; j < MetalPartials.Length; j++) { num6 += (float)Math.Sin(Math.PI * 2.0 * (double)MetalPartials[j] * (double)num4); } num6 /= (float)MetalPartials.Length; float num7 = ((float)rng.NextDouble() * 2f - 1f) * 0.3f; buf[i] += (num6 * 0.7f + num7) * num5 * gain; } } private static void SoftClip(float[] buf, float ceiling) { float num = 0.0001f; for (int i = 0; i < buf.Length; i++) { float num2 = Mathf.Abs(buf[i]); if (num2 > num) { num = num2; } } float num3 = ((num > ceiling) ? (ceiling / num) : 1f); if (!(num3 >= 1f)) { for (int j = 0; j < buf.Length; j++) { buf[j] *= num3; } } } } public static class WavLoader { public static AudioClip Load(string path) { try { if (!File.Exists(path)) { return null; } byte[] array = File.ReadAllBytes(path); if (array.Length < 44) { return null; } if (array[0] != 82 || array[1] != 73 || array[2] != 70 || array[3] != 70) { return null; } if (array[8] != 87 || array[9] != 65 || array[10] != 86 || array[11] != 69) { return null; } int num = 1; int num2 = 44100; int num3 = 16; ushort num4 = 1; int num5 = -1; int num6 = 0; int num7 = 12; while (num7 + 8 <= array.Length) { string text = new string(new char[4] { (char)array[num7], (char)array[num7 + 1], (char)array[num7 + 2], (char)array[num7 + 3] }); int num8 = BitConverter.ToInt32(array, num7 + 4); int num9 = num7 + 8; if (text == "fmt ") { num4 = BitConverter.ToUInt16(array, num9); num = BitConverter.ToUInt16(array, num9 + 2); num2 = BitConverter.ToInt32(array, num9 + 4); num3 = BitConverter.ToUInt16(array, num9 + 14); } else if (text == "data") { num5 = num9; num6 = Mathf.Min(num8, array.Length - num9); } num7 = num9 + num8 + (num8 & 1); } if (num5 < 0 || num < 1) { return null; } int num10 = Mathf.Max(1, num3 / 8); int num11 = num6 / num10; float[] array2 = new float[num11]; for (int i = 0; i < num11; i++) { int num12 = num5 + i * num10; float num13 = ((num4 == 3 && num3 == 32) ? BitConverter.ToSingle(array, num12) : (num3 switch { 16 => (float)BitConverter.ToInt16(array, num12) / 32768f, 32 => (float)BitConverter.ToInt32(array, num12) / 2.1474836E+09f, 24 => (float)(array[num12] | (array[num12 + 1] << 8) | ((sbyte)array[num12 + 2] << 16)) / 8388608f, _ => (float)(array[num12] - 128) / 128f, })); array2[i] = num13; } AudioClip obj = AudioClip.Create(Path.GetFileNameWithoutExtension(path), num11 / num, num, num2, false); obj.SetData(array2, 0); return obj; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[WeaponAudio] WAV load failed for " + Path.GetFileName(path) + ": " + ex.Message)); return null; } } } public static class WeaponAudio { private static AudioSource _src; private static readonly Dictionary _clips = new Dictionary(); private static readonly Dictionary _map = new Dictionary(); private static string _mapSrc; private static string _dir; private static string SoundsDir { get { if (_dir != null) { return _dir; } try { _dir = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? ".", "sounds"); } catch { _dir = "sounds"; } return _dir; } } private static AudioSource Src() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if ((Object)(object)_src != (Object)null) { return _src; } GameObject val = new GameObject("ContentWarningDoom.WeaponAudio"); Object.DontDestroyOnLoad((Object)val); _src = val.AddComponent(); _src.spatialBlend = 0f; _src.playOnAwake = false; return _src; } private static string FileFor(WeaponId id) { string text = DoomConfig.WeaponSoundFiles.Value ?? ""; if (text != _mapSrc) { _mapSrc = text; _map.Clear(); string[] array = text.Split(';'); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split('='); if (array2.Length == 2 && Enum.TryParse(array2[0].Trim(), ignoreCase: true, out var result)) { _map[result] = array2[1].Trim(); } } } if (!_map.TryGetValue(id, out var value)) { return null; } return value; } private static AudioClip Wav(string name) { if (string.IsNullOrEmpty(name)) { return null; } string key = "wav:" + name; if (_clips.TryGetValue(key, out var value)) { return value; } value = WavLoader.Load(Path.Combine(SoundsDir, name + ".wav")); _clips[key] = value; Plugin.LogWeapon(((Object)(object)value != (Object)null) ? ("[WeaponAudio] loaded sounds/" + name + ".wav") : ("[WeaponAudio] sounds/" + name + ".wav not found — using procedural")); return value; } private static AudioClip Burst(string key, float seconds, float baseFreq, float decay, float noiseMix) { if (_clips.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } int num = 44100; int num2 = Mathf.Max(1, (int)((float)num * seconds)); float[] array = new float[num2]; float num3 = 0f; for (int i = 0; i < num2; i++) { float num4 = (float)i / (float)num; float num5 = Mathf.Exp((0f - decay) * num4); num3 += MathF.PI * 2f * baseFreq / (float)num; float num6 = Mathf.Sin(num3); float num7 = Random.value * 2f - 1f; array[i] = Mathf.Clamp(Mathf.Lerp(num6, num7, noiseMix) * num5, -1f, 1f); } value = AudioClip.Create(key, num2, 1, num, false); value.SetData(array, 0); _clips[key] = value; return value; } private static AudioClip ProceduralFor(WeaponId id) { switch (id) { case WeaponId.Shotgun: case WeaponId.SuperShotgun: case WeaponId.AutoShotgun: return Burst("p_shotgun", 0.34f, 85f, 15f, 0.9f); case WeaponId.BFG: return Burst("p_bfg", 0.7f, 55f, 6f, 0.5f); case WeaponId.GrenadeLauncher: return Burst("p_gl", 0.3f, 70f, 18f, 0.8f); default: return Burst("p_shot", 0.16f, 220f, 40f, 0.7f); } } public static void PlayFire(WeaponId id, Vector3 pos) { AudioClip val = Wav(FileFor(id)) ?? ProceduralFor(id); if (!((Object)(object)val == (Object)null)) { float num = Mathf.Clamp01(DoomConfig.WeaponSoundVolume.Value); if (id == WeaponId.Minigun || id == WeaponId.Smg) { num *= 0.72f; } AudioSource obj = Src(); obj.pitch = Random.Range(0.94f, 1.06f); obj.PlayOneShot(val, num); } } public static void PlayReload(WeaponId id) { AudioSource obj = Src(); obj.pitch = 1f; obj.PlayOneShot(Burst("reload", 0.12f, 140f, 30f, 0.8f), 0.4f * Mathf.Clamp01(DoomConfig.WeaponSoundVolume.Value)); } } } namespace ContentWarningDoom.ActionMode { public class ActionCamera : MonoBehaviour { private float _localTimeLeft; private float _syncTimer; private bool _lastSent; private CameraViewmodel _viewmodel; private CameraViewfinder _viewfinder; private readonly Plane[] _frustum = (Plane[])(object)new Plane[6]; private int _frustumFrame = -1; public static ActionCamera Instance { get; private set; } public float MaxTime { get; private set; } public bool IsRecording { get; private set; } public float TimeRemaining { get { ActionVideoRecorder instance = ActionVideoRecorder.Instance; if ((Object)(object)instance != (Object)null && instance.NativeReady && instance.TimeLeft >= 0f) { return instance.TimeLeft; } return _localTimeLeft; } } public bool OutOfFilm => TimeRemaining <= 0.05f; private Transform RecViewpoint { get { Camera recordingCamera = GetRecordingCamera(); if (!((Object)(object)recordingCamera != (Object)null)) { if (!((Object)(object)MainCamera.instance != (Object)null)) { return null; } return ((Component)MainCamera.instance).transform; } return ((Component)recordingCamera).transform; } } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.ActionCamera"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } public void BeginRound(float maxTime) { MaxTime = maxTime; _localTimeLeft = maxTime; IsRecording = false; _lastSent = false; ActionVideoRecorder.Instance?.BeginRound(maxTime); ActionNet.SendRecState(recording: false, TimeRemaining); } public Camera GetRecordingCamera() { ActionVideoRecorder instance = ActionVideoRecorder.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.RecordingCamera != (Object)null) { return instance.RecordingCamera; } if (!((Object)(object)MainCamera.instance != (Object)null)) { return null; } return MainCamera.instance.Cam; } private void Update() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Invalid comparison between Unknown and I4 UpdateViewmodel(); bool num = ActionRoundManager.Phase == ActionRoundPhase.Action && !OutOfFilm && (Object)(object)Player.localPlayer != (Object)null && Player.localPlayer.data != null && !Player.localPlayer.data.dead && (Object)(object)MainCamera.instance != (Object)null; Mouse current = Mouse.current; bool flag = num && current != null && current.rightButton.isPressed && (int)Cursor.lockState == 1; if (flag && !IsRecording) { IsRecording = true; ActionVideoRecorder.Instance?.StartNative(); } else if (!flag && IsRecording) { IsRecording = false; ActionVideoRecorder.Instance?.StopNative(); } ActionVideoRecorder instance = ActionVideoRecorder.Instance; bool flag2 = (Object)(object)instance != (Object)null && instance.NativeReady; if (IsRecording && !flag2) { _localTimeLeft -= Time.unscaledDeltaTime; if (_localTimeLeft < 0f) { _localTimeLeft = 0f; } } if (IsRecording && OutOfFilm) { IsRecording = false; ActionVideoRecorder.Instance?.StopNative(); Plugin.LogMode("[ActionVideo] film exhausted — recording forced STOP"); } _syncTimer += Time.deltaTime; if (IsRecording != _lastSent || _syncTimer > 0.5f) { _lastSent = IsRecording; _syncTimer = 0f; ActionNet.SendRecState(IsRecording, TimeRemaining); } } private void UpdateViewmodel() { bool flag = (Object)(object)Player.localPlayer != (Object)null && Player.localPlayer.data != null && !Player.localPlayer.data.dead; bool num = Plugin.DoomModeActive && DoomConfig.ActionModeEnabled.Value && (Object)(object)MainCamera.instance != (Object)null && flag; bool flag2 = num && DoomConfig.ShowCameraViewmodel.Value; Transform val = ((flag2 && DoomConfig.AttachToRealHands.Value) ? PlayerHands.Left() : null); if (flag2 && ((Object)(object)_viewmodel == (Object)null || ((Object)(object)val != (Object)null && (Object)(object)_viewmodel.ParentedTo != (Object)(object)val))) { if ((Object)(object)_viewmodel != (Object)null) { Object.Destroy((Object)(object)((Component)_viewmodel).gameObject); } _viewmodel = CameraViewmodel.Build(((Object)(object)val != (Object)null) ? val : ((Component)MainCamera.instance).transform, (Object)(object)val != (Object)null); } else if (!flag2 && (Object)(object)_viewmodel != (Object)null) { Object.Destroy((Object)(object)((Component)_viewmodel).gameObject); _viewmodel = null; } bool flag3 = num && DoomConfig.ShowViewfinder.Value; if (flag3 && (Object)(object)_viewfinder == (Object)null) { _viewfinder = CameraViewfinder.Build(); } else if (!flag3 && (Object)(object)_viewfinder != (Object)null) { Object.Destroy((Object)(object)((Component)_viewfinder).gameObject); _viewfinder = null; } } private void RefreshFrustum() { if (_frustumFrame != Time.frameCount) { _frustumFrame = Time.frameCount; Camera recordingCamera = GetRecordingCamera(); if ((Object)(object)recordingCamera != (Object)null) { GeometryUtility.CalculateFrustumPlanes(recordingCamera, _frustum); } } } public bool IsFilming(Vector3 worldPos, float radius = 0.6f) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if (!IsRecording) { return false; } Transform recViewpoint = RecViewpoint; if ((Object)(object)recViewpoint == (Object)null) { return false; } Vector3 position = recViewpoint.position; Vector3 val = worldPos - position; if (((Vector3)(ref val)).sqrMagnitude > DoomConfig.MaxFilmDistance.Value * DoomConfig.MaxFilmDistance.Value) { return false; } RefreshFrustum(); if (!GeometryUtility.TestPlanesAABB(_frustum, new Bounds(worldPos, Vector3.one * (radius * 2f)))) { return false; } RaycastHit val2 = HelperFunctions.LineCheck(position, worldPos, (LayerType)1); if ((Object)(object)((RaycastHit)(ref val2)).transform != (Object)null) { val = ((RaycastHit)(ref val2)).point - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; val = worldPos - position; if (sqrMagnitude < ((Vector3)(ref val)).sqrMagnitude - 1f) { return false; } } return true; } } public class ActionCameraSpawner : MonoBehaviour { private sealed class HiddenLooseCam : MonoBehaviour { } private GameObject _holder; private GameObject _camObj; private VideoCamera _vc; private ItemInstanceData _data; private VideoInfoEntry _entry; private bool _shared; private float _hideLooseCamTimer; public static ActionCameraSpawner Instance { get; private set; } public bool Ready { get { if ((Object)(object)_vc != (Object)null && _data != null && _entry != null) { return (Object)(object)_vc.m_camera != (Object)null; } return false; } } public bool IsHiddenOwn { get { if (Ready) { return !_shared; } return false; } } public VideoCamera Cam => _vc; public Camera UnityCamera { get { if (!((Object)(object)_vc != (Object)null)) { return null; } return _vc.m_camera; } } public ItemInstanceData Data => _data; public VideoInfoEntry Entry => _entry; public Guid Guid { get { if (_data == null) { return Guid.Empty; } return _data.m_guid; } } public string GuidShort { get { if (_data == null || !(_data.m_guid != Guid.Empty)) { return ""; } return _data.m_guid.ToString().Substring(0, 8); } } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.ActionCameraSpawner"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } public bool CreateOrBind(float filmTime) { if (!DoomConfig.RealVideoRecording.Value) { return false; } if (Ready) { ResetEntry(filmTime); Plugin.Log.LogInfo((object)string.Format("[ActionVideo] actor={0} action camera reused guid={1} ({2})", DoomNet.LocalActor, GuidShort, _shared ? "shared" : "hidden-own")); return true; } if (DoomConfig.SpawnHiddenActionCamera.Value) { try { if (SpawnHidden(filmTime)) { return true; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ActionVideo] hidden camera spawn FAILED: " + ex.Message + " — falling back to shared camera")); } } return BindShared(filmTime); } public static Item FindCameraItemPublic() { return FindCameraItem(); } private static Item FindCameraItem() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) VideoCamera val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null && (Object)(object)((ItemInstanceBehaviour)val).itemInstance != (Object)null && (Object)(object)((ItemInstanceBehaviour)val).itemInstance.item != (Object)null && (Object)(object)((ItemInstanceBehaviour)val).itemInstance.item.itemObject != (Object)null) { return ((ItemInstanceBehaviour)val).itemInstance.item; } Item val2 = default(Item); for (int i = 0; i < 256; i++) { try { if (ItemDatabase.TryGetItemFromID((byte)i, ref val2) && (Object)(object)val2 != (Object)null && (int)val2.itemType == 0 && (Object)(object)val2.itemObject != (Object)null) { return val2; } } catch { } } return null; } private bool SpawnHidden(float filmTime) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown Item val = FindCameraItem(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[ActionVideo] no camera Item found in ItemDatabase"); return false; } if ((Object)(object)_holder == (Object)null) { _holder = new GameObject("ContentWarningDoom.ActionCameraHolder"); Object.DontDestroyOnLoad((Object)(object)_holder); } _camObj = Object.Instantiate(val.itemObject, _holder.transform); ((Object)_camObj).name = "DoomActionCamera"; _camObj.transform.position = new Vector3(0f, -5000f, 0f); _vc = _camObj.GetComponentInChildren(true); if ((Object)(object)_vc == (Object)null || (Object)(object)_vc.m_camera == (Object)null) { Object.Destroy((Object)(object)_camObj); _camObj = null; _vc = null; return false; } _data = new ItemInstanceData(Guid.NewGuid()); _entry = new VideoInfoEntry { videoID = VideoHandle.Invalid, timeLeft = filmTime, maxTime = filmTime }; _data.AddDataEntry((ItemDataEntry)(object)_entry); try { ItemInstanceDataHandler.AddInstanceData(_data); } catch { } PersistantObject[] componentsInChildren = _camObj.GetComponentsInChildren(true); foreach (PersistantObject val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { try { Object.Destroy((Object)(object)val2); } catch { } } } Pickup[] componentsInChildren2 = _camObj.GetComponentsInChildren(true); foreach (Pickup val3 in componentsInChildren2) { if ((Object)(object)val3 != (Object)null) { try { Object.Destroy((Object)(object)val3); } catch { } } } MonoBehaviour[] componentsInChildren3 = _camObj.GetComponentsInChildren(true); foreach (MonoBehaviour val4 in componentsInChildren3) { if ((Object)(object)val4 == (Object)null || val4 is VideoCamera) { continue; } string text = ((object)val4).GetType().Namespace; if (text == null || !text.StartsWith("ContentWarningDoom")) { try { ((Behaviour)val4).enabled = false; } catch { } } } Collider[] componentsInChildren4 = _camObj.GetComponentsInChildren(true); foreach (Collider val5 in componentsInChildren4) { if ((Object)(object)val5 != (Object)null) { val5.enabled = false; } } Rigidbody[] componentsInChildren5 = _camObj.GetComponentsInChildren(true); foreach (Rigidbody val6 in componentsInChildren5) { if ((Object)(object)val6 != (Object)null) { val6.isKinematic = true; val6.detectCollisions = false; } } Renderer[] componentsInChildren6 = _camObj.GetComponentsInChildren(true); foreach (Renderer val7 in componentsInChildren6) { if ((Object)(object)val7 != (Object)null) { val7.enabled = false; } } Light[] componentsInChildren7 = _camObj.GetComponentsInChildren(true); foreach (Light val8 in componentsInChildren7) { if ((Object)(object)val8 != (Object)null) { ((Behaviour)val8).enabled = false; } } if ((Object)(object)_vc.findMeLight != (Object)null) { ((Behaviour)_vc.findMeLight).enabled = false; } ((ItemInstanceBehaviour)_vc).isHeld = true; ((ItemInstanceBehaviour)_vc).isHeldByMe = false; ((ItemInstanceBehaviour)_vc).isSimulatedByMe = true; PhotonView val9 = (((Object)(object)Player.localPlayer != (Object)null && Player.localPlayer.refs != null) ? Player.localPlayer.refs.view : null); try { CameraHandler.UnregisterCamera(_data.m_guid); } catch { } try { ((ItemInstanceBehaviour)_vc).ConfigItem(_data, val9); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ActionVideo] ConfigItem warn: " + ex.Message)); } VideoInfoEntry val10 = default(VideoInfoEntry); if (_data.TryGetEntry(ref val10) && val10 != null) { _entry = val10; } ResetEntry(filmTime); _shared = false; _camObj.SetActive(true); Plugin.Log.LogInfo((object)$"[ActionVideo] actor={DoomNet.LocalActor} action camera created guid={GuidShort} videoIDreset item='{((Object)val).name}'"); return Ready; } private bool BindShared(float filmTime) { Player localPlayer = Player.localPlayer; _vc = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).GetComponentInChildren(true) : null) ?? Object.FindObjectOfType(); if ((Object)(object)_vc == (Object)null || (Object)(object)((ItemInstanceBehaviour)_vc).itemInstance == (Object)null || ((ItemInstanceBehaviour)_vc).itemInstance.m_guid.IsNone) { _vc = null; return false; } try { ItemInstanceData data = default(ItemInstanceData); if (!ItemInstanceDataHandler.TryGetInstanceData(((ItemInstanceBehaviour)_vc).itemInstance.m_guid.Value, ref data)) { return false; } _data = data; if (!_data.TryGetEntry(ref _entry)) { return false; } } catch { return false; } _shared = true; ResetEntry(filmTime); Plugin.Log.LogWarning((object)$"[ActionVideo] actor={DoomNet.LocalActor} using SHARED vanilla camera guid={GuidShort} — only works if this player holds it (independent per-player recording unavailable this run)"); return Ready; } private void ResetEntry(float filmTime) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (_entry == null) { return; } try { _entry.maxTime = filmTime; _entry.timeLeft = filmTime; _entry.isRecording = false; _entry.videoID = VideoHandle.Invalid; } catch { } } private void Update() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.DoomModeActive || !DoomConfig.ActionModeEnabled.Value) { return; } _hideLooseCamTimer -= Time.deltaTime; if (_hideLooseCamTimer > 0f) { return; } _hideLooseCamTimer = 3f; VideoCamera[] array = Object.FindObjectsOfType(); foreach (VideoCamera val in array) { if ((Object)(object)val == (Object)null || ((Component)val).transform.position.y < -1000f) { continue; } bool flag; try { flag = ((ItemInstanceBehaviour)val).isHeld || ((ItemInstanceBehaviour)val).isHeldByMe; } catch { flag = true; } if (flag) { continue; } GameObject gameObject = ((Component)((Component)val).transform.root).gameObject; bool flag2 = (Object)(object)gameObject.GetComponent() == (Object)null; if (flag2) { gameObject.AddComponent(); } Renderer[] componentsInChildren = gameObject.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren.Length; j++) { componentsInChildren[j].enabled = false; } Collider[] componentsInChildren2 = gameObject.GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren2) { if (!val2.isTrigger) { val2.enabled = false; } } if (flag2) { Plugin.LogMode("[ActionCamera] hid loose vanilla camera '" + ((Object)gameObject).name + "'"); } } } private void LateUpdate() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_vc == (Object)null) && !((Object)(object)_vc.m_camera == (Object)null) && !((Object)(object)MainCamera.instance == (Object)null) && DoomConfig.ActionModeEnabled.Value) { Transform transform = ((Component)MainCamera.instance).transform; ((Component)_vc.m_camera).transform.SetPositionAndRotation(transform.position + transform.forward * 0.12f, transform.rotation); Camera cam = MainCamera.instance.Cam; if ((Object)(object)cam != (Object)null) { _vc.m_camera.cullingMask = cam.cullingMask; _vc.m_camera.nearClipPlane = cam.nearClipPlane; _vc.m_camera.farClipPlane = cam.farClipPlane; _vc.m_camera.fieldOfView = cam.fieldOfView; } if (!((Component)_vc.m_camera).gameObject.activeSelf) { ((Component)_vc.m_camera).gameObject.SetActive(true); } } } public void Cleanup() { try { if ((Object)(object)_vc != (Object)null && _data != null) { CameraHandler.UnregisterCamera(_data.m_guid); } } catch { } if ((Object)(object)_camObj != (Object)null) { Object.Destroy((Object)(object)_camObj); } _camObj = null; _vc = null; _data = null; _entry = null; _shared = false; } } public static class ActionContentScore { public static int BaseWeight(ActionContentEventType t, int tier) { return t switch { ActionContentEventType.MonsterVisible => DoomConfig.W_MonsterVisible.Value, ActionContentEventType.MonsterKill => DoomConfig.W_MonsterKill.Value, ActionContentEventType.Headshot => DoomConfig.W_Headshot.Value, ActionContentEventType.HeadshotKill => DoomConfig.W_HeadshotKill.Value, ActionContentEventType.AirborneKill => DoomConfig.W_AirborneKill.Value, ActionContentEventType.DashKill => DoomConfig.W_DashKill.Value, ActionContentEventType.GloryKill => DoomConfig.W_GloryKill.Value, ActionContentEventType.MultiKill => DoomConfig.W_MultiKill.Value * Mathf.Max(1, tier - 1), ActionContentEventType.BFGMultiKill => DoomConfig.W_BFGMultiKill.Value, ActionContentEventType.CloseRangeKill => DoomConfig.W_CloseRangeKill.Value, ActionContentEventType.DangerousMoment => DoomConfig.W_DangerMoment.Value, ActionContentEventType.SpeechMoment => DoomConfig.W_SpeechMoment.Value, ActionContentEventType.PlayerCombat => DoomConfig.W_PlayerCombat.Value, ActionContentEventType.PlayerKill => DoomConfig.W_PlayerKill.Value, _ => 25, }; } private static bool IsMonsterEvent(ActionContentEventType t) { if (t <= ActionContentEventType.CloseRangeKill) { return true; } return false; } public static int Award(PlayerActionSession s, ActionContentEventType t, bool rare, int tier, int dangerTier = 1) { int num = BaseWeight(t, tier); if (num <= 0) { return 0; } s.EventCounts.TryGetValue(t, out var value); float num2 = 1f + DoomConfig.VarietyBonusPerType.Value * (float)s.DistinctEventTypes; float num3 = 1f / (1f + DoomConfig.RepeatDiminishFactor.Value * (float)value); float num4 = (rare ? Mathf.Max(1f, DoomConfig.RareMonsterMultiplier.Value) : 1f); float num5 = ((dangerTier >= 2 && IsMonsterEvent(t)) ? (1f + Mathf.Max(0f, DoomConfig.DangerMonsterMultiplierPerLevel.Value) * (float)(dangerTier - 1)) : 1f); int num6 = Mathf.Max(1, Mathf.RoundToInt((float)num * num2 * num3 * num4 * num5)); s.EventCounts[t] = value + 1; s.ContentScore += num6; switch (t) { case ActionContentEventType.MonsterKill: case ActionContentEventType.HeadshotKill: case ActionContentEventType.AirborneKill: case ActionContentEventType.DashKill: case ActionContentEventType.CloseRangeKill: case ActionContentEventType.PlayerKill: s.Kills++; break; case ActionContentEventType.Headshot: s.Headshots++; break; case ActionContentEventType.GloryKill: s.GloryKills++; break; case ActionContentEventType.MultiKill: case ActionContentEventType.BFGMultiKill: s.MultiKills++; break; } return num6; } public static int ToViews(int contentScore) { float num = (float)contentScore * Mathf.Max(0f, DoomConfig.ViewsMultiplier.Value); float num2 = Mathf.Clamp01(DoomConfig.ViewsRandomVariance.Value); num *= 1f + Random.Range(0f - num2, num2); return Mathf.Max(0, Mathf.RoundToInt(num)); } } public class ActionContentTracker : MonoBehaviour { private float _visiblePollTimer; private readonly Dictionary _visibleNext = new Dictionary(); private float _dangerNext; private readonly List _localKillTimes = new List(); private int _lastHitViewId = -1; private HitZone _lastHitZone = HitZone.Body; private byte _lastHitDmgType; private float _lastHitTime = -10f; private HashSet _rareNames; public static ActionContentTracker Instance { get; private set; } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.ActionContentTracker"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void OnEnable() { DoomNet.OnMonsterDeath += OnMonsterDeath; ActionNet.OnKillMeta += OnKillMeta; ActionEvents.OnLocalHitDealt += OnLocalHitDealt; } private void OnDisable() { DoomNet.OnMonsterDeath -= OnMonsterDeath; ActionNet.OnKillMeta -= OnKillMeta; ActionEvents.OnLocalHitDealt -= OnLocalHitDealt; } private void HandlePvpKill(int killerActor, int victimActor, Vector3 pos) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (killerActor == DoomNet.LocalActor) { Plugin.HudLocalKill(); } ActionCamera instance = ActionCamera.Instance; if (!((Object)(object)instance == (Object)null) && instance.IsRecording && ActionRoundManager.Phase == ActionRoundPhase.Action && instance.IsFilming(pos, 1f)) { ActionNet.SendFilmClaim(14, killerActor, victimActor, pos, 0); } } private HashSet Rare() { if (_rareNames != null) { return _rareNames; } _rareNames = new HashSet(StringComparer.OrdinalIgnoreCase); string[] array = (DoomConfig.RareMonsterNames.Value ?? "").Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { _rareNames.Add(text); } } return _rareNames; } private bool IsRareName(string name) { if (string.IsNullOrEmpty(name)) { return false; } foreach (string item in Rare()) { if (name.IndexOf(item, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static byte DangerBits(MonsterHealth h) { int num = h?.JumpScareLevel ?? (-1); if (num < 0) { return 0; } if (num >= 3) { return 128; } if (num == 2 || num == 0) { return 64; } return 0; } private void Update() { //IL_01c1: 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_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) if (ActionRoundManager.Phase != ActionRoundPhase.Action) { return; } ActionCamera instance = ActionCamera.Instance; if ((Object)(object)instance == (Object)null || !instance.IsRecording || (Object)(object)MonsterRegistry.Instance == (Object)null) { return; } _visiblePollTimer += Time.deltaTime; if (_visiblePollTimer >= 0.4f) { _visiblePollTimer = 0f; foreach (MonsterHealth item in MonsterRegistry.Instance.All) { if (item.Alive && !((Object)(object)item.Root == (Object)null) && (!_visibleNext.TryGetValue(item.ViewId, out var value) || !(Time.time < value)) && instance.IsFilming(item.CenterPos, 1.2f)) { _visibleNext[item.ViewId] = Time.time + Mathf.Max(1f, DoomConfig.MonsterVisibleCooldown.Value); byte b = (byte)(IsRareName(item.MonsterName) ? 32 : 0); b |= DangerBits(item); ActionNet.SendFilmClaim(0, 0, item.ViewId, item.CenterPos, b); } } } Player localPlayer = Player.localPlayer; if (!((Object)(object)localPlayer != (Object)null) || localPlayer.data == null || localPlayer.data.dead || !(Time.time >= _dangerNext)) { return; } float maxHealth = PlayerData.maxHealth; if (!(localPlayer.data.health <= maxHealth * DoomConfig.DangerHealthFraction.Value)) { return; } int num = 0; Vector3 val = ((localPlayer.refs != null && (Object)(object)localPlayer.refs.headPos != (Object)null) ? localPlayer.refs.headPos.position : ((Component)localPlayer).transform.position); foreach (MonsterHealth item2 in MonsterRegistry.Instance.All) { if (item2.Alive && (Object)(object)item2.Root != (Object)null) { Vector3 val2 = item2.CenterPos - val; if (((Vector3)(ref val2)).sqrMagnitude < DoomConfig.DangerRadius.Value * DoomConfig.DangerRadius.Value) { num++; } } } if (num >= 2) { _dangerNext = Time.time + Mathf.Max(2f, DoomConfig.DangerCooldown.Value); byte flags = SpeechFlag(localPlayer); ActionNet.SendFilmClaim(10, DoomNet.LocalActor, 0, val, flags); } } private static byte SpeechFlag(Player p) { if (!((Object)(object)p != (Object)null) || p.data == null || !(p.data.microphoneValue > DoomConfig.SpeechMicThreshold.Value)) { return 0; } return 16; } private void OnLocalHitDealt(int viewId, HitZone zone, byte dmgType) { _lastHitViewId = viewId; _lastHitZone = zone; _lastHitDmgType = dmgType; _lastHitTime = Time.time; } private void OnMonsterDeath(int viewId, Vector3 dir, int killerActor) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) if (killerActor != DoomNet.LocalActor || ActionRoundManager.Phase != ActionRoundPhase.Action) { return; } Player localPlayer = Player.localPlayer; Vector3 val = Vector3.zero; string name = ""; MonsterHealth h = null; if ((Object)(object)MonsterRegistry.Instance != (Object)null && MonsterRegistry.Instance.TryGet(viewId, out var h2)) { val = h2.CenterPos; name = h2.MonsterName; h = h2; } byte b = _lastHitDmgType; HitZone hitZone = HitZone.Body; if (_lastHitViewId == viewId && Time.time - _lastHitTime < 1.5f) { hitZone = _lastHitZone; } else { WeaponManager instance = WeaponManager.Instance; if ((Object)(object)instance != (Object)null && instance.CurrentDef != null) { b = (byte)instance.CurrentDef.DamageType; } } _localKillTimes.RemoveAll((float t) => Time.time - t > DoomConfig.MultiKillWindow.Value); _localKillTimes.Add(Time.time); int count = _localKillTimes.Count; KillFlags killFlags = KillFlags.None; if ((Object)(object)localPlayer != (Object)null && localPlayer.data != null && !localPlayer.data.isGrounded) { killFlags |= KillFlags.Airborne; } DoomPlayerMovement doomPlayerMovement = Object.FindObjectOfType(); if ((Object)(object)doomPlayerMovement != (Object)null && !doomPlayerMovement.DashReady && doomPlayerMovement.DashCooldownLeft > DoomConfig.DashCooldown.Value - DoomConfig.DashKillWindow.Value) { killFlags |= KillFlags.Dash; } if ((Object)(object)localPlayer != (Object)null && localPlayer.refs != null && (Object)(object)localPlayer.refs.headPos != (Object)null && val != Vector3.zero && Vector3.Distance(localPlayer.refs.headPos.position, val) <= DoomConfig.CloseRangeDistance.Value) { killFlags |= KillFlags.CloseRange; } if (_lastHitViewId == viewId && _lastHitDmgType == 5) { killFlags |= KillFlags.Glory; } if (b == 5) { killFlags |= KillFlags.Glory; } if (IsRareName(name)) { killFlags |= KillFlags.Rare; } killFlags = (KillFlags)((uint)killFlags | (uint)SpeechFlag(localPlayer)); killFlags = (KillFlags)((uint)killFlags | (uint)DangerBits(h)); byte multi = (byte)Mathf.Clamp(count, 1, 15); ActionNet.SendKillMeta(killerActor, viewId, val, b, (byte)hitZone, (byte)killFlags, multi); } private void OnKillMeta(int killerActor, int viewId, Vector3 pos, byte dmgType, byte hitZone, byte flagsB, byte multi) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (viewId < 0) { HandlePvpKill(killerActor, -viewId - 1, pos); return; } ActionCamera instance = ActionCamera.Instance; if ((Object)(object)instance == (Object)null || !instance.IsRecording || ActionRoundManager.Phase != ActionRoundPhase.Action) { return; } if (pos == Vector3.zero) { pos = LocalMonsterPos(viewId); } if (!instance.IsFilming(pos, 1f)) { return; } KillFlags killFlags = (KillFlags)flagsB; byte b = (byte)(killFlags & (KillFlags.Speech | KillFlags.Rare | KillFlags.Dangerous | KillFlags.VeryDangerous)); HitZone hitZone2 = (HitZone)hitZone; Claim(ActionContentEventType.MonsterKill, killerActor, viewId, pos, b); if (hitZone2 == HitZone.Head) { Claim(ActionContentEventType.Headshot, killerActor, viewId, pos, b); Claim(ActionContentEventType.HeadshotKill, killerActor, viewId, pos, b); } if ((killFlags & KillFlags.Airborne) != KillFlags.None) { Claim(ActionContentEventType.AirborneKill, killerActor, viewId, pos, b); } if ((killFlags & KillFlags.Dash) != KillFlags.None) { Claim(ActionContentEventType.DashKill, killerActor, viewId, pos, b); } if ((killFlags & KillFlags.Glory) != KillFlags.None) { Claim(ActionContentEventType.GloryKill, killerActor, viewId, pos, b); } if ((killFlags & KillFlags.CloseRange) != KillFlags.None) { Claim(ActionContentEventType.CloseRangeKill, killerActor, viewId, pos, b); } if ((killFlags & KillFlags.Speech) != KillFlags.None) { Claim(ActionContentEventType.SpeechMoment, killerActor, viewId, pos, b); } if (multi >= 2) { byte flags = (byte)(b | (multi & 0xF)); Claim(ActionContentEventType.MultiKill, killerActor, viewId, pos, flags); DamageType damageType = (DamageType)dmgType; if (multi >= 3 && (damageType == DamageType.BFG || damageType == DamageType.Explosion)) { Claim(ActionContentEventType.BFGMultiKill, killerActor, viewId, pos, flags); } } if (killerActor != DoomNet.LocalActor) { Claim(ActionContentEventType.PlayerCombat, killerActor, viewId, pos, b); } ActionEvents.RaiseMonsterKilled(killerActor, viewId, pos, dmgType, hitZone2, killFlags, multi); } private static void Claim(ActionContentEventType t, int killerActor, int viewId, Vector3 pos, byte flags) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ActionNet.SendFilmClaim((byte)t, killerActor, viewId, pos, flags); } private static Vector3 LocalMonsterPos(int viewId) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MonsterRegistry.Instance != (Object)null && MonsterRegistry.Instance.TryGet(viewId, out var h) && (Object)(object)h.Root != (Object)null) { return h.CenterPos; } return Vector3.zero; } } public static class ActionEconomy { private static readonly Dictionary _credits = new Dictionary(); private static readonly Dictionary> _purchased = new Dictionary>(); public static int GetCredits(int actor) { if (!_credits.TryGetValue(actor, out var value)) { return 0; } return value; } public static void AddCredits(int actor, int amount) { _credits[actor] = GetCredits(actor) + Mathf.Max(0, amount); } public static bool SpendCredits(int actor, int amount) { if (GetCredits(actor) < amount) { return false; } _credits[actor] = GetCredits(actor) - amount; return true; } public static int CreditsFromViews(int views) { float num = Mathf.Max(1f, DoomConfig.ActionCreditsDivisor.Value); return Mathf.Max(0, Mathf.RoundToInt((float)views / num)); } public static HashSet Purchased(int actor) { if (!_purchased.TryGetValue(actor, out var value)) { value = new HashSet(); _purchased[actor] = value; } return value; } public static int PriceOf(WeaponId id) { return id switch { WeaponId.Minigun => 150, WeaponId.GrenadeLauncher => 200, _ => 999999, }; } public static bool TryBuy(int actor, WeaponId id) { if (Purchased(actor).Contains(id)) { return true; } if (!SpendCredits(actor, PriceOf(id))) { return false; } Purchased(actor).Add(id); Plugin.LogMode($"actor {actor} bought {id} ({PriceOf(id)} credits, {GetCredits(actor)} left)"); return true; } public static void ApplyPurchasesToLocalPlayer(int actor) { WeaponManager instance = WeaponManager.Instance; if ((Object)(object)instance == (Object)null) { return; } foreach (WeaponId item in Purchased(actor)) { instance.Unlock(item); instance.GiveAmmo(item, 99999); } } public static void ClearPurchasesForNextRun() { _purchased.Clear(); } } public class ActionHUD : MonoBehaviour { private struct Popup { public string text; public float until; } private readonly List _popups = new List(); private float _headshotUntil; private GUIStyle _big; private GUIStyle _mid; private GUIStyle _small; private GUIStyle _center; private GUIStyle _pop; private void OnEnable() { ActionNet.OnContentEvent += OnContentEvent; ActionEvents.OnLocalHeadshot += delegate { _headshotUntil = Time.time + 0.5f; }; } private void OnDisable() { ActionNet.OnContentEvent -= OnContentEvent; } private void OnContentEvent(int opActor, byte type, int awarded, int total, Vector3 pos) { if (opActor == DoomNet.LocalActor) { _popups.Add(new Popup { text = $"{ActionRoundManager.PrettyName((ActionContentEventType)type)} +{awarded}", until = Time.time + 2.2f }); if (_popups.Count > 6) { _popups.RemoveAt(0); } } } private void Styles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown if (_big == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 30, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val.normal.textColor = new Color(1f, 0.85f, 0.3f); _big = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 18, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val2.normal.textColor = Color.white; _mid = val2; GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 14, alignment = (TextAnchor)4 }; val3.normal.textColor = new Color(0.9f, 0.9f, 0.9f); _small = val3; GUIStyle val4 = new GUIStyle(GUI.skin.label) { fontSize = 22, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val4.normal.textColor = new Color(1f, 0.9f, 0.4f); _center = val4; GUIStyle val5 = new GUIStyle(GUI.skin.label) { fontSize = 17, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; val5.normal.textColor = new Color(1f, 0.95f, 0.6f); _pop = val5; } } private void OnGUI() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Expected O, but got Unknown //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.DoomModeActive || !DoomConfig.ActionModeEnabled.Value) { return; } Styles(); float num = Screen.width; float cx = num * 0.5f; switch (ActionRoundManager.Phase) { case ActionRoundPhase.Preparation: GUI.Label(new Rect(0f, 70f, num, 40f), "ACTION STARTS IN", _mid); GUI.Label(new Rect(0f, 100f, num, 60f), Mathf.CeilToInt(ActionRoundManager.PhaseTimer).ToString(), _big); GUI.Label(new Rect(0f, 160f, num, 24f), "friendly fire off — spread out and get ready", _small); break; case ActionRoundPhase.Action: DrawActionTopBar(cx); DrawPopups(); break; case ActionRoundPhase.Returning: GUI.Label(new Rect(0f, 80f, num, 40f), "RETURN TO THE DIVE BELL", _mid); break; case ActionRoundPhase.WaitingForSubmissions: DrawWaiting(cx); break; case ActionRoundPhase.ProcessingVideo: { GUI.Label(new Rect(0f, 70f, num, 34f), "PROCESSING BEST VIDEO", _center); GUI.Label(new Rect(0f, 104f, num, 20f), $"{Mathf.CeilToInt(ActionRoundManager.PhaseTimer)}s", _small); int num2 = 0; int num3 = 0; foreach (PlayerActionSession item in ActionSessions.All) { num3++; if (item.VideoStatus == VideoStatus.Ready || item.VideoStatus == VideoStatus.Sharing || item.VideoStatus == VideoStatus.Playable || item.VideoStatus == VideoStatus.Failed) { num2++; } } GUI.Label(new Rect(0f, 126f, num, 20f), (num3 > 0) ? $"{num2} / {num3}" : "", _small); if (!string.IsNullOrEmpty(ActionRoundManager.TvStatusLine)) { GUI.Label(new Rect(0f, 148f, num, 20f), ActionRoundManager.TvStatusLine, _small); } break; } case ActionRoundPhase.Results: DrawResults(cx); break; } if (ActionRoundManager.Phase == ActionRoundPhase.Action || ActionRoundManager.Phase == ActionRoundPhase.Returning) { ActionSessions.TryGet(DoomNet.LocalActor, out var s); int num4 = s?.ContentScore ?? 0; GUIStyle val = new GUIStyle(_mid) { alignment = (TextAnchor)3 }; val.normal.textColor = new Color(1f, 0.8f, 0.3f); GUIStyle val2 = val; GUI.Label(new Rect(24f, (float)(Screen.height - 132), 360f, 26f), $"CONTENT: {num4:n0}", val2); } } private void DrawActionTopBar(float cx) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown ActionCamera instance = ActionCamera.Instance; float num = (((Object)(object)instance != (Object)null) ? instance.TimeRemaining : 0f); bool flag = (Object)(object)instance != (Object)null && instance.IsRecording; int num2 = Mathf.FloorToInt(num / 60f); int num3 = Mathf.FloorToInt(num % 60f); Color textColor = ((!flag) ? new Color(0.5f, 0.5f, 0.5f) : ((Mathf.Sin(Time.time * 8f) > 0f) ? new Color(1f, 0.2f, 0.2f) : new Color(0.6f, 0.1f, 0.1f))); GUIStyle val = new GUIStyle(_mid); val.normal.textColor = textColor; GUIStyle val2 = val; GUI.Label(new Rect(0f, 16f, (float)Screen.width, 26f), flag ? $"REC ● {num2:00}:{num3:00}" : $"○ REC {num2:00}:{num3:00}", val2); GUI.Label(new Rect(0f, 42f, (float)Screen.width, 20f), flag ? "hold RMB filming" : $"RECORDING LEFT: {Mathf.CeilToInt(num)}s — hold RMB to film", _small); if (Time.time < _headshotUntil) { Rect val3 = new Rect(0f, (float)Screen.height * 0.5f + 28f, (float)Screen.width, 24f); GUIStyle val4 = new GUIStyle(_small) { fontStyle = (FontStyle)1 }; val4.normal.textColor = new Color(1f, 0.9f, 0.4f); GUI.Label(val3, "HEADSHOT", val4); } } private void DrawPopups() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) float num = (float)Screen.height * 0.34f; for (int num2 = _popups.Count - 1; num2 >= 0; num2--) { if (Time.time > _popups[num2].until) { _popups.RemoveAt(num2); } else { float num3 = Mathf.Clamp01(_popups[num2].until - Time.time); GUIStyle val = new GUIStyle(_pop); val.normal.textColor = new Color(1f, 0.95f, 0.6f, num3); GUIStyle val2 = val; GUI.Label(new Rect((float)(Screen.width - 320), num, 300f, 24f), _popups[num2].text, val2); num += 26f; } } } private void DrawWaiting(float cx) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) bool value = DoomConfig.RequireCameraDeposit.Value; GUI.Label(new Rect(0f, 66f, (float)Screen.width, 34f), value ? "DEPOSIT YOUR CAMERA IN THE RECYCLER" : "WAITING FOR CAMERAS", _center); GUI.Label(new Rect(0f, 100f, (float)Screen.width, 20f), $"{Mathf.CeilToInt(ActionRoundManager.PhaseTimer)}s", _small); if (value) { bool uploaded = ActionSessions.Get(DoomNet.LocalActor).Uploaded; float recyclerDistance = ActionRoundManager.RecyclerDistance; if (uploaded) { GUIStyle val = new GUIStyle(_center) { fontSize = 22 }; val.normal.textColor = new Color(0.5f, 1f, 0.5f); GUIStyle val2 = val; GUI.Label(new Rect(0f, (float)Screen.height * 0.5f + 30f, (float)Screen.width, 30f), "✓ CAMERA HANDED IN — waiting for others", val2); } else if (ActionRoundManager.DepositPromptVisible) { GUIStyle val3 = new GUIStyle(_center) { fontSize = 24 }; val3.normal.textColor = new Color(0.5f, 1f, 0.5f); GUIStyle val4 = val3; GUI.Label(new Rect(0f, (float)Screen.height * 0.5f + 30f, (float)Screen.width, 34f), "[E] / [F] / [RMB] DEPOSIT CAMERA · or Alt+E anywhere", val4); } else if (recyclerDistance > 0f) { GUI.Label(new Rect(0f, (float)Screen.height * 0.5f + 30f, (float)Screen.width, 24f), $"go to the video recycler ({Mathf.RoundToInt(recyclerDistance)} m) · or Alt+E to hand it in now", _small); } else { GUI.Label(new Rect(0f, (float)Screen.height * 0.5f + 30f, (float)Screen.width, 24f), "press Alt+E to hand in your camera", _small); } } float num = 126f; Player[] playerList = PhotonNetwork.PlayerList; if (playerList != null) { Player[] array = playerList; foreach (Player val5 in array) { ActionSessions.TryGet(val5.ActorNumber, out var s); bool flag = s?.Uploaded ?? false; string text = ((s != null && !string.IsNullOrEmpty(s.PlayerName)) ? s.PlayerName : (val5.NickName ?? ("P" + val5.ActorNumber))); GUI.Label(new Rect(0f, num, (float)Screen.width, 22f), text + " " + (flag ? "✓" : "…"), _small); num += 22f; } } } private void DrawResults(float cx) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) int winnerActor = ActionRoundManager.WinnerActor; string text = "—"; if (winnerActor >= 0) { ActionSessions.TryGet(winnerActor, out var s); text = ((s != null && !string.IsNullOrEmpty(s.PlayerName)) ? s.PlayerName : ("Player " + winnerActor)); } GUI.Label(new Rect(0f, 60f, (float)Screen.width, 40f), "BEST VIDEO", _center); GUI.Label(new Rect(0f, 100f, (float)Screen.width, 50f), text.ToUpperInvariant(), _big); GUI.Label(new Rect(0f, 150f, (float)Screen.width, 30f), $"{ActionRoundManager.WinnerViews:n0} VIEWS", _mid); GUI.Label(new Rect(0f, 180f, (float)Screen.width, 22f), $"content score {ActionRoundManager.WinnerScore:n0} · gets the disc", _small); if (ActionRoundManager.DiscToLocalPlayer) { GUIStyle val = new GUIStyle(_small); val.normal.textColor = new Color(0.5f, 1f, 0.5f); GUIStyle val2 = val; GUI.Label(new Rect(0f, 200f, (float)Screen.width, 22f), "the video disc is in inventory SLOT 1", val2); GUI.Label(new Rect(0f, 220f, (float)Screen.width, 20f), "turn Doom Mode OFF (Alt+K) to select your slots", _small); } int videoWinnerActor = ActionRoundManager.VideoWinnerActor; if (videoWinnerActor >= 0 && videoWinnerActor != winnerActor) { ActionSessions.TryGet(videoWinnerActor, out var s2); string text2 = ((s2 != null && !string.IsNullOrEmpty(s2.PlayerName)) ? s2.PlayerName : ("Player " + videoWinnerActor)); GUI.Label(new Rect(0f, 204f, (float)Screen.width, 20f), "(video: " + text2 + " — content winner's clip unavailable)", _small); } if (DoomConfig.RealVideoRecording.Value && !ActionRoundManager.WinnerVideoPlayedLocally) { string tvStatusLine = ActionRoundManager.TvStatusLine; GUI.Label(new Rect(0f, 226f, (float)Screen.width, 20f), string.IsNullOrEmpty(tvStatusLine) ? "TV: preparing…" : ((tvStatusLine == "SUCCESS") ? "" : ("VIDEO UNAVAILABLE — " + tvStatusLine)), _small); } ActionSessions.TryGet(DoomNet.LocalActor, out var s3); if (s3 != null) { GUI.Label(new Rect(0f, 210f, (float)Screen.width, 22f), $"you: {s3.FinalViews:n0} views · +{ActionEconomy.CreditsFromViews(s3.FinalViews)} credits", _small); } } } public enum ActionRoundPhase : byte { Surface = 0, Preparation = 1, Action = 2, Returning = 3, WaitingForSubmissions = 4, ProcessingVideo = 6, Results = 5 } public enum ActionContentEventType : byte { MonsterVisible, MonsterKill, Headshot, HeadshotKill, AirborneKill, DashKill, GloryKill, MultiKill, BFGMultiKill, CloseRangeKill, DangerousMoment, PlayerCombat, RareMonster, SpeechMoment, PlayerKill } public enum HitZone : byte { Other, Body, Head } public enum VideoStatus : byte { None, CameraReady, Recording, Stopped, Encoding, Ready, Sharing, Playable, Failed } [Flags] public enum KillFlags : byte { None = 0, Airborne = 1, Dash = 2, Glory = 4, CloseRange = 8, Speech = 0x10, Rare = 0x20, Dangerous = 0x40, VeryDangerous = 0x80 } public class PlayerActionSession { public int ActorNumber; public string PlayerName = "PLAYER"; public float MaxRecordingTime = 90f; public float RecordingTimeRemaining = 90f; public bool IsRecording; public int ContentScore; public int FinalViews; public bool Uploaded; public int Kills; public int Headshots; public int GloryKills; public int MultiKills; public VideoStatus VideoStatus; public string VideoIdShort = ""; public int ClipCount; public readonly Dictionary EventCounts = new Dictionary(); public int DistinctEventTypes => EventCounts.Count; public void ResetForRound(float maxTime) { MaxRecordingTime = maxTime; RecordingTimeRemaining = maxTime; IsRecording = false; ContentScore = 0; FinalViews = 0; Uploaded = false; Kills = (Headshots = (GloryKills = (MultiKills = 0))); VideoStatus = VideoStatus.None; VideoIdShort = ""; ClipCount = 0; EventCounts.Clear(); } } public static class ActionSessions { private static readonly Dictionary _sessions = new Dictionary(); public static IEnumerable All => _sessions.Values; public static int Count => _sessions.Count; public static PlayerActionSession Get(int actor) { if (!_sessions.TryGetValue(actor, out var value)) { value = new PlayerActionSession { ActorNumber = actor }; _sessions[actor] = value; } return value; } public static bool TryGet(int actor, out PlayerActionSession s) { return _sessions.TryGetValue(actor, out s); } public static void ResetAll(float maxTime) { foreach (PlayerActionSession value in _sessions.Values) { value.ResetForRound(maxTime); } } public static void Clear() { _sessions.Clear(); } } public static class ActionEvents { public static event Action OnMonsterKilled; public static event Action OnLocalHeadshot; public static event Action OnLocalHitDealt; public static void RaiseMonsterKilled(int killerActor, int monsterViewId, Vector3 pos, byte dmgType, HitZone zone, KillFlags flags, int multi) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) ActionEvents.OnMonsterKilled?.Invoke(killerActor, monsterViewId, pos, dmgType, zone, flags, multi); } public static void RaiseLocalHeadshot() { ActionEvents.OnLocalHeadshot?.Invoke(); } public static void RaiseLocalHitDealt(int viewId, HitZone zone, byte dmgType) { ActionEvents.OnLocalHitDealt?.Invoke(viewId, zone, dmgType); } } public class ActionNet : MonoBehaviour, IOnEventCallback { public const byte EVT_ROUND_STATE = 190; public const byte EVT_REC_STATE = 191; public const byte EVT_CONTENT_EVENT = 192; public const byte EVT_FILM_CLAIM = 193; public const byte EVT_KILL_META = 194; public const byte EVT_SUBMIT = 195; public const byte EVT_RESULTS = 196; public const byte EVT_SESSION_SYNC = 197; public const byte EVT_WINNER_VIDEO = 198; private static readonly RaiseEventOptions ToAll = new RaiseEventOptions { Receivers = (ReceiverGroup)1 }; private static readonly RaiseEventOptions ToOthers = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; private static readonly RaiseEventOptions ToMaster = new RaiseEventOptions { Receivers = (ReceiverGroup)2 }; public static ActionNet Instance { get; private set; } public static event Action OnRoundState; public static event Action OnRecState; public static event Action OnContentEvent; public static event Action OnFilmClaim; public static event Action OnKillMeta; public static event Action OnSubmit; public static event Action OnResults; public static event Action OnSessionSync; public static event Action OnWinnerVideo; public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.ActionNet"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void OnEnable() { PhotonNetwork.AddCallbackTarget((object)this); } private void OnDisable() { PhotonNetwork.RemoveCallbackTarget((object)this); } private static void Send(byte code, RaiseEventOptions opts, params object[] content) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (!DoomNet.InRoom) { return; } try { PhotonNetwork.RaiseEvent(code, (object)content, opts, SendOptions.SendReliable); } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[DoomNetwork] Action RaiseEvent {code} failed: {ex.Message}"); } } public static void SendRoundState(byte phase, float timer, bool spawnsAllowed, float actionLen) { Send(190, ToAll, phase, timer, spawnsAllowed, actionLen); } public static void SendRecState(bool recording, float timeLeft) { Send(191, ToAll, DoomNet.LocalActor, recording, timeLeft); } public static void SendContentEvent(int opActor, byte type, int awarded, int total, Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) Send(192, ToAll, opActor, type, awarded, total, pos.x, pos.y, pos.z); } public static void SendFilmClaim(byte type, int killerActor, int monsterViewId, Vector3 pos, byte flags) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) Send(193, ToMaster, DoomNet.LocalActor, type, killerActor, monsterViewId, pos.x, pos.y, pos.z, flags); } public static void SendKillMeta(int killerActor, int monsterViewId, Vector3 pos, byte dmgType, byte hitZone, byte flags, byte multi) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Send(194, ToAll, killerActor, monsterViewId, pos.x, pos.y, pos.z, dmgType, hitZone, flags, multi); } public static void SendSubmit(string videoIdShort, int clipCount, byte videoStatus) { Send(195, ToMaster, DoomNet.LocalActor, videoIdShort ?? "", clipCount, videoStatus); } public static void SendResults(int winnerActor, int winnerViews, int winnerScore, int videoWinnerActor) { Send(196, ToAll, winnerActor, winnerViews, winnerScore, videoWinnerActor); } public static void SendSessionSync(int actor, int score, int kills, int views, byte recFlag, float timeLeft, string name, byte videoStatus, int headshots) { Send(197, ToAll, actor, score, kills, views, recFlag, timeLeft, name ?? "", videoStatus, headshots); } public static void SendWinnerVideo(byte[] videoGuid, int views) { Send(198, ToAll, videoGuid ?? new byte[16], views); } public static void SendPvpKill(int killerActor, int victimActor, Vector3 pos) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) SendKillMeta(killerActor, -victimActor - 1, pos, 0, 0, 0, 1); } public void OnEvent(EventData e) { //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) if (e.Code < 190 || e.Code > 198) { return; } object[] array; try { array = (object[])e.CustomData; } catch { return; } if (array == null) { return; } try { switch (e.Code) { case 190: ActionNet.OnRoundState?.Invoke(Convert.ToByte(array[0]), Convert.ToSingle(array[1]), (bool)array[2], Convert.ToSingle(array[3])); break; case 191: ActionNet.OnRecState?.Invoke(Convert.ToInt32(array[0]), (bool)array[1], Convert.ToSingle(array[2])); break; case 192: ActionNet.OnContentEvent?.Invoke(Convert.ToInt32(array[0]), Convert.ToByte(array[1]), Convert.ToInt32(array[2]), Convert.ToInt32(array[3]), new Vector3(Convert.ToSingle(array[4]), Convert.ToSingle(array[5]), Convert.ToSingle(array[6]))); break; case 193: ActionNet.OnFilmClaim?.Invoke(Convert.ToInt32(array[0]), Convert.ToByte(array[1]), Convert.ToInt32(array[2]), Convert.ToInt32(array[3]), new Vector3(Convert.ToSingle(array[4]), Convert.ToSingle(array[5]), Convert.ToSingle(array[6])), Convert.ToByte(array[7])); break; case 194: ActionNet.OnKillMeta?.Invoke(Convert.ToInt32(array[0]), Convert.ToInt32(array[1]), new Vector3(Convert.ToSingle(array[2]), Convert.ToSingle(array[3]), Convert.ToSingle(array[4])), Convert.ToByte(array[5]), Convert.ToByte(array[6]), Convert.ToByte(array[7]), Convert.ToByte(array[8])); break; case 195: ActionNet.OnSubmit?.Invoke(Convert.ToInt32(array[0]), (string)array[1], Convert.ToInt32(array[2]), Convert.ToByte(array[3])); break; case 196: ActionNet.OnResults?.Invoke(Convert.ToInt32(array[0]), Convert.ToInt32(array[1]), Convert.ToInt32(array[2]), (array.Length > 3) ? Convert.ToInt32(array[3]) : Convert.ToInt32(array[0])); break; case 197: ActionNet.OnSessionSync?.Invoke(Convert.ToInt32(array[0]), Convert.ToInt32(array[1]), Convert.ToInt32(array[2]), Convert.ToInt32(array[3]), Convert.ToByte(array[4]), Convert.ToSingle(array[5]), (string)array[6], (byte)((array.Length > 7) ? Convert.ToByte(array[7]) : 0), (array.Length > 8) ? Convert.ToInt32(array[8]) : 0); break; case 198: ActionNet.OnWinnerVideo?.Invoke((byte[])array[0], Convert.ToInt32(array[1])); break; } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[DoomNetwork] Action bad event {e.Code}: {ex.Message}"); } } } public class ActionRoundManager : MonoBehaviour { private byte[] _winnerGuid; private float _procTimer; private bool _winnerVideoBroadcast; private float _statusResendTimer; private bool _discAwarded; private ExtractVideoMachine _recycler; private float _syncTimer; private float _submitTimer; private bool _prepFrozen; private float _sinceWaiting; private readonly HashSet _seenClaims = new HashSet(); private readonly Dictionary _visibleCooldown = new Dictionary(); private float _depositLogTimer; public static ActionRoundManager Instance { get; private set; } public static ActionRoundPhase Phase { get; private set; } = ActionRoundPhase.Surface; public static float PhaseTimer { get; private set; } public static bool SpawnsAllowed { get; private set; } = true; public static float ActionLength { get; private set; } public static int WinnerActor { get; private set; } = -1; public static int WinnerViews { get; private set; } public static int WinnerScore { get; private set; } public static int VideoWinnerActor { get; private set; } = -1; public static bool WinnerVideoPlayedLocally { get; private set; } public static string TvStatusLine { get; private set; } = ""; public static string LastEventPopup { get; private set; } public static float LastEventPopupTime { get; private set; } public static bool DepositPromptVisible { get; private set; } public static bool DiscToLocalPlayer { get; private set; } public static float RecyclerDistance { get; private set; } = -1f; private static bool ActionEnabled { get { if (DoomConfig.ActionModeEnabled.Value) { return Plugin.DoomModeActive; } return false; } } private static bool OnSurface { get { //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) Scene activeScene = SceneManager.GetActiveScene(); string text = ((Scene)(ref activeScene)).name ?? ""; if (!text.Contains("Surface") && !text.Contains("Menu")) { return text.Length == 0; } return true; } } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.ActionRoundManager"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; ActionNet.OnRoundState += OnRoundStateNet; ActionNet.OnFilmClaim += OnFilmClaimHost; ActionNet.OnRecState += OnRecStateHost; ActionNet.OnSubmit += OnSubmitHost; ActionNet.OnContentEvent += OnContentEventAll; ActionNet.OnSessionSync += OnSessionSyncAll; ActionNet.OnResults += OnResultsAll; ActionNet.OnWinnerVideo += OnWinnerVideoAll; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; ActionNet.OnRoundState -= OnRoundStateNet; ActionNet.OnFilmClaim -= OnFilmClaimHost; ActionNet.OnRecState -= OnRecStateHost; ActionNet.OnSubmit -= OnSubmitHost; ActionNet.OnContentEvent -= OnContentEventAll; ActionNet.OnSessionSync -= OnSessionSyncAll; ActionNet.OnResults -= OnResultsAll; ActionNet.OnWinnerVideo -= OnWinnerVideoAll; } private void OnSceneLoaded(Scene s, LoadSceneMode m) { _prepFrozen = false; if (!ActionEnabled) { SetPhase(ActionRoundPhase.Surface, 0f, spawns: true); } else { if (!DoomNet.IsHost) { return; } if (OnSurface) { if (Phase == ActionRoundPhase.Action || Phase == ActionRoundPhase.Returning || Phase == ActionRoundPhase.Preparation) { _submitTimer = DoomConfig.CameraSubmissionTimeout.Value; SetPhase(ActionRoundPhase.WaitingForSubmissions, _submitTimer, spawns: false); } else { SetPhase(ActionRoundPhase.Surface, 0f, spawns: true); } } else { SetPhase(ActionRoundPhase.Preparation, DoomConfig.PreparationDuration.Value, spawns: false); ActionSessions.ResetAll(DoomConfig.RecordingTime.Value); _seenClaims.Clear(); _visibleCooldown.Clear(); } } } private void Update() { if (!ActionEnabled) { if (Phase != ActionRoundPhase.Surface) { SetPhase(ActionRoundPhase.Surface, 0f, spawns: true); } return; } if (Phase == ActionRoundPhase.Preparation) { FreezeBotsForPrep(); } else if (_prepFrozen) { UnfreezeBots(); } if (Phase == ActionRoundPhase.WaitingForSubmissions) { _sinceWaiting += Time.deltaTime; ActionVideoRecorder instance = ActionVideoRecorder.Instance; if ((Object)(object)instance != (Object)null && instance.IsRecordingNative) { instance.StopNative(); } if ((Object)(object)instance != (Object)null) { instance.PollEncode(); } bool uploaded = ActionSessions.Get(DoomNet.LocalActor).Uploaded; if (!uploaded && DoomConfig.RequireCameraDeposit.Value) { HandleDepositInput(_sinceWaiting < 0.4f); } else if (!uploaded && (((Object)(object)instance == (Object)null || instance.Status == VideoStatus.Ready || instance.Status == VideoStatus.Playable || instance.Status == VideoStatus.Failed) ? (_sinceWaiting > 1f) : (_sinceWaiting > 8f))) { DoLocalSubmit("auto"); } } else { _sinceWaiting = 0f; DepositPromptVisible = false; } if (Phase == ActionRoundPhase.WaitingForSubmissions || Phase == ActionRoundPhase.ProcessingVideo) { ActionVideoRecorder instance2 = ActionVideoRecorder.Instance; instance2?.PollEncode(); if ((Object)(object)instance2 != (Object)null) { ActionSessions.Get(DoomNet.LocalActor).VideoStatus = instance2.Status; } _statusResendTimer += Time.deltaTime; if (_statusResendTimer > 2f) { _statusResendTimer = 0f; byte videoStatus = (byte)(((Object)(object)instance2 != (Object)null) ? instance2.Status : VideoStatus.Failed); string videoIdShort = (((Object)(object)instance2 != (Object)null) ? instance2.VideoIdShort : ""); int clipCount = (((Object)(object)instance2 != (Object)null) ? instance2.ClipCount : 0); if (DoomNet.IsHost) { ApplySubmission(DoomNet.LocalActor, videoIdShort, clipCount, videoStatus); } else { ActionNet.SendSubmit(videoIdShort, clipCount, videoStatus); } } TryPlayWinnerVideo(); } if (!DoomNet.IsHost) { if (PhaseTimer > 0f) { PhaseTimer = Mathf.Max(0f, PhaseTimer - Time.deltaTime); } return; } PhaseTimer = Mathf.Max(0f, PhaseTimer - Time.deltaTime); switch (Phase) { case ActionRoundPhase.Preparation: if (PhaseTimer <= 0f) { StartAction(); } break; case ActionRoundPhase.Action: if (PhaseTimer <= 0f) { SetPhase(ActionRoundPhase.Returning, 4f, spawns: true); } break; case ActionRoundPhase.Returning: if (PhaseTimer <= 0f && !OnSurface) { PhaseTimer = 2f; } else if (PhaseTimer <= 0f) { _submitTimer = DoomConfig.CameraSubmissionTimeout.Value; SetPhase(ActionRoundPhase.WaitingForSubmissions, _submitTimer, spawns: false); } break; case ActionRoundPhase.WaitingForSubmissions: _submitTimer -= Time.deltaTime; PhaseTimer = Mathf.Max(0f, _submitTimer); if (AllSubmitted() || _submitTimer <= 0f) { ComputeResults(); } break; case ActionRoundPhase.ProcessingVideo: { _procTimer -= Time.deltaTime; PhaseTimer = Mathf.Max(0f, _procTimer); int videoWinnerActor = VideoWinnerActor; RecomputeVideoWinner(); if (VideoWinnerActor != videoWinnerActor) { ActionNet.SendResults(WinnerActor, WinnerViews, WinnerScore, VideoWinnerActor); } PlayerActionSession playerActionSession = ((VideoWinnerActor >= 0) ? ActionSessions.Get(VideoWinnerActor) : null); if ((playerActionSession != null && playerActionSession.VideoStatus == VideoStatus.Playable) || _procTimer <= 0f) { Plugin.Log.LogInfo((object)string.Format("[ActionVideo] processing done — videoWinner actor={0} status={1} (timeout={2})", VideoWinnerActor, (playerActionSession != null) ? playerActionSession.VideoStatus.ToString() : "none", _procTimer <= 0f)); SetPhase(ActionRoundPhase.Results, 16f, spawns: true); } break; } case ActionRoundPhase.Results: if (PhaseTimer <= 0f) { FinishResults(); SetPhase(ActionRoundPhase.Surface, 0f, spawns: true); } break; } _syncTimer += Time.deltaTime; if (!(_syncTimer > 1f)) { return; } _syncTimer = 0f; ActionNet.SendRoundState((byte)Phase, PhaseTimer, SpawnsAllowed, ActionLength); foreach (PlayerActionSession item in ActionSessions.All) { ActionNet.SendSessionSync(item.ActorNumber, item.ContentScore, item.Kills, item.FinalViews, (byte)((item.IsRecording ? 1u : 0u) | (uint)(item.Uploaded ? 2 : 0)), item.RecordingTimeRemaining, item.PlayerName, (byte)item.VideoStatus, item.Headshots); } } private void StartAction() { _discAwarded = false; DiscToLocalPlayer = false; DepositPromptVisible = false; _recycler = null; ActionLength = DoomConfig.ActionDuration.Value; SetPhase(ActionRoundPhase.Action, ActionLength, spawns: true); ActionSessions.ResetAll(DoomConfig.RecordingTime.Value); Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { ActionSessions.Get(val.ActorNumber).PlayerName = val.NickName ?? ("P" + val.ActorNumber); } ActionCamera.Instance?.BeginRound(DoomConfig.RecordingTime.Value); ActionEconomy.ApplyPurchasesToLocalPlayer(DoomNet.LocalActor); Plugin.Log.LogInfo((object)"========== ACTION! =========="); ActionNet.SendRoundState((byte)Phase, PhaseTimer, SpawnsAllowed, ActionLength); } private void SetPhase(ActionRoundPhase p, float timer, bool spawns) { bool num = Phase != p; Phase = p; PhaseTimer = timer; SpawnsAllowed = spawns; if (num) { Plugin.LogMode($"round phase -> {p} (timer {timer:0}s, spawns {spawns})"); } if (DoomNet.IsHost) { ActionNet.SendRoundState((byte)p, timer, spawns, ActionLength); } } private void FreezeBotsForPrep() { BotHandler instance = BotHandler.instance; if ((Object)(object)instance == (Object)null || instance.bots == null) { return; } for (int i = 0; i < instance.bots.Count; i++) { Bot val = instance.bots[i]; if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled) { ((Behaviour)val).enabled = false; } } _prepFrozen = true; } private void UnfreezeBots() { BotHandler instance = BotHandler.instance; if ((Object)(object)instance != (Object)null && instance.bots != null) { for (int i = 0; i < instance.bots.Count; i++) { Bot val = instance.bots[i]; if ((Object)(object)val != (Object)null && !((Behaviour)val).enabled && (Object)(object)((Component)val).GetComponentInParent() == (Object)null) { ((Behaviour)val).enabled = true; } } } _prepFrozen = false; } public void RequestLocalSubmit() { if (ActionSessions.Get(DoomNet.LocalActor).Uploaded) { Plugin.LogMode("[ActionVideo] Alt+E: camera already handed in"); } else if (Phase == ActionRoundPhase.WaitingForSubmissions) { DoLocalSubmit("manual (Alt+E)"); } else { Plugin.LogMode($"[ActionVideo] Alt+E: not the submission phase yet (phase={Phase}) — walk to the video station or wait"); } } private void HandleDepositInput(bool grace) { //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) DepositPromptVisible = false; RecyclerDistance = -1f; Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.data == null || localPlayer.data.dead || localPlayer.refs == null || (Object)(object)localPlayer.refs.headPos == (Object)null) { return; } if ((Object)(object)_recycler == (Object)null) { ExtractVideoMachine recycler = null; float num = float.MaxValue; ExtractVideoMachine[] array = Object.FindObjectsOfType(); foreach (ExtractVideoMachine val in array) { if (!((Object)(object)val == (Object)null)) { float num2 = Vector3.Distance(localPlayer.refs.headPos.position, ((Component)val).transform.position); if (num2 < num) { num = num2; recycler = val; } } } _recycler = recycler; if ((Object)(object)_recycler != (Object)null) { Plugin.LogMode($"[ActionVideo] recycler = '{((Object)_recycler).name}' at {((Component)_recycler).transform.position:F1}"); } } bool flag; if ((Object)(object)_recycler != (Object)null) { Vector3 position = localPlayer.refs.headPos.position; float num3 = Vector3.Distance(position, ((Component)_recycler).transform.position); Collider[] componentsInChildren = ((Component)_recycler).GetComponentsInChildren(); foreach (Collider val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { float num4 = num3; Bounds bounds = val2.bounds; num3 = Mathf.Min(num4, Vector3.Distance(position, ((Bounds)(ref bounds)).ClosestPoint(position))); } } RecyclerDistance = num3; flag = num3 <= Mathf.Max(3f, DoomConfig.DepositRange.Value); } else { flag = _sinceWaiting > 5f; } _depositLogTimer -= Time.deltaTime; if (_depositLogTimer <= 0f) { _depositLogTimer = 2f; object[] obj = new object[5] { localPlayer.refs.headPos.position, null, null, null, null }; object obj2; if (!((Object)(object)_recycler != (Object)null)) { obj2 = "?"; } else { Vector3 position2 = ((Component)_recycler).transform.position; obj2 = ((Vector3)(ref position2)).ToString("F0"); } obj[1] = obj2; obj[2] = RecyclerDistance; obj[3] = DoomConfig.DepositRange.Value; obj[4] = (flag ? "IN RANGE, press E" : "walk closer"); Plugin.LogMode(string.Format("[ActionVideo] deposit: you at {0:F0}, station {1}, dist {2:0.0}m / range {3:0}m -> {4}", obj)); } if (!flag) { return; } DepositPromptVisible = true; if (!grace) { Keyboard current = Keyboard.current; Mouse current2 = Mouse.current; if ((current != null && (((ButtonControl)current.eKey).wasPressedThisFrame || ((ButtonControl)current.fKey).wasPressedThisFrame)) || (current2 != null && current2.rightButton.wasPressedThisFrame)) { DoLocalSubmit(((Object)(object)_recycler != (Object)null) ? "deposited in recycler" : "deposited (grace)"); } } } private void DoLocalSubmit(string reason) { if (!ActionSessions.Get(DoomNet.LocalActor).Uploaded) { ActionVideoRecorder instance = ActionVideoRecorder.Instance; string text = (((Object)(object)instance != (Object)null) ? instance.VideoIdShort : ""); int num = (((Object)(object)instance != (Object)null) ? instance.ClipCount : 0); byte b = (byte)(((Object)(object)instance != (Object)null) ? instance.Status : VideoStatus.Failed); if (DoomNet.IsHost) { ApplySubmission(DoomNet.LocalActor, text, num, b); } else { ActionNet.SendSubmit(text, num, b); } DepositPromptVisible = false; Plugin.Log.LogInfo((object)string.Format("[ActionVideo] actor={0} camera {1} (handle {2}, clips {3}, {4})", DoomNet.LocalActor, reason, string.IsNullOrEmpty(text) ? "" : text, num, (VideoStatus)b)); } } private void GiveDiscToWinner() { //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (_discAwarded) { return; } _discAwarded = true; DiscToLocalPlayer = WinnerActor == DoomNet.LocalActor; if (!DiscToLocalPlayer) { return; } try { if ((Object)(object)_recycler == (Object)null) { _recycler = Object.FindObjectOfType(); } Item val = (((Object)(object)_recycler != (Object)null) ? _recycler.m_flashCardItem : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[ActionVideo] disc NOT awarded — no ExtractVideoMachine / flashcard item found (are you on the surface?)"); return; } Player localPlayer = Player.localPlayer; PlayerInventory val2 = default(PlayerInventory); if ((Object)(object)localPlayer == (Object)null || !localPlayer.TryGetInventory(ref val2)) { Plugin.Log.LogWarning((object)"[ActionVideo] disc NOT awarded — no inventory"); return; } ItemInstanceData val3 = new ItemInstanceData(Guid.NewGuid()); ActionVideoRecorder instance = ActionVideoRecorder.Instance; val3.AddDataEntry((ItemDataEntry)new FlashcardEntry { videoID = (((Object)(object)instance != (Object)null) ? instance.VideoHandle : VideoHandle.Invalid) }); ItemDescriptor val4 = default(ItemDescriptor); ((ItemDescriptor)(ref val4))..ctor(val, val3); bool flag = false; try { val2.SyncClearSlot(0); val2.SyncAddToSlot(0, val4); flag = true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ActionVideo] disc -> slot 0 failed (" + ex.Message + "); using first free slot")); } if (!flag) { flag = val2.TryAddItem(val4); } if (flag) { Plugin.Log.LogInfo((object)$"[ActionVideo] disc awarded to actor={DoomNet.LocalActor} in slot 0 (best video, {WinnerViews} views)"); } else { Plugin.Log.LogWarning((object)"[ActionVideo] disc NOT awarded — inventory full"); } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[ActionVideo] disc award failed: " + ex2.Message)); } } private bool AllSubmitted() { Player[] playerList = PhotonNetwork.PlayerList; if (playerList == null || playerList.Length == 0) { return true; } Player[] array = playerList; foreach (Player val in array) { if (!ActionSessions.Get(val.ActorNumber).Uploaded) { Player val2 = FindPlayerByActor(val.ActorNumber); if (!((Object)(object)val2 != (Object)null) || val2.data == null || !val2.data.dead) { return false; } } } return true; } private void ComputeResults() { int num = -1; int num2 = -1; int num3 = -1; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { PlayerActionSession playerActionSession = ActionSessions.Get(val.ActorNumber); playerActionSession.FinalViews = ActionContentScore.ToViews(playerActionSession.ContentScore); if (playerActionSession.FinalViews > num2 || (playerActionSession.FinalViews == num2 && playerActionSession.ContentScore > num3) || (playerActionSession.FinalViews == num2 && playerActionSession.ContentScore == num3 && (num < 0 || val.ActorNumber < num))) { num = val.ActorNumber; num2 = playerActionSession.FinalViews; num3 = playerActionSession.ContentScore; } } WinnerActor = num; WinnerViews = Mathf.Max(0, num2); WinnerScore = Mathf.Max(0, num3); Plugin.Log.LogInfo((object)$"[ActionVideo] CONTENT winner actor={WinnerActor} score={WinnerScore} views={WinnerViews}"); RecomputeVideoWinner(); playerList = PhotonNetwork.PlayerList; for (int i = 0; i < playerList.Length; i++) { PlayerActionSession playerActionSession2 = ActionSessions.Get(playerList[i].ActorNumber); ActionNet.SendSessionSync(playerActionSession2.ActorNumber, playerActionSession2.ContentScore, playerActionSession2.Kills, playerActionSession2.FinalViews, (byte)(playerActionSession2.Uploaded ? 2u : 0u), 0f, playerActionSession2.PlayerName, (byte)playerActionSession2.VideoStatus, playerActionSession2.Headshots); } ActionNet.SendResults(WinnerActor, WinnerViews, WinnerScore, VideoWinnerActor); if (!DoomConfig.RealVideoRecording.Value) { SetPhase(ActionRoundPhase.Results, 14f, spawns: true); return; } _procTimer = Mathf.Max(10f, DoomConfig.EncodeWaitTimeout.Value + DoomConfig.ShareWaitTimeout.Value); _winnerVideoBroadcast = false; SetPhase(ActionRoundPhase.ProcessingVideo, _procTimer, spawns: true); } private void RecomputeVideoWinner() { int winnerActor = WinnerActor; PlayerActionSession playerActionSession = ((winnerActor >= 0) ? ActionSessions.Get(winnerActor) : null); if (playerActionSession != null && (playerActionSession.VideoStatus == VideoStatus.Ready || playerActionSession.VideoStatus == VideoStatus.Sharing || playerActionSession.VideoStatus == VideoStatus.Playable)) { VideoWinnerActor = winnerActor; return; } int num = -1; int num2 = -1; foreach (PlayerActionSession item in ActionSessions.All) { if ((item.VideoStatus == VideoStatus.Ready || item.VideoStatus == VideoStatus.Sharing || item.VideoStatus == VideoStatus.Playable) && item.ContentScore > num2) { num2 = item.ContentScore; num = item.ActorNumber; } } VideoWinnerActor = ((num >= 0) ? num : winnerActor); } private void FinishResults() { Player[] playerList = PhotonNetwork.PlayerList; foreach (Player obj in playerList) { ActionEconomy.AddCredits(amount: ActionEconomy.CreditsFromViews(ActionSessions.Get(obj.ActorNumber).FinalViews), actor: obj.ActorNumber); } ActionEconomy.ClearPurchasesForNextRun(); ActionCameraSpawner.Instance?.Cleanup(); ActionVideoRecorder.Instance?.EndRoundCleanup(); _winnerGuid = null; _winnerVideoBroadcast = false; WinnerVideoPlayedLocally = false; } private void OnResultsWinnerBroadcast() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!_winnerVideoBroadcast && (WinnerActor == DoomNet.LocalActor || VideoWinnerActor == DoomNet.LocalActor)) { ActionVideoRecorder instance = ActionVideoRecorder.Instance; if (!((Object)(object)instance == (Object)null) && !(instance.VideoHandle.id == Guid.Empty)) { _winnerVideoBroadcast = true; ActionNet.SendWinnerVideo(instance.VideoHandle.id.ToByteArray(), WinnerViews); Plugin.Log.LogInfo((object)$"[ActionVideo] sharing winner actor={DoomNet.LocalActor} clip=* video={instance.VideoIdShort}"); } } } private void OnWinnerVideoAll(byte[] guid, int views) { _winnerGuid = guid; WinnerViews = views; Plugin.Log.LogInfo((object)("[ActionVideo] winner video handle received (" + ((guid != null && guid.Length == 16) ? new Guid(guid).ToString().Substring(0, 8) : "bad") + ")")); } private void TryPlayWinnerVideo() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (WinnerVideoPlayedLocally || !DoomConfig.AttemptTvPlayback.Value) { return; } OnResultsWinnerBroadcast(); if (_winnerGuid == null || _winnerGuid.Length != 16) { TvStatusLine = "waiting for winner video handle…"; return; } CameraRecording val = null; try { RecordingsHandler.TryGetRecording(new VideoHandle(new Guid(_winnerGuid)), ref val); } catch { } string reason; if ((Object)(object)val == (Object)null) { TvStatusLine = "winner recording not on this client yet"; } else if (!(((Object)(object)ActionVideoRecorder.Instance != (Object)null && WinnerActor == DoomNet.LocalActor) ? ActionVideoRecorder.Instance.IsPlayable(out reason) : RecordingPlayable(val, out reason))) { TvStatusLine = reason; } else if (ActionTVPlayback.TryPlayWinnerLocal(val, WinnerViews, out reason)) { WinnerVideoPlayedLocally = true; TvStatusLine = "SUCCESS"; Plugin.Log.LogInfo((object)"[ActionVideo] TV playback START (local)"); if (WinnerActor == DoomNet.LocalActor && (Object)(object)ActionVideoRecorder.Instance != (Object)null) { ActionVideoRecorder.Instance.MarkPlayable(); } } else { TvStatusLine = "FAILED: " + reason; Plugin.Log.LogWarning((object)("[ActionVideo] TV playback FAILED — " + reason)); } } private static bool RecordingPlayable(CameraRecording rec, out string reason) { reason = ""; if (rec.m_clips == null || rec.m_clips.Count == 0) { reason = "0 clips"; return false; } bool flag = false; foreach (Clip clip in rec.m_clips) { if (clip.Valid) { if (clip.local && !clip.encoded) { reason = "a clip is still encoding"; return false; } if (!clip.local && !clip.hasBeenRecieved) { reason = "a clip is still transferring"; return false; } string text = Path.Combine(clip.GetClipDirectory(), "output.webm"); if (File.Exists(text) && new FileInfo(text).Length > 0) { flag = true; } } } if (!flag) { reason = "no output.webm on disk"; return false; } return true; } private void OnRecStateHost(int actor, bool recording, float timeLeft) { PlayerActionSession playerActionSession = ActionSessions.Get(actor); playerActionSession.IsRecording = recording; playerActionSession.RecordingTimeRemaining = timeLeft; } private void OnSubmitHost(int actor, string videoIdShort, int clipCount, byte videoStatus) { if (DoomNet.IsHost) { ApplySubmission(actor, videoIdShort, clipCount, videoStatus); } } private void ApplySubmission(int actor, string videoIdShort, int clipCount, byte videoStatus) { PlayerActionSession playerActionSession = ActionSessions.Get(actor); playerActionSession.Uploaded = true; playerActionSession.VideoIdShort = videoIdShort ?? ""; playerActionSession.ClipCount = clipCount; playerActionSession.VideoStatus = (VideoStatus)videoStatus; Plugin.Log.LogInfo((object)string.Format("[ActionVideo] actor={0} submitted handle={1} clips={2} status={3}", actor, string.IsNullOrEmpty(playerActionSession.VideoIdShort) ? "" : playerActionSession.VideoIdShort, clipCount, playerActionSession.VideoStatus)); } private void OnFilmClaimHost(int opActor, byte type, int killerActor, int monsterViewId, Vector3 pos, byte flags) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) if (!DoomNet.IsHost || Phase != ActionRoundPhase.Action) { return; } PlayerActionSession playerActionSession = ActionSessions.Get(opActor); if (!playerActionSession.IsRecording) { return; } ActionContentEventType actionContentEventType = (ActionContentEventType)type; switch (actionContentEventType) { case ActionContentEventType.MonsterVisible: { int key = opActor * 100000 + monsterViewId; if (_visibleCooldown.TryGetValue(key, out var value) && Time.time < value) { return; } _visibleCooldown[key] = Time.time + Mathf.Max(1f, DoomConfig.MonsterVisibleCooldown.Value); break; } default: { int item = opActor * 1000000 + monsterViewId * 20 + type; if (!_seenClaims.Add(item)) { return; } break; } case ActionContentEventType.DangerousMoment: case ActionContentEventType.PlayerCombat: case ActionContentEventType.PlayerKill: break; } Player val = FindPlayerByActor(opActor); if (!((Object)(object)val != (Object)null) || val.refs == null || !((Object)(object)val.refs.headPos != (Object)null) || !(Vector3.Distance(val.refs.headPos.position, pos) > DoomConfig.MaxFilmDistance.Value * 1.6f)) { bool flag = (flags & 0x20) != 0; int tier = ((actionContentEventType == ActionContentEventType.MultiKill || actionContentEventType == ActionContentEventType.BFGMultiKill) ? Mathf.Max(2, flags & 0xF) : 0); int num = (((flags & 0x80) != 0) ? 3 : (((flags & 0x40) == 0) ? 1 : 2)); int num2 = ActionContentScore.Award(playerActionSession, actionContentEventType, flag, tier, num); if (num2 > 0) { ActionNet.SendContentEvent(opActor, type, num2, playerActionSession.ContentScore, pos); Plugin.LogMode(string.Format("[content] actor {0} filmed {1}{2}{3} +{4} (total {5})", opActor, actionContentEventType, flag ? " (rare)" : "", (num >= 2) ? $" (danger {num})" : "", num2, playerActionSession.ContentScore)); } } } private void OnRoundStateNet(byte phase, float timer, bool spawns, float actionLen) { if (!DoomNet.IsHost) { Phase = (ActionRoundPhase)phase; PhaseTimer = timer; SpawnsAllowed = spawns; ActionLength = actionLen; if (Phase == ActionRoundPhase.Action && ((Object)(object)ActionCamera.Instance == (Object)null || ActionCamera.Instance.MaxTime <= 0f)) { ActionCamera.Instance?.BeginRound(DoomConfig.RecordingTime.Value); } } } private void OnContentEventAll(int opActor, byte type, int awarded, int total, Vector3 pos) { ActionSessions.Get(opActor).ContentScore = total; if (opActor == DoomNet.LocalActor) { LastEventPopup = $"{PrettyName((ActionContentEventType)type)} +{awarded}"; LastEventPopupTime = Time.time; } } private void OnSessionSyncAll(int actor, int score, int kills, int views, byte recFlag, float timeLeft, string name, byte videoStatus, int headshots) { PlayerActionSession playerActionSession = ActionSessions.Get(actor); playerActionSession.ContentScore = score; playerActionSession.Kills = kills; playerActionSession.Headshots = headshots; playerActionSession.FinalViews = views; playerActionSession.IsRecording = (recFlag & 1) != 0; playerActionSession.Uploaded = (recFlag & 2) != 0; if (timeLeft > 0f) { playerActionSession.RecordingTimeRemaining = timeLeft; } if (!string.IsNullOrEmpty(name)) { playerActionSession.PlayerName = name; } if (actor != DoomNet.LocalActor && videoStatus != 0) { playerActionSession.VideoStatus = (VideoStatus)videoStatus; } } private void OnResultsAll(int winnerActor, int winnerViews, int winnerScore, int videoWinnerActor) { WinnerActor = winnerActor; WinnerViews = winnerViews; WinnerScore = winnerScore; VideoWinnerActor = videoWinnerActor; if (Phase != ActionRoundPhase.ProcessingVideo && Phase != ActionRoundPhase.Results) { WinnerVideoPlayedLocally = false; TvStatusLine = ""; } if (!DoomNet.IsHost && Phase != ActionRoundPhase.Results) { if (DoomConfig.RealVideoRecording.Value) { Phase = ActionRoundPhase.ProcessingVideo; PhaseTimer = Mathf.Max(10f, DoomConfig.EncodeWaitTimeout.Value + DoomConfig.ShareWaitTimeout.Value); } else { Phase = ActionRoundPhase.Results; PhaseTimer = 14f; } } Plugin.Log.LogInfo((object)$"[ActionVideo] results: content winner={winnerActor} score={winnerScore} views={winnerViews} videoWinner={videoWinnerActor}"); GiveDiscToWinner(); } public static Player FindPlayerByActor(int actor) { PlayerHandler instance = PlayerHandler.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { return null; } for (int i = 0; i < instance.players.Count; i++) { Player val = instance.players[i]; if ((Object)(object)val != (Object)null && val.refs != null && (Object)(object)val.refs.view != (Object)null && val.refs.view.Owner != null && val.refs.view.Owner.ActorNumber == actor) { return val; } } return null; } public static string PrettyName(ActionContentEventType t) { return t switch { ActionContentEventType.MonsterVisible => "ON CAMERA", ActionContentEventType.MonsterKill => "KILL FILMED", ActionContentEventType.Headshot => "HEADSHOT", ActionContentEventType.HeadshotKill => "HEADSHOT KILL", ActionContentEventType.AirborneKill => "AIRBORNE KILL", ActionContentEventType.DashKill => "DASH KILL", ActionContentEventType.GloryKill => "GLORY KILL", ActionContentEventType.MultiKill => "MULTI KILL", ActionContentEventType.BFGMultiKill => "BFG MASSACRE", ActionContentEventType.CloseRangeKill => "POINT BLANK", ActionContentEventType.DangerousMoment => "DANGER", ActionContentEventType.SpeechMoment => "COMMENTARY", ActionContentEventType.PlayerCombat => "TEAMMATE COMBAT", ActionContentEventType.PlayerKill => "PLAYER DOWN", _ => t.ToString().ToUpperInvariant(), }; } } public static class ActionTVPlayback { public static bool TryPlayWinnerLocal(CameraRecording rec, int views, out string reason) { reason = ""; try { if ((Object)(object)rec == (Object)null) { reason = "no CameraRecording resolved for the winner on this client"; return false; } if (rec.m_clips == null || rec.m_clips.Count == 0) { reason = "winner recording has 0 clips"; return false; } bool flag = false; long num = 0L; foreach (Clip clip in rec.m_clips) { string text = Path.Combine(clip.GetClipDirectory(), "output.webm"); if (File.Exists(text)) { long length = new FileInfo(text).Length; num += length; if (length > 0) { flag = true; } } } if (!flag) { reason = "no encoded output.webm on disk — vanilla encode/extraction step (RecordingsHandler.Encode / ExtractVideoMachine.ExtractVideo) was not run"; return false; } UploadCompleteUI val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { reason = "UploadCompleteUI not found (only exists on the surface / upload station)"; return false; } ((Component)val).gameObject.SetActive(true); val.PlayVideos(rec, views, Array.Empty(), (Action)null); Plugin.Log.LogInfo((object)$"[ActionVideo] TV playback START clips={rec.m_clips.Count} bytes={num}"); return true; } catch (Exception ex) { reason = "exception: " + ex.Message; return false; } } } public class ActionVideoRecorder : MonoBehaviour { private ItemInstanceData _data; private VideoInfoEntry _entry; private bool _recording; private int _clipsStarted; public static ActionVideoRecorder Instance { get; private set; } public VideoStatus Status { get; private set; } public bool NativeReady { get { if (_data != null && _entry != null) { return DoomConfig.RealVideoRecording.Value; } return false; } } public bool IsRecordingNative => _recording; public float TimeLeft { get { if (_entry == null) { return -1f; } return _entry.timeLeft; } } public VideoHandle VideoHandle { get { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (_entry == null) { return VideoHandle.Invalid; } return _entry.videoID; } } public string VideoIdShort { get { Guid guid = ((_entry != null) ? _entry.videoID.id : Guid.Empty); if (!(guid == Guid.Empty)) { return guid.ToString().Substring(0, 8); } return ""; } } public string CameraGuidShort { get { if (!((Object)(object)ActionCameraSpawner.Instance != (Object)null)) { return ""; } return ActionCameraSpawner.Instance.GuidShort; } } public int ClipCount { get { try { CameraRecording rec; return TryResolveLocalRecording(out rec) ? rec.ClipCount : 0; } catch { return 0; } } } public Camera RecordingCamera { get { ActionCameraSpawner instance = ActionCameraSpawner.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.UnityCamera != (Object)null) { return instance.UnityCamera; } if (!((Object)(object)MainCamera.instance != (Object)null)) { return null; } return MainCamera.instance.Cam; } } public static void Create() { //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)Instance != (Object)null)) { GameObject val = new GameObject("ContentWarningDoom.ActionVideoRecorder"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } public void BeginRound(float maxTime) { _recording = false; _clipsStarted = 0; _data = null; _entry = null; Status = VideoStatus.None; if (!DoomConfig.ActionModeEnabled.Value || !DoomConfig.RealVideoRecording.Value) { Plugin.Log.LogInfo((object)"[ActionVideo] real recording disabled (config) — logical tracking only."); return; } ActionCameraSpawner instance = ActionCameraSpawner.Instance; if ((Object)(object)instance == (Object)null || !instance.CreateOrBind(maxTime)) { Status = VideoStatus.Failed; Plugin.Log.LogWarning((object)$"[ActionVideo] actor={DoomNet.LocalActor} FAILED to obtain a recording camera — logical tracking only."); return; } _data = instance.Data; _entry = instance.Entry; Status = VideoStatus.CameraReady; Plugin.Log.LogInfo((object)$"[ActionVideo] actor={DoomNet.LocalActor} camera={instance.GuidShort} video= status=CameraReady hidden={instance.IsHiddenOwn}"); } public void StartNative() { if (_recording || !NativeReady || _entry.timeLeft <= 0.05f) { return; } try { PhotonView val = (((Object)(object)Player.localPlayer != (Object)null && Player.localPlayer.refs != null) ? Player.localPlayer.refs.view : null); RetrievableSingleton.Instance.StartRecording(_data, val); _recording = true; _clipsStarted++; Status = VideoStatus.Recording; Plugin.Log.LogInfo((object)$"[ActionVideo] actor={DoomNet.LocalActor} camera={CameraGuidShort} video={VideoIdShort} START clip={_clipsStarted} remaining={_entry.timeLeft:0.0}"); } catch (Exception ex) { Status = VideoStatus.Failed; Plugin.Log.LogWarning((object)("[ActionVideo] FAILED StartRecording: " + ex.Message)); } } public void StopNative() { if (!_recording) { return; } _recording = false; try { RetrievableSingleton.Instance.StopRecording(_data); Status = VideoStatus.Stopped; Plugin.Log.LogInfo((object)$"[ActionVideo] actor={DoomNet.LocalActor} video={VideoIdShort} STOP clip={_clipsStarted} clips={ClipCount} remaining={((_entry != null) ? _entry.timeLeft : (-1f)):0.0}"); } catch (Exception ex) { Status = VideoStatus.Failed; Plugin.Log.LogWarning((object)("[ActionVideo] FAILED StopRecording: " + ex.Message)); } } public void PollEncode() { if (Status == VideoStatus.Failed || Status == VideoStatus.Playable) { return; } if (!NativeReady) { if (Status != VideoStatus.None) { Status = VideoStatus.Failed; } } else { if (_recording) { return; } if (!TryResolveLocalRecording(out var rec) || rec.ClipCount == 0) { if (_clipsStarted > 0 && Status != VideoStatus.Encoding) { Status = VideoStatus.Failed; Plugin.Log.LogWarning((object)$"[ActionVideo] actor={DoomNet.LocalActor} FAILED — no CameraRecording after {_clipsStarted} start(s)."); } return; } bool flag = true; long num = 0L; foreach (Clip clip in rec.m_clips) { if (!clip.Valid) { continue; } if (clip.local && !clip.encoded) { flag = false; continue; } string text = Path.Combine(clip.GetClipDirectory(), "output.webm"); if (File.Exists(text)) { num += new FileInfo(text).Length; } } if (!flag) { if (Status != VideoStatus.Encoding) { Status = VideoStatus.Encoding; Plugin.Log.LogInfo((object)$"[ActionVideo] actor={DoomNet.LocalActor} Encoding clips={rec.ClipCount}"); } } else if (Status != VideoStatus.Ready && Status != VideoStatus.Sharing) { Status = VideoStatus.Ready; Plugin.Log.LogInfo((object)$"[ActionVideo] actor={DoomNet.LocalActor} Ready clips={rec.ClipCount} bytes={num} video={VideoIdShort}"); } } } public bool IsPlayable(out string reason) { reason = ""; if (!NativeReady) { reason = "no native recorder"; return false; } if (!TryResolveLocalRecording(out var rec)) { reason = "CameraRecording not resolvable"; return false; } if (rec.m_clips == null || rec.m_clips.Count == 0) { reason = "0 clips"; return false; } bool flag = false; foreach (Clip clip in rec.m_clips) { if (clip.Valid) { if (clip.local && !clip.encoded) { reason = "clip " + ((ClipID)(ref clip.clipID)).ToMiniString() + " not encoded"; return false; } if (!clip.local && !clip.hasBeenRecieved) { reason = "clip " + ((ClipID)(ref clip.clipID)).ToMiniString() + " not received"; return false; } string text = Path.Combine(clip.GetClipDirectory(), "output.webm"); if (File.Exists(text) && new FileInfo(text).Length > 0) { flag = true; } } } if (!flag) { reason = "no output.webm on disk"; return false; } return true; } public void MarkPlayable() { if (Status != VideoStatus.Failed) { Status = VideoStatus.Playable; } } public void MarkSharing() { if (Status == VideoStatus.Ready) { Status = VideoStatus.Sharing; } } public bool TryResolveLocalRecording(out CameraRecording rec) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) rec = null; if (_entry == null) { return false; } try { return RecordingsHandler.TryGetRecording(_entry.videoID, ref rec) && (Object)(object)rec != (Object)null; } catch { return false; } } public void EndRoundCleanup() { _recording = false; _data = null; _entry = null; } } public class CameraViewfinder : MonoBehaviour { public const int ViewmodelLayer = 31; private Camera _cam; private RenderTexture _rt; private GUIStyle _lbl; private GUIStyle _big; private Texture2D _px; public static CameraViewfinder Instance { get; private set; } public RenderTexture RT => _rt; public static CameraViewfinder Build() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) CameraViewfinder obj = (Instance = new GameObject("DoomCameraViewfinder").AddComponent()); obj.Init(); return obj; } private void Init() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown _rt = new RenderTexture(384, 216, 16) { name = "DoomViewfinderRT" }; _rt.Create(); _cam = ((Component)this).gameObject.AddComponent(); Camera val = (((Object)(object)MainCamera.instance != (Object)null) ? MainCamera.instance.Cam : null); if ((Object)(object)val != (Object)null) { _cam.CopyFrom(val); _cam.cullingMask = val.cullingMask & 0x7FFFFFFF; } else { _cam.cullingMask = int.MaxValue; _cam.fieldOfView = 68f; } _cam.targetTexture = _rt; _cam.depth = -50f; ((Component)_cam).tag = "Untagged"; ((Behaviour)_cam).enabled = true; } private void LateUpdate() { //IL_001c: 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) MainCamera instance = MainCamera.instance; if (!((Object)(object)instance == (Object)null)) { ((Component)this).transform.SetPositionAndRotation(((Component)instance).transform.position, ((Component)instance).transform.rotation); if ((Object)(object)_cam != (Object)null && (Object)(object)instance.Cam != (Object)null) { _cam.fieldOfView = instance.Cam.fieldOfView; _cam.cullingMask = instance.Cam.cullingMask & 0x7FFFFFFF; } } } private void OnGUI() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) if (Plugin.DoomModeActive && DoomConfig.ActionModeEnabled.Value && DoomConfig.ShowViewfinder.Value && !((Object)(object)_rt == (Object)null)) { if (_lbl == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 12, fontStyle = (FontStyle)1 }; val.normal.textColor = Color.white; _lbl = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 15, fontStyle = (FontStyle)1 }; val2.normal.textColor = Color.white; _big = val2; _px = new Texture2D(1, 1); _px.SetPixel(0, 0, Color.white); _px.Apply(); } float num = 256f; float num2 = 144f; float num3 = 16f; float num4 = (float)Screen.width - num - num3; float num5 = num3 + 4f; ActionCamera instance = ActionCamera.Instance; bool flag = (Object)(object)instance != (Object)null && instance.IsRecording; float num6 = (((Object)(object)instance != (Object)null) ? instance.TimeRemaining : 0f); float num7 = (((Object)(object)instance != (Object)null && instance.MaxTime > 0f) ? instance.MaxTime : DoomConfig.RecordingTime.Value); bool flag2 = ActionRoundManager.Phase == ActionRoundPhase.Action; bool num8 = (Object)(object)instance != (Object)null && instance.OutOfFilm; Fill(new Rect(num4 - 3f, num5 - 3f, num + 6f, num2 + 24f), new Color(0f, 0f, 0f, 0.55f)); GUI.DrawTexture(new Rect(num4, num5, num, num2), (Texture)(object)_rt, (ScaleMode)2, false); Fill(new Rect(num4, num5 + num2, num, 2f), new Color(1f, 1f, 1f, 0.25f)); string text = (num8 ? "FILM OUT" : (flag ? "REC" : (flag2 ? "STANDBY" : "OFFLINE"))); Color c = (num8 ? new Color(0.6f, 0.6f, 0.6f) : ((!flag) ? new Color(0.75f, 0.75f, 0.2f) : ((Mathf.Sin(Time.time * 8f) > 0f) ? new Color(1f, 0.15f, 0.15f) : new Color(0.5f, 0.05f, 0.05f)))); Fill(new Rect(num4 + 6f, num5 + 6f, 10f, 10f), c); GUI.Label(new Rect(num4 + 22f, num5 + 2f, 120f, 18f), text, _big); int num9 = Mathf.FloorToInt(Mathf.Max(0f, num6) / 60f); int num10 = Mathf.FloorToInt(Mathf.Max(0f, num6) % 60f); GUI.Label(new Rect(num4 + num - 70f, num5 + 3f, 70f, 18f), $"{num9:00}:{num10:00}", _lbl); float num11 = ((num7 > 0f) ? Mathf.Clamp01(num6 / num7) : 0f); Fill(new Rect(num4, num5 + num2 + 6f, num, 6f), new Color(0f, 0f, 0f, 0.6f)); Fill(new Rect(num4, num5 + num2 + 6f, num * num11, 6f), flag ? new Color(1f, 0.3f, 0.3f) : new Color(0.9f, 0.8f, 0.35f)); GUI.Label(new Rect(num4, num5 + num2 + 12f, num, 16f), string.Format("FILM {0}% {1}", Mathf.CeilToInt(num11 * 100f), flag ? "hold RMB — recording" : "hold RMB to record"), _lbl); } } private void Fill(Rect r, Color c) { //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_000b: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = c; GUI.DrawTexture(r, (Texture)(object)_px); GUI.color = color; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } if ((Object)(object)_cam != (Object)null) { _cam.targetTexture = null; } if ((Object)(object)_rt != (Object)null) { _rt.Release(); Object.Destroy((Object)(object)_rt); } } } public class CameraViewmodel : MonoBehaviour { private Transform _model; private Transform _grip; private Renderer _screen; private Material _screenMat; private Vector3 _restPos; private Vector3 _aimPos; private Quaternion _restRot; private Quaternion _aimRot; private float _raise; private float _bob; private bool _handAttached; public Transform ParentedTo => ((Component)this).transform.parent; public static CameraViewmodel Build(Transform parent, bool handAttached) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DoomCameraViewmodel"); val.transform.SetParent(parent, false); CameraViewmodel cameraViewmodel = val.AddComponent(); cameraViewmodel._handAttached = handAttached; cameraViewmodel.Construct(); return cameraViewmodel; } private void Construct() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) _model = new GameObject("model").transform; _model.SetParent(((Component)this).transform, false); if (_handAttached) { _restPos = ParseVec(DoomConfig.HandCameraOffset.Value); _restRot = Quaternion.Euler(ParseVec(DoomConfig.HandCameraEuler.Value)); _aimPos = _restPos; _aimRot = _restRot; } else { _restPos = new Vector3(-0.17f, -0.12f, 0.4f); _restRot = Quaternion.Euler(4f, 12f, -3f); _aimPos = new Vector3(-0.11f, -0.07f, 0.34f); _aimRot = Quaternion.Euler(0f, 6f, 0f); } ((Component)this).transform.localPosition = _restPos; ((Component)this).transform.localRotation = _restRot; if (!TryBuildFromGameMesh()) { BuildPrimitive(); } FinishCommon(); if (!_handAttached && DoomConfig.ShowViewmodelArms.Value) { _grip = new GameObject("gripL").transform; _grip.SetParent(((Component)this).transform, false); _grip.localPosition = ParseVec(DoomConfig.LeftGripOffset.Value); _grip.localRotation = Quaternion.Euler(ParseVec(DoomConfig.LeftGripEuler.Value)); HeldItemPose.LeftGrip = _grip; } } private void OnDestroy() { if ((Object)(object)_grip != (Object)null && (Object)(object)HeldItemPose.LeftGrip == (Object)(object)_grip) { HeldItemPose.LeftGrip = null; } } private void FinishCommon() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown if ((Object)(object)_screen == (Object)null) { GameObject val = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)val).name = "screen"; val.transform.SetParent(_model, false); val.transform.localPosition = new Vector3(-0.085f, 0.03f, 0f); val.transform.localRotation = Quaternion.Euler(0f, -110f, 0f); val.transform.localScale = new Vector3(0.09f, 0.055f, 1f); _screen = val.GetComponent(); Shader val2 = Shader.Find("Unlit/Texture") ?? Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard"); _screenMat = new Material(val2) { color = Color.black }; _screen.material = _screenMat; _screen.shadowCastingMode = (ShadowCastingMode)0; } Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } WeaponVisual.SetLayer(((Component)this).gameObject, 31); } private bool TryBuildFromGameMesh() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) try { Item val = ActionCameraSpawner.FindCameraItemPublic(); if ((Object)(object)val == (Object)null || (Object)(object)val.itemObject == (Object)null) { return false; } GameObject val2 = Object.Instantiate(val.itemObject); ((Object)val2).hideFlags = (HideFlags)61; val2.SetActive(false); GameObject val3 = new GameObject("cameraMesh"); val3.transform.SetParent(_model, false); Bounds val4 = default(Bounds); bool flag = false; MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren(true); Bounds val8 = default(Bounds); foreach (MeshRenderer val5 in componentsInChildren) { MeshFilter component = ((Component)val5).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null)) { GameObject val6 = new GameObject(((Object)val5).name); val6.transform.SetParent(val3.transform, false); val6.transform.localPosition = val2.transform.InverseTransformPoint(((Component)val5).transform.position); val6.transform.localRotation = Quaternion.Inverse(val2.transform.rotation) * ((Component)val5).transform.rotation; val6.transform.localScale = ((Component)val5).transform.lossyScale; val6.AddComponent().sharedMesh = component.sharedMesh; MeshRenderer obj = val6.AddComponent(); ((Renderer)obj).sharedMaterials = ((Renderer)val5).sharedMaterials; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; Vector3 localScale = val6.transform.localScale; Bounds bounds = component.sharedMesh.bounds; Vector3 val7 = Vector3.Scale(((Bounds)(ref bounds)).size, localScale); ((Bounds)(ref val8))..ctor(val6.transform.localPosition + Vector3.Scale(((Bounds)(ref bounds)).center, localScale), val7); if (!flag) { val4 = val8; flag = true; } else { ((Bounds)(ref val4)).Encapsulate(val8); } } } Object.Destroy((Object)(object)val2); if (!flag) { Object.Destroy((Object)(object)val3); return false; } float num = Mathf.Max(((Bounds)(ref val4)).size.x, Mathf.Max(((Bounds)(ref val4)).size.y, ((Bounds)(ref val4)).size.z)); if (num < 0.0001f) { num = 1f; } float num2 = 0.2f / num; val3.transform.localScale = Vector3.one * num2; val3.transform.localRotation = Quaternion.Euler(ParseVec(DoomConfig.CameraModelEuler.Value)); val3.transform.localPosition = Vector3.zero; Plugin.LogWeapon($"camcorder: using real game camera mesh from item '{((Object)val).name}' (scale {num2:0.000})"); return true; } catch (Exception ex) { Plugin.LogWeapon("camcorder: game-mesh build failed (" + ex.Message + ") — using primitive"); return false; } } private void BuildPrimitive() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) Color val = default(Color); ((Color)(ref val))..ctor(0.12f, 0.12f, 0.14f); Box(_model, new Vector3(0.12f, 0.09f, 0.16f), new Vector3(0f, 0f, 0f), val); Box(_model, new Vector3(0.055f, 0.11f, 0.06f), new Vector3(0f, -0.09f, -0.02f), val * 0.8f).localRotation = Quaternion.Euler(12f, 0f, 0f); Cyl(_model, 0.032f, 0.07f, new Vector3(0f, 0.01f, 0.11f), new Color(0.05f, 0.05f, 0.06f)); Cyl(_model, 0.026f, 0.012f, new Vector3(0f, 0.01f, 0.15f), new Color(0.15f, 0.35f, 0.55f)); Box(_model, new Vector3(0.07f, 0.045f, 0.006f), new Vector3(0.085f, 0.02f, 0f), new Color(0.02f, 0.02f, 0.03f)).localRotation = Quaternion.Euler(0f, 25f, 0f); } private void LateUpdate() { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)ActionCamera.Instance != (Object)null && ActionCamera.Instance.IsRecording; _raise = Mathf.MoveTowards(_raise, flag ? 1f : 0f, Time.deltaTime * 5f); _bob += Time.deltaTime * (flag ? 6f : 1.4f); float num = (_handAttached ? 0.15f : 1f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Mathf.Sin(_bob) * 0.004f * num, Mathf.Cos(_bob * 1.3f) * 0.003f * num, 0f); ((Component)this).transform.localPosition = Vector3.Lerp(((Component)this).transform.localPosition, Vector3.Lerp(_restPos, _aimPos, _raise) + val, Time.deltaTime * 12f); ((Component)this).transform.localRotation = Quaternion.Slerp(((Component)this).transform.localRotation, Quaternion.Slerp(_restRot, _aimRot, _raise), Time.deltaTime * 12f); if ((Object)(object)_screenMat != (Object)null) { RenderTexture val2 = (((Object)(object)CameraViewfinder.Instance != (Object)null) ? CameraViewfinder.Instance.RT : null); if ((Object)(object)_screenMat.mainTexture != (Object)(object)val2) { _screenMat.mainTexture = (Texture)(object)val2; } float num2 = ((!flag) ? 0f : ((Mathf.Sin(Time.time * 9f) > 0f) ? 0.35f : 0.12f)); _screenMat.color = (((Object)(object)val2 != (Object)null) ? Color.Lerp(Color.white, new Color(1f, 0.35f, 0.35f), num2) : Color.black); } } private static Vector3 ParseVec(string s) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(s)) { return Vector3.zero; } string[] array = s.Split(','); if (array.Length != 3) { return Vector3.zero; } CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (float.TryParse(array[0], NumberStyles.Float, invariantCulture, out var result) && float.TryParse(array[1], NumberStyles.Float, invariantCulture, out var result2) && float.TryParse(array[2], NumberStyles.Float, invariantCulture, out var result3)) { return new Vector3(result, result2, result3); } return Vector3.zero; } private static Transform Box(Transform p, Vector3 size, Vector3 pos, Color c) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3); obj.transform.SetParent(p, false); obj.transform.localPosition = pos; obj.transform.localScale = size; Paint(obj, c); return obj.transform; } private static Transform Cyl(Transform p, float r, float len, Vector3 pos, Color c) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)2); obj.transform.SetParent(p, false); obj.transform.localPosition = pos; obj.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); obj.transform.localScale = new Vector3(r * 2f, len, r * 2f); Paint(obj, c); return obj.transform; } private static void Paint(GameObject g, Color c) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown MeshRenderer component = g.GetComponent(); Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"); ((Renderer)component).material = new Material(val) { color = c }; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; } } public static class MonsterHitZoneResolver { private static readonly string[] HeadNames = new string[6] { "head", "skull", "cranium", "neck", "jaw", "face" }; public static HitZone Resolve(MonsterHealth h, Collider col, Vector3 hitPoint) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if (h == null || (Object)(object)h.Root == (Object)null) { return HitZone.Other; } Bodypart val = CwRagdollApi.BodypartFromCollider(h.Ragdoll, col); if ((Object)(object)val != (Object)null) { if ((int)val.bodypartType != 4) { return HitZone.Body; } return HitZone.Head; } bool flag = false; if ((Object)(object)col != (Object)null) { Transform val2 = ((Component)col).transform; int num = 0; while (num < 6 && (Object)(object)val2 != (Object)null) { string text = ((Object)val2).name.ToLowerInvariant(); string[] headNames = HeadNames; foreach (string value in headNames) { if (text.Contains(value)) { flag = true; break; } } if (flag) { break; } num++; val2 = val2.parent; } } Bounds val3 = WorldBounds(h.Root); float num2 = ((((Bounds)(ref val3)).size.y > 0.01f) ? Mathf.InverseLerp(((Bounds)(ref val3)).min.y, ((Bounds)(ref val3)).max.y, hitPoint.y) : 0.5f); bool flag2 = num2 >= 1f - Mathf.Clamp01(DoomConfig.HeadTopFraction.Value); if (flag && num2 > 0.4f) { return HitZone.Head; } if (flag2) { return HitZone.Head; } return HitZone.Body; } private static Bounds WorldBounds(GameObject root) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = root.GetComponentsInChildren(); if (componentsInChildren.Length == 0) { return new Bounds(root.transform.position + Vector3.up, Vector3.one * 2f); } Bounds bounds = componentsInChildren[0].bounds; for (int i = 1; i < componentsInChildren.Length; i++) { ((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds); } return bounds; } } }