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);
}