Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LightBat v1.0.2
LightBat.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
#define DEBUG using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalLib.Modules; using LightBat.NetcodePatcher; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LightBat")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.5.14.0")] [assembly: AssemblyInformationalVersion("1.5.14+3fa48b0ac7566ae8d1afb254877f0e76fda72420")] [assembly: AssemblyProduct("LightBat")] [assembly: AssemblyTitle("LightBat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.14.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 LightBat { internal static class DepletedApparatusRegistry { private static readonly int EmissiveColorProperty = Shader.PropertyToID("_EmissiveColor"); private static readonly int EmissiveColorLdrProperty = Shader.PropertyToID("_EmissiveColorLDR"); private static readonly int EmissiveIntensityProperty = Shader.PropertyToID("_EmissiveIntensity"); private static readonly int StandardEmissionColorProperty = Shader.PropertyToID("_EmissionColor"); private static readonly Dictionary<ulong, DepletedApparatusState> ActiveStates = new Dictionary<ulong, DepletedApparatusState>(); private static GameObject? StatePrefab { get; set; } internal static bool Register(AssetBundle assets) { if ((Object)(object)StatePrefab != (Object)null) { return true; } GameObject val = assets.LoadAsset<GameObject>("DepletedApparatusState"); if ((Object)(object)val == (Object)null || (Object)(object)val.GetComponent<NetworkObject>() == (Object)null || (Object)(object)val.GetComponent<DepletedApparatusState>() == (Object)null) { Plugin.Logger.LogError((object)"The asset bundle is missing the depleted Apparatus network state prefab."); return false; } NetworkPrefabs.RegisterNetworkPrefab(val); StatePrefab = val; Plugin.Logger.LogInfo((object)"Registered the persistent depleted Apparatus network state."); return true; } internal static bool SpawnState(LungProp apparatus, int scrapValue) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = default(NetworkObject); if ((Object)(object)apparatus == (Object)null || (Object)(object)StatePrefab == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || !((Component)apparatus).TryGetComponent<NetworkObject>(ref val) || !val.IsSpawned) { return false; } ulong networkObjectId = val.NetworkObjectId; if (ActiveStates.TryGetValue(networkObjectId, out DepletedApparatusState value) && (Object)(object)value != (Object)null && ((NetworkBehaviour)value).IsSpawned) { ApplyState(apparatus, scrapValue); return true; } ActiveStates.Remove(networkObjectId); GameObject val2 = Object.Instantiate<GameObject>(StatePrefab, Vector3.zero, Quaternion.identity); NetworkObject component = val2.GetComponent<NetworkObject>(); DepletedApparatusState component2 = val2.GetComponent<DepletedApparatusState>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)val2); return false; } component.Spawn(false); ActiveStates[networkObjectId] = component2; component2.Initialize(new NetworkObjectReference(val), scrapValue); return true; } internal static void UnregisterState(DepletedApparatusState state) { ulong? num = null; foreach (KeyValuePair<ulong, DepletedApparatusState> activeState in ActiveStates) { if ((Object)(object)activeState.Value == (Object)(object)state) { num = activeState.Key; break; } } if (num.HasValue) { ActiveStates.Remove(num.Value); } } internal static void ApplyState(LungProp apparatus, int scrapValue) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)apparatus == (Object)null) { return; } apparatus.isLungPowered = false; ((GrabbableObject)apparatus).isBeingUsed = false; apparatus.lungDeviceLightIntensity = 0f; ((GrabbableObject)apparatus).SetScrapValue(Mathf.Max(0, scrapValue)); Light[] componentsInChildren = ((Component)apparatus).GetComponentsInChildren<Light>(true); foreach (Light val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { val.intensity = 0f; ((Behaviour)val).enabled = false; } } ParticleSystem[] componentsInChildren2 = ((Component)apparatus).GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null)) { val2.Stop(true, (ParticleSystemStopBehavior)0); } } if ((Object)(object)apparatus.sparkParticle != (Object)null) { apparatus.sparkParticle.SetActive(false); } MaterialPropertyBlock val3 = new MaterialPropertyBlock(); Renderer[] componentsInChildren3 = ((Component)apparatus).GetComponentsInChildren<Renderer>(true); foreach (Renderer val4 in componentsInChildren3) { if (!((Object)(object)val4 == (Object)null) && !((Object)((Component)val4).transform).name.StartsWith("ScanNode", StringComparison.OrdinalIgnoreCase)) { val4.GetPropertyBlock(val3); val3.SetColor(EmissiveColorProperty, Color.black); val3.SetColor(EmissiveColorLdrProperty, Color.black); val3.SetColor(StandardEmissionColorProperty, Color.black); val3.SetFloat(EmissiveIntensityProperty, 0f); val4.SetPropertyBlock(val3); val3.Clear(); } } } } public sealed class DepletedApparatusState : NetworkBehaviour { private const float ResolveTimeout = 15f; private const float MissingTargetDespawnDelay = 5f; private const float StateEnforcementInterval = 0.75f; private readonly NetworkVariable<NetworkObjectReference> targetApparatus = new NetworkVariable<NetworkObjectReference>(default(NetworkObjectReference), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private readonly NetworkVariable<bool> initialized = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); internal readonly NetworkVariable<int> finalScrapValue = new NetworkVariable<int>(30, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private Coroutine? resolveCoroutine; private float missingTargetTime; private float nextStateEnforcementTime; internal void Initialize(NetworkObjectReference apparatusReference, int finalScrapValue) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || !((NetworkBehaviour)this).IsSpawned) { Plugin.Logger.LogError((object)"Tried to initialize a depleted Apparatus state before its network object was spawned."); return; } targetApparatus.Value = apparatusReference; this.finalScrapValue.Value = finalScrapValue; initialized.Value = true; StartResolvingTarget(); } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); NetworkVariable<NetworkObjectReference> obj = targetApparatus; obj.OnValueChanged = (OnValueChangedDelegate<NetworkObjectReference>)(object)Delegate.Combine((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<NetworkObjectReference>(OnTargetChanged)); NetworkVariable<bool> obj2 = initialized; obj2.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Combine((Delegate?)(object)obj2.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnInitializedChanged)); if (initialized.Value) { StartResolvingTarget(); } } public override void OnNetworkDespawn() { DepletedApparatusRegistry.UnregisterState(this); NetworkVariable<NetworkObjectReference> obj = targetApparatus; obj.OnValueChanged = (OnValueChangedDelegate<NetworkObjectReference>)(object)Delegate.Remove((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<NetworkObjectReference>(OnTargetChanged)); NetworkVariable<bool> obj2 = initialized; obj2.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Remove((Delegate?)(object)obj2.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnInitializedChanged)); if (resolveCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(resolveCoroutine); resolveCoroutine = null; } ((NetworkBehaviour)this).OnNetworkDespawn(); } private void Update() { //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) if (!((NetworkBehaviour)this).IsSpawned || !initialized.Value) { return; } NetworkObjectReference value = targetApparatus.Value; NetworkObject val = default(NetworkObject); LungProp apparatus = default(LungProp); if (((NetworkObjectReference)(ref value)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<LungProp>(ref apparatus)) { missingTargetTime = 0f; if (Time.time >= nextStateEnforcementTime) { DepletedApparatusRegistry.ApplyState(apparatus, finalScrapValue.Value); nextStateEnforcementTime = Time.time + 0.75f; } } else if (((NetworkBehaviour)this).IsServer) { missingTargetTime += Time.deltaTime; if (missingTargetTime >= 5f) { ((NetworkBehaviour)this).NetworkObject.Despawn(true); } } } private void OnTargetChanged(NetworkObjectReference previous, NetworkObjectReference current) { if (initialized.Value) { StartResolvingTarget(); } } private void OnInitializedChanged(bool previous, bool current) { if (current) { StartResolvingTarget(); } } private void StartResolvingTarget() { if (((NetworkBehaviour)this).IsSpawned && !TryApplyState()) { if (resolveCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(resolveCoroutine); } resolveCoroutine = ((MonoBehaviour)this).StartCoroutine(ResolveTarget()); } } private IEnumerator ResolveTarget() { float startedAt = Time.realtimeSinceStartup; while (((NetworkBehaviour)this).IsSpawned && initialized.Value && Time.realtimeSinceStartup - startedAt < 15f) { if (TryApplyState()) { resolveCoroutine = null; yield break; } yield return null; } resolveCoroutine = null; if (((NetworkBehaviour)this).IsSpawned && initialized.Value) { Plugin.Logger.LogWarning((object)"Could not resolve the Apparatus for a replicated depleted Apparatus state."); } } private bool TryApplyState() { //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) if (initialized.Value) { NetworkObjectReference value = targetApparatus.Value; NetworkObject val = default(NetworkObject); LungProp apparatus = default(LungProp); if (((NetworkObjectReference)(ref value)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<LungProp>(ref apparatus)) { DepletedApparatusRegistry.ApplyState(apparatus, finalScrapValue.Value); nextStateEnforcementTime = Time.time + 0.75f; return true; } } return false; } protected override void __initializeVariables() { if (targetApparatus == null) { throw new Exception("DepletedApparatusState.targetApparatus cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)targetApparatus).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)targetApparatus, "targetApparatus"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)targetApparatus); if (initialized == null) { throw new Exception("DepletedApparatusState.initialized cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)initialized).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)initialized, "initialized"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)initialized); if (finalScrapValue == null) { throw new Exception("DepletedApparatusState.finalScrapValue cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)finalScrapValue).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)finalScrapValue, "finalScrapValue"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)finalScrapValue); ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { ((NetworkBehaviour)this).__initializeRpcs(); } protected internal override string __getTypeName() { return "DepletedApparatusState"; } } internal static class DischargedLampRegistry { private static readonly int EmissiveColorProperty = Shader.PropertyToID("_EmissiveColor"); private static readonly int EmissiveColorLdrProperty = Shader.PropertyToID("_EmissiveColorLDR"); private static readonly int EmissiveIntensityProperty = Shader.PropertyToID("_EmissiveIntensity"); private static readonly int StandardEmissionColorProperty = Shader.PropertyToID("_EmissionColor"); internal static Item? Item { get; private set; } private static GameObject? StatePrefab { get; set; } internal static bool Register(AssetBundle assets) { if ((Object)(object)Item != (Object)null) { return true; } Item val = assets.LoadAsset<Item>("DischargedLamp"); GameObject val2 = assets.LoadAsset<GameObject>("DischargedLampState"); if ((Object)(object)val == (Object)null) { Plugin.Logger.LogError((object)"The asset bundle is missing the Discharged lamp Item."); return false; } if ((Object)(object)val2 == (Object)null || (Object)(object)val2.GetComponent<NetworkObject>() == (Object)null || (Object)(object)val2.GetComponent<DischargedLampState>() == (Object)null) { Plugin.Logger.LogError((object)"The asset bundle is missing the Discharged lamp network state prefab."); return false; } GameObject spawnPrefab = val.spawnPrefab; PhysicsProp val3 = (((Object)(object)spawnPrefab != (Object)null) ? spawnPrefab.GetComponent<PhysicsProp>() : null); if ((Object)(object)spawnPrefab == (Object)null || (Object)(object)spawnPrefab.GetComponent<NetworkObject>() == (Object)null || (Object)(object)val3 == (Object)null) { Plugin.Logger.LogError((object)"The Discharged lamp Item has an invalid network prefab."); return false; } ((Object)val).name = "DischargedLamp"; val.itemName = "Discharged lamp"; ((GrabbableObject)val3).itemProperties = val; NetworkPrefabs.RegisterNetworkPrefab(spawnPrefab); NetworkPrefabs.RegisterNetworkPrefab(val2); Items.RegisterItem(val); Item = val; StatePrefab = val2; Plugin.Logger.LogInfo((object)"Registered Discharged lamp as a non-spawning LethalLib item."); return true; } internal static bool SpawnState(GrabbableObject lamp, int scrapValue) { //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_00a5: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = default(NetworkObject); if ((Object)(object)lamp == (Object)null || (Object)(object)StatePrefab == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || !((Component)lamp).TryGetComponent<NetworkObject>(ref val) || !val.IsSpawned) { return false; } GameObject val2 = Object.Instantiate<GameObject>(StatePrefab, Vector3.zero, Quaternion.identity); NetworkObject component = val2.GetComponent<NetworkObject>(); DischargedLampState component2 = val2.GetComponent<DischargedLampState>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)val2); return false; } component.Spawn(false); component2.Initialize(new NetworkObjectReference(val), scrapValue); return true; } internal static void ApplyState(GrabbableObject lamp, int scrapValue) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00d7: 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_00f9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)lamp == (Object)null) { return; } lamp.insertedBattery = new Battery(true, 0f); lamp.isBeingUsed = false; lamp.itemUsedUp = false; Light[] componentsInChildren = ((Component)lamp).GetComponentsInChildren<Light>(true); foreach (Light val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { val.intensity = 0f; ((Behaviour)val).enabled = false; } } MaterialPropertyBlock val2 = new MaterialPropertyBlock(); Renderer[] componentsInChildren2 = ((Component)lamp).GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren2) { if (!((Object)(object)val3 == (Object)null) && !((Object)((Component)val3).transform).name.StartsWith("ScanNode", StringComparison.OrdinalIgnoreCase)) { val3.GetPropertyBlock(val2); val2.SetColor(EmissiveColorProperty, Color.black); val2.SetColor(EmissiveColorLdrProperty, Color.black); val2.SetColor(StandardEmissionColorProperty, Color.black); val2.SetFloat(EmissiveIntensityProperty, 0f); val3.SetPropertyBlock(val2); val2.Clear(); } } if ((Object)(object)Item != (Object)null) { lamp.itemProperties = Item; } lamp.SetScrapValue(Mathf.Max(0, scrapValue)); ScanNodeProperties componentInChildren = ((Component)lamp).GetComponentInChildren<ScanNodeProperties>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.headerText = "Discharged lamp"; } RefreshLocalInventoryIcon(lamp); } private static void RefreshLocalInventoryIcon(GrabbableObject lamp) { if ((Object)(object)Item == (Object)null || (Object)(object)Item.itemIcon == (Object)null || (Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)HUDManager.Instance == (Object)null) { return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null || localPlayerController.ItemSlots == null) { return; } for (int i = 0; i < localPlayerController.ItemSlots.Length; i++) { if (!((Object)(object)localPlayerController.ItemSlots[i] != (Object)(object)lamp)) { if (typeof(HUDManager).GetField("itemSlotIcons")?.GetValue(HUDManager.Instance) is Array array && i < array.Length) { object value = array.GetValue(i); value?.GetType().GetProperty("sprite")?.SetValue(value, Item.itemIcon); } break; } } } } public sealed class DischargedLampState : NetworkBehaviour { private const float ResolveTimeout = 15f; private const float MissingTargetDespawnDelay = 5f; private readonly NetworkVariable<NetworkObjectReference> targetLamp = new NetworkVariable<NetworkObjectReference>(default(NetworkObjectReference), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private readonly NetworkVariable<int> dischargedValue = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private readonly NetworkVariable<bool> initialized = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private Coroutine? resolveCoroutine; private float missingTargetTime; internal void Initialize(NetworkObjectReference lampReference, int scrapValue) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || !((NetworkBehaviour)this).IsSpawned) { Plugin.Logger.LogError((object)"Tried to initialize a Discharged lamp state before its network object was spawned."); return; } targetLamp.Value = lampReference; dischargedValue.Value = Mathf.Max(0, scrapValue); initialized.Value = true; StartResolvingTarget(); } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); NetworkVariable<NetworkObjectReference> obj = targetLamp; obj.OnValueChanged = (OnValueChangedDelegate<NetworkObjectReference>)(object)Delegate.Combine((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<NetworkObjectReference>(OnTargetChanged)); NetworkVariable<int> obj2 = dischargedValue; obj2.OnValueChanged = (OnValueChangedDelegate<int>)(object)Delegate.Combine((Delegate?)(object)obj2.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<int>(OnValueChanged)); NetworkVariable<bool> obj3 = initialized; obj3.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Combine((Delegate?)(object)obj3.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnInitializedChanged)); if (initialized.Value) { StartResolvingTarget(); } } public override void OnNetworkDespawn() { NetworkVariable<NetworkObjectReference> obj = targetLamp; obj.OnValueChanged = (OnValueChangedDelegate<NetworkObjectReference>)(object)Delegate.Remove((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<NetworkObjectReference>(OnTargetChanged)); NetworkVariable<int> obj2 = dischargedValue; obj2.OnValueChanged = (OnValueChangedDelegate<int>)(object)Delegate.Remove((Delegate?)(object)obj2.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<int>(OnValueChanged)); NetworkVariable<bool> obj3 = initialized; obj3.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Remove((Delegate?)(object)obj3.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnInitializedChanged)); if (resolveCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(resolveCoroutine); resolveCoroutine = null; } ((NetworkBehaviour)this).OnNetworkDespawn(); } private void Update() { //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) if (!((NetworkBehaviour)this).IsServer || !((NetworkBehaviour)this).IsSpawned || !initialized.Value) { return; } NetworkObjectReference value = targetLamp.Value; NetworkObject val = default(NetworkObject); if (((NetworkObjectReference)(ref value)).TryGet(ref val, (NetworkManager)null)) { missingTargetTime = 0f; return; } missingTargetTime += Time.deltaTime; if (missingTargetTime >= 5f) { ((NetworkBehaviour)this).NetworkObject.Despawn(true); } } private void OnTargetChanged(NetworkObjectReference previous, NetworkObjectReference current) { if (initialized.Value) { StartResolvingTarget(); } } private void OnValueChanged(int previous, int current) { if (initialized.Value) { StartResolvingTarget(); } } private void OnInitializedChanged(bool previous, bool current) { if (current) { StartResolvingTarget(); } } private void StartResolvingTarget() { if (((NetworkBehaviour)this).IsSpawned && !TryApplyState()) { if (resolveCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(resolveCoroutine); } resolveCoroutine = ((MonoBehaviour)this).StartCoroutine(ResolveTarget()); } } private IEnumerator ResolveTarget() { float startedAt = Time.realtimeSinceStartup; while (((NetworkBehaviour)this).IsSpawned && initialized.Value && Time.realtimeSinceStartup - startedAt < 15f) { if (TryApplyState()) { resolveCoroutine = null; yield break; } yield return null; } resolveCoroutine = null; if (((NetworkBehaviour)this).IsSpawned && initialized.Value) { Plugin.Logger.LogWarning((object)"Could not resolve the Fancy lamp for a replicated Discharged lamp state."); } } private bool TryApplyState() { //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) if (initialized.Value) { NetworkObjectReference value = targetLamp.Value; NetworkObject val = default(NetworkObject); GrabbableObject lamp = default(GrabbableObject); if (((NetworkObjectReference)(ref value)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<GrabbableObject>(ref lamp)) { DischargedLampRegistry.ApplyState(lamp, dischargedValue.Value); return true; } } return false; } protected override void __initializeVariables() { if (targetLamp == null) { throw new Exception("DischargedLampState.targetLamp cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)targetLamp).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)targetLamp, "targetLamp"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)targetLamp); if (dischargedValue == null) { throw new Exception("DischargedLampState.dischargedValue cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)dischargedValue).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)dischargedValue, "dischargedValue"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)dischargedValue); if (initialized == null) { throw new Exception("DischargedLampState.initialized cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)initialized).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)initialized, "initialized"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)initialized); ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { ((NetworkBehaviour)this).__initializeRpcs(); } protected internal override string __getTypeName() { return "DischargedLampState"; } } internal static class UtilityFlashlightInventory { internal const int UtilitySlotIndex = 50; private static readonly MethodInfo? SwitchToItemSlotMethod = AccessTools.Method(typeof(PlayerControllerB), "SwitchToItemSlot", new Type[2] { typeof(int), typeof(GrabbableObject) }, (Type[])null); private static readonly MethodInfo? SwitchToSlotServerRpcMethod = AccessTools.Method(typeof(PlayerControllerB), "SwitchToSlotServerRpc", new Type[1] { typeof(int) }, (Type[])null); private static readonly FieldInfo? ThrowingObjectField = AccessTools.Field(typeof(PlayerControllerB), "throwingObject"); internal static bool IsInUtilitySlot(PlayerControllerB player, FlashlightItem flashlight) { return (Object)(object)player != (Object)null && (Object)(object)flashlight != (Object)null && (Object)(object)player.ItemOnlySlot == (Object)(object)flashlight; } internal static int FindNormalSlot(PlayerControllerB player, FlashlightItem flashlight) { if (player.ItemSlots == null) { return -1; } for (int i = 0; i < player.ItemSlots.Length; i++) { if ((Object)(object)player.ItemSlots[i] == (Object)(object)flashlight) { return i; } } return -1; } internal static bool IsStoredByPlayer(PlayerControllerB player, FlashlightItem flashlight) { return IsInUtilitySlot(player, flashlight) || FindNormalSlot(player, flashlight) >= 0 || (Object)(object)player.pocketedFlashlight == (Object)(object)flashlight || (Object)(object)player.currentlyHeldObjectServer == (Object)(object)flashlight || (Object)(object)player.currentlyHeldObject == (Object)(object)flashlight; } internal static int FindStoredSlot(PlayerControllerB player, FlashlightItem flashlight) { if (IsInUtilitySlot(player, flashlight)) { return 50; } return FindNormalSlot(player, flashlight); } internal static bool IsInActiveHand(PlayerControllerB player, FlashlightItem flashlight) { if ((Object)(object)player == (Object)null || (Object)(object)flashlight == (Object)null || ((GrabbableObject)flashlight).isPocketed) { return false; } if (!((player.currentItemSlot != 50) ? (player.ItemSlots != null && player.currentItemSlot >= 0 && player.currentItemSlot < player.ItemSlots.Length && (Object)(object)player.ItemSlots[player.currentItemSlot] == (Object)(object)flashlight) : ((Object)(object)player.ItemOnlySlot == (Object)(object)flashlight))) { return false; } return !((NetworkBehaviour)player).IsOwner || (Object)(object)player.currentlyHeldObjectServer == (Object)(object)flashlight || (Object)(object)player.currentlyHeldObject == (Object)(object)flashlight; } internal static bool SwitchToStoredFlashlight(PlayerControllerB player, FlashlightItem flashlight) { int num = FindStoredSlot(player, flashlight); if (SwitchToItemSlotMethod == null || SwitchToSlotServerRpcMethod == null || num < 0 || (num != 50 && (player.ItemSlots == null || num >= player.ItemSlots.Length))) { return false; } GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer; FlashlightItem val = (FlashlightItem)(((object)((currentlyHeldObjectServer is FlashlightItem) ? currentlyHeldObjectServer : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/)); if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)flashlight && LightBatAI.IsFlashlightInteractionLocked(val)) { return false; } try { SwitchToItemSlotMethod.Invoke(player, new object[2] { num, null }); if (!IsInActiveHand(player, flashlight)) { return false; } SwitchToSlotServerRpcMethod.Invoke(player, new object[1] { num }); return true; } catch (Exception arg) { Plugin.Logger.LogError((object)$"Could not deploy a stored flashlight into hand: {arg}"); return false; } } internal static bool IsThrowingObject(PlayerControllerB player) { object obj = ThrowingObjectField?.GetValue(player); return obj is bool && (bool)obj; } } [HarmonyPatch(typeof(FlashlightItem), "ItemActivate")] internal static class LockedFlashlightActivationPatch { [HarmonyPrefix] private static bool AllowActivation(FlashlightItem __instance) { return !LightBatAI.IsFlashlightInteractionLocked(__instance); } } [HarmonyPatch(typeof(FlashlightItem), "PocketItem")] internal static class LockedFlashlightPocketPatch { [HarmonyPrefix] private static bool AllowPocketing(FlashlightItem __instance) { return !LightBatAI.IsFlashlightInteractionLocked(__instance); } } [HarmonyPatch(typeof(FlashlightItem), "Update")] internal static class LockedFlashlightUpdatePatch { [HarmonyPostfix] private static void KeepAttachedFlashlightOn(FlashlightItem __instance) { if (LightBatAI.IsFlashlightInteractionLocked(__instance) && ((GrabbableObject)__instance).insertedBattery != null && !((GrabbableObject)__instance).insertedBattery.empty && !(((GrabbableObject)__instance).insertedBattery.charge <= 0f)) { ((GrabbableObject)__instance).isBeingUsed = true; if ((Object)(object)__instance.flashlightBulb != (Object)null && !((Behaviour)__instance.flashlightBulb).enabled) { __instance.SwitchFlashlight(true); } } } } [HarmonyPatch(typeof(PlayerControllerB), "SwitchToItemSlot")] internal static class LockedFlashlightInventorySlotPatch { [HarmonyPrefix] private static bool AllowSlotSwitch(PlayerControllerB __instance, int slot) { if (slot == __instance.currentItemSlot) { return true; } GrabbableObject currentlyHeldObjectServer = __instance.currentlyHeldObjectServer; FlashlightItem val = (FlashlightItem)(((object)((currentlyHeldObjectServer is FlashlightItem) ? currentlyHeldObjectServer : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/)); return (Object)(object)val == (Object)null || !LightBatAI.IsFlashlightInteractionLocked(val); } } [HarmonyPatch(typeof(PlayerControllerB), "DiscardHeldObject")] internal static class LockedFlashlightDiscardPatch { [HarmonyPrefix] internal static bool AllowDiscard(PlayerControllerB __instance) { if (__instance.isPlayerDead) { return true; } GrabbableObject currentlyHeldObjectServer = __instance.currentlyHeldObjectServer; FlashlightItem val = (FlashlightItem)(((object)((currentlyHeldObjectServer is FlashlightItem) ? currentlyHeldObjectServer : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/)); return (Object)(object)val == (Object)null || !LightBatAI.IsFlashlightInteractionLocked(val); } } [HarmonyPatch(typeof(PlayerControllerB), "Discard_performed")] internal static class LockedFlashlightDiscardInputPatch { [HarmonyPrefix] private static bool AllowDiscardInput(PlayerControllerB __instance) { return LockedFlashlightDiscardPatch.AllowDiscard(__instance); } } public sealed class LightBatAI : EnemyAI { private enum ApparatusPhase { None, Approaching, Perched, Hauling, Draining } private sealed class ApparatusFlock { public ulong ApparatusId; public LungProp Apparatus = null; public int Generation; public readonly List<LightBatAI> Members = new List<LightBatAI>(); public ApparatusPhase Phase = ApparatusPhase.Approaching; public bool Ending; public int SimulatedFrame = -1; public PlayerControllerB? Holder; public GameObject NavObject = null; public NavMeshAgent Nav = null; public bool NavReady; public Vector3 HaulOrigin; public Vector3 HaulDestination; public bool HasHaulDestination; public float HaulStartedAt; public float HaulProgressAt; public Vector3 HaulProgressPosition; public float NextHaulReplanAt; public int HaulReplanCount; public float HaulHeight; public Vector3 CarryPosition; public Vector3 CarryFacing; public float CarryYaw; public int CarryTick; public float NextCarryPublishAt; public float PullStartedAt = -1f; public Vector3 PullDirection; public Vector3 PullDestination; public bool HasPullDestination; public float NextPullDestinationAt; public Vector3 PublishedPull; public bool DrainActive; public bool DrainCompleted; public float DrainElapsed; public float NextDrainSyncAt; public float PhaseEnteredAt; public float PerchedSince = -1f; public float UnperchedSince = -1f; public int PublishedPerchedCount = -1; } private sealed class ApparatusHold { public ulong ApparatusId; public LungProp Apparatus = null; public int Generation; public GameObject AnchorObject = null; public Transform Anchor = null; public Vector3 SmoothPosition; public float SmoothYaw; public bool Primed; public int AppliedTick = int.MinValue; public int AppliedFrame = -1; public int TouchedFrame = -1; } private sealed class ApparatusLightVisualState { public LungProp Apparatus = null; public Light[] Lights = null; public float[] FullIntensities = null; } private sealed class ApparatusLiftState { public float Height; public float GroundY; public bool HasGround; public bool HoldingVertical; public int TouchedFrame = -1; } private sealed class ApparatusDrainProgress { public float Elapsed; public int StartValue; public int TargetValue; public bool Completed; } private sealed class ApparatusHoldDriver : MonoBehaviour { private void LateUpdate() { SweepOrphanedApparatusHolds(); } } private sealed class ApparatusShape { public LungProp Apparatus = null; public Vector3 LocalCenter; public Vector3 Extents; } private sealed class BurnMeshState { public SkinnedMeshRenderer BodyRenderer = null; public SkinnedMeshRenderer EdgeRenderer = null; public Mesh OriginalMesh = null; public Mesh BodyMesh = null; public Mesh EdgeMesh = null; public int[][] SourceTriangles = null; public float[][] TriangleScores = null; public List<int>[] BodyTriangles = null; public List<int>[] EdgeTriangles = null; } private sealed class SharedFacilityLightState { public Animator Animator = null; public Light[] Lights = null; public float[] FullIntensities = null; public float RemainingEnergy = 1f; public float FlickerStartedAt; public float FlickerEndsAt; public readonly Dictionary<ulong, int> PerchSlots = new Dictionary<ulong, int>(); } private sealed class FlashlightRaid { public ulong FlashlightId; public FlashlightItem Flashlight = null; public PlayerControllerB Player = null; public LightBatAI Volunteer = null; public readonly List<LightBatAI> Members = new List<LightBatAI>(); public bool Ending; public int RaidGeneration; public bool DeployingFlashlight; public bool OwnerConfirmedEquipped; public int DeploymentRequestId; public float DeploymentStartedAt; public float NextDeploymentRequestAt; public float HandStableSince = -1f; public float ReturnCooldown = 8f; } private sealed class LampVisualState { public Light[] Lights = null; public float[] FullIntensities = null; } private sealed class LampValueState { public GrabbableObject Lamp = null; public int OriginalScrapValue; } private enum State { SearchingForLight, FlyingToLight, Perching, Draining, Fleeing, FlyingToRaidFlashlight, AttachedToFlashlight, OrbitingFlashlightPlayer, FlyingToHeldApparatus, PerchedOnHeldApparatus, CarryingApparatus, FlyingToDroppedApparatus, DrainingApparatus } private enum TargetKind { None, FacilityLight, Flashlight, ItemLamp } private const float ApparatusAttachDistance = 0.85f; private const float ApparatusApproachRepathInterval = 0.55f; private const float ApparatusApproachStallTime = 0.7f; private const float ApparatusApproachGiveUpTime = 7f; private const float ApparatusFlockAbandonTime = 20f; private const int ApparatusHoldSweepFrames = 12; private const float ApparatusMaximumPull = 4f; private const float ApparatusMaximumAirbornePull = 5.5f; private const float ApparatusLiftRiseRate = 1.1f; private const float ApparatusLiftFallRate = 2.6f; private const float ApparatusLiftStiffness = 6f; private const float ApparatusLiftMaximumVerticalSpeed = 4f; private const float ApparatusLiftPlayerHeight = 2.6f; private const float ApparatusLiftCeilingMargin = 0.3f; private const float ApparatusLiftMinimumHeight = 0.2f; private const float ApparatusLiftProbeAhead = 1.6f; private const float ApparatusLiftProbeCeiling = 8f; private const float ApparatusLiftGroundProbe = 12f; private const float ApparatusLiftGroundTrackRate = 3f; private const int ApparatusLiftExpiryFrames = 8; private const float ApparatusHaulStallTime = 0.7f; private const float ApparatusHaulReplanCooldown = 0.45f; private const float ApparatusHaulTimeout = 26f; private const float ApparatusHaulArriveDistance = 2.2f; private const float ApparatusHaulMinimumDisplacement = 7f; private const float ApparatusPerchSettleTime = 0.45f; private const float ApparatusReturnCooldown = 6f; private const float ApparatusDepletedCooldown = 14f; private const float ApparatusPullRampTime = 1.2f; private const float ApparatusPullDestinationInterval = 6f; private const float ApparatusCarryPublishInterval = 0.05f; private const float ApparatusDrainSyncInterval = 0.15f; private const float ApparatusDoorOpenCooldown = 1.1f; private const float ApparatusDoorScanDistance = 3.6f; private const int ApparatusSlotsPerRing = 5; private const int ApparatusFinalScrapMinimum = 30; private const int ApparatusFinalScrapMaximumExclusive = 46; private readonly NetworkVariable<NetworkObjectReference> syncedApparatus = new NetworkVariable<NetworkObjectReference>(default(NetworkObjectReference), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<int> syncedApparatusPhase = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<int> syncedApparatusSlot = new NetworkVariable<int>(-1, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<int> syncedApparatusGeneration = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<int> syncedApparatusPerchedCount = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<Vector3> syncedApparatusPull = new NetworkVariable<Vector3>(Vector3.zero, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<Vector3> syncedApparatusCarryPosition = new NetworkVariable<Vector3>(Vector3.zero, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<float> syncedApparatusCarryYaw = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<int> syncedApparatusCarryTick = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private static readonly Dictionary<ulong, ApparatusFlock> activeApparatusFlocks = new Dictionary<ulong, ApparatusFlock>(); private static readonly Dictionary<ulong, ApparatusHold> apparatusHolds = new Dictionary<ulong, ApparatusHold>(); private static readonly Dictionary<int, ApparatusLightVisualState> apparatusLightVisualStates = new Dictionary<int, ApparatusLightVisualState>(); private static readonly Dictionary<int, float> nextApparatusDoorOpenTime = new Dictionary<int, float>(); private static readonly Dictionary<ulong, int> apparatusPullFrame = new Dictionary<ulong, int>(); private static readonly Dictionary<ulong, ApparatusDrainProgress> apparatusDrainProgress = new Dictionary<ulong, ApparatusDrainProgress>(); private static readonly Dictionary<ulong, ApparatusLiftState> apparatusLiftStates = new Dictionary<ulong, ApparatusLiftState>(); private static readonly List<ulong> apparatusLiftSweepBuffer = new List<ulong>(); private static readonly HashSet<ulong> announcedApparatusDrains = new HashSet<ulong>(); private static readonly List<ulong> apparatusHoldSweepBuffer = new List<ulong>(); private static StartOfRound? apparatusSessionRound; private static int apparatusSessionSeed = int.MinValue; private static int apparatusSessionLevelId = int.MinValue; private static int apparatusHoldSweepFrame = -1; private static int nextApparatusFlockGeneration; private ApparatusFlock? activeApparatusFlock; private LungProp? cachedApparatus; private int apparatusSlot = -1; private bool apparatusActuallyPerched; private float nextApparatusFlockAllowedTime; private Vector3 apparatusApproachProgressPosition; private float apparatusApproachProgressAt; private float apparatusApproachStartedAt; private float nextApparatusApproachRepathAt; private Vector3 apparatusApproachDetour; private bool apparatusGroundPoseApplied; private static ApparatusHoldDriver? apparatusHoldDriver; private static readonly Dictionary<int, ApparatusShape> apparatusShapes = new Dictionary<int, ApparatusShape>(); [Header("LightBat")] public Transform visualRoot = null; public AudioClip[] flapSounds = null; public AudioClip burningSound = null; public Material burnEdgeMaterial = null; private const float PerchDistance = 1.1f; private const float MovingTargetBreakDistance = 2.2f; private const float FacilityPerchOffset = 0.25f; private const float DroppedFlashlightPerchOffset = 0.65f; private const float ItemLampPerchOffset = 0.28f; private const int CarriedLightTier = 0; private const int FacilityLightTier = 1; private const float DischargedLampValueMultiplier = 0.4f; private const float MinimumFlightHeight = 0.65f; private const float NavMeshProjectionRadius = 3f; private const float MaximumTargetNavOffset = 1.15f; private const float FinalObstacleReleaseDistance = 1.35f; private const float ModelHalfHeight = 0.62f; private const float ModelCollisionRadius = 0.48f; private const float FacilityTargetStuckTime = 4f; private const float FailedFacilityTargetCooldown = 600f; private const float CruiseHeightVariation = 0.72f; private const float HeightLaneStep = 0.618034f; private const float ClearanceLookAheadDistance = 3.8f; private const float ClearanceProbeSpacing = 0.55f; private const float ClearanceProbeRadius = 0.2f; private const float FinalPathProbeRadius = 0.16f; private const float FinalTargetAllowance = 0.28f; private const float HitFearLevel = 0.7f; private const float FleeSafeDistance = 16f; private const float FleeMinimumTime = 1.5f; private const float FleeMaximumTime = 10f; private const float FleeRepathInterval = 0.75f; private const float FleeSpeedMultiplier = 1.85f; private const float LandingFlickerDuration = 0.7f; private const float SharedLampPerchRadius = 0.28f; private const float AdditionalPerchRingSpacing = 0.42f; private const int PerchSlotsPerRing = 12; private const float ActiveAgentRadius = 0.5f; private const float PerchedAgentRadius = 0.05f; private const float RaidAttachDistance = 0.62f; private const float RaidFlashlightForwardOffset = 0.16f; private const float RaidFlashlightVerticalOffset = 0.22f; private const float RaidOrbitRadius = 3.1f; private const float RaidOrbitRingSpacing = 0.42f; private const int RaidOrbitSlotsPerRing = 8; private const float RaidOrbitDegreesPerSecond = 38f; private const float RaidReturnCooldown = 8f; private const float RaidStressLevel = 0.24f; private const float RaidStressInterval = 0.65f; private const float FlashlightDeploymentRetryInterval = 0.65f; private const float FlashlightDeploymentTimeout = 7f; private const float FlashlightHandSettleTime = 0.3f; private const float FlashlightDeploymentFailureCooldown = 1.25f; private const float FlapSoundVolume = 0.55f; private const float MinimumFlapPitch = 1.25f; private const float MaximumFlapPitch = 1.4f; private const float EnergizedDuration = 10f; private const float EnergizedSpeedMultiplier = 1.65f; private const float EnergizedAnimationSpeed = 1.25f; private const float SunlightBurnDuration = 3.8f; private const float SunlightBurnSoundVolume = 0.85f; private const float SunlightBurnEdgeWidth = 0.055f; private const int SunlightBurnIgnitionPointCount = 7; private const float MinimumVisualBoundsExtent = 2.5f; private const int EyeGlowMaterialIndex = 1; private static readonly int EmissiveColorProperty = Shader.PropertyToID("_EmissiveColor"); private static readonly int EmissiveColorLdrProperty = Shader.PropertyToID("_EmissiveColorLDR"); private static readonly int EmissiveIntensityProperty = Shader.PropertyToID("_EmissiveIntensity"); private static readonly int StandardEmissionColorProperty = Shader.PropertyToID("_EmissionColor"); private static readonly Color EyeEnergyColor = new Color(1f, 0.5f, 0.14f, 1f); private static readonly int[] PerchSlotOrder = new int[12] { 0, 6, 3, 9, 1, 7, 4, 10, 2, 8, 5, 11 }; private readonly NetworkVariable<bool> syncedFinalClimb = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<float> syncedCruiseHeightOffset = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<NetworkObjectReference> syncedRaidFlashlight = new NetworkVariable<NetworkObjectReference>(default(NetworkObjectReference), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<NetworkObjectReference> syncedBurnFlashlight = new NetworkVariable<NetworkObjectReference>(default(NetworkObjectReference), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<NetworkObjectReference> syncedBurnLamp = new NetworkVariable<NetworkObjectReference>(default(NetworkObjectReference), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<NetworkObjectReference> syncedBurnApparatus = new NetworkVariable<NetworkObjectReference>(default(NetworkObjectReference), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<int> syncedBurnApparatusSlot = new NetworkVariable<int>(-1, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<bool> syncedEnergized = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<bool> syncedBurningOut = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly NetworkVariable<float> syncedDissolveProgress = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private readonly AISearchRoutine wideSearch = new AISearchRoutine { loopSearch = true, searchWidth = 200f, searchPrecision = 12f, randomized = true }; private readonly Dictionary<int, float> blockedFacilityTargets = new Dictionary<int, float>(); private TargetKind targetKind; private int targetFacilityLightIndex = -1; private FlashlightItem? targetFlashlight; private GrabbableObject? targetLamp; private PlayerControllerB? fleeFromPlayer; private Vector3 fleeDestination; private float nextFleeRepathTime; private float stateTimer; private float retargetCooldown; private Vector3 visualRootStartPosition; private Vector3 targetNavigationPosition; private float targetPathDistance; private float bestTargetPathDistance; private float timeAtLastTargetProgress; private float smoothedVerticalSpeed; private float smoothedYaw; private float yawVelocity; private float previousRootYaw; private float smoothedVisualTurnRate; private Vector3 previousRootPosition; private float smoothedRootSpeed; private Renderer? eyeGlowRenderer; private MaterialPropertyBlock? eyeGlowProperties; private float eyeGlowCharge; private static int heightLaneSequence; private float nextClearanceProbeTime; private float cachedSafeFlightHeight = float.PositiveInfinity; private Coroutine? facilityDrainCoroutine; private Coroutine? facilityFlickerCoroutine; private Coroutine? flashlightDrainCoroutine; private Coroutine? lampDrainCoroutine; private Coroutine? flashlightDeploymentCoroutine; private int nextFlashlightDeploymentRequestId; private int activeLocalFlashlightDeploymentGeneration; private int latestCancelledFlashlightRaidGeneration; private int localRaidAttachmentGeneration; private ulong activeLampDrainId; private bool hasActiveLampDrain; private float lastHitSoundTime = float.NegativeInfinity; private int reservedFacilityAnimatorId = -1; private ulong reservedPerchOwnerId; private int reservedPerchSlot = -1; private Vector3 reservedPerchOffset; private int reservedLampInstanceId = -1; private FlashlightRaid? activeFlashlightRaid; private bool isFlashlightRaidVolunteer; private FlashlightItem? cachedRaidFlashlight; private FlashlightItem? cachedBurnFlashlight; private LungProp? cachedBurnApparatus; private GrabbableObject? cachedBurnLamp; private int flashlightRaidOrbitSlot = -1; private float nextFlashlightRaidAllowedTime; private float nextRaidStressPulseTime; private bool attachedAnimationEnabled; private bool wingFlapTrackingActive; private float previousWingCycle; private int lastFlapSoundIndex = -1; private float energizedUntilTime; private float sunlightBurnStartedAt; private bool deathFallInitialized; private bool deathFallSettled; private float deathFallSpeed; private float deathGroundY; private float deathSettleTimer; private float deathPoseSink; private Mesh? deathPoseMesh; private SkinnedMeshRenderer? deathPoseRenderer; private const float DeathPoseSettleTime = 1.5f; private float burnPlaybackStartedAt; private float displayedDissolveProgress; private bool burnPlaybackInitialized; private bool burnMaterialApplied; private bool burningAudioStarted; private AudioSource? burningAudioSource; private readonly List<BurnMeshState> burnMeshes = new List<BurnMeshState>(); private MaterialPropertyBlock? burnProperties; private static readonly Dictionary<int, SharedFacilityLightState> sharedFacilityLights = new Dictionary<int, SharedFacilityLightState>(); private static readonly Dictionary<ulong, FlashlightRaid> activeFlashlightRaids = new Dictionary<ulong, FlashlightRaid>(); private static readonly HashSet<int> lockedFlashlights = new HashSet<int>(); private static readonly Dictionary<int, ulong> reservedItemLamps = new Dictionary<int, ulong>(); private static readonly HashSet<ulong> activeLampDrains = new HashSet<ulong>(); private static readonly Dictionary<int, LampVisualState> lampVisualStates = new Dictionary<int, LampVisualState>(); private static readonly Dictionary<ulong, LampValueState> lampValueStates = new Dictionary<ulong, LampValueState>(); private bool ApparatusPoseIsGrounded => apparatusGroundPoseApplied; private void ResetApparatusSupportLocally() { //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) EnsureApparatusSessionState(); activeApparatusFlock = null; cachedApparatus = null; apparatusSlot = -1; apparatusActuallyPerched = false; apparatusApproachDetour = Vector3.zero; nextApparatusApproachRepathAt = 0f; ClearApparatusGroundDrainPose(); } private static void EnsureApparatusSessionState() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || (apparatusSessionRound == instance && apparatusSessionSeed == instance.randomMapSeed && apparatusSessionLevelId == instance.currentLevelID)) { return; } apparatusSessionRound = instance; apparatusSessionSeed = instance.randomMapSeed; apparatusSessionLevelId = instance.currentLevelID; foreach (ApparatusFlock value in activeApparatusFlocks.Values) { DestroyApparatusNav(value); } foreach (ApparatusHold value2 in apparatusHolds.Values) { if ((Object)(object)value2.AnchorObject != (Object)null) { Object.Destroy((Object)(object)value2.AnchorObject); } } activeApparatusFlocks.Clear(); apparatusHolds.Clear(); apparatusLightVisualStates.Clear(); apparatusShapes.Clear(); nextApparatusDoorOpenTime.Clear(); apparatusPullFrame.Clear(); apparatusDrainProgress.Clear(); apparatusLiftStates.Clear(); announcedApparatusDrains.Clear(); apparatusHoldSweepBuffer.Clear(); apparatusLiftSweepBuffer.Clear(); nextApparatusFlockGeneration = 0; } private void ResetSyncedApparatusState() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsOwner && ((NetworkBehaviour)this).IsSpawned) { syncedApparatus.Value = default(NetworkObjectReference); syncedApparatusPhase.Value = 0; syncedApparatusSlot.Value = -1; syncedApparatusGeneration.Value = 0; syncedApparatusPerchedCount.Value = 0; syncedApparatusPull.Value = Vector3.zero; syncedApparatusCarryPosition.Value = Vector3.zero; syncedApparatusCarryYaw.Value = 0f; syncedApparatusCarryTick.Value = 0; } } private bool TryStartOrJoinApparatusFlock() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) EnsureApparatusSessionState(); if (!((NetworkBehaviour)this).IsServer || activeApparatusFlock != null || activeFlashlightRaid != null || (Object)(object)StartOfRound.Instance == (Object)null || base.isEnemyDead || syncedBurningOut.Value || Time.time < nextApparatusFlockAllowedTime) { return false; } float num = Mathf.Max(5f, 30f); LungProp val = null; NetworkObject val2 = null; float num2 = num; LungProp[] array = Object.FindObjectsOfType<LungProp>(); NetworkObject val4 = default(NetworkObject); foreach (LungProp val3 in array) { if (ApparatusIsAvailable(val3) && ((Component)val3).TryGetComponent<NetworkObject>(ref val4) && val4.IsSpawned) { float num3 = Vector3.Distance(((Component)this).transform.position, GetApparatusCenter(val3)); if (!(num3 >= num2)) { val = val3; val2 = val4; num2 = num3; } } } if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } ulong networkObjectId = val2.NetworkObjectId; if (activeApparatusFlocks.TryGetValue(networkObjectId, out ApparatusFlock value)) { if (value.Ending || (Object)(object)value.Apparatus == (Object)null) { EndApparatusFlock(value, depleted: false); activeApparatusFlocks.Remove(networkObjectId); return false; } JoinApparatusFlock(value); return true; } ApparatusFlock apparatusFlock = new ApparatusFlock { ApparatusId = networkObjectId, Apparatus = val, Generation = ++nextApparatusFlockGeneration, Phase = ApparatusPhase.Approaching, PhaseEnteredAt = Time.time, Holder = (((GrabbableObject)val).isHeld ? ((GrabbableObject)val).playerHeldBy : null) }; activeApparatusFlocks[networkObjectId] = apparatusFlock; LightBatAI[] array2 = Object.FindObjectsOfType<LightBatAI>(); foreach (LightBatAI lightBatAI in array2) { if (lightBatAI.CanJoinApparatusFlock(val)) { lightBatAI.JoinApparatusFlock(apparatusFlock); } } if (apparatusFlock.Members.Count == 0) { activeApparatusFlocks.Remove(networkObjectId); return false; } LogDebug($"LightBat Apparatus flock #{apparatusFlock.Generation} started with " + $"{apparatusFlock.Members.Count} bats."); return true; } private bool CanJoinApparatusFlock(LungProp apparatus) { //IL_006f: 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) if (!((NetworkBehaviour)this).IsOwner || !((NetworkBehaviour)this).IsServer || !((NetworkBehaviour)this).IsSpawned || base.isEnemyDead || syncedBurningOut.Value || activeApparatusFlock != null || activeFlashlightRaid != null || base.currentBehaviourStateIndex == 4 || Time.time < nextApparatusFlockAllowedTime || !ApparatusIsAvailable(apparatus)) { return false; } return Vector3.Distance(((Component)this).transform.position, GetApparatusCenter(apparatus)) <= Mathf.Max(5f, 30f); } private static bool ApparatusIsAvailable(LungProp apparatus) { if ((Object)(object)apparatus == (Object)null || !((Component)apparatus).gameObject.activeInHierarchy || !apparatus.isLungPowered || ((GrabbableObject)apparatus).scrapValue <= 0 || ((GrabbableObject)apparatus).isPocketed || ((GrabbableObject)apparatus).deactivated) { return false; } if (ApparatusIsDocked(apparatus)) { return false; } if (((GrabbableObject)apparatus).isHeld || (Object)(object)((GrabbableObject)apparatus).playerHeldBy != (Object)null) { PlayerControllerB playerHeldBy = ((GrabbableObject)apparatus).playerHeldBy; return (Object)(object)playerHeldBy != (Object)null && playerHeldBy.isPlayerControlled && !playerHeldBy.isPlayerDead && playerHeldBy.isInsideFactory && !playerHeldBy.isInHangarShipRoom; } return ((GrabbableObject)apparatus).isInFactory && !((GrabbableObject)apparatus).isInShipRoom && !((GrabbableObject)apparatus).isInElevator; } private static bool ApparatusIsPlayerHeld(LungProp apparatus) { return (Object)(object)apparatus != (Object)null && ((GrabbableObject)apparatus).isHeld && !((GrabbableObject)apparatus).isPocketed && (Object)(object)((GrabbableObject)apparatus).playerHeldBy != (Object)null; } private static bool ApparatusIsDocked(LungProp apparatus) { return (Object)(object)apparatus != (Object)null && (apparatus.isLungDocked || apparatus.isLungDockedInElevator); } private static bool ApparatusHasLeftFacility(LungProp apparatus) { if ((Object)(object)apparatus == (Object)null) { return false; } if (((GrabbableObject)apparatus).isHeld && (Object)(object)((GrabbableObject)apparatus).playerHeldBy != (Object)null) { return !((GrabbableObject)apparatus).playerHeldBy.isInsideFactory; } return !((GrabbableObject)apparatus).isInFactory || ((GrabbableObject)apparatus).isInShipRoom || ((GrabbableObject)apparatus).isInElevator; } private void JoinApparatusFlock(ApparatusFlock flock) { //IL_006a: 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_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) if (base.currentSearch.inProgress) { ((EnemyAI)this).StopSearch(base.currentSearch, true); } if (base.currentBehaviourStateIndex == 3) { CancelActiveDrainServerRpc(); } ClearTarget(); activeApparatusFlock = flock; cachedApparatus = flock.Apparatus; apparatusSlot = FindOpenApparatusSlot(flock); apparatusActuallyPerched = false; apparatusApproachProgressPosition = ((Component)this).transform.position; apparatusApproachProgressAt = Time.time; apparatusApproachStartedAt = Time.time; nextApparatusApproachRepathAt = 0f; apparatusApproachDetour = Vector3.zero; flock.Members.Add(this); flock.UnperchedSince = -1f; PublishApparatusState(flock, ApparatusPhase.Approaching); TransitionTo((flock.Phase == ApparatusPhase.Draining) ? State.FlyingToDroppedApparatus : State.FlyingToHeldApparatus); } private static int FindOpenApparatusSlot(ApparatusFlock flock) { int num = 0; bool flag; do { flag = false; foreach (LightBatAI member in flock.Members) { if ((Object)(object)member != (Object)null && member.apparatusSlot == num) { flag = true; num++; break; } } } while (flag); return num; } private void PublishApparatusState(ApparatusFlock flock, ApparatusPhase phase) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = default(NetworkObject); if (((NetworkBehaviour)this).IsOwner && ((NetworkBehaviour)this).IsSpawned && !((Object)(object)flock.Apparatus == (Object)null) && ((Component)flock.Apparatus).TryGetComponent<NetworkObject>(ref val) && val.IsSpawned) { syncedApparatus.Value = new NetworkObjectReference(val); syncedApparatusPhase.Value = (int)phase; syncedApparatusSlot.Value = apparatusSlot; syncedApparatusGeneration.Value = flock.Generation; } } private bool TryGetValidApparatusFlock(out ApparatusFlock flock) { flock = activeApparatusFlock; ApparatusFlock value; return flock != null && !flock.Ending && (Object)(object)flock.Apparatus != (Object)null && flock.Members.Contains(this) && activeApparatusFlocks.TryGetValue(flock.ApparatusId, out value) && value == flock; } private void UpdateApparatusFlockSimulation() { if (((NetworkBehaviour)this).IsServer && TryGetValidApparatusFlock(out ApparatusFlock flock) && flock.SimulatedFrame != Time.frameCount) { flock.SimulatedFrame = Time.frameCount; SimulateApparatusFlock(flock); } } private void SimulateApparatusFlock(ApparatusFlock flock) { LungProp apparatus = flock.Apparatus; if ((Object)(object)apparatus == (Object)null || ((GrabbableObject)apparatus).deactivated) { EndApparatusFlock(flock, depleted: false); return; } PruneApparatusFlockMembers(flock); if (flock.Members.Count == 0) { EndApparatusFlock(flock, depleted: false); return; } int num = CountPerchedApparatusBats(flock); PublishApparatusPerchedCount(flock, num); bool flag = ApparatusIsPlayerHeld(apparatus); flock.Holder = (flag ? ((GrabbableObject)apparatus).playerHeldBy : null); if (!ApparatusIsAvailable(apparatus)) { bool burnMembers = apparatus.isLungPowered && !((GrabbableObject)apparatus).deactivated && ApparatusHasLeftFacility(apparatus); EndApparatusFlock(flock, depleted: false, burnMembers); return; } if (flag) { if (flock.Phase != ApparatusPhase.Perched) { ReleaseApparatusCustody(flock, dropToFloor: false); flock.DrainActive = false; SetApparatusPhase(flock, ApparatusPhase.Perched); } UpdateApparatusPull(flock, num); return; } ClearApparatusPull(flock); switch (flock.Phase) { case ApparatusPhase.Approaching: case ApparatusPhase.Perched: if (num <= 0) { flock.PerchedSince = -1f; if (flock.UnperchedSince < 0f) { flock.UnperchedSince = Time.time; } else if (Time.time - flock.UnperchedSince >= 20f) { EndApparatusFlock(flock, depleted: false); } break; } flock.UnperchedSince = -1f; if (flock.PerchedSince < 0f) { flock.PerchedSince = Time.time; } if (!(Time.time - flock.PerchedSince < 0.45f)) { if (ApparatusIsDocked(apparatus)) { SetApparatusPhase(flock, ApparatusPhase.Draining); } else { BeginApparatusHaul(flock); } } break; case ApparatusPhase.Hauling: UpdateApparatusHaul(flock, num); break; case ApparatusPhase.Draining: UpdateApparatusDrain(flock, num); break; } } private void PruneApparatusFlockMembers(ApparatusFlock flock) { for (int num = flock.Members.Count - 1; num >= 0; num--) { LightBatAI lightBatAI = flock.Members[num]; if ((Object)(object)lightBatAI == (Object)null) { flock.Members.RemoveAt(num); } else if (((EnemyAI)lightBatAI).isEnemyDead || lightBatAI.syncedBurningOut.Value || lightBatAI.activeApparatusFlock != flock) { flock.Members.RemoveAt(num); if (lightBatAI.activeApparatusFlock == flock) { lightBatAI.DetachFromApparatusFlock(6f); } } } } private static int CountPerchedApparatusBats(ApparatusFlock flock) { int num = 0; foreach (LightBatAI member in flock.Members) { if ((Object)(object)member != (Object)null && !((EnemyAI)member).isEnemyDead && member.apparatusActuallyPerched) { num++; } } return num; } private static void PublishApparatusPerchedCount(ApparatusFlock flock, int perched) { flock.PublishedPerchedCount = perched; foreach (LightBatAI member in flock.Members) { if ((Object)(object)member != (Object)null && ((NetworkBehaviour)member).IsOwner && ((NetworkBehaviour)member).IsSpawned && member.syncedApparatusPerchedCount.Value != perched) { member.syncedApparatusPerchedCount.Value = perched; } } } private void SetApparatusPhase(ApparatusFlock flock, ApparatusPhase phase) { if (flock.Phase == phase) { return; } flock.Phase = phase; flock.PhaseEnteredAt = Time.time; flock.PerchedSince = -1f; if (1 == 0) { } State state = phase switch { ApparatusPhase.Hauling => State.CarryingApparatus, ApparatusPhase.Draining => State.DrainingApparatus, ApparatusPhase.Perched => State.PerchedOnHeldApparatus, _ => State.FlyingToHeldApparatus, }; if (1 == 0) { } State state2 = state; foreach (LightBatAI member in flock.Members) { if (!((Object)(object)member == (Object)null) && !((EnemyAI)member).isEnemyDead) { if (!member.apparatusActuallyPerched) { member.PublishApparatusState(flock, ApparatusPhase.Approaching); continue; } member.PublishApparatusState(flock, phase); member.TransitionTo(state2); } } LogDebug($"LightBat Apparatus flock #{flock.Generation} -> {phase}."); } private void FlyToApparatus() { //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_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_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_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_00ac: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_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_01aa: 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_01b6: 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_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_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0237: 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_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) if (!TryGetValidApparatusFlock(out ApparatusFlock flock)) { DetachFromApparatusFlock(6f); return; } LungProp apparatus = flock.Apparatus; if (!ApparatusIsAvailable(apparatus)) { return; } Vector3 apparatusAttachmentPosition = GetApparatusAttachmentPosition(apparatus, apparatusSlot); float num = Vector3.Distance(((Component)this).transform.position, apparatusAttachmentPosition); if (num <= 0.85f) { AttachToApparatus(flock); return; } OpenApparatusDoorsAhead(((Component)this).transform.position, apparatusAttachmentPosition - ((Component)this).transform.position, 3.6f); if (Vector3.Distance(((Component)this).transform.position, apparatusApproachProgressPosition) >= 0.35f) { apparatusApproachProgressPosition = ((Component)this).transform.position; apparatusApproachProgressAt = Time.time; apparatusApproachDetour = Vector3.zero; } else if (Time.time - apparatusApproachProgressAt >= 0.7f) { apparatusApproachProgressAt = Time.time; apparatusApproachDetour = PickApparatusDetour(apparatusAttachmentPosition); nextApparatusApproachRepathAt = 0f; if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { base.agent.ResetPath(); } if (Time.time - apparatusApproachStartedAt >= 7f) { LeaveApparatusFlock(flock, 6f); return; } } Vector3 targetPosition = apparatusAttachmentPosition + apparatusApproachDetour; if (Time.time >= nextApparatusApproachRepathAt || targetNavigationPosition == Vector3.zero) { nextApparatusApproachRepathAt = Time.time + 0.55f; if (!TryGetReachableNavigationPosition(targetPosition, out targetNavigationPosition, out targetPathDistance) && !TryGetReachableNavigationPosition(apparatusAttachmentPosition, out targetNavigationPosition, out targetPathDistance)) { targetNavigationPosition = apparatusAttachmentPosition; targetPathDistance = num; } } SyncVisualTargetHeight(apparatusAttachmentPosition); if ((Object)(object)base.agent != (Object)null) { base.agent.speed = 3.4f; } ((EnemyAI)this).SetDestinationToPosition(targetNavigationPosition, false); } private Vector3 PickApparatusDetour(Vector3 attachPosition) { //IL_0001: 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_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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0037: 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_0066: 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) Vector3 val = attachPosition - ((Component)this).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { return Vector3.zero; } Vector3 val2 = Vector3.Cross(Vector3.up, ((Vector3)(ref val)).normalized); float num = ((Random.value < 0.5f) ? (-1f) : 1f); return val2 * (num * Random.Range(1.6f, 3.2f)); } private void AttachToApparatus(ApparatusFlock flock) { //IL_0017: 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) StopMoving(); PrepareForFlashlightAttachment(); apparatusActuallyPerched = true; apparatusApproachDetour = Vector3.zero; ApparatusPhase apparatusPhase = ((flock.Phase == ApparatusPhase.Approaching) ? ApparatusPhase.Perched : flock.Phase); PublishApparatusState(flock, apparatusPhase); if (1 == 0) { } State state = apparatusPhase switch { ApparatusPhase.Hauling => State.CarryingApparatus, ApparatusPhase.Draining => State.DrainingApparatus, _ => State.PerchedOnHeldApparatus, }; if (1 == 0) { } TransitionTo(state); LockToApparatus(flock.Apparatus, apparatusSlot); } private void UpdateApparatusPull(ApparatusFlock flock, int perched) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0096: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_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_015c: Expected O, but got Unknown //IL_015f: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Invalid comparison between Unknown and I4 //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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) //IL_01e7: 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_0186: 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_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0263: 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_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025c: 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_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026b: 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_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0280: 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_02d7: Unknown result type (might be due to invalid IL or missing references) if (perched <= 0 || (Object)(object)flock.Holder == (Object)null) { ClearApparatusPull(flock); return; } if (flock.PullStartedAt < 0f) { flock.PullStartedAt = Time.time; flock.PullDirection = Vector3.zero; flock.HasPullDestination = false; flock.NextPullDestinationAt = 0f; } PlayerControllerB holder = flock.Holder; Vector3 position = ((Component)holder).transform.position; EnsureApparatusNav(flock, position); if (!flock.HasPullDestination || Time.time >= flock.NextPullDestinationAt || HorizontalDistance(position, flock.PullDestination) < 6f) { flock.NextPullDestinationAt = Time.time + 6f; Vector3 pullDestination = flock.PullDestination; bool hasPullDestination = flock.HasPullDestination; flock.HasPullDestination = TryChooseApparatusDestination(flock, position, 14f, 80f, pullDestination, hasPullDestination, out flock.PullDestination); } Vector3 val = Vector3.zero; if (flock.HasPullDestination && flock.NavReady && flock.Nav.isOnNavMesh) { NavMeshAgent nav = flock.Nav; NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(position, ref val2, 3f, nav.areaMask)) { nav.Warp(((NavMeshHit)(ref val2)).position); } NavMeshPath val3 = new NavMeshPath(); if (nav.CalculatePath(flock.PullDestination, val3) && (int)val3.status != 2) { val = GetFirstMeaningfulPathDirection(val3, position, 1.4f); } } if (((Vector3)(ref val)).sqrMagnitude < 0.01f && flock.HasPullDestination) { val = flock.PullDestination - position; val.y = 0f; } if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = -((Component)holder).transform.forward; val.y = 0f; } if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.forward; } ((Vector3)(ref val)).Normalize(); Vector3 pullDirection; if (!(((Vector3)(ref flock.PullDirection)).sqrMagnitude < 0.01f)) { Vector3 val4 = Vector3.Slerp(flock.PullDirection, val, 1f - Mathf.Exp(-6f * Time.deltaTime)); pullDirection = ((Vector3)(ref val4)).normalized; } else { pullDirection = val; } flock.PullDirection = pullDirection; OpenApparatusDoorsAhead(position + Vector3.up * 0.6f, flock.PullDirection, 3.6f); float num = Mathf.Clamp01((Time.time - flock.PullStartedAt) / 1.2f); num = num * num * (3f - 2f * num); float num2 = Mathf.Min(GetApparatusPullMagnitude(perched) * num, 4f); PublishApparatusPull(flock, flock.PullDirection * num2); } private static float GetApparatusPullMagnitude(int perched) { if (1 == 0) { } float result = ((perched <= 0) ? 0f : (perched switch { 1 => 0.7f, 2 => 1.2f, 3 => 1.9f, 4 => 2.5f, _ => 3.1f, })); if (1 == 0) { } return result; } private static void ClearApparatusPull(ApparatusFlock flock) { //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_001f: Unknown result type (might be due to invalid IL or missing references) flock.PullStartedAt = -1f; flock.PullDirection = Vector3.zero; flock.HasPullDestination = false; PublishApparatusPull(flock, Vector3.zero); } private static void PublishApparatusPull(ApparatusFlock flock, Vector3 pull) { //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_000d: 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_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_008b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = flock.PublishedPull - pull; bool flag = ((Vector3)(ref val)).sqrMagnitude >= 0.0004f; flock.PublishedPull = pull; foreach (LightBatAI member in flock.Members) { if (!((Object)(object)member == (Object)null) && ((NetworkBehaviour)member).IsOwner && ((NetworkBehaviour)member).IsSpawned && (flag || !(member.syncedApparatusPull.Value == pull))) { member.syncedApparatusPull.Value = pull; } } } private void UpdateApparatusPlayerPull() { //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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: 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_0149: 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_0120: 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_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) if (base.isEnemyDead || syncedApparatusPhase.Value != 2 || syncedApparatusPerchedCount.Value <= 0 || (Object)(object)GameNetworkManager.Instance == (Object)null) { return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; NetworkObject val = default(NetworkObject); if ((Object)(object)localPlayerController == (Object)null || localPlayerController.isPlayerDead || localPlayerController.inSpecialInteractAnimation || localPlayerController.isClimbingLadder || !TryGetSyncedApparatus(out LungProp apparatus) || !ApparatusIsPlayerHeld(apparatus) || (Object)(object)((GrabbableObject)apparatus).playerHeldBy != (Object)(object)localPlayerController || !((Component)apparatus).TryGetComponent<NetworkObject>(ref val)) { return; } ulong networkObjectId = val.NetworkObjectId; int frameCount = Time.frameCount; if (!apparatusPullFrame.TryGetValue(networkObjectId, out var value) || value != frameCount) { apparatusPullFrame[networkObjectId] = frameCount; Vector3 val2 = syncedApparatusPull.Value; val2.y = 0f; bool airborne; float num = UpdateApparatusLift(localPlayerController, syncedApparatusPerchedCount.Value, val2, frameCount, out airborne); if (airborne) { val2 = Vector3.ClampMagnitude(val2 * 1.35f, 5.5f); } localPlayerController.externalForces += new Vector3(val2.x, num, val2.z); } } private static float UpdateApparatusLift(PlayerControllerB player, int perched, Vector3 pull, int frame, out bool airborne) { //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_00c6: 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_0166: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) airborne = false; if (perched < 4 || player.isInHangarShipRoom || player.isClimbingLadder || player.inSpecialInteractAnimation || player.isPlayerDead) { ReleaseApparatusLift(player); return 0f; } ulong playerClientId = player.playerClientId; Vector3 position = ((Component)player).transform.position; bool flag = false; if (!apparatusLiftStates.TryGetValue(playerClientId, out ApparatusLiftState value)) { value = new ApparatusLiftState(); apparatusLiftStates[playerClientId] = value; flag = true; EnsureApparatusHoldDriver(); } else if (frame - value.TouchedFrame > 1) { flag = true; value.HoldingVertical = false; value.HasGround = false; } value.TouchedFrame = frame; float groundY; bool flag2 = TryFindApparatusLiftGround(position, out groundY); if (flag2) { value.GroundY = (value.HasGround ? Mathf.MoveTowards(value.GroundY, groundY, 3f * Time.deltaTime) : groundY); value.HasGround = true; } if (flag) { value.Height = (value.HasGround ? Mathf.Clamp(position.y - value.GroundY, 0f, 1.15f) : 0f); } float num; if (!flag2) { num = 0f; } else { float num2 = MeasureApparatusLiftCeiling(player, position, ResolveApparatusLiftDirection(player, pull)); num = Mathf.Min(1.15f, num2 - value.GroundY - 2.6f - 0.3f); if (num < 0.2f) { num = 0f; } } value.Height = Mathf.MoveTowards(value.Height, num, ((num > value.Height) ? 1.1f : 2.6f) * Time.deltaTime); if (value.Height <= 0.01f && num <= 0f) { if (value.HoldingVertical) { value.HoldingVertical = false; NeutralizePlayerFall(player); } return 0f; } value.HoldingVertical = true; airborne = true; NeutralizePlayerFall(player); if (!value.HasGround) { return 0f; } float num3 = position.y - value.GroundY; return Mathf.Clamp((value.Height - num3) * 6f, -4f, 4f); } private static Vector3 ResolveApparatusLiftDirection(PlayerControllerB player, Vector3 pull) { //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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_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_008b: 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_00d4: 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_00e2: Unknown result type (might be due to invalid IL or missing references) Vector3 val = pull; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { ((Vector3)(ref val)).Normalize(); } else { val = Vector3.zero; } if ((Object)(object)player.thisController != (Object)null) { Vector3 velocity = player.thisController.velocity; velocity.y = 0f; if (((Vector3)(ref velocity)).sqrMagnitude > 0.04f) { val += ((Vector3)(ref velocity)).normalized * 1.5f; } } if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { return ((Vector3)(ref val)).normalized; } Vector3 forward = ((Component)player).transform.forward; forward.y = 0f; return (((Vector3)(ref forward)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref forward)).normalized : Vector3.forward; } private static void ReleaseApparatusLift(PlayerControllerB player) { if (apparatusLiftStates.TryGetValue(player.playerClientId, out ApparatusLiftState value)) { apparatusLiftStates.Remove(player.playerClientId); if (value.HoldingVertical) { NeutralizePlayerFall(player); } } } private static void NeutralizePlayerFall(PlayerControllerB player) { player.fallValue = 0f; player.fallValueUncapped = 0f; player.takingFallDamage = false; } private static bool TryFindApparatusLiftGround(Vector3 foot, out float groundY) { //IL_001d: 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_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_0039: 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_0068: 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_0093: Unknown result type (might be due to invalid IL or missing references) int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-1)); groundY = foot.y; RaycastHit[] array = Physics.RaycastAll(foot + Vector3.up * 0.3f, Vector3.down, 12f, num, (QueryTriggerInteraction)1); bool flag = false; float num2 = float.NegativeInfinity; RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit hit = array2[i]; if (ApparatusLiftProbeHitIsWorld(hit) && ((RaycastHit)(ref hit)).point.y > num2) { num2 = ((RaycastHit)(ref hit)).point.y; flag = true; } } if (flag) { groundY = num2; } return flag; } private static float MeasureApparatusLiftCeiling(PlayerControllerB player, Vector3 foot, Vector3 direction) { //IL_004c: 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_0068: 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_00b4: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-1)); float num2 = (((Object)(object)player.thisController != (Object)null) ? Mathf.Clamp(player.thisController.radius, 0.2f, 0.8f) : 0.5f); float num3 = foot.y + num2 + 0.1f; float num4 = 1.6f; RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Vector3(foot.x, num3, foot.z), direction, ref val, 1.6f, num, (QueryTriggerInteraction)1)) { num4 = Mathf.Max(0f, ((RaycastHit)(ref val)).distance - 0.15f); } float num5 = num3 + 8f; for (int i = 0; i <= 2; i++) { Vector3 val2 = foot + direction * (num4 * (float)i * 0.5f) + Vector3.up * (num2 + 0.1f); RaycastHit[] array = Physics.SphereCastAll(val2, num2, Vector3.up, 8f, num, (QueryTriggerInteraction)1); RaycastHit[] array2 = array; for (int j = 0; j < array2.Length; j++) { RaycastHit hit = array2[j]; if (ApparatusLiftProbeHitIsWorld(hit)) { num5 = Mathf.Min(num5, val2.y + ((RaycastHit)(ref hit)).distance + num2); } } } return num5; } private static bool ApparatusLiftProbeHitIsWorld(RaycastHit hit) { return (Object)(object)((RaycastHit)(ref hit)).collider != (Object)null && (Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<GrabbableObject>() == (Object)null && (Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<PlayerControllerB>() == (Object)null; } private static void ExpireApparatusLiftStates() { if (apparatusLiftStates.Count == 0) { return; } apparatusLiftSweepBuffer.Clear(); foreach (KeyValuePair<ulong, ApparatusLiftState> apparatusLiftState in apparatusLiftStates) { if (Time.frameCount - apparatusLiftState.Value.TouchedFrame > 8) { apparatusLiftSweepBuffer.Add(apparatusLiftState.Key); } } foreach (ulong item in apparatusLiftSweepBuffer)