using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AK; using Agents; using BepInEx; using BepInEx.Unity.IL2CPP; using EOSExt.EMP.Definition; using EOSExt.EMP.EMPComponent; using EOSExt.EMP.Impl; using EOSExt.EMP.Impl.Handlers; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using FloLib.Networks.Replications; using GTFO.API; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Inas07.EOSExt.EMP")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.EOSExt.EMP")] [assembly: AssemblyTitle("Inas07.EOSExt.EMP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 EOSExt.EMP { public class EMPManager : GenericExpeditionDefinitionManager { public struct pEMPState { public uint pEMPIndex; public bool enabled; public pEMPState() { pEMPIndex = 0u; enabled = false; } public pEMPState(pEMPState o) { pEMPIndex = 0u; enabled = false; o.pEMPIndex = pEMPIndex; o.enabled = enabled; } } private readonly Dictionary _pEMPs = new Dictionary(); public IEnumerable pEMPs => _pEMPs.Values; protected override string DEFINITION_NAME => "PersistentEMP"; private List _empTargets { get; } = new List(); private List _activeEMPShock { get; } = new List(); public static EMPManager Current { get; private set; } public PlayerAgent LocalPlayerAgent { get; private set; } public IEnumerable EMPTargets => _empTargets; internal void SetupHUDAndFlashlight() { if ((Object)(object)LocalPlayerAgent == (Object)null) { EOSLogger.Error($"{"SetupHUDAndFlashlight": LocalPlayerAgent is not set!}"); } else if (!((Object)(object)((Component)LocalPlayerAgent).gameObject.GetComponent() != (Object)null)) { ((Component)LocalPlayerAgent).gameObject.AddComponent().AssignHandler(new EMPPlayerHudHandler()); ((Component)LocalPlayerAgent).gameObject.AddComponent().AssignHandler(new EMPPlayerFlashLightHandler()); EOSLogger.Log("pEMP: PlayerHUD & flashlight setup completed"); } } internal void SetupAmmoWeaponHandlers(InventorySlot slot) { //IL_0000: 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_0004: Invalid comparison between Unknown and I4 //IL_0006: 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) if (slot - 1 <= 1) { SetupAmmoWeaponHandlerForSlot(slot); EOSLogger.Log($"pEMP: Backpack {slot} setup completed"); } static void SetupAmmoWeaponHandlerForSlot(InventorySlot slot) { //IL_0005: 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) BackpackItem val = default(BackpackItem); if (PlayerBackpackManager.LocalBackpack.TryGetBackpackItem(slot, ref val)) { if (!((Object)(object)((Component)val.Instance).gameObject.GetComponent() != (Object)null)) { ((Component)val.Instance).gameObject.AddComponent().AssignHandler(new EMPGunSightHandler()); } } else { EOSLogger.Warning($"Couldn't get item for slot {slot}!"); } } } internal void SetupToolHandler() { BackpackItem val = default(BackpackItem); if (PlayerBackpackManager.LocalBackpack.TryGetBackpackItem((InventorySlot)3, ref val)) { if (!((Object)(object)((Component)val.Instance).gameObject.GetComponent() != (Object)null) && (Object)(object)((Component)val.Instance).GetComponent() != (Object)null) { ((Component)val.Instance).gameObject.AddComponent().AssignHandler(new EMPBioTrackerHandler()); EOSLogger.Warning($"pEMP: Backpack {3} setup completed"); } } else { EOSLogger.Warning($"Couldn't get item for slot {3}!"); } } public void TogglepEMPState(uint pEMPIndex, bool enabled) { if (!_pEMPs.ContainsKey(pEMPIndex)) { EOSLogger.Error($"TogglepEMPState: pEMPIndex {pEMPIndex} not defined"); } else { ActiveState newState = (enabled ? ActiveState.ENABLED : ActiveState.DISABLED); _pEMPs[pEMPIndex].ChangeState(newState); } } public void TogglepEMPState(WardenObjectiveEventData e) { uint count = (uint)e.Count; bool enabled = e.Enabled; TogglepEMPState(count, enabled); } private void pEMPInit() { LevelAPI.OnBuildStart += delegate { pEMPClear(); InitializepEMPs(); }; LevelAPI.OnLevelCleanup += pEMPClear; } private void pEMPClear() { _pEMPs.Clear(); } private void InitializepEMPs() { if (!base.definitions.ContainsKey(base.CurrentMainLevelLayout)) { return; } GenericExpeditionDefinition val = base.definitions[base.CurrentMainLevelLayout]; if (val == null || val.Definitions.Count < 1) { return; } foreach (pEMPDefinition definition in val.Definitions) { pEMP pEMP = new pEMP(definition); _pEMPs[definition.pEMPIndex] = pEMP; uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { EOSLogger.Error("SetuppEMPReplicators: replicator ID depleted, cannot set up!"); } else { pEMP.SetupReplicator(num); EOSLogger.Debug($"SetuppEMPReplicators: replicator_{num} setup! "); } EOSLogger.Warning($"pEMP_{definition.pEMPIndex} initialized"); } } internal void SetLocalPlayerAgent(PlayerAgent localPlayerAgent) { LocalPlayerAgent = localPlayerAgent; PlayerpEMPComponent.Current = ((Component)localPlayerAgent).gameObject.AddComponent(); PlayerpEMPComponent.Current.player = localPlayerAgent; EOSLogger.Debug("LocalPlayerAgent setup completed"); } internal void OnLocalPlayerAgentDestroy() { PlayerpEMPComponent.Current = null; EOSLogger.Debug("LocalPlayerAgent Destroyed"); } public void AddTarget(EMPController target) { _empTargets.Add(target); } public void RemoveTarget(EMPController target) { _empTargets.Remove(target); } public void ActivateEMPShock(Vector3 position, float range, float duration) { //IL_0018: 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_003d: Unknown result type (might be due to invalid IL or missing references) if (!GameStateManager.IsInExpedition) { EOSLogger.Error("Tried to activate an EMP when not in level, this shouldn't happen!"); return; } _activeEMPShock.Add(new EMPShock(position, range, duration)); foreach (EMPController empTarget in _empTargets) { if (Vector3.Distance(position, empTarget.Position) < range) { empTarget.AddTime(duration); } } } public float DurationFromPosition(Vector3 position) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) _activeEMPShock.RemoveAll((EMPShock e) => Mathf.Round(e.RemainingTime) <= 0f); float num = 0f; foreach (EMPShock item in _activeEMPShock) { if (item.InRange(position)) { num += item.RemainingTime; } } return num; } private void Clear() { _empTargets.Clear(); _activeEMPShock.Clear(); EMPHandler.Cleanup(); } public override void Init() { EMPWardenEvents.Init(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; Events.InventoryWielded = (Action)Delegate.Combine(Events.InventoryWielded, new Action(SetupAmmoWeaponHandlers)); pEMPInit(); } private EMPManager() { } static EMPManager() { Current = new EMPManager(); ClassInjector.RegisterTypeInIl2Cpp(); ClassInjector.RegisterTypeInIl2Cpp(); } } internal static class EMPWardenEvents { public enum EMPEvents { Instant_Shock = 300, Toggle_PEMP_State } internal static void InstantShock(WardenObjectiveEventData e) { //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_001a: Unknown result type (might be due to invalid IL or missing references) Vector3 position = e.Position; float fogTransitionDuration = e.FogTransitionDuration; float duration = e.Duration; EMPManager.Current.ActivateEMPShock(position, fogTransitionDuration, duration); } internal static void TogglepEMPState(WardenObjectiveEventData e) { EMPManager.Current.TogglepEMPState(e); } internal static void Init() { EOSWardenEventManager.Current.AddEventDefinition(EMPEvents.Instant_Shock.ToString(), 300u, (Action)InstantShock); EOSWardenEventManager.Current.AddEventDefinition(EMPEvents.Toggle_PEMP_State.ToString(), 301u, (Action)TogglepEMPState); } } public static class Events { public static Action FlashLightWielded; public static Action InventoryWielded; public static Action EnterGSInLevel; } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.EOSExt.EMP", "EOSExt.EMP", "1.0.4")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.EMP"; public const string VERSION = "1.0.4"; private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("EOSExt.EMP"); m_Harmony.PatchAll(); SetupManagers(); } private void SetupManagers() { ((GenericExpeditionDefinitionManager)EMPManager.Current).Init(); } } } namespace EOSExt.EMP.Patches { [HarmonyPatch(typeof(EnemyScanner))] internal static class Inject_EnemyScanner { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("UpdateDetectedEnemies")] internal static bool Pre_UpdateDetectedEnemies() { return !EMPHandler.IsLocalPlayerDisabled; } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("UpdateTagProgress")] internal static bool Pre_UpdateTagProgress(EnemyScanner __instance) { //IL_0061: 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) if (EMPHandler.IsLocalPlayerDisabled) { ((ItemEquippable)__instance).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true); __instance.m_screen.SetStatusText("ERROR"); ((ProgressBarBase)__instance.m_progressBar).SetProgress(1f); __instance.m_screen.SetGuixColor(Color.yellow); return false; } __instance.m_screen.SetStatusText("Ready to tag"); __instance.m_screen.SetGuixColor(Color.red); return true; } } [HarmonyPatch(typeof(LG_Light))] internal static class Inject_LG_Light { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("Start")] internal static void Pre_Start(LG_Light __instance) { ((Component)__instance).gameObject.AddComponent().AssignHandler(new EMPLightHandler()); } } [HarmonyPatch(typeof(PlayerAgent))] internal static class Inject_PlayerAgent { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch("Setup")] internal static void Post_Setup(PlayerAgent __instance) { if (((Agent)__instance).IsLocallyOwned) { EMPManager.Current.SetLocalPlayerAgent(__instance); } } } [HarmonyPatch(typeof(PlayerGuiLayer))] internal static class Inject_PlayerGuiLayer { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("UpdateGUIElementsVisibility")] internal static bool Pre_UpdateGUIElementsVisibility() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 if (EMPHandler.IsLocalPlayerDisabled) { foreach (EMPPlayerHudHandler handler in EMPPlayerHudHandler.Handlers) { handler.ForceState(EMPState.Off); } return false; } if ((int)GameStateManager.CurrentStateName == 10) { foreach (EMPPlayerHudHandler handler2 in EMPPlayerHudHandler.Handlers) { handler2.ForceState(EMPState.On); } } return true; } } [HarmonyPatch] internal static class Inject_Events { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerInventoryBase), "OnItemEquippableFlashlightWielded")] internal static void Post_OnItemEquippableFlashlightWielded(GearPartFlashlight flashlight) { Events.FlashLightWielded?.Invoke(flashlight); } [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerInventoryLocal), "DoWieldItem")] internal static void Post_DoWieldItem(PlayerInventoryLocal __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) Events.InventoryWielded?.Invoke(((PlayerInventoryBase)__instance).WieldedSlot); } [HarmonyPostfix] [HarmonyPatch(typeof(GS_InLevel), "Enter")] private static void Post_SetupGear(GS_InLevel __instance) { Events.EnterGSInLevel?.Invoke(); } } [HarmonyPatch(typeof(PlayerSync))] internal static class Inject_PlayerSync { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("WantsToSetFlashlightEnabled")] internal static bool Pre_WantsToSetFlashlightEnabled(PlayerSync __instance, bool enable) { if (EMPHandler.IsLocalPlayerDisabled) { return false; } if (enable != __instance.m_agent.Inventory.FlashlightEnabled) { return true; } __instance.WantsToSetFlashlightEnabled(!__instance.m_agent.Inventory.FlashlightEnabled, false); return false; } } [HarmonyPatch(typeof(SentryGunFirstPerson))] internal static class Inject_SentryGunFirstPerson { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("CheckCanPlace")] internal static bool Pre_CheckCanPlace(ref bool __result) { if (!EMPHandler.IsLocalPlayerDisabled) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(SentryGunInstance))] internal static class Inject_SentryGunInstance { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch("Setup")] internal static void Post_Setup(SentryGunInstance __instance) { ((Component)__instance).gameObject.AddComponent().AssignHandler(new EMPSentryHandler()); } } } namespace EOSExt.EMP.Definition { public class ItemToDisable { public bool BioTracker { get; set; } = true; public bool PlayerHUD { get; set; } = true; public bool PlayerFlashLight { get; set; } = true; public bool EnvLight { get; set; } = true; public bool GunSight { get; set; } = true; public bool Sentry { get; set; } = true; } public class pEMPDefinition { public uint pEMPIndex { get; set; } public Vec3 Position { get; set; } = new Vec3(); public float Range { get; set; } public ItemToDisable ItemToDisable { get; set; } = new ItemToDisable(); public pEMPDefinition() { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown public pEMPDefinition(pEMPDefinition other) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0066: Expected O, but got Unknown pEMPIndex = other.pEMPIndex; Position = new Vec3 { x = other.Position.x, y = other.Position.y, z = other.Position.z }; Range = other.Range; ItemToDisable = new ItemToDisable { BioTracker = other.ItemToDisable.BioTracker, PlayerHUD = other.ItemToDisable.PlayerHUD, PlayerFlashLight = other.ItemToDisable.PlayerFlashLight, EnvLight = other.ItemToDisable.EnvLight, GunSight = other.ItemToDisable.GunSight, Sentry = other.ItemToDisable.Sentry }; } } } namespace EOSExt.EMP.EMPComponent { public class PlayerpEMPComponent : MonoBehaviour { private float nextUpdateTime = float.NaN; public const float UPDATE_INTERVAL = 0.2f; public static PlayerpEMPComponent Current { get; internal set; } public bool InAnypEMP { get; private set; } public PlayerAgent player { get; internal set; } private void CheckSetup() { if (!((Object)(object)EMPManager.Current.LocalPlayerAgent == (Object)null)) { EMPManager.Current.SetupHUDAndFlashlight(); EMPManager.Current.SetupToolHandler(); } } private void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10 || (!float.IsNaN(nextUpdateTime) && Clock.Time < nextUpdateTime)) { return; } nextUpdateTime = Clock.Time + 0.2f; CheckSetup(); if ((Object)(object)player == (Object)null) { return; } ItemToDisable itemToDisable = new ItemToDisable { BioTracker = false, PlayerFlashLight = false, PlayerHUD = false, EnvLight = false, GunSight = false, Sentry = false }; InAnypEMP = false; foreach (pEMP pEMP in EMPManager.Current.pEMPs) { if (pEMP.State == ActiveState.ENABLED && pEMP.InRange(((Agent)player).Position)) { itemToDisable.BioTracker = itemToDisable.BioTracker || pEMP.ItemToDisable.BioTracker; itemToDisable.PlayerFlashLight = itemToDisable.PlayerFlashLight || pEMP.ItemToDisable.PlayerFlashLight; itemToDisable.PlayerHUD = itemToDisable.PlayerHUD || pEMP.ItemToDisable.PlayerHUD; itemToDisable.GunSight = itemToDisable.GunSight || pEMP.ItemToDisable.GunSight; itemToDisable.Sentry = itemToDisable.Sentry || pEMP.ItemToDisable.Sentry; InAnypEMP = true; } } if (itemToDisable.BioTracker) { foreach (EMPBioTrackerHandler handler in EMPBioTrackerHandler.Handlers) { handler?.controller?.AddTime(float.PositiveInfinity); } } else { foreach (EMPBioTrackerHandler handler2 in EMPBioTrackerHandler.Handlers) { handler2?.controller?.ClearTime(); } } if (itemToDisable.PlayerFlashLight) { foreach (EMPPlayerFlashLightHandler handler3 in EMPPlayerFlashLightHandler.Handlers) { handler3?.controller?.AddTime(float.PositiveInfinity); } } else { foreach (EMPPlayerFlashLightHandler handler4 in EMPPlayerFlashLightHandler.Handlers) { handler4?.controller?.ClearTime(); } } if (itemToDisable.PlayerHUD) { foreach (EMPPlayerHudHandler handler5 in EMPPlayerHudHandler.Handlers) { handler5?.controller?.AddTime(float.PositiveInfinity); } } else { foreach (EMPPlayerHudHandler handler6 in EMPPlayerHudHandler.Handlers) { handler6?.controller?.ClearTime(); } } if (itemToDisable.GunSight) { foreach (EMPGunSightHandler handler7 in EMPGunSightHandler.Handlers) { handler7?.controller?.AddTime(float.PositiveInfinity); } } else { foreach (EMPGunSightHandler handler8 in EMPGunSightHandler.Handlers) { handler8?.controller?.ClearTime(); } } if (itemToDisable.Sentry) { foreach (EMPSentryHandler handler9 in EMPSentryHandler.Handlers) { handler9?.controller?.AddTime(float.PositiveInfinity); } return; } foreach (EMPSentryHandler handler10 in EMPSentryHandler.Handlers) { handler10?.controller?.ClearTime(); } } private void OnDestroy() { EMPManager.Current.OnLocalPlayerAgentDestroy(); player = null; } static PlayerpEMPComponent() { } } } namespace EOSExt.EMP.Impl { public sealed class EMPController : MonoBehaviour { private bool _hasHandler; private bool _setup; public EMPHandler Handler { get; private set; } public float endTime { get; private set; } [HideFromIl2Cpp] private bool IsEMPActive => endTime > Clock.Time; [HideFromIl2Cpp] public Vector3 Position => ((Component)this).transform.position; private void Awake() { EMPManager.Current.AddTarget(this); } private void OnEnable() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)GameStateManager.CurrentStateName == 10 && _setup) { if (endTime > Clock.Time) { Handler.ForceState(EMPState.Off); } else { Handler.ForceState(EMPState.On); } } } private void Update() { if (_hasHandler) { Handler.Tick(IsEMPActive); } } [HideFromIl2Cpp] public void AddTime(float time) { endTime = Clock.Time + time; } [HideFromIl2Cpp] public void ClearTime() { endTime = Clock.Time - 1f; } [HideFromIl2Cpp] public void AssignHandler(EMPHandler handler) { if (Handler != null) { EOSLogger.Warning("Tried to assign a handler to a controller that already had one!"); return; } Handler = handler; Handler.Setup(((Component)this).gameObject, this); _hasHandler = true; _setup = true; } [HideFromIl2Cpp] public void ForceState(EMPState state) { if (Handler != null) { Handler.ForceState(state); } } private void OnDestroy() { EMPManager.Current.RemoveTarget(this); Handler.OnDespawn(); Handler = null; } } public abstract class EMPHandler { protected enum DeviceState { On, Off, Unknown } protected DeviceState _deviceState; protected float _stateTimer; private static bool _isLocalPlayerDisabled; private float _delayTimer; private bool _destroyed; protected static Random _rand = new Random(); public EMPState State { get; protected set; } public EMPController controller { get; protected set; } public GameObject gameObject { get; protected set; } public static bool IsLocalPlayerDisabled { get { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if (_isLocalPlayerDisabled) { return (int)GameStateManager.CurrentStateName == 10; } return false; } } protected virtual float FlickerDuration => 0.2f; protected virtual float MinDelay => 0f; protected virtual float MaxDelay => 1.5f; protected virtual bool IsDeviceOnPlayer => false; public virtual void Setup(GameObject gameObject, EMPController controller) { this.gameObject = gameObject; this.controller = controller; } public static void Cleanup() { _isLocalPlayerDisabled = false; } public void ForceState(EMPState state) { if (State != state) { State = state; _delayTimer = Clock.Time - 1f; _stateTimer = Clock.Time - 1f; switch (state) { case EMPState.Off: _deviceState = DeviceState.Off; DeviceOff(); break; default: _deviceState = DeviceState.Unknown; break; case EMPState.On: _deviceState = DeviceState.On; DeviceOn(); break; } } } public void Tick(bool isEMPD) { if (_destroyed) { return; } if (isEMPD && State == EMPState.On) { float randomDelay = GetRandomDelay(MinDelay, MaxDelay); State = EMPState.FlickerOff; _delayTimer = Clock.Time + randomDelay; _stateTimer = Clock.Time + FlickerDuration + randomDelay; } if (!isEMPD && State == EMPState.Off) { float randomDelay2 = GetRandomDelay(0f, 1.5f); State = EMPState.FlickerOn; _delayTimer = Clock.Time + randomDelay2; _stateTimer = Clock.Time + FlickerDuration + randomDelay2; } switch (State) { case EMPState.On: if (_deviceState != 0) { DeviceOn(); _deviceState = DeviceState.On; if (IsDeviceOnPlayer) { _isLocalPlayerDisabled = false; } } break; case EMPState.FlickerOff: if (!(_delayTimer > Clock.Time)) { if (Clock.Time < _stateTimer) { FlickerDevice(); } else { State = EMPState.Off; } } break; case EMPState.Off: if (_deviceState != DeviceState.Off) { DeviceOff(); _deviceState = DeviceState.Off; if (IsDeviceOnPlayer) { _isLocalPlayerDisabled = true; } } break; case EMPState.FlickerOn: if (!(_delayTimer > Clock.Time)) { if (Clock.Time < _stateTimer) { FlickerDevice(); } else { State = EMPState.On; } } break; } } public void OnDespawn() { _destroyed = true; } protected abstract void FlickerDevice(); protected abstract void DeviceOn(); protected abstract void DeviceOff(); protected static float GetRandomDelay(float min, float max) { return (float)((double)min + _rand.NextDouble() * (double)(max - min)); } protected static float GetRandom01() { return (float)_rand.NextDouble(); } protected static int GetRandomRange(int min, int maxPlusOne) { return _rand.Next(min, maxPlusOne); } protected static int Index(int length) { return _rand.Next(0, length); } protected static bool FlickerUtil(int oneInX = 2) { return Index(oneInX) == 0; } } public class EMPShock { public Vector3 position { get; internal set; } public float range { get; internal set; } public float endTime { get; internal set; } public float RemainingTime => endTime - Clock.Time; public EMPShock(Vector3 position, float range, float duration) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) this.position = position; this.range = range; endTime = Clock.Time + duration; } public bool InRange(Vector3 position) { //IL_0000: 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) return Vector3.Distance(position, this.position) < range; } } public enum EMPState { On, FlickerOff, Off, FlickerOn } public enum ActiveState { DISABLED, ENABLED } public struct pEMPState { public ActiveState status; public pEMPState() { status = ActiveState.DISABLED; } public pEMPState(ActiveState status) { this.status = status; } public pEMPState(pEMPState o) { status = o.status; } } public class pEMP : EMPShock { public readonly ItemToDisable DISABLE_NOTHING = new ItemToDisable { BioTracker = false, PlayerFlashLight = false, PlayerHUD = false, Sentry = false, EnvLight = false, GunSight = false }; public pEMPDefinition def { get; private set; } public StateReplicator StateReplicator { get; private set; } public ActiveState State { get { if (StateReplicator == null) { return ActiveState.DISABLED; } return StateReplicator.State.status; } } public ItemToDisable ItemToDisable { get { if (def == null) { return DISABLE_NOTHING; } return def.ItemToDisable; } } public void OnStateChanged(pEMPState oldState, pEMPState newState, bool isRecall) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (def == null || oldState.status == newState.status) { return; } EOSLogger.Debug($"pEMP_{def.pEMPIndex} Change state: {oldState.status} -> {newState.status}"); switch (newState.status) { case ActiveState.DISABLED: base.endTime = float.NegativeInfinity; break; case ActiveState.ENABLED: base.endTime = float.PositiveInfinity; break; default: throw new NotImplementedException(); } foreach (EMPController eMPTarget in EMPManager.Current.EMPTargets) { if ((Object)(object)((Component)eMPTarget).GetComponent() == (Object)null) { continue; } switch (newState.status) { case ActiveState.DISABLED: eMPTarget.ClearTime(); break; case ActiveState.ENABLED: if (InRange(eMPTarget.Position)) { eMPTarget.AddTime(float.PositiveInfinity); } else { eMPTarget.ClearTime(); } break; default: throw new NotImplementedException(); } } } public void ChangeState(ActiveState newState) { StateReplicator?.SetState(new pEMPState { status = newState }); } internal void SetupReplicator(uint replicatorID) { StateReplicator = StateReplicator.Create(replicatorID, new pEMPState { status = ActiveState.DISABLED }, (LifeTimeType)1, (IStateReplicatorHolder)null); StateReplicator.OnStateChanged += OnStateChanged; } public pEMP(pEMPDefinition def) : base(def.Position.ToVector3(), def.Range, float.NegativeInfinity) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) this.def = new pEMPDefinition(def); } internal void Destroy() { StateReplicator = null; def = null; } } } namespace EOSExt.EMP.Impl.Handlers { public class EMPBioTrackerHandler : EMPHandler { private static List handlers; private EnemyScanner _scanner; public static IEnumerable Handlers => handlers; private static void Clear() { handlers.Clear(); } static EMPBioTrackerHandler() { handlers = new List(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); _scanner = gameObject.GetComponent(); if ((Object)(object)_scanner == (Object)null) { EOSLogger.Error("Couldn't get bio-tracker component!"); } handlers.Add(this); } protected override void DeviceOff() { ((ItemEquippable)_scanner).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true); _scanner.m_graphics.m_display.enabled = false; } protected override void DeviceOn() { _scanner.m_graphics.m_display.enabled = true; } protected override void FlickerDevice() { ((Behaviour)_scanner).enabled = EMPHandler.FlickerUtil(); } } public class EMPGunSightHandler : EMPHandler { private static List handlers; public GameObject[] _sightPictures; public static IEnumerable Handlers => handlers; static EMPGunSightHandler() { handlers = new List(); LevelAPI.OnLevelCleanup += Clear; LevelAPI.OnBuildStart += Clear; } private void SetupGunSights() { Il2CppArrayBase componentsInChildren = base.gameObject.GetComponentsInChildren(true); if (componentsInChildren != null) { _sightPictures = (from x in (IEnumerable)componentsInChildren where (Object)(object)x.sharedMaterial != (Object)null && (Object)(object)x.sharedMaterial.shader != (Object)null where ((Object)x.sharedMaterial.shader).name.Contains("HolographicSight") select ((Component)x).gameObject).ToArray(); } if (_sightPictures == null || _sightPictures.Length < 1) { EOSLogger.Error("Unable to find sight on " + ((Object)base.gameObject).name + "!"); } } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); SetupGunSights(); handlers.Add(this); } protected override void DeviceOff() { ForEachSights(delegate(GameObject x) { x.SetActive(false); }); } protected override void DeviceOn() { ForEachSights(delegate(GameObject x) { x.SetActive(true); }); } protected override void FlickerDevice() { ForEachSights(delegate(GameObject x) { x.SetActive(EMPHandler.FlickerUtil()); }); } private void ForEachSights(Action action) { GameObject[] sightPictures = _sightPictures; foreach (GameObject val in sightPictures) { if ((Object)(object)val != (Object)null) { action?.Invoke(val); } } } private static void Clear() { handlers.Clear(); } } public class EMPLightHandler : EMPHandler { private static List handlers; private LG_Light _light; private float _originalIntensity; private Color _originalColor; public static IEnumerable Handlers => handlers; private static void Clear() { handlers.Clear(); } static EMPLightHandler() { handlers = new List(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { //IL_0046: 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_0066: 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_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) base.Setup(gameObject, controller); _light = gameObject.GetComponent(); if ((Object)(object)_light == (Object)null) { EOSLogger.Warning("No Light!"); } else { _originalIntensity = _light.GetIntensity(); _originalColor = new Color(_light.m_color.r, _light.m_color.g, _light.m_color.b, _light.m_color.a); base.State = EMPState.On; } handlers.Add(this); } protected override void FlickerDevice() { if (!((Object)(object)_light == (Object)null)) { _light.ChangeIntensity(EMPHandler.GetRandom01() * _originalIntensity); } } protected override void DeviceOn() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_light == (Object)null)) { _light.ChangeIntensity(_originalIntensity); _light.ChangeColor(_originalColor); } } protected override void DeviceOff() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_light == (Object)null)) { _light.ChangeIntensity(0f); _light.ChangeColor(Color.black); } } } public class EMPPlayerFlashLightHandler : EMPHandler { private static List handlers; private PlayerInventoryBase _inventory; private float _originalIntensity; private bool _originalFlashlightState; public static IEnumerable Handlers => handlers; protected override bool IsDeviceOnPlayer => true; private bool FlashlightEnabled => _inventory.FlashlightEnabled; private static void Clear() { handlers.Clear(); } static EMPPlayerFlashLightHandler() { handlers = new List(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); _inventory = gameObject.GetComponent().Inventory; if ((Object)(object)_inventory == (Object)null) { EOSLogger.Warning("Player inventory was null!"); } else { base.State = EMPState.On; Events.FlashLightWielded = (Action)Delegate.Combine(Events.FlashLightWielded, new Action(InventoryEvents_ItemWielded)); } handlers.Add(this); } private void InventoryEvents_ItemWielded(GearPartFlashlight flashlight) { _originalIntensity = GameDataBlockBase.GetBlock(flashlight.m_settingsID).intensity; } protected override void DeviceOff() { _originalFlashlightState = FlashlightEnabled; if (_originalFlashlightState) { _inventory.Owner.Sync.WantsToSetFlashlightEnabled(false, false); } } protected override void DeviceOn() { if (_originalFlashlightState != FlashlightEnabled) { _inventory.Owner.Sync.WantsToSetFlashlightEnabled(_originalFlashlightState, false); } _inventory.m_flashlight.intensity = _originalIntensity; } protected override void FlickerDevice() { if (FlashlightEnabled) { _inventory.m_flashlight.intensity = EMPHandler.GetRandom01() * _originalIntensity; } } } public class EMPPlayerHudHandler : EMPHandler { private static List handlers; private readonly List _targets = new List(); public static IEnumerable Handlers => handlers; private static void Clear() { handlers.Clear(); } static EMPPlayerHudHandler() { handlers = new List(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { _targets.Clear(); base.Setup(gameObject, controller); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_compass); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_wardenObjective); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.Inventory); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_playerStatus); handlers.Add(this); } protected override void DeviceOff() { foreach (RectTransformComp target in _targets) { ((Component)target).gameObject.SetActive(false); } } protected override void DeviceOn() { foreach (RectTransformComp target in _targets) { ((Component)target).gameObject.SetActive(true); } } protected override void FlickerDevice() { foreach (RectTransformComp target in _targets) { target.SetVisible(EMPHandler.FlickerUtil()); } } } public class EMPSentryHandler : EMPHandler { private static List handlers; private static Color _offColor; private SentryGunInstance _sentry; private SentryGunInstance_ScannerVisuals_Plane _visuals; public static IEnumerable Handlers => handlers; private static void Clear() { handlers.Clear(); } static EMPSentryHandler() { //IL_000c: 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_0043: Unknown result type (might be due to invalid IL or missing references) handlers = new List(); _offColor = new Color { r = 0f, g = 0f, b = 0f, a = 0f }; LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); _sentry = gameObject.GetComponent(); _visuals = gameObject.GetComponent(); if ((Object)(object)_sentry == (Object)null || (Object)(object)_visuals == (Object)null) { EOSLogger.Error($"Missing components on Sentry! Has Sentry?: {(Object)(object)_sentry == (Object)null}, Has Visuals?: {(Object)(object)_visuals == (Object)null}"); } handlers.Add(this); } protected override void DeviceOff() { //IL_000b: 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) _visuals.m_scannerPlane.SetColor(_offColor); _visuals.UpdateLightProps(_offColor, false); _sentry.m_isSetup = false; _sentry.m_isScanning = false; _sentry.m_isFiring = false; ((ItemEquippable)_sentry).Sound.Post(EVENTS.SENTRYGUN_STOP_ALL_LOOPS, true); } protected override void DeviceOn() { _sentry.m_isSetup = true; _sentry.m_visuals.SetVisualStatus((eSentryGunStatus)0, true); _sentry.m_isScanning = false; _sentry.m_startScanTimer = Clock.Time + _sentry.m_initialScanDelay; ((ItemEquippable)_sentry).Sound.Post(EVENTS.SENTRYGUN_LOW_AMMO_WARNING, true); } protected override void FlickerDevice() { int randomRange = EMPHandler.GetRandomRange(0, 3); _sentry.StopFiring(); switch (randomRange) { case 0: _visuals.SetVisualStatus((eSentryGunStatus)4, true); break; case 1: _visuals.SetVisualStatus((eSentryGunStatus)1, true); break; case 2: _visuals.SetVisualStatus((eSentryGunStatus)2, true); break; } } } }