Decompiled source of Haunted Harpist v1.3.24
BepInEx/plugins/HauntedHarpist/LethalCompanyHarpGhost.dll
Decompiled 19 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Formatters.Binary; 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 LethalCompanyHarpGhost.BagpipesGhost; using LethalCompanyHarpGhost.EnforcerGhost; using LethalCompanyHarpGhost.HarpGhost; using LethalCompanyHarpGhost.Items; using LethalCompanyHarpGhost.NetcodePatcher; using LethalCompanyHarpGhost.Types; using LethalLib; using LethalLib.Modules; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.VFX; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("LethalLib")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: AssemblyCompany("Louis")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Lethal Company Haunted Harpist Mod")] [assembly: AssemblyFileVersion("1.3.24.0")] [assembly: AssemblyInformationalVersion("1.3.24+2f1525b26a3a68d11c99b9e88ca0669959bb656f")] [assembly: AssemblyProduct("LethalCompanyHarpGhost")] [assembly: AssemblyTitle("LethalCompanyHarpGhost")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.24.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LethalCompanyHarpGhost { internal static class Assets { internal static AssetBundle MainAssetBundle; private static string GetAssemblyName() { return Assembly.GetExecutingAssembly().FullName.Split(',')[0]; } internal static void LoadAssetBundle(string assetBundleName) { try { AssetBundle mainAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException("Could not find assetbundle: " + assetBundleName), "AssetBundles", assetBundleName)); MainAssetBundle = mainAssetBundle; } catch (Exception arg) { Plugin.logger.LogWarning((object)$"Could not load assetbundle: {arg}"); MainAssetBundle = null; } } internal static IEnumerator LoadAudioClipAsync(string clipName, Action<AudioClip> callback) { if (!((Object)(object)MainAssetBundle == (Object)null)) { AssetBundleRequest request = MainAssetBundle.LoadAssetAsync<AudioClip>(clipName); yield return request; Object asset = request.asset; AudioClip obj = (AudioClip)(object)((asset is AudioClip) ? asset : null); callback?.Invoke(obj); } } } internal static class GhostUtils { internal enum PathStatus { Invalid, ValidButInLos, Valid, Unknown } internal static void AssignCorrectAINodesType(EnemyAI enemyAI) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_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_0065: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)enemyAI).transform.position; Vector3 val = Vector3.positiveInfinity; Vector3 val2 = Vector3.positiveInfinity; GameObject[] array = GameObject.FindGameObjectsWithTag("AINode"); GameObject[] array2 = GameObject.FindGameObjectsWithTag("OutsideAINode"); IEnumerable<Vector3> enumerable = FindInsideAINodePositions(array); IEnumerable<Vector3> enumerable2 = FindOutsideAINodePositions(array2); Vector3 val3; foreach (Vector3 item in enumerable2) { val3 = item - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; val3 = val - position; if (sqrMagnitude < ((Vector3)(ref val3)).sqrMagnitude) { val = item; } } foreach (Vector3 item2 in enumerable) { val3 = item2 - position; float sqrMagnitude2 = ((Vector3)(ref val3)).sqrMagnitude; val3 = val2 - position; if (sqrMagnitude2 < ((Vector3)(ref val3)).sqrMagnitude) { val2 = item2; } } val3 = val - position; float sqrMagnitude3 = ((Vector3)(ref val3)).sqrMagnitude; val3 = val2 - position; enemyAI.allAINodes = ((sqrMagnitude3 < ((Vector3)(ref val3)).sqrMagnitude) ? array2 : array); } internal static IEnumerable<Vector3> FindOutsideAINodePositions(GameObject[] outsideAINodes = null) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (outsideAINodes == null) { outsideAINodes = GameObject.FindGameObjectsWithTag("OutsideAINode"); } Vector3[] array = (Vector3[])(object)new Vector3[outsideAINodes.Length]; for (int i = 0; i < outsideAINodes.Length; i++) { array[i] = outsideAINodes[i].transform.position; } return array; } internal static IEnumerable<Vector3> FindInsideAINodePositions(GameObject[] insideAINodes = null) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (insideAINodes == null) { insideAINodes = GameObject.FindGameObjectsWithTag("AINode"); } Vector3[] array = (Vector3[])(object)new Vector3[insideAINodes.Length]; for (int i = 0; i < insideAINodes.Length; i++) { array[i] = insideAINodes[i].transform.position; } return array; } public static void SafeSet<T>(this NetworkVariable<T> networkVariable, T newValue) where T : IEquatable<T> { if (!EqualityComparer<T>.Default.Equals(networkVariable.Value, newValue)) { networkVariable.Value = newValue; } } internal static bool IsPlayerDead(PlayerControllerB player) { if (!player.isPlayerDead) { return !player.isPlayerControlled; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static PlayerControllerB GetPlayerFromClientId(ulong playerClientId) { return StartOfRound.Instance.allPlayerScripts[playerClientId]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static ulong GetClientIdFromPlayer(PlayerControllerB player) { return player.playerClientId; } } public class MusicalGhost : EnemyAI { internal const ulong NullPlayerId = 69420uL; internal readonly PlayerTargetableConditions PlayerTargetableConditions = new PlayerTargetableConditions(); internal bool HasLineOfSight(Vector3 targetPosition, Transform eyeTransform, float viewWidth = 45f, float viewRange = 60f, float proximityAwareness = -1f) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)eyeTransform)) { return false; } Vector3 position = eyeTransform.position; Vector3 val = targetPosition - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude <= 0.0001f) { return true; } float num = viewRange; if (base.isOutside && !base.enemyType.canSeeThroughFog && (int)TimeOfDay.Instance.currentLevelWeather == 3) { num = Mathf.Clamp(viewRange, 0f, 30f); } float num2 = num * num; if (sqrMagnitude > num2) { return false; } float num3 = Mathf.Sqrt(sqrMagnitude); if (!(proximityAwareness >= 0f) || !(num3 <= proximityAwareness)) { float num4 = Mathf.Clamp(viewWidth, 0f, 180f) * 0.5f * (MathF.PI / 180f); float num5 = Mathf.Cos(num4); float num6 = Vector3.Dot(eyeTransform.forward, val / num3); if (num6 < num5) { return false; } } if (Physics.Linecast(position, targetPosition, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { return false; } return true; } internal PlayerControllerB GetClosestVisiblePlayer(Transform eyeTransform, float viewWidth = 45f, float viewRange = 60f, PlayerControllerB currentTargetPlayer = null, float bufferDistance = 1.5f, float proximityAwareness = -1f) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = null; float num = float.MaxValue; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; float num2 = float.MaxValue; Vector3 val2; if (Object.op_Implicit((Object)(object)currentTargetPlayer) && PlayerTargetableConditions.IsPlayerTargetable(currentTargetPlayer) && HasLineOfSight(((Component)currentTargetPlayer.gameplayCamera).transform.position, eyeTransform, viewWidth, viewRange, proximityAwareness)) { val = currentTargetPlayer; val2 = ((Component)currentTargetPlayer).transform.position - eyeTransform.position; num2 = ((Vector3)(ref val2)).sqrMagnitude; num = num2; } foreach (PlayerControllerB val3 in allPlayerScripts) { if ((Object)(object)val3 == (Object)(object)currentTargetPlayer || !PlayerTargetableConditions.IsPlayerTargetable(val3)) { continue; } Vector3 position = ((Component)val3.gameplayCamera).transform.position; if (HasLineOfSight(position, eyeTransform, viewWidth, viewRange, proximityAwareness)) { val2 = ((Component)val3).transform.position - eyeTransform.position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { val = val3; num = sqrMagnitude; } } } if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)currentTargetPlayer) && (Object)(object)val != (Object)(object)currentTargetPlayer && num > num2 - bufferDistance * bufferDistance) { return currentTargetPlayer; } return val; } protected override void __initializeVariables() { ((EnemyAI)this).__initializeVariables(); } protected override void __initializeRpcs() { ((EnemyAI)this).__initializeRpcs(); } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "MusicalGhost"; } } [BepInPlugin("LethalCompanyHarpGhost", "LethalCompanyHarpGhost", "1.3.24")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class HarpGhostPlugin : BaseUnityPlugin { public const string ModGuid = "HauntedHarpist|1.3.24"; private const string ModName = "Lethal Company Haunted Harpist Mod"; private readonly Harmony _harmony = new Harmony("HauntedHarpist|1.3.24"); private static readonly ManualLogSource Mls = Logger.CreateLogSource("HauntedHarpist|1.3.24"); private static HarpGhostPlugin _instance; private static readonly Dictionary<string, List<AudioClip>> InstrumentAudioClips = new Dictionary<string, List<AudioClip>>(); private static EnemyType _harpGhostEnemyType; private static EnemyType _bagpipesGhostEnemyType; internal static EnemyType EnforcerGhostEnemyType; public static Item HarpItem; public static Item BagpipesItem; private static Item TubaItem; private static Item _plushieItem; public static GameObject ShotgunPrefab; public static RuntimeAnimatorController CustomShotgunAnimator; public static HarpGhostConfig HarpGhostConfig { get; internal set; } public static BagpipeGhostConfig BagpipeGhostConfig { get; internal set; } public static EnforcerGhostConfig EnforcerGhostConfig { get; internal set; } private void Awake() { if ((Object)(object)_instance == (Object)null) { _instance = this; } if (LobbyCompatibilityChecker.Enabled) { LobbyCompatibilityChecker.Init(); } InitializeNetworkStuff(); Assets.LoadAssetBundle("harpghostbundle"); if (!Object.op_Implicit((Object)(object)Assets.MainAssetBundle)) { Mls.LogError((object)"MainAssetBundle is null"); return; } _harmony.PatchAll(); HarpGhostConfig = new HarpGhostConfig(((BaseUnityPlugin)this).Config); BagpipeGhostConfig = new BagpipeGhostConfig(((BaseUnityPlugin)this).Config); EnforcerGhostConfig = new EnforcerGhostConfig(((BaseUnityPlugin)this).Config); SetupHarpGhost(); SetupBagpipesGhost(); SetupEnforcerGhost(); SetupHarp(); SetupBagpipes(); SetupPlushie(); _harmony.PatchAll(); _harmony.PatchAll(typeof(HarpGhostPlugin)); Mls.LogInfo((object)"Plugin Lethal Company Haunted Harpist Mod is loaded!"); } private void SetupHarpGhost() { _harpGhostEnemyType = Assets.MainAssetBundle.LoadAsset<EnemyType>("HarpGhost"); _harpGhostEnemyType.canDie = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostIsKillable.Value; _harpGhostEnemyType.PowerLevel = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostPowerLevel.Value; _harpGhostEnemyType.canBeStunned = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostIsStunnable.Value; _harpGhostEnemyType.MaxCount = SyncedInstance<HarpGhostConfig>.Instance.MaxAmountOfHarpGhosts.Value; _harpGhostEnemyType.stunTimeMultiplier = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostStunTimeMultiplier.Value; _harpGhostEnemyType.stunGameDifficultyMultiplier = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostStunGameDifficultyMultiplier.Value; _harpGhostEnemyType.canSeeThroughFog = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostCanSeeThroughFog.Value; TerminalNode terminalNode = Assets.MainAssetBundle.LoadAsset<TerminalNode>("HarpGhostTN"); TerminalKeyword terminalKeyword = Assets.MainAssetBundle.LoadAsset<TerminalKeyword>("HarpGhostTK"); NetworkPrefabs.RegisterNetworkPrefab(_harpGhostEnemyType.enemyPrefab); Utilities.FixMixerGroups(_harpGhostEnemyType.enemyPrefab); RegisterEnemyWithConfig(SyncedInstance<HarpGhostConfig>.Instance.HarpGhostEnabled.Value, SyncedInstance<HarpGhostConfig>.Instance.HarpGhostSpawnRarity.Value, _harpGhostEnemyType, terminalNode, terminalKeyword); } private void SetupBagpipesGhost() { _bagpipesGhostEnemyType = Assets.MainAssetBundle.LoadAsset<EnemyType>("BagpipesGhost"); _bagpipesGhostEnemyType.canDie = SyncedInstance<BagpipeGhostConfig>.Instance.BagpipeGhostIsKillable.Value; _bagpipesGhostEnemyType.PowerLevel = SyncedInstance<BagpipeGhostConfig>.Instance.BagpipeGhostPowerLevel.Value; _bagpipesGhostEnemyType.canBeStunned = SyncedInstance<BagpipeGhostConfig>.Instance.BagpipeGhostIsStunnable.Value; _bagpipesGhostEnemyType.MaxCount = SyncedInstance<BagpipeGhostConfig>.Instance.MaxAmountOfBagpipeGhosts.Value; _bagpipesGhostEnemyType.stunTimeMultiplier = SyncedInstance<BagpipeGhostConfig>.Instance.BagpipeGhostStunTimeMultiplier.Value; _bagpipesGhostEnemyType.stunGameDifficultyMultiplier = SyncedInstance<BagpipeGhostConfig>.Instance.BagpipeGhostStunGameDifficultyMultiplier.Value; TerminalNode terminalNode = Assets.MainAssetBundle.LoadAsset<TerminalNode>("BagpipeGhostTN"); TerminalKeyword terminalKeyword = Assets.MainAssetBundle.LoadAsset<TerminalKeyword>("BagpipeGhostTK"); NetworkPrefabs.RegisterNetworkPrefab(_bagpipesGhostEnemyType.enemyPrefab); Utilities.FixMixerGroups(_bagpipesGhostEnemyType.enemyPrefab); RegisterEnemyWithConfig(SyncedInstance<BagpipeGhostConfig>.Instance.BagpipeGhostEnabled.Value, SyncedInstance<BagpipeGhostConfig>.Instance.BagpipeGhostSpawnRarity.Value, _bagpipesGhostEnemyType, terminalNode, terminalKeyword); } private void SetupEnforcerGhost() { EnforcerGhostEnemyType = Assets.MainAssetBundle.LoadAsset<EnemyType>("EnforcerGhost"); EnforcerGhostEnemyType.canDie = SyncedInstance<EnforcerGhostConfig>.Instance.EnforcerGhostIsKillable.Value; EnforcerGhostEnemyType.PowerLevel = SyncedInstance<EnforcerGhostConfig>.Instance.EnforcerGhostPowerLevel.Value; EnforcerGhostEnemyType.canBeStunned = SyncedInstance<EnforcerGhostConfig>.Instance.EnforcerGhostIsStunnable.Value; EnforcerGhostEnemyType.MaxCount = SyncedInstance<EnforcerGhostConfig>.Instance.MaxAmountOfEnforcerGhosts.Value; EnforcerGhostEnemyType.stunTimeMultiplier = SyncedInstance<EnforcerGhostConfig>.Instance.EnforcerGhostStunTimeMultiplier.Value; EnforcerGhostEnemyType.stunGameDifficultyMultiplier = SyncedInstance<EnforcerGhostConfig>.Instance.EnforcerGhostStunGameDifficultyMultiplier.Value; TerminalNode terminalNode = Assets.MainAssetBundle.LoadAsset<TerminalNode>("EnforcerGhostTN"); TerminalKeyword terminalKeyword = Assets.MainAssetBundle.LoadAsset<TerminalKeyword>("EnforcerGhostTK"); NetworkPrefabs.RegisterNetworkPrefab(EnforcerGhostEnemyType.enemyPrefab); Utilities.FixMixerGroups(EnforcerGhostEnemyType.enemyPrefab); RegisterEnemyWithConfig(SyncedInstance<EnforcerGhostConfig>.Instance.EnforcerGhostEnabled.Value, SyncedInstance<EnforcerGhostConfig>.Instance.EnforcerGhostSpawnRarity.Value, EnforcerGhostEnemyType, terminalNode, terminalKeyword); CustomShotgunAnimator = Assets.MainAssetBundle.LoadAsset<RuntimeAnimatorController>("AnimatorShotgun"); if ((Object)(object)CustomShotgunAnimator == (Object)null) { Mls.LogError((object)"custom shotgun animator is null"); } } private void SetupHarp() { HarpItem = Assets.MainAssetBundle.LoadAsset<Item>("HarpItemData"); if (!Object.op_Implicit((Object)(object)HarpItem)) { Mls.LogError((object)"Failed to load HarpItemData from AssetBundle."); return; } if (!Object.op_Implicit((Object)(object)HarpItem.spawnPrefab)) { Mls.LogError((object)"Failed to load spawnPrefab from HarpItemData."); return; } NetworkPrefabs.RegisterNetworkPrefab(HarpItem.spawnPrefab); Utilities.FixMixerGroups(HarpItem.spawnPrefab); InstrumentBehaviour component = HarpItem.spawnPrefab.GetComponent<InstrumentBehaviour>(); if (!Object.op_Implicit((Object)(object)component)) { Mls.LogError((object)"Failed to load harp item behaviour script from harp spawnPrefab."); return; } AudioClip[] instrumentAudioClips = component.instrumentAudioClips; List<string> list = new List<string>(); list.AddRange(instrumentAudioClips.Select((AudioClip curAudioClip) => ((Object)curAudioClip).name)); LoadInstrumentAudioClipsAsync(HarpItem.itemName, list); Items.RegisterScrap(HarpItem, 0, (LevelTypes)(-1)); } private void SetupBagpipes() { BagpipesItem = Assets.MainAssetBundle.LoadAsset<Item>("BagpipesItemData"); if (!Object.op_Implicit((Object)(object)BagpipesItem)) { Mls.LogError((object)"Failed to load BagpipesItemData from AssetBundle"); return; } NetworkPrefabs.RegisterNetworkPrefab(BagpipesItem.spawnPrefab); Utilities.FixMixerGroups(BagpipesItem.spawnPrefab); AudioClip[] instrumentAudioClips = BagpipesItem.spawnPrefab.GetComponent<InstrumentBehaviour>().instrumentAudioClips; List<string> list = new List<string>(); list.AddRange(instrumentAudioClips.Select((AudioClip curAudioClip) => ((Object)curAudioClip).name)); LoadInstrumentAudioClipsAsync(BagpipesItem.itemName, list); Items.RegisterScrap(BagpipesItem, 0, (LevelTypes)(-1)); } private static void SetupTuba() { TubaItem = Assets.MainAssetBundle.LoadAsset<Item>("TubaItemData"); if (!Object.op_Implicit((Object)(object)TubaItem)) { Mls.LogError((object)"Failed to load TubaItemData from AssetBundle"); return; } NetworkPrefabs.RegisterNetworkPrefab(TubaItem.spawnPrefab); Utilities.FixMixerGroups(TubaItem.spawnPrefab); Items.RegisterScrap(TubaItem, 0, (LevelTypes)(-1)); } private static void SetupPlushie() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) _plushieItem = Assets.MainAssetBundle.LoadAsset<Item>("GhostPlushieItemData"); if (!Object.op_Implicit((Object)(object)_plushieItem)) { Mls.LogError((object)"Failed to load GhostPlushieItemData from AssetBundle"); return; } _plushieItem.minValue = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Instance.PlushieMinValue.Value, 0, int.MaxValue); _plushieItem.maxValue = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Instance.PlushieMaxValue.Value, 0, int.MaxValue); NetworkPrefabs.RegisterNetworkPrefab(_plushieItem.spawnPrefab); Utilities.FixMixerGroups(_plushieItem.spawnPrefab); Items.RegisterScrap(_plushieItem, Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Instance.PlushieSpawnRate.Value, 0, int.MaxValue), SyncedInstance<HarpGhostConfig>.Instance.PlushieSpawnLevel.Value); } [HarmonyPatch(typeof(Terminal), "Start")] [HarmonyPostfix] private static void GetShotgunPrefab() { for (int i = 0; i < StartOfRound.Instance.allItemsList.itemsList.Count; i++) { Item val = StartOfRound.Instance.allItemsList.itemsList[i]; if (!(((Object)val).name.ToLower() != "shotgun")) { ShotgunPrefab = val.spawnPrefab; break; } } } private void LoadInstrumentAudioClipsAsync(string instrumentName, List<string> audioClipNames) { for (int i = 0; i < audioClipNames.Count; i++) { string audioClipName = audioClipNames[i]; ((MonoBehaviour)this).StartCoroutine(Assets.LoadAudioClipAsync(audioClipName, delegate(AudioClip clip) { if (!InstrumentAudioClips.ContainsKey(instrumentName)) { InstrumentAudioClips[instrumentName] = new List<AudioClip>(); } InstrumentAudioClips[instrumentName].Add(clip); Mls.LogDebug((object)(instrumentName + " audio clip '" + audioClipName + "' loaded asynchronously")); })); } } public static AudioClip GetInstrumentAudioClip(string instrumentName, int index) { if (InstrumentAudioClips.ContainsKey(instrumentName) && index < InstrumentAudioClips[instrumentName].Count) { return InstrumentAudioClips[instrumentName][index]; } return null; } private static void RegisterEnemyWithConfig(bool enemyEnabled, string configMoonRarity, EnemyType enemy, TerminalNode terminalNode, TerminalKeyword terminalKeyword) { if (enemyEnabled) { var (dictionary, dictionary2) = ConfigParsing(configMoonRarity); Enemies.RegisterEnemy(enemy, dictionary, dictionary2, terminalNode, terminalKeyword); } else { Enemies.RegisterEnemy(enemy, 0, (LevelTypes)(-1), terminalNode, terminalKeyword); } } private static (Dictionary<LevelTypes, int> spawnRateByLevelType, Dictionary<string, int> spawnRateByCustomLevelType) ConfigParsing(string configMoonRarity) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Dictionary<LevelTypes, int> dictionary = new Dictionary<LevelTypes, int>(); Dictionary<string, int> dictionary2 = new Dictionary<string, int>(); string[] array = configMoonRarity.Split(','); foreach (string text in array) { string text2 = text.Trim(); string[] array2 = text2.Split(':'); if (array2.Length != 2) { continue; } string text3 = array2[0]; if (!int.TryParse(array2[1], out var result)) { continue; } if (Enum.TryParse<LevelTypes>(text3, ignoreCase: true, out LevelTypes result2)) { dictionary[result2] = result; continue; } string value = text3 + "Level"; if (Enum.TryParse<LevelTypes>(value, ignoreCase: true, out result2)) { dictionary[result2] = result; } else { dictionary2[text3] = result; } } return (dictionary, dictionary2); } private static void InitializeNetworkStuff() { IEnumerable<Type> enumerable; try { enumerable = Assembly.GetExecutingAssembly().GetTypes(); } catch (ReflectionTypeLoadException ex) { enumerable = ex.Types.Where((Type t) => t != null); } foreach (Type item in enumerable) { MethodInfo[] methods = item.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } } } internal static class LobbyCompatibilityChecker { internal static bool Enabled => Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void Init() { PluginHelper.RegisterPlugin("LethalCompanyHarpGhost", Version.Parse("1.3.24"), (CompatibilityLevel)2, (VersionStrictness)3); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "LethalCompanyHarpGhost"; public const string PLUGIN_NAME = "LethalCompanyHarpGhost"; public const string PLUGIN_VERSION = "1.3.24"; } } namespace LethalCompanyHarpGhost.Types { public class CachedList<T> : IEnumerable<T>, IEnumerable { private readonly Func<List<T>> _computeListFunction; private readonly object _lock = new object(); private List<T> _cachedList; private bool _hasValue; public List<T> Value { get { if (!_hasValue) { lock (_lock) { if (!_hasValue) { ComputeAndCacheListInternal(); } } } return _cachedList ?? Enumerable.Empty<T>().ToList(); } } public bool HasValue { get { lock (_lock) { return _hasValue; } } } public CachedList(Func<List<T>> computeListFunction) { _computeListFunction = computeListFunction ?? throw new ArgumentNullException("computeListFunction"); _cachedList = null; _hasValue = false; } public void Reset() { lock (_lock) { _cachedList = null; _hasValue = false; } } private void ComputeAndCacheListInternal() { try { _cachedList = _computeListFunction(); _hasValue = true; } catch { _hasValue = false; throw; } } public IEnumerator<T> GetEnumerator() { return Value.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public class CachedValue<T> { private readonly Func<T> _computeValueFunction; private readonly object _lock = new object(); private T _cachedValue; private bool _hasValue; public T Value { get { if (!_hasValue) { lock (_lock) { if (!_hasValue) { ComputeAndCacheValueInternal(); } } } return _cachedValue; } } public bool HasValue { get { lock (_lock) { return _hasValue; } } } public CachedValue(Func<T> computeValueFunction, bool eager = false) { _computeValueFunction = computeValueFunction ?? throw new ArgumentNullException("computeValueFunction"); _cachedValue = default(T); _hasValue = false; if (eager) { ComputeAndCacheValueInternal(); } } public void Reset() { lock (_lock) { _cachedValue = default(T); _hasValue = false; } } private void ComputeAndCacheValueInternal() { try { _cachedValue = _computeValueFunction(); _hasValue = true; } catch { _hasValue = false; throw; } } } public class PlayerTargetableConditions { private readonly List<Func<PlayerControllerB, bool>> _conditions = new List<Func<PlayerControllerB, bool>>(); public void AddCondition(Func<PlayerControllerB, bool> condition) { _conditions.Add(condition); } public void RemoveCondition(Func<PlayerControllerB, bool> condition) { _conditions.Remove(condition); } public void ClearConditions() { _conditions.Clear(); } public bool IsPlayerTargetable(PlayerControllerB player) { if (!Object.op_Implicit((Object)(object)player)) { return false; } for (int i = 0; i < _conditions.Count; i++) { Func<PlayerControllerB, bool> func = _conditions[i]; if (!func(player)) { return false; } } return true; } } [Serializable] public class SyncedInstance<T> { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestSync; public static HandleNamedMessageDelegate <1>__OnReceiveSync; } [NonSerialized] protected static int IntSize = 4; internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager; internal static bool IsClient => NetworkManager.Singleton.IsClient; internal static bool IsHost => NetworkManager.Singleton.IsHost; public static T Default { get; private set; } public static T Instance { get; private set; } public static bool Synced { get; internal set; } protected void InitInstance(T instance) { Default = instance; Instance = instance; IntSize = 4; } private static void RequestSync() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!IsClient) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(IntSize, (Allocator)2, -1); try { MessageManager.SendNamedMessage("HauntedHarpist|1.3.24_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private static void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (!IsHost) { return; } Debug.Log((object)$"Config sync request received from client: {clientId}"); byte[] array = SerializeToBytes(Instance); int num = array.Length; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num + IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); MessageManager.SendNamedMessage("HauntedHarpist|1.3.24_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3); } catch (Exception arg) { Debug.Log((object)$"Error occurred syncing config with client: {clientId}\n{arg}"); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private static void OnReceiveSync(ulong _, FastBufferReader reader) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((FastBufferReader)(ref reader)).TryBeginRead(IntSize)) { Debug.LogError((object)"Config sync error: Could not begin reading buffer."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); if (!((FastBufferReader)(ref reader)).TryBeginRead(num)) { Debug.LogError((object)"Config sync error: Host could not sync."); return; } byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); SyncInstance(data); Debug.Log((object)"Successfully synced config with host."); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] public static void InitializeLocalPlayer() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (IsHost) { CustomMessagingManager messageManager = MessageManager; object obj = <>O.<0>__OnRequestSync; if (obj == null) { HandleNamedMessageDelegate val = OnRequestSync; <>O.<0>__OnRequestSync = val; obj = (object)val; } messageManager.RegisterNamedMessageHandler("HauntedHarpist|1.3.24_OnRequestConfigSync", (HandleNamedMessageDelegate)obj); Synced = true; return; } Synced = false; CustomMessagingManager messageManager2 = MessageManager; object obj2 = <>O.<1>__OnReceiveSync; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnReceiveSync; <>O.<1>__OnReceiveSync = val2; obj2 = (object)val2; } messageManager2.RegisterNamedMessageHandler("HauntedHarpist|1.3.24_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2); RequestSync(); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")] public static void PlayerLeave() { RevertSync(); } internal static void SyncInstance(byte[] data) { Instance = DeserializeFromBytes(data); Synced = true; } internal static void RevertSync() { Instance = Default; Synced = false; } public static byte[] SerializeToBytes(T val) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream memoryStream = new MemoryStream(); try { binaryFormatter.Serialize(memoryStream, val); return memoryStream.ToArray(); } catch (Exception arg) { Debug.LogError((object)$"Error serializing instance: {arg}"); return null; } } public static T DeserializeFromBytes(byte[] data) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream serializationStream = new MemoryStream(data); try { return (T)binaryFormatter.Deserialize(serializationStream); } catch (Exception arg) { Debug.LogError((object)$"Error deserializing instance: {arg}"); return default(T); } } } } namespace LethalCompanyHarpGhost.Items { public class InstrumentBehaviour : PhysicsProp { [Serializable] public struct ItemOffset : INetworkSerializable { public Vector3 positionOffset; public Vector3 rotationOffset; public ItemOffset(Vector3 positionOffset = default(Vector3), Vector3 rotationOffset = default(Vector3)) { //IL_0006: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) this.positionOffset = default(Vector3); this.rotationOffset = default(Vector3); this.positionOffset = positionOffset; this.rotationOffset = rotationOffset; } public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter { serializer.SerializeValue(ref positionOffset); serializer.SerializeValue(ref rotationOffset); } } private ManualLogSource _mls; private string _instrumentId; public AudioSource instrumentAudioSource; public AudioClip[] instrumentAudioClips; [SerializeField] private AudioLowPassFilter instrumentAudioLowPassFilter; [SerializeField] private AudioHighPassFilter instrumentAudioHighPassFilter; [SerializeField] private AudioEchoFilter instrumentAudioEchoFilter; [SerializeField] private AudioChorusFilter instrumentAudioChorusFilter; [SerializeField] private OccludeAudio instrumentOccludeAudio; private int _timesPlayedWithoutTurningOff; private float _noiseInterval; private float _defaultPitch; private bool _isPlayingMusic; private bool _isInAltPlayerOffset; [SerializeField] private ItemOffset playerInstrumentOffset; [SerializeField] private ItemOffset playerAltInstrumentOffset; [SerializeField] private ItemOffset enemyInstrumentOffset; private void Awake() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_05aa: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Unknown result type (might be due to invalid IL or missing references) string itemName = ((GrabbableObject)this).itemProperties.itemName; switch (itemName) { default: _ = itemName == "Sitar"; break; case "Harp": playerInstrumentOffset = new ItemOffset(new Vector3(-0.8f, 0.22f, 0.07f), new Vector3(3f, 12f, -100f)); playerAltInstrumentOffset = new ItemOffset(new Vector3(-0.4f, 0.2f, -0.1f), new Vector3(-70f, 115f, -200f)); enemyInstrumentOffset = new ItemOffset(new Vector3(0f, -0.6f, 0.6f)); _defaultPitch = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Default.HarpPitch.Value, -3f, 3f); instrumentAudioSource.pitch = _defaultPitch; instrumentAudioSource.volume = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Default.HarpVolume.Value, 0f, 1f); instrumentAudioSource.bypassReverbZones = SyncedInstance<HarpGhostConfig>.Default.HarpBypassReverbZones.Value; instrumentAudioSource.reverbZoneMix = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Default.HarpReverbZoneMix.Value, 0f, 1.1f); instrumentAudioSource.dopplerLevel = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Default.HarpDopplerLevel.Value, 0f, 5f); instrumentAudioSource.spread = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Default.HarpSoundSpread.Value, 0, 360); instrumentAudioSource.maxDistance = Mathf.Clamp((float)SyncedInstance<HarpGhostConfig>.Default.HarpSoundMaxDistance.Value, 0f, float.PositiveInfinity); instrumentAudioLowPassFilter = ((Component)this).GetComponent<AudioLowPassFilter>(); ((Behaviour)instrumentAudioLowPassFilter).enabled = SyncedInstance<HarpGhostConfig>.Default.HarpAudioLowPassFilterEnabled.Value; instrumentAudioLowPassFilter.cutoffFrequency = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Default.HarpAudioLowPassFilterCutoffFrequency.Value, 10, 2200); instrumentAudioLowPassFilter.lowpassResonanceQ = SyncedInstance<HarpGhostConfig>.Default.HarpAudioLowPassFilterLowpassResonanceQ.Value; instrumentAudioHighPassFilter = ((Component)this).GetComponent<AudioHighPassFilter>(); ((Behaviour)instrumentAudioHighPassFilter).enabled = SyncedInstance<HarpGhostConfig>.Default.HarpAudioHighPassFilterEnabled.Value; instrumentAudioHighPassFilter.cutoffFrequency = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Default.HarpAudioHighPassFilterCutoffFrequency.Value, 10, 22000); instrumentAudioHighPassFilter.highpassResonanceQ = SyncedInstance<HarpGhostConfig>.Default.HarpAudioHighPassFilterHighpassResonanceQ.Value; instrumentAudioEchoFilter = ((Component)this).GetComponent<AudioEchoFilter>(); ((Behaviour)instrumentAudioEchoFilter).enabled = SyncedInstance<HarpGhostConfig>.Default.HarpAudioEchoFilterEnabled.Value; instrumentAudioEchoFilter.delay = SyncedInstance<HarpGhostConfig>.Default.HarpAudioEchoFilterDelay.Value; instrumentAudioEchoFilter.decayRatio = Mathf.Clamp(SyncedInstance<HarpGhostConfig>.Default.HarpAudioEchoFilterDecayRatio.Value, 0f, 1f); instrumentAudioEchoFilter.dryMix = SyncedInstance<HarpGhostConfig>.Default.HarpAudioEchoFilterDryMix.Value; instrumentAudioEchoFilter.wetMix = SyncedInstance<HarpGhostConfig>.Default.HarpAudioEchoFilterWetMix.Value; instrumentAudioChorusFilter = ((Component)this).GetComponent<AudioChorusFilter>(); ((Behaviour)instrumentAudioChorusFilter).enabled = SyncedInstance<HarpGhostConfig>.Default.HarpAudioChorusFilterEnabled.Value; instrumentAudioChorusFilter.dryMix = SyncedInstance<HarpGhostConfig>.Default.HarpAudioChorusFilterDryMix.Value; instrumentAudioChorusFilter.wetMix1 = SyncedInstance<HarpGhostConfig>.Default.HarpAudioChorusFilterWetMix1.Value; instrumentAudioChorusFilter.wetMix2 = SyncedInstance<HarpGhostConfig>.Default.HarpAudioChorusFilterWetMix2.Value; instrumentAudioChorusFilter.wetMix3 = SyncedInstance<HarpGhostConfig>.Default.HarpAudioChorusFilterWetMix3.Value; instrumentAudioChorusFilter.delay = SyncedInstance<HarpGhostConfig>.Default.HarpAudioChorusFilterDelay.Value; instrumentAudioChorusFilter.rate = SyncedInstance<HarpGhostConfig>.Default.HarpAudioChorusFilterRate.Value; instrumentAudioChorusFilter.depth = SyncedInstance<HarpGhostConfig>.Default.HarpAudioChorusFilterDepth.Value; instrumentOccludeAudio = ((Component)this).GetComponent<OccludeAudio>(); ((Behaviour)instrumentOccludeAudio).enabled = SyncedInstance<HarpGhostConfig>.Default.HarpOccludeAudioEnabled.Value; instrumentOccludeAudio.useReverb = SyncedInstance<HarpGhostConfig>.Default.HarpOccludeAudioUseReverbEnabled.Value; instrumentOccludeAudio.overridingLowPass = SyncedInstance<HarpGhostConfig>.Default.HarpOccludeAudioOverridingLowPassEnabled.Value; instrumentOccludeAudio.lowPassOverride = SyncedInstance<HarpGhostConfig>.Default.HarpOccludeAudioLowPassOverride.Value; break; case "Bagpipes": playerInstrumentOffset = new ItemOffset(new Vector3(-0.24f, 0.15f, 0.07f), new Vector3(-5f, 15f, -105f)); enemyInstrumentOffset = new ItemOffset(new Vector3(0.5f, -0.25f, 0.4f), new Vector3(0f, 90f, 0f)); _defaultPitch = Mathf.Clamp(SyncedInstance<BagpipeGhostConfig>.Default.BagpipesPitch.Value, -3f, 3f); instrumentAudioSource.pitch = _defaultPitch; instrumentAudioSource.volume = Mathf.Clamp(SyncedInstance<BagpipeGhostConfig>.Default.BagpipesVolume.Value, 0f, 1f); instrumentAudioSource.maxDistance = Mathf.Clamp((float)SyncedInstance<BagpipeGhostConfig>.Default.BagpipesSoundMaxDistance.Value, 0f, float.PositiveInfinity); break; case "Tuba": playerInstrumentOffset = new ItemOffset(new Vector3(-0.4f, 0.2f, -0.1f), new Vector3(-70f, 115f, -200f)); break; } } public override void Start() { ((GrabbableObject)this).Start(); _instrumentId = Guid.NewGuid().ToString(); _mls = Logger.CreateLogSource("HauntedHarpist|1.3.24 | Instrument " + _instrumentId); if (!((NetworkBehaviour)this).IsOwner) { return; } if (!Object.op_Implicit((Object)(object)instrumentAudioSource)) { _mls.LogError((object)"instrumentAudioSource is null!"); return; } if (instrumentAudioClips == null || instrumentAudioClips.Length == 0) { _mls.LogError((object)"instrumentAudioClips is null or empty!"); } _isPlayingMusic = false; } public override void Update() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) ((GrabbableObject)this).Update(); if (!((NetworkBehaviour)this).IsOwner || !_isPlayingMusic) { return; } if ((double)_noiseInterval <= 0.0) { _noiseInterval = 1f; _timesPlayedWithoutTurningOff++; if (((GrabbableObject)this).isHeldByEnemy && SyncedInstance<HarpGhostConfig>.Instance.HarpAudibleByEnemies.Value) { RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, 16f, 3f, _timesPlayedWithoutTurningOff, ((GrabbableObject)this).isInShipRoom && StartOfRound.Instance.hangarDoorsClosed, 540); } } else { _noiseInterval -= Time.deltaTime; } } public override void LateUpdate() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) Vector3 rotationOffset; Vector3 positionOffset; if (((GrabbableObject)this).isHeldByEnemy) { rotationOffset = enemyInstrumentOffset.rotationOffset; positionOffset = enemyInstrumentOffset.positionOffset; } else if (_isInAltPlayerOffset) { rotationOffset = playerAltInstrumentOffset.rotationOffset; positionOffset = playerAltInstrumentOffset.positionOffset; } else { rotationOffset = playerInstrumentOffset.rotationOffset; positionOffset = playerInstrumentOffset.positionOffset; } ((GrabbableObject)this).itemProperties.positionOffset = positionOffset; ((GrabbableObject)this).itemProperties.rotationOffset = rotationOffset; ((GrabbableObject)this).LateUpdate(); } public override void ItemActivate(bool used, bool buttonDown = true) { ((GrabbableObject)this).ItemActivate(used, buttonDown); if (((NetworkBehaviour)this).IsOwner) { if (!_isPlayingMusic) { StartMusicServerRpc(); } else { StopMusicServerRpc(); } ((GrabbableObject)this).isBeingUsed = used; } } private void StartMusic(int clipIndex) { AudioClip val = HarpGhostPlugin.GetInstrumentAudioClip(((GrabbableObject)this).itemProperties.itemName, clipIndex); if (!Object.op_Implicit((Object)(object)val)) { _mls.LogWarning((object)(((GrabbableObject)this).itemProperties.itemName + " audio clips not loaded yet!")); val = instrumentAudioClips[clipIndex]; } instrumentAudioSource.clip = val; instrumentAudioSource.pitch = _defaultPitch; instrumentAudioSource.Play(); WalkieTalkie.TransmitOneShotAudio(instrumentAudioSource, instrumentAudioSource.clip, instrumentAudioSource.volume); _isPlayingMusic = true; } private void StopMusic() { ((MonoBehaviour)this).StartCoroutine(MusicPitchDown()); _timesPlayedWithoutTurningOff = 0; _isPlayingMusic = false; } public override void ItemInteractLeftRight(bool right) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0038: Unknown result type (might be due to invalid IL or missing references) ((GrabbableObject)this).ItemInteractLeftRight(right); if (right && (!(playerAltInstrumentOffset.positionOffset == default(Vector3)) || !(playerInstrumentOffset.rotationOffset == default(Vector3)))) { _isInAltPlayerOffset = !_isInAltPlayerOffset; } } private IEnumerator MusicPitchDown() { int i = 0; while (i < 30) { yield return null; AudioSource obj = instrumentAudioSource; obj.pitch -= 0.033f; if ((double)instrumentAudioSource.pitch <= 0.0) { break; } int num = i + 1; i = num; } instrumentAudioSource.Stop(); } public override void PocketItem() { ((GrabbableObject)this).PocketItem(); StopMusicServerRpc(); } public override void EquipItem() { ((PhysicsProp)this).EquipItem(); ((GrabbableObject)this).isHeld = true; } public override void FallWithCurve() { ((GrabbableObject)this).FallWithCurve(); ((GrabbableObject)this).isHeld = false; ((GrabbableObject)this).isHeldByEnemy = false; } public override void OnHitGround() { ((GrabbableObject)this).OnHitGround(); ((GrabbableObject)this).isHeld = false; ((GrabbableObject)this).isHeldByEnemy = false; StopMusicServerRpc(); } public override void GrabItemFromEnemy(EnemyAI enemy) { ((GrabbableObject)this).GrabItemFromEnemy(enemy); ((GrabbableObject)this).isHeldByEnemy = true; ((GrabbableObject)this).isHeld = true; } public override void DiscardItemFromEnemy() { ((GrabbableObject)this).DiscardItemFromEnemy(); ((GrabbableObject)this).isHeldByEnemy = false; ((GrabbableObject)this).isHeld = false; } [ServerRpc(RequireOwnership = false)] internal void StopMusicServerRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2522209364u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2522209364u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (_isPlayingMusic) { StopMusicClientRpc(); } } } [ClientRpc] private void StopMusicClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3641364563u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3641364563u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; StopMusic(); } } } [ServerRpc(RequireOwnership = false)] internal void StartMusicServerRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(397421066u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 397421066u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (!_isPlayingMusic) { StartMusicClientRpc(Random.Range(0, instrumentAudioClips.Length)); } } } [ClientRpc] private void StartMusicClientRpc(int clipNumber) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(483246262u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, clipNumber); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 483246262u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; StartMusic(clipNumber); } } } protected override void __initializeVariables() { ((PhysicsProp)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(2522209364u, new RpcReceiveHandler(__rpc_handler_2522209364), "StopMusicServerRpc"); ((NetworkBehaviour)this).__registerRpc(3641364563u, new RpcReceiveHandler(__rpc_handler_3641364563), "StopMusicClientRpc"); ((NetworkBehaviour)this).__registerRpc(397421066u, new RpcReceiveHandler(__rpc_handler_397421066), "StartMusicServerRpc"); ((NetworkBehaviour)this).__registerRpc(483246262u, new RpcReceiveHandler(__rpc_handler_483246262), "StartMusicClientRpc"); ((PhysicsProp)this).__initializeRpcs(); } private static void __rpc_handler_2522209364(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((InstrumentBehaviour)(object)target).StopMusicServerRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3641364563(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((InstrumentBehaviour)(object)target).StopMusicClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_397421066(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((InstrumentBehaviour)(object)target).StartMusicServerRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_483246262(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int clipNumber = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref clipNumber); target.__rpc_exec_stage = (__RpcExecStage)1; ((InstrumentBehaviour)(object)target).StartMusicClientRpc(clipNumber); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "InstrumentBehaviour"; } } public class PlushieBehaviour : PhysicsProp { private string _plushieId; [SerializeField] private Material[] plushieMaterialVariants; private CachedValue<NetworkObject> _networkObject; private readonly NetworkVariable<int> _variantIndex = new NetworkVariable<int>(-1, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1); private bool _loadedVariantFromSave; private bool _networkEventsSubscribed; private void Awake() { _networkObject = new CachedValue<NetworkObject>((Func<NetworkObject>)((Component)this).GetComponent<NetworkObject>, eager: true); } private void OnEnable() { SubscribeToNetworkEvents(); } private void OnDisable() { UnsubscribeFromNetworkEvents(); } public override void Start() { ((GrabbableObject)this).Start(); if (((NetworkBehaviour)this).IsServer) { _plushieId = Guid.NewGuid().ToString(); Random.InitState(StartOfRound.Instance.randomMapSeed + _plushieId.GetHashCode()); if (!_loadedVariantFromSave) { _variantIndex.Value = Random.Range(0, plushieMaterialVariants.Length); } } } private void ApplyVariant(int chosenVariantIndex) { if (plushieMaterialVariants.Length != 0) { ((Renderer)((GrabbableObject)this).mainObjectRenderer).material = plushieMaterialVariants[chosenVariantIndex]; } } private void OnVariantIndexChanged(int oldValue, int newValue) { ApplyVariant(newValue); } public override int GetItemDataToSave() { return _variantIndex.Value + 1; } public override void LoadItemSaveData(int saveData) { _loadedVariantFromSave = true; ((MonoBehaviour)this).StartCoroutine(ApplyItemSaveData(saveData - 1)); } private IEnumerator ApplyItemSaveData(int loadedVariantIndex) { while (!_networkObject.Value.IsSpawned) { yield return (object)new WaitForSeconds(0.2f); } _variantIndex.Value = loadedVariantIndex; } private void SubscribeToNetworkEvents() { if (!_networkEventsSubscribed) { NetworkVariable<int> variantIndex = _variantIndex; variantIndex.OnValueChanged = (OnValueChangedDelegate<int>)(object)Delegate.Combine((Delegate?)(object)variantIndex.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<int>(OnVariantIndexChanged)); _networkEventsSubscribed = true; } } private void UnsubscribeFromNetworkEvents() { if (_networkEventsSubscribed) { NetworkVariable<int> variantIndex = _variantIndex; variantIndex.OnValueChanged = (OnValueChangedDelegate<int>)(object)Delegate.Remove((Delegate?)(object)variantIndex.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<int>(OnVariantIndexChanged)); _networkEventsSubscribed = false; } } protected override void __initializeVariables() { if (_variantIndex == null) { throw new Exception("PlushieBehaviour._variantIndex cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_variantIndex).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_variantIndex, "_variantIndex"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_variantIndex); ((PhysicsProp)this).__initializeVariables(); } protected override void __initializeRpcs() { ((PhysicsProp)this).__initializeRpcs(); } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "PlushieBehaviour"; } } } namespace LethalCompanyHarpGhost.HarpGhost { public class HarpGhostAIClient : MonoBehaviour { private ManualLogSource _mls; private string _ghostId; private static readonly int AlternativeColourFadeInTimer = Shader.PropertyToID("_AlternativeColourFadeInTimer"); [SerializeField] private Transform grabTarget; [SerializeField] private Transform eye; [SerializeField] private HarpGhostNetcodeController netcodeController; [Header("Materials and Renderers")] [Space(3f)] [SerializeField] private bool enableGhostAngryModel = true; [SerializeField] private Renderer rendererLeftEye; [SerializeField] private Renderer rendererRightEye; [SerializeField] private MaterialPropertyBlock _propertyBlock; private InstrumentBehaviour _heldInstrument; private PlayerControllerB _targetPlayer; private NetworkObjectReference _instrumentObjectRef; private bool _isTransitioningMaterial; private float _transitioningMaterialTimer; private int _instrumentScrapValue; private void OnEnable() { netcodeController.OnDropHarp += HandleDropInstrument; netcodeController.OnSpawnHarp += HandleSpawnInstrument; netcodeController.OnGrabHarp += HandleGrabInstrument; netcodeController.OnPlayHarpMusic += HandleOnPlayInstrumentMusic; netcodeController.OnStopHarpMusic += HandleOnStopInstrumentMusic; netcodeController.OnChangeTargetPlayer += HandleChangeTargetPlayer; netcodeController.OnDamageTargetPlayer += HandleDamageTargetPlayer; netcodeController.OnIncreaseTargetPlayerFearLevel += HandleIncreaseTargetPlayerFearLevel; netcodeController.OnUpdateGhostIdentifier += HandleUpdateGhostIdentifier; netcodeController.OnGhostEyesTurnRed += HandleGhostEyesTurnRed; } private void OnDisable() { netcodeController.OnDropHarp -= HandleDropInstrument; netcodeController.OnSpawnHarp -= HandleSpawnInstrument; netcodeController.OnGrabHarp -= HandleGrabInstrument; netcodeController.OnPlayHarpMusic -= HandleOnPlayInstrumentMusic; netcodeController.OnStopHarpMusic -= HandleOnStopInstrumentMusic; netcodeController.OnChangeTargetPlayer -= HandleChangeTargetPlayer; netcodeController.OnDamageTargetPlayer -= HandleDamageTargetPlayer; netcodeController.OnIncreaseTargetPlayerFearLevel -= HandleIncreaseTargetPlayerFearLevel; netcodeController.OnUpdateGhostIdentifier -= HandleUpdateGhostIdentifier; netcodeController.OnGhostEyesTurnRed -= HandleGhostEyesTurnRed; } private void Start() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown _mls = Logger.CreateLogSource("HauntedHarpist|1.3.24 | Harp Ghost AI " + _ghostId + " | Client"); _propertyBlock = new MaterialPropertyBlock(); InitializeConfigValues(); } private void InitializeConfigValues() { enableGhostAngryModel = SyncedInstance<HarpGhostConfig>.Default.HarpGhostAngryEyesEnabled.Value; } private void HandleUpdateGhostIdentifier(string receivedGhostId) { _ghostId = receivedGhostId; } private void HandleGhostEyesTurnRed(string receivedGhostId) { if (!(_ghostId != receivedGhostId) && enableGhostAngryModel && !_isTransitioningMaterial) { ((MonoBehaviour)this).StartCoroutine(GhostEyesTurnRed()); } } private IEnumerator GhostEyesTurnRed() { _isTransitioningMaterial = true; _transitioningMaterialTimer = 0f; while (true) { _transitioningMaterialTimer += Time.deltaTime; float num = Mathf.Clamp01(_transitioningMaterialTimer / 5f); rendererLeftEye.GetPropertyBlock(_propertyBlock); rendererRightEye.GetPropertyBlock(_propertyBlock); _propertyBlock.SetFloat(AlternativeColourFadeInTimer, num); rendererLeftEye.SetPropertyBlock(_propertyBlock); rendererRightEye.SetPropertyBlock(_propertyBlock); if (_transitioningMaterialTimer >= 5f) { break; } LogDebug($"Transition material timer: {_transitioningMaterialTimer}"); yield return (object)new WaitForSeconds(0.01f); } } private void HandleIncreaseTargetPlayerFearLevel(string receivedGhostId) { //IL_0040: 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_009a: Unknown result type (might be due to invalid IL or missing references) if (!(_ghostId != receivedGhostId) && Object.op_Implicit((Object)(object)_targetPlayer) && !((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)(object)_targetPlayer)) { if (_targetPlayer.HasLineOfSightToPosition(eye.position, 115f, 50, 3f)) { _targetPlayer.JumpToFearLevel(1f, true); _targetPlayer.IncreaseFearLevelOverTime(0.8f, 1f); } else if (Vector3.Distance(((Component)eye).transform.position, ((Component)_targetPlayer).transform.position) < 3f) { _targetPlayer.JumpToFearLevel(0.6f, true); _targetPlayer.IncreaseFearLevelOverTime(0.4f, 1f); } } } private void HandleOnPlayInstrumentMusic(string receivedGhostId) { if (!(_ghostId != receivedGhostId) && Object.op_Implicit((Object)(object)_heldInstrument)) { _heldInstrument.StartMusicServerRpc(); } } private void HandleOnStopInstrumentMusic(string receivedGhostId) { if (!(_ghostId != receivedGhostId) && Object.op_Implicit((Object)(object)_heldInstrument)) { _heldInstrument.StopMusicServerRpc(); } } private void HandleDropInstrument(string receivedGhostId, Vector3 dropPosition) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!(_ghostId != receivedGhostId) && Object.op_Implicit((Object)(object)_heldInstrument)) { ((GrabbableObject)_heldInstrument).parentObject = null; ((Component)_heldInstrument).transform.SetParent(StartOfRound.Instance.propsContainer, true); ((GrabbableObject)_heldInstrument).EnablePhysics(true); ((GrabbableObject)_heldInstrument).fallTime = 0f; Transform parent; ((GrabbableObject)_heldInstrument).startFallingPosition = (parent = ((Component)_heldInstrument).transform.parent).InverseTransformPoint(((Component)_heldInstrument).transform.position); ((GrabbableObject)_heldInstrument).targetFloorPosition = parent.InverseTransformPoint(dropPosition); ((GrabbableObject)_heldInstrument).floorYRot = -1; ((GrabbableObject)_heldInstrument).grabbable = true; ((GrabbableObject)_heldInstrument).grabbableToEnemies = true; ((GrabbableObject)_heldInstrument).isHeld = false; ((GrabbableObject)_heldInstrument).isHeldByEnemy = false; _heldInstrument.StopMusicServerRpc(); _heldInstrument = null; } } private void HandleGrabInstrument(string receivedGhostId) { NetworkObject val = default(NetworkObject); if (!(_ghostId != receivedGhostId) && !Object.op_Implicit((Object)(object)_heldInstrument) && ((NetworkObjectReference)(ref _instrumentObjectRef)).TryGet(ref val, (NetworkManager)null)) { _heldInstrument = ((Component)val).gameObject.GetComponent<InstrumentBehaviour>(); ((GrabbableObject)_heldInstrument).SetScrapValue(_instrumentScrapValue); ((GrabbableObject)_heldInstrument).parentObject = grabTarget; ((GrabbableObject)_heldInstrument).isHeldByEnemy = true; ((GrabbableObject)_heldInstrument).grabbableToEnemies = false; ((GrabbableObject)_heldInstrument).grabbable = false; } } private void HandleSpawnInstrument(string receivedGhostId, NetworkObjectReference instrumentObject, int instrumentScrapValue) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!(_ghostId != receivedGhostId)) { _instrumentObjectRef = instrumentObject; _instrumentScrapValue = instrumentScrapValue; } } private void HandleChangeTargetPlayer(string receivedGhostId, ulong targetPlayerObjectId) { if (!(_ghostId != receivedGhostId)) { if (targetPlayerObjectId == 69420) { _targetPlayer = null; return; } PlayerControllerB targetPlayer = StartOfRound.Instance.allPlayerScripts[targetPlayerObjectId]; _targetPlayer = targetPlayer; } } private void HandleDamageTargetPlayer(string receivedGhostId, int damage, CauseOfDeath causeOfDeath = 0) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!(_ghostId != receivedGhostId)) { _targetPlayer.DamagePlayer(damage, true, true, causeOfDeath, 0, false, default(Vector3)); } } private void LogDebug(string msg) { } } public class HarpGhostAIServer : MusicalGhost { private enum States { PlayingMusic, SearchingForPlayers, InvestigatingTargetPosition, ChasingTargetPlayer, Dead } private ManualLogSource _mls; private string _ghostId; [Header("AI and Pathfinding")] [Space(5f)] public AISearchRoutine roamMap; public AISearchRoutine searchForPlayers; [SerializeField] private float agentMaxAcceleration = 50f; [SerializeField] private float agentMaxSpeed = 0.3f; [SerializeField] private float annoyanceLevel; [SerializeField] private float annoyanceDecayRate = 0.3f; [SerializeField] private float annoyanceThreshold = 8f; [SerializeField] private float maxSearchRadius = 100f; [SerializeField] private float attackCooldown = 2f; [SerializeField] private float viewWidth = 135f; [SerializeField] private int viewRange = 80; [SerializeField] private int proximityAwareness = 3; [SerializeField] private bool canHearPlayers = true; [SerializeField] private bool friendlyFire = true; [Header("Transforms")] [Space(5f)] [SerializeField] private BoxCollider attackArea; [Header("Controllers and Managers")] [Space(5f)] [SerializeField] private HarpGhostAudioManager audioManager; [SerializeField] private HarpGhostNetcodeController netcodeController; [SerializeField] private HarpGhostAnimationController animationController; private Collider[] attackHitBuffer; private Vector3 _targetPosition; private Vector3 _agentLastPosition; private float _agentCurrentSpeed; private float _timeSinceHittingLocalPlayer; private float _hearNoiseCooldown; private bool _hasBegunInvestigating; private bool _inStunAnimation; private bool _hasTransitionedMaterial; private bool _areNetworkEventsSubscribed; public void OnEnable() { SubscribeToNetworkEvents(); } public void OnDisable() { UnsubscribeFromNetworkEvents(); } public override void Start() { ((EnemyAI)this).Start(); if (((NetworkBehaviour)this).IsServer) { _ghostId = Guid.NewGuid().ToString(); _mls = Logger.CreateLogSource("HauntedHarpist|1.3.24 | Harp Ghost AI " + _ghostId + " | Server"); netcodeController = ((Component)this).GetComponent<HarpGhostNetcodeController>(); if (!Object.op_Implicit((Object)(object)netcodeController)) { _mls.LogError((object)"Netcode Controller is null"); } ((EnemyAI)this).agent = ((Component)this).GetComponent<NavMeshAgent>(); if (!Object.op_Implicit((Object)(object)((EnemyAI)this).agent)) { _mls.LogError((object)("NavMeshAgent component not found on " + ((Object)this).name)); } ((Behaviour)((EnemyAI)this).agent).enabled = true; audioManager = ((Component)this).GetComponent<HarpGhostAudioManager>(); if (!Object.op_Implicit((Object)(object)audioManager)) { _mls.LogError((object)"Audio Manger is null"); } animationController = ((Component)this).GetComponent<HarpGhostAnimationController>(); if (!Object.op_Implicit((Object)(object)animationController)) { _mls.LogError((object)"Animation Controller is null"); } SubscribeToNetworkEvents(); netcodeController.SyncGhostIdentifierClientRpc(_ghostId); Random.InitState(StartOfRound.Instance.randomMapSeed + _ghostId.GetHashCode() - ((EnemyAI)this).thisEnemyIndex); InitializeConfigValues(); attackHitBuffer = (Collider[])(object)new Collider[20]; PlayerTargetableConditions.AddCondition((PlayerControllerB player) => !GhostUtils.IsPlayerDead(player)); PlayerTargetableConditions.AddCondition((PlayerControllerB player) => !player.isInHangarShipRoom); PlayerTargetableConditions.AddCondition((PlayerControllerB player) => (double)player.sinkingValue < 0.7300000190734863); netcodeController.ChangeAnimationParameterBoolClientRpc(_ghostId, HarpGhostAnimationController.IsDead, value: false); netcodeController.ChangeAnimationParameterBoolClientRpc(_ghostId, HarpGhostAnimationController.IsStunned, value: false); netcodeController.ChangeAnimationParameterBoolClientRpc(_ghostId, HarpGhostAnimationController.IsRunning, value: false); netcodeController.SpawnHarpServerRpc(_ghostId); netcodeController.GrabHarpClientRpc(_ghostId); ((MonoBehaviour)this).StartCoroutine(DelayedHarpMusicActivate()); LogDebug("Harp Ghost Spawned"); } } private void FixedUpdate() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) if (((NetworkBehaviour)this).IsServer) { Vector3 position = ((Component)this).transform.position; float agentCurrentSpeed = _agentCurrentSpeed; Vector3 val = position - _agentLastPosition; _agentCurrentSpeed = Mathf.Lerp(agentCurrentSpeed, ((Vector3)(ref val)).magnitude / Time.deltaTime, 0.75f); _agentLastPosition = position; } } public override void Update() { //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).Update(); if (!((NetworkBehaviour)this).IsServer) { return; } CalculateAgentSpeed(); if ((double)((EnemyAI)this).stunNormalizedTimer <= 0.0 && _inStunAnimation && !((EnemyAI)this).isEnemyDead) { netcodeController.ChangeAnimationParameterBoolClientRpc(_ghostId, HarpGhostAnimationController.IsStunned, value: false); _inStunAnimation = false; } if (StartOfRound.Instance.allPlayersDead) { netcodeController.ChangeAnimationParameterBoolClientRpc(_ghostId, HarpGhostAnimationController.IsRunning, value: false); return; } _timeSinceHittingLocalPlayer += Time.deltaTime; _hearNoiseCooldown -= Time.deltaTime; switch (((EnemyAI)this).currentBehaviourStateIndex) { case 0: if (annoyanceLevel > 0f) { annoyanceLevel -= annoyanceDecayRate * Time.deltaTime; annoyanceLevel = Mathf.Clamp(annoyanceLevel, 0f, float.PositiveInfinity); } if (annoyanceLevel >= annoyanceThreshold) { TurnGhostEyesRed(); netcodeController.PlayCreatureVoiceClientRpc(_ghostId, 4, audioManager.upsetSfx.Length); if (_targetPosition != default(Vector3)) { SwitchBehaviourStateLocally(2); } else { SwitchBehaviourStateLocally(1); } } break; case 1: case 2: case 3: RunAnimation(); break; case 4: break; } } public override void DoAIInterval() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).DoAIInterval(); if (!((NetworkBehaviour)this).IsServer) { return; } switch (((EnemyAI)this).currentBehaviourStateIndex) { case 0: if (searchForPlayers.inProgress) { ((EnemyAI)this).StopSearch(searchForPlayers, true); } if (!roamMap.inProgress) { ((EnemyAI)this).StartSearch(((Component)this).transform.position, roamMap); } break; case 1: { if (roamMap.inProgress) { ((EnemyAI)this).StopSearch(roamMap, true); } PlayerControllerB val = ((EnemyAI)this).CheckLineOfSightForClosestPlayer(viewWidth, viewRange, proximityAwareness, 0f); if (Object.op_Implicit((Object)(object)val)) { BeginChasingPlayer(GhostUtils.GetClientIdFromPlayer(val)); SwitchBehaviourStateLocally(3); } else if (!searchForPlayers.inProgress) { if (_targetPosition != default(Vector3) && CheckForPath(_targetPosition)) { searchForPlayers.searchWidth = 30f; ((EnemyAI)this).StartSearch(_targetPosition, searchForPlayers); } else { searchForPlayers.searchWidth = 100f; ((EnemyAI)this).StartSearch(((Component)this).transform.position, searchForPlayers); LogDebug("Started search"); } } break; } case 2: { if (roamMap.inProgress) { ((EnemyAI)this).StopSearch(roamMap, true); } if (searchForPlayers.inProgress) { ((EnemyAI)this).StopSearch(searchForPlayers, true); } PlayerControllerB val2 = ((EnemyAI)this).CheckLineOfSightForClosestPlayer(viewWidth, viewRange, proximityAwareness, 0f); if (Object.op_Implicit((Object)(object)val2)) { BeginChasingPlayer(GhostUtils.GetClientIdFromPlayer(val2)); SwitchBehaviourStateLocally(3); break; } if (!_hasBegunInvestigating) { if (_targetPosition == default(Vector3)) { SwitchBehaviourStateLocally(1); } else { if (!((EnemyAI)this).SetDestinationToPosition(_targetPosition, true)) { SwitchBehaviourStateLocally(1); break; } _hasBegunInvestigating = true; } } if (Vector3.Distance(((Component)this).transform.position, _targetPosition) <= 1f) { SwitchBehaviourStateLocally(1); } break; } case 3: { if (roamMap.inProgress) { ((EnemyAI)this).StopSearch(roamMap, true); } if (searchForPlayers.inProgress) { ((EnemyAI)this).StopSearch(searchForPlayers, true); } PlayerControllerB closestVisiblePlayer = GetClosestVisiblePlayer(((EnemyAI)this).eye, viewWidth, viewRange, ((EnemyAI)this).targetPlayer, 1.5f, proximityAwareness); if (!Object.op_Implicit((Object)(object)closestVisiblePlayer)) { SwitchBehaviourStateLocally(2); break; } if ((Object)(object)closestVisiblePlayer != (Object)(object)((EnemyAI)this).targetPlayer) { BeginChasingPlayer(GhostUtils.GetClientIdFromPlayer(closestVisiblePlayer)); } _targetPosition = ((Component)((EnemyAI)this).targetPlayer).transform.position; netcodeController.IncreaseTargetPlayerFearLevelClientRpc(_ghostId); if (Vector3.Distance(((Component)this).transform.position, ((Component)((EnemyAI)this).targetPlayer).transform.position) < 8f) { AttackPlayerIfClose(); } break; } case 4: if (roamMap.inProgress) { ((EnemyAI)this).StopSearch(roamMap, true); } if (searchForPlayers.inProgress) { ((EnemyAI)this).StopSearch(searchForPlayers, true); } break; } } private void SwitchBehaviourStateLocally(int state) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsServer) { switch (state) { case 0: LogDebug($"Switched to behaviour state {0}!"); agentMaxSpeed = 0.3f; agentMaxAcceleration = 50f; ((EnemyAI)this).movingTowardsTargetPlayer = false; _targetPosition = default(Vector3); _hasBegunInvestigating = false; ((EnemyAI)this).openDoorSpeedMultiplier = 6f; netcodeController.ChangeTargetPlayerClientRpc(_ghostId, 69420uL); break; case 1: LogDebug($"Switched to behaviour state {1}!"); agentMaxSpeed = 3f; agentMaxAcceleration = 100f; ((EnemyAI)this).movingTowardsTargetPlayer = false; _hasBegunInvestigating = false; ((EnemyAI)this).openDoorSpeedMultiplier = 2f; _targetPosition = default(Vector3); netcodeController.DropHarpClientRpc(_ghostId, ((Component)this).transform.position); break; case 2: LogDebug($"Switched to behaviour state {2}!"); agentMaxSpeed = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostMaxSpeedInChaseMode.Value; agentMaxAcceleration = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostMaxAccelerationInChaseMode.Value; ((EnemyAI)this).movingTowardsTargetPlayer = false; _hasBegunInvestigating = false; ((EnemyAI)this).openDoorSpeedMultiplier = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostDoorSpeedMultiplierInChaseMode.Value; netcodeController.DropHarpClientRpc(_ghostId, ((Component)this).transform.position); break; case 3: LogDebug($"Switched to behaviour state {3}!"); agentMaxSpeed = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostMaxSpeedInChaseMode.Value; agentMaxAcceleration = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostMaxAccelerationInChaseMode.Value; ((EnemyAI)this).movingTowardsTargetPlayer = true; _hasBegunInvestigating = false; _targetPosition = default(Vector3); ((EnemyAI)this).openDoorSpeedMultiplier = SyncedInstance<HarpGhostConfig>.Instance.HarpGhostDoorSpeedMultiplierInChaseMode.Value; netcodeController.DropHarpClientRpc(_ghostId, ((Component)this).transform.position); break; case 4: LogDebug($"Switched to behaviour state {4}!"); agentMaxSpeed = 0f; agentMaxAcceleration = 0f; ((EnemyAI)this).movingTowardsTargetPlayer = false; ((EnemyAI)this).agent.speed = 0f; ((Behaviour)((EnemyAI)this).agent).enabled = false; ((EnemyAI)this).isEnemyDead = true; _hasBegunInvestigating = false; _targetPosition = default(Vector3); netcodeController.ChangeTargetPlayerClientRpc(_ghostId, 69420uL); netcodeController.DropHarpClientRpc(_ghostId, ((Component)this).transform.position); netcodeController.ChangeAnimationParameterBoolClientRpc(_ghostId, HarpGhostAnimationController.IsDead, value: true); break; } if (((EnemyAI)this).currentBehaviourStateIndex != state) { ((EnemyAI)this).previousBehaviourStateIndex = ((EnemyAI)this).currentBehaviourStateIndex; ((EnemyAI)this).currentBehaviourStateIndex = state; } } } public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitId = -1) { ((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitId); if (!((NetworkBehaviour)this).IsServer || ((EnemyAI)this).isEnemyDead) { return; } bool flag = !Object.op_Implicit((Object)(object)playerWhoHit); if (!(!friendlyFire && flag)) { ((EnemyAI)this).enemyHP = ((EnemyAI)this).enemyHP - force; if (((EnemyAI)this).enemyHP <= 0) { ((EnemyAI)this).KillEnemyClientRpc(false); } else if (!flag) { TurnGhostEyesRed(); netcodeController.PlayCreatureVoiceClientRpc(_ghostId, 1, audioManager.damageSfx.Length); netcodeController.ChangeTargetPlayerClientRpc(_ghostId, playerWhoHit.playerClientId); SwitchBehaviourStateLocally(3); } } } public override void KillEnemy(bool destroy = false) { ((EnemyAI)this).KillEnemy(destroy); if (((NetworkBehaviour)this).IsServer) { netcodeController.EnterDeathStateClientRpc(_ghostId); SwitchBehaviourStateLocally(4); } } public override void SetEnemyStunned(bool setToStunned, float setToStunTime = 1f, PlayerControllerB setStunnedByPlayer = null) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).SetEnemyStunned(setToStunned, setToStunTime, setStunnedByPlayer); if (((NetworkBehaviour)this).IsServer) { TurnGhostEyesRed(); netcodeController.PlayCreatureVoiceClientRpc(_ghostId, 3, audioManager.stunSfx.Length); netcodeController.DropHarpClientRpc(_ghostId, ((Component)this).transform.position); netcodeController.ChangeAnimationParameterBoolClientRpc(_ghostId, HarpGhostAnimationController.IsStunned, value: true); netcodeController.DoAnimationClientRpc(_ghostId, HarpGhostAnimationController.IsStunned); _inStunAnimation = true; if (Object.op_Implicit((Object)(object)setStunnedByPlayer)) { netcodeController.ChangeTargetPlayerClientRpc(_ghostId, setStunnedByPlayer.playerClientId); SwitchBehaviourStateLocally(3); } else if (((EnemyAI)this).currentBehaviourStateIndex == 0) { SwitchBehaviourStateLocally(1); } } } private void TurnGhostEyesRed() { if (((NetworkBehaviour)this).IsServer && !_hasTransitionedMaterial) { _hasTransitionedMaterial = true; netcodeController.TurnGhostEyesRedClientRpc(_ghostId); } } private void AttackPlayerIfClose() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || ((EnemyAI)this).currentBehaviourStateIndex != 3 || _timeSinceHittingLocalPlayer < attackCooldown || _inStunAnimation) { return; } int num = Physics.OverlapBoxNonAlloc(((Component)attackArea).transform.position, attackArea.size * 0.5f, attackHitBuffer, Quaternion.identity, 8, (QueryTriggerInteraction)1); if (num <= 0) { return; } for (int i = 0; i < attackHitBuffer.Length; i++) { Collider collider = attackHitBuffer[i]; PlayerControllerB val = PlayerMeetsStandardCollisionConditions(collider); if (Object.op_Implicit((Object)(object)val)) { netcodeController.ChangeTargetPlayerClientRpc(_ghostId, val.playerClientId); _timeSinceHittingLocalPlayer = 0f; netcodeController.DoAnimationClientRpc(_ghostId, HarpGhostAnimationController.Attack); break; } } } private IEnumerator DelayedHarpMusicActivate() { yield return (object)new WaitForSeconds(0.5f); netcodeController.PlayHarpMusicClientRpc(_ghostId); }