Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Haunted Harpist v1.3.24
BepInEx/plugins/HauntedHarpist/LethalCompanyHarpGhost.dll
Decompiled 6 months 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); }