Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EchoStalker v0.2.3
EchoStalker.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.AI; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("oance")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Prototype custom enemy for R.E.P.O.")] [assembly: AssemblyFileVersion("0.2.3.0")] [assembly: AssemblyInformationalVersion("0.2.3")] [assembly: AssemblyProduct("EchoStalker")] [assembly: AssemblyTitle("EchoStalker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EchoStalker { [BepInPlugin("oance.EchoStalker", "EchoStalker", "0.2.3")] [BepInProcess("REPO.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "oance.EchoStalker"; public const string PluginName = "EchoStalker"; public const string PluginVersion = "0.2.3"; public const string RepoLibGuid = "REPOLib"; internal static Plugin Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; internal static PrototypeConfig Settings { get; private set; } internal static bool IsInitialized { get { if ((Object)(object)Instance != (Object)null) { return Settings != null; } return false; } } private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; private void Awake() { Instance = this; Settings = new PrototypeConfig(((BaseUnityPlugin)this).Config); Logger.LogInfo((object)"oance.EchoStalker v0.2.3 loaded; waiting for the Echo Stalker REPOLib bundle."); } } internal sealed class PrototypeConfig { internal ConfigEntry<float> RoamSpeed { get; } internal ConfigEntry<float> ChaseSpeed { get; } internal ConfigEntry<int> CaptureDamage { get; } internal ConfigEntry<float> CaptureDamageInterval { get; } internal PrototypeConfig(ConfigFile config) { RoamSpeed = config.Bind<float>("Movement", "RoamSpeed", 1.7f, "Movement speed while roaming."); ChaseSpeed = config.Bind<float>("Movement", "ChaseBaseSpeed", 8.5f, "Base movement speed while chasing a player. This v0.2 key supersedes the prototype's old ChaseSpeed setting; the monster also gains catch-up speed at range."); CaptureDamage = config.Bind<int>("Capture", "Damage", 20, "Nonlethal damage dealt on capture and on each latched damage tick."); CaptureDamageInterval = config.Bind<float>("Capture", "DamageInterval", 5f, "Seconds between nonlethal damage ticks while latched to a player."); } } } namespace EchoStalker.Runtime { public sealed class EchoStalkerController : MonoBehaviour { private static readonly int AnimatorState = Animator.StringToHash("State"); private static readonly int AnimatorDeath = Animator.StringToHash("Death"); private static readonly FieldInfo? AudioCurrentSnapshotField = typeof(AudioManager).GetField("currentSnapshot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly HashSet<int> AudioIsolationOwners = new HashSet<int>(); private static SoundSnapshot audioSnapshotBeforeIsolation = (SoundSnapshot)1; private static bool audioSnapshotStored; [Header("Required R.E.P.O. components")] [SerializeField] private Enemy enemy; [SerializeField] private EnemyNavMeshAgent agent; [SerializeField] private EnemyHealth health; [SerializeField] private EnemyVision vision; [SerializeField] private EnemyStateSpawn spawnState; [SerializeField] private EnemyStateDespawn despawnState; [SerializeField] private EnemyStateStunned stunnedState; [SerializeField] private Collider bodyCollider; private PhotonView photonView; [Header("Origins")] [SerializeField] private Transform visionOrigin; [SerializeField] private Transform attackOrigin; [SerializeField] private Transform visualRoot; [Header("Presentation")] [SerializeField] private Animator? animator; [SerializeField] private Sound? spawnSound; [SerializeField] private Sound? ambientSound; [SerializeField] private Sound? alertSound; [SerializeField] private Sound? attackSound; [SerializeField] private Sound? captiveSound; [SerializeField] private Sound? hurtSound; [SerializeField] private Sound? deathSound; [Header("Senses")] [SerializeField] [Min(1f)] private float senseRange = 16f; [Header("Roaming")] [SerializeField] [Min(0.1f)] private float roamSpeed = 1.7f; [SerializeField] [Min(0.1f)] private float roamAcceleration = 6f; [SerializeField] [Min(0.1f)] private float roamRepathTime = 2.5f; [Header("Chase")] [SerializeField] [Min(0f)] private float alertTime = 0.85f; [SerializeField] [Min(0.1f)] private float chaseSpeed = 8.5f; [SerializeField] [Min(0.1f)] private float chaseAcceleration = 34f; [Header("Capture")] [SerializeField] [Min(0.1f)] private float captureRange = 2.1f; [SerializeField] [Min(0f)] private float captureWindup = 0.55f; [SerializeField] [Min(0f)] private int captureDamage = 20; [SerializeField] [Min(0.25f)] private float captureDamageInterval = 5f; [SerializeField] [Min(0.25f)] private float sitDistance = 0.7f; [SerializeField] [Min(0.1f)] private float sitFollowSpeed = 5f; [SerializeField] [Min(0.1f)] private float sitFollowAcceleration = 18f; [SerializeField] [Min(0.05f)] private float sitDeadZone = 0.22f; [SerializeField] [Min(0.1f)] private float sitTurnSpeed = 7f; [SerializeField] [Min(0.1f)] private float captureDamageConfirmTimeout = 1.25f; [Header("Thrown object impacts")] [SerializeField] [Min(0.1f)] private float thrownObjectMinSpeed = 2.5f; [SerializeField] [Min(0.1f)] private float thrownObjectMediumSpeed = 5f; [SerializeField] [Min(0.1f)] private float thrownObjectHeavySpeed = 8f; [SerializeField] [Min(0f)] private float thrownObjectDamagePerMass = 5f; [SerializeField] [Min(0f)] private float thrownObjectStunMass = 2f; [SerializeField] [Min(0f)] private float thrownObjectHitCooldown = 0.35f; [Header("Lifecycle")] [SerializeField] [Min(0f)] private float stateDespawnDelay = 0.65f; [SerializeField] [Min(0f)] private float deathDespawnDelay = 2.2f; private PlayerAvatar? target; private EnemyState observedState; private LayerMask visionMask; private float stateTime; private float repathTime; private bool hitApplied; private bool targetClaimed; private bool captureCommitted; private bool captureHealthReady; private bool captureDamageExpected; private bool captureDamageConfirmed; private bool captureDamageObserved; private bool captureHitInFlight; private int lowestObservedTargetHealth; private int healthFloorBeforePendingHit; private int claimedTargetViewId = -1; private int captureHitSequence; private int pendingCaptureHitSequence; private int lastProcessedCaptureHitMasterActorNumber = -1; private int lastProcessedCaptureHitSequence; private int lastProcessedCaptureHitTargetViewId = -1; private int lastProcessedCaptureHitPostHealth; private bool lastProcessedCaptureHitHealDetected; private float captureHitRequestedTime; private float captureAcknowledgedTime; private float nextCaptureDamageTime; private Vector3 sitOffsetDirection; private Quaternion visualRootInitialLocalRotation; private bool localCaptureHealthReady; private bool localCaptureAudioReleased; private int localLowestObservedTargetHealth; private bool holdsAudioIsolation; private bool captiveMixerAssigned; private bool captivePlaybackStartedLogged; private bool captivePlaybackWarningLogged; private float captivePlaybackRequestedTime; private bool dead; private bool deathFinished; private bool despawnCommitted; private float deathTime; private float nextThrownObjectHitTime; private bool setupIsValid; private bool IsHost => SemiFunc.IsMasterClientOrSingleplayer(); private void Awake() { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Expected O, but got Unknown //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown if (enemy == null) { enemy = ((Component)this).GetComponent<Enemy>(); } if (agent == null) { agent = ((Component)this).GetComponent<EnemyNavMeshAgent>(); } if (health == null) { health = ((Component)this).GetComponent<EnemyHealth>(); } if (vision == null) { vision = ((Component)this).GetComponentInChildren<EnemyVision>(true); } if (spawnState == null) { spawnState = ((Component)this).GetComponentInChildren<EnemyStateSpawn>(true); } if (despawnState == null) { despawnState = ((Component)this).GetComponentInChildren<EnemyStateDespawn>(true); } if (stunnedState == null) { stunnedState = ((Component)this).GetComponentInChildren<EnemyStateStunned>(true); } if (bodyCollider == null) { bodyCollider = ((Component)this).GetComponent<Collider>(); } if (photonView == null) { photonView = ((Component)this).GetComponent<PhotonView>(); } if (visionOrigin == null) { visionOrigin = ((Component)this).transform; } if (attackOrigin == null) { attackOrigin = ((Component)this).transform; } if (visualRoot == null) { visualRoot = ((Component)this).transform; } visualRootInitialLocalRotation = visualRoot.localRotation; visionMask = SemiFunc.LayerMaskGetVisionObstruct(); ConfigureCaptiveAudioSource(); DisableVanillaStates<EnemyStateRoaming>(); DisableVanillaStates<EnemyStateChaseBegin>(); DisableVanillaStates<EnemyStateChase>(); DisableVanillaStates<EnemyStateChaseSlow>(); DisableVanillaStates<EnemyStateChaseEnd>(); if (Plugin.IsInitialized) { roamSpeed = Mathf.Max(0.1f, Plugin.Settings.RoamSpeed.Value); chaseSpeed = Mathf.Max(0.1f, Plugin.Settings.ChaseSpeed.Value); captureDamage = Mathf.Max(0, Plugin.Settings.CaptureDamage.Value); captureDamageInterval = Mathf.Max(0.25f, Plugin.Settings.CaptureDamageInterval.Value); } setupIsValid = ValidateSetup(); if (!setupIsValid) { ((Behaviour)this).enabled = false; return; } health.onDeathStart.AddListener(new UnityAction(OnDeathStart)); health.onDeath.AddListener(new UnityAction(OnDeath)); health.onHurt.AddListener(new UnityAction(OnHurt)); spawnState.OnSpawn.AddListener(new UnityAction(OnSpawn)); } private void OnDestroy() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown ReleaseAudioIsolation(); if ((Object)(object)health != (Object)null) { UnityEvent onDeathStart = health.onDeathStart; if (onDeathStart != null) { onDeathStart.RemoveListener(new UnityAction(OnDeathStart)); } UnityEvent onDeath = health.onDeath; if (onDeath != null) { onDeath.RemoveListener(new UnityAction(OnDeath)); } UnityEvent onHurt = health.onHurt; if (onHurt != null) { onHurt.RemoveListener(new UnityAction(OnHurt)); } } if ((Object)(object)spawnState != (Object)null) { UnityEvent onSpawn = spawnState.OnSpawn; if (onSpawn != null) { onSpawn.RemoveListener(new UnityAction(OnSpawn)); } } Sound? obj = ambientSound; if (obj != null) { obj.Stop(); } Sound? obj2 = captiveSound; if (obj2 != null) { obj2.Stop(); } } private void OnDisable() { ReleaseAudioIsolation(); Sound? obj = captiveSound; if (obj != null) { obj.Stop(); } } private void Update() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Invalid comparison between Unknown and I4 //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Invalid comparison between Unknown and I4 //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Invalid comparison between Unknown and I4 //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Invalid comparison between Unknown and I4 //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected I4, but got Unknown if (!setupIsValid) { return; } EnemyState currentState = enemy.CurrentState; if (currentState != observedState) { observedState = currentState; EnterState(currentState); } bool flag = !dead && (int)currentState != 0 && (int)currentState != 11 && (int)currentState != 6; Sound? obj = ambientSound; if (obj != null) { obj.PlayLoop(flag, 0.25f, 0.25f, 1f, 1f); } bool captureStateActive = !dead && (int)currentState == 6; bool flag2 = UpdateLocalCaptureAudio(captureStateActive); Sound? obj2 = captiveSound; if (obj2 != null) { obj2.PlayLoop(flag2, 4f, 8f, 1f, 1f); } ReportCaptivePlayback(captureStateActive, flag2); UpdateReplicatedPresentation(currentState); if (targetClaimed && !dead) { MaintainClaimProtection(); } if (dead) { agent.Stop(0.1f); if (deathFinished) { deathTime += Time.deltaTime; if (IsHost && deathTime >= deathDespawnDelay) { CommitDespawn(); } } } else if ((int)currentState == 11) { agent.Stop(0.1f); stateTime += Time.deltaTime; if (IsHost && stateTime >= stateDespawnDelay) { CommitDespawn(); } } else { if (!IsHost) { return; } if ((int)currentState == 9 && targetClaimed) { stunnedState.Reset(); SetState((EnemyState)(captureCommitted ? 6 : 4)); return; } if (((int)currentState <= 1 || (int)currentState == 9) ? true : false) { agent.Stop(0.1f); return; } stateTime += Time.deltaTime; switch (currentState - 2) { case 0: UpdateRoam(); break; case 1: UpdateAlert(); break; case 2: UpdateChase(); break; case 3: UpdateCaptureWindup(); break; case 4: UpdateCaptured(); break; } } } private void OnCollisionEnter(Collision collision) { //IL_0069: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) if (!setupIsValid || !IsHost || dead || targetClaimed || !health.objectHurt || Time.time < nextThrownObjectHitTime) { return; } Rigidbody rigidbody = collision.rigidbody; if ((Object)(object)rigidbody == (Object)null || ((Object)(object)((Component)rigidbody).GetComponent<PhysGrabObject>() == (Object)null && (Object)(object)((Component)rigidbody).GetComponentInParent<PhysGrabObject>() == (Object)null)) { return; } Vector3 val = collision.relativeVelocity; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude < thrownObjectMinSpeed)) { nextThrownObjectHitTime = Time.time + thrownObjectHitCooldown; float num = ((magnitude >= thrownObjectHeavySpeed) ? 3f : ((magnitude >= thrownObjectMediumSpeed) ? 2f : 1f)); int num2 = Mathf.Max(1, Mathf.RoundToInt(thrownObjectDamagePerMass * num * Mathf.Max(0.5f, rigidbody.mass) * Mathf.Max(0f, health.objectHurtMultiplier))); val = ((Component)this).transform.position - rigidbody.worldCenterOfMass; Vector3 normalized = ((Vector3)(ref val)).normalized; health.Hurt(num2, normalized); UnityEvent onObjectHurt = health.onObjectHurt; if (onObjectHurt != null) { onObjectHurt.Invoke(); } if (!dead && health.objectHurtStun && rigidbody.mass >= thrownObjectStunMass) { stunnedState.Set(2f); } } } private void EnterState(EnemyState state) { //IL_003c: 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_0070: Expected I4, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected I4, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) stateTime = 0f; repathTime = 0f; hitApplied = false; if ((Object)(object)animator != (Object)null) { animator.SetInteger(AnimatorState, (int)state); } switch (state - 1) { case 0: dead = false; deathFinished = false; despawnCommitted = false; deathTime = 0f; nextThrownObjectHitTime = 0f; target = null; targetClaimed = false; captureCommitted = false; captureHealthReady = false; captureDamageExpected = false; captureDamageConfirmed = false; captureDamageObserved = false; captureHitInFlight = false; lowestObservedTargetHealth = 0; healthFloorBeforePendingHit = 0; claimedTargetViewId = -1; pendingCaptureHitSequence = 0; captureHitRequestedTime = 0f; captureAcknowledgedTime = 0f; nextCaptureDamageTime = 0f; sitOffsetDirection = Vector3.zero; ResetLocalCaptureAudioState(); ReleaseAudioIsolation(); visualRoot.localRotation = visualRootInitialLocalRotation; health.OverrideDamageResistance(0f, 0f); stunnedState.OverrideDisable(0f); bodyCollider.enabled = true; Play(spawnSound); break; case 2: { if (enemy.TargetPlayerViewID > 0) { claimedTargetViewId = enemy.TargetPlayerViewID; } ResetLocalCaptureAudioState(); targetClaimed = true; MaintainClaimProtection(); EnemyNavMeshAgent obj3 = agent; if (obj3 != null) { obj3.Stop(0.1f); } Play(alertSound); break; } case 3: targetClaimed = true; MaintainClaimProtection(); break; case 4: { targetClaimed = true; MaintainClaimProtection(); EnemyNavMeshAgent obj2 = agent; if (obj2 != null) { obj2.Stop(0.1f); } Play(attackSound); break; } case 5: { targetClaimed = true; captureCommitted = true; MaintainClaimProtection(); EnemyNavMeshAgent obj5 = agent; if (obj5 != null) { obj5.Stop(0.1f); } bodyCollider.enabled = false; nextCaptureDamageTime = Time.time + captureDamageInterval; break; } case 8: { EnemyNavMeshAgent obj4 = agent; if (obj4 != null) { obj4.Stop(0.1f); } break; } case 10: { despawnCommitted = false; EnemyNavMeshAgent obj = agent; if (obj != null) { obj.Stop(0.1f); } StopLoops(); ReleaseAudioIsolation(); break; } case 1: case 6: case 7: case 9: break; } } private void UpdateRoam() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Invalid comparison between Unknown and I4 agent.UpdateAgent(roamSpeed, roamAcceleration); repathTime -= Time.deltaTime; if (repathTime <= 0f || !agent.HasPath()) { Vector3 destination = default(Vector3); if (SemiFunc.EnemyRoamPoint(enemy, ref destination)) { agent.SetDestination(destination); } repathTime = roamRepathTime; } PlayerAvatar val = FindTarget(senseRange); if (IsTargetUsable(val)) { target = val; claimedTargetViewId = val.photonView.ViewID; targetClaimed = true; MaintainClaimProtection(); enemy.SetChaseTarget(val); if ((int)enemy.CurrentState != 3) { target = null; claimedTargetViewId = -1; targetClaimed = false; } } } private void UpdateAlert() { agent.Stop(0.1f); if (!IsTargetUsable(target)) { RecoverReplicatedTarget(); } if (!IsTargetUsable(target)) { SetState((EnemyState)11); } else if (stateTime >= alertTime) { SetState((EnemyState)4); } } private void UpdateChase() { //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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (!IsTargetUsable(target)) { RecoverReplicatedTarget(); } if (!IsTargetUsable(target)) { SetState((EnemyState)11); return; } PlayerAvatar val = target; Vector3 position = val.playerTransform.position; float num = Vector3.Distance(((Component)this).transform.position, position); enemy.SetChaseTimer(); float num2 = chaseSpeed + Mathf.Clamp((num - 4f) * 0.65f, 0f, 4f); agent.UpdateAgent(num2, chaseAcceleration); agent.SetDestination(position); if (num <= captureRange && SemiFunc.PlayerVisionCheckPosition(attackOrigin.position, position, captureRange + 0.5f, val, true)) { SetState((EnemyState)5); } } private void UpdateCaptureWindup() { agent.Stop(0.1f); if (!IsTargetUsable(target)) { RecoverReplicatedTarget(); } if (!IsTargetUsable(target)) { SetState((EnemyState)11); } else if (!hitApplied && stateTime >= captureWindup) { if (!TryCaptureTarget()) { SetState((EnemyState)4); return; } hitApplied = true; SetState((EnemyState)6); } } private void UpdateCaptured() { if (!IsTargetUsable(target)) { RecoverReplicatedTarget(); } if (!IsTargetUsable(target) || (Object)(object)target.playerHealth == (Object)null || target.playerHealth.health <= 0) { SetState((EnemyState)11); return; } MoveBesideTarget(target); PlayerHealth playerHealth = target.playerHealth; if (!captureHealthReady) { if (playerHealth.healthSet) { captureHealthReady = true; lowestObservedTargetHealth = playerHealth.health; captureDamageConfirmed = true; captureDamageObserved = true; captureHitInFlight = false; } return; } int num = playerHealth.health; if (!captureDamageConfirmed) { if (Time.time - captureHitRequestedTime >= captureDamageConfirmTimeout) { SetState((EnemyState)11); } } else if (!captureDamageObserved) { if (num <= lowestObservedTargetHealth) { captureDamageObserved = true; lowestObservedTargetHealth = num; } else if (Time.time - captureAcknowledgedTime >= 0.35f) { SetState((EnemyState)11); } } else if (num > lowestObservedTargetHealth) { SetState((EnemyState)11); } else { lowestObservedTargetHealth = Mathf.Min(lowestObservedTargetHealth, num); if (Time.time >= nextCaptureDamageTime) { BeginCaptureDamageHit(playerHealth); } } } private PlayerAvatar? FindTarget(float range) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return SemiFunc.PlayerGetNearestPlayerAvatarWithinRange(range, visionOrigin.position, true, visionMask); } private bool TryCaptureTarget() { //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_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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!IsTargetUsable(target) || (Object)(object)target.playerHealth == (Object)null) { return false; } Vector3 position = target.playerTransform.position; if (Vector3.Distance(attackOrigin.position, position) > captureRange + 0.5f || !SemiFunc.PlayerVisionCheckPosition(attackOrigin.position, position, captureRange + 0.5f, target, true)) { return false; } PlayerHealth playerHealth = target.playerHealth; if (!playerHealth.healthSet) { return false; } captureHealthReady = playerHealth.healthSet; lowestObservedTargetHealth = playerHealth.health; captureCommitted = true; SetSitOffset(target); BeginCaptureDamageHit(playerHealth); return true; } private void BeginCaptureDamageHit(PlayerHealth targetHealth) { if (targetHealth.healthSet) { lowestObservedTargetHealth = Mathf.Min(lowestObservedTargetHealth, targetHealth.health); healthFloorBeforePendingHit = lowestObservedTargetHealth; captureDamageExpected = captureDamage > 0 && targetHealth.health > 1; captureDamageConfirmed = !captureDamageExpected; captureDamageObserved = !captureDamageExpected; captureHitInFlight = captureDamageExpected; captureHitRequestedTime = Time.time; nextCaptureDamageTime = Time.time + captureDamageInterval; if (captureDamageExpected) { pendingCaptureHitSequence = ++captureHitSequence; SendNonlethalCaptureHit(targetHealth, pendingCaptureHitSequence); } } } private void SendNonlethalCaptureHit(PlayerHealth targetHealth, int hitSequence) { int num = SemiFunc.EnemyGetIndex(enemy); if (!GameManager.Multiplayer()) { int num2 = ApplyNonlethalCaptureHit(targetHealth, captureDamage, num); ConfirmCaptureHit(targetHealth.photonView.ViewID, hitSequence, num2); RecordLocalCaptureHealth(num2); return; } photonView.RPC("CaptureHitRPC", (RpcTarget)0, new object[5] { targetHealth.photonView.ViewID, hitSequence, healthFloorBeforePendingHit, captureDamage, num }); } [PunRPC] private void CaptureHitRPC(int targetViewId, int hitSequence, int expectedHealthFloor, int requestedDamage, int enemyIndex, PhotonMessageInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Invalid comparison between Unknown and I4 if (!SemiFunc.MasterOnlyRPC(info)) { return; } PhotonView val = PhotonView.Find(targetViewId); if ((Object)(object)val == (Object)null || !val.IsMine) { return; } PlayerHealth val2 = ((Component)val).GetComponent<PlayerHealth>() ?? ((Component)val).GetComponentInChildren<PlayerHealth>(true) ?? ((Component)val).GetComponentInParent<PlayerHealth>(); if ((Object)(object)val2 == (Object)null) { return; } Player sender = info.Sender; int num = ((sender != null) ? sender.ActorNumber : (-1)); if (num == lastProcessedCaptureHitMasterActorNumber && hitSequence <= lastProcessedCaptureHitSequence) { if (hitSequence == lastProcessedCaptureHitSequence && targetViewId == lastProcessedCaptureHitTargetViewId) { SendCaptureHitResult(targetViewId, hitSequence, lastProcessedCaptureHitPostHealth, lastProcessedCaptureHitHealDetected); } return; } EnemyState currentState = enemy.CurrentState; bool flag = currentState - 3 <= 3; bool flag2 = flag; if (((Behaviour)this).enabled && setupIsValid && !dead && flag2 && (claimedTargetViewId <= 0 || targetViewId == claimedTargetViewId)) { bool flag3 = localCaptureAudioReleased || val2.health > Mathf.Max(1, expectedHealthFloor) || (localCaptureHealthReady && val2.health > localLowestObservedTargetHealth); int num2 = val2.health; if (flag3) { localCaptureAudioReleased = true; ReleaseAudioIsolation(); } else { num2 = ApplyNonlethalCaptureHit(val2, requestedDamage, enemyIndex); RecordLocalCaptureHealth(num2); } lastProcessedCaptureHitMasterActorNumber = num; lastProcessedCaptureHitSequence = hitSequence; lastProcessedCaptureHitTargetViewId = targetViewId; lastProcessedCaptureHitPostHealth = num2; lastProcessedCaptureHitHealDetected = flag3; SendCaptureHitResult(targetViewId, hitSequence, num2, flag3); } } private void SendCaptureHitResult(int targetViewId, int hitSequence, int postHitHealth, bool healDetected) { photonView.RPC("CaptureHitResultRPC", (RpcTarget)2, new object[4] { targetViewId, hitSequence, postHitHealth, healDetected }); } [PunRPC] private void CaptureHitResultRPC(int targetViewId, int hitSequence, int postHitHealth, bool healDetected, PhotonMessageInfo info) { //IL_0033: 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) //IL_003b: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient || !captureCommitted || !captureHitInFlight || targetViewId != claimedTargetViewId || hitSequence != pendingCaptureHitSequence || postHitHealth < 1) { return; } EnemyState currentState = enemy.CurrentState; if ((int)currentState != 5 && (int)currentState != 6) { return; } PhotonView val = PhotonView.Find(targetViewId); if (!((Object)(object)val == (Object)null) && SemiFunc.OwnerOnlyRPC(info, val)) { if (healDetected || postHitHealth > healthFloorBeforePendingHit) { captureHitInFlight = false; SetState((EnemyState)11); } else { ConfirmCaptureHit(targetViewId, hitSequence, postHitHealth); } } } private void ConfirmCaptureHit(int targetViewId, int hitSequence, int postHitHealth) { if (hitSequence == pendingCaptureHitSequence && (!GameManager.Multiplayer() || targetViewId == claimedTargetViewId)) { captureHitInFlight = false; captureDamageConfirmed = true; captureDamageObserved = !captureDamageExpected; lowestObservedTargetHealth = Mathf.Min(healthFloorBeforePendingHit, Mathf.Max(1, postHitHealth)); captureAcknowledgedTime = Time.time; } } private static int ApplyNonlethalCaptureHit(PlayerHealth targetHealth, int requestedDamage, int enemyIndex) { int num = Mathf.Min(Mathf.Max(0, requestedDamage), Mathf.Max(0, targetHealth.health - 1)); if (num > 0) { targetHealth.Hurt(num, false, enemyIndex, false); } return targetHealth.health; } private void MoveBesideTarget(PlayerAvatar activeTarget) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref sitOffsetDirection)).sqrMagnitude < 0.5f) { SetSitOffset(activeTarget); } Vector3 position = activeTarget.playerTransform.position; Vector3 val = position + sitOffsetDirection * sitDistance; NavMeshHit val2 = default(NavMeshHit); val = ((!NavMesh.SamplePosition(val, ref val2, 1.5f, -1)) ? position : ((NavMeshHit)(ref val2)).position); Vector3 val3 = val - ((Component)this).transform.position; val3.y = 0f; if (((Vector3)(ref val3)).magnitude > sitDeadZone) { agent.UpdateAgent(sitFollowSpeed, sitFollowAcceleration); agent.SetDestination(val); } else { agent.Stop(0.1f); } } private void SetSitOffset(PlayerAvatar activeTarget) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) Vector3 right = activeTarget.playerTransform.right; right.y = 0f; if (((Vector3)(ref right)).sqrMagnitude < 0.01f) { right = Vector3.right; } ((Vector3)(ref right)).Normalize(); Vector3 val = ((Component)this).transform.position - activeTarget.playerTransform.position; val.y = 0f; float num = ((Vector3.Dot(val, right) < 0f) ? (-1f) : 1f); sitOffsetDirection = right * num; } private void RecoverReplicatedTarget() { if (IsClaimedTarget(enemy.TargetPlayerAvatar)) { target = enemy.TargetPlayerAvatar; } } private void MaintainClaimProtection() { health.OverrideDamageResistance(1f, 0.5f); stunnedState.OverrideDisable(0.5f); } private bool UpdateLocalCaptureAudio(bool captureStateActive) { ConfigureCaptiveAudioSource(); if (!captureStateActive) { ReleaseAudioIsolation(); return false; } PlayerAvatar val = (PlayerAvatar)(IsClaimedTarget(target) ? ((object)target) : ((object)enemy.TargetPlayerAvatar)); if (!IsClaimedTarget(val) || !IsLocalPlayer(val)) { ReleaseAudioIsolation(); return false; } PlayerHealth playerHealth = val.playerHealth; if (playerHealth.healthSet) { if (!localCaptureHealthReady) { RecordLocalCaptureHealth(playerHealth.health); } else if (playerHealth.health > localLowestObservedTargetHealth) { localCaptureAudioReleased = true; } else { localLowestObservedTargetHealth = Mathf.Min(localLowestObservedTargetHealth, playerHealth.health); } } if (localCaptureAudioReleased) { ReleaseAudioIsolation(); return false; } AcquireAudioIsolation(); return true; } private void RecordLocalCaptureHealth(int currentHealth) { int num = Mathf.Max(1, currentHealth); if (!localCaptureHealthReady) { localCaptureHealthReady = true; localCaptureAudioReleased = false; localLowestObservedTargetHealth = num; } else { localLowestObservedTargetHealth = Mathf.Min(localLowestObservedTargetHealth, num); } } private void ResetLocalCaptureAudioState() { localCaptureHealthReady = false; localCaptureAudioReleased = false; localLowestObservedTargetHealth = 0; } private void ConfigureCaptiveAudioSource() { AudioSource val = captiveSound?.Source; if ((Object)(object)val == (Object)null) { return; } captiveSound.StartTimeOverride = 0f; val.ignoreListenerPause = true; val.ignoreListenerVolume = false; val.priority = 0; if (!captiveMixerAssigned && !((Object)(object)AudioManager.instance == (Object)null) && !((Object)(object)AudioManager.instance.AudioCutscene == (Object)null)) { AudioSource component = AudioManager.instance.AudioCutscene.GetComponent<AudioSource>(); if ((Object)(object)component != (Object)null && (Object)(object)component.outputAudioMixerGroup != (Object)null) { val.outputAudioMixerGroup = component.outputAudioMixerGroup; captiveMixerAssigned = true; } } } private void AcquireAudioIsolation() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) AudioManager instance = AudioManager.instance; if (holdsAudioIsolation || (Object)(object)captiveSound?.Source == (Object)null || (Object)(object)instance == (Object)null || !captiveMixerAssigned) { return; } int instanceID = ((Object)this).GetInstanceID(); if (AudioIsolationOwners.Add(instanceID) && AudioIsolationOwners.Count == 1) { if (!TryGetCurrentSoundSnapshot(instance, out audioSnapshotBeforeIsolation)) { audioSnapshotBeforeIsolation = (SoundSnapshot)1; } audioSnapshotStored = true; instance.SetSoundSnapshot((SoundSnapshot)3, 0.05f); } holdsAudioIsolation = true; } private void ReleaseAudioIsolation() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 if (!holdsAudioIsolation) { return; } Sound? obj = captiveSound; if (obj != null) { obj.Stop(); } AudioIsolationOwners.Remove(((Object)this).GetInstanceID()); holdsAudioIsolation = false; if (AudioIsolationOwners.Count == 0 && audioSnapshotStored) { AudioManager instance = AudioManager.instance; if ((Object)(object)instance != (Object)null && (!TryGetCurrentSoundSnapshot(instance, out var snapshot) || (int)snapshot == 3)) { instance.SetSoundSnapshot(audioSnapshotBeforeIsolation, 0.1f); } audioSnapshotStored = false; } } private static bool TryGetCurrentSoundSnapshot(AudioManager audioManager, out SoundSnapshot snapshot) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected I4, but got Unknown if (AudioCurrentSnapshotField?.GetValue(audioManager) is SoundSnapshot val) { snapshot = (SoundSnapshot)(int)val; return true; } snapshot = (SoundSnapshot)1; return false; } private void ReportCaptivePlayback(bool captureStateActive, bool captiveActive) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Invalid comparison between Unknown and I4 //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) AudioSource val = captiveSound?.Source; if (!captureStateActive) { captivePlaybackStartedLogged = false; captivePlaybackWarningLogged = false; captivePlaybackRequestedTime = 0f; } else { if (!captiveActive || (Object)(object)val == (Object)null) { return; } if (captivePlaybackRequestedTime <= 0f) { captivePlaybackRequestedTime = Time.unscaledTime; } AudioClip clip = val.clip; if (val.isPlaying) { if (!captivePlaybackStartedLogged && Plugin.IsInitialized) { string arg = (((Object)(object)val.outputAudioMixerGroup != (Object)null) ? ((Object)val.outputAudioMixerGroup).name : "direct output"); Plugin.Logger.LogInfo((object)("Captive audio started: clip='" + (((clip != null) ? ((Object)clip).name : null) ?? "<none>") + "', loadState=" + (((clip != null) ? ((object)clip.loadState/*cast due to .constrained prefix*/).ToString() : null) ?? "missing") + ", " + $"volume={val.volume:F2}, mixer='{arg}'.")); } captivePlaybackStartedLogged = true; return; } bool flag = (Object)(object)clip != (Object)null && (int)clip.loadState == 3; if (!captivePlaybackWarningLogged && (flag || Time.unscaledTime - captivePlaybackRequestedTime >= 1.5f) && Plugin.IsInitialized) { Plugin.Logger.LogWarning((object)("Captive audio was requested but is not playing: clip='" + (((clip != null) ? ((Object)clip).name : null) ?? "<none>") + "', loadState=" + (((clip != null) ? ((object)clip.loadState/*cast due to .constrained prefix*/).ToString() : null) ?? "missing") + ", " + $"sourceEnabled={((Behaviour)val).enabled}, active={((Component)val).gameObject.activeInHierarchy}, " + $"mixerAssigned={(Object)(object)val.outputAudioMixerGroup != (Object)null}.")); captivePlaybackWarningLogged = true; } } } private static bool IsLocalPlayer(PlayerAvatar player) { if ((Object)(object)PlayerController.instance != (Object)null && (Object)(object)player == (Object)(object)PlayerController.instance.playerAvatarScript) { return true; } if (!GameManager.Multiplayer()) { return (Object)(object)PlayerController.instance == (Object)null; } if ((Object)(object)player.photonView != (Object)null) { return player.photonView.IsMine; } return false; } private bool IsClaimedTarget(PlayerAvatar? player) { if (IsTargetUsable(player) && (Object)(object)player.photonView != (Object)null) { if (claimedTargetViewId > 0) { return player.photonView.ViewID == claimedTargetViewId; } return true; } return false; } private void UpdateReplicatedPresentation(EnemyState state) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) bodyCollider.enabled = !dead && (int)state != 6 && (int)state != 11; if ((int)state != 6 || (Object)(object)visualRoot == (Object)null) { return; } PlayerAvatar val = (PlayerAvatar)(IsClaimedTarget(target) ? ((object)target) : ((object)enemy.TargetPlayerAvatar)); if (IsClaimedTarget(val)) { Vector3 val2 = val.playerTransform.position - visualRoot.position; val2.y = 0f; if (!(((Vector3)(ref val2)).sqrMagnitude < 0.01f)) { Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up); visualRoot.rotation = Quaternion.Slerp(visualRoot.rotation, val3, 1f - Mathf.Exp((0f - sitTurnSpeed) * Time.deltaTime)); } } } private void SetState(EnemyState next) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (IsHost && !dead && enemy.CurrentState != next) { enemy.CurrentState = next; } } private void OnHurt() { if (!targetClaimed) { Play(hurtSound); } } private void OnDeathStart() { dead = true; deathFinished = false; despawnCommitted = false; deathTime = 0f; EnemyNavMeshAgent obj = agent; if (obj != null) { obj.Stop(0.5f); } StopLoops(); Play(deathSound); Animator? obj2 = animator; if (obj2 != null) { obj2.SetTrigger(AnimatorDeath); } } private void OnDeath() { deathFinished = true; deathTime = 0f; } private void OnSpawn() { if (IsHost) { SemiFunc.EnemySpawn(enemy); } } private void Play(Sound? sound) { if (sound != null) { sound.Play(((Component)this).transform, 1f, 1f, 1f, 1f); } } private void StopLoops() { Sound? obj = ambientSound; if (obj != null) { obj.PlayLoop(false, 0.1f, 0.25f, 1f, 1f); } Sound? obj2 = captiveSound; if (obj2 != null) { obj2.PlayLoop(false, 0.1f, 0.25f, 1f, 1f); } ReleaseAudioIsolation(); } private bool ValidateSetup() { string missing = string.Empty; AppendMissing((Object)(object)enemy == (Object)null, "Enemy"); AppendMissing((Object)(object)agent == (Object)null, "EnemyNavMeshAgent"); AppendMissing((Object)(object)health == (Object)null, "EnemyHealth"); AppendMissing((Object)(object)vision == (Object)null, "EnemyVision"); AppendMissing((Object)(object)spawnState == (Object)null, "EnemyStateSpawn"); AppendMissing((Object)(object)despawnState == (Object)null, "EnemyStateDespawn"); AppendMissing((Object)(object)stunnedState == (Object)null, "EnemyStateStunned"); AppendMissing((Object)(object)bodyCollider == (Object)null, "body Collider"); AppendMissing((Object)(object)photonView == (Object)null, "PhotonView"); AppendMissing((Object)(object)visualRoot == (Object)null, "visual root"); AppendMissing((Object)(object)((Component)this).GetComponentInChildren<EnemyStateChase>(true) == (Object)null, "EnemyStateChase marker"); AppendMissing((Object)(object)health != (Object)null && health.onDeathStart == null, "EnemyHealth.onDeathStart"); AppendMissing((Object)(object)health != (Object)null && health.onDeath == null, "EnemyHealth.onDeath"); AppendMissing((Object)(object)health != (Object)null && health.onHurt == null, "EnemyHealth.onHurt"); AppendMissing((Object)(object)spawnState != (Object)null && spawnState.OnSpawn == null, "EnemyStateSpawn.OnSpawn"); AppendMissing(ambientSound == null || (Object)(object)ambientSound.Source == (Object)null, "ambient Sound.Source"); AppendMissing(captiveSound == null || (Object)(object)captiveSound.Source == (Object)null, "captive Sound.Source"); if (missing.Length == 0) { return true; } Debug.LogError((object)("[EchoStalker] Prefab setup is incomplete (" + missing + "). Disabling custom AI on '" + ((Object)this).name + "'."), (Object)(object)this); return false; void AppendMissing(bool condition, string item) { if (condition) { missing += ((missing.Length == 0) ? item : (", " + item)); } } } private static bool IsTargetUsable(PlayerAvatar? player) { if ((Object)(object)player != (Object)null && !player.isDisabled && (Object)(object)player.playerTransform != (Object)null && (Object)(object)player.playerHealth != (Object)null) { return player.playerHealth.health > 0; } return false; } private void DisableVanillaStates<T>() where T : Behaviour { T[] componentsInChildren = ((Component)this).GetComponentsInChildren<T>(true); foreach (T val in componentsInChildren) { ((Behaviour)val).enabled = false; } } private void CommitDespawn() { if (!despawnCommitted && IsHost) { despawnCommitted = true; despawnState.Despawn(); } } } public sealed class FriendMonsterVisualAnimator : MonoBehaviour { private readonly struct JointPose { internal Transform Transform { get; } internal Quaternion Rotation { get; } internal JointPose(Transform transform) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Transform = transform; Rotation = transform.localRotation; } } private static readonly int MouthOpenProperty = Shader.PropertyToID("_MouthOpen"); [SerializeField] private Enemy enemy; private readonly List<JointPose> fingers = new List<JointPose>(); private Transform? rig; private Transform? torso; private Transform? head; private Transform? leftShoulder; private Transform? rightShoulder; private Transform? leftElbow; private Transform? rightElbow; private Transform? leftWrist; private Transform? rightWrist; private Transform? leftHip; private Transform? rightHip; private Transform? mouth; private Renderer? faceRenderer; private MaterialPropertyBlock? faceProperties; private Vector3 rigPosition; private Vector3 torsoPosition; private Vector3 headPosition; private Vector3 mouthScale; private Quaternion torsoRotation; private Quaternion headRotation; private Quaternion leftShoulderRotation; private Quaternion rightShoulderRotation; private Quaternion leftElbowRotation; private Quaternion rightElbowRotation; private Quaternion leftWristRotation; private Quaternion rightWristRotation; private Quaternion leftHipRotation; private Quaternion rightHipRotation; private float phaseOffset; private float renderedMouthOpen; private bool ready; private void Awake() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: 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_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: 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_0272: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028f: 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_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) if (enemy == null) { enemy = ((Component)this).GetComponentInParent<Enemy>(); } rig = FindDescendant("Friend Rig"); torso = FindDescendant("Torso Pivot"); head = FindDescendant("Head Pivot"); leftShoulder = FindDescendant("Left Shoulder Pivot"); rightShoulder = FindDescendant("Right Shoulder Pivot"); leftElbow = FindDescendant("Left Elbow Pivot"); rightElbow = FindDescendant("Right Elbow Pivot"); leftWrist = FindDescendant("Left Wrist Pivot"); rightWrist = FindDescendant("Right Wrist Pivot"); leftHip = FindDescendant("Left Hip Pivot"); rightHip = FindDescendant("Right Hip Pivot"); mouth = FindDescendant("Mouth"); Transform? obj = FindDescendant("Friend Face Decal"); faceRenderer = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null); faceProperties = ((!((Object)(object)faceRenderer != (Object)null)) ? ((MaterialPropertyBlock)null) : new MaterialPropertyBlock()); ready = (Object)(object)enemy != (Object)null && (Object)(object)rig != (Object)null && (Object)(object)torso != (Object)null && (Object)(object)head != (Object)null && (Object)(object)leftShoulder != (Object)null && (Object)(object)rightShoulder != (Object)null && (Object)(object)leftElbow != (Object)null && (Object)(object)rightElbow != (Object)null && (Object)(object)leftWrist != (Object)null && (Object)(object)rightWrist != (Object)null && (Object)(object)leftHip != (Object)null && (Object)(object)rightHip != (Object)null && (Object)(object)mouth != (Object)null; if (!ready) { ((Behaviour)this).enabled = false; return; } rigPosition = rig.localPosition; torsoPosition = torso.localPosition; headPosition = head.localPosition; mouthScale = mouth.localScale; torsoRotation = torso.localRotation; headRotation = head.localRotation; leftShoulderRotation = leftShoulder.localRotation; rightShoulderRotation = rightShoulder.localRotation; leftElbowRotation = leftElbow.localRotation; rightElbowRotation = rightElbow.localRotation; leftWristRotation = leftWrist.localRotation; rightWristRotation = rightWrist.localRotation; leftHipRotation = leftHip.localRotation; rightHipRotation = rightHip.localRotation; phaseOffset = (float)(((Object)this).GetInstanceID() & 0xFF) * (1f / 32f); Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name.StartsWith("Finger ", StringComparison.Ordinal) || ((Object)val).name == "Thumb") { fingers.Add(new JointPose(val)); } } } private void Update() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00a3: Expected I4, but got Unknown //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Unknown result type (might be due to invalid IL or missing references) //IL_0572: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Unknown result type (might be due to invalid IL or missing references) //IL_05d8: Unknown result type (might be due to invalid IL or missing references) //IL_05df: Unknown result type (might be due to invalid IL or missing references) //IL_05f3: Unknown result type (might be due to invalid IL or missing references) //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Unknown result type (might be due to invalid IL or missing references) //IL_0662: Unknown result type (might be due to invalid IL or missing references) //IL_0669: Unknown result type (might be due to invalid IL or missing references) //IL_0674: Unknown result type (might be due to invalid IL or missing references) //IL_0676: Invalid comparison between Unknown and I4 if (ready) { EnemyState currentState = enemy.CurrentState; float num = Time.time + phaseOffset; float num2 = 0f; float num3 = 0f; float num4 = 0f; float num5 = 0f; float num6 = 0f; float num7 = 0f; float num8 = 0f; float num9 = 0f; float num10 = 0f; float num11 = 0f; float num12 = 4f; float num13 = 0f; float num14 = 10f; switch (currentState - 2) { case 0: num2 = num * 2.4f; num3 = Mathf.Abs(Mathf.Sin(num2)) * 0.035f; num8 = 15f; num11 = 5f; num12 = 7f; num13 = 0.08f; num14 = 6f; break; case 1: num2 = num * 5f; num4 = -0.18f; num5 = -16f; num6 = 12f; num7 = -28f; num9 = 12f; num10 = -18f; num11 = 12f; num12 = 2f; num13 = 0.35f; num14 = 13f; break; case 2: num2 = num * 9.5f; num3 = Mathf.Abs(Mathf.Sin(num2)) * 0.09f; num5 = -13f; num6 = 9f; num7 = -8f; num8 = 54f; num9 = 8f; num10 = -24f; num11 = 24f; num12 = 16f + Mathf.Sin(num2 * 1.7f) * 13f; num13 = 0.35f + Mathf.Abs(Mathf.Sin(num2 * 0.55f)) * 0.35f; num14 = 18f; break; case 3: num2 = num * 8f; num4 = -0.12f; num5 = -20f; num6 = 14f; num7 = -72f; num9 = 10f; num10 = -22f; num11 = 18f; num12 = 8f + Mathf.Sin(num2) * 7f; num13 = 0.65f; num14 = 20f; break; case 4: num2 = num * 7.5f; num4 = -0.42f; num3 = Mathf.Sin(num2 * 0.5f) * 0.025f; num5 = -7f + Mathf.Sin(num2 * 0.45f) * 5f; num6 = Mathf.Sin(num2 * 0.65f) * 8f; num7 = -48f; num8 = 20f; num9 = 28f; num10 = -48f; num11 = 38f; num12 = 18f + Mathf.Sin(num2 * 1.6f) * 17f; num13 = SpeechEnvelope(num); num14 = 16f; break; case 7: num4 = -0.28f; num5 = 24f; num6 = -20f; num7 = 25f; num10 = 18f; num12 = 32f; num14 = 9f; break; } float num15 = Mathf.Sin(num2); float num16 = Mathf.Sin(num2 + MathF.PI); float num17 = Mathf.Sin(num2 * 1.9f); float num18 = 1f - Mathf.Exp((0f - num14) * Time.deltaTime); rig.localPosition = Vector3.Lerp(rig.localPosition, rigPosition + Vector3.up * (num4 + num3), num18); torso.localPosition = Vector3.Lerp(torso.localPosition, torsoPosition + Vector3.up * (num3 * 0.25f), num18); head.localPosition = Vector3.Lerp(head.localPosition, headPosition + new Vector3(num17 * 0.012f, num3 * 0.4f, 0f), num18); Rotate(torso, torsoRotation, new Vector3(num5, 0f, num17 * 2.5f), num18); Rotate(head, headRotation, new Vector3(num6, num17 * 4f, (0f - num17) * 2f), num18); Rotate(leftShoulder, leftShoulderRotation, new Vector3(num7 + num15 * num8, 0f, num9), num18); Rotate(rightShoulder, rightShoulderRotation, new Vector3(num7 + num16 * num8, 0f, 0f - num9), num18); Rotate(leftElbow, leftElbowRotation, new Vector3(num10 - num16 * 12f, 0f, 0f), num18); Rotate(rightElbow, rightElbowRotation, new Vector3(num10 - num15 * 12f, 0f, 0f), num18); Rotate(leftWrist, leftWristRotation, new Vector3(num17 * num11, (0f - num15) * num11 * 0.5f, num15 * num11), num18); Rotate(rightWrist, rightWristRotation, new Vector3((0f - num17) * num11, (0f - num16) * num11 * 0.5f, num16 * num11), num18); Rotate(leftHip, leftHipRotation, new Vector3(num16 * num8 * 0.55f, 0f, 0f), num18); Rotate(rightHip, rightHipRotation, new Vector3(num15 * num8 * 0.55f, 0f, 0f), num18); for (int i = 0; i < fingers.Count; i++) { JointPose jointPose = fingers[i]; float num19 = Mathf.Sin(num2 * 1.35f + (float)i * 0.73f) * 8f; jointPose.Transform.localRotation = Quaternion.Slerp(jointPose.Transform.localRotation, jointPose.Rotation * Quaternion.Euler(num12 + num19, 0f, 0f), num18); } mouth.localScale = Vector3.Lerp(mouth.localScale, new Vector3(mouthScale.x, mouthScale.y * (1f + num13 * 2.2f), mouthScale.z), num18); UpdateFaceMouth(((int)currentState == 6) ? num13 : 0f, num18); } } private void OnDisable() { UpdateFaceMouth(0f, 1f); } private static float SpeechEnvelope(float phase) { float num = Mathf.Abs(Mathf.Sin(phase * 10.7f + Mathf.Sin(phase * 2.3f) * 1.4f)); float num2 = 0.38f + Mathf.Abs(Mathf.Sin(phase * 1.37f + 0.4f)) * 0.62f; return Mathf.Clamp01((num - 0.16f) * 1.3f * num2); } private void UpdateFaceMouth(float target, float blend) { if (!((Object)(object)faceRenderer == (Object)null) && faceProperties != null) { renderedMouthOpen = Mathf.Lerp(renderedMouthOpen, target, blend); faceRenderer.GetPropertyBlock(faceProperties); faceProperties.SetFloat(MouthOpenProperty, renderedMouthOpen); faceRenderer.SetPropertyBlock(faceProperties); } } private static void Rotate(Transform? joint, Quaternion rest, Vector3 euler, float blend) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)joint == (Object)null)) { joint.localRotation = Quaternion.Slerp(joint.localRotation, rest * Quaternion.Euler(euler), blend); } } private Transform? FindDescendant(string targetName) { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == targetName) { return val; } } return null; } } }