Decompiled source of VepMod v1.0.3
VepMod.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using Photon.Voice; using REPOLib.Objects.Sdk; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.AI; using UnityEngine.Animations; using UnityEngine.SceneManagement; using UnityEngine.UI; using VepMod.Enemies.Whispral; using VepMod.Patchs; using VepMod.VepFramework; using VepMod.VepFramework.Config; using VepMod.VepFramework.Extensions; using VepMod.VepFramework.Structures.FSM; using VepMod.VepFramework.Structures.Range; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Vep")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+964f939a0a8b38515bbd611a6cc973183debaf02")] [assembly: AssemblyProduct("VepMod")] [assembly: AssemblyTitle("VepMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 VepMod { public static class ConfigRanges { public static readonly RangeValue<float> Volume = RangeValue.Percentage(); public static readonly RangeValue<int> SamplesPerPlayer = RangeValue.Int(5, 20, 20); public static readonly RangeValue<int> SamplingRate = RangeValue.Int(16000, 48000, 48000); public static readonly MinMaxRange<float> ShareDelay = MinMaxRange.Float(10f, 60f, 10f, 10f, 120f, 30f); public static readonly MinMaxRange<float> VoiceDelay = MinMaxRange.Float(6f, 30f, 8f, 6f, 30f, 15f); } [BepInPlugin("com.vep.vepMod", "VepMod", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class VepMod : BaseUnityPlugin { private static Harmony _harmony; public static ConfigEntry<float> ConfigVoiceVolume; public static ConfigEntry<int> ConfigSamplingRate; public static BoundMinMaxRange<float> ShareDelay; public static ConfigEntry<int> ConfigSamplesPerPlayer; public static BoundMinMaxRange<float> VoiceDelay; public static ConfigEntry<bool> ConfigVoiceFilterEnabled; public static readonly Dictionary<string, ConfigEntry<bool>> EnemyConfigEntries = new Dictionary<string, ConfigEntry<bool>>(); internal Harmony? Harmony { get; set; } private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _harmony = new Harmony("VepMod.Plugin"); PreventDelete(); InitConfig(); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); ((MonoBehaviour)this).StartCoroutine(DroidPrefabLoader.PreloadAsync(delegate(bool success) { if (success) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"LostDroid prefab preloaded successfully."); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"LostDroid prefab preload failed - hallucinations may not work."); } })); } public void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Scene loaded: " + ((Scene)(ref scene)).name)); } private void InitConfig() { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown ((BaseUnityPlugin)this).Logger.LogInfo((object)"Initializing config for VepMod..."); ConfigVoiceVolume = ((BaseUnityPlugin)this).Config.BindRange("General", "Volume", ConfigRanges.Volume, "Volume of the mimic voices."); ShareDelay = ((BaseUnityPlugin)this).Config.BindMinMax("Audio Sharing", "Share Min Delay", "Share Max Delay", ConfigRanges.ShareDelay, "Minimum time between sharing audio clips with other players.", "Maximum time between sharing audio clips with other players."); ConfigSamplesPerPlayer = ((BaseUnityPlugin)this).Config.BindRange("Audio Sharing", "Samples Per Player", ConfigRanges.SamplesPerPlayer, "Maximum number of audio samples stored per player."); VoiceDelay = ((BaseUnityPlugin)this).Config.BindMinMax("Voice Playback", "Voice Min Delay", "Voice Max Delay", ConfigRanges.VoiceDelay, "Minimum time between voice playback commands during Whispral debuff.", "Maximum time between voice playback commands during Whispral debuff."); ConfigVoiceFilterEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Voice Playback", "Voice Filter Enabled?", false, new ConfigDescription("Turning this will enable modifiable filters for which enemies can play back voices during the Whispral debuff.", (AcceptableValueBase)null, Array.Empty<object>())); ConfigSamplingRate = ((BaseUnityPlugin)this).Config.BindRange("Experimental", "Sampling Rate", ConfigRanges.SamplingRate, "Only change this value if the console gives you a warning about your microphone frequency not being supported."); } private void PreventDelete() { ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; } internal void Unpatch() { _harmony.UnpatchSelf(); } } } namespace VepMod.VepFramework { public sealed class VepLogger { private const string Prefix = "VepMod"; private readonly ManualLogSource _log; public bool DebugEnabled { get; set; } private VepLogger(string className, bool debugEnabled = false) { _log = Logger.CreateLogSource("VepMod." + className); DebugEnabled = debugEnabled; } public static VepLogger Create<T>(bool debugEnabled = false) { return new VepLogger(typeof(T).Name, debugEnabled); } public static VepLogger Create(string className, bool debugEnabled = false) { return new VepLogger(className, debugEnabled); } public void Debug(string message) { if (DebugEnabled) { _log.LogDebug((object)message); } } public void Info(string message) { _log.LogInfo((object)message); } public void Warning(string message) { _log.LogWarning((object)message); } public void Error(string message) { _log.LogError((object)message); } } } namespace VepMod.VepFramework.Structures.Range { public sealed class MinMaxRange<T> where T : struct, IComparable<T> { public RangeValue<T> MinRange { get; } public RangeValue<T> MaxRange { get; } public MinMaxRange(RangeValue<T> minRange, RangeValue<T> maxRange) { MinRange = minRange; MaxRange = maxRange; } public T GetMin(T minValue, T maxValue) { if (minValue.CompareTo(maxValue) > 0) { return maxValue; } return minValue; } public T GetMax(T minValue, T maxValue) { if (maxValue.CompareTo(minValue) < 0) { return minValue; } return maxValue; } } public static class MinMaxRange { public static MinMaxRange<float> Float(float minLower, float minUpper, float minDefault, float maxLower, float maxUpper, float maxDefault) { return new MinMaxRange<float>(RangeValue.Float(minLower, minUpper, minDefault), RangeValue.Float(maxLower, maxUpper, maxDefault)); } } public sealed class RangeValue<T> where T : struct, IComparable<T> { public T Min { get; } public T Max { get; } public T Default { get; } public RangeValue(T min, T max, T defaultValue) { if (min.CompareTo(max) > 0) { throw new ArgumentException($"Min ({min}) cannot be greater than Max ({max})"); } Min = min; Max = max; Default = Clamp(defaultValue); } public T Clamp(T value) { if (value.CompareTo(Min) < 0) { return Min; } if (value.CompareTo(Max) > 0) { return Max; } return value; } } public static class RangeValue { public static RangeValue<float> Float(float min, float max, float defaultValue) { return new RangeValue<float>(min, max, defaultValue); } public static RangeValue<int> Int(int min, int max, int defaultValue) { return new RangeValue<int>(min, max, defaultValue); } public static RangeValue<float> Percentage(float defaultValue = 1f) { return new RangeValue<float>(0f, 1f, defaultValue); } } } namespace VepMod.VepFramework.Structures.FSM { public class StateMachineBase<TMachine, TStateId> where TMachine : StateMachineBase<TMachine, TStateId> { public class StateBase { public TMachine Machine { get; set; } public virtual void OnStateEnter(TStateId previous) { } public virtual void OnStateExit(TStateId next) { } public virtual void OnStateUpdate() { } } public class StateBaseTimed : StateBase { public float TimeElapsed { get; protected set; } public override void OnStateEnter(TStateId previous) { base.OnStateEnter(previous); TimeElapsed = 0f; } public override void OnStateUpdate() { base.OnStateUpdate(); TimeElapsed += Time.deltaTime; } } public class StateBaseTransition : StateBaseTimed { public float Duration; public TStateId NextState; public StateBaseTransition(float duration, TStateId nextState) { Duration = duration; NextState = nextState; } public override void OnStateEnter(TStateId previous) { base.OnStateEnter(previous); if (Duration <= 0f) { base.Machine.NextStateStateId = NextState; } } public override void OnStateUpdate() { base.OnStateUpdate(); if (base.TimeElapsed >= Duration) { base.Machine.NextStateStateId = NextState; } } } private readonly StateBase Default = new StateBase(); private readonly Dictionary<TStateId, StateBase> states = new Dictionary<TStateId, StateBase>(); private StateBase _currentStateBaseRunning; public TStateId CurrentStateStateId { get; private set; } public TStateId NextStateStateId { get; set; } public StateMachineBase(TStateId defaultStateId) { CurrentStateStateId = defaultStateId; NextStateStateId = defaultStateId; } public void AddState(TStateId stateId, StateBase stateBase) { stateBase.Machine = this as TMachine; if (states.ContainsKey(stateId)) { Debug.LogWarning((object)$"[FSM] Fsm already defines a state with key {stateId}, it will be overidden"); } states[stateId] = stateBase; } public StateBase GetState(TStateId stateId) { if (!states.TryGetValue(stateId, out StateBase value)) { return Default; } return value; } public T GetStateTyped<T>(TStateId stateId) where T : StateBase { return GetState(stateId) as T; } private void RefreshStatesIO() { for (StateBase state = GetState(NextStateStateId); state != _currentStateBaseRunning; state = GetState(NextStateStateId)) { TStateId nextStateStateId = NextStateStateId; _currentStateBaseRunning?.OnStateExit(nextStateStateId); if (!states.ContainsKey(nextStateStateId)) { Debug.LogWarning((object)$"[FSM] Fsm does not define any state with key {nextStateStateId}, it will play default state"); } _currentStateBaseRunning = GetState(nextStateStateId); _currentStateBaseRunning?.OnStateEnter(CurrentStateStateId); CurrentStateStateId = nextStateStateId; } } public void Update() { RefreshStatesIO(); _currentStateBaseRunning?.OnStateUpdate(); RefreshStatesIO(); } } public abstract class StateMachineComponent<TOwner, TStateId> : MonoBehaviour where TOwner : StateMachineComponent<TOwner, TStateId> { protected sealed class StateMachine : StateMachineBase<StateMachine, TStateId> { public TOwner Owner { get; } public StateMachine(TOwner owner, TStateId defaultKey) : base(defaultKey) { Owner = owner; } } protected StateMachine Fsm; protected abstract TStateId DefaultState { get; } protected virtual void Awake() { Fsm = new StateMachine(this as TOwner, DefaultState); } protected virtual void Update() { Fsm.Update(); } } } namespace VepMod.VepFramework.Extensions { public static class TaskExtensions { [CompilerGenerated] private sealed class <AsCoroutine>d__0 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Task task; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AsCoroutine>d__0(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (!task.IsCompleted) { <>2__current = null; <>1__state = 1; return true; } if (task.Exception != null) { throw task.Exception; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [IteratorStateMachine(typeof(<AsCoroutine>d__0))] public static IEnumerator AsCoroutine(this Task task) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AsCoroutine>d__0(0) { task = task }; } } } namespace VepMod.VepFramework.Config { public sealed class BoundMinMaxRange<T> where T : struct, IComparable<T> { private readonly MinMaxRange<T> _range; private readonly ConfigEntry<T> _minEntry; private readonly ConfigEntry<T> _maxEntry; public T Min => _range.GetMin(_minEntry.Value, _maxEntry.Value); public T Max => _range.GetMax(_minEntry.Value, _maxEntry.Value); public BoundMinMaxRange(MinMaxRange<T> range, ConfigEntry<T> minEntry, ConfigEntry<T> maxEntry) { _range = range; _minEntry = minEntry; _maxEntry = maxEntry; } } public static class ConfigExtensions { private static AcceptableValueRange<T> ToAcceptableValueRange<T>(this RangeValue<T> range) where T : struct, IComparable, IComparable<T> { return new AcceptableValueRange<T>(range.Min, range.Max); } private static ConfigDescription ToConfigDescription<T>(this RangeValue<T> range, string description) where T : struct, IComparable, IComparable<T> { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown return new ConfigDescription(description, (AcceptableValueBase)(object)range.ToAcceptableValueRange(), Array.Empty<object>()); } public static ConfigEntry<T> BindRange<T>(this ConfigFile config, string section, string key, RangeValue<T> range, string description) where T : struct, IComparable, IComparable<T> { return config.Bind<T>(section, key, range.Default, range.ToConfigDescription(description)); } public static BoundMinMaxRange<T> BindMinMax<T>(this ConfigFile config, string section, string minKey, string maxKey, MinMaxRange<T> range, string minDescription, string maxDescription) where T : struct, IComparable, IComparable<T> { ConfigEntry<T> minEntry = config.Bind<T>(section, minKey, range.MinRange.Default, range.MinRange.ToConfigDescription(minDescription)); ConfigEntry<T> maxEntry = config.Bind<T>(section, maxKey, range.MaxRange.Default, range.MaxRange.ToConfigDescription(maxDescription)); return new BoundMinMaxRange<T>(range, minEntry, maxEntry); } } } namespace VepMod.Patchs { [HarmonyPatch(typeof(EnemyDirector), "FirstSpawnPointAdd")] public class EnemyLoggerPatch { private static readonly VepLogger LOG = VepLogger.Create<EnemyLoggerPatch>(); [HarmonyPrefix] private static void Prefix(EnemyParent _enemyParent) { LOG.Info($"EnemyDirector.FirstSpawnPointAdd: {_enemyParent} added as first spawn point."); } } [HarmonyPatch(typeof(LocalVoiceFramed<short>), "PushDataAsync")] internal class LocalVoiceFramedPatch { private static readonly VepLogger LOG = VepLogger.Create<LocalVoiceFramedPatch>(); private static void Prefix(short[] buf, LocalVoiceFramed<short> __instance) { VepFinder.EnsureInitialized(); if (!IsNotReady()) { VepFinder.LocalMimics.ProcessVoiceData(buf); } } private static bool IsNotReady() { bool flag = !PhotonNetwork.IsConnectedAndReady; WhispralMimics localMimics = VepFinder.LocalMimics; bool flag2 = (Object)(object)localMimics == (Object)null; if (flag || flag2) { return true; } bool flag3 = (Object)(object)((Component)localMimics).gameObject == (Object)null; bool flag4 = (Object)(object)localMimics.PhotonView == (Object)null || !localMimics.PhotonView.IsMine; return flag3 || flag4; } } [HarmonyPatch(typeof(Materials))] internal static class MaterialsImpulsePatch { [HarmonyPrefix] [HarmonyPatch("Impulse")] private static bool Impulse_Prefix(Vector3 origin, bool footstep, HostType hostType) { //IL_000d: 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_0012: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!footstep) { return true; } if ((int)hostType != 0 && (int)hostType != 1) { return true; } if (InvisiblePlayerDebuff.IsPositionNearHiddenPlayer(origin)) { return false; } return true; } } [HarmonyPatch(typeof(PlayerAvatar), "Awake")] internal class PlayerAvatarPatch { private static readonly VepLogger LOG = VepLogger.Create<PlayerAvatarPatch>(); private static void Postfix(PlayerAvatar __instance) { if (PhotonNetwork.IsConnectedAndReady) { WhispralMimics whispralMimics = ((Component)__instance).GetComponent<WhispralMimics>(); if (!Object.op_Implicit((Object)(object)whispralMimics)) { whispralMimics = ((Component)__instance).gameObject.AddComponent<WhispralMimics>(); LOG.Debug("Added Mimics component to PlayerAvatar: " + ((Object)__instance).name); } else { LOG.Warning("PlayerAvatar: " + ((Object)__instance).name + " already has a WhispralMimics component."); } PhotonView component = ((Component)__instance).GetComponent<PhotonView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsMine) { LOG.Warning("PhotonView is null or not owned by local player."); return; } VepFinder.LocalMimics = whispralMimics; LOG.Info("Set LocalMimics for local PlayerAvatar: " + ((Object)__instance).name); } } } [HarmonyPatch(typeof(PlayerController))] internal static class PlayerControllerPatch { } [HarmonyPatch(typeof(ValuableDirector), "Spawn")] public class ValuableLoggerPatch { [HarmonyPrefix] private static void Prefix(PrefabRef _valuable, ValuableVolume _volume, string _path) { } } public class VepFinder : MonoBehaviour { private static VepFinder _instance; private static bool _initialized; private static readonly VepLogger LOG = VepLogger.Create<VepFinder>(); public static WhispralMimics LocalMimics { get; set; } private void OnDestroy() { if (_initialized) { LocalMimics = null; _instance = null; LOG.Info("VepFinder destroyed, clearing cache."); } } public static void EnsureInitialized() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_instance)) { _instance = new GameObject("VepFinder").AddComponent<VepFinder>(); _initialized = true; Object.DontDestroyOnLoad((Object)(object)((Component)_instance).gameObject); Player localPlayer = PhotonNetwork.LocalPlayer; LOG.Info($"MimicsFinder initialized for Player {((localPlayer != null) ? localPlayer.ActorNumber : (-1))}"); } } } } namespace VepMod.Enemies.Whispral { public static class AudioFilters { private const float TwoPi = MathF.PI * 2f; private const float Int16MaxValue = 32768f; private const float AlienVibratoFrequency = 5f; private const float AlienVibratoDepth = 0.05f; private const float AlienRingModFrequency = 200f; private const float AlienRingModMix = 0.3f; public const float PitchShiftLow = 0.5f; public const float PitchShiftHigh = 1.2f; private const float DefaultLowPassCutoff = 4500f; public static float[] ApplyAlienFilter(float[] samples, int sampleRate) { float[] array = new float[samples.Length]; for (int i = 0; i < samples.Length; i++) { float num = (float)i / (float)sampleRate; float num2 = 1f + Mathf.Sin(MathF.PI * 10f * num) * 0.05f; float num3 = (float)i * num2; int num4 = (int)num3; float num5 = num3 - (float)num4; float num6 = ((num4 + 1 >= samples.Length) ? ((num4 >= samples.Length) ? 0f : samples[num4]) : (samples[num4] * (1f - num5) + samples[num4 + 1] * num5)); float num7 = Mathf.Sin(MathF.PI * 400f * num); float num8 = num6 * num7 * 0.3f; array[i] = Mathf.Clamp(num6 * 0.7f + num8, -1f, 1f); } return array; } public static float[] ApplyLowPassFilter(float[] samples, int sampleRate, float cutoffFrequency = 4500f) { float num = 1f / (MathF.PI * 2f * cutoffFrequency); float num2 = 1f / (float)sampleRate; float num3 = num2 / (num + num2); float[] array = new float[samples.Length]; array[0] = samples[0]; for (int i = 1; i < samples.Length; i++) { array[i] = array[i - 1] + num3 * (samples[i] - array[i - 1]); } float[] array2 = new float[samples.Length]; array2[samples.Length - 1] = array[samples.Length - 1]; for (int num4 = samples.Length - 2; num4 >= 0; num4--) { array2[num4] = array2[num4 + 1] + num3 * (array[num4] - array2[num4 + 1]); } return array2; } public static float[] ApplyPitchShift(float[] samples, float pitchFactor) { int num = (int)((float)samples.Length / pitchFactor); float[] array = new float[num]; for (int i = 0; i < num; i++) { float num2 = (float)i * pitchFactor; int num3 = (int)num2; float num4 = num2 - (float)num3; if (num3 + 1 < samples.Length) { array[i] = samples[num3] * (1f - num4) + samples[num3 + 1] * num4; } else if (num3 < samples.Length) { array[i] = samples[num3]; } } return array; } public static float[] ConvertBytesToFloats(byte[] byteArray) { int num = byteArray.Length / 2; float[] array = new float[num]; for (int i = 0; i < num; i++) { short num2 = (short)(byteArray[i * 2] | (byteArray[i * 2 + 1] << 8)); array[i] = (float)num2 / 32768f; } return array; } public static byte[] ConvertFloatsToBytes(float[] floatArray) { byte[] array = new byte[floatArray.Length * 2]; for (int i = 0; i < floatArray.Length; i++) { short num = (short)(floatArray[i] * 32767f); array[i * 2] = (byte)((uint)num & 0xFFu); array[i * 2 + 1] = (byte)((uint)(num >> 8) & 0xFFu); } return array; } public static float[] ApplyFadeAndPadding(float[] samples, int sampleRate) { int num = (int)((float)sampleRate * 0.5f); int num2 = (int)((float)sampleRate * 0.02f); float[] array = new float[samples.Length + 2 * num]; for (int i = 0; i < num; i++) { array[i] = 0f; } for (int j = 0; j < samples.Length; j++) { float num3 = 1f; if (j < num2) { num3 = (float)j / (float)num2; } else if (j >= samples.Length - num2) { num3 = (float)(samples.Length - j) / (float)num2; } array[j + num] = samples[j] * num3; } for (int k = samples.Length + num; k < array.Length; k++) { array[k] = 0f; } return array; } } public sealed class DilatedPupilsDebuff : MonoBehaviour { private const float PupilSizeMultiplier = 3f; private const int Priority = 5; private const float SpringSpeedIn = 10f; private const float SpringDampIn = 0.5f; private const float SpringSpeedOut = 5f; private const float SpringDampOut = 0.3f; private const float RefreshInterval = 0.1f; private static readonly VepLogger LOG = VepLogger.Create<DilatedPupilsDebuff>(); private PlayerAvatar? playerAvatar; private float refreshTimer; public bool IsActive { get; private set; } private void Awake() { playerAvatar = ((Component)this).GetComponent<PlayerAvatar>(); } private void Update() { if (IsActive && !((Object)(object)playerAvatar == (Object)null)) { refreshTimer -= Time.deltaTime; if (refreshTimer <= 0f) { ApplyPupilEffect(); refreshTimer = 0.1f; } } } public void ApplyDebuff(bool dilated) { IsActive = dilated; LOG.Debug($"Applying dilated pupils debuff: {dilated}"); if (dilated) { refreshTimer = 0f; ApplyPupilEffect(); } } private void ApplyPupilEffect() { if (!((Object)(object)playerAvatar == (Object)null)) { playerAvatar.OverridePupilSize(3f, 5, 10f, 0.5f, 5f, 0.3f, 0.15f); } } } public sealed class DroidController : StateMachineComponent<DroidController, DroidController.StateId> { public enum StateId { Idle, Wander, Sprint, CheckMap, StalkApproach, StalkStare, StalkFlee } private sealed class IdleState : StateMachineBase<StateMachine, StateId>.StateBaseTimed { private const string ClipName = "LostDroidStand"; private const float IdleLoopStart = 0f; private const float IdleLoopEnd = 4.5f; private const float BlendDelay = 0.3f; private const float MinIdleTime = 2f; private const float MaxIdleTime = 4f; private const float PrecomputeRetryInterval = 1f; private const float CheckMapChance = 0.25f; private Animator _animator; private bool _animatorTakenOver; private AnimationClip? _clip; private float _currentTime; private float _duration; private float _precomputeTimer; private GameObject? _targetObject; public override void OnStateEnter(StateId previous) { base.OnStateEnter(previous); _duration = Random.Range(2f, 4f); _precomputeTimer = 0f; _animatorTakenOver = false; base.Machine.Owner.ResetPath(); base.Machine.Owner.HasChangedMovementState = false; _animator = base.Machine.Owner.Animator; if ((Object)(object)_animator != (Object)null) { _clip = DroidHelpers.GetAnimationClip(_animator, "LostDroidStand"); if ((Object)(object)_clip != (Object)null) { _targetObject = ((Component)_animator).gameObject; } } base.Machine.Owner.StartPrecomputeDestination(); } public override void OnStateUpdate() { base.OnStateUpdate(); if (!_animatorTakenOver && (Object)(object)_clip != (Object)null && (Object)(object)_targetObject != (Object)null && base.TimeElapsed >= 0.3f) { ((Behaviour)_animator).enabled = false; _currentTime = 0f; _animatorTakenOver = true; } if (_animatorTakenOver && (Object)(object)_clip != (Object)null && (Object)(object)_targetObject != (Object)null) { _currentTime += Time.deltaTime; if (_currentTime >= 4.5f) { _currentTime = 0f; } _clip.SampleAnimation(_targetObject, _currentTime); } if (!base.Machine.Owner.HasPrecomputedDestination) { _precomputeTimer -= Time.deltaTime; if (_precomputeTimer <= 0f) { base.Machine.Owner.StartPrecomputeDestination(); _precomputeTimer = 1f; } } if (!(base.TimeElapsed >= _duration)) { return; } float distanceToPlayer = base.Machine.Owner.GetDistanceToPlayer(); if (distanceToPlayer > 15f && Random.value < 0.1f) { base.Machine.NextStateStateId = StateId.StalkApproach; return; } float value = Random.value; if (value < 0.25f) { base.Machine.NextStateStateId = StateId.CheckMap; } else { base.Machine.NextStateStateId = ((!(Random.value < 0.5f)) ? StateId.Wander : StateId.Sprint); } } public override void OnStateExit(StateId next) { base.OnStateExit(next); if ((Object)(object)_animator != (Object)null && next != StateId.CheckMap) { ((Behaviour)_animator).enabled = true; } } } private abstract class MovementState : StateMachineBase<StateMachine, StateId>.StateBaseTimed { private const float SwitchCheckInterval = 1f; private const float SwitchChance = 0.2f; private const float PrecomputeForwardInterval = 0.5f; private float _duration; private float _nextSwitchCheck; private float _nextPrecomputeForward; protected abstract float MinDuration { get; } protected abstract float MaxDuration { get; } protected abstract float Speed { get; } protected abstract StateId SwitchTargetState { get; } protected abstract void SetMovementFlag(bool value); public override void OnStateEnter(StateId previous) { base.OnStateEnter(previous); _duration = Random.Range(MinDuration, MaxDuration); _nextSwitchCheck = 1f; _nextPrecomputeForward = 0.5f; if ((uint)(previous - 1) <= 1u) { base.Machine.Owner.TryExtendCurrentPath(); } else if (!base.Machine.Owner.TrySetRandomDestination()) { base.Machine.NextStateStateId = StateId.Idle; return; } base.Machine.Owner.SetSpeed(Speed); SetMovementFlag(value: true); base.Machine.Owner.StartPrecomputeForwardDestination(); } public override void OnStateExit(StateId next) { base.OnStateExit(next); SetMovementFlag(value: false); if ((uint)(next - 1) > 1u) { base.Machine.Owner.ClearPrecomputedForwardDestination(); } } public override void OnStateUpdate() { base.OnStateUpdate(); if (base.Machine.Owner.HasReachedDestination() || base.TimeElapsed >= _duration) { base.Machine.NextStateStateId = StateId.Idle; return; } _nextPrecomputeForward -= Time.deltaTime; if (_nextPrecomputeForward <= 0f) { _nextPrecomputeForward = 0.5f; base.Machine.Owner.StartPrecomputeForwardDestination(); } if (!base.Machine.Owner.HasChangedMovementState && base.TimeElapsed >= _nextSwitchCheck) { _nextSwitchCheck += 1f; if (Random.value < 0.2f) { base.Machine.Owner.HasChangedMovementState = true; base.Machine.NextStateStateId = SwitchTargetState; } } } } private sealed class WanderState : MovementState { protected override float MinDuration => 5f; protected override float MaxDuration => 15f; protected override float Speed => 2f; protected override StateId SwitchTargetState => StateId.Sprint; protected override void SetMovementFlag(bool value) { base.Machine.Owner.IsWalking = value; } } private sealed class SprintState : MovementState { protected override float MinDuration => 3f; protected override float MaxDuration => 8f; protected override float Speed => 5f; protected override StateId SwitchTargetState => StateId.Wander; protected override void SetMovementFlag(bool value) { base.Machine.Owner.IsSprinting = value; } } private sealed class CheckMapState : StateMachineBase<StateMachine, StateId>.StateBaseTimed { private enum Phase { Raise, Look, Lower } private const string ClipName = "LostDroidStand"; private const float RaiseStartTime = 4.65f; private const float LookStartTime = 5.5f; private const float LookEndTime = 6.9333334f; private const float LowerEndTime = 7.15f; private const float MinLookDuration = 0.5f; private const float MaxLookDuration = 3f; private Animator? _animator; private AnimationClip? _clip; private Phase _currentPhase; private float _currentTime; private float _lookDuration; private float _lookTimer; private GameObject? _targetObject; public override void OnStateEnter(StateId previous) { base.OnStateEnter(previous); _animator = base.Machine.Owner.Animator; if ((Object)(object)_animator == (Object)null) { LOG.Warning("CheckMapState: Animator is null!"); base.Machine.NextStateStateId = StateId.Idle; return; } _clip = DroidHelpers.GetAnimationClip(_animator, "LostDroidStand"); if ((Object)(object)_clip == (Object)null) { LOG.Warning("CheckMapState: Clip 'LostDroidStand' not found!"); base.Machine.NextStateStateId = StateId.Idle; return; } _targetObject = ((Component)_animator).gameObject; base.Machine.Owner.IsWalking = false; base.Machine.Owner.IsSprinting = false; base.Machine.Owner.ResetPath(); ((Behaviour)_animator).enabled = false; _lookDuration = Random.Range(0.5f, 3f); _lookTimer = 0f; _currentPhase = Phase.Raise; _currentTime = 4.65f; LOG.Debug($"CheckMapState: ENTER - Clip length={_clip.length}s, starting at {_currentTime}s"); LOG.Debug($"CheckMapState: Thresholds - Raise={4.65f}s, Look={5.5f}s-{6.9333334f}s, Lower={7.15f}s"); LOG.Debug($"CheckMapState: LookDuration={_lookDuration:F1}s"); _clip.SampleAnimation(_targetObject, _currentTime); } public override void OnStateUpdate() { base.OnStateUpdate(); if ((Object)(object)_clip == (Object)null || (Object)(object)_targetObject == (Object)null) { base.Machine.NextStateStateId = StateId.Idle; return; } _currentTime += Time.deltaTime; switch (_currentPhase) { case Phase.Raise: if (_currentTime >= 5.5f) { LOG.Debug("CheckMapState: Transitioning to Phase.Look"); _currentPhase = Phase.Look; _lookTimer = 0f; } break; case Phase.Look: _lookTimer += Time.deltaTime; if (_currentTime >= 6.9333334f) { if (_lookTimer < _lookDuration) { _currentTime = 5.5f; break; } LOG.Debug("CheckMapState: Transitioning to Phase.Lower"); _currentPhase = Phase.Lower; } break; case Phase.Lower: if (_currentTime >= 7.15f) { LOG.Debug("CheckMapState: Animation complete, returning to Idle"); base.Machine.NextStateStateId = StateId.Idle; return; } break; } _clip.SampleAnimation(_targetObject, _currentTime); } public override void OnStateExit(StateId next) { base.OnStateExit(next); LOG.Debug($"CheckMapState: EXIT -> {next}"); if ((Object)(object)_animator != (Object)null) { ((Behaviour)_animator).enabled = true; } } } private sealed class StalkApproachState : StateMachineBase<StateMachine, StateId>.StateBaseTimed { private const float MaxApproachTime = 30f; private const float DestinationUpdateInterval = 1f; private float _nextDestinationUpdate; public override void OnStateEnter(StateId previous) { base.OnStateEnter(previous); LOG.Debug("=== STALK: Approach started - running towards player ==="); base.Machine.Owner.IsSprinting = true; base.Machine.Owner.SetSpeed(5f); _nextDestinationUpdate = 0f; if (!base.Machine.Owner.TrySetDestinationToPlayer()) { LOG.Debug("STALK: Failed to set destination to player, aborting"); base.Machine.NextStateStateId = StateId.Idle; } } public override void OnStateUpdate() { base.OnStateUpdate(); float distanceToPlayer = base.Machine.Owner.GetDistanceToPlayer(); bool flag = base.Machine.Owner.HasReachedDestination(); if (base.TimeElapsed >= 30f) { LOG.Debug($"STALK: Approach timeout, dist={distanceToPlayer:F1}m, aborting"); base.Machine.NextStateStateId = StateId.Idle; return; } if (distanceToPlayer <= 5f) { LOG.Debug($"STALK: Arrived near player (distance={distanceToPlayer:F1}m)"); base.Machine.NextStateStateId = StateId.StalkStare; return; } if (flag) { LOG.Debug($"STALK: Reached nav destination but player still at {distanceToPlayer:F1}m, starting stare anyway"); base.Machine.NextStateStateId = StateId.StalkStare; return; } _nextDestinationUpdate -= Time.deltaTime; if (_nextDestinationUpdate <= 0f) { base.Machine.Owner.TrySetDestinationToPlayer(); _nextDestinationUpdate = 1f; } } public override void OnStateExit(StateId next) { base.OnStateExit(next); base.Machine.Owner.IsSprinting = false; base.Machine.Owner.ResetPath(); } } private sealed class StalkStareState : StateMachineBase<StateMachine, StateId>.StateBaseTimed { private const float MaxStareTime = 30f; private const float DestinationUpdateInterval = 0.5f; private float _fleeCountdown; private bool _hasBeenSeen; private float _nextDestinationUpdate; public override void OnStateEnter(StateId previous) { base.OnStateEnter(previous); LOG.Debug("=== STALK: Staring at player ==="); _hasBeenSeen = false; _fleeCountdown = 2f; _nextDestinationUpdate = 0f; base.Machine.Owner.IsWalking = true; base.Machine.Owner.IsSprinting = false; base.Machine.Owner.SetSpeed(2f); } public override void OnStateUpdate() { base.OnStateUpdate(); base.Machine.Owner.LookAtPlayer(); float distanceToPlayer = base.Machine.Owner.GetDistanceToPlayer(); if (base.Machine.Owner.IsPlayerLookingAtMe && !_hasBeenSeen) { _hasBeenSeen = true; LOG.Debug("=== STALK: Player sees me! Maintaining eye contact... ==="); base.Machine.Owner.IsWalking = false; base.Machine.Owner.ResetPath(); } if (_hasBeenSeen) { _fleeCountdown -= Time.deltaTime; if (_fleeCountdown <= 0f) { LOG.Debug("=== STALK: Eye contact over, fleeing! ==="); base.Machine.NextStateStateId = StateId.StalkFlee; return; } } else if (distanceToPlayer > 3f) { _nextDestinationUpdate -= Time.deltaTime; if (_nextDestinationUpdate <= 0f) { base.Machine.Owner.TrySetDestinationToPlayer(); _nextDestinationUpdate = 0.5f; } } else { base.Machine.Owner.ResetPath(); } if (base.TimeElapsed >= 30f) { LOG.Debug("STALK: Stare timeout, fleeing"); base.Machine.NextStateStateId = StateId.StalkFlee; } } public override void OnStateExit(StateId next) { base.OnStateExit(next); base.Machine.Owner.IsWalking = false; } } private sealed class StalkFleeState : StateMachineBase<StateMachine, StateId>.StateBaseTimed { private const float MaxFleeTime = 10f; public override void OnStateEnter(StateId previous) { base.OnStateEnter(previous); LOG.Debug("=== STALK: Fleeing from player! ==="); base.Machine.Owner.IsSprinting = true; base.Machine.Owner.SetSpeed(5f); if (!base.Machine.Owner.TrySetFleeDestination()) { LOG.Debug("STALK: Failed to set flee destination, going to idle"); base.Machine.NextStateStateId = StateId.Idle; } } public override void OnStateUpdate() { base.OnStateUpdate(); if (base.Machine.Owner.HasReachedDestination() || base.TimeElapsed >= 10f) { LOG.Debug("=== STALK: Flee complete, returning to idle ==="); base.Machine.NextStateStateId = StateId.Idle; } } public override void OnStateExit(StateId next) { base.OnStateExit(next); base.Machine.Owner.IsSprinting = false; } } internal const float WalkSpeed = 2f; internal const float SprintSpeed = 5f; internal const float SprintChance = 0.5f; internal const float StalkMinDistance = 15f; internal const float StalkChance = 0.1f; internal const float StalkArrivalDistance = 5f; internal const float StalkMinKeepDistance = 3f; internal const float StalkFleeDistance = 20f; internal const float StalkStareBeforeFlee = 2f; private static readonly VepLogger LOG = VepLogger.Create<DroidController>(); private static readonly int IsWalkingKey = Animator.StringToHash("isWalking"); private static readonly int IsSprintingKey = Animator.StringToHash("isSprinting"); private static readonly int IsTurningKey = Animator.StringToHash("isTurning"); private static readonly int StunKey = Animator.StringToHash("stun"); private static readonly int AlbedoColorKey = Shader.PropertyToID("_AlbedoColor"); private readonly MaterialTrigger _materialTrigger = new MaterialTrigger(); private DroidFaceAnimationController _animController; private CharacterController _charController; private DroidNameplate _nameplateController; private NavMeshAgent _navAgent; private Transform _rigidbodyTransform; private int _savedAgentTypeID; private int _savedAreaMask = -1; internal Animator Animator; public bool IsWalking { get; set; } public bool IsSprinting { get; set; } public bool IsTurning { get; private set; } public bool HasChangedMovementState { get; set; } public PlayerAvatar SourcePlayer { get; private set; } public Transform ControllerTransform { get; private set; } public DroidMovementController Movement { get; private set; } public bool IsPlayerLookingAtMe => _animController.IsPlayerLookingAtMe; public bool IsStalking { get { StateId currentStateStateId = Fsm.CurrentStateStateId; if ((uint)(currentStateStateId - 4) <= 2u) { return true; } return false; } } protected override StateId DefaultState => StateId.Idle; public bool HasPrecomputedDestination => Movement.HasPrecomputedDestination; protected override void Awake() { } protected override void Update() { if (!((Object)(object)Movement == (Object)null) && !((Object)(object)_navAgent == (Object)null) && _navAgent.isOnNavMesh && !((Object)(object)ControllerTransform == (Object)null)) { Fsm.Update(); StateId currentStateStateId = Fsm.CurrentStateStateId; bool isMovementState = DroidHelpers.IsMovementState(currentStateStateId); Movement.UpdateMovement(isMovementState); Movement.UpdateRotation(); Movement.SyncVisualsToController(((Component)Animator).transform); UpdateAnimationFlags(); Movement.SyncNavAgentPosition(isMovementState); } } public void PlayVoice(bool applyFilter = false) { if ((Object)(object)SourcePlayer == (Object)null || (Object)(object)ControllerTransform == (Object)null) { return; } PlayerAvatar instance = PlayerAvatar.instance; if (!((Object)(object)instance == (Object)null)) { WhispralMimics component = ((Component)instance).GetComponent<WhispralMimics>(); if ((Object)(object)component == (Object)null) { LOG.Warning("WhispralMimics not found on local player"); } else { component.PlayAudioAtTransform(ControllerTransform, SourcePlayer.playerName, applyFilter); } } } private void UpdateAnimationFlags() { //IL_003f: 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) StateId currentStateStateId = Fsm.CurrentStateStateId; if (DroidHelpers.IsMovementState(currentStateStateId) && (Object)(object)ControllerTransform != (Object)null && (Object)(object)Movement != (Object)null) { float num = Quaternion.Angle(ControllerTransform.rotation, Movement.TargetRotation); IsTurning = num > 7f; } else { IsTurning = false; } if ((Object)(object)Animator != (Object)null) { Animator.SetBool(IsWalkingKey, IsWalking); Animator.SetBool(IsSprintingKey, IsSprinting); Animator.SetBool(IsTurningKey, IsTurning); Animator.SetBool(StunKey, false); } } public bool TrySetRandomDestination() { return (Object)(object)Movement != (Object)null && Movement.TrySetRandomDestination(); } public bool TryExtendCurrentPath() { return (Object)(object)Movement != (Object)null && Movement.TryExtendCurrentPath(); } public void StartPrecomputeForwardDestination() { Movement?.StartPrecomputeForwardDestination(); } public void ClearPrecomputedForwardDestination() { Movement?.ClearPrecomputedForwardDestination(); } public void StartPrecomputeDestination() { Movement.StartPrecomputeDestination(); } public void ResetPath() { Movement.ResetPath(); } public bool HasReachedDestination() { return Movement.HasReachedDestination(); } public float GetDistanceToPlayer() { return Movement.GetDistanceToPlayer(); } public bool TrySetDestinationToPlayer() { return (Object)(object)Movement != (Object)null && Movement.TrySetDestinationToPlayer(); } public bool TrySetFleeDestination() { return (Object)(object)Movement != (Object)null && Movement.TrySetFleeDestination(20f); } public void LookAtPlayer() { Movement.LookAtPlayer(); } public void SetSpeed(float speed) { Movement.SetSpeed(speed); } public static DroidController? Create(PlayerAvatar sourcePlayer, Vector3 spawnPosition) { //IL_0027: 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) if (!DroidPrefabLoader.IsAvailable) { LOG.Warning("LostDroid prefab not available"); return null; } GameObject val = Object.Instantiate<GameObject>(DroidPrefabLoader.LostDroidPrefab, spawnPosition, Quaternion.identity); if ((Object)(object)val == (Object)null) { LOG.Error("Failed to instantiate LostDroid prefab"); return null; } ((Object)val).name = "HallucinationDroid_" + sourcePlayer.playerName; DroidController droidController = val.AddComponent<DroidController>(); droidController.Initialize(sourcePlayer); return droidController; } private void Initialize(PlayerAvatar sourcePlayer) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) SourcePlayer = sourcePlayer; FindCriticalTransforms(); SaveNavMeshSettings(); DisableEnemyComponents(); SetupNavigation(); SetupMovementController(); SetupAnimator(); SetupAnimationController(); ApplyPlayerColor(); SetupNameplate(); InitializeFsm(); LOG.Info($"HallucinationDroid created for {sourcePlayer.playerName} at {ControllerTransform.position}"); } private void SetupMovementController() { if (!((Object)(object)ControllerTransform == (Object)null)) { Movement = ((Component)this).gameObject.AddComponent<DroidMovementController>(); Movement.Initialize(ControllerTransform, _rigidbodyTransform, _navAgent, _charController, _savedAreaMask); Movement.OnNavMeshError += HandleNavMeshError; } } private void HandleNavMeshError() { Fsm.NextStateStateId = StateId.Idle; } private void SetupAnimationController() { _animController = ((Component)this).gameObject.AddComponent<DroidFaceAnimationController>(); _animController.Initialize(this, ControllerTransform); Transform val = DroidHelpers.FindChildByName(((Component)this).transform, "code_head_top"); if ((Object)(object)val != (Object)null) { _animController.SetupTalking(val); } SetupEyelidsForAnimController(); } private void SetupEyelidsForAnimController() { try { Transform val = DroidHelpers.FindChildByName(((Component)this).transform, "ANIM EYE LEFT"); Transform val2 = DroidHelpers.FindChildByName(((Component)this).transform, "ANIM EYE RIGHT"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { LOG.Warning("ANIM EYE LEFT/RIGHT not found for angry eyes effect"); return; } Transform val3 = FindEyelidSource(); if ((Object)(object)val3 == (Object)null) { LOG.Warning("No PlayerAvatar found to copy eyelid structure"); return; } Transform droidEye = DroidHelpers.FindChildByName(((Component)this).transform, "code_eye_left") ?? val; Transform droidEye2 = DroidHelpers.FindChildByName(((Component)this).transform, "code_eye_right") ?? val2; Transform upperRotationX; Transform upperRotationZ; Transform lowerRotationX; GameObject val4 = SetupEyeFromPlayer(droidEye, val3, "LEFT", out upperRotationX, out upperRotationZ, out lowerRotationX); Transform upperRotationX2; Transform upperRotationZ2; Transform lowerRotationX2; GameObject val5 = SetupEyeFromPlayer(droidEye2, val3, "RIGHT", out upperRotationX2, out upperRotationZ2, out lowerRotationX2); if ((Object)(object)val4 != (Object)null) { val4.SetActive(false); } if ((Object)(object)val5 != (Object)null) { val5.SetActive(false); } _animController.SetupEyelids(val4, val5, upperRotationX, upperRotationZ, lowerRotationX, upperRotationX2, upperRotationZ2, lowerRotationX2); LOG.Info($"Angry eyes setup: left={(Object)(object)val4 != (Object)null}, right={(Object)(object)val5 != (Object)null}"); } catch (Exception ex) { LOG.Error("SetupEyelidsForAnimController: Exception - " + ex.Message + "\n" + ex.StackTrace); } } private void LateUpdate() { _nameplateController.UpdateNameplate(); _animController.UpdateAnimations(); } private void OnDestroy() { if ((Object)(object)Movement != (Object)null) { Movement.OnNavMeshError -= HandleNavMeshError; } } private Material? GetDroidBodyMaterial() { MeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val in componentsInChildren) { string text = ((Object)((Component)val).gameObject).name.ToLower(); if (!text.Contains("eye") && !text.Contains("pupil") && !text.Contains("eyelid") && (Object)(object)((Renderer)val).material != (Object)null) { return ((Renderer)val).material; } } return null; } private Transform? FindEyelidSource() { PlayerAvatarVisuals[] array = Object.FindObjectsOfType<PlayerAvatarVisuals>(); PlayerAvatarVisuals[] array2 = array; foreach (PlayerAvatarVisuals val in array2) { Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if (((Object)val2).name == "EYELIDS LEFT") { return ((Component)val).transform; } } } LOG.Warning("No PlayerAvatarVisuals with EYELIDS LEFT found"); return null; } private GameObject? SetupEyeFromPlayer(Transform droidEye, Transform playerSource, string side, out Transform? upperRotationX, out Transform? upperRotationZ, out Transform? lowerRotationX) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) upperRotationX = null; upperRotationZ = null; lowerRotationX = null; string text = "EYELIDS " + side; Transform val = null; Transform[] componentsInChildren = ((Component)playerSource).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if (((Object)val2).name == text) { val = val2; break; } } if ((Object)(object)val == (Object)null) { LOG.Warning(text + " not found on player source"); return null; } Transform val3 = null; foreach (Transform item in droidEye) { Transform val4 = item; if (((Object)val4).name == text) { val3 = val4; break; } } if ((Object)(object)val3 == (Object)null) { val3 = CopyTransformHierarchy(val, droidEye); val3.localScale = Vector3.one * 1.3f; Material droidBodyMaterial = GetDroidBodyMaterial(); if ((Object)(object)droidBodyMaterial != (Object)null) { MeshRenderer[] componentsInChildren2 = ((Component)val3).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val5 in componentsInChildren2) { ((Renderer)val5).material = droidBodyMaterial; } } } Transform[] componentsInChildren3 = ((Component)val3).GetComponentsInChildren<Transform>(true); foreach (Transform val6 in componentsInChildren3) { switch (((Object)val6).name) { case "eyelid_upper": upperRotationX = val6; break; case "eyelid_upper_rotation": upperRotationZ = val6; break; case "eyelid_lower": lowerRotationX = val6; break; } } return ((Component)val3).gameObject; } private Transform CopyTransformHierarchy(Transform source, Transform newParent) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown GameObject val = new GameObject(((Object)source).name); val.transform.SetParent(newParent, false); val.transform.localPosition = source.localPosition; val.transform.localRotation = source.localRotation; val.transform.localScale = source.localScale; MeshFilter component = ((Component)source).GetComponent<MeshFilter>(); MeshRenderer component2 = ((Component)source).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { MeshFilter val2 = val.AddComponent<MeshFilter>(); MeshRenderer val3 = val.AddComponent<MeshRenderer>(); val2.sharedMesh = component.sharedMesh; ((Renderer)val3).sharedMaterials = ((Renderer)component2).sharedMaterials; ((Renderer)val3).shadowCastingMode = ((Renderer)component2).shadowCastingMode; ((Renderer)val3).receiveShadows = ((Renderer)component2).receiveShadows; } foreach (Transform item in source) { Transform source2 = item; CopyTransformHierarchy(source2, val.transform); } return val.transform; } public void PlayMediumFootstep() { //IL_0019: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ControllerTransform == (Object)null)) { Vector3 val = ControllerTransform.position + Vector3.up * 0.1f; Materials.Instance.Impulse(val, Vector3.down, (SoundType)1, true, true, _materialTrigger, (HostType)1); } } private void SetupNameplate() { _nameplateController = ((Component)this).gameObject.AddComponent<DroidNameplate>(); _nameplateController.Initialize(ControllerTransform, SourcePlayer); } private void ApplyPlayerColor() { //IL_005e: 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_0176: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)SourcePlayer == (Object)null) { return; } int playerColor = StatsManager.instance.GetPlayerColor(SourcePlayer.steamID); if (playerColor < 0 || playerColor >= AssetManager.instance.playerColors.Count) { return; } Color val = AssetManager.instance.playerColors[playerColor]; Transform val2 = ((Component)this).transform.Find("Rigidbody/Cube") ?? ((Component)this).transform.Find("Cube"); if ((Object)(object)val2 == (Object)null) { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(); foreach (Transform val3 in componentsInChildren) { if (((Object)val3).name == "Cube") { val2 = val3; break; } } } if ((Object)(object)val2 == (Object)null) { LOG.Warning("Cube transform not found for color application"); return; } Renderer[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<Renderer>(); foreach (Renderer val4 in componentsInChildren2) { string name = ((Object)((Component)val4).gameObject).name; if (!name.Contains("eye") && !name.Contains("pupil") && !name.Contains("mesh_health")) { Material[] materials = val4.materials; foreach (Material val5 in materials) { val5.SetColor(AlbedoColorKey, val); } } } } private void InitializeFsm() { Fsm = new StateMachineComponent<DroidController, StateId>.StateMachine(this, DefaultState); Fsm.AddState(StateId.Idle, new IdleState()); Fsm.AddState(StateId.Wander, new WanderState()); Fsm.AddState(StateId.Sprint, new SprintState()); Fsm.AddState(StateId.CheckMap, new CheckMapState()); Fsm.AddState(StateId.StalkApproach, new StalkApproachState()); Fsm.AddState(StateId.StalkStare, new StalkStareState()); Fsm.AddState(StateId.StalkFlee, new StalkFleeState()); } private void FindCriticalTransforms() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) ControllerTransform = ((Component)this).transform.Find("Controller"); if ((Object)(object)ControllerTransform == (Object)null) { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(); foreach (Transform val in componentsInChildren) { if (((Object)val).name == "Controller") { ControllerTransform = val; break; } } } if ((Object)(object)ControllerTransform == (Object)null) { LOG.Warning("Controller transform not found, creating one"); GameObject val2 = new GameObject("Controller"); val2.transform.SetParent(((Component)this).transform); val2.transform.localPosition = Vector3.zero; ControllerTransform = val2.transform; } _rigidbodyTransform = ((Component)this).transform.Find("Rigidbody"); if ((Object)(object)_rigidbodyTransform == (Object)null) { Transform[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Transform>(); foreach (Transform val3 in componentsInChildren2) { if (((Object)val3).name == "Rigidbody") { _rigidbodyTransform = val3; break; } } } if ((Object)(object)_rigidbodyTransform == (Object)null) { LOG.Warning("Rigidbody transform not found"); } } private void SaveNavMeshSettings() { NavMeshAgent val = null; if ((Object)(object)ControllerTransform != (Object)null) { val = ((Component)ControllerTransform).GetComponent<NavMeshAgent>(); } if ((Object)(object)val == (Object)null) { val = ((Component)this).GetComponentInChildren<NavMeshAgent>(); } if ((Object)(object)val != (Object)null) { _savedAgentTypeID = val.agentTypeID; _savedAreaMask = val.areaMask; } else { _savedAgentTypeID = -334000983; _savedAreaMask = 1; } } private void DisableEnemyComponents() { //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) List<Component> list = new List<Component>(); List<MonoBehaviour> list2 = new List<MonoBehaviour>(); Component[] componentsInChildren = ((Component)this).GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)this) { continue; } string name = ((object)val).GetType().Name; string text = ((object)val).GetType().FullName ?? ""; if (val is Transform || val is Animator || val is Renderer || val is MeshFilter || val is SkinnedMeshRenderer || val is NavMeshAgent) { continue; } if (text.Contains("Photon") || name.Contains("Photon") || text.Contains("Enemy") || text.Contains("LostDroid") || name.Contains("Enemy") || name.Contains("LostDroid")) { list.Add(val); continue; } MonoBehaviour val2 = (MonoBehaviour)(object)((val is MonoBehaviour) ? val : null); if (val2 != null) { list2.Add(val2); } } for (int j = 0; j < 5; j++) { int num = 0; foreach (Component item in list) { if ((Object)(object)item != (Object)null) { try { Object.DestroyImmediate((Object)(object)item); num++; } catch { } } } if (num == 0) { break; } } foreach (MonoBehaviour item2 in list2) { if ((Object)(object)item2 != (Object)null && (Object)(object)item2 != (Object)(object)this) { ((Behaviour)item2).enabled = false; } } Rigidbody[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Rigidbody>(); foreach (Rigidbody val3 in componentsInChildren2) { val3.isKinematic = true; val3.useGravity = false; val3.velocity = Vector3.zero; val3.angularVelocity = Vector3.zero; } Collider[] componentsInChildren3 = ((Component)this).GetComponentsInChildren<Collider>(); foreach (Collider val4 in componentsInChildren3) { val4.isTrigger = true; } } private void SetupAnimator() { Animator = ((Component)this).GetComponentInChildren<Animator>(); if ((Object)(object)Animator != (Object)null) { ((Behaviour)Animator).enabled = true; Animator.applyRootMotion = false; ParentConstraint component = ((Component)Animator).GetComponent<ParentConstraint>(); if ((Object)(object)component != (Object)null && !component.constraintActive) { component.constraintActive = true; } DroidFootstepsEventReceiver orAddComponent = ComponentHolderProtocol.GetOrAddComponent<DroidFootstepsEventReceiver>((Object)(object)Animator); orAddComponent.Initialize(this); } else { LOG.Warning("No Animator found on prefab"); } } private void SetupNavigation() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0076: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ControllerTransform == (Object)null) { LOG.Error("Cannot setup navigation: Controller is null"); return; } _navAgent = ((Component)ControllerTransform).GetComponent<NavMeshAgent>(); if ((Object)(object)_navAgent == (Object)null) { _navAgent = ((Component)ControllerTransform).gameObject.AddComponent<NavMeshAgent>(); } Vector3 position = ControllerTransform.position; Vector3 val = position; bool flag = false; NavMeshQueryFilter val2 = default(NavMeshQueryFilter); ((NavMeshQueryFilter)(ref val2)).agentTypeID = _savedAgentTypeID; ((NavMeshQueryFilter)(ref val2)).areaMask = _savedAreaMask; NavMeshQueryFilter val3 = val2; float[] array = new float[4] { 5f, 10f, 20f, 50f }; float[] array2 = array; NavMeshHit val4 = default(NavMeshHit); foreach (float num in array2) { if (NavMesh.SamplePosition(position, ref val4, num, val3)) { val = ((NavMeshHit)(ref val4)).position; flag = true; break; } } if (!flag) { LOG.Error($"No NavMesh found near {position}"); return; } ((Behaviour)_navAgent).enabled = false; _navAgent.agentTypeID = _savedAgentTypeID; _navAgent.areaMask = _savedAreaMask; _navAgent.baseOffset = 0f; _navAgent.speed = 2f; _navAgent.angularSpeed = 999f; _navAgent.acceleration = 15f; _navAgent.stoppingDistance = 0f; _navAgent.autoBraking = true; _navAgent.updatePosition = false; _navAgent.updateRotation = false; _navAgent.radius = 0.7f; _navAgent.height = 2f; _navAgent.obstacleAvoidanceType = (ObstacleAvoidanceType)4; _navAgent.avoidancePriority = 10; _navAgent.autoTraverseOffMeshLink = true; _navAgent.autoRepath = true; ControllerTransform.position = val; _navAgent.Warp(val); ((Behaviour)_navAgent).enabled = true; SetupCharacterController(); } private void SetupCharacterController() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ControllerTransform == (Object)null)) { CharacterController component = ((Component)ControllerTransform).GetComponent<CharacterController>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } _charController = ((Component)ControllerTransform).gameObject.AddComponent<CharacterController>(); _charController.height = 2f; _charController.radius = 0.5f; _charController.center = new Vector3(0f, 1f, 0f); _charController.slopeLimit = 45f; _charController.stepOffset = 0.3f; _charController.skinWidth = 0.08f; _charController.minMoveDistance = 0.001f; } } } public sealed class DroidDebuff : MonoBehaviour { private static readonly VepLogger LOG = VepLogger.Create<DroidDebuff>(); private readonly Dictionary<PlayerAvatar, DroidController> _droids = new Dictionary<PlayerAvatar, DroidController>(); private WhispralDebuffManager _debuffManager; private InvisiblePlayerDebuff _invisiblePlayerDebuff; public bool IsActive { get; private set; } private void Update() { if (IsActive && !((Object)(object)_invisiblePlayerDebuff == (Object)null)) { SyncHallucinations(); } } private void OnDestroy() { DestroyAllHallucinations(); } public void ApplyDebuff(bool active, InvisiblePlayerDebuff sourcePlayerDebuff) { if (!SemiFunc.IsMultiplayer()) { LOG.Debug("Singleplayer mode detected, skipping hallucinations."); return; } IsActive = active; _invisiblePlayerDebuff = sourcePlayerDebuff; _debuffManager = ((Component)this).GetComponent<WhispralDebuffManager>(); if (active) { CreateHallucinations(); } else { DestroyAllHallucinations(); } } public DroidController? GetDroidByPlayerName(string playerName) { foreach (KeyValuePair<PlayerAvatar, DroidController> droid in _droids) { if (Object.op_Implicit((Object)(object)droid.Key) && Object.op_Implicit((Object)(object)droid.Value) && droid.Key.playerName == playerName) { return droid.Value; } } return null; } private void CreateHallucination(PlayerAvatar sourcePlayer) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) LOG.Debug("Creating hallucination for player " + sourcePlayer.playerName); if (!DroidPrefabLoader.IsAvailable) { LOG.Warning("LostDroid prefab not available - cannot create hallucination"); return; } Vector3? val = FindSpawnPosition(); if (!val.HasValue) { LOG.Warning("Could not find spawn position for hallucination of " + sourcePlayer.playerName); return; } DroidController droidController = DroidController.Create(sourcePlayer, val.Value); if ((Object)(object)droidController == (Object)null) { LOG.Warning("Hallucination for " + sourcePlayer.playerName + " failed to create"); return; } _droids[sourcePlayer] = droidController; LOG.Debug($"Hallucination created at {((Component)droidController).transform.position}"); } private void CreateHallucinations() { if ((Object)(object)_invisiblePlayerDebuff == (Object)null) { return; } LOG.Debug("Creating hallucinations for hidden players."); foreach (PlayerAvatar hiddenPlayer in _invisiblePlayerDebuff.HiddenPlayers) { if (Object.op_Implicit((Object)(object)hiddenPlayer) && !_droids.ContainsKey(hiddenPlayer)) { CreateHallucination(hiddenPlayer); } } } private void DestroyAllHallucinations() { LOG.Debug("Destroying all hallucinations."); foreach (KeyValuePair<PlayerAvatar, DroidController> droid in _droids) { if (Object.op_Implicit((Object)(object)droid.Value)) { Object.Destroy((Object)(object)((Component)droid.Value).gameObject); } } _droids.Clear(); } private void DestroyHallucination(PlayerAvatar? player) { if (!((Object)(object)player == (Object)null) && _droids.TryGetValue(player, out DroidController value)) { LOG.Debug("Destroying hallucination for player " + player.playerName); if (Object.op_Implicit((Object)(object)value)) { Object.Destroy((Object)(object)((Component)value).gameObject); } _droids.Remove(player); } } private Vector3? FindSpawnPosition() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_debuffManager != (Object)null) { Vector3? precomputedSpawnPosition = _debuffManager.GetPrecomputedSpawnPosition(); if (precomputedSpawnPosition.HasValue) { LOG.Debug($"Using precomputed spawn position: {precomputedSpawnPosition.Value}"); return precomputedSpawnPosition.Value; } } LOG.Warning("No precomputed position available, falling back to sync search"); Vector3 position = ((Component)PlayerAvatar.instance).transform.position; LevelPoint val = SemiFunc.LevelPointGet(position, 5f, 15f) ?? SemiFunc.LevelPointGet(position, 0f, 999f); if (!Object.op_Implicit((Object)(object)val)) { LOG.Warning("No LevelPoint found for hallucination spawn"); return null; } return ((Component)val).transform.position; } private void SyncHallucinations() { IReadOnlyList<PlayerAvatar> hiddenPlayers = _invisiblePlayerDebuff.HiddenPlayers; foreach (PlayerAvatar item in hiddenPlayers) { if (Object.op_Implicit((Object)(object)item) && !_droids.ContainsKey(item)) { CreateHallucination(item); } } List<PlayerAvatar> list = new List<PlayerAvatar>(); foreach (KeyValuePair<PlayerAvatar, DroidController> droid in _droids) { if (!Object.op_Implicit((Object)(object)droid.Key) || !Object.op_Implicit((Object)(object)droid.Value) || !hiddenPlayers.Contains(droid.Key)) { list.Add(droid.Key); } } foreach (PlayerAvatar item2 in list) { DestroyHallucination(item2); } } } public sealed class DroidFaceAnimationController : MonoBehaviour { private static class AngryExpression { public const float UpperLidAngleLeft = -34f; public const float UpperLidAngleRight = 34f; public const float UpperLidClosed = 83f; public const float LowerLidClosed = -83f; } private const float LookAtAngle = 50f; private const float LookAtMaxDistance = 30f; private const float AngryEyesCooldown = 0.3f; private const float TalkRotationMaxAngle = 25f; private const int SampleDataLength = 256; private const float StalkStareBeforeFlee = 3.030303f; private static readonly VepLogger LOG = VepLogger.Create<DroidFaceAnimationController>(); private float _angryTimer; private Transform _controllerTransform; private DroidController _droidController; private GameObject? _eyelidsLeft; private GameObject? _eyelidsRight; private Transform? _headTopTransform; private bool _isAngry; private Transform? _leftLowerEyelidRotationX; private Transform? _leftUpperEyelidRotationX; private Transform? _leftUpperEyelidRotationZ; private Transform? _rightLowerEyelidRotationX; private Transform? _rightUpperEyelidRotationX; private Transform? _rightUpperEyelidRotationZ; private float[]? _sampleData; private AudioSource? _talkingAudioSource; private bool _wasPlayerLooking; public bool IsPlayerLookingAtMe { get; private set; } public void Initialize(DroidController droidController, Transform controllerTransform) { _droidController = droidController; _controllerTransform = droidController.ControllerTransform; } public void SetupEyelids(GameObject? eyelidsLeft, GameObject? eyelidsRight, Transform? leftUpperX, Transform? leftUpperZ, Transform? leftLowerX, Transform? rightUpperX, Transform? rightUpperZ, Transform? rightLowerX) { _eyelidsLeft = eyelidsLeft; _eyelidsRight = eyelidsRight; _leftUpperEyelidRotationX = leftUpperX; _leftUpperEyelidRotationZ = leftUpperZ; _leftLowerEyelidRotationX = leftLowerX; _rightUpperEyelidRotationX = rightUpperX; _rightUpperEyelidRotationZ = rightUpperZ; _rightLowerEyelidRotationX = rightLowerX; } public void SetupTalking(Transform headTopTransform) { _headTopTransform = headTopTransform; } public void UpdateAnimations() { UpdatePlayerLookDetection(); UpdateAngryEyes(); UpdateTalkingAnimation(); } private void UpdateAngryEyes() { //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_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_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0209: 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_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_eyelidsLeft == (Object)null || (Object)(object)_eyelidsRight == (Object)null || (Object)(object)_leftUpperEyelidRotationX == (Object)null || (Object)(object)_rightUpperEyelidRotationX == (Object)null) { return; } if (IsPlayerLookingAtMe && !_wasPlayerLooking) { _angryTimer = (_droidController.IsStalking ? 3.030303f : 0.3f); } _wasPlayerLooking = IsPlayerLookingAtMe; if (IsPlayerLookingAtMe) { _angryTimer -= Time.deltaTime; if (_angryTimer <= 0f) { _isAngry = false; } } else { _isAngry = true; } if (_isAngry && !_eyelidsLeft.activeSelf) { _eyelidsLeft.SetActive(true); _eyelidsRight.SetActive(true); } float num = (_isAngry ? 83f : 0f); float num2 = (_isAngry ? (-83f) : 0f); float num3 = (_isAngry ? (-34f) : 0f); float num4 = (_isAngry ? 34f : 0f); float num5 = Time.deltaTime * 8f; _leftUpperEyelidRotationX.localRotation = Quaternion.Slerp(_leftUpperEyelidRotationX.localRotation, Quaternion.Euler(num, 0f, 0f), num5); _rightUpperEyelidRotationX.localRotation = Quaternion.Slerp(_rightUpperEyelidRotationX.localRotation, Quaternion.Euler(num, 0f, 0f), num5); if ((Object)(object)_leftUpperEyelidRotationZ != (Object)null) { _leftUpperEyelidRotationZ.localRotation = Quaternion.Slerp(_leftUpperEyelidRotationZ.localRotation, Quaternion.Euler(0f, 0f, num3), num5); } if ((Object)(object)_rightUpperEyelidRotationZ != (Object)null) { _rightUpperEyelidRotationZ.localRotation = Quaternion.Slerp(_rightUpperEyelidRotationZ.localRotation, Quaternion.Euler(0f, 0f, num4), num5); } if ((Object)(object)_leftLowerEyelidRotationX != (Object)null) { _leftLowerEyelidRotationX.localRotation = Quaternion.Slerp(_leftLowerEyelidRotationX.localRotation, Quaternion.Euler(num2, 0f, 0f), num5); } if ((Object)(object)_rightLowerEyelidRotationX != (Object)null) { _rightLowerEyelidRotationX.localRotation = Quaternion.Slerp(_rightLowerEyelidRotationX.localRotation, Quaternion.Euler(num2, 0f, 0f), num5); } if (!_isAngry && _eyelidsLeft.activeSelf) { float num6 = Mathf.Abs(_leftUpperEyelidRotationX.localEulerAngles.x); if ((num6 < 10f || num6 > 350f) ? true : false) { _eyelidsLeft.SetActive(false); _eyelidsRight.SetActive(false); } } } private void UpdatePlayerLookDetection() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0076: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if ((Object)(object)main == (Object)null || (Object)(object)_controllerTransform == (Object)null) { IsPlayerLookingAtMe = false; return; } Vector3 val = _controllerTransform.position + Vector3.up; Vector3 position = ((Component)main).transform.position; float num = Vector3.Distance(position, val); if (num > 30f) { IsPlayerLookingAtMe = false; return; } Vector3 val2 = val - position; Vector3 normalized = ((Vector3)(ref val2)).normalized; float num2 = Vector3.Dot(((Component)main).transform.forward, normalized); float num3 = Mathf.Cos(0.87266463f); IsPlayerLookingAtMe = num2 >= num3; } private void UpdateTalkingAnimation() { //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_headTopTransform == (Object)null) { return; } float num = 0f; if ((Object)(object)_talkingAudioSource == (Object)null && (Object)(object)_controllerTransform != (Object)null) { _talkingAudioSource = ((Component)_controllerTransform).GetComponent<AudioSource>(); } if ((Object)(object)_talkingAudioSource != (Object)null && _talkingAudioSource.isPlaying) { if (_sampleData == null) { _sampleData = new float[256]; } _talkingAudioSource.GetOutputData(_sampleData, 0); float num2 = 0f; float[] sampleData = _sampleData; foreach (float num3 in sampleData) { num2 += Mathf.Abs(num3); } num2 /= 256f; if (num2 > 0.01f) { num = Mathf.Lerp(0f, -25f, num2 * 10f); } } else { _talkingAudioSource = null; } _headTopTransform.localRotation = Quaternion.Slerp(_headTopTransform.localRotation, Quaternion.Euler(num, 0f, 0f), Time.deltaTime * 20f); } } public sealed class DroidFootstepsEventReceiver : MonoBehaviour { private static readonly VepLogger LOG = VepLogger.Create<DroidFootstepsEventReceiver>(); private DroidController _droid; public void Initialize(DroidController droidController) { _droid = droidController; } public void PlayMediumFootstep() { _droid.PlayMediumFootstep(); } } public static class DroidHelpers { public static bool IsMovementState(DroidController.StateId state) { if ((uint)(state - 1) <= 1u || (uint)(state - 4) <= 2u) { return true; } return false; } public static Transform? FindChildByName(Transform? root, string name, bool includeInactive = true) { if ((Object)(object)root == (Object)null) { return null; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(includeInactive); foreach (Transform val in componentsInChildren) { if (((Object)val).name == name) { return val; } } return null; } public static void FindChildrenByNames(Transform root, bool includeInactive, params (string name, Action<Transform> onFound)[] searches) { if ((Object)(object)root == (Object)null) { return; } int num = searches.Length; Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(includeInactive); foreach (Transform val in componentsInChildren) { for (int j = 0; j < searches.Length; j++) { var (text, action) = searches[j]; if (((Object)val).name == text) { action(val); num--; if (num == 0) { return; } } } } } public static bool TryGetNavMeshPosition(Vector3 position, out Vector3 result, int areaMask, float maxDistance = 5f) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(position, ref val, maxDistance, areaMask)) { result = ((NavMeshHit)(ref val)).position; return true; } result = position; return false; } public static AnimationClip? GetAnimationClip(Animator animator, string clipName) { if ((Object)(object)animator == (Object)null || (Object)(object)animator.runtimeAnimatorController == (Object)null) { return null; } AnimationClip[] animationClips = animator.runtimeAnimatorController.animationClips; foreach (AnimationClip val in animationClips) { if (((Object)val).name == clipName) { return val; } } return null; } public static bool IsNavAgentValid(NavMeshAgent agent) { return (Object)(object)agent != (Object)null && agent.isOnNavMesh; } public static Vector3? GetLocalPlayerPosition() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar instance = PlayerAvatar.instance; return ((Object)(object)instance != (Object)null) ? new Vector3?(((Component)instance).transform.position) : null; } } public sealed class DroidMovementController : MonoBehaviour { [CompilerGenerated] private sealed class <PrecomputeDestinationCoroutine>d__46 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public DroidMovementController <>4__this; private Vector3 <controllerPos>5__1; private LevelPoint <levelPoint>5__2; private Vector3 <targetPos>5__3; private NavMeshHit <hit>5__4; private NavMeshPath <path>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrecomputeDestinationCoroutine>d__46(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <levelPoint>5__2 = null; <path>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_00ee: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Invalid comparison between Unknown and I4 //IL_01f7: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this._isPrecomputingDestination = true; <controllerPos>5__1 = (((Object)(object)<>4__this._controllerTransform != (Object)null) ? <>4__this._controllerTransform.position : ((Component)<>4__this).transform.position); <levelPoint>5__2 = SemiFunc.LevelPointGet(<controllerPos>5__1, 5f, 15f) ?? SemiFunc.LevelPointGet(<controllerPos>5__1, 0f, 20f); if ((Object)(object)<levelPoint>5__2 == (Object)null) { <>4__this._isPrecomputingDestination = false; return false; } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <targetPos>5__3 = ((Component)<levelPoint>5__2).transform.position; if (!NavMesh.SamplePosition(<targetPos>5__3, ref <hit>5__4, 5f, <>4__this._savedAreaMask)) { <>4__this._isPrecomputingDestination = false; return false; } <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; if (!Physics.Raycast(((NavMeshHit)(ref <hit>5__4)).position + Vector3.up, Vector3.down, 5f, LayerMask.GetMask(new string[1] { "Default" }))) { <>4__this._isPrecomputingDestination = false; return false; } <path>5__5 = new NavMeshPath(); if (DroidHelpers.IsNavAgentValid(<>4__this._navAgent) && <>4__this._navAgent.CalculatePath(((NavMeshHit)(ref <hit>5__4)).position, <path>5__5) && (int)<path>5__5.status == 0) { <>4__this._precomputedDestination = ((NavMeshHit)(ref <hit>5__4)).position; } <>4__this._isPrecomputingDestination = false; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PrecomputeForwardDestinationCoroutine>d__49 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float minDistance; public float maxDistance; public float maxAngleDeviation; public DroidMovementController <>4__this; private Vector3 <direction>5__1; private string <directionSource>5__2; private float <angleDeviation>5__3; private float <distance>5__4; private Vector3 <currentPos>5__5; private Vector3 <targetPos>5__6; private NavMeshHit <hit>5__7; private NavMeshPath <path>5__8; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrecomputeForwardDestinationCoroutine>d__49(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <directionSource>5__2 = null; <path>5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: 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_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Expected O, but got Unknown //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Invalid comparison between Unknown and I4 //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this._isPrecomputingForward = true; LOG.Debug("PrecomputeForward: Starting coroutine"); if ((Object)(object)<>4__this._controllerTransform == (Object)null || !DroidHelpers.IsNavAgentValid(<>4__this._navAgent)) { LOG.Debug("PrecomputeForward: Invalid controller or NavAgent"); <>4__this._isPrecomputingForward = false; return false; } <direction>5__1 = ((Vector3)(ref <>4__this._currentVelocity)).normalized; <directionSource>5__2 = "velocity"; if (((Vector3)(ref <direction>5__1)).sqrMagnitude < 0.01f) { Vector3 val = <>4__this._destination - <>4__this._controllerTransform.position; <direction>5__1 = ((Vector3)(ref val)).normalized; <directionSource>5__2 = "destination"; } if (((Vector3)(ref <direction>5__1)).sqrMagnitude < 0.01f) { LOG.Debug("PrecomputeForward: No valid direction found"); <>4__this._isPrecomputingForward = false; return false; } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <angleDeviation>5__3 = Random.Range(0f - maxAngleDeviation, maxAngleDeviation); <direction>5__1 = Quaternion.Euler(0f, <angleDeviation>5__3, 0f) * <direction>5__1; <distance>5__4 = Random.Range(minDistance, maxDistance); <currentPos>5__5 = <>4__this._controllerTransform.position; <targetPos>5__6 = <currentPos>5__5 + <direction>5__1 * <distance>5__4; LOG.Debug($"PrecomputeForward: source={<directionSource>5__2}, angle={<angleDeviation>5__3:F1}°, dist={<distance>5__4:F1}m"); <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; if (!NavMesh.SamplePosition(<targetPos>5__6, ref <hit>5__7, 10f, <>4__this._savedAreaMask)) { LOG.Debug($"PrecomputeForward: No NavMesh position found near {<targetPos>5__6}"); <>4__this._isPrecomputingForward = false; return false; } <>2__current = null; <>1__state = 3; return true; case 3: <>1__state = -1; <path>5__8 = new NavMeshPath(); if (!<>4__this._navAgent.CalculatePath(((NavMeshHit)(ref <hit>5__7)).position, <path>5__8) || (int)<path>5__8.status > 0) { LOG.Debug($"PrecomputeForward: Path calculation failed to {((NavMeshHit)(ref <hit>5__7)).position}"); <>4__this._isPrecomputingForward = false; return false; } <>4__this._precomputedForwardDestination = ((NavMeshHit)(ref <hit>5__7)).position; LOG.Debug($"PrecomputeForward: SUCCESS - precomputed destination at {((NavMeshHit)(ref <hit>5__7)).position}"); <>4__this._isPrecomputingForward = false; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float RotationSpeed = 10f; private const float VisualYOffset = 0.25f; private static readonly VepLogger LOG = VepLogger.Create<DroidMovementController>(); private CharacterController _charController; private Transform _controllerTransform; private Vector3 _currentVelocity; private Vector3 _destination; private bool _isPrecomputingDestination; private bool _isPrecomputingForward; private NavMeshAgent _navAgent; private Vector3? _precomputedDestination; private Vector3? _precomputedForwardDestination; private Transform? _rigidbodyTransform; private int _savedAreaMask = -1; public bool HasPrecomputedDestination => _precomputedDestination.HasValue; public bool HasPrecomputedForwardDestination => _precomputedForwardDestination.HasValue; public Quaternion TargetRotation { get; private set; } = Quaternion.identity; public Vector3 CurrentVelocity => _currentVelocity; public event Action? OnNavMeshError; public float GetDistanceToPlayer() { //IL_0031: 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) Vector3? localPlayerPosition = DroidHelpers.GetLocalPlayerPosition(); if (!localPlayerPosition.HasValue || (Object)(object)_controllerTransform == (Object)null) { return float.MaxValue; } return Vector3.Distance(_controllerTransform.position, localPlayerPosition.Value); } public bool HasReachedDestination() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_navAgent == (Object)null || _navAgent.pathPending) { return false; } Vector3 val = (((Object)(object)_controllerTransform != (Object)null) ? _controllerTransform.position : ((Component)this).transform.position); float num = Vector3.Distance(val, _destination); return !_navAgent.hasPath || num <= _navAgent.stoppingDistance; } public void Initialize(Transform controllerTransform, Transform rigidbodyTransform, NavMeshAgent navAgent, CharacterController charController, int areaMask) { _controllerTransform = controllerTransform; _rigidbodyTransform = rigidbodyTransform; _navAgent = navAgent; _charController = charController; _savedAreaMask = areaMask; } public void LookAtPlayer() { //IL_002b: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) PlayerAvatar instance = PlayerAvatar.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)_c