using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Dawn; using GameNetcodeStuff; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Audio; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using Y4NGZCreepyDoll.NetcodePatcher; using Y4NGZMonsters.Shared; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Y4NGZCreepyDoll")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+25ca94fed298fe073d4c739917e3b7f046e875bf")] [assembly: AssemblyProduct("Y4NGZCreepyDoll")] [assembly: AssemblyTitle("Y4NGZCreepyDoll")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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 Y4NGZCreepyDoll { public sealed class CreepyDollAI : EnemyAI { private enum EncounterState { Dormant, Suspicious, Chase, Search, Hypnosis } private sealed class RaycastHitDistanceComparer : IComparer { internal static readonly RaycastHitDistanceComparer Instance = new RaycastHitDistanceComparer(); public int Compare(RaycastHit x, RaycastHit y) { return ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance); } } public const int StateIdle = 0; public const int StateLuring = 1; public const int StateNeckSlash = 2; private const float PossessionProbeInterval = 0.12f; private const float ConstantLoopVolume = 0.3f; private const float MindControlVolume = 0.95f; private const float MindControlDampenedDecibels = -18f; private const float PursuitSirenVolume = 0.55f; private const float IdleBeatVolume = 0.4f; private const int IdleBeatMinimumSteps = 5; private const int IdleBeatMaximumSteps = 9; private const float FootstepPhaseWindow = 0.09f; private const float MinimumMoveSpeed = 0.34f; private const float MinimumAcceleration = 22.5f; private const float MinimumAngularSpeed = 120f; private const float MinimumGazeRange = 80f; private const float NavigationRadius = 0.5f; private const float NavigationHeight = 2f; private const float NavigationStoppingDistance = 0.6f; private const float SlowWalkClipDurationSeconds = 4.85f; private const float SlowWalkCycleDistance = 4.56f; private const float SlowWalkControllerStateSpeed = 0.625f; private const float RunClipDurationSeconds = 1.9f; private const float RunCycleDistance = 4.54f; private const float RunGaitEnterSpeedMetersPerSecond = 1.3f; private const float RunGaitExitSpeedMetersPerSecond = 1.1f; private const float HeadFocusHeardSeconds = 4.5f; private const float HeadTrackingAimDeadZoneDegrees = 0.35f; private const float NoisePlayerMatchRadius = 4f; private const float VoiceHearingMinimumAmplitude = 0.02f; private const float OccludedHearingRangeFraction = 0.5f; private const float HeadFocusSyncInterval = 0.22f; private const float NeckYawShare = 0.42f; private const float NeckPitchShare = 0.38f; private const float LowerSpineDuckShare = 0.3f; private const float UpperSpineDuckShare = 0.32f; private const float NeckDuckShare = 0.22f; private const float IdleSoundMinDistance = 2f; private const float IdleSoundMaxDistance = 30f; private const float CreatureAudioSpread = 40f; private const float MinimumPossessionStopDistance = 4.35f; private const float ScheduledExecutionKillDelay = 2f; private const float ExecutionDollStopDistance = 2.05f; private const float ExecutionCloseMinimumSpeed = 2.35f; private const float ExecutionHeadFocusRefreshSeconds = 0.08f; private const float PursuitDropRangeMultiplier = 1.75f; private const float PursuitMinimumDropRange = 12f; private const float PursuitMaximumDropRange = 35f; private const float SuspiciousMinDwellSeconds = 3f; private const float SuspiciousTimeoutSeconds = 6f; private const float ChaseMinDwellSeconds = 5f; private const float ChaseLostSeconds = 12f; private const float ReacquireRefractorySeconds = 20f; private const float SearchVocalIntervalSeconds = 4f; private const float SearchScanSpeedMultiplier = 2f; private const float SearchScanHoldScale = 0.5f; private const float PossessionCommandAckSeconds = 1f; private const float InvestigateTravelTimeoutSeconds = 12f; private const float InvestigateArriveRadius = 1.6f; private const float InvestigateLookHoldSeconds = 5f; private const float SearchLingerSeconds = 30f; private const float SearchLingerWidthScale = 0.5f; private const int MinLingerSearchNodes = 4; private const float ChaseSpeedMetersPerSecond = 2f; private const float ChaseSprintSpeedMetersPerSecond = 3.6f; private const float SprintDurationSeconds = 3f; private const float SprintCooldownSeconds = 30f; private const float SprintChance = 0.35f; private const float SprintMinimumTriggerDistance = 6f; private const float SprintReleaseDistance = 2.5f; private const float SprintWindupDelaySeconds = 0.8f; private const float SprintRerollIntervalSeconds = 20f; private const float SprintSpawnGraceSeconds = 30f; private const float SprintVocalVolume = 0.85f; private const float SprintVocalPitchMinimum = 1.12f; private const float SprintVocalPitchMaximum = 1.18f; private const float SprintLungeDuckDegrees = 22f; private const float NeckSlashImpactRangeGrace = 0.35f; private const float NeckSlashVerticalTolerance = 1.75f; private const float NeckSlashFacingHalfAngleDegrees = 75f; private const float SpotConfirmHysteresisDegrees = 8f; private const float SpotConfirmRangeHysteresis = 1.15f; private const float PitchReachSlackDegrees = 15f; private const float NoiseAcceptCooldownSeconds = 1.75f; private const float NoiseMinimumLoudness = 0.3f; private const float NoiseMinimumPerceivedLoudness = 0.04f; private const float HeadSnapWindowSeconds = 0.35f; private const float HeadSnapSettleDegrees = 3f; private const float HeadSnapRearmDegrees = 18f; private const float SightFocusOcclusionGraceSeconds = 0.4f; private const float ObservationHoldSeconds = 4.5f; private const float ObservationPlantMaximumSeconds = 4.5f; private const float ObservationReplantCooldownSeconds = 10f; private const float FootGroundedDistance = 0.14f; private const float FootstepContactCooldown = 0.24f; private const float MinimumTravelPerFootstep = 0.34f; private const float GroundRaycastVerticalPadding = 1.4f; private const float VisualGroundSmoothSpeed = 14f; private const float FootBoneGroundingFallbackSoleOffset = 0.18f; private const float DoorwayDuckCastRadius = 0.13f; private const float DoorwayDuckSmoothDegreesPerSecond = 190f; private const float DoorwayPeekSmoothDegreesPerSecond = 70f; private const float DoorwayDuckChestProbeHeight = 0.95f; private const float DoorwayDuckMinimumClearanceHeight = 1.25f; private const float DoorwayDuckMinimumLocomotionSpeed = 0.06f; private const float DoorwayLintelProbeInset = 0.21f; private const float HeadPostureMeasureInterval = 0.2f; private const float HeadPostureSyncStepDegrees = 1.5f; private const float PeekRollFocusRetention = 0.4f; private const float IdleScanDuckSuppressionDegrees = 8f; private const float GazeAuthorityBlendPerSecond = 8f; private const float HypnosisPitchBlendSeconds = 0.3f; private const float NeckCumulativeDuckShare = 0.84000003f; private const float NeckRollShare = 0.3f; private const double IdleScanEpochCellSeconds = 60.0; private const long IdleScanBeatsPerCell = 128L; private const float IdleScanGlanceHoldMinSeconds = 0.6f; private const float IdleScanGlanceHoldMaxSeconds = 1.2f; private const float IdleScanDownwardPitchDegrees = 4f; private const float FootClearanceProbeHeight = 1f; private const float FootClearanceProbeDepth = 2.5f; private const float FootSoleOffsetDecayPerSecond = 0.08f; private const float FootSoleOffsetMinimumSample = 0.02f; private const float FootSoleOffsetSeedCeiling = 0.35f; private const float StandingHeadHeightDecayPerSecond = 0.15f; private const float RoamSearchMinimumWidth = 12f; private const float RoamSearchMaximumWidth = 40f; private const float RoamSearchNodeBudgetSeconds = 16f; private const float RoamSearchRegionSpread = 2.5f; private const float RoamSearchPrecision = 1.5f; private const float BodyTurnStepThresholdDegreesPerSecond = 10f; private const float BodyTurnStepMetersPerDegree = 0.006f; private const float NeckSlashRecoverySeconds = 0.32f; private const int ClientConfirmLogReceived = 1; private const int FootstepSurfaceConcrete = 0; private const int FootstepSurfaceMetal = 1; private const int FootstepSurfaceWood = 2; private const float FootstepGainConcrete = 11.2f; private const float FootstepGainMetal = 15f; private const float FootstepGainWood = 5.3f; private const float FootstepGainCeiling = 64f; private const float StandardFootstepBroadcastVolume = 1f; private const float FolleyChance = 0.35f; private const float FolleyVolumeScale = 0.8f; private const float FolleyGainQuietClip = 5.6f; private const string FolleyQuietClipName = "folley02"; public Transform attackOrigin; public AudioSource stepAudioSource; public AudioSource idleAudioSource; public AudioSource constantAudioSource; public AudioSource mindControlAudioSource; public AudioClip[] stepClips = (AudioClip[])(object)new AudioClip[0]; public AudioClip[] stepClipsConcrete = (AudioClip[])(object)new AudioClip[0]; public AudioClip[] stepClipsMetal = (AudioClip[])(object)new AudioClip[0]; public AudioClip[] stepClipsWood = (AudioClip[])(object)new AudioClip[0]; public AudioClip[] idleClips = (AudioClip[])(object)new AudioClip[0]; public AudioClip idleBeatClip; public AudioClip[] folleyClips = (AudioClip[])(object)new AudioClip[0]; public AudioClip constantClip; public AudioClip mindControlClip; public AudioClip[] mindControlClips = (AudioClip[])(object)new AudioClip[0]; public AudioClip killClip; public AudioClip headSnapClip; public AISearchRoutine facilitySearch = new AISearchRoutine(); private static readonly int AnimIsMoving = Animator.StringToHash("IsMoving"); private static readonly int AnimIsRunning = Animator.StringToHash("IsRunning"); private static readonly int AnimWalkRate = Animator.StringToHash("WalkRate"); private static readonly int AnimRunRate = Animator.StringToHash("RunRate"); private static readonly int AnimNeckSlash = Animator.StringToHash("NeckSlash"); private static readonly float[] StandardWalkFootstepPhases = new float[2] { 0.08f, 0.56f }; private static readonly string[] VoiceSpeakingMemberNames = new string[4] { "IsSpeaking", "isSpeaking", "Speaking", "speaking" }; private static readonly string[] VoiceAmplitudeMemberNames = new string[2] { "Amplitude", "amplitude" }; private static readonly float[] VoiceOutputSamples = new float[64]; private static FieldInfo _voicePlayerStateField; private EncounterState _encounterState; private float _encounterStateEnteredTime; private ulong _encounterTargetClientId = ulong.MaxValue; private float _encounterLastStimulusTime; private ulong _chaseRefractoryClientId = ulong.MaxValue; private float _chaseRefractoryUntilTime; private float _nextSearchVocalTime; private int _lastEncounterNoticeCueFrame = -1; private PlayerControllerB _serverEntrancedPlayer; private ulong _serverEntrancedClientId = ulong.MaxValue; private float _serverPossessionCommandTime; private bool _serverPossessionAcknowledged; private PlayerControllerB _serverPursuitPlayer; private ulong _serverPursuitClientId = ulong.MaxValue; private float _serverPursuitLastVisibleTime; private string _serverPursuitSource = "none"; private bool _serverPursuitSirenActive; private Vector3 _serverPursuitLastSeenPosition; private bool _hasServerPursuitLastSeen; private bool _serverInvestigating; private bool _serverInvestigateLooking; private Vector3 _serverInvestigatePoint; private float _serverInvestigateStartedTime; private float _serverInvestigateLookUntilTime; private bool _serverInvestigateLingering; private float _serverInvestigateLingerUntilTime; private string _serverSearchExitReason = "search complete"; private float _serverSprintPendingStartTime = -1f; private float _serverSprintUntilTime; private float _nextSprintAllowedTime; private float _nextSprintRollTime; private bool _serverSprintGuaranteePending; private bool _serverSprintLungeActive; private bool _serverSprintWasActive; private ulong _serverSlashTargetClientId = ulong.MaxValue; private bool _isNeckSlashing; private float _serverSlashMomentumSpeed; private float _serverSlashMomentumUntil; private bool _audioParityApplied; private AudioSource _constantLoopConfiguredSource; private AudioSource _idleAudioConfiguredSource; private bool _serverExecutionShouldCloseDistance; private float _nextNeckSlashTime; private ulong _serverObservationClientId = ulong.MaxValue; private bool _serverObservationFromNoise; private float _serverObservationUntilTime; private float _serverGazeContactSeconds; private float _serverGazeLastContactTime; private bool _serverGazeGraceLogged; private bool _serverSpotConfirmed; private float _serverSpotConfirmedAtTime; private int _serverSpotConfirmEpoch; private int _possessionRangeRefusalEpoch = -1; private ulong _possessionRangeRefusalClientId = ulong.MaxValue; private Vector3 _serverNoiseStimulusPoint; private float _serverSightLastSeenTime; private float _nextNoiseAcceptTime; private float _nextVoiceAcceptTime; private ulong _syncedObservedClientId = ulong.MaxValue; private bool _syncedSpotConfirmed; private int _syncedSpotConfirmEpoch; private float _nextObservationSyncRefreshTime; private ulong _replicatedObservedClientId = ulong.MaxValue; private bool _replicatedSpotConfirmed; private float _replicatedSpotConfirmedTime; private int _replicatedSpotConfirmEpoch; private int _clientConfirmLogEpoch = -1; private int _clientConfirmLogFlags; private float _serverEntrancedStartTime; private float _serverBodyRotationUnlockTime; private bool _localPossessed; private bool _localControlsSaved; private bool _localSavedDisableLookInput; private bool _localSavedDisableMoveInput; private float _localPossessionStartTime; private float _localPossessionStopTime; private float _nextLocalSlashRequestTime; private bool _localExecutionRequested; private bool _localSlashPresentationActive; private bool _localSlashImpactReceived; private float _localSlashStartedTime; private float _localSlashImpactTime; private float _localSlashWindupSeconds; private bool _localSlashUsesClip; private bool _localSlashClipRecoveryStarted; private int _strikeClipPresence; private float _nextMovementDiagnosticTime; private ulong _reportedPossessionClientId = ulong.MaxValue; private readonly RaycastHit[] _lineOfSightHits = (RaycastHit[])(object)new RaycastHit[32]; private readonly Vector3[] _bodyProbePoints = (Vector3[])(object)new Vector3[3]; private float _nextPossessionLosProbeTime; private bool _cachedPossessionLos; private float _possessionLosLostSinceTime; private float _hypnosisPitchBlend; private int _lastFootstepClipIndex = -1; private int _lastFolleyClipIndex = -1; private int _lastStandardFootstepKey = -1; private int _stepsUntilIdleBeat = -1; private bool _mindControlAudioPlaying; private bool _mindControlAudioDampened; private float _nextMindControlSnapshotRefreshTime; private bool _localMindControlCameraSaved; private float _localMindControlBaseFov; private Transform _headBone; private Transform _neckBone; private Transform _lowerSpineBone; private Transform _upperSpineBone; private Transform _rightClavicleBone; private Transform _rightUpperArmBone; private Transform _rightForearmBone; private Vector3 _headFocusPoint; private float _headFocusUntilTime; private float _headBodyFollowAllowedTime; private float _headSnapUntilTime; private bool _headFocusFromNoise; private float _nextHeadFocusSyncTime; private float _headAimYawDegrees; private float _headAimPitchDegrees; private float _headAimRollDegrees; private Vector3 _headAimWorldDirection; private Quaternion _headRestToRoot = Quaternion.identity; private Quaternion _neckRestToRoot = Quaternion.identity; private bool _hasHeadChainRestPose; private string _headRestPoseSource = "none"; private float _gazeAuthorityWeight; private readonly NetworkVariable _networkDuckDegrees = new NetworkVariable(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private readonly NetworkVariable _networkPeekYawDegrees = new NetworkVariable(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private readonly NetworkVariable _networkPeekRollDegrees = new NetworkVariable(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private float _headPeekYawDegrees; private float _headPeekRollDegrees; private float _nextHeadPostureMeasureTime; private readonly Vector3[] _pathCornerBuffer = (Vector3[])(object)new Vector3[8]; private bool _serverDuckActive; private bool _serverPeekActive; private long _idleScanBeatIndex; private long _idleScanCell; private long _idleScanBeatStep; private double _idleScanBeatStartTime; private double _idleScanBeatEndTime; private bool _hasIdleScanCursor; private float _idleScanHoldScale = 1f; private bool _idleScanActive; private Transform _leftFootBone; private Transform _rightFootBone; private Vector3 _leftFootPreviousPosition; private Vector3 _rightFootPreviousPosition; private bool _leftFootWasGrounded; private bool _rightFootWasGrounded; private float _leftFootSoleOffset = -1f; private float _rightFootSoleOffset = -1f; private bool _contactFootstepClockActive; private float _nextContactFootstepTime; private Vector3 _lastFootstepTravelPosition; private bool _hasFootstepTravelPosition; private float _footstepTravelAccumulator; private Transform _visualRoot; private Vector3 _lastLocomotionSamplePosition; private float _lastLocomotionSampleYawDegrees; private bool _hasLocomotionSample; private float _smoothedLocomotionSpeed; private float _smoothedBodyTurnSpeed; private float _lastSlowWalkPlaybackRate; private string _lastGaitName = "none"; private bool _runGaitEngaged; private int _runClipPresence; private int _gaitRateParameterPresence; private float _doorwayDuckPitchDegrees; private float _standingHeadHeight; private bool _hasStandingHeadHeight; private bool _standingHeadHeightIsBoundsSeed; private bool _serverObservationPlanted; private float _serverObservationPlantStartTime; private float _serverObservationPlantAlignedTime; private bool _serverObservationPlantSpent; private ulong _serverLastPlantedClientId = ulong.MaxValue; private float _serverLastPlantCompletedTime = float.NegativeInfinity; private bool _loggedRuntimeDiagnostics; private float _nextHeadDiagnosticTime; private float _nextRoamDiagnosticTime; private string _lastHeadStateLogLine; private float _nextHeadStateLogTime; private bool _loggedEyeOrigin; private bool _serverBodyTurnInProgress; private int _contactFootstepCount; private int _phasedFootstepCount; private float _nextFootstepDiagnosticTime; private const float BodyProbeChestHeight = 2f; private const float BodyProbeLowHeight = 0.5f; private const int GazeAngleProbePointCount = 2; private float MoveSpeed => Mathf.Clamp(Plugin.ModConfig?.MoveSpeed?.Value ?? 0.6f, 0.34f, 5f); private float Acceleration => Mathf.Max(22.5f, 22.5f); private float AngularSpeed => Mathf.Max(120f, 150f); private float GazeRange => Mathf.Clamp(Plugin.ModConfig?.GazeRange?.Value ?? 80f, 5f, 100f); private float HypnosisOnsetDelaySeconds => Mathf.Clamp(Plugin.ModConfig?.HypnosisOnsetDelay?.Value ?? 0.5f, 0f, 5f); private float GazeHalfAngleDegrees => 18f; private float CloseRangeGazeHalfAngleDegrees => 40f; private float MovementLockDelay => Mathf.Clamp(Plugin.ModConfig?.MovementLockDelay?.Value ?? 3f, 0f, 10f); private float PossessionStrafeSeconds => 2f; private float PossessedWalkSpeed => Mathf.Clamp(Plugin.ModConfig?.PullSpeed?.Value ?? 0.85f, 0.1f, 5f); private float PossessedStrafeSpeed => 0.75f; private float PossessedLookTurnSpeed => 280f; private float RoamRadius => 18f; private float RoamRepathSeconds => 5f; private float RoamSearchWidth { get { float num = Mathf.Clamp(MoveSpeed * 16f * 2.5f, 12f, 40f); return Mathf.Clamp(RoamRadius * 2.5f, 12f, num); } } private bool HeadTrackingEnabled => true; private float HeadTrackingRange => Mathf.Max(80f, 80f); private float HeadSightRange => Mathf.Clamp(Plugin.ModConfig?.SightRange?.Value ?? 18f, 2f, HeadTrackingRange); private float HeadHearingRange => Mathf.Clamp(Plugin.ModConfig?.HearingRange?.Value ?? 20f, 4f, 80f); private float HeadVisionConeDegrees => 30f; private float HeadProximityAwareness => 3f; private float HeadRearAwarenessRange => 4.5f; private float HeadSightHoldSeconds => 3.5f; private float HeadRearTurnDelaySeconds => 1.2f; private float SpotConfirmSeconds => 0.8f; private float SpotConfirmGraceSeconds => 0.6f; private float PossessionBeginMaxDistance => 12f; private float PossessionLosGraceSeconds => 0.6f; private float HeadYawLimitDegrees => 78f; private float HeadPitchLimitDegrees => 32f; private float HypnosisHeadPitchLimitDegrees => 55f; private float EffectiveHeadPitchLimitDegrees => Mathf.Lerp(HeadPitchLimitDegrees, HypnosisHeadPitchLimitDegrees, _hypnosisPitchBlend); private float HeadSnapSpeed => 520f; private float HeadTrackSpeed => 120f; private float HeadBodyFollowDelay => 3f; private float HeadBodyFollowSpeed => 60f; private float PursuitDropRange => Mathf.Clamp(HeadSightRange * 1.75f, 12f, 35f); private float NeckSlashRange => Mathf.Clamp(Plugin.ModConfig?.NeckSlashRange?.Value ?? 2.15f, 0.5f, 5f); private float NeckSlashCooldown => Mathf.Clamp(Plugin.ModConfig?.AttackCooldown?.Value ?? 2.4f, 0.1f, 30f); private float NeckSlashKillDelay => Mathf.Max(2f, 2f); private float PossessionStopDistance => Mathf.Max(4.35f, NeckSlashRange + 2f); private bool PlayNeckSlashAnimation => Plugin.PlayAttackAnimation; private bool StaticVisualTestMode => Plugin.StaticVisualTestMode; private bool DoorwayDuckEnabled => true; private float DoorwayDuckProbeDistance => 1.15f; private float DoorwayDuckAngleDegrees => 32f; private float DoorwayDuckClearanceMargin => 0.08f; private float DoorwayDuckDegreesPerMeter => 55f; private bool DoorwayPeekEnabled => true; private float DoorwayPeekYawDegrees => 40f; private float DoorwayPeekRollDegrees => 14f; private float DoorwayPeekLookaheadDistance => 3f; private float DoorwayPeekMinimumTurnDegrees => 45f; private float HeadPoseAuthority => 1f; private float HeadRestPitchTrimDegrees => 0f; private float HeadRollLimitDegrees => 18f; private bool IdleExamineEnabled => true; private float IdleScanYawRangeDegrees => 55f; private float IdleScanPitchRangeDegrees => 12f; private float IdleScanRollDegrees => 6f; private float IdleScanSpeedDegreesPerSecond => 26f; private float IdleScanHoldMinSeconds => 2.5f; private float IdleScanHoldMaxSeconds => 6f; private float IdleScanGlanceChance => 0.2f; private float FootstepVolume => Mathf.Clamp(Plugin.ModConfig?.FootstepVolume?.Value ?? 1f, 0f, 4f); private float MindControlVisualIntensity => Mathf.Clamp01(Plugin.ModConfig?.MindControlVisualIntensity?.Value ?? 0.65f); private bool DevSnapSpawnNearPlayer => false; private float DevSpawnDistance => 6f; private bool DebugLogs => Plugin.ModConfig?.DebugLogs?.Value == true; private bool ServerMindControlMovementUnlocked { get { if (_serverEntrancedClientId != ulong.MaxValue) { return Time.time - _serverEntrancedStartTime >= MovementLockDelay; } return false; } } private bool ServerSprintActive => Time.time < _serverSprintUntilTime; public override void Awake() { try { EnsureBehaviourStates(); ((EnemyAI)this).Awake(); ResolveRuntimeReferences(); ConfigureSearchDefaults(); } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[CreepyDollAI] Awake failed: {arg}"); } } } public override void Start() { //IL_0111: Unknown result type (might be due to invalid IL or missing references) try { EnsureBehaviourStates(); ((EnemyAI)this).Start(); ResolveRuntimeReferences(); CorrectPrototypeSpawnPlacement(); ConfigureAgent(); ConfigureSearchDefaults(); Plugin.EnsureCollision(((Component)this).gameObject, this); Plugin.EnsureScanNode(((Component)this).gameObject); Plugin.DisablePhysicalVisualColliders(((Component)this).gameObject); RepairFacilityAINodes(); Plugin.RepairVisuals(((Component)this).gameObject, "spawned instance"); Plugin.ApplyVisualYawOffset(((Component)this).gameObject, "spawned instance"); SeedStandingHeadHeightFromBounds(); base.enemyHP = 999; base.isOutside = false; if ((Object)(object)base.creatureAnimator != (Object)null) { Plugin.ConfigureAnimatorForCurrentMode(base.creatureAnimator, "spawned instance"); if (!StaticVisualTestMode) { base.creatureAnimator.SetBool(AnimIsMoving, false); base.creatureAnimator.SetBool(AnimIsRunning, false); _runGaitEngaged = false; base.creatureAnimator.ResetTrigger(AnimNeckSlash); base.creatureAnimator.Play("Idle", 0, 0f); } } EnsureConstantLoop(); if (((NetworkBehaviour)this).IsServer) { StartRoamingSearch(((Component)this).transform.position); _nextSprintAllowedTime = Time.time + 30f; } if (DebugLogs) { LogSpawnDiagnostic("Started"); } LogHushdollRuntimeDiagnostics("start"); } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[CreepyDollAI] Start failed: {arg}"); } } } public override void Update() { try { ((EnemyAI)this).Update(); if (base.isEnemyDead) { EndLocalPossession(); StopConstantLoop(); StopPursuitSirenLocal(); return; } if ((Object)(object)base.creatureAnimator == (Object)null || (Object)(object)base.agent == (Object)null) { ResolveRuntimeReferences(); } Plugin.ApplyVisualYawOffset(((Component)this).gameObject, "static visual tick", log: false); TickLocalGaze(); UpdateAnimatorMovementFlag(); TickCreatureAudio(); UpdateEyeTransform(); TickServerHeadDetectionState(); TickServerEncounterState(); SyncServerObservationState(); RefreshAgentRotationOwnership(); TickServerBodyFollowHeadFocus(); TickServerHeadPosture(); LogRoamDiagnostic(); } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[CreepyDollAI] Update failed: {arg}"); } } } private void LateUpdate() { try { TickLocalPossessionControl(); StabilizeVisualRootOnGround(); ResolveHeadTrackingReferences(); TrackStandingHeadHeight(); TickHeadPostureSmoothing(); ApplyProceduralPose(); ApplyProceduralNeckSlash(); } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[CreepyDollAI] LateUpdate failed: {arg}"); } } } private void OnDisable() { try { if (_localPossessed || _reportedPossessionClientId != ulong.MaxValue) { EndLocalPossession(); } else { StopLocalMindControlAudioAndEffects(); } StopConstantLoop(); StopPursuitSirenLocal(); _localSlashPresentationActive = false; _localSlashImpactReceived = false; _localSlashUsesClip = false; _localSlashClipRecoveryStarted = false; } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[CreepyDollAI] OnDisable failed: {arg}"); } } } public override void DoAIInterval() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) try { ((EnemyAI)this).DoAIInterval(); if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayersDead) { return; } ConfigureAgent(); ConfigureSearchDefaults(); RepairFacilityAINodes(); if (_isNeckSlashing) { StopAgentPath(); PlayerControllerB val = FindPlayerByClientId(_serverSlashTargetClientId); if ((Object)(object)val != (Object)null && !val.isPlayerDead) { FacePosition(((Component)val).transform.position); FocusHeadOnPlayerServer(val, 0.45f, fromNoise: false); } return; } if ((_encounterState == EncounterState.Chase || _encounterState == EncounterState.Hypnosis) && Time.time >= _nextNeckSlashTime) { PlayerControllerB val2 = FindBasicAttackTarget(); if ((Object)(object)val2 != (Object)null) { BeginNeckSlashServer(val2, fromPossessionStop: false); return; } } switch (_encounterState) { case EncounterState.Hypnosis: { PlayerControllerB val3 = ResolveServerEntrancedPlayer(); if ((Object)(object)val3 != (Object)null) { PursueServerTarget(val3, respectMindControlDelay: true); } else { StopMovingServer(); } break; } case EncounterState.Chase: { PlayerControllerB val4 = ResolveServerPursuitPlayer(); if ((Object)(object)val4 != (Object)null) { TickServerSprint(val4); PursueServerTarget(val4, respectMindControlDelay: false); } else { StopMovingServer(); } break; } case EncounterState.Search: if (!TickServerInvestigation()) { StopMovingServer(); } break; case EncounterState.Suspicious: if (ServerHoldsStillForObservation()) { StopMovingServer(); } else { RoamServer(); } break; default: RoamServer(); break; } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[CreepyDollAI] DoAIInterval failed: {arg}"); } } } private void TickServerEncounterState() { if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead) { return; } PlayerControllerB val = ResolveEncounterTargetPlayer(); if (_isNeckSlashing) { if ((Object)(object)val == (Object)null && (_encounterState == EncounterState.Suspicious || _encounterState == EncounterState.Chase)) { LeaveChaseBookkeeping(); TransitionEncounterState(EncounterState.Dormant, "target invalid during slash"); } if (_encounterState == EncounterState.Hypnosis && (Object)(object)ResolveServerEntrancedPlayer() == (Object)null) { LeaveHypnosisAfterRelease(); } return; } switch (_encounterState) { case EncounterState.Suspicious: TickSuspiciousEncounterState(val); break; case EncounterState.Chase: TickChaseEncounterState(val); break; case EncounterState.Search: TickSearchEncounterState(); break; case EncounterState.Hypnosis: TickHypnosisEncounterState(); break; } } private void TickSuspiciousEncounterState(PlayerControllerB target) { if ((Object)(object)target == (Object)null) { TransitionEncounterState(EncounterState.Dormant, "target invalid"); } else if (!TryEnterHypnosisFromGaze(target)) { float num = Time.time - _encounterStateEnteredTime; if (Time.time - _encounterLastStimulusTime > 6f && num >= 3f) { TransitionEncounterState(EncounterState.Dormant, "no stimulus refresh"); } } } private void TickChaseEncounterState(PlayerControllerB target) { //IL_002c: 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_0041: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { LeaveChaseBookkeeping(); TransitionEncounterState(EncounterState.Dormant, "chase target invalid"); } else { if (TryEnterHypnosisFromGaze(target)) { return; } Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position; float magnitude = ((Vector3)(ref val)).magnitude; bool flag = magnitude <= PursuitDropRange; if (flag && HasClearLineOfSightToPlayerFace(target)) { _serverPursuitPlayer = target; _serverPursuitLastVisibleTime = Time.time; _serverPursuitLastSeenPosition = ((Component)target).transform.position; _hasServerPursuitLastSeen = true; return; } float num = Time.time - _serverPursuitLastVisibleTime; if ((!flag || !(num <= 12f)) && !(Time.time - _encounterStateEnteredTime < 5f)) { LogHeadStateEvent($"chase lost: player={_encounterTargetClientId}, source={_serverPursuitSource}, " + $"distance={magnitude:0.0}/{PursuitDropRange:0.0} m, unseen={num:0.00} s."); bool hasServerPursuitLastSeen = _hasServerPursuitLastSeen; Vector3 serverPursuitLastSeenPosition = _serverPursuitLastSeenPosition; ulong encounterTargetClientId = _encounterTargetClientId; LeaveChaseBookkeeping(); ArmChaseRefractory(encounterTargetClientId); if (hasServerPursuitLastSeen) { BeginServerInvestigation(serverPursuitLastSeenPosition); _encounterTargetClientId = encounterTargetClientId; TransitionEncounterState(EncounterState.Search, "lost sight"); } else { TransitionEncounterState(EncounterState.Dormant, "lost sight, nowhere to search"); } } } } private void TickSearchEncounterState() { if (!_serverInvestigating) { TransitionEncounterState(EncounterState.Dormant, _serverSearchExitReason); } else if (Time.time >= _nextSearchVocalTime) { _nextSearchVocalTime = Time.time + 4f; PlayIdleBeatClientRpc(0.5f, 1f); } } private void TickHypnosisEncounterState() { if ((Object)(object)ResolveServerEntrancedPlayer() != (Object)null) { if (!_serverPossessionAcknowledged && Time.time - _serverPossessionCommandTime > 1f) { LogHeadStateEvent("possession command unacknowledged after " + $"{Time.time - _serverPossessionCommandTime:0.00} s: player={_serverEntrancedClientId}. " + "Releasing the trance."); ClearServerEntrancedPlayer(_serverEntrancedClientId); LeaveHypnosisAfterRelease(); } else { _encounterTargetClientId = _serverEntrancedClientId; } } else { LeaveHypnosisAfterRelease(); } } private void LeaveHypnosisAfterRelease() { //IL_0022: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = ResolveEncounterTargetPlayer(); if ((Object)(object)val != (Object)null) { ArmChaseRefractory(val.actualClientId); Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position; if (!(((Vector3)(ref val2)).magnitude <= PursuitDropRange) || !HasClearLineOfSightToPlayerFace(val, allowBodyPoints: true) || !TryBeginChase(val, "trance released, still visible")) { BeginServerInvestigation(((Component)val).transform.position); TransitionEncounterState(EncounterState.Search, "trance released, victim gone"); } } else { ArmChaseRefractory(_encounterTargetClientId); TransitionEncounterState(EncounterState.Dormant, "trance released, no victim"); } } private bool TryEnterHypnosisFromGaze(PlayerControllerB target) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || (Object)(object)target == (Object)null || _serverEntrancedClientId != ulong.MaxValue || !_serverSpotConfirmed || _serverObservationClientId != target.actualClientId || Time.time - _serverSpotConfirmedAtTime < HypnosisOnsetDelaySeconds || !((EnemyAI)this).PlayerIsTargetable(target, true, false, true) || !HasClearLineOfSightToPlayerFace(target, allowBodyPoints: true)) { return false; } float num = Vector3.Distance(((Component)this).transform.position, ((Component)target).transform.position); if (num > PossessionBeginMaxDistance) { LogPossessionRangeRefusal(target.actualClientId, num); return false; } BeginServerPossession(target); _encounterTargetClientId = target.actualClientId; ArmChaseRefractory(target.actualClientId); TransitionEncounterState(EncounterState.Hypnosis, "mutual gaze held"); return true; } private void LogPossessionRangeRefusal(ulong clientId, float distance) { if (_possessionRangeRefusalEpoch != _serverSpotConfirmEpoch || _possessionRangeRefusalClientId != clientId) { _possessionRangeRefusalEpoch = _serverSpotConfirmEpoch; _possessionRangeRefusalClientId = clientId; LogHeadStateEvent($"possession refused (out of reach): player={clientId}, " + $"epoch={_serverSpotConfirmEpoch}, distance={distance:0.0} m, " + $"max={PossessionBeginMaxDistance:0.0} m."); } } private void BeginServerPossession(PlayerControllerB player) { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsServer && !((Object)(object)player == (Object)null)) { ulong actualClientId = player.actualClientId; ClearServerPursuitTarget(clearObservationForSameTarget: false); _serverEntrancedPlayer = player; _serverEntrancedClientId = actualClientId; _serverEntrancedStartTime = Time.time; _serverPossessionCommandTime = Time.time; _serverPossessionAcknowledged = false; _serverBodyRotationUnlockTime = Time.time; ClearServerObservationTarget(); ResetServerObservationPlantHistory(); base.targetPlayer = player; base.movingTowardsTargetPlayer = false; _headBodyFollowAllowedTime = Time.time; ForceHeadSnapToPlayerServer(player, 0.65f); StopSearchIfNeeded(clear: false); StopAgentPath(); if (!StaticVisualTestMode && base.currentBehaviourStateIndex != 0) { ((EnemyAI)this).SwitchToBehaviourState(0); } LogHeadStateEvent($"possession commanded: player={actualClientId}, epoch={_serverSpotConfirmEpoch}, " + $"confirmAge={Time.time - _serverSpotConfirmedAtTime:0.00}/{HypnosisOnsetDelaySeconds:0.00} s, " + $"distance={Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position):0.0} m."); BeginPossessionClientRpc(actualClientId); } } [ClientRpc] private void BeginPossessionClientRpc(ulong playerClientId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(301402725u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, playerClientId); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 301402725u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; PlayerControllerB val3 = ResolveLocalPlayer(); if (!((Object)(object)val3 == (Object)null) && !val3.isPlayerDead && PlayerMatchesClientId(val3, playerClientId) && ((EnemyAI)this).PlayerIsTargetable(val3, false, false, true) && !_localPossessed) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[CreepyDollAI][head][client] possession commanded by the server: " + $"clientId={playerClientId}.")); } BeginLocalPossession(val3); } } [ClientRpc] private void EndPossessionClientRpc(ulong playerClientId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2754516961u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, playerClientId); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2754516961u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (!_localPossessed) { return; } PlayerControllerB val3 = ResolveLocalPlayer(); if (!((Object)(object)val3 == (Object)null) && PlayerMatchesClientId(val3, playerClientId)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[CreepyDollAI][head][client] possession released by the server: " + $"clientId={playerClientId}.")); } EndLocalPossession(); } } private void TransitionEncounterState(EncounterState next, string reason) { if (!((NetworkBehaviour)this).IsServer || next == _encounterState) { return; } EncounterState encounterState = _encounterState; float num = Time.time - _encounterStateEnteredTime; _encounterState = next; _encounterStateEnteredTime = Time.time; bool num2 = encounterState == EncounterState.Chase || encounterState == EncounterState.Hypnosis; bool flag = next == EncounterState.Chase || next == EncounterState.Hypnosis; if (num2 && !flag) { StopPursuitSirenServer(); } switch (next) { case EncounterState.Suspicious: if (encounterState == EncounterState.Dormant) { if (TargetIsInChaseRefractory(_encounterTargetClientId)) { reason += ", re-entered (remembered)"; } else { PlayEncounterNoticeCue(); } } break; case EncounterState.Chase: if (TargetIsInChaseRefractory(_encounterTargetClientId)) { reason += ", re-entered (remembered)"; } else { PlayEncounterNoticeCue(); } StartPursuitSirenServer(); _serverSprintGuaranteePending = true; break; case EncounterState.Search: _nextSearchVocalTime = Time.time + 4f; PlayIdleBeatClientRpc(0.55f, 1f); break; case EncounterState.Dormant: if (encounterState == EncounterState.Search) { PlayIdleBeatClientRpc(0.3f, 0.94f); } _encounterTargetClientId = ulong.MaxValue; break; } if (encounterState == EncounterState.Chase) { _serverSprintUntilTime = 0f; _serverSprintPendingStartTime = -1f; _serverSprintWasActive = false; } ApplyAgentSpeed(); LogHeadStateEvent($"[encounter] {encounterState} -> {next}: reason={reason}, " + "target=" + ((_encounterTargetClientId == ulong.MaxValue) ? "none" : _encounterTargetClientId.ToString()) + ", " + $"dwell={num:0.0}s"); } private void PlayEncounterNoticeCue() { if (_lastEncounterNoticeCueFrame != Time.frameCount) { _lastEncounterNoticeCueFrame = Time.frameCount; PlayHeadSnapClientRpc(); } } private void ArmChaseRefractory(ulong clientId) { if (clientId != ulong.MaxValue) { _chaseRefractoryClientId = clientId; _chaseRefractoryUntilTime = Time.time + 20f; } } private bool TargetIsInChaseRefractory(ulong clientId) { if (clientId != ulong.MaxValue && _chaseRefractoryClientId == clientId) { return Time.time <= _chaseRefractoryUntilTime; } return false; } private void NoteEncounterStimulus(PlayerControllerB player, bool seen, Vector3? point = null) { //IL_00cf: 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) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead || (Object)(object)player == (Object)null || player.isPlayerDead || !((EnemyAI)this).PlayerIsTargetable(player, true, false, true)) { return; } ulong actualClientId = player.actualClientId; switch (_encounterState) { case EncounterState.Dormant: _encounterTargetClientId = actualClientId; _encounterLastStimulusTime = Time.time; TransitionEncounterState(EncounterState.Suspicious, seen ? "sighted" : "heard"); if (!seen) { break; } goto case EncounterState.Suspicious; case EncounterState.Suspicious: _encounterLastStimulusTime = Time.time; if (_serverObservationClientId == actualClientId) { _encounterTargetClientId = actualClientId; } if (seen) { TryBeginChase(player, "clear sight of a player"); } break; case EncounterState.Chase: { if (!seen || actualClientId == _encounterTargetClientId) { break; } PlayerControllerB val = ResolveEncounterTargetPlayer(); if ((Object)(object)val != (Object)null) { Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; val2 = ((Component)player).transform.position - ((Component)this).transform.position; if (sqrMagnitude <= ((Vector3)(ref val2)).sqrMagnitude) { break; } } SetServerPursuitTarget(player, "sight"); if (_serverPursuitClientId == actualClientId) { _encounterTargetClientId = actualClientId; LogHeadStateEvent($"[encounter] chase retargeted to player={actualClientId} (no announcement)."); } break; } case EncounterState.Search: if (seen && TryBeginChase(player, "sighted during search")) { EndServerInvestigation("target sighted again"); } break; } } private bool TryBeginChase(PlayerControllerB player, string reason) { if ((Object)(object)player == (Object)null) { return false; } SetServerPursuitTarget(player, "sight"); if (_serverPursuitClientId != player.actualClientId) { return false; } _encounterTargetClientId = player.actualClientId; TransitionEncounterState(EncounterState.Chase, reason); return true; } private void LeaveChaseBookkeeping() { ClearServerPursuitTarget(clearObservationForSameTarget: true); } private PlayerControllerB ResolveEncounterTargetPlayer() { if (_encounterTargetClientId == ulong.MaxValue) { return null; } PlayerControllerB val = FindPlayerByClientId(_encounterTargetClientId); if ((Object)(object)val == (Object)null || val.isPlayerDead || !((EnemyAI)this).PlayerIsTargetable(val, true, false, true)) { return null; } return val; } private bool EncounterStateAllowsRoaming() { if (_encounterState == EncounterState.Dormant) { return true; } if (_encounterState == EncounterState.Suspicious) { return !ServerHoldsStillForObservation(); } return false; } private void PursueServerTarget(PlayerControllerB target, bool respectMindControlDelay) { //IL_0064: 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) if (!((NetworkBehaviour)this).IsServer || (Object)(object)target == (Object)null || target.isPlayerDead) { return; } base.targetPlayer = target; StopSearchIfNeeded(clear: false); int num; if (respectMindControlDelay) { num = (ServerMindControlMovementUnlocked ? 1 : 0); if (num == 0) { base.movingTowardsTargetPlayer = false; StopAgentPath(); goto IL_004d; } } else { num = 1; } ((EnemyAI)this).SetMovingTowardsTargetPlayer(target); goto IL_004d; IL_004d: FocusHeadOnPlayerServer(target, 0.65f, fromNoise: false); if (num == 0) { FacePosition(((Component)target).transform.position); if (!StaticVisualTestMode && base.currentBehaviourStateIndex != 0) { ((EnemyAI)this).SwitchToBehaviourState(0); } return; } if (EnsureAgentOnNavMesh()) { base.agent.updateRotation = AgentDrivesBodyRotation(); base.agent.isStopped = false; } else { StopAgentPath(); LogMovementDiagnostic("target movement skipped: agent is not on NavMesh"); } if (!AgentDrivesBodyRotation()) { FacePosition(((Component)target).transform.position); } if (!StaticVisualTestMode && base.currentBehaviourStateIndex != 1) { ((EnemyAI)this).SwitchToBehaviourState(1); } } private PlayerControllerB FindBasicAttackTarget() { //IL_0058: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return null; } PlayerControllerB result = null; float num = float.PositiveInfinity; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (PlayerFitsNeckSlashGeometry(val, NeckSlashRange, requireFacing: false, requireLineOfSight: true)) { Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position; val2.y = 0f; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (!(sqrMagnitude >= num)) { num = sqrMagnitude; result = val; } } } return result; } private void RoamServer() { if (!((NetworkBehaviour)this).IsServer || _isNeckSlashing || !EncounterStateAllowsRoaming()) { return; } base.targetPlayer = null; base.movingTowardsTargetPlayer = false; if (!EnsureAgentOnNavMesh()) { LogMovementDiagnostic("roam skipped: agent is not on NavMesh"); return; } base.agent.updateRotation = AgentDrivesBodyRotation(); base.agent.isStopped = false; EnsureRoamingSearch(); if (!StaticVisualTestMode && base.currentBehaviourStateIndex != 1) { ((EnemyAI)this).SwitchToBehaviourState(1); } } private void ConfigureSearchDefaults() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown if (facilitySearch == null) { facilitySearch = new AISearchRoutine(); } facilitySearch.loopSearch = true; facilitySearch.randomized = false; facilitySearch.onlySearchNodesInLOS = false; bool flag = _serverInvestigating && _serverInvestigateLingering && _encounterState == EncounterState.Search; facilitySearch.searchWidth = (flag ? (RoamSearchWidth * 0.5f) : RoamSearchWidth); facilitySearch.searchPrecision = 1.5f; } private void EnsureRoamingSearch() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead && !_isNeckSlashing && EncounterStateAllowsRoaming() && !((Object)(object)base.agent == (Object)null) && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { ConfigureSearchDefaults(); if (facilitySearch == null || base.currentSearch != facilitySearch || !facilitySearch.inProgress) { StartRoamingSearch(((Component)this).transform.position); } } } private void StartRoamingSearch(Vector3 start) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead && !((Object)(object)base.agent == (Object)null) && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { ConfigureSearchDefaults(); StopSearchIfNeeded(clear: false); ((EnemyAI)this).StartSearch(start, facilitySearch); } } private void StartLingerSearch() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) StartRoamingSearch(_serverInvestigatePoint); NarrowSearchToLingerArea(); } private void NarrowSearchToLingerArea() { //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_0073: 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) //IL_0083: Unknown result type (might be due to invalid IL or missing references) List list = facilitySearch?.unsearchedNodes; if (list == null || list.Count <= 4) { return; } Vector3 anchor = _serverInvestigatePoint; list.Sort(delegate(GameObject a, GameObject b) { //IL_000f: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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) Vector3 val3; float num3; if (!((Object)(object)a == (Object)null)) { val3 = a.transform.position - anchor; num3 = ((Vector3)(ref val3)).sqrMagnitude; } else { num3 = float.MaxValue; } float num4 = num3; float num5; if (!((Object)(object)b == (Object)null)) { val3 = b.transform.position - anchor; num5 = ((Vector3)(ref val3)).sqrMagnitude; } else { num5 = float.MaxValue; } float value = num5; return num4.CompareTo(value); }); float num = RoamSearchWidth * 0.5f; num *= num; int num2; for (num2 = 4; num2 < list.Count; num2++) { GameObject val = list[num2]; if ((Object)(object)val == (Object)null) { break; } Vector3 val2 = val.transform.position - anchor; if (((Vector3)(ref val2)).sqrMagnitude > num) { break; } } if (num2 < list.Count) { list.RemoveRange(num2, list.Count - num2); } } private void StopSearchIfNeeded(bool clear) { if (base.currentSearch != null && base.currentSearch.inProgress) { ((EnemyAI)this).StopSearch(base.currentSearch, clear); } } private void RefreshAgentRotationOwnership() { if (!((Object)(object)base.agent == (Object)null) && ((Behaviour)base.agent).enabled) { bool flag = AgentDrivesBodyRotation(); if (base.agent.updateRotation != flag) { base.agent.updateRotation = flag; } } } [ServerRpc(RequireOwnership = false)] private void ReportPossessionServerRpc(ulong playerClientId, bool active) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val2 = default(ServerRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(1621209323u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, playerClientId); ((FastBufferWriter)(ref val)).WriteValueSafe(ref active, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 1621209323u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; try { if (active) { if (_serverEntrancedClientId != playerClientId) { LogHeadStateEvent($"possession report ignored: player={playerClientId} was never commanded " + "(entranced=" + ((_serverEntrancedClientId == ulong.MaxValue) ? "none" : _serverEntrancedClientId.ToString()) + ")."); } else { _serverPossessionAcknowledged = true; } } else if (_serverEntrancedClientId == playerClientId) { ClearServerEntrancedPlayer(ulong.MaxValue); } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[CreepyDollAI] ReportPossessionServerRpc failed: {arg}"); } } } [ServerRpc(RequireOwnership = false)] private void RequestNeckSlashKillServerRpc(ulong playerClientId, bool fromPossessionStop) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val2 = default(ServerRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2495072846u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, playerClientId); ((FastBufferWriter)(ref val)).WriteValueSafe(ref fromPossessionStop, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 2495072846u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; try { PlayerControllerB val3 = FindPlayerByClientId(playerClientId); if (!((Object)(object)val3 == (Object)null) && !val3.isPlayerDead && ((EnemyAI)this).PlayerIsTargetable(val3, false, false, true)) { float num = (fromPossessionStop ? (PossessionStopDistance + 1f) : (NeckSlashRange + 1.5f)); if (!(Vector3.Distance(((Component)this).transform.position, ((Component)val3).transform.position) > num)) { BeginNeckSlashServer(val3, fromPossessionStop); } } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[CreepyDollAI] RequestNeckSlashKillServerRpc failed: {arg}"); } } } [ClientRpc] private void PlayNeckSlashClientRpc(ulong playerClientId, float windupSeconds) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1190224957u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, playerClientId); ((FastBufferWriter)(ref val)).WriteValueSafe(ref windupSeconds, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 1190224957u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveRuntimeReferences(); _localSlashPresentationActive = true; _localSlashImpactReceived = false; _localSlashUsesClip = false; _localSlashClipRecoveryStarted = false; _localSlashStartedTime = Time.time; _localSlashImpactTime = 0f; _localSlashWindupSeconds = Mathf.Max(0.05f, windupSeconds); PlayClipOneShot(base.creatureSFX ?? stepAudioSource, headSnapClip, 0.7f, 0.9f); if (!((Object)(object)base.creatureAnimator == (Object)null) && !StaticVisualTestMode) { base.creatureAnimator.applyRootMotion = false; base.creatureAnimator.ResetTrigger(AnimNeckSlash); _localSlashUsesClip = PlayNeckSlashAnimation && AnimatorHasStrikeClip(); if (_localSlashUsesClip) { float num = (_runGaitEngaged ? 0.35f : 0.12f); base.creatureAnimator.SetBool(AnimIsMoving, false); base.creatureAnimator.SetBool(AnimIsRunning, false); _runGaitEngaged = false; base.creatureAnimator.CrossFadeInFixedTime("NeckSlash", num, 0, 0f); } else if (_smoothedLocomotionSpeed <= 0.05f) { base.creatureAnimator.SetBool(AnimIsMoving, false); base.creatureAnimator.SetBool(AnimIsRunning, false); _runGaitEngaged = false; base.creatureAnimator.CrossFadeInFixedTime("Idle", 0.08f, 0, 0f); } } } private bool AnimatorHasStrikeClip() { if (_strikeClipPresence == 0) { _strikeClipPresence = -1; RuntimeAnimatorController val = (((Object)(object)base.creatureAnimator != (Object)null) ? base.creatureAnimator.runtimeAnimatorController : null); if ((Object)(object)val != (Object)null) { AnimationClip[] animationClips = val.animationClips; foreach (AnimationClip val2 in animationClips) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name.IndexOf("NeckSlash_Strike", StringComparison.OrdinalIgnoreCase) >= 0) { _strikeClipPresence = 1; break; } } } } return _strikeClipPresence == 1; } [ClientRpc] private void ResolveNeckSlashClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1957274175u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 1957274175u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (_localSlashPresentationActive) { _localSlashImpactReceived = true; _localSlashImpactTime = Time.time; } } } [ClientRpc] private void PlayFootstepClientRpc(int surfaceIndex, int clipIndex, float volume, float pitch) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(799409866u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, surfaceIndex); BytePacker.WriteValueBitPacked(val, clipIndex); ((FastBufferWriter)(ref val)).WriteValueSafe(ref volume, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref pitch, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 799409866u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveRuntimeReferences(); AudioClip[] array = ResolveStepClipPool(surfaceIndex); float volume2 = volume * ResolveStepClipGain(array); AudioSource source = stepAudioSource ?? base.creatureSFX; PlayClipOneShot(source, array, clipIndex, volume2, pitch); MaybePlayFootstepFolley(source, volume * FootstepVolume); } } } private void MaybePlayFootstepFolley(AudioSource source, float stepBroadcastVolume) { if (folleyClips != null && folleyClips.Length != 0 && !(Random.value > 0.35f)) { int num = PickRandomClipIndex(folleyClips, ref _lastFolleyClipIndex); if (num >= 0) { AudioClip clip = folleyClips[num]; PlayClipOneShot(source ?? base.creatureSFX, clip, stepBroadcastVolume * 0.8f * ResolveFolleyClipGain(clip), Random.Range(0.95f, 1.05f)); } } } private static float ResolveFolleyClipGain(AudioClip clip) { if ((Object)(object)clip == (Object)null || ((Object)clip).name == null) { return 1f; } if (((Object)clip).name.IndexOf("folley02", StringComparison.OrdinalIgnoreCase) < 0) { return 1f; } return 5.6f; } private float ResolveStepClipGain(AudioClip[] pool) { if (pool == null || pool.Length == 0) { return 1f; } float num = ((pool == stepClipsMetal) ? 15f : ((pool == stepClipsWood) ? 5.3f : ((pool != stepClipsConcrete) ? 1f : 11.2f))); return num * FootstepVolume; } [ClientRpc] private void PlayIdleBeatClientRpc(float volume, float pitch) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2374545687u, val2, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe(ref volume, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref pitch, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2374545687u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveRuntimeReferences(); PlayClipOneShot(idleAudioSource ?? base.creatureSFX, idleBeatClip, volume, pitch); } } } [ClientRpc] private void PlaySprintVocalClientRpc(float volume, float pitch) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(726890257u, val2, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe(ref volume, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref pitch, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 726890257u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveRuntimeReferences(); AudioSource val3 = idleAudioSource ?? base.creatureSFX; if (!((Object)(object)val3 == (Object)null) && !((Object)(object)idleBeatClip == (Object)null)) { val3.pitch = Mathf.Clamp(pitch, 0.6f, 1.35f); val3.PlayOneShot(idleBeatClip, Mathf.Clamp(volume, 0f, 1f)); } } } [ClientRpc] private void StartPursuitSirenClientRpc(int clipIndex) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2920004268u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, clipIndex); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2920004268u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveRuntimeReferences(); AudioClip val3 = null; if (mindControlClips != null && clipIndex >= 0 && clipIndex < mindControlClips.Length) { val3 = mindControlClips[clipIndex]; } if ((Object)(object)val3 == (Object)null) { val3 = mindControlClip; } AudioSource val4 = (((Object)(object)base.creatureVoice != (Object)null) ? base.creatureVoice : base.creatureSFX); if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val3 == (Object)null)) { val4.clip = val3; val4.loop = true; val4.volume = 0.55f; val4.pitch = 1f; val4.Play(); } } } [ClientRpc] private void StopPursuitSirenClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2826517116u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2826517116u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; StopPursuitSirenLocal(); } } } private void StopPursuitSirenLocal() { if (!((Object)(object)base.creatureVoice == (Object)null) && base.creatureVoice.loop) { base.creatureVoice.Stop(); base.creatureVoice.loop = false; base.creatureVoice.clip = null; base.creatureVoice.volume = 1f; } } [ClientRpc] private void PlayHeadSnapClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2504793662u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2504793662u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveRuntimeReferences(); PlayClipOneShot(base.creatureSFX ?? stepAudioSource, headSnapClip, 0.55f, Random.Range(0.97f, 1.03f)); } } } [ClientRpc] private void PlayKillSoundClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(395634359u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 395634359u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveRuntimeReferences(); PlayClipOneShot(((Object)(object)base.creatureVoice != (Object)null && !base.creatureVoice.loop) ? base.creatureVoice : (((Object)(object)base.creatureSFX != (Object)null) ? base.creatureSFX : base.creatureVoice), killClip, 0.95f, Random.Range(0.96f, 1.03f)); } } } [ClientRpc] private void ExecuteNeckSlashKillClientRpc(ulong playerClientId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2272386025u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, playerClientId); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2272386025u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; PlayerControllerB val3 = ResolveLocalPlayer(); if (!((Object)(object)val3 == (Object)null) && (val3.actualClientId == playerClientId || val3.playerClientId == playerClientId)) { bool flag = !val3.isPlayerDead; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[CreepyDollAI][combat][victim] neck slash kill " + string.Format("{0}: clientId={1}, ", flag ? "executed" : "skipped", playerClientId) + $"isPlayerDead={val3.isPlayerDead}.")); } if (flag) { val3.KillPlayer(Vector3.up * 14f, true, (CauseOfDeath)17, 7, default(Vector3), false); } EndLocalPossession(); } } [ClientRpc] private void RearmPossessionExecutionClientRpc(ulong playerClientId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(4045993336u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, playerClientId); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 4045993336u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; PlayerControllerB val3 = ResolveLocalPlayer(); if (!((Object)(object)val3 == (Object)null) && !val3.isPlayerDead && PlayerMatchesClientId(val3, playerClientId) && _localPossessed) { _localExecutionRequested = false; _localPossessionStopTime = 0f; _nextLocalSlashRequestTime = Time.time + Mathf.Max(0.25f, NeckSlashCooldown); } } } public override void DetectNoise(Vector3 noisePosition, float noiseLoudness, int timesPlayedInOneSpot = 0, int noiseID = 0) { //IL_0001: 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_003d: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).DetectNoise(noisePosition, noiseLoudness, timesPlayedInOneSpot, noiseID); if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead || !HeadTrackingEnabled || Time.time < _nextNoiseAcceptTime) { return; } float num = Vector3.Distance(((Component)this).transform.position, noisePosition); if (!(num > HeadHearingRange) && !(num <= 0.05f) && !(noiseLoudness < 0.3f) && !(noiseLoudness / Mathf.Max(num, 1f) < 0.04f)) { PlayerControllerB val = FindPlayerNearPosition(noisePosition, 4f); if (PlayerCanBeHeadTracked(val) && ((EnemyAI)this).PlayerIsTargetable(val, true, false, true) && (!(num > HeadHearingRange * 0.5f) || HasClearLineOfSightToPlayerFace(val))) { _nextNoiseAcceptTime = Time.time + 1.75f; SetServerObservationTarget(val, fromNoise: true, noisePosition, "noise"); NoteEncounterStimulus(val, seen: false, noisePosition); } } } private void TickLocalGaze() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = ResolveLocalPlayer(); if ((Object)(object)val == (Object)null || val.isPlayerDead || !((EnemyAI)this).PlayerIsTargetable(val, false, false, true)) { _cachedPossessionLos = false; EndLocalPossession(); } else if (_localPossessed) { if (!PossessionLineOfSightHolds(val)) { EndLocalPossession(); return; } ReportLocalPossession(val, active: true); SetHeadFocus(GetPlayerFocusPoint(val), 0.35f, fromNoise: false); TryRequestExecutionFromLocalStop(val); } else if (_replicatedSpotConfirmed && _replicatedObservedClientId != ulong.MaxValue && PlayerMatchesClientId(val, _replicatedObservedClientId)) { LogClientConfirmEvent(1, $"confirm received (t-{Time.time - _replicatedSpotConfirmedTime:0.00} s), " + $"server onset delay {HypnosisOnsetDelaySeconds:0.00} s."); } } private void TickLocalPossessionControl() { if (!_localPossessed) { return; } PlayerControllerB val = ResolveLocalPlayer(); if ((Object)(object)val == (Object)null || val.isPlayerDead) { EndLocalPossession(); return; } if (!PossessionLineOfSightHolds(val)) { EndLocalPossession(); return; } val.disableLookInput = true; bool flag = Time.time - _localPossessionStartTime >= MovementLockDelay; val.disableMoveInput = flag || _localSavedDisableMoveInput; AimLocalPlayerAtDoll(val); if (flag) { MoveLocalPlayerTowardDoll(val, flag); } TryRequestExecutionFromLocalStop(val); UpdateLocalMindControlAudioAndEffects(val); } private bool PossessionLineOfSightHolds(PlayerControllerB player) { if (CachedPlayerHasLineOfSightToDoll(player, 0.12f, ref _nextPossessionLosProbeTime, ref _cachedPossessionLos)) { _possessionLosLostSinceTime = 0f; return true; } if (_possessionLosLostSinceTime <= 0f) { _possessionLosLostSinceTime = Time.time; } return Time.time - _possessionLosLostSinceTime < PossessionLosGraceSeconds; } private void BeginLocalPossession(PlayerControllerB player) { if ((Object)(object)player == (Object)null || _localPossessed) { return; } _localPossessed = true; _localPossessionStartTime = Time.time; _localPossessionStopTime = 0f; _nextLocalSlashRequestTime = Time.time + 0.25f; _localExecutionRequested = false; _nextPossessionLosProbeTime = Time.time + PossessionLosGraceSeconds; _cachedPossessionLos = true; _possessionLosLostSinceTime = 0f; SaveLocalControlState(player); player.disableLookInput = true; player.disableMoveInput = _localSavedDisableMoveInput; ReportLocalPossession(player, active: true); StartLocalMindControlAudioAndEffects(player); if (DebugLogs) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[CreepyDollAI] Local player possessed by gaze. clientId={player.actualClientId}"); } } } private void EndLocalPossession() { if (!_localPossessed && _reportedPossessionClientId == ulong.MaxValue && !_mindControlAudioPlaying && !_mindControlAudioDampened) { return; } bool localPossessed = _localPossessed; ulong reportedPossessionClientId = _reportedPossessionClientId; _localPossessed = false; _reportedPossessionClientId = ulong.MaxValue; PlayerControllerB val = ResolveLocalPlayer(); if ((Object)(object)val != (Object)null) { RestoreLocalControlState(val); } StopLocalMindControlAudioAndEffects(); if (reportedPossessionClientId != ulong.MaxValue) { if (((NetworkBehaviour)this).IsServer) { ClearServerEntrancedPlayer(reportedPossessionClientId); } else { ReportPossessionServerRpc(reportedPossessionClientId, active: false); } } _localControlsSaved = false; _localPossessionStopTime = 0f; _localExecutionRequested = false; _nextPossessionLosProbeTime = 0f; _cachedPossessionLos = false; _possessionLosLostSinceTime = 0f; if (localPossessed) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[CreepyDollAI][head][client] local possession ended after " + $"{Time.time - _localPossessionStartTime:0.00} s.")); } } } private void ReportLocalPossession(PlayerControllerB player, bool active) { if ((Object)(object)player == (Object)null) { return; } ulong actualClientId = player.actualClientId; if (active && _reportedPossessionClientId == actualClientId) { return; } _reportedPossessionClientId = (active ? actualClientId : ulong.MaxValue); if (((NetworkBehaviour)this).IsServer) { if (!active) { ClearServerEntrancedPlayer(actualClientId); } else if (_serverEntrancedClientId == actualClientId) { _serverPossessionAcknowledged = true; } } else { ReportPossessionServerRpc(actualClientId, active); } } private void SaveLocalControlState(PlayerControllerB player) { if (!((Object)(object)player == (Object)null) && !_localControlsSaved) { _localSavedDisableLookInput = player.disableLookInput; _localSavedDisableMoveInput = player.disableMoveInput; _localControlsSaved = true; } } private void RestoreLocalControlState(PlayerControllerB player) { if (!((Object)(object)player == (Object)null) && _localControlsSaved) { player.disableLookInput = _localSavedDisableLookInput; player.disableMoveInput = _localSavedDisableMoveInput; } } private void AimLocalPlayerAtDoll(PlayerControllerB player) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0073: 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_0095: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bb: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)player.thisPlayerBody != (Object)null) ? player.thisPlayerBody : ((Component)player).transform); Vector3 lookTargetPoint = GetLookTargetPoint(); Vector3 val2 = lookTargetPoint - val.position; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up); val.rotation = Quaternion.RotateTowards(val.rotation, val3, PossessedLookTurnSpeed * Time.deltaTime); } Camera gameplayCamera = player.gameplayCamera; if (!((Object)(object)gameplayCamera == (Object)null)) { Vector3 val4 = lookTargetPoint - ((Component)gameplayCamera).transform.position; if (((Vector3)(ref val4)).sqrMagnitude > 0.001f) { Quaternion val5 = Quaternion.LookRotation(((Vector3)(ref val4)).normalized, Vector3.up); ((Component)gameplayCamera).transform.rotation = Quaternion.RotateTowards(((Component)gameplayCamera).transform.rotation, val5, PossessedLookTurnSpeed * Time.deltaTime); } } } private void MoveLocalPlayerTowardDoll(PlayerControllerB player, bool movementLocked) { //IL_0006: 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_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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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) //IL_00dc: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_00fd: 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) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position - ((Component)player).transform.position; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; Vector3 val2 = Vector3.zero; float possessionStopDistance = PossessionStopDistance; bool flag = magnitude <= possessionStopDistance; if (!flag && ((Vector3)(ref val)).sqrMagnitude > 0.001f) { float num = Mathf.Min(PossessedWalkSpeed * Time.deltaTime, magnitude - possessionStopDistance); if (num > 0.001f) { val2 += ((Vector3)(ref val)).normalized * num; } } if (!movementLocked && !flag && Time.time - _localPossessionStartTime < PossessionStrafeSeconds && ((Vector3)(ref val)).sqrMagnitude > 0.001f) { float num2 = ReadLocalStrafeInput(player); if (Mathf.Abs(num2) > 0.01f) { Vector3 val3 = Vector3.Cross(Vector3.up, ((Vector3)(ref val)).normalized); val2 += val3 * num2 * PossessedStrafeSpeed * Time.deltaTime; } } if (((Vector3)(ref val2)).sqrMagnitude <= 1E-06f) { if (flag) { player.externalForceAutoFade = Vector3.zero; player.ResetFallGravity(); } return; } if ((Object)(object)player.thisController != (Object)null && ((Collider)player.thisController).enabled) { player.thisController.Move(val2); } else { Transform transform = ((Component)player).transform; transform.position += val2; } player.serverPlayerPosition = ((Component)player).transform.localPosition; player.externalForceAutoFade = Vector3.zero; player.ResetFallGravity(); } private void TryRequestExecutionFromLocalStop(PlayerControllerB player) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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) if (!_localPossessed || _localExecutionRequested || (Object)(object)player == (Object)null || player.isPlayerDead || !(Time.time - _localPossessionStartTime >= MovementLockDelay)) { return; } Vector3 val = ((Component)this).transform.position - ((Component)player).transform.position; val.y = 0f; if (((Vector3)(ref val)).magnitude > PossessionStopDistance) { return; } player.externalForceAutoFade = Vector3.zero; player.ResetFallGravity(); if (_localPossessionStopTime <= 0f) { _localPossessionStopTime = Time.time; } if (!(Time.time < _nextLocalSlashRequestTime)) { _localExecutionRequested = true; _nextLocalSlashRequestTime = Time.time + 999f; if (((NetworkBehaviour)this).IsServer) { BeginNeckSlashServer(player, fromPossessionStop: true); } else { RequestNeckSlashKillServerRpc(player.actualClientId, fromPossessionStop: true); } } } private void StartLocalMindControlAudioAndEffects(PlayerControllerB player) { ResolveRuntimeReferences(); AudioClip val = PickMindControlClip(); if ((Object)(object)mindControlAudioSource != (Object)null && (Object)(object)val != (Object)null) { mindControlAudioSource.clip = val; mindControlAudioSource.loop = true; mindControlAudioSource.volume = 0.95f; mindControlAudioSource.pitch = 1f; mindControlAudioSource.spatialBlend = 0f; mindControlAudioSource.minDistance = 500f; mindControlAudioSource.maxDistance = 500f; if (!mindControlAudioSource.isPlaying) { mindControlAudioSource.Play(); } _mindControlAudioPlaying = true; } ApplyLocalMindControlDampening(forceSnapshot: true); ApplyLocalMindControlFear(player, immediate: true); ApplyLocalMindControlVisualEffect(player, immediate: true); } private void UpdateLocalMindControlAudioAndEffects(PlayerControllerB player) { if (!_mindControlAudioPlaying && (Object)(object)mindControlAudioSource != (Object)null && HasAnyMindControlClip()) { StartLocalMindControlAudioAndEffects(player); } ApplyLocalMindControlDampening(forceSnapshot: false); ApplyLocalMindControlFear(player, immediate: false); ApplyLocalMindControlVisualEffect(player, immediate: false); } private void StopLocalMindControlAudioAndEffects() { RestoreLocalMindControlVisualEffect(ResolveLocalPlayer()); if ((Object)(object)mindControlAudioSource != (Object)null && mindControlAudioSource.isPlaying) { mindControlAudioSource.Stop(); } _mindControlAudioPlaying = false; if (!_mindControlAudioDampened) { return; } try { if ((Object)(object)SoundManager.Instance != (Object)null) { SoundManager.Instance.SetDiageticMasterVolume(0f); SoundManager.Instance.SetDiageticMixerSnapshot(0, 0.25f); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[CreepyDollAI] Failed to restore audio dampening: " + ex.Message)); } } _mindControlAudioDampened = false; _nextMindControlSnapshotRefreshTime = 0f; } private void ApplyLocalMindControlDampening(bool forceSnapshot) { try { if (!((Object)(object)SoundManager.Instance == (Object)null)) { SoundManager.Instance.SetDiageticMasterVolume(-18f); if (forceSnapshot || Time.time >= _nextMindControlSnapshotRefreshTime) { SoundManager.Instance.SetDiageticMixerSnapshot(2, forceSnapshot ? 0.05f : 0.2f); _nextMindControlSnapshotRefreshTime = Time.time + 0.75f; } _mindControlAudioDampened = true; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[CreepyDollAI] Failed to apply audio dampening: " + ex.Message)); } } } private static void ApplyLocalMindControlFear(PlayerControllerB player, bool immediate) { if ((Object)(object)player == (Object)null) { return; } try { if (immediate) { player.JumpToFearLevel(0.85f, true); } else { player.IncreaseFearLevelOverTime(1.35f, 0.95f); } } catch { } } private void ApplyLocalMindControlVisualEffect(PlayerControllerB player, bool immediate) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player.gameplayCamera == (Object)null)) { Camera gameplayCamera = player.gameplayCamera; if (!_localMindControlCameraSaved) { _localMindControlBaseFov = gameplayCamera.fieldOfView; _localMindControlCameraSaved = true; } float mindControlVisualIntensity = MindControlVisualIntensity; if (!(mindControlVisualIntensity <= 0.001f)) { float num = Mathf.Clamp01(Mathf.Max(0f, Time.time - _localPossessionStartTime) / Mathf.Max(0.2f, MovementLockDelay)); float num2 = 0.5f + Mathf.Sin(Time.time * 8.5f) * 0.5f; float num3 = (0.65f + num2 * 1.35f + num * 0.85f) * mindControlVisualIntensity; float num4 = Mathf.Clamp(_localMindControlBaseFov - num3, 45f, 90f); gameplayCamera.fieldOfView = (immediate ? num4 : Mathf.Lerp(gameplayCamera.fieldOfView, num4, 1f - Mathf.Exp(-9f * Time.deltaTime))); } } } private void RestoreLocalMindControlVisualEffect(PlayerControllerB player) { if (_localMindControlCameraSaved) { if ((Object)(object)player != (Object)null && (Object)(object)player.gameplayCamera != (Object)null) { player.gameplayCamera.fieldOfView = _localMindControlBaseFov; } _localMindControlCameraSaved = false; _localMindControlBaseFov = 0f; } } private static float ReadLocalStrafeInput(PlayerControllerB player) { //IL_0010: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) try { if (player != null) { PlayerActions playerActions = player.playerActions; if (playerActions != null) { _ = playerActions.Movement; if (true) { MovementActions movement = player.playerActions.Movement; return ((MovementActions)(ref movement)).Move.ReadValue().x; } } } } catch { } float num = 0f; Keyboard current = Keyboard.current; if (current != null) { if (((ButtonControl)current.aKey).isPressed) { num -= 1f; } if (((ButtonControl)current.dKey).isPressed) { num += 1f; } } return Mathf.Clamp(num, -1f, 1f); } private void BeginNeckSlashServer(PlayerControllerB player, bool fromPossessionStop) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || (Object)(object)player == (Object)null || player.isPlayerDead || !((EnemyAI)this).PlayerIsTargetable(player, true, false, true) || _isNeckSlashing || (!fromPossessionStop && Time.time < _nextNeckSlashTime)) { return; } if (fromPossessionStop) { if (_serverEntrancedClientId != player.actualClientId || !PlayerFitsNeckSlashGeometry(player, PossessionStopDistance + 1f, requireFacing: false, requireLineOfSight: true)) { return; } } else if (!PlayerFitsNeckSlashGeometry(player, NeckSlashRange, requireFacing: false, requireLineOfSight: true)) { return; } _isNeckSlashing = true; _serverSlashTargetClientId = player.actualClientId; _serverExecutionShouldCloseDistance = fromPossessionStop; _nextNeckSlashTime = Time.time + Mathf.Max(0.5f, NeckSlashCooldown); base.targetPlayer = player; float num; if (fromPossessionStop || !((Object)(object)base.agent != (Object)null) || !((Behaviour)base.agent).enabled) { num = 0f; } else { Vector3 velocity = base.agent.velocity; num = ((Vector3)(ref velocity)).magnitude; } float num2 = num; if (num2 >= 1.3f) { _serverSlashMomentumSpeed = num2; _serverSlashMomentumUntil = Time.time + 0.45f; } else { _serverSlashMomentumSpeed = 0f; _serverSlashMomentumUntil = 0f; } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[CreepyDollAI][combat] slash windup: mode=" + (fromPossessionStop ? "hypnosis" : "basic") + ", " + $"player={player.actualClientId}, distance={Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position):0.00} m, " + "momentum=" + ((_serverSlashMomentumSpeed > 0f) ? $"{_serverSlashMomentumSpeed:0.00} m/s carry" : "none") + ".")); } FocusHeadOnPlayerServer(player, NeckSlashKillDelay + 1.25f, fromNoise: false, forceSync: true); StopSearchIfNeeded(clear: false); StopAgentPath(); FacePosition(((Component)player).transform.position); PlayNeckSlashClientRpc(player.actualClientId, NeckSlashKillDelay); ((MonoBehaviour)this).StartCoroutine(KillAfterNeckSlashDelay(player.actualClientId)); } private IEnumerator KillAfterNeckSlashDelay(ulong playerClientId) { float endTime = Time.time + Mathf.Max(0.05f, NeckSlashKillDelay); float previousStepTime = Time.time; while (Time.time < endTime) { if (!((NetworkBehaviour)this).IsServer) { yield break; } PlayerControllerB val = FindPlayerByClientId(playerClientId); if ((Object)(object)val == (Object)null || val.isPlayerDead) { break; } float stepSeconds = Mathf.Max(Time.deltaTime, Time.time - previousStepTime); previousStepTime = Time.time; FacePosition(((Component)val).transform.position, stepSeconds); FocusHeadOnPlayerServer(val, 0.45f, fromNoise: false); if (_serverExecutionShouldCloseDistance) { MoveServerExecutionCloser(val, stepSeconds); } else if (Time.time < _serverSlashMomentumUntil) { MoveServerSlashMomentum(val, stepSeconds); } yield return (object)new WaitForSeconds(0.08f); } if (!((NetworkBehaviour)this).IsServer) { yield break; } bool serverExecutionShouldCloseDistance = _serverExecutionShouldCloseDistance; bool flag = _serverEntrancedClientId == playerClientId; bool flag2 = false; PlayerControllerB val2 = FindPlayerByClientId(playerClientId); if ((Object)(object)val2 != (Object)null && !val2.isPlayerDead) { FacePosition(((Component)val2).transform.position); FocusHeadOnPlayerServer(val2, 0.65f, fromNoise: false, forceSync: true); if (PlayerIsInNeckSlashContact(val2)) { flag2 = true; PlayKillSoundClientRpc(); ExecuteNeckSlashKillClientRpc(playerClientId); } } ResolveNeckSlashClientRpc(); _isNeckSlashing = false; _serverSlashTargetClientId = ulong.MaxValue; _serverExecutionShouldCloseDistance = false; _serverSlashMomentumSpeed = 0f; _serverSlashMomentumUntil = 0f; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[CreepyDollAI][combat] slash outcome: " + string.Format("mode={0}, player={1}, ", serverExecutionShouldCloseDistance ? "hypnosis" : "basic", playerClientId) + "result=" + (flag2 ? "hit" : "miss") + ".")); } if (flag2 && flag) { ClearServerEntrancedPlayer(playerClientId); } else if (!flag2 && serverExecutionShouldCloseDistance && flag) { RearmPossessionExecutionClientRpc(playerClientId); } } private void MoveServerExecutionCloser(PlayerControllerB player, float stepSeconds) { //IL_0020: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || (Object)(object)player == (Object)null || player.isPlayerDead) { return; } Vector3 val = ((Component)player).transform.position - ((Component)this).transform.position; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 2.05f || magnitude <= 0.05f) { return; } Vector3 val2 = ((Vector3)(ref val)).normalized * Mathf.Min(Mathf.Max(2.35f, MoveSpeed * 2.35f) * Mathf.Max(0f, stepSeconds), magnitude - 2.05f); if (!(((Vector3)(ref val2)).sqrMagnitude <= 1E-06f)) { if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { base.agent.Move(val2); return; } Transform transform = ((Component)this).transform; transform.position += val2; } } private void MoveServerSlashMomentum(PlayerControllerB player, float stepSeconds) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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) if (!((NetworkBehaviour)this).IsServer || (Object)(object)player == (Object)null || player.isPlayerDead || _serverSlashMomentumSpeed <= 0f) { return; } float num = Mathf.Max(0.05f, 0.45f); float num2 = Mathf.Clamp01((_serverSlashMomentumUntil - Time.time) / num); float num3 = _serverSlashMomentumSpeed * num2; if (num3 <= 0.01f) { return; } Vector3 val = ((Component)player).transform.position - ((Component)this).transform.position; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 1.5f || magnitude <= 0.05f) { return; } Vector3 val2 = ((Vector3)(ref val)).normalized * Mathf.Min(num3 * Mathf.Max(0f, stepSeconds), magnitude - 1.5f); if (!(((Vector3)(ref val2)).sqrMagnitude <= 1E-06f)) { if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { base.agent.Move(val2); return; } Transform transform = ((Component)this).transform; transform.position += val2; } } private bool PlayerIsInNeckSlashContact(PlayerControllerB player) { return PlayerFitsNeckSlashGeometry(player, NeckSlashRange + 0.35f, requireFacing: true, requireLineOfSight: true); } private bool PlayerFitsNeckSlashGeometry(PlayerControllerB player, float maximumRange, bool requireFacing, bool requireLineOfSight) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00d7: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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) if ((Object)(object)player == (Object)null || player.isPlayerDead || !((EnemyAI)this).PlayerIsTargetable(player, true, false, true)) { return false; } Vector3 val = ((Component)player).transform.position - ((Component)this).transform.position; if (Mathf.Abs(val.y) > 1.75f) { return false; } val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude > Mathf.Max(0.05f, maximumRange)) { return false; } if (requireFacing && magnitude > 0.05f && Vector3.Angle(((Component)this).transform.forward, val / magnitude) > 75f) { return false; } if (!requireLineOfSight) { return true; } Vector3 val2 = (((Object)(object)attackOrigin != (Object)null) ? attackOrigin.position : (((Component)this).transform.position + ((Component)this).transform.forward * 0.85f + Vector3.up * 1.05f)); Vector3 val3 = (((Object)(object)player.gameplayCamera != (Object)null) ? ((Component)player.gameplayCamera).transform.position : (((Component)player).transform.position + Vector3.up * 1.15f)) - val2; float magnitude2 = ((Vector3)(ref val3)).magnitude; if (!(magnitude2 <= 0.05f)) { return HasClearLineOfSight(val2, val3 / magnitude2, magnitude2, ((Component)player).transform); } return true; } private PlayerControllerB ResolveServerEntrancedPlayer() { if ((Object)(object)_serverEntrancedPlayer != (Object)null && !_serverEntrancedPlayer.isPlayerDead && ((EnemyAI)this).PlayerIsTargetable(_serverEntrancedPlayer, false, false, true)) { return _serverEntrancedPlayer; } if (_serverEntrancedClientId != ulong.MaxValue) { PlayerControllerB val = FindPlayerByClientId(_serverEntrancedClientId); if ((Object)(object)val != (Object)null && !val.isPlayerDead && ((EnemyAI)this).PlayerIsTargetable(val, false, false, true)) { _serverEntrancedPlayer = val; return val; } } ClearServerEntrancedPlayer(ulong.MaxValue); return null; } private void ClearServerEntrancedPlayer(ulong onlyClientId = ulong.MaxValue) { if ((onlyClientId == ulong.MaxValue || _serverEntrancedClientId == onlyClientId) && (!((Object)(object)_serverEntrancedPlayer == (Object)null) || _serverEntrancedClientId != ulong.MaxValue)) { ulong serverEntrancedClientId = _serverEntrancedClientId; _serverEntrancedPlayer = null; _serverEntrancedClientId = ulong.MaxValue; _serverEntrancedStartTime = 0f; _serverBodyRotationUnlockTime = 0f; _serverPossessionAcknowledged = false; base.targetPlayer = null; base.movingTowardsTargetPlayer = false; if (((NetworkBehaviour)this).IsServer && ((NetworkBehaviour)this).IsSpawned && serverEntrancedClientId != ulong.MaxValue) { EndPossessionClientRpc(serverEntrancedClientId); } if (((NetworkBehaviour)this).IsServer && !_isNeckSlashing) { RoamServer(); } } } private void SetServerPursuitTarget(PlayerControllerB player, string source) { //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) //IL_00c7: 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) if (((NetworkBehaviour)this).IsServer && !((Object)(object)player == (Object)null) && !player.isPlayerDead && ((EnemyAI)this).PlayerIsTargetable(player, true, false, true) && _serverEntrancedClientId == ulong.MaxValue) { ulong actualClientId = player.actualClientId; bool num = _serverPursuitClientId != actualClientId; _serverPursuitPlayer = player; _serverPursuitClientId = actualClientId; _serverPursuitLastVisibleTime = Time.time; _serverPursuitSource = (string.IsNullOrEmpty(source) ? "sight" : source); _serverPursuitLastSeenPosition = ((Component)player).transform.position; _hasServerPursuitLastSeen = true; EndServerInvestigation("new pursuit acquired"); _serverObservationPlanted = false; _serverObservationPlantSpent = true; if (num) { LogHeadStateEvent($"pursuit target latched: player={actualClientId}, source={_serverPursuitSource}, " + $"distance={Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position):0.0} m."); } } } private void StartPursuitSirenServer() { if (((NetworkBehaviour)this).IsServer && !_serverPursuitSirenActive) { int clipIndex = -1; if (mindControlClips != null && mindControlClips.Length != 0) { clipIndex = Random.Range(0, mindControlClips.Length); } _serverPursuitSirenActive = true; StartPursuitSirenClientRpc(clipIndex); } } private void StopPursuitSirenServer() { if (((NetworkBehaviour)this).IsServer && _serverPursuitSirenActive) { _serverPursuitSirenActive = false; StopPursuitSirenClientRpc(); } } private PlayerControllerB ResolveServerPursuitPlayer() { if (!((NetworkBehaviour)this).IsServer || _serverPursuitClientId == ulong.MaxValue) { return null; } PlayerControllerB val = _serverPursuitPlayer; if ((Object)(object)val == (Object)null || !PlayerMatchesClientId(val, _serverPursuitClientId)) { val = FindPlayerByClientId(_serverPursuitClientId); } if ((Object)(object)val == (Object)null || val.isPlayerDead || !((EnemyAI)this).PlayerIsTargetable(val, true, false, true)) { ClearServerPursuitTarget(clearObservationForSameTarget: true); return null; } _serverPursuitPlayer = val; return val; } private void BeginServerInvestigation(Vector3 point) { //IL_002c: 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_0043: 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_005e: Unknown result type (might be due to invalid IL or missing references) _serverInvestigating = true; _serverInvestigateLooking = false; _serverInvestigateLingering = false; _serverInvestigateLingerUntilTime = 0f; _serverSearchExitReason = "search complete"; _serverInvestigatePoint = point; _serverInvestigateStartedTime = Time.time; LogHeadStateEvent($"investigating last seen position {point} " + $"({Vector3.Distance(((Component)this).transform.position, point):0.0} m away)."); } private void EndServerInvestigation(string reason) { if (_serverInvestigating) { _serverInvestigating = false; _serverInvestigateLooking = false; _serverInvestigateLingering = false; _serverInvestigateLingerUntilTime = 0f; _serverSearchExitReason = reason; LogHeadStateEvent("investigation ended: " + reason + "."); } } private bool TickServerInvestigation() { //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_01da: 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_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || !_serverInvestigating) { return false; } base.targetPlayer = null; base.movingTowardsTargetPlayer = false; if (_serverInvestigateLingering) { if (Time.time >= _serverInvestigateLingerUntilTime) { EndServerInvestigation("search exhausted"); return false; } if (!EnsureAgentOnNavMesh()) { EndServerInvestigation("agent is not on NavMesh"); return false; } base.agent.updateRotation = AgentDrivesBodyRotation(); base.agent.isStopped = false; if (facilitySearch == null || base.currentSearch != facilitySearch || !facilitySearch.inProgress) { StartLingerSearch(); } if (!StaticVisualTestMode && base.currentBehaviourStateIndex != 1) { ((EnemyAI)this).SwitchToBehaviourState(1); } return true; } if (_serverInvestigateLooking) { if (Time.time >= _serverInvestigateLookUntilTime) { _serverInvestigateLooking = false; _serverInvestigateLingering = true; _serverInvestigateLingerUntilTime = Time.time + 30f; StartLingerSearch(); LogHeadStateEvent("look hold complete: sweeping the area for " + $"{30f:0} s before standing down."); return true; } StopMovingServer(); return true; } Vector3 val = ((Component)this).transform.position - _serverInvestigatePoint; val.y = 0f; bool num = ((Vector3)(ref val)).sqrMagnitude <= 2.5600002f; bool flag = Time.time - _serverInvestigateStartedTime > 12f; if (num || flag) { _serverInvestigateLooking = true; _serverInvestigateLookUntilTime = Time.time + 5f; ClearHeadFocus(syncClients: true); StopMovingServer(); return true; } StopSearchIfNeeded(clear: false); if (!EnsureAgentOnNavMesh()) { EndServerInvestigation("agent is not on NavMesh"); return false; } base.agent.updateRotation = AgentDrivesBodyRotation(); base.agent.isStopped = false; if (!((EnemyAI)this).SetDestinationToPosition(_serverInvestigatePoint, false)) { EndServerInvestigation("last seen position unreachable"); return false; } FocusHeadOnPointServer(_serverInvestigatePoint + Vector3.up * 1.4f, 0.8f); if (!StaticVisualTestMode && base.currentBehaviourStateIndex != 1) { ((EnemyAI)this).SwitchToBehaviourState(1); } return true; } private void TickServerSprint(PlayerControllerB target) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || (Object)(object)target == (Object)null) { return; } Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (!ServerSprintActive && _serverSprintPendingStartTime < 0f && (_serverSprintGuaranteePending || Time.time >= _nextSprintRollTime)) { TryScheduleSprint(magnitude); } if (_serverSprintPendingStartTime >= 0f && Time.time >= _serverSprintPendingStartTime) { _serverSprintPendingStartTime = -1f; if (magnitude >= 6f) { bool serverSprintGuaranteePending = _serverSprintGuaranteePending; _serverSprintGuaranteePending = false; _serverSprintUntilTime = Time.time + 3f; _nextSprintAllowedTime = Time.time + 30f; ApplyAgentSpeed(); PlayHeadSnapClientRpc(); PlaySprintVocalClientRpc(0.85f, Random.Range(1.12f, 1.18f)); LogHeadStateEvent($"sprint begin: player={target.actualClientId}, distance={magnitude:0.0} m, " + $"speed={3.6f:0.00} m/s for {3f:0.0} s, " + "source=" + (serverSprintGuaranteePending ? "guaranteed" : "roll") + "."); } } if (ServerSprintActive && magnitude <= 2.5f) { _serverSprintUntilTime = 0f; ApplyAgentSpeed(); LogHeadStateEvent($"sprint end: player={target.actualClientId}, reason=released, " + $"distance={magnitude:0.0}/{2.5f:0.0} m."); _serverSprintWasActive = false; return; } bool serverSprintActive = ServerSprintActive; if (_serverSprintWasActive && !serverSprintActive) { ApplyAgentSpeed(); LogHeadStateEvent($"sprint end: player={target.actualClientId}, reason=expired, " + $"distance={magnitude:0.0} m, speed={2f:0.00} m/s."); } _serverSprintWasActive = serverSprintActive; } private void TryScheduleSprint(float distanceToTarget) { if (Time.time < _nextSprintAllowedTime || distanceToTarget < 6f) { return; } if (!_serverSprintGuaranteePending) { _nextSprintRollTime = Time.time + 20f; if (Random.value > 0.35f) { return; } } _serverSprintPendingStartTime = Time.time + 0.8f; } private void ClearServerPursuitTarget(bool clearObservationForSameTarget) { ulong serverPursuitClientId = _serverPursuitClientId; _serverPursuitPlayer = null; _serverPursuitClientId = ulong.MaxValue; _serverPursuitLastVisibleTime = 0f; _serverPursuitSource = "none"; _hasServerPursuitLastSeen = false; _serverSprintPendingStartTime = -1f; _serverSprintUntilTime = 0f; _serverSprintWasActive = false; _nextSprintRollTime = 0f; if ((Object)(object)base.targetPlayer != (Object)null && serverPursuitClientId != ulong.MaxValue && PlayerMatchesClientId(base.targetPlayer, serverPursuitClientId)) { base.targetPlayer = null; base.movingTowardsTargetPlayer = false; } if (clearObservationForSameTarget && serverPursuitClientId != ulong.MaxValue && _serverObservationClientId == serverPursuitClientId) { ClearServerObservationTarget(clearHeadFocus: true); } } private void StopMovingServer() { if (((NetworkBehaviour)this).IsServer) { StopAgentPath(); if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled) { base.agent.updateRotation = AgentDrivesBodyRotation(); } if (!StaticVisualTestMode && base.currentBehaviourStateIndex != 0) { ((EnemyAI)this).SwitchToBehaviourState(0); } } } private void StopAgentPath() { if (!((Object)(object)base.agent == (Object)null) && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh && !base.agent.isStopped) { base.agent.isStopped = true; } } private void UpdateAnimatorMovementFlag() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_009c: 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) if ((Object)(object)base.creatureAnimator == (Object)null || StaticVisualTestMode) { return; } base.creatureAnimator.applyRootMotion = false; float num = SampleLocomotionSpeed(); bool num2 = num > 0.05f; bool flag = _smoothedBodyTurnSpeed > 10f; bool flag2 = num2 || flag; base.creatureAnimator.SetBool(AnimIsMoving, flag2); float num3 = Mathf.Min(MoveSpeed, _smoothedBodyTurnSpeed * 0.006f); float presentationSpeed = Mathf.Max(num, num3); bool flag3 = ResolveGait(flag2, presentationSpeed); AnimatorStateInfo currentAnimatorStateInfo = base.creatureAnimator.GetCurrentAnimatorStateInfo(0); bool flag4 = base.creatureAnimator.IsInTransition(0); AnimatorStateInfo val = (flag4 ? base.creatureAnimator.GetNextAnimatorStateInfo(0) : currentAnimatorStateInfo); bool flag5 = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("SlowWalk") || (flag4 && ((AnimatorStateInfo)(ref val)).IsName("SlowWalk")); bool flag6 = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Run") || (flag4 && ((AnimatorStateInfo)(ref val)).IsName("Run")); if (!flag2 || !(flag5 || flag6)) { _lastSlowWalkPlaybackRate = 0f; _lastGaitName = "none"; base.creatureAnimator.speed = 1f; return; } float num4 = GaitPlaybackRate(presentationSpeed, 4.85f, 4.56f); float num5 = GaitPlaybackRate(presentationSpeed, 1.9f, 4.54f); _lastSlowWalkPlaybackRate = (flag3 ? num5 : num4); _lastGaitName = (flag3 ? "run" : "walk"); if (HasGaitRateParameters()) { base.creatureAnimator.SetFloat(AnimWalkRate, num4); base.creatureAnimator.SetFloat(AnimRunRate, num5); base.creatureAnimator.speed = 1f; } else { float num6 = ((((AnimatorStateInfo)(ref val)).speed > 0.01f) ? ((AnimatorStateInfo)(ref val)).speed : 0.625f); float num7 = Mathf.Max(0.65f, 17.46f / (4.56f * num6)); base.creatureAnimator.speed = Mathf.Clamp(num4 / num6, 0.65f, num7); } } private static float GaitPlaybackRate(float presentationSpeed, float clipDuration, float clipDistance) { if (clipDistance <= 0.01f) { return 1f; } return presentationSpeed * clipDuration / clipDistance; } private bool ResolveGait(bool moving, float presentationSpeed) { if (!AnimatorHasRunClip()) { _runGaitEngaged = false; return false; } if (!moving) { _runGaitEngaged = false; } else if (_runGaitEngaged) { _runGaitEngaged = presentationSpeed >= 1.1f; } else { _runGaitEngaged = presentationSpeed >= 1.3f; } base.creatureAnimator.SetBool(AnimIsRunning, _runGaitEngaged); return _runGaitEngaged; } private bool AnimatorHasRunClip() { if (_runClipPresence == 0) { _runClipPresence = -1; RuntimeAnimatorController val = (((Object)(object)base.creatureAnimator != (Object)null) ? base.creatureAnimator.runtimeAnimatorController : null); if ((Object)(object)val != (Object)null) { AnimationClip[] animationClips = val.animationClips; foreach (AnimationClip val2 in animationClips) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name.IndexOf("CreepyDoll_Run", StringComparison.OrdinalIgnoreCase) >= 0) { _runClipPresence = 1; break; } } } } return _runClipPresence == 1; } private bool HasGaitRateParameters() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 if (_gaitRateParameterPresence == 0) { _gaitRateParameterPresence = -1; if ((Object)(object)base.creatureAnimator != (Object)null && (Object)(object)base.creatureAnimator.runtimeAnimatorController != (Object)null) { AnimatorControllerParameter[] parameters = base.creatureAnimator.parameters; bool flag = false; bool flag2 = false; foreach (AnimatorControllerParameter val in parameters) { if ((int)val.type == 1) { if (val.nameHash == AnimWalkRate) { flag = true; } else if (val.nameHash == AnimRunRate) { flag2 = true; } } } if (flag && flag2) { _gaitRateParameterPresence = 1; } } } return _gaitRateParameterPresence == 1; } private float SampleLocomotionSpeed() { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0094: 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_0033: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; position.y = 0f; float y = ((Component)this).transform.eulerAngles.y; if (!_hasLocomotionSample) { _lastLocomotionSamplePosition = position; _lastLocomotionSampleYawDegrees = y; _hasLocomotionSample = true; _smoothedLocomotionSpeed = 0f; _smoothedBodyTurnSpeed = 0f; return 0f; } float num = Mathf.Max(Time.deltaTime, 0.0001f); float num2 = Vector3.Distance(position, _lastLocomotionSamplePosition); float num3 = Mathf.Abs(Mathf.DeltaAngle(_lastLocomotionSampleYawDegrees, y)); _lastLocomotionSamplePosition = position; _lastLocomotionSampleYawDegrees = y; if (num2 > 3f) { _smoothedLocomotionSpeed = 0f; _smoothedBodyTurnSpeed = 0f; return 0f; } float num4 = num2 / num; float num5 = num3 / num; float num6 = 1f - Mathf.Exp(-12f * num); _smoothedLocomotionSpeed = Mathf.Lerp(_smoothedLocomotionSpeed, num4, num6); _smoothedBodyTurnSpeed = Mathf.Lerp(_smoothedBodyTurnSpeed, num5, num6); return _smoothedLocomotionSpeed; } private void TickCreatureAudio() { ApplyVanillaAudioParity(); EnsureConstantLoop(); EnsureIdleAudioSourceSettings(); if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead && !StaticVisualTestMode) { TickFootstepAudio(); } } private void ApplyVanillaAudioParity() { if (_audioParityApplied) { return; } SoundManager instance = SoundManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.diageticMixer == (Object)null) { return; } AudioMixerGroup[] array = instance.diageticMixer.FindMatchingGroups("Master"); if (array == null || array.Length == 0) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[CreepyDollAI] Diagetic mixer has no Master group; audio left unrouted."); } return; } AudioMixerGroup val = array[0]; int num = 0; int num2 = 0; AudioSource val2 = null; AudioSource[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (AudioSource val3 in componentsInChildren) { if ((Object)(object)val3 == (Object)null) { continue; } if (IsFootstepSource(val3)) { val2 = val3; } if ((Object)(object)val3 != (Object)(object)mindControlAudioSource) { val3.outputAudioMixerGroup = val; num++; } val3.rolloffMode = (AudioRolloffMode)1; val3.dopplerLevel = 0f; if (val3.spatialBlend <= 0f) { continue; } val3.reverbZoneMix = 1f; val3.bypassReverbZones = false; if (val3.spread <= 0f) { val3.spread = 40f; } if (IsFootstepSource(val3)) { NeutralizeAuthoredOcclusion(val3); continue; } bool flag = !IsConstantLoopSource(val3); OccludeAudio component = ((Component)val3).GetComponent(); if ((Object)(object)component == (Object)null) { ((Component)val3).gameObject.AddComponent().useReverb = flag; num2++; } else if (!flag) { component.useReverb = false; } if (!flag) { AudioReverbFilter component2 = ((Component)val3).GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } } } _audioParityApplied = true; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)($"[CreepyDollAI] Audio parity applied: routed {num} source(s) to " + $"Diagetic/{((Object)val).name}, added OccludeAudio to {num2}.")); } LogResolvedStepSourceState(val2 ?? stepAudioSource); } private bool IsFootstepSource(AudioSource source) { if ((Object)(object)source == (Object)null) { return false; } if (source != stepAudioSource) { return string.Equals(((Object)((Component)source).gameObject).name, "StepSFX", StringComparison.Ordinal); } return true; } private bool IsConstantLoopSource(AudioSource source) { if ((Object)(object)source == (Object)null) { return false; } if (source != constantAudioSource) { return string.Equals(((Object)((Component)source).gameObject).name, "ConstantLoopSFX", StringComparison.Ordinal); } return true; } private static void NeutralizeAuthoredOcclusion(AudioSource source) { OccludeAudio component = ((Component)source).GetComponent(); if ((Object)(object)component != (Object)null) { component.overridingLowPass = true; component.lowPassOverride = 20000f; return; } AudioLowPassFilter component2 = ((Component)source).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.cutoffFrequency = 20000f; } } private void LogResolvedStepSourceState(AudioSource source) { //IL_0127: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[CreepyDollAI][stepsfx] No footstep AudioSource resolved at audio parity; steps will fall back to CreatureSFX."); } return; } OccludeAudio component = ((Component)source).GetComponent(); AudioLowPassFilter component2 = ((Component)source).GetComponent(); string arg = (((Object)(object)source.outputAudioMixerGroup != (Object)null) ? ((Object)source.outputAudioMixerGroup).name : ""); string text = (((Object)(object)component == (Object)null) ? "none" : $"present(enabled={((Behaviour)component).enabled}, overridden={component.overridingLowPass}@{component.lowPassOverride:0})"); string text2 = (((Object)(object)component2 == (Object)null) ? "none" : $"{component2.cutoffFrequency:0} Hz"); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)($"[CreepyDollAI][stepsfx] resolved '{((Object)((Component)source).gameObject).name}': volume={source.volume:0.00}, " + $"mixer={arg}, spatialBlend={source.spatialBlend:0.00}, " + $"min/max={source.minDistance:0.00}/{source.maxDistance:0.00} m, " + $"rolloff={source.rolloffMode}, spread={source.spread:0}, doppler={source.dopplerLevel:0.00}, " + $"priority={source.priority}, mute={source.mute}, occludeAudio={text}, lowPass={text2}, " + $"broadcastVolume={1f:0.00}, poolGain={ResolveStepClipGain(stepClips):0.00}.")); } } private void EnsureConstantLoop() { if (!((Object)(object)constantAudioSource == (Object)null) && !((Object)(object)constantClip == (Object)null) && !base.isEnemyDead) { if ((Object)(object)_constantLoopConfiguredSource != (Object)(object)constantAudioSource) { constantAudioSource.clip = constantClip; constantAudioSource.loop = true; constantAudioSource.volume = 0.3f; constantAudioSource.spatialBlend = 1f; constantAudioSource.minDistance = 3f; constantAudioSource.maxDistance = 6f; constantAudioSource.rolloffMode = (AudioRolloffMode)1; _constantLoopConfiguredSource = constantAudioSource; } if (!constantAudioSource.isPlaying) { constantAudioSource.Play(); } } } private void StopConstantLoop() { if ((Object)(object)constantAudioSource != (Object)null && constantAudioSource.isPlaying) { constantAudioSource.Stop(); } } private void EnsureIdleAudioSourceSettings() { if ((Object)(object)idleAudioSource == (Object)null) { _idleAudioConfiguredSource = null; } else if (!((Object)(object)_idleAudioConfiguredSource == (Object)(object)idleAudioSource)) { idleAudioSource.spatialBlend = 1f; idleAudioSource.volume = 1f; idleAudioSource.minDistance = 2f; idleAudioSource.maxDistance = 30f; _idleAudioConfiguredSource = idleAudioSource; } } private void TickFootstepAudio() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)base.creatureAnimator == (Object)null) && HasAnyStepClips()) { AccumulateFootstepTravelDistance(); LogFootstepDiagnostic(); AnimatorStateInfo currentAnimatorStateInfo = base.creatureAnimator.GetCurrentAnimatorStateInfo(0); if (!CreatureIsWalkingForFootsteps()) { _lastStandardFootstepKey = -1; _contactFootstepClockActive = false; ResetFootstepTravelTracking(keepAccumulator: false); } else if (!TickContactFootsteps(1f, 0.96f)) { TryTriggerPhasedFootstep(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime, StandardWalkFootstepPhases, ref _lastStandardFootstepKey, 1f, 0.96f); } } } private bool CreatureIsWalkingForFootsteps() { return _smoothedLocomotionSpeed > 0.05f; } private void TryTriggerPhasedFootstep(float normalizedTime, float[] phases, ref int lastFootstepKey, float volume, float pitchBase) { int num = Mathf.FloorToInt(normalizedTime); float num2 = Mathf.Repeat(normalizedTime, 1f); for (int i = 0; i < phases.Length; i++) { int num3 = num * phases.Length + i; if (num3 != lastFootstepKey && !(num2 < phases[i]) && !(num2 > phases[i] + 0.09f) && ConsumeFootstepTravelDistance()) { lastFootstepKey = num3; int surfaceIndex = ClassifySurfaceBelowRoot(); int num4 = PickRandomClipIndex(ResolveStepClipPool(surfaceIndex), ref _lastFootstepClipIndex); if (num4 >= 0) { PlayFootstepClientRpc(surfaceIndex, num4, volume, Random.Range(pitchBase - 0.05f, pitchBase + 0.05f)); _phasedFootstepCount++; MaybeCueIdleBeat(); } break; } } } private bool TickContactFootsteps(float volume, float pitchBase) { ResolveFootReferences(); if ((Object)(object)_leftFootBone == (Object)null || (Object)(object)_rightFootBone == (Object)null) { _contactFootstepClockActive = false; return false; } if (!_contactFootstepClockActive) { PrimeContactFootstep(_leftFootBone, ref _leftFootWasGrounded, ref _leftFootPreviousPosition, ref _leftFootSoleOffset); PrimeContactFootstep(_rightFootBone, ref _rightFootWasGrounded, ref _rightFootPreviousPosition, ref _rightFootSoleOffset); _contactFootstepClockActive = true; return true; } bool allowFootstep = CreatureIsWalkingForFootsteps(); TryTriggerContactFootstep(_leftFootBone, ref _leftFootWasGrounded, ref _leftFootPreviousPosition, ref _leftFootSoleOffset, volume, pitchBase, allowFootstep); TryTriggerContactFootstep(_rightFootBone, ref _rightFootWasGrounded, ref _rightFootPreviousPosition, ref _rightFootSoleOffset, volume, pitchBase, allowFootstep); return true; } private void PrimeContactFootstep(Transform foot, ref bool wasGrounded, ref Vector3 previousPosition, ref float soleOffset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) Vector3 position = foot.position; wasGrounded = FootIsGrounded(position, previousPosition, ref soleOffset, out var _); previousPosition = position; } private bool TryTriggerContactFootstep(Transform foot, ref bool wasGrounded, ref Vector3 previousPosition, ref float soleOffset, float volume, float pitchBase, bool allowFootstep) { //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_0013: 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_00a1: 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) if ((Object)(object)foot == (Object)null) { return false; } Vector3 position = foot.position; int surfaceIndex; bool flag = FootIsGrounded(position, previousPosition, ref soleOffset, out surfaceIndex); bool result = false; if (allowFootstep && flag && !wasGrounded && Time.time >= _nextContactFootstepTime) { int num = PickRandomClipIndex(ResolveStepClipPool(surfaceIndex), ref _lastFootstepClipIndex); if (num >= 0) { _nextContactFootstepTime = Time.time + 0.24f; PlayFootstepClientRpc(surfaceIndex, num, volume, Random.Range(pitchBase - 0.05f, pitchBase + 0.05f)); _contactFootstepCount++; MaybeCueIdleBeat(); result = true; } } wasGrounded = flag; previousPosition = position; return result; } private float AccumulateFootstepTravelDistance() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0026: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) Vector3 footstepTravelPosition = GetFootstepTravelPosition(); if (!_hasFootstepTravelPosition) { _lastFootstepTravelPosition = footstepTravelPosition; _hasFootstepTravelPosition = true; return _footstepTravelAccumulator; } float num = Vector3.Distance(footstepTravelPosition, _lastFootstepTravelPosition); _lastFootstepTravelPosition = footstepTravelPosition; if (num > 1.5f) { _footstepTravelAccumulator = 0f; return _footstepTravelAccumulator; } if (num > 0.001f) { _footstepTravelAccumulator = Mathf.Min(_footstepTravelAccumulator + num, 0.85f); } return _footstepTravelAccumulator; } private bool ConsumeFootstepTravelDistance() { if (_footstepTravelAccumulator < 0.34f) { return false; } _footstepTravelAccumulator = Mathf.Max(0f, _footstepTravelAccumulator - 0.34f); return true; } private Vector3 GetFootstepTravelPosition() { //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_0018: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; position.y = 0f; return position; } private void ResetFootstepTravelTracking(bool keepAccumulator) { _hasFootstepTravelPosition = false; _contactFootstepClockActive = false; if (!keepAccumulator) { _footstepTravelAccumulator = 0f; } } private bool FootIsGrounded(Vector3 footPosition, Vector3 previousPosition, ref float soleOffset, out int surfaceIndex) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //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_0020: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) surfaceIndex = 0; Vector3 val = footPosition + Vector3.up * 1f; int num = ResolveLineOfSightMask(); RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(val, Vector3.down, ref val2, 3.5f, num, (QueryTriggerInteraction)1)) { return false; } if ((Object)(object)((RaycastHit)(ref val2)).collider != (Object)null && ((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(((Component)this).transform)) { return false; } surfaceIndex = ClassifySurfaceFromCollider(((RaycastHit)(ref val2)).collider); float num2 = footPosition.y - ((RaycastHit)(ref val2)).point.y; if (num2 < -0.5f || num2 > 2.5f) { return false; } bool flag = UpdateFootSoleOffsetFromClearance(num2, ref soleOffset); if (soleOffset < 0f) { return false; } float num3 = ((Time.deltaTime > 0.0001f) ? ((footPosition.y - previousPosition.y) / Time.deltaTime) : 0f); float num4 = (flag ? (soleOffset + 0.14f) : 0.14f); if (num2 <= num4) { return num3 <= 0.18f; } return false; } private static bool UpdateFootSoleOffsetFromClearance(float clearance, ref float soleOffset) { bool flag = soleOffset >= 0f; if (clearance >= 0.02f && (flag || clearance <= 0.35f)) { soleOffset = (flag ? Mathf.Min(clearance, soleOffset + 0.08f * Time.deltaTime) : clearance); } return flag; } private void CalibrateFootSoleOffset(Transform foot, ref float soleOffset) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_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_0026: 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_0072: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)foot == (Object)null) { return; } Vector3 position = foot.position; RaycastHit val = default(RaycastHit); if (Physics.Raycast(position + Vector3.up * 1f, Vector3.down, ref val, 3.5f, ResolveLineOfSightMask(), (QueryTriggerInteraction)1) && (!((Object)(object)((RaycastHit)(ref val)).collider != (Object)null) || !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)this).transform))) { float num = position.y - ((RaycastHit)(ref val)).point.y; if (!(num < -0.5f) && !(num > 2.5f)) { UpdateFootSoleOffsetFromClearance(num, ref soleOffset); } } } private static int ClassifySurfaceFromCollider(Collider collider) { if ((Object)(object)collider == (Object)null) { return 0; } string tag = ((Component)collider).tag; if (!string.IsNullOrEmpty(tag) && !tag.Equals("Untagged", StringComparison.OrdinalIgnoreCase)) { if (tag.Equals("Metal", StringComparison.OrdinalIgnoreCase) || tag.Equals("Catwalk", StringComparison.OrdinalIgnoreCase)) { return 1; } if (tag.Equals("Wood", StringComparison.OrdinalIgnoreCase)) { return 2; } return 0; } string text = ((Object)collider).name; if ((Object)(object)collider.sharedMaterial != (Object)null && !string.IsNullOrEmpty(((Object)collider.sharedMaterial).name)) { text = text + "|" + ((Object)collider.sharedMaterial).name; } if (text.IndexOf("metal", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("catwalk", StringComparison.OrdinalIgnoreCase) >= 0) { return 1; } if (text.IndexOf("wood", StringComparison.OrdinalIgnoreCase) >= 0) { return 2; } return 0; } private int ClassifySurfaceBelowRoot() { //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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position + Vector3.up * 0.35f; int num = ResolveLineOfSightMask(); RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, Vector3.down, ref val2, 1.6f, num, (QueryTriggerInteraction)1) && (Object)(object)((RaycastHit)(ref val2)).collider != (Object)null && !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(((Component)this).transform)) { return ClassifySurfaceFromCollider(((RaycastHit)(ref val2)).collider); } return 0; } private AudioClip[] ResolveStepClipPool(int surfaceIndex) { AudioClip[] array = surfaceIndex switch { 1 => stepClipsMetal, 2 => stepClipsWood, _ => stepClipsConcrete, }; if (array != null && array.Length != 0) { return array; } if (stepClips != null && stepClips.Length != 0) { return stepClips; } if (stepClipsConcrete != null && stepClipsConcrete.Length != 0) { return stepClipsConcrete; } if (stepClipsMetal != null && stepClipsMetal.Length != 0) { return stepClipsMetal; } return stepClipsWood; } private bool HasAnyStepClips() { AudioClip[] array = ResolveStepClipPool(0); if (array != null) { return array.Length != 0; } return false; } private AudioClip PickMindControlClip() { if (mindControlClips != null && mindControlClips.Length != 0) { int lastIndex = -1; int num = PickRandomClipIndex(mindControlClips, ref lastIndex); if (num >= 0) { return mindControlClips[num]; } } return mindControlClip; } private bool HasAnyMindControlClip() { if ((Object)(object)mindControlClip != (Object)null) { return true; } if (mindControlClips == null) { return false; } for (int i = 0; i < mindControlClips.Length; i++) { if ((Object)(object)mindControlClips[i] != (Object)null) { return true; } } return false; } private void MaybeCueIdleBeat() { if (((NetworkBehaviour)this).IsServer && !((Object)(object)idleBeatClip == (Object)null)) { if (_stepsUntilIdleBeat < 0) { _stepsUntilIdleBeat = Random.Range(5, 10); } if (--_stepsUntilIdleBeat <= 0) { _stepsUntilIdleBeat = Random.Range(5, 10); PlayIdleBeatClientRpc(0.4f, Random.Range(0.94f, 1.05f)); } } } private static int PickRandomClipIndex(AudioClip[] clips, ref int lastIndex) { if (clips == null || clips.Length == 0) { return -1; } if (clips.Length == 1) { lastIndex = ((!((Object)(object)clips[0] != (Object)null)) ? (-1) : 0); return lastIndex; } for (int i = 0; i < 12; i++) { int num = Random.Range(0, clips.Length); if (num != lastIndex && (Object)(object)clips[num] != (Object)null) { lastIndex = num; return num; } } for (int j = 0; j < clips.Length; j++) { if (j != lastIndex && (Object)(object)clips[j] != (Object)null) { lastIndex = j; return j; } } return -1; } private static void PlayClipOneShot(AudioSource source, AudioClip[] clips, int clipIndex, float volume, float pitch) { if (clips != null && clipIndex >= 0 && clipIndex < clips.Length) { PlayClipOneShot(source, clips[clipIndex], volume, pitch); } } private static void PlayClipOneShot(AudioSource source, AudioClip clip, float volume, float pitch) { if (!((Object)(object)source == (Object)null) && !((Object)(object)clip == (Object)null)) { if (!source.isPlaying) { source.pitch = Mathf.Clamp(pitch, 0.6f, 1.35f); } source.PlayOneShot(clip, Mathf.Clamp(volume, 0f, 64f)); } } private float CurrentGazeGateDegrees(PlayerControllerB player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.gameplayCamera == (Object)null) { return GazeHalfAngleDegrees; } return EffectiveGazeHalfAngleDegrees(Vector3.Distance(GetFacePoint(), ((Component)player.gameplayCamera).transform.position)); } private float EffectiveGazeHalfAngleDegrees(float distance) { float num = 4f; float num2 = 10f; if (distance <= num) { return CloseRangeGazeHalfAngleDegrees; } if (distance >= num2 || num2 <= num) { return GazeHalfAngleDegrees; } return Mathf.Lerp(CloseRangeGazeHalfAngleDegrees, GazeHalfAngleDegrees, Mathf.InverseLerp(num, num2, distance)); } private int FillBodyProbePoints(Vector3[] buffer) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) buffer[0] = GetLookTargetPoint(); buffer[1] = ((Component)this).transform.position + Vector3.up * 2f; buffer[2] = ((Component)this).transform.position + Vector3.up * 0.5f; return 3; } private bool PlayerHasLineOfSightToDoll(PlayerControllerB player) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.gameplayCamera == (Object)null) { return false; } int num = FillBodyProbePoints(_bodyProbePoints); for (int i = 0; i < num; i++) { if (PlayerHasLineOfSightToDollPoint(player, _bodyProbePoints[i])) { return true; } } return false; } private bool PlayerHasLineOfSightToDollPoint(PlayerControllerB player, Vector3 target) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)player.gameplayCamera).transform.position; Vector3 val = target - position; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.05f || magnitude > GazeRange) { return false; } Vector3 val2 = val / magnitude; int num = ResolveLineOfSightMask(); int num2 = Physics.RaycastNonAlloc(position, val2, _lineOfSightHits, magnitude - 0.08f, num, (QueryTriggerInteraction)1); if (num2 > 1) { Array.Sort(_lineOfSightHits, 0, num2, RaycastHitDistanceComparer.Instance); } for (int i = 0; i < num2; i++) { Collider collider = ((RaycastHit)(ref _lineOfSightHits[i])).collider; if (!((Object)(object)collider == (Object)null)) { Transform transform = ((Component)collider).transform; if (!transform.IsChildOf(((Component)this).transform) && !transform.IsChildOf(((Component)player).transform)) { return false; } } } return true; } private bool CachedPlayerHasLineOfSightToDoll(PlayerControllerB player, float interval, ref float nextProbeTime, ref bool cachedResult) { if (Time.time >= nextProbeTime) { nextProbeTime = Time.time + Mathf.Max(0.02f, interval); cachedResult = PlayerHasLineOfSightToDoll(player); } return cachedResult; } [ClientRpc] private void SetHeadFocusClientRpc(Vector3 focusPoint, float duration, bool fromNoise) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(79685772u, val2, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe(ref focusPoint); ((FastBufferWriter)(ref val)).WriteValueSafe(ref duration, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref fromNoise, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 79685772u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; SetHeadFocus(focusPoint, duration, fromNoise); } } } [ClientRpc] private void ClearHeadFocusClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1932402267u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 1932402267u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ClearHeadFocus(syncClients: false); } } } [ClientRpc] private void SyncObservationStateClientRpc(ulong observedClientId, bool spotConfirmed, float confirmedSecondsAgo, int confirmEpoch) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(759200182u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, observedClientId); ((FastBufferWriter)(ref val)).WriteValueSafe(ref spotConfirmed, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref confirmedSecondsAgo, default(ForPrimitives)); BytePacker.WriteValueBitPacked(val, confirmEpoch); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 759200182u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; _replicatedObservedClientId = observedClientId; _replicatedSpotConfirmed = spotConfirmed && observedClientId != ulong.MaxValue; if (!_replicatedSpotConfirmed) { _replicatedSpotConfirmedTime = 0f; _replicatedSpotConfirmEpoch = 0; } else { _replicatedSpotConfirmedTime = Time.time - Mathf.Max(0f, confirmedSecondsAgo); _replicatedSpotConfirmEpoch = confirmEpoch; } } } private void SyncServerObservationState() { if (((NetworkBehaviour)this).IsServer) { ulong num = (ServerHasActiveObservationTarget() ? _serverObservationClientId : ulong.MaxValue); bool flag = num != ulong.MaxValue && _serverSpotConfirmed; int num2 = (flag ? _serverSpotConfirmEpoch : 0); bool num3 = num != _syncedObservedClientId || flag != _syncedSpotConfirmed || num2 != _syncedSpotConfirmEpoch; bool flag2 = flag && Time.time >= _nextObservationSyncRefreshTime; if (num3 || flag2) { _syncedObservedClientId = num; _syncedSpotConfirmed = flag; _syncedSpotConfirmEpoch = num2; _nextObservationSyncRefreshTime = Time.time + 1f; float confirmedSecondsAgo = (flag ? Mathf.Max(0f, Time.time - _serverSpotConfirmedAtTime) : 0f); SyncObservationStateClientRpc(num, flag, confirmedSecondsAgo, num2); } } } private void FocusHeadOnPlayerServer(PlayerControllerB player, float duration, bool fromNoise, bool forceSync = false) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) if (((NetworkBehaviour)this).IsServer && !((Object)(object)player == (Object)null) && !player.isPlayerDead && HeadTrackingEnabled) { Vector3 playerFocusPoint = GetPlayerFocusPoint(player); SetHeadFocus(playerFocusPoint, duration, fromNoise); if (forceSync || !(Time.time < _nextHeadFocusSyncTime)) { _nextHeadFocusSyncTime = Time.time + 0.22f; SetHeadFocusClientRpc(playerFocusPoint, duration, fromNoise); } } } private void ForceHeadSnapToPlayerServer(PlayerControllerB player, float duration) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsServer && !((Object)(object)player == (Object)null) && !player.isPlayerDead && HeadTrackingEnabled) { Vector3 playerFocusPoint = GetPlayerFocusPoint(player); SetHeadFocus(playerFocusPoint, duration, fromNoise: false, forceSnap: true); _nextHeadFocusSyncTime = Time.time + 0.22f; SetHeadFocusSnapClientRpc(playerFocusPoint, duration); } } [ClientRpc] private void SetHeadFocusSnapClientRpc(Vector3 focusPoint, float duration) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(3527252639u, val2, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe(ref focusPoint); ((FastBufferWriter)(ref val)).WriteValueSafe(ref duration, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 3527252639u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; SetHeadFocus(focusPoint, duration, fromNoise: false, forceSnap: true); } } } private void FocusHeadOnPointServer(Vector3 focusPoint, float duration, bool forceSync = false) { //IL_0012: 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) if (((NetworkBehaviour)this).IsServer && HeadTrackingEnabled) { SetHeadFocus(focusPoint, duration, fromNoise: true); if (forceSync || !(Time.time < _nextHeadFocusSyncTime)) { _nextHeadFocusSyncTime = Time.time + 0.22f; SetHeadFocusClientRpc(focusPoint, duration, fromNoise: true); } } } private void TickServerHeadDetectionState() { //IL_0120: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead || !HeadTrackingEnabled || StaticVisualTestMode) { _serverObservationPlanted = false; ResetServerObservationPlantHistory(); } else { if (_isNeckSlashing) { return; } if (_serverEntrancedClientId != ulong.MaxValue) { ClearServerPursuitTarget(clearObservationForSameTarget: false); ClearServerObservationTarget(); ResetServerObservationPlantHistory(); return; } bool fromNoise; string source; PlayerControllerB val = FindHeadTrackingDetectionCandidate(out fromNoise, out source); if ((Object)(object)val != (Object)null) { bool fromNoise2 = fromNoise; string source2 = source; SetServerObservationTarget(val, fromNoise2, null, source2); NoteEncounterStimulus(val, !fromNoise); } ulong serverObservationClientId = _serverObservationClientId; bool serverSpotConfirmed = _serverSpotConfirmed; bool serverObservationFromNoise = _serverObservationFromNoise; PlayerControllerB val2 = ResolveServerObservationTarget(); if ((Object)(object)val2 == (Object)null) { if (serverObservationClientId != ulong.MaxValue) { LogHeadStateEvent($"observation expired: player={serverObservationClientId}, " + string.Format("source={0}, wasSpotConfirmed={1}. ", serverObservationFromNoise ? "noise" : "sight", serverSpotConfirmed) + "Head now eases back to the animated pose."); } ClearServerObservationTarget(clearHeadFocus: true); return; } if (_serverObservationFromNoise && !_serverSpotConfirmed) { FocusHeadOnPointServer(_serverNoiseStimulusPoint, 0.55f); } else { FocusHeadOnPlayerServer(val2, 0.55f, fromNoise: false); } bool flag = _serverGazeContactSeconds > 0f; float facingYawDegrees; float playerLookAngleDegrees; string failReason; bool flag2 = ServerPlayerIsMakingEyeContact(val2, flag || _serverSpotConfirmed, out facingYawDegrees, out playerLookAngleDegrees, out failReason); if (flag2) { _serverGazeContactSeconds += Time.deltaTime; _serverGazeLastContactTime = Time.time; _serverGazeGraceLogged = false; } else if (flag && Time.time - _serverGazeLastContactTime <= SpotConfirmGraceSeconds) { if (!_serverGazeGraceLogged) { _serverGazeGraceLogged = true; LogHeadStateEvent($"spot GRACE: player={_serverObservationClientId}, " + $"window={SpotConfirmGraceSeconds:0.00} s, confirmed={_serverSpotConfirmed}, " + $"fail={failReason}, facingYaw={facingYawDegrees:0} deg, " + $"playerLook={playerLookAngleDegrees:0}/{CurrentGazeGateDegrees(val2):0} deg."); } } else { if (_serverSpotConfirmed || flag) { LogHeadStateEvent($"spot LOST: player={_serverObservationClientId}, " + $"wasConfirmed={_serverSpotConfirmed}, contact={_serverGazeContactSeconds:0.00} s, " + "fail=" + failReason + ", " + $"facingYaw={facingYawDegrees:0} deg, " + $"playerLook={playerLookAngleDegrees:0}/{CurrentGazeGateDegrees(val2):0} deg."); } _serverGazeContactSeconds = 0f; _serverGazeLastContactTime = 0f; _serverGazeGraceLogged = false; _serverSpotConfirmed = false; } if (_serverGazeContactSeconds > 0f) { bool serverSpotConfirmed2 = _serverSpotConfirmed; if (!serverSpotConfirmed2 && _serverGazeContactSeconds >= SpotConfirmSeconds) { _serverSpotConfirmed = true; _serverSpotConfirmedAtTime = Time.time; _serverSpotConfirmEpoch++; } if (_serverSpotConfirmed) { _serverObservationFromNoise = false; if (flag2) { _serverSightLastSeenTime = Time.time; } _serverObservationUntilTime = Mathf.Max(_serverObservationUntilTime, Time.time + HeadSightHoldSeconds); FocusHeadOnPlayerServer(val2, HeadSightHoldSeconds, fromNoise: false, !serverSpotConfirmed2); if (!serverSpotConfirmed2) { LogHeadStateEvent($"spot CONFIRMED: player={_serverObservationClientId}, epoch={_serverSpotConfirmEpoch}, " + $"contact={_serverGazeContactSeconds:0.00}/{SpotConfirmSeconds:0.00} s accumulated, " + $"facingYaw={facingYawDegrees:0} deg, playerLook={playerLookAngleDegrees:0}/{CurrentGazeGateDegrees(val2):0} deg, " + $"hypnosis may begin in {HypnosisOnsetDelaySeconds:0.00} s."); } } } TightenBodyTurnDelayForRegionCrossing(val2); UpdateServerObservationPlant(); } } private void TightenBodyTurnDelayForRegionCrossing(PlayerControllerB player) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (_serverObservationFromNoise && !_serverSpotConfirmed) || _serverObservationPlanted || _serverObservationPlantSpent) { return; } float num = CalculateHeadYawToPoint(GetPlayerFocusPoint(player)); if (!(Mathf.Abs(num) <= HeadYawLimitDegrees)) { float num2 = Time.time + Mathf.Max(0f, HeadRearTurnDelaySeconds); if (!(num2 >= _headBodyFollowAllowedTime)) { _headBodyFollowAllowedTime = num2; LogHeadStateEvent($"body turn delay tightened: player={_serverObservationClientId}, " + $"yawToTarget={num:0} deg (limit {HeadYawLimitDegrees:0}), " + $"body may follow in {Mathf.Max(0f, HeadRearTurnDelaySeconds):0.00} s."); } } } private bool SetServerObservationTarget(PlayerControllerB player, bool fromNoise, Vector3? noisePosition = null, string source = null) { //IL_0161: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || !PlayerCanBeHeadTracked(player) || _serverEntrancedClientId != ulong.MaxValue) { return false; } ulong actualClientId = player.actualClientId; bool flag = _serverObservationClientId != actualClientId; if (fromNoise && _serverSpotConfirmed) { return false; } if (fromNoise && !flag && !_serverObservationFromNoise) { return false; } if (fromNoise && flag && !_serverObservationFromNoise && ServerHasActiveObservationTarget()) { PlayerControllerB val = FindPlayerByClientId(_serverObservationClientId); if ((Object)(object)val != (Object)null) { float num = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position); if (Vector3.Distance(((Component)this).transform.position, (Vector3)(((??)noisePosition) ?? ((Component)player).transform.position)) >= num * 0.5f) { return false; } } } bool result = fromNoise && (flag || !_serverObservationFromNoise || !HasActiveHeadFocus()); if (flag) { _serverObservationClientId = actualClientId; _serverGazeContactSeconds = 0f; _serverGazeLastContactTime = 0f; _serverGazeGraceLogged = false; _serverSpotConfirmed = false; _serverBodyTurnInProgress = false; _serverObservationPlanted = false; _serverObservationPlantStartTime = 0f; _serverObservationPlantAlignedTime = 0f; _serverObservationPlantSpent = !ServerPlantIsAvailableFor(actualClientId); _serverSightLastSeenTime = Time.time; float num2 = CalculateHeadYawToPoint(GetPlayerFocusPoint(player)); bool flag2 = Mathf.Abs(num2) > HeadYawLimitDegrees; float num3 = Mathf.Max(0f, flag2 ? HeadRearTurnDelaySeconds : HeadBodyFollowDelay); _headBodyFollowAllowedTime = Time.time + num3; LogHeadStateEvent($"observation acquired: player={actualClientId}, " + "source=" + (source ?? (fromNoise ? "noise" : "sight")) + ", " + $"distance={Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position):0.0} m, " + $"yawToTarget={num2:0} deg (limit {HeadYawLimitDegrees:0}), " + $"bodyDelay={num3:0.00} s, " + $"cone={HeadVisionConeDegrees:0} deg, sightRange={HeadSightRange:0}, " + $"proximity={HeadProximityAwareness:0.0}, rear={HeadRearAwarenessRange:0.0}."); } _serverObservationFromNoise = fromNoise; _serverObservationUntilTime = Time.time + (fromNoise ? 4.5f : HeadSightHoldSeconds); if (fromNoise) { _serverNoiseStimulusPoint = (Vector3)(((??)noisePosition) ?? GetPlayerFocusPoint(player)); } if (fromNoise) { FocusHeadOnPointServer(_serverNoiseStimulusPoint, 4.5f, flag); } else { FocusHeadOnPlayerServer(player, HeadSightHoldSeconds, fromNoise: false, flag); } return result; } private PlayerControllerB ResolveServerObservationTarget() { if (!((NetworkBehaviour)this).IsServer || _serverObservationClientId == ulong.MaxValue || Time.time > _serverObservationUntilTime) { ClearServerObservationTarget(clearHeadFocus: true); return null; } PlayerControllerB val = FindPlayerByClientId(_serverObservationClientId); if (!PlayerCanBeHeadTracked(val) || !((EnemyAI)this).PlayerIsTargetable(val, true, false, true)) { ClearServerObservationTarget(clearHeadFocus: true); return null; } if (!_serverObservationFromNoise) { if (ObservationTargetIsVisible(val)) { _serverSightLastSeenTime = Time.time; _serverObservationUntilTime = Mathf.Max(_serverObservationUntilTime, Time.time + HeadSightHoldSeconds); } else if (Time.time - _serverSightLastSeenTime > 0.4f) { ClearServerObservationTarget(clearHeadFocus: true); return null; } } return val; } private bool ObservationTargetIsVisible(PlayerControllerB player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Vector3 headTrackingOrigin = GetHeadTrackingOrigin(); Vector3 val = GetPlayerFocusPoint(player) - headTrackingOrigin; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.05f || magnitude > HeadTrackingRange) { return false; } return HasClearLineOfSight(headTrackingOrigin, val / magnitude, magnitude, ((Component)player).transform); } private bool ServerHasActiveObservationTarget() { if (_serverObservationClientId != ulong.MaxValue) { return Time.time <= _serverObservationUntilTime; } return false; } private void UpdateServerObservationPlant() { if (_serverObservationFromNoise && !_serverSpotConfirmed) { _serverObservationPlanted = false; return; } if (_serverPursuitClientId != ulong.MaxValue && _serverPursuitClientId == _serverObservationClientId) { _serverObservationPlanted = false; _serverObservationPlantSpent = true; return; } if (!ServerHasActiveObservationTarget() || _serverObservationPlantSpent) { _serverObservationPlanted = false; return; } if (Time.time < _headBodyFollowAllowedTime) { _serverObservationPlanted = false; return; } if (!_serverObservationPlanted) { _serverObservationPlanted = true; _serverObservationPlantStartTime = Time.time; _serverObservationPlantAlignedTime = 0f; return; } if (_serverObservationPlantAlignedTime <= 0f && ServerBodyIsAlignedWithObservation()) { _serverObservationPlantAlignedTime = Time.time; } bool num = _serverObservationPlantAlignedTime > 0f && Time.time - _serverObservationPlantAlignedTime >= 4.5f; bool flag = Time.time - _serverObservationPlantStartTime >= 4.5f + 180f / Mathf.Max(1f, HeadBodyFollowSpeed); if (num || flag) { _serverObservationPlanted = false; _serverObservationPlantSpent = true; _serverLastPlantedClientId = _serverObservationClientId; _serverLastPlantCompletedTime = Time.time; } } private bool ServerPlantIsAvailableFor(ulong clientId) { if (_serverLastPlantedClientId == ulong.MaxValue || _serverLastPlantedClientId != clientId) { return true; } return Time.time - _serverLastPlantCompletedTime >= 10f; } private void ResetServerObservationPlantHistory() { _serverLastPlantedClientId = ulong.MaxValue; _serverLastPlantCompletedTime = float.NegativeInfinity; } private bool ServerBodyIsAlignedWithObservation() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_005d: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = FindPlayerByClientId(_serverObservationClientId); if ((Object)(object)val == (Object)null) { return true; } Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { return true; } return Vector3.Angle(((Component)this).transform.forward, ((Vector3)(ref val2)).normalized) <= 20f; } private bool ServerHoldsStillForObservation() { if (_serverObservationPlanted) { if (_serverObservationFromNoise) { return _serverSpotConfirmed; } return true; } return false; } private void ClearServerObservationTarget(bool clearHeadFocus = false) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) bool num = _serverObservationClientId != ulong.MaxValue; _serverObservationClientId = ulong.MaxValue; _serverObservationFromNoise = false; _serverObservationUntilTime = 0f; _serverGazeContactSeconds = 0f; _serverGazeLastContactTime = 0f; _serverGazeGraceLogged = false; _serverSpotConfirmed = false; if (num) { _serverBodyTurnInProgress = false; } _serverNoiseStimulusPoint = Vector3.zero; _serverSightLastSeenTime = 0f; _serverObservationPlanted = false; _serverObservationPlantStartTime = 0f; _serverObservationPlantAlignedTime = 0f; if (clearHeadFocus) { ClearHeadFocus(((NetworkBehaviour)this).IsServer); } } private bool AgentDrivesBodyRotation() { if (!((NetworkBehaviour)this).IsServer) { return true; } if (_isNeckSlashing) { return false; } if (_serverEntrancedClientId != ulong.MaxValue) { if (ServerMindControlMovementUnlocked) { return Time.time >= _serverBodyRotationUnlockTime; } return false; } if (_serverPursuitClientId != ulong.MaxValue) { return true; } return !ServerHoldsStillForObservation(); } private bool ServerPlayerIsMakingEyeContact(PlayerControllerB player, bool sustaining, out float facingYawDegrees, out float playerLookAngleDegrees, out string failReason) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_005f: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) facingYawDegrees = 0f; playerLookAngleDegrees = 180f; failReason = string.Empty; if (!PlayerCanBeHeadTracked(player) || (Object)(object)player.gameplayCamera == (Object)null) { failReason = "untrackable"; return false; } float num = (sustaining ? 8f : 0f); Vector3 facePoint = GetFacePoint(); Vector3 position = ((Component)player.gameplayCamera).transform.position; Vector3 val = position - facePoint; float magnitude = ((Vector3)(ref val)).magnitude; float num2 = HeadSightRange * (sustaining ? 1.15f : 1f); if (magnitude <= 0.05f || magnitude > num2) { failReason = "range"; return false; } facingYawDegrees = CalculateHeadYawToPoint(position); if (Mathf.Abs(facingYawDegrees) > HeadYawLimitDegrees + num) { failReason = "yaw"; return false; } Vector3 val2 = ((Component)this).transform.InverseTransformDirection(val / magnitude); Vector2 val3 = new Vector2(val2.x, val2.z); float magnitude2 = ((Vector2)(ref val3)).magnitude; if (Mathf.Abs(Mathf.Atan2(val2.y, magnitude2) * 57.29578f) > HeadPitchLimitDegrees + 15f) { failReason = "pitch"; return false; } if (_serverObservationClientId != player.actualClientId) { failReason = "notObserved"; return false; } float num3 = EffectiveGazeHalfAngleDegrees(magnitude) + num; bool flag = false; float num4 = 180f; float num5 = 180f; int num6 = FillBodyProbePoints(_bodyProbePoints); for (int i = 0; i < num6; i++) { Vector3 val4 = position - _bodyProbePoints[i]; float magnitude3 = ((Vector3)(ref val4)).magnitude; if (magnitude3 <= 0.05f) { continue; } Vector3 val5 = val4 / magnitude3; float num7 = Vector3.Angle(((Component)player.gameplayCamera).transform.forward, -val5); if (i == 0) { num5 = num7; } if (!HasClearLineOfSight(_bodyProbePoints[i], val5, magnitude3, ((Component)player).transform)) { continue; } flag = true; if (i < 2) { if (num7 < num4) { num4 = num7; } if (num7 <= num3) { playerLookAngleDegrees = num7; return true; } } } if (!flag || num4 > 179f) { playerLookAngleDegrees = num5; failReason = "occluded"; return false; } playerLookAngleDegrees = num4; failReason = "playerLook"; return false; } private void ApplyProceduralPose() { //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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) if (StaticVisualTestMode || base.isEnemyDead) { _headAimYawDegrees = 0f; _headAimPitchDegrees = 0f; _headAimRollDegrees = 0f; _headAimWorldDirection = Vector3.zero; _gazeAuthorityWeight = 0f; _idleScanActive = false; _hypnosisPitchBlend = 0f; return; } ResolveHeadTrackingReferences(); CaptureHeadChainRestPose(); float headPoseAuthority = HeadPoseAuthority; _gazeAuthorityWeight = Mathf.MoveTowards(_gazeAuthorityWeight, headPoseAuthority, 8f * Time.deltaTime); bool flag = _localPossessed || (((NetworkBehaviour)this).IsServer && _encounterState == EncounterState.Hypnosis); _hypnosisPitchBlend = Mathf.MoveTowards(_hypnosisPitchBlend, flag ? 1f : 0f, Time.deltaTime / Mathf.Max(0.01f, 0.3f)); Vector3 focusPoint; bool flag2 = TryGetActiveHeadFocus(out focusPoint) && HeadTrackingEnabled; bool flag3 = Mathf.Abs(_headPeekYawDegrees) > 0.5f || Mathf.Abs(_headPeekRollDegrees) > 0.5f; float num = 0f; float num2 = 0f; float num3 = 0f; float num4 = HeadTrackSpeed; float yawDegrees; float pitchDegrees; float rollDegrees; float speedDegreesPerSecond; if (flag2) { num = CalculateHeadYawToPoint(focusPoint); num2 = CalculateHeadPitchToPoint(focusPoint); num3 = _headPeekRollDegrees * 0.4f; _idleScanActive = false; } else if (flag3) { num = _headPeekYawDegrees; num3 = _headPeekRollDegrees; _idleScanActive = false; } else if (TryGetIdleExamineBeat(out yawDegrees, out pitchDegrees, out rollDegrees, out speedDegreesPerSecond)) { num = yawDegrees; num2 = pitchDegrees; num3 = rollDegrees; num4 = speedDegreesPerSecond; } num = Mathf.Clamp(num, 0f - HeadYawLimitDegrees, HeadYawLimitDegrees); float effectiveHeadPitchLimitDegrees = EffectiveHeadPitchLimitDegrees; num2 = Mathf.Clamp(num2, 0f - effectiveHeadPitchLimitDegrees, effectiveHeadPitchLimitDegrees); num3 = Mathf.Clamp(num3, 0f - HeadRollLimitDegrees, HeadRollLimitDegrees); bool flag4 = flag2 && Time.time <= _headSnapUntilTime; if (flag4 && Mathf.Abs(num - _headAimYawDegrees) <= 3f && Mathf.Abs(num2 - _headAimPitchDegrees) <= 3f) { _headSnapUntilTime = 0f; flag4 = false; } float num5 = (flag4 ? HeadSnapSpeed : num4); float num6 = Mathf.Max(1f, num5) * Time.deltaTime; float num7 = Mathf.Max(1f, num5 * 0.55f) * Time.deltaTime; float num8 = Mathf.Max(1f, num5 * 0.55f) * Time.deltaTime; _headAimYawDegrees = Mathf.MoveTowards(_headAimYawDegrees, num, num6); _headAimPitchDegrees = Mathf.MoveTowards(_headAimPitchDegrees, num2, num7); _headAimRollDegrees = Mathf.MoveTowards(_headAimRollDegrees, num3, num8); float doorwayDuckPitchDegrees = _doorwayDuckPitchDegrees; float headRestPitchTrimDegrees = HeadRestPitchTrimDegrees; float pitchDegrees2 = (((Object)(object)_lowerSpineBone != (Object)null) ? (doorwayDuckPitchDegrees * 0.3f) : 0f); float pitchDegrees3 = (((Object)(object)_upperSpineBone != (Object)null) ? (doorwayDuckPitchDegrees * 0.32f) : 0f); bool flag5 = false; flag5 |= ApplyAdditiveBoneAim(_lowerSpineBone, 0f, pitchDegrees2); flag5 |= ApplyAdditiveBoneAim(_upperSpineBone, 0f, pitchDegrees3); flag5 |= ApplyGazeBoneRotation(_neckBone, _neckRestToRoot, _headAimYawDegrees * 0.42f, _headAimPitchDegrees * 0.38f + doorwayDuckPitchDegrees * 0.84000003f + headRestPitchTrimDegrees * 0.38f, _headAimRollDegrees * 0.3f, _gazeAuthorityWeight); flag5 |= ApplyGazeBoneRotation(_headBone, _headRestToRoot, _headAimYawDegrees, _headAimPitchDegrees + doorwayDuckPitchDegrees + headRestPitchTrimDegrees, _headAimRollDegrees, _gazeAuthorityWeight); _headAimWorldDirection = BuildHeadAimDirection(_headAimYawDegrees, _headAimPitchDegrees); if (DebugLogs && Time.time >= _nextHeadDiagnosticTime) { _nextHeadDiagnosticTime = Time.time + 1f; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[CreepyDollAI] Procedural pose: hasFocus={flag2}, yaw={_headAimYawDegrees:0.0}/{num:0.0}, pitch={_headAimPitchDegrees:0.0}/{num2:0.0}, roll={_headAimRollDegrees:0.0}/{num3:0.0}, duck={doorwayDuckPitchDegrees:0.0}, peek={_headPeekYawDegrees:0.0}/{_headPeekRollDegrees:0.0}, scan={_idleScanActive}, authority={_gazeAuthorityWeight:0.00}/{HeadPoseAuthority:0.00} (rest={_headRestPoseSource}), applied={flag5}, head={GetTransformPath(_headBone)}, neck={GetTransformPath(_neckBone)}, lowerSpine={GetTransformPath(_lowerSpineBone)}, upperSpine={GetTransformPath(_upperSpineBone)}."); } } } private void ApplyProceduralNeckSlash() { if (!_localSlashPresentationActive) { return; } if (base.isEnemyDead) { _localSlashPresentationActive = false; _localSlashImpactReceived = false; _localSlashUsesClip = false; _localSlashClipRecoveryStarted = false; return; } if (_localSlashUsesClip) { TickSlashClipPresentation(); return; } float num = 1f; if (_localSlashImpactReceived) { float num2 = Mathf.Clamp01((Time.time - _localSlashImpactTime) / 0.32f); num = 1f - Mathf.SmoothStep(0f, 1f, num2); if (num2 >= 1f) { _localSlashPresentationActive = false; _localSlashImpactReceived = false; return; } } if (!StaticVisualTestMode && PlayNeckSlashAnimation) { ResolveHeadTrackingReferences(); float num3 = (_localSlashImpactReceived ? 1f : Mathf.Clamp01((Time.time - _localSlashStartedTime) / Mathf.Max(0.05f, _localSlashWindupSeconds))); float num4 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0f, 0.62f, num3)); float num5 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.62f, 0.88f, num3)); float windupWeight = num4 * (1f - num5) * num; float strikeWeight = num5 * num; ApplyAdditiveSlashBoneRotation(_upperSpineBone, BlendSlashPose(windupWeight, strikeWeight, 8f, -10f), BlendSlashPose(windupWeight, strikeWeight, -2f, 2f), 0f); ApplyAdditiveSlashBoneRotation(_rightClavicleBone, BlendSlashPose(windupWeight, strikeWeight, 6f, -8f), BlendSlashPose(windupWeight, strikeWeight, -2f, 0f), BlendSlashPose(windupWeight, strikeWeight, -4f, 3f)); ApplyAdditiveSlashBoneRotation(_rightUpperArmBone, BlendSlashPose(windupWeight, strikeWeight, 8f, -12f), BlendSlashPose(windupWeight, strikeWeight, -5f, -3f), BlendSlashPose(windupWeight, strikeWeight, -20f, 18f)); ApplyAdditiveSlashBoneRotation(_rightForearmBone, BlendSlashPose(windupWeight, strikeWeight, 5f, -8f), 0f, BlendSlashPose(windupWeight, strikeWeight, -5f, 4f)); } } private void TickSlashClipPresentation() { if (_localSlashImpactReceived) { if (!_localSlashClipRecoveryStarted) { _localSlashClipRecoveryStarted = true; if ((Object)(object)base.creatureAnimator != (Object)null && !StaticVisualTestMode) { base.creatureAnimator.CrossFadeInFixedTime("Idle", 0.32f, 0, 0f); } } else if (Time.time - _localSlashImpactTime >= 0.32f) { _localSlashPresentationActive = false; _localSlashImpactReceived = false; _localSlashUsesClip = false; _localSlashClipRecoveryStarted = false; } } else if (Time.time - _localSlashStartedTime > _localSlashWindupSeconds + 3f) { if ((Object)(object)base.creatureAnimator != (Object)null && !StaticVisualTestMode) { base.creatureAnimator.CrossFadeInFixedTime("Idle", 0.32f, 0, 0f); } _localSlashPresentationActive = false; _localSlashImpactReceived = false; _localSlashUsesClip = false; _localSlashClipRecoveryStarted = false; } } private static float BlendSlashPose(float windupWeight, float strikeWeight, float windupValue, float strikeValue) { return windupWeight * windupValue + strikeWeight * strikeValue; } private bool ApplyAdditiveSlashBoneRotation(Transform bone, float yawDegrees, float pitchDegrees, float rollDegrees) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bone == (Object)null) { return false; } Quaternion val = Quaternion.AngleAxis(yawDegrees, ((Component)this).transform.up) * Quaternion.AngleAxis(pitchDegrees, ((Component)this).transform.right) * Quaternion.AngleAxis(rollDegrees, ((Component)this).transform.forward); bone.rotation = val * bone.rotation; return true; } private void CaptureHeadChainRestPose() { //IL_001d: 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_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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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) //IL_00dc: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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) if (_hasHeadChainRestPose || (Object)(object)_headBone == (Object)null) { return; } Quaternion val = Quaternion.Inverse(((Component)this).transform.rotation) * _headBone.rotation; Quaternion neckRestToRoot = (((Object)(object)_neckBone != (Object)null) ? (Quaternion.Inverse(((Component)this).transform.rotation) * _neckBone.rotation) : Quaternion.identity); Quaternion restToRoot; bool flag = TryGetBindposeRestRotation(_headBone, out restToRoot); if (!flag || (Object)(object)_neckBone == (Object)null || !TryGetBindposeRestRotation(_neckBone, out _neckRestToRoot)) { _neckRestToRoot = neckRestToRoot; } _headRestToRoot = (flag ? restToRoot : val); float num = MeasureRestPitchDegrees(_headRestToRoot); Vector3 val2 = _headRestToRoot * Vector3.forward; Vector3 val3 = Vector3.ProjectOnPlane(val2, Vector3.up); if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f && ((Vector3)(ref val3)).sqrMagnitude > 0.0001f) { _headRestToRoot = Quaternion.FromToRotation(((Vector3)(ref val2)).normalized, ((Vector3)(ref val3)).normalized) * _headRestToRoot; } _headRestPoseSource = (flag ? "bindpose" : "live"); _hasHeadChainRestPose = true; float num2 = MeasureRestPitchDegrees(_headRestToRoot); float num3 = MeasureRestPitchDegrees(val); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[CreepyDollAI][head] rest captured: source=" + _headRestPoseSource + ", " + $"authoredRestPitch={num:0.0} deg, leveledRestPitch={num2:0.0} deg, " + $"livePitch={num3:0.0} deg (positive = face down), " + "head=" + GetTransformPath(_headBone) + ", neck=" + GetTransformPath(_neckBone) + ".")); } if (flag && Mathf.Abs(Mathf.DeltaAngle(num, num3)) > 5f) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)($"[CreepyDollAI][head] rest sources disagree by {Mathf.Abs(Mathf.DeltaAngle(num, num3)):0.0} deg " + "(bindpose vs the pose on screen). The bindpose is used; a large gap means the retargeted clips bake a head rotation, which is what HeadPoseAuthority exists to override.")); } } } private bool TryGetBindposeRestRotation(Transform bone, out Quaternion restToRoot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b1: 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_00bb: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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) //IL_0101: Unknown result type (might be due to invalid IL or missing references) restToRoot = Quaternion.identity; if ((Object)(object)bone == (Object)null) { return false; } SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sharedMesh == (Object)null || val.bones == null) { continue; } Transform[] bones = val.bones; Matrix4x4[] bindposes = val.sharedMesh.bindposes; if (bindposes == null) { continue; } for (int j = 0; j < bones.Length && j < bindposes.Length; j++) { if (!((Object)(object)bones[j] != (Object)(object)bone)) { Matrix4x4 val2 = ((Component)this).transform.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix * ((Matrix4x4)(ref bindposes[j])).inverse; Vector3 val3 = Vector4.op_Implicit(((Matrix4x4)(ref val2)).GetColumn(2)); Vector3 val4 = Vector4.op_Implicit(((Matrix4x4)(ref val2)).GetColumn(1)); if (!(((Vector3)(ref val3)).sqrMagnitude < 0.0001f) && !(((Vector3)(ref val4)).sqrMagnitude < 0.0001f)) { restToRoot = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, ((Vector3)(ref val4)).normalized); return true; } } } } return false; } private static float MeasureRestPitchDegrees(Quaternion restToRoot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_001d: 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_002e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = restToRoot * Vector3.forward; Vector2 val2 = new Vector2(val.x, val.z); float magnitude = ((Vector2)(ref val2)).magnitude; if (magnitude <= 0.0001f) { if (!(val.y > 0f)) { return 90f; } return -90f; } return (0f - Mathf.Atan2(val.y, magnitude)) * 57.29578f; } private bool ApplyGazeBoneRotation(Transform bone, Quaternion restToRoot, float yawDegrees, float pitchDegrees, float rollDegrees, float authority) { //IL_0022: 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_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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bone == (Object)null || authority <= 0.001f || !_hasHeadChainRestPose) { return false; } Quaternion val = ((Component)this).transform.rotation * restToRoot; Quaternion val2 = Quaternion.AngleAxis(yawDegrees, ((Component)this).transform.up) * Quaternion.AngleAxis(pitchDegrees, ((Component)this).transform.right) * Quaternion.AngleAxis(rollDegrees, ((Component)this).transform.forward) * val; bone.rotation = Quaternion.Slerp(bone.rotation, val2, Mathf.Clamp01(authority)); return true; } private bool ApplyAdditiveBoneAim(Transform bone, float yawDegrees, float pitchDegrees) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bone == (Object)null) { return false; } if (Mathf.Abs(yawDegrees) <= 0.35f && Mathf.Abs(pitchDegrees) <= 0.35f) { return false; } Quaternion val = Quaternion.AngleAxis(yawDegrees, ((Component)this).transform.up) * Quaternion.AngleAxis(pitchDegrees, ((Component)this).transform.right); bone.rotation = val * bone.rotation; return true; } private Vector3 BuildHeadAimDirection(float yawDegrees, float pitchDegrees) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_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_0023: 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_0038: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.Euler(pitchDegrees, yawDegrees, 0f); Vector3 val2 = ((Component)this).transform.TransformDirection(val * Vector3.forward); if (((Vector3)(ref val2)).sqrMagnitude < 0.001f) { return ((Component)this).transform.forward; } return ((Vector3)(ref val2)).normalized; } private float CalculateHeadYawToPoint(Vector3 focusPoint) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //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) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) Vector3 headTrackingOrigin = GetHeadTrackingOrigin(); Vector3 val = focusPoint - headTrackingOrigin; if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { return 0f; } Vector3 val2 = ((Component)this).transform.InverseTransformDirection(((Vector3)(ref val)).normalized); val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.001f) { return 0f; } ((Vector3)(ref val2)).Normalize(); return Mathf.Atan2(val2.x, val2.z) * 57.29578f; } private float CalculateHeadPitchToPoint(Vector3 focusPoint) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //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) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_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_0075: 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) Vector3 headTrackingOrigin = GetHeadTrackingOrigin(); Vector3 val = focusPoint - headTrackingOrigin; if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { return 0f; } Vector3 val2 = ((Component)this).transform.InverseTransformDirection(((Vector3)(ref val)).normalized); Vector2 val3 = new Vector2(val2.x, val2.z); float magnitude = ((Vector2)(ref val3)).magnitude; if (magnitude <= 0.001f) { if (!(val2.y > 0f)) { return EffectiveHeadPitchLimitDegrees; } return 0f - EffectiveHeadPitchLimitDegrees; } return (0f - Mathf.Atan2(val2.y, magnitude)) * 57.29578f; } private void TrackStandingHeadHeight() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_headBone == (Object)null || _isNeckSlashing || _doorwayDuckPitchDegrees > 0.5f) { return; } float num = _headBone.position.y - ((Component)this).transform.position.y; if (!(num <= 0.2f) && !(num > 6f)) { if (!_hasStandingHeadHeight || _standingHeadHeightIsBoundsSeed) { _standingHeadHeight = num; _hasStandingHeadHeight = true; _standingHeadHeightIsBoundsSeed = false; } else { _standingHeadHeight = Mathf.Max(num, _standingHeadHeight - 0.15f * Time.deltaTime); } } } private void SeedStandingHeadHeightFromBounds() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (_hasStandingHeadHeight) { return; } Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); float num = float.MinValue; foreach (Renderer val in componentsInChildren) { if (RendererShouldCountForGrounding(val)) { float num2 = num; Bounds bounds = val.bounds; num = Mathf.Max(num2, ((Bounds)(ref bounds)).max.y); } } if (num <= float.MinValue) { return; } float num3 = num - ((Component)this).transform.position.y - 0.1f; if (!(num3 <= 0.5f) && !(num3 > 6f)) { _standingHeadHeight = num3; _hasStandingHeadHeight = true; _standingHeadHeightIsBoundsSeed = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)($"[CreepyDollAI][head] standing height seeded from bounds: {num3:0.00} m " + "(provisional: replaced by the first measured head-bone sample).")); } } } private bool TryGetIdleExamineBeat(out float yawDegrees, out float pitchDegrees, out float rollDegrees, out float speedDegreesPerSecond) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) yawDegrees = 0f; pitchDegrees = 0f; rollDegrees = 0f; speedDegreesPerSecond = IdleScanSpeedDegreesPerSecond; if (!IdleExamineEnabled || !HeadTrackingEnabled || base.isEnemyDead || StaticVisualTestMode || _isNeckSlashing || _doorwayDuckPitchDegrees > 8f) { _idleScanActive = false; return false; } double num; if (!((Object)(object)((NetworkBehaviour)this).NetworkManager != (Object)null)) { num = Time.timeAsDouble; } else { NetworkTime serverTime = ((NetworkBehaviour)this).NetworkManager.ServerTime; num = ((NetworkTime)(ref serverTime)).Time; } double serverTime2 = num; bool flag = ((NetworkBehaviour)this).IsServer && _encounterState == EncounterState.Search; ResolveIdleExamineBeat(serverTime2, flag ? 0.5f : 1f); bool flag2 = DeterministicUnit(_idleScanBeatIndex, 4) < IdleScanGlanceChance; yawDegrees = Mathf.Lerp(0f - IdleScanYawRangeDegrees, IdleScanYawRangeDegrees, DeterministicUnit(_idleScanBeatIndex, 1)); pitchDegrees = Mathf.Lerp(0f - IdleScanPitchRangeDegrees, 4f, DeterministicUnit(_idleScanBeatIndex, 2)); rollDegrees = Mathf.Lerp(0f - IdleScanRollDegrees, IdleScanRollDegrees, DeterministicUnit(_idleScanBeatIndex, 3)); speedDegreesPerSecond = (flag2 ? HeadSnapSpeed : IdleScanSpeedDegreesPerSecond); if (flag) { speedDegreesPerSecond *= 2f; } if (!_idleScanActive) { _idleScanActive = true; LogHeadStateEvent($"scan begin: index={_idleScanBeatIndex}, yaw={yawDegrees:0} deg, pitch={pitchDegrees:0} deg, " + string.Format("roll={0:0} deg, {1}.", rollDegrees, flag2 ? "glance" : "sweep")); } return true; } private void ResolveIdleExamineBeat(double serverTime, float holdScale) { long num = (long)Math.Floor(serverTime / 60.0); double num2 = (double)num * 60.0; double num3 = num2 + 60.0; if (!_hasIdleScanCursor || _idleScanCell != num || !Mathf.Approximately(_idleScanHoldScale, holdScale) || !(serverTime >= _idleScanBeatStartTime)) { _hasIdleScanCursor = true; _idleScanHoldScale = holdScale; _idleScanCell = num; _idleScanBeatStep = 0L; _idleScanBeatIndex = num * 128; _idleScanBeatStartTime = num2; _idleScanBeatEndTime = Math.Min(num3, num2 + (double)ResolveIdleExamineBeatDuration(_idleScanBeatIndex, holdScale)); } while (serverTime >= _idleScanBeatEndTime && _idleScanBeatEndTime < num3 && _idleScanBeatStep < 127) { _idleScanBeatStep++; _idleScanBeatIndex = num * 128 + _idleScanBeatStep; _idleScanBeatStartTime = _idleScanBeatEndTime; _idleScanBeatEndTime = Math.Min(num3, _idleScanBeatStartTime + (double)ResolveIdleExamineBeatDuration(_idleScanBeatIndex, holdScale)); if (DebugLogs) { LogHeadStateEvent($"scan beat: index={_idleScanBeatIndex}, hold={ResolveIdleExamineBeatDuration(_idleScanBeatIndex, holdScale):0.00} s."); } } } private float ResolveIdleExamineBeatDuration(long beatIndex, float holdScale) { float num = DeterministicUnit(beatIndex, 0); float num2 = ((DeterministicUnit(beatIndex, 4) < IdleScanGlanceChance) ? Mathf.Lerp(0.6f, 1.2f, num) : Mathf.Lerp(IdleScanHoldMinSeconds, IdleScanHoldMaxSeconds, num)); return Mathf.Max(0.15f, num2 * Mathf.Clamp(holdScale, 0.1f, 1f)); } private float DeterministicUnit(long beatIndex, int channel) { long num = ((long)(((NetworkBehaviour)this).IsSpawned ? ((NetworkBehaviour)this).NetworkObjectId : 1) * -7046029254386353131L) ^ (beatIndex * 656542357) ^ ((channel + 1) * 374761393); long num2 = (num ^ (num >>> 33)) * -49064778989728563L; long num3 = (num2 ^ (num2 >>> 33)) * -4265267296055464877L; return (float)((double)((ulong)(num3 ^ (num3 >>> 33)) >> 40) / 16777216.0); } private void TickServerBodyFollowHeadFocus() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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) if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead || _isNeckSlashing || AgentDrivesBodyRotation() || (_serverObservationFromNoise && !_serverSpotConfirmed && _serverEntrancedClientId == ulong.MaxValue) || !TryGetActiveHeadFocus(out var focusPoint)) { return; } PlayerControllerB val = ResolveServerEntrancedPlayer(); if ((Object)(object)val == (Object)null && ServerHasActiveObservationTarget()) { val = FindPlayerByClientId(_serverObservationClientId); } if ((Object)(object)val == (Object)null || Time.time < _headBodyFollowAllowedTime) { return; } if ((Object)(object)val == (Object)(object)ResolveServerEntrancedPlayer() || !_serverObservationFromNoise) { focusPoint = GetPlayerFocusPoint(val); } Vector3 val2 = focusPoint - ((Component)this).transform.position; val2.y = 0f; if (!(((Vector3)(ref val2)).sqrMagnitude < 0.001f)) { Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up); float num = Quaternion.Angle(((Component)this).transform.rotation, val3); ulong actualClientId = val.actualClientId; if (!_serverBodyTurnInProgress && num > 15f) { _serverBodyTurnInProgress = true; LogHeadStateEvent($"body turn begin: player={actualClientId}, " + $"remaining={num:0} deg at {HeadBodyFollowSpeed:0} deg/s " + $"(~{num / Mathf.Max(1f, HeadBodyFollowSpeed):0.0} s)."); } else if (_serverBodyTurnInProgress && num <= 5f) { _serverBodyTurnInProgress = false; LogHeadStateEvent($"body turn complete: player={actualClientId}, remaining={num:0} deg."); } ((Component)this).transform.rotation = Quaternion.RotateTowards(((Component)this).transform.rotation, val3, HeadBodyFollowSpeed * Time.deltaTime); } } private void SetHeadFocus(Vector3 focusPoint, float duration, bool fromNoise, bool forceSnap = false) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) bool flag = HasActiveHeadFocus(); bool flag2 = _headFocusFromNoise != fromNoise; bool flag3 = Mathf.Abs(Mathf.Clamp(CalculateHeadYawToPoint(focusPoint), 0f - HeadYawLimitDegrees, HeadYawLimitDegrees) - _headAimYawDegrees) >= 18f; _headFocusPoint = focusPoint; _headFocusUntilTime = Time.time + Mathf.Max(0.05f, duration); _headFocusFromNoise = fromNoise; if (forceSnap || !flag || flag2 || flag3) { _headSnapUntilTime = Time.time + 0.35f; } if (((NetworkBehaviour)this).IsServer && _serverEntrancedClientId != ulong.MaxValue) { _headBodyFollowAllowedTime = Time.time; } else if (!flag || flag2) { _headBodyFollowAllowedTime = Time.time + Mathf.Max(0f, HeadBodyFollowDelay); } } private void ClearHeadFocus(bool syncClients) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) bool num = _headFocusUntilTime > 0f; _headFocusPoint = Vector3.zero; _headFocusUntilTime = 0f; _headFocusFromNoise = false; if (num && syncClients && ((NetworkBehaviour)this).IsServer) { ClearHeadFocusClientRpc(); } } private bool TryGetActiveHeadFocus(out Vector3 focusPoint) { //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_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) if (Time.time <= _headFocusUntilTime) { focusPoint = _headFocusPoint; return true; } focusPoint = Vector3.zero; return false; } private bool HasActiveHeadFocus() { return Time.time <= _headFocusUntilTime; } private PlayerControllerB FindHeadTrackingDetectionCandidate(out bool fromNoise, out string source) { fromNoise = false; source = "sight"; if (_serverObservationClientId != ulong.MaxValue && !_serverObservationFromNoise) { PlayerControllerB val = FindPlayerByClientId(_serverObservationClientId); if (PlayerCanBeHeadTracked(val) && ((EnemyAI)this).PlayerIsTargetable(val, true, false, true) && PlayerIsWithinSightRange(val) && HasClearLineOfSightToPlayerFace(val)) { return val; } } PlayerControllerB val2 = ((EnemyAI)this).CheckLineOfSightForPlayer(HeadVisionConeDegrees, Mathf.RoundToInt(HeadSightRange), Mathf.RoundToInt(HeadProximityAwareness)); if (PlayerCanBeHeadTracked(val2) && ((EnemyAI)this).PlayerIsTargetable(val2, true, false, true)) { return val2; } PlayerControllerB val3 = FindNearestPlayerWithinRearAwareness(); if ((Object)(object)val3 != (Object)null) { source = "proximity"; return val3; } PlayerControllerB val4 = FindNearestSpeakingPlayer(); if ((Object)(object)val4 == (Object)null) { return null; } fromNoise = true; source = "voice"; return val4; } private PlayerControllerB FindNearestPlayerWithinRearAwareness() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return null; } PlayerControllerB result = null; float num = HeadRearAwarenessRange * HeadRearAwarenessRange; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (PlayerCanBeHeadTracked(val) && ((EnemyAI)this).PlayerIsTargetable(val, true, false, true)) { Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (!(sqrMagnitude > num) && HasClearLineOfSightToPlayerFace(val)) { num = sqrMagnitude; result = val; } } } return result; } private bool PlayerIsWithinSightRange(PlayerControllerB player) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)null) { Vector3 val = ((Component)player).transform.position - ((Component)this).transform.position; return ((Vector3)(ref val)).sqrMagnitude <= HeadSightRange * HeadSightRange; } return false; } private bool HasClearLineOfSightToPlayerFace(PlayerControllerB player, bool allowBodyPoints = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3 playerFocusPoint = GetPlayerFocusPoint(player); if (HasClearLineOfSightFromPoint(GetFacePoint(), playerFocusPoint, player)) { return true; } if (allowBodyPoints) { return HasClearLineOfSightFromPoint(((Component)this).transform.position + Vector3.up * 2f, playerFocusPoint, player); } return false; } private bool HasClearLineOfSightFromPoint(Vector3 origin, Vector3 focusPoint, PlayerControllerB player) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = focusPoint - origin; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.05f) { return true; } return HasClearLineOfSight(origin, val / magnitude, magnitude, ((Component)player).transform); } private PlayerControllerB FindNearestSpeakingPlayer() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return null; } if (Time.time < _nextVoiceAcceptTime) { return null; } PlayerControllerB val = null; float num = HeadHearingRange * HeadHearingRange; float num2 = HeadHearingRange * 0.5f; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val2 in allPlayerScripts) { if (PlayerCanBeHeadTracked(val2) && ((EnemyAI)this).PlayerIsTargetable(val2, true, false, true)) { Vector3 val3 = ((Component)val2).transform.position - ((Component)this).transform.position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (!(sqrMagnitude > num) && PlayerIsAudiblySpeaking(val2) && (!(sqrMagnitude > num2 * num2) || HasClearLineOfSightToPlayerFace(val2))) { num = sqrMagnitude; val = val2; } } } if ((Object)(object)val != (Object)null) { _nextVoiceAcceptTime = Time.time + 1.75f; } return val; } private Vector3 GetDollGazeForward() { //IL_002b: 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) if (((Vector3)(ref _headAimWorldDirection)).sqrMagnitude > 0.001f) { return ((Vector3)(ref _headAimWorldDirection)).normalized; } return BuildHeadAimDirection(_headAimYawDegrees, _headAimPitchDegrees); } private Vector3 GetHeadTrackingOrigin() { //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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) float num = (_hasStandingHeadHeight ? _standingHeadHeight : 1.45f); return ((Component)this).transform.position + Vector3.up * num; } private Vector3 GetFacePoint() { //IL_002f: 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 ((Object)(object)_headBone == (Object)null) { ResolveHeadTrackingReferences(); } if ((Object)(object)_headBone != (Object)null) { return _headBone.position; } return GetHeadTrackingOrigin(); } private void UpdateEyeTransform() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //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_004e: 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) if (!((Object)(object)base.eye == (Object)null) && !base.isEnemyDead) { base.eye.position = GetHeadTrackingOrigin() + ((Component)this).transform.forward * 0.18f; base.eye.rotation = ((Component)this).transform.rotation; if (!_loggedEyeOrigin && _hasStandingHeadHeight) { _loggedEyeOrigin = true; LogHeadStateEvent($"eye origin: y={base.eye.localPosition.y:0.00} m above the root, " + $"standingHeadHeight={_standingHeadHeight:0.00} m. " + "Below ~1.5 means the knee-height marker of #96 is still in play."); } } } private static Vector3 GetPlayerFocusPoint(PlayerControllerB player) { //IL_0009: 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_0039: 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_0028: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return Vector3.zero; } if ((Object)(object)player.gameplayCamera != (Object)null) { return ((Component)player.gameplayCamera).transform.position; } return ((Component)player).transform.position + Vector3.up * 1.15f; } private static bool PlayerCanBeHeadTracked(PlayerControllerB player) { if ((Object)(object)player != (Object)null && player.isPlayerControlled) { return !player.isPlayerDead; } return false; } private static bool PlayerIsAudiblySpeaking(PlayerControllerB player) { if (!PlayerCanBeHeadTracked(player)) { return false; } if (player.speakingToWalkieTalkie) { return true; } if (TryGetPlayerVoiceAmplitude(player, out var amplitude)) { return amplitude >= 0.02f; } if (TryReadVoiceBool(GetPlayerVoiceState(player), VoiceSpeakingMemberNames, out var value) && value) { return true; } AudioSource val = player.currentVoiceChatAudioSource; if ((Object)(object)val == (Object)null && (Object)(object)player.currentVoiceChatIngameSettings != (Object)null) { val = player.currentVoiceChatIngameSettings.voiceAudio; } return TryMeasureVoiceOutput(val) >= 0.02f; } private static float TryMeasureVoiceOutput(AudioSource voiceAudio) { if ((Object)(object)voiceAudio == (Object)null || !voiceAudio.isPlaying || voiceAudio.mute || voiceAudio.volume <= 0.001f) { return 0f; } try { voiceAudio.GetOutputData(VoiceOutputSamples, 0); float num = 0f; for (int i = 0; i < VoiceOutputSamples.Length; i++) { num = Mathf.Max(num, Mathf.Abs(VoiceOutputSamples[i])); } return num * voiceAudio.volume; } catch { return 0f; } } private static bool TryGetPlayerVoiceAmplitude(PlayerControllerB player, out float amplitude) { if (TryReadVoiceFloat(GetPlayerVoiceState(player), VoiceAmplitudeMemberNames, out amplitude)) { amplitude = Mathf.Max(0f, amplitude); return true; } try { if ((Object)(object)player != (Object)null && (Object)(object)player.currentVoiceChatIngameSettings != (Object)null && TryReadVoiceFloat(((object)player.currentVoiceChatIngameSettings).GetType().GetField("_playerState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player.currentVoiceChatIngameSettings), VoiceAmplitudeMemberNames, out amplitude)) { amplitude = Mathf.Max(0f, amplitude); return true; } } catch { } amplitude = 0f; return false; } private static object GetPlayerVoiceState(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return null; } try { _voicePlayerStateField = _voicePlayerStateField ?? typeof(PlayerControllerB).GetField("voicePlayerState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return _voicePlayerStateField?.GetValue(player); } catch { return null; } } private static bool TryReadVoiceBool(object state, string[] memberNames, out bool value) { value = false; if (state == null || memberNames == null) { return false; } Type type = state.GetType(); foreach (string name in memberNames) { PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(bool)) { value = (bool)property.GetValue(state); return true; } FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(bool)) { value = (bool)field.GetValue(state); return true; } } return false; } private static bool TryReadVoiceFloat(object state, string[] memberNames, out float value) { value = 0f; if (state == null || memberNames == null) { return false; } Type type = state.GetType(); foreach (string name in memberNames) { PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && TryConvertToFloat(property.GetValue(state), out value)) { return true; } FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && TryConvertToFloat(field.GetValue(state), out value)) { return true; } } return false; } private static bool TryConvertToFloat(object raw, out float value) { value = 0f; if (raw == null) { return false; } if (raw is float num) { value = num; return true; } if (raw is double num2) { value = (float)num2; return true; } if (raw is int num3) { value = num3; return true; } return false; } private bool HasClearLineOfSight(Vector3 origin, Vector3 direction, float distance, Transform ignoredPlayerRoot) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) int num = ResolveLineOfSightMask(); int num2 = Physics.RaycastNonAlloc(origin, direction, _lineOfSightHits, Mathf.Max(0.05f, distance - 0.08f), num, (QueryTriggerInteraction)1); if (num2 > 1) { Array.Sort(_lineOfSightHits, 0, num2, RaycastHitDistanceComparer.Instance); } for (int i = 0; i < num2; i++) { Collider collider = ((RaycastHit)(ref _lineOfSightHits[i])).collider; if (!((Object)(object)collider == (Object)null)) { Transform transform = ((Component)collider).transform; if (!transform.IsChildOf(((Component)this).transform) && (!((Object)(object)ignoredPlayerRoot != (Object)null) || !transform.IsChildOf(ignoredPlayerRoot))) { return false; } } } return true; } private PlayerControllerB FindPlayerNearPosition(Vector3 position, float radius) { //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_005a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return null; } PlayerControllerB result = null; float num = radius * radius; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!((Object)(object)val == (Object)null) && !val.isPlayerDead) { Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude <= num) { num = sqrMagnitude; result = val; } } } return result; } private int ResolveLineOfSightMask() { if ((Object)(object)StartOfRound.Instance != (Object)null) { return StartOfRound.Instance.collidersAndRoomMaskAndDefault; } return -1; } private Vector3 GetLookTargetPoint() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) ResolveHeadTrackingReferences(); if ((Object)(object)_headBone != (Object)null) { return _headBone.position; } return GetHeadTrackingOrigin(); } private void StabilizeVisualRootOnGround() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.StabilizeVisualRoot || StaticVisualTestMode) { return; } if ((Object)(object)_visualRoot == (Object)null) { _visualRoot = ((Component)this).transform.Find("VisualRoot"); } if (!((Object)(object)_visualRoot == (Object)null) && TryGetVisualBottomY(out var bottomY) && TryResolveGroundYUnderDoll(out var groundY)) { float num = groundY + Plugin.VisualGroundOffset - bottomY; if (!float.IsNaN(num) && !(Mathf.Abs(num) > 1.75f)) { Vector3 localPosition = _visualRoot.localPosition; float num2 = Mathf.Clamp(localPosition.y + num, -2.25f, 0.5f); float num3 = 1f - Mathf.Exp(-14f * Time.deltaTime); localPosition.y = Mathf.Lerp(localPosition.y, num2, num3); _visualRoot.localPosition = localPosition; } } } private bool TryGetVisualBottomY(out float bottomY) { if (TryGetFootSoleY(out bottomY)) { return true; } return TryGetRendererVisualBottomY(out bottomY); } private bool TryGetFootSoleY(out float bottomY) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) ResolveFootReferences(); if (!_contactFootstepClockActive) { CalibrateFootSoleOffset(_leftFootBone, ref _leftFootSoleOffset); CalibrateFootSoleOffset(_rightFootBone, ref _rightFootSoleOffset); } bottomY = float.MaxValue; bool flag = false; if ((Object)(object)_leftFootBone != (Object)null) { bottomY = Mathf.Min(bottomY, _leftFootBone.position.y - ResolveFootSoleOffset(_leftFootSoleOffset)); flag = true; } if ((Object)(object)_rightFootBone != (Object)null) { bottomY = Mathf.Min(bottomY, _rightFootBone.position.y - ResolveFootSoleOffset(_rightFootSoleOffset)); flag = true; } if (flag) { return !float.IsInfinity(bottomY); } return false; } private static float ResolveFootSoleOffset(float learnedSoleOffset) { if (!(learnedSoleOffset >= 0f)) { return 0.18f; } return learnedSoleOffset; } private bool TryGetRendererVisualBottomY(out float bottomY) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) bottomY = float.MaxValue; bool result = false; Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if (RendererShouldCountForGrounding(val)) { float num = bottomY; Bounds bounds = val.bounds; bottomY = Mathf.Min(num, ((Bounds)(ref bounds)).min.y); result = true; } } return result; } private bool TryResolveGroundYUnderDoll(out float groundY) { //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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position; if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { val = base.agent.nextPosition; } RaycastHit[] array = Physics.RaycastAll(val + Vector3.up * 1.4f, Vector3.down, 4.4f, ResolveLineOfSightMask(), (QueryTriggerInteraction)1); float num = float.MaxValue; groundY = val.y; bool flag = false; for (int i = 0; i < array.Length; i++) { RaycastHit val2 = array[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(((Component)this).transform) && ((RaycastHit)(ref val2)).distance < num) { num = ((RaycastHit)(ref val2)).distance; groundY = ((RaycastHit)(ref val2)).point.y; flag = true; } } if (flag) { return true; } NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(val, ref val3, 2f, -1)) { groundY = ((NavMeshHit)(ref val3)).position.y; return true; } groundY = ((Component)this).transform.position.y; return true; } private static bool RendererShouldCountForGrounding(Renderer renderer) { if ((Object)(object)renderer != (Object)null && renderer.enabled && ((Component)renderer).gameObject.activeInHierarchy) { return (Object)(object)((Component)renderer).GetComponentInParent() == (Object)null; } return false; } private void TickServerHeadPosture() { if (!((NetworkBehaviour)this).IsServer) { return; } float num = 0f; float peekYawDegrees = 0f; float peekRollDegrees = 0f; if (StaticVisualTestMode || base.isEnemyDead) { _serverDuckActive = false; _serverPeekActive = false; _serverSprintLungeActive = false; WriteHeadPosture(0f, 0f, 0f); } else { if (Time.time < _nextHeadPostureMeasureTime) { return; } _nextHeadPostureMeasureTime = Time.time + 0.2f; if (DoorwayDuckEnabled && DollIsTravelling() && TryMeasureDoorwayDuck(out var duckDegrees, out var apertureHeight, out var neededDrop)) { num = duckDegrees; if (!_serverDuckActive) { _serverDuckActive = true; LogHeadStateEvent($"duck begin: aperture={apertureHeight:0.00} m, standing={_standingHeadHeight:0.00} m, " + $"needed={neededDrop:0.00} m, angle={num:0.0}/{DoorwayDuckAngleDegrees:0} deg."); } } else if (_serverDuckActive) { _serverDuckActive = false; LogHeadStateEvent("duck end: opening cleared, head returns to level."); } if (TryMeasureDoorwayPeek(out peekYawDegrees, out peekRollDegrees, out var turnDegrees)) { if (!_serverPeekActive) { _serverPeekActive = true; LogHeadStateEvent(string.Format("peek begin: turn={0:0} deg, side={1}, ", turnDegrees, (peekYawDegrees >= 0f) ? "right" : "left") + $"yaw={peekYawDegrees:0} deg, roll={peekRollDegrees:0} deg."); } } else if (_serverPeekActive) { _serverPeekActive = false; LogHeadStateEvent("peek end: corner passed."); } if (ServerSprintActive) { num = Mathf.Max(num, 22f); if (!_serverSprintLungeActive) { _serverSprintLungeActive = true; LogHeadStateEvent($"sprint lunge begin: fold={num:0.0} deg " + "(doorway duck=" + (_serverDuckActive ? "active" : "none") + ")."); } } else if (_serverSprintLungeActive) { _serverSprintLungeActive = false; LogHeadStateEvent("sprint lunge end: burst over, posture returns to walk."); } WriteHeadPosture(num, peekYawDegrees, peekRollDegrees); } } private void WriteHeadPosture(float duckDegrees, float peekYawDegrees, float peekRollDegrees) { _networkDuckDegrees.Value = QuantizePostureDegrees(duckDegrees); _networkPeekYawDegrees.Value = QuantizePostureDegrees(peekYawDegrees); _networkPeekRollDegrees.Value = QuantizePostureDegrees(peekRollDegrees); } private void TickHeadPostureSmoothing() { if (StaticVisualTestMode || base.isEnemyDead) { _doorwayDuckPitchDegrees = 0f; _headPeekYawDegrees = 0f; _headPeekRollDegrees = 0f; return; } float num = (DoorwayDuckEnabled ? _networkDuckDegrees.Value : 0f); float num2 = (DoorwayPeekEnabled ? _networkPeekYawDegrees.Value : 0f); float num3 = (DoorwayPeekEnabled ? _networkPeekRollDegrees.Value : 0f); float num4 = 190f * Time.deltaTime; float num5 = 70f * Time.deltaTime; _doorwayDuckPitchDegrees = Mathf.MoveTowards(_doorwayDuckPitchDegrees, num, num4); _headPeekYawDegrees = Mathf.MoveTowards(_headPeekYawDegrees, num2, num5); _headPeekRollDegrees = Mathf.MoveTowards(_headPeekRollDegrees, num3, num5); } private static float QuantizePostureDegrees(float degrees) { return Mathf.Round(degrees / 1.5f) * 1.5f; } private bool DollIsTravelling() { //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) if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh && !base.agent.isStopped) { Vector3 desiredVelocity = base.agent.desiredVelocity; if (((Vector3)(ref desiredVelocity)).sqrMagnitude > 0.0036f) { return true; } } return _smoothedLocomotionSpeed > 0.06f; } private bool TryMeasureDoorwayDuck(out float duckDegrees, out float apertureHeight, out float neededDrop) { //IL_002f: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_005b: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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) //IL_0120: 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_013c: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) duckDegrees = 0f; apertureHeight = 0f; neededDrop = 0f; if (!_hasStandingHeadHeight || !TryGetDoorwayClearanceDirection(out var direction)) { return false; } Vector3 val = ((Component)this).transform.position + Vector3.up * (_standingHeadHeight - 0.05f); Vector3 val2 = Vector3.Cross(Vector3.up, direction); if (((Vector3)(ref val2)).sqrMagnitude < 0.001f) { val2 = ((Component)this).transform.right; } ((Vector3)(ref val2)).Normalize(); float num = Mathf.Max(0.12f, (((Object)(object)base.agent != (Object)null) ? base.agent.radius : 0.5f) * 0.55f); RaycastHit hit = default(RaycastHit); bool flag = false; for (int i = -1; i <= 1; i++) { Vector3 origin = val + val2 * num * (float)i; if (DoorwayProbeHitsBlockingGeometry(origin, direction, DoorwayDuckProbeDistance, out hit)) { flag = true; break; } } if (!flag) { return false; } Vector3 origin2 = ((Component)this).transform.position + Vector3.up * 0.95f; if (DoorwayProbeHitsBlockingGeometry(origin2, direction, DoorwayDuckProbeDistance * 1.1f, out var _)) { return false; } RaycastHit val3 = default(RaycastHit); if (!Physics.Raycast(new Vector3(((RaycastHit)(ref hit)).point.x, ((Component)this).transform.position.y + 0.95f, ((RaycastHit)(ref hit)).point.z) + direction * 0.21f, Vector3.up, ref val3, _standingHeadHeight + 1.5f, ResolveLineOfSightMask(), (QueryTriggerInteraction)1)) { return false; } if ((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null || ((Component)((RaycastHit)(ref val3)).collider).transform.IsChildOf(((Component)this).transform) || ((RaycastHit)(ref val3)).distance <= 0.0001f) { return false; } apertureHeight = ((RaycastHit)(ref val3)).point.y - ((Component)this).transform.position.y; if (apertureHeight <= 1.25f) { return false; } neededDrop = _standingHeadHeight + DoorwayDuckClearanceMargin - apertureHeight; if (neededDrop <= 0f) { return false; } duckDegrees = Mathf.Clamp(neededDrop * DoorwayDuckDegreesPerMeter, 0f, DoorwayDuckAngleDegrees); return duckDegrees > 0.5f; } private bool TryMeasureDoorwayPeek(out float peekYawDegrees, out float peekRollDegrees, out float turnDegrees) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_009a: 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) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) peekYawDegrees = 0f; peekRollDegrees = 0f; turnDegrees = 0f; if (!DoorwayPeekEnabled || !DollIsTravelling() || (Object)(object)base.agent == (Object)null || !((Behaviour)base.agent).enabled || !base.agent.isOnNavMesh || !base.agent.hasPath) { return false; } NavMeshPath path = base.agent.path; if (path == null || path.GetCornersNonAlloc(_pathCornerBuffer) < 3) { return false; } Vector3 val = _pathCornerBuffer[1]; Vector3 val2 = val - ((Component)this).transform.position; val2.y = 0f; if (((Vector3)(ref val2)).magnitude > DoorwayPeekLookaheadDistance || ((Vector3)(ref val2)).sqrMagnitude < 0.01f) { return false; } Vector3 val3 = _pathCornerBuffer[2] - val; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { return false; } turnDegrees = Vector3.SignedAngle(((Vector3)(ref val2)).normalized, ((Vector3)(ref val3)).normalized, Vector3.up); if (Mathf.Abs(turnDegrees) < DoorwayPeekMinimumTurnDegrees) { return false; } Vector3 origin = val + Vector3.up * Mathf.Max(0.6f, _standingHeadHeight * 0.6f); if (!DoorwayProbeHitsBlockingGeometry(origin, ((Vector3)(ref val2)).normalized, DoorwayPeekLookaheadDistance * 0.5f, out var _)) { return false; } float num = Mathf.Sign(turnDegrees); peekYawDegrees = num * Mathf.Min(DoorwayPeekYawDegrees, HeadYawLimitDegrees); peekRollDegrees = (0f - num) * Mathf.Min(DoorwayPeekRollDegrees, HeadRollLimitDegrees); return true; } private bool TryGetDoorwayClearanceDirection(out Vector3 direction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) direction = Vector3.zero; if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { Vector3 val = base.agent.desiredVelocity; if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { direction = base.agent.desiredVelocity; } else if (base.agent.hasPath) { direction = base.agent.steeringTarget - ((Component)this).transform.position; } else { val = base.agent.velocity; if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { direction = base.agent.velocity; } } } direction.y = 0f; if (((Vector3)(ref direction)).sqrMagnitude < 0.001f && base.movingTowardsTargetPlayer && (Object)(object)base.targetPlayer != (Object)null) { direction = ((Component)base.targetPlayer).transform.position - ((Component)this).transform.position; } direction.y = 0f; if (((Vector3)(ref direction)).sqrMagnitude < 0.001f) { direction = ((Component)this).transform.forward; } direction.y = 0f; if (((Vector3)(ref direction)).sqrMagnitude < 0.001f) { return false; } ((Vector3)(ref direction)).Normalize(); return true; } private bool DoorwayProbeHitsBlockingGeometry(Vector3 origin, Vector3 direction, float distance, out RaycastHit hit) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!Physics.SphereCast(origin, 0.13f, direction, ref hit, distance, ResolveLineOfSightMask(), (QueryTriggerInteraction)1)) { return false; } if (((RaycastHit)(ref hit)).distance <= 0.0001f) { return false; } if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)null || ((Component)((RaycastHit)(ref hit)).collider).transform.IsChildOf(((Component)this).transform)) { return false; } if ((Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent() != (Object)null) { return false; } return true; } private PlayerControllerB FindPlayerByClientId(ulong clientId) { if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return null; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!((Object)(object)val == (Object)null) && PlayerMatchesClientId(val, clientId)) { return val; } } return null; } private static bool PlayerMatchesClientId(PlayerControllerB player, ulong clientId) { if ((Object)(object)player != (Object)null) { if (player.actualClientId != clientId) { return player.playerClientId == clientId; } return true; } return false; } private PlayerControllerB ResolveLocalPlayer() { if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) { return GameNetworkManager.Instance.localPlayerController; } return ResolveReferencePlayer(); } private void ResolveRuntimeReferences() { if ((Object)(object)base.agent == (Object)null) { base.agent = ((Component)this).GetComponent(); if ((Object)(object)base.agent == (Object)null) { base.agent = ((Component)this).gameObject.AddComponent(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[CreepyDollAI] Instance was missing a root NavMeshAgent; added at runtime."); } } } if ((Object)(object)base.creatureAnimator == (Object)null) { base.creatureAnimator = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInChildren(true); } if ((Object)(object)base.creatureSFX == (Object)null) { Transform val = ((Component)this).transform.Find("CreatureSFX"); if ((Object)(object)val != (Object)null) { base.creatureSFX = ((Component)val).GetComponent(); } } if ((Object)(object)base.creatureVoice == (Object)null) { Transform val2 = ((Component)this).transform.Find("CreatureVoice"); if ((Object)(object)val2 != (Object)null) { base.creatureVoice = ((Component)val2).GetComponent(); } } if ((Object)(object)stepAudioSource == (Object)null) { Transform val3 = ((Component)this).transform.Find("StepSFX"); if ((Object)(object)val3 != (Object)null) { stepAudioSource = ((Component)val3).GetComponent(); } } if ((Object)(object)idleAudioSource == (Object)null) { Transform val4 = ((Component)this).transform.Find("IdleVoice"); if ((Object)(object)val4 != (Object)null) { idleAudioSource = ((Component)val4).GetComponent(); } } if ((Object)(object)constantAudioSource == (Object)null) { Transform val5 = ((Component)this).transform.Find("ConstantLoopSFX"); if ((Object)(object)val5 != (Object)null) { constantAudioSource = ((Component)val5).GetComponent(); } } if ((Object)(object)mindControlAudioSource == (Object)null) { Transform val6 = ((Component)this).transform.Find("MindControlSFX"); if ((Object)(object)val6 != (Object)null) { mindControlAudioSource = ((Component)val6).GetComponent(); } } if ((Object)(object)base.eye == (Object)null) { Transform val7 = ((Component)this).transform.Find("Eye"); if ((Object)(object)val7 != (Object)null) { base.eye = val7; } } if ((Object)(object)attackOrigin == (Object)null) { Transform val8 = ((Component)this).transform.Find("AttackOrigin"); if ((Object)(object)val8 != (Object)null) { attackOrigin = val8; } } EnsureIdleAudioSourceSettings(); ResolveHeadTrackingReferences(); ResolveFootReferences(); Plugin.RepairCollisionDetectMainScripts(((Component)this).gameObject, this); Plugin.DisablePhysicalVisualColliders(((Component)this).gameObject); } private void ResolveHeadTrackingReferences() { Transform visualSearchRoot = GetVisualSearchRoot(); if ((Object)(object)_headBone == (Object)null && (Object)(object)base.creatureAnimator != (Object)null && base.creatureAnimator.isHuman) { _headBone = base.creatureAnimator.GetBoneTransform((HumanBodyBones)10); } if ((Object)(object)_neckBone == (Object)null && (Object)(object)base.creatureAnimator != (Object)null && base.creatureAnimator.isHuman) { _neckBone = base.creatureAnimator.GetBoneTransform((HumanBodyBones)9); } if ((Object)(object)_headBone == (Object)null) { _headBone = FindDescendantByName(visualSearchRoot, "CC_Base_Head", "Bip001 Head", "Bip Head", "head", "Head") ?? FindDescendantByName(((Component)this).transform, "CC_Base_Head", "Bip001 Head", "Bip Head", "head", "Head") ?? FindDescendantByNamePart(visualSearchRoot, "head", "nub", "end", "target", "scan") ?? FindDescendantByNamePart(((Component)this).transform, "head", "nub", "end", "target", "scan"); } if ((Object)(object)_neckBone == (Object)null) { _neckBone = FindDescendantByName(visualSearchRoot, "CC_Base_NeckTwist01", "CC_Base_NeckTwist02", "Bip001 Neck", "Bip Neck", "neck_01", "Neck") ?? FindDescendantByName(((Component)this).transform, "CC_Base_NeckTwist01", "CC_Base_NeckTwist02", "Bip001 Neck", "Bip Neck", "neck_01", "Neck") ?? FindDescendantByNamePart(visualSearchRoot, "neck", "target", "scan") ?? FindDescendantByNamePart(((Component)this).transform, "neck", "target", "scan"); } if ((Object)(object)_lowerSpineBone == (Object)null) { _lowerSpineBone = FindDescendantByName(visualSearchRoot, "CC_Base_Spine01", "Bip001 Spine", "Bip Spine", "spine_01", "Spine") ?? FindDescendantByName(((Component)this).transform, "CC_Base_Spine01", "Bip001 Spine", "Bip Spine", "spine_01", "Spine"); } if ((Object)(object)_upperSpineBone == (Object)null) { _upperSpineBone = FindDescendantByName(visualSearchRoot, "CC_Base_Spine02", "Bip001 Spine1", "Bip Spine1", "spine_02", "Chest") ?? FindDescendantByName(((Component)this).transform, "CC_Base_Spine02", "Bip001 Spine1", "Bip Spine1", "spine_02", "Chest"); } if ((Object)(object)_rightClavicleBone == (Object)null && (Object)(object)base.creatureAnimator != (Object)null && base.creatureAnimator.isHuman) { _rightClavicleBone = base.creatureAnimator.GetBoneTransform((HumanBodyBones)12); } if ((Object)(object)_rightUpperArmBone == (Object)null && (Object)(object)base.creatureAnimator != (Object)null && base.creatureAnimator.isHuman) { _rightUpperArmBone = base.creatureAnimator.GetBoneTransform((HumanBodyBones)14); } if ((Object)(object)_rightForearmBone == (Object)null && (Object)(object)base.creatureAnimator != (Object)null && base.creatureAnimator.isHuman) { _rightForearmBone = base.creatureAnimator.GetBoneTransform((HumanBodyBones)16); } if ((Object)(object)_rightClavicleBone == (Object)null) { _rightClavicleBone = FindDescendantByName(visualSearchRoot, "CC_Base_R_Clavicle", "RightShoulder", "clavicle_r", "R_Clavicle") ?? FindDescendantByName(((Component)this).transform, "CC_Base_R_Clavicle", "RightShoulder", "clavicle_r", "R_Clavicle"); } if ((Object)(object)_rightUpperArmBone == (Object)null) { _rightUpperArmBone = FindDescendantByName(visualSearchRoot, "CC_Base_R_Upperarm", "RightArm", "upperarm_r", "R_UpperArm") ?? FindDescendantByName(((Component)this).transform, "CC_Base_R_Upperarm", "RightArm", "upperarm_r", "R_UpperArm"); } if ((Object)(object)_rightForearmBone == (Object)null) { _rightForearmBone = FindDescendantByName(visualSearchRoot, "CC_Base_R_Forearm", "RightForeArm", "lowerarm_r", "R_Forearm") ?? FindDescendantByName(((Component)this).transform, "CC_Base_R_Forearm", "RightForeArm", "lowerarm_r", "R_Forearm"); } } private Transform GetVisualSearchRoot() { if ((Object)(object)_visualRoot == (Object)null) { _visualRoot = ((Component)this).transform.Find("VisualRoot"); } if (!((Object)(object)_visualRoot != (Object)null)) { return ((Component)this).transform; } return _visualRoot; } private void ResolveFootReferences() { //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_leftFootBone == (Object)null && (Object)(object)base.creatureAnimator != (Object)null && base.creatureAnimator.isHuman) { _leftFootBone = base.creatureAnimator.GetBoneTransform((HumanBodyBones)5); } if ((Object)(object)_rightFootBone == (Object)null && (Object)(object)base.creatureAnimator != (Object)null && base.creatureAnimator.isHuman) { _rightFootBone = base.creatureAnimator.GetBoneTransform((HumanBodyBones)6); } if ((Object)(object)_leftFootBone == (Object)null) { _leftFootBone = FindDescendantByName(((Component)this).transform, "CC_Base_L_Foot", "LeftFoot", "foot_l", "L_Foot", "mixamorig:LeftFoot"); } if ((Object)(object)_rightFootBone == (Object)null) { _rightFootBone = FindDescendantByName(((Component)this).transform, "CC_Base_R_Foot", "RightFoot", "foot_r", "R_Foot", "mixamorig:RightFoot"); } if ((Object)(object)_leftFootBone != (Object)null && _leftFootPreviousPosition == Vector3.zero) { _leftFootPreviousPosition = _leftFootBone.position; } if ((Object)(object)_rightFootBone != (Object)null && _rightFootPreviousPosition == Vector3.zero) { _rightFootPreviousPosition = _rightFootBone.position; } } private static Transform FindDescendantByName(Transform root, params string[] names) { if ((Object)(object)root == (Object)null || names == null) { return null; } for (int i = 0; i < names.Length; i++) { Transform val = FindDescendantByName(root, names[i]); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static Transform FindDescendantByName(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return null; } if (string.Equals(((Object)root).name, name, StringComparison.OrdinalIgnoreCase)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindDescendantByName(root.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static Transform FindDescendantByNamePart(Transform root, string requiredPart, params string[] excludedParts) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(requiredPart)) { return null; } string text = NormalizeTransformName(((Object)root).name); string value = NormalizeTransformName(requiredPart); bool flag = text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0; if (flag && excludedParts != null) { for (int i = 0; i < excludedParts.Length; i++) { string value2 = NormalizeTransformName(excludedParts[i]); if (!string.IsNullOrEmpty(value2) && text.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0) { flag = false; break; } } } if (flag) { return root; } for (int j = 0; j < root.childCount; j++) { Transform val = FindDescendantByNamePart(root.GetChild(j), requiredPart, excludedParts); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static string NormalizeTransformName(string value) { if (!string.IsNullOrEmpty(value)) { return value.Replace(" ", string.Empty).Replace("_", string.Empty).Replace("-", string.Empty) .Replace(":", string.Empty); } return string.Empty; } private void ApplyAgentSpeed() { if (!((Object)(object)base.agent == (Object)null) && ((Behaviour)base.agent).enabled) { base.agent.speed = ((_encounterState != EncounterState.Chase) ? MoveSpeed : (ServerSprintActive ? 3.6f : 2f)); } } private void ConfigureAgent() { //IL_0061: 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) if ((Object)(object)base.agent == (Object)null) { base.agent = ((Component)this).GetComponent(); if ((Object)(object)base.agent == (Object)null) { base.agent = ((Component)this).gameObject.AddComponent(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[CreepyDollAI] ConfigureAgent added a missing root NavMeshAgent."); } } } if (!((Behaviour)base.agent).enabled) { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(((Component)this).transform.position, ref val, 8f, -1)) { ((Component)this).transform.position = ((NavMeshHit)(ref val)).position; } ((Behaviour)base.agent).enabled = true; } ApplyAgentSpeed(); base.agent.acceleration = Acceleration; base.agent.angularSpeed = AngularSpeed; base.agent.radius = 0.5f; base.agent.height = 2f; base.agent.baseOffset = 0f; base.agent.stoppingDistance = 0.6f; base.agent.autoBraking = true; base.agent.updateRotation = AgentDrivesBodyRotation(); base.agent.autoRepath = true; base.agent.obstacleAvoidanceType = (ObstacleAvoidanceType)4; base.agent.avoidancePriority = 45; base.agentMask = (((Object)(object)RoundManager.Instance != (Object)null && (Object)(object)base.enemyType != (Object)null) ? RoundManager.Instance.GetLayermaskForEnemySizeLimit(base.enemyType, false, -1) : (-1)); base.agent.areaMask = base.agentMask; base.agent.autoTraverseOffMeshLink = true; if (base.openDoorSpeedMultiplier <= 0f) { base.openDoorSpeedMultiplier = (((Object)(object)base.enemyType != (Object)null && base.enemyType.doorSpeedMultiplier > 0f) ? base.enemyType.doorSpeedMultiplier : 1f); } EnsureAgentOnNavMesh(24f); } private void RepairFacilityAINodes() { if (base.allAINodes == null || base.allAINodes.Length == 0) { GameObject[] array = null; if ((Object)(object)RoundManager.Instance != (Object)null) { array = RoundManager.Instance.insideAINodes; } if (array == null || array.Length == 0) { array = GameObject.FindGameObjectsWithTag("AINode"); } base.allAINodes = (GameObject[])(((object)array) ?? ((object)new GameObject[0])); } } private bool EnsureAgentOnNavMesh(float searchRadius = 8f) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.agent == (Object)null || !((Behaviour)base.agent).enabled) { return false; } if (base.agent.isOnNavMesh) { return true; } NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(((Component)this).transform.position, ref val, searchRadius, -1)) { MoveRootTo(((NavMeshHit)(ref val)).position, $"nearest NavMesh within {searchRadius:0.#}m", ResolveReferencePlayer(), logAlways: false); if (base.agent.isOnNavMesh) { LogMovementDiagnostic("warped agent onto nearest NavMesh"); return true; } } LogMovementDiagnostic("could not find nearby NavMesh"); return false; } private void CorrectPrototypeSpawnPlacement() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = ResolveReferencePlayer(); bool flag = (Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh; float num = (((Object)(object)val != (Object)null) ? Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position) : 0f); if (!DevSnapSpawnNearPlayer) { EnsureAgentOnNavMesh(32f); LogSpawnDiagnostic("Dev snap disabled"); return; } if ((Object)(object)val == (Object)null) { EnsureAgentOnNavMesh(32f); LogSpawnDiagnostic("No reference player for dev snap"); return; } if (flag && num <= 25f) { LogSpawnDiagnostic("Kept dev spawn placement"); return; } Vector3 forward = ((Component)val).transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.001f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); Vector3 val2 = ((Component)val).transform.position + forward * Mathf.Max(2.5f, DevSpawnDistance); if (TryFindNavPosition(val2, 18f, out var position) || TryFindNavPosition(((Component)val).transform.position, 18f, out position) || TryFindNavPosition(((Component)this).transform.position, 40f, out position)) { MoveRootTo(position, "dev snap to player-near NavMesh", val, logAlways: true); return; } Vector3 position2 = val2; RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(val2 + Vector3.up * 30f, Vector3.down, ref val3, 80f, -1, (QueryTriggerInteraction)1)) { position2.y = ((RaycastHit)(ref val3)).point.y; } MoveRootTo(position2, "dev snap to player fallback without NavMesh", val, logAlways: true); } private bool TryFindNavPosition(Vector3 origin, float radius, out Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //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) NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(origin, ref val, radius, -1)) { position = ((NavMeshHit)(ref val)).position; return true; } position = Vector3.zero; return false; } private void MoveRootTo(Vector3 position, string reason, PlayerControllerB referencePlayer, bool logAlways) { //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_0012: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Vector3 position2 = ((Component)this).transform.position; ((Component)this).transform.position = position; bool flag = false; if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled) { flag = base.agent.Warp(position); } if (logAlways || DebugLogs) { string text = (((Object)(object)referencePlayer != (Object)null) ? $", playerPos={((Component)referencePlayer).transform.position}, distanceToPlayer={Vector3.Distance(((Component)this).transform.position, ((Component)referencePlayer).transform.position):0.00}" : string.Empty); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[CreepyDollAI] Spawn placement: {reason}; before={position2}, after={((Component)this).transform.position}, agentWarped={flag}, agentOnNavMesh={(Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh}{text}."); } } } private PlayerControllerB ResolveReferencePlayer() { if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) { return GameNetworkManager.Instance.localPlayerController; } if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return null; } PlayerControllerB val = null; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val2 in allPlayerScripts) { if (!((Object)(object)val2 == (Object)null)) { val = val ?? val2; if (!val2.isPlayerDead) { return val2; } } } return val; } private void FacePosition(Vector3 target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) FacePosition(target, Time.deltaTime); } private void FacePosition(Vector3 target, float stepSeconds) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) Vector3 val = target - ((Component)this).transform.position; val.y = 0f; if (!(((Vector3)(ref val)).sqrMagnitude < 0.001f)) { Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); ((Component)this).transform.rotation = Quaternion.RotateTowards(((Component)this).transform.rotation, val2, AngularSpeed * Mathf.Max(0f, stepSeconds)); } } private void LogSpawnDiagnostic(string reason) { //IL_0022: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = ResolveReferencePlayer(); string text = (((Object)(object)val != (Object)null) ? $", playerPos={((Component)val).transform.position}, distanceToPlayer={Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position):0.00}" : ", playerPos="); bool flag = (Object)(object)base.agent != (Object)null; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[CreepyDollAI] {reason}. IsServer={((NetworkBehaviour)this).IsServer}, agent={flag}, enabled={flag && ((Behaviour)base.agent).enabled}, onNavMesh={flag && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh}, animator={(Object)(object)base.creatureAnimator != (Object)null}, pos={((Component)this).transform.position}{text}."); } } private void LogHushdollRuntimeDiagnostics(string context) { if (_loggedRuntimeDiagnostics) { return; } _loggedRuntimeDiagnostics = true; ResolveHeadTrackingReferences(); ResolveFootReferences(); int num = Plugin.RepairCollisionDetectMainScripts(((Component)this).gameObject, this); int num2 = Plugin.DisablePhysicalVisualColliders(((Component)this).gameObject); EnemyAICollisionDetect[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); Collider[] componentsInChildren2 = ((Component)this).GetComponentsInChildren(true); string text = (((Object)(object)base.agent != (Object)null) ? $"agent enabled={((Behaviour)base.agent).enabled}, onNavMesh={((Behaviour)base.agent).enabled && base.agent.isOnNavMesh}, radius={base.agent.radius:0.00}, height={base.agent.height:0.00}, stoppingDistance={base.agent.stoppingDistance:0.00}, areaMask={base.agent.areaMask}, updateRotation={base.agent.updateRotation}" : "agent="); StringBuilder stringBuilder = new StringBuilder(); foreach (Collider val in componentsInChildren2) { if (!((Object)(object)val == (Object)null)) { if (stringBuilder.Length > 0) { stringBuilder.Append("; "); } stringBuilder.Append($"{((object)val).GetType().Name} on {GetTransformPath(((Component)val).transform)} (layer={LayerMask.LayerToName(((Component)val).gameObject.layer)}, trigger={val.isTrigger}, enabled={val.enabled})"); } } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[CreepyDollAI] Runtime diagnostics ({context}): head={GetTransformPath(_headBone)}, neck={GetTransformPath(_neckBone)}, leftFoot={GetTransformPath(_leftFootBone)}, rightFoot={GetTransformPath(_rightFootBone)}, eye={GetTransformPath(base.eye)}, {text}, collisionDetects={componentsInChildren.Length}, repairedDetects={num}, disabledVisualColliders={num2}, colliders={componentsInChildren2.Length} [{stringBuilder}]."); } } private static string GetTransformPath(Transform target) { if ((Object)(object)target == (Object)null) { return ""; } string text = ((Object)target).name; Transform parent = target.parent; int num = 0; while ((Object)(object)parent != (Object)null && num++ < 32) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private void LogHeadStateEvent(string message) { if (((NetworkBehaviour)this).IsServer && !string.IsNullOrEmpty(message) && (!string.Equals(message, _lastHeadStateLogLine, StringComparison.Ordinal) || !(Time.time < _nextHeadStateLogTime))) { _lastHeadStateLogLine = message; _nextHeadStateLogTime = Time.time + 0.25f; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[CreepyDollAI][head] " + message)); } } } private void LogClientConfirmEvent(int stageFlag, string message) { if (_clientConfirmLogEpoch != _replicatedSpotConfirmEpoch) { _clientConfirmLogEpoch = _replicatedSpotConfirmEpoch; _clientConfirmLogFlags = 0; } if ((_clientConfirmLogFlags & stageFlag) == 0) { _clientConfirmLogFlags |= stageFlag; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[CreepyDollAI][head][client] epoch={_replicatedSpotConfirmEpoch}: {message}"); } } } private void LogFootstepDiagnostic() { if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead && !StaticVisualTestMode && !(Time.time < _nextFootstepDiagnosticTime) && (_contactFootstepCount != 0 || _phasedFootstepCount != 0)) { _nextFootstepDiagnosticTime = Time.time + 10f; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)($"[CreepyDollAI][steps] last 10s: contact={_contactFootstepCount}, phased={_phasedFootstepCount}, " + $"speed={_smoothedLocomotionSpeed:0.00} m/s, gait={_lastGaitName}, " + $"clipPlayback={_lastSlowWalkPlaybackRate:0.00}x (1.00 = feet match ground), " + $"leftFootClearance={MeasureFootClearance(_leftFootBone):0.000} (reach {DescribeFootReach(_leftFootSoleOffset)}), " + $"rightFootClearance={MeasureFootClearance(_rightFootBone):0.000} (reach {DescribeFootReach(_rightFootSoleOffset)}).")); } _contactFootstepCount = 0; _phasedFootstepCount = 0; } } private string DescribeFootReach(float soleOffset) { if (!(soleOffset < 0f)) { return (soleOffset + 0.14f).ToString("0.000"); } return "uncalibrated"; } private float MeasureFootClearance(Transform foot) { //IL_0010: 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_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_0029: 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_0084: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)foot == (Object)null) { return -1f; } RaycastHit val = default(RaycastHit); if (!Physics.Raycast(foot.position + Vector3.up * 1f, Vector3.down, ref val, 4f, ResolveLineOfSightMask(), (QueryTriggerInteraction)1)) { return -1f; } if ((Object)(object)((RaycastHit)(ref val)).collider != (Object)null && ((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)this).transform)) { return -1f; } return foot.position.y - ((RaycastHit)(ref val)).point.y; } private void LogRoamDiagnostic() { //IL_00ee: 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_0119: 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) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if (DebugLogs && ((NetworkBehaviour)this).IsServer && !base.isEnemyDead && !(Time.time < _nextRoamDiagnosticTime)) { _nextRoamDiagnosticTime = Time.time + 1f; string text = (_isNeckSlashing ? "slash" : string.Format("{0}{1}", _encounterState, _serverObservationPlanted ? "+planted" : string.Empty)); object obj; if (!((Object)(object)base.agent != (Object)null) || !((Behaviour)base.agent).enabled || !base.agent.isOnNavMesh) { obj = "agent="; } else { object[] obj2 = new object[8] { base.agent.isStopped, base.agent.hasPath, base.agent.pathPending, base.agent.pathStatus, base.agent.remainingDistance, null, null, null }; Vector3 val = base.agent.velocity; obj2[5] = ((Vector3)(ref val)).magnitude; val = base.agent.desiredVelocity; obj2[6] = ((Vector3)(ref val)).magnitude; obj2[7] = base.agent.areaMask; obj = string.Format("stopped={0}, hasPath={1}, pending={2}, status={3}, remaining={4:0.00}, speed={5:0.00}/{6:0.00}, areaMask={7}", obj2); } string text2 = (string)obj; string text3 = ((base.currentSearch != null && base.currentSearch.inProgress) ? string.Format("search inProgress, node={0}, unsearched={1}, waitingForNode={2}", ((Object)(object)base.currentSearch.currentTargetNode != (Object)null) ? (Vector3.Distance(((Component)this).transform.position, base.currentSearch.currentTargetNode.transform.position).ToString("0.0") + "m") : "", base.currentSearch.unsearchedNodes?.Count ?? (-1), base.currentSearch.waitingForTargetNode) : "search stopped"); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)string.Format("[CreepyDollAI] Roam diagnostic: mode={0}, {1}, {2}, observed={3}, pursuit={4}, spotConfirmed={5}, plantSpent={6}, agentOwnsRotation={7}, headYaw={8:0.0}, duck={9:0.0} deg.", text, text2, text3, _serverObservationClientId != ulong.MaxValue, (_serverPursuitClientId != ulong.MaxValue) ? _serverPursuitClientId.ToString() : "none", _serverSpotConfirmed, _serverObservationPlantSpent, (Object)(object)base.agent != (Object)null && base.agent.updateRotation, _headAimYawDegrees, _doorwayDuckPitchDegrees)); } } } private void LogMovementDiagnostic(string reason) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) if (DebugLogs && !(Time.time < _nextMovementDiagnosticTime)) { _nextMovementDiagnosticTime = Time.time + 1.5f; bool flag = (Object)(object)base.agent != (Object)null; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[CreepyDollAI] Movement diagnostic: {reason}; hasAgent={flag}, enabled={flag && ((Behaviour)base.agent).enabled}, onNavMesh={flag && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh}, pos={((Component)this).transform.position}."); } } } private void EnsureBehaviourStates() { //IL_001d: 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_002d: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //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_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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown if (base.enemyBehaviourStates == null || base.enemyBehaviourStates.Length < 3) { base.enemyBehaviourStates = (EnemyBehaviourState[])(object)new EnemyBehaviourState[3] { new EnemyBehaviourState { name = "Idle", IsAnimTrigger = false, parameterString = "IsMoving", boolValue = false }, new EnemyBehaviourState { name = "Luring", IsAnimTrigger = false, parameterString = "IsMoving", boolValue = true }, new EnemyBehaviourState { name = "Neck Slash", IsAnimTrigger = true, parameterString = "NeckSlash" } }; base.currentBehaviourStateIndex = 0; base.currentBehaviourState = base.enemyBehaviourStates[0]; } } protected override void __initializeVariables() { if (_networkDuckDegrees == null) { throw new Exception("CreepyDollAI._networkDuckDegrees cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_networkDuckDegrees).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_networkDuckDegrees, "_networkDuckDegrees"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_networkDuckDegrees); if (_networkPeekYawDegrees == null) { throw new Exception("CreepyDollAI._networkPeekYawDegrees cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_networkPeekYawDegrees).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_networkPeekYawDegrees, "_networkPeekYawDegrees"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_networkPeekYawDegrees); if (_networkPeekRollDegrees == null) { throw new Exception("CreepyDollAI._networkPeekRollDegrees cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_networkPeekRollDegrees).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_networkPeekRollDegrees, "_networkPeekRollDegrees"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_networkPeekRollDegrees); ((EnemyAI)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(301402725u, new RpcReceiveHandler(__rpc_handler_301402725), "BeginPossessionClientRpc"); ((NetworkBehaviour)this).__registerRpc(2754516961u, new RpcReceiveHandler(__rpc_handler_2754516961), "EndPossessionClientRpc"); ((NetworkBehaviour)this).__registerRpc(1621209323u, new RpcReceiveHandler(__rpc_handler_1621209323), "ReportPossessionServerRpc"); ((NetworkBehaviour)this).__registerRpc(2495072846u, new RpcReceiveHandler(__rpc_handler_2495072846), "RequestNeckSlashKillServerRpc"); ((NetworkBehaviour)this).__registerRpc(1190224957u, new RpcReceiveHandler(__rpc_handler_1190224957), "PlayNeckSlashClientRpc"); ((NetworkBehaviour)this).__registerRpc(1957274175u, new RpcReceiveHandler(__rpc_handler_1957274175), "ResolveNeckSlashClientRpc"); ((NetworkBehaviour)this).__registerRpc(799409866u, new RpcReceiveHandler(__rpc_handler_799409866), "PlayFootstepClientRpc"); ((NetworkBehaviour)this).__registerRpc(2374545687u, new RpcReceiveHandler(__rpc_handler_2374545687), "PlayIdleBeatClientRpc"); ((NetworkBehaviour)this).__registerRpc(726890257u, new RpcReceiveHandler(__rpc_handler_726890257), "PlaySprintVocalClientRpc"); ((NetworkBehaviour)this).__registerRpc(2920004268u, new RpcReceiveHandler(__rpc_handler_2920004268), "StartPursuitSirenClientRpc"); ((NetworkBehaviour)this).__registerRpc(2826517116u, new RpcReceiveHandler(__rpc_handler_2826517116), "StopPursuitSirenClientRpc"); ((NetworkBehaviour)this).__registerRpc(2504793662u, new RpcReceiveHandler(__rpc_handler_2504793662), "PlayHeadSnapClientRpc"); ((NetworkBehaviour)this).__registerRpc(395634359u, new RpcReceiveHandler(__rpc_handler_395634359), "PlayKillSoundClientRpc"); ((NetworkBehaviour)this).__registerRpc(2272386025u, new RpcReceiveHandler(__rpc_handler_2272386025), "ExecuteNeckSlashKillClientRpc"); ((NetworkBehaviour)this).__registerRpc(4045993336u, new RpcReceiveHandler(__rpc_handler_4045993336), "RearmPossessionExecutionClientRpc"); ((NetworkBehaviour)this).__registerRpc(79685772u, new RpcReceiveHandler(__rpc_handler_79685772), "SetHeadFocusClientRpc"); ((NetworkBehaviour)this).__registerRpc(1932402267u, new RpcReceiveHandler(__rpc_handler_1932402267), "ClearHeadFocusClientRpc"); ((NetworkBehaviour)this).__registerRpc(759200182u, new RpcReceiveHandler(__rpc_handler_759200182), "SyncObservationStateClientRpc"); ((NetworkBehaviour)this).__registerRpc(3527252639u, new RpcReceiveHandler(__rpc_handler_3527252639), "SetHeadFocusSnapClientRpc"); ((EnemyAI)this).__initializeRpcs(); } private static void __rpc_handler_301402725(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong playerClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).BeginPossessionClientRpc(playerClientId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2754516961(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong playerClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).EndPossessionClientRpc(playerClientId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1621209323(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong playerClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId); bool active = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref active, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).ReportPossessionServerRpc(playerClientId, active); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2495072846(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong playerClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId); bool fromPossessionStop = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref fromPossessionStop, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).RequestNeckSlashKillServerRpc(playerClientId, fromPossessionStop); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1190224957(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong playerClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId); float windupSeconds = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref windupSeconds, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).PlayNeckSlashClientRpc(playerClientId, windupSeconds); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1957274175(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).ResolveNeckSlashClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_799409866(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0064: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int surfaceIndex = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref surfaceIndex); int clipIndex = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref clipIndex); float volume = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref volume, default(ForPrimitives)); float pitch = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref pitch, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).PlayFootstepClientRpc(surfaceIndex, clipIndex, volume, pitch); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2374545687(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { float volume = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref volume, default(ForPrimitives)); float pitch = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref pitch, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).PlayIdleBeatClientRpc(volume, pitch); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_726890257(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { float volume = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref volume, default(ForPrimitives)); float pitch = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref pitch, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).PlaySprintVocalClientRpc(volume, pitch); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2920004268(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int clipIndex = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref clipIndex); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).StartPursuitSirenClientRpc(clipIndex); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2826517116(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).StopPursuitSirenClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2504793662(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).PlayHeadSnapClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_395634359(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).PlayKillSoundClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2272386025(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong playerClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).ExecuteNeckSlashKillClientRpc(playerClientId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_4045993336(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong playerClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).RearmPossessionExecutionClientRpc(playerClientId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_79685772(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_003c: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { Vector3 focusPoint = default(Vector3); ((FastBufferReader)(ref reader)).ReadValueSafe(ref focusPoint); float duration = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref duration, default(ForPrimitives)); bool fromNoise = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref fromNoise, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).SetHeadFocusClientRpc(focusPoint, duration, fromNoise); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1932402267(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).ClearHeadFocusClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_759200182(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0042: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong observedClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref observedClientId); bool spotConfirmed = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref spotConfirmed, default(ForPrimitives)); float confirmedSecondsAgo = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref confirmedSecondsAgo, default(ForPrimitives)); int confirmEpoch = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref confirmEpoch); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).SyncObservationStateClientRpc(observedClientId, spotConfirmed, confirmedSecondsAgo, confirmEpoch); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3527252639(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_003c: 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_0051: 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_006f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { Vector3 focusPoint = default(Vector3); ((FastBufferReader)(ref reader)).ReadValueSafe(ref focusPoint); float duration = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref duration, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((CreepyDollAI)(object)target).SetHeadFocusSnapClientRpc(focusPoint, duration); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "CreepyDollAI"; } } internal sealed class CreepyDollConfig { public ConfigEntry Enabled { get; } public ConfigEntry SpawnWeightMultiplier { get; } public ConfigEntry MaxCount { get; } public ConfigEntry PowerLevel { get; } public ConfigEntry GazeRange { get; } public ConfigEntry SightRange { get; } public ConfigEntry HearingRange { get; } public ConfigEntry MoveSpeed { get; } public ConfigEntry PullSpeed { get; } public ConfigEntry AttackCooldown { get; } public ConfigEntry NeckSlashRange { get; } public ConfigEntry HypnosisOnsetDelay { get; } public ConfigEntry MovementLockDelay { get; } public ConfigEntry FootstepVolume { get; } public ConfigEntry MindControlVisualIntensity { get; } public ConfigEntry DebugLogs { get; } public CreepyDollConfig(ConfigFile config) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Expected O, but got Unknown //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Expected O, but got Unknown //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Expected O, but got Unknown //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Expected O, but got Unknown //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Expected O, but got Unknown //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Expected O, but got Unknown bool saveOnConfigSet = config.SaveOnConfigSet; config.SaveOnConfigSet = false; try { CreepyDollConfigMigration.TryMigrate(config, Plugin.Log); ConfigSectionNameMigration.TryMigrate(config, Plugin.Log, "Hushdoll"); Enabled = config.Bind("General", "Enabled", true, "Enable the Hushdoll encounter."); SpawnWeightMultiplier = config.Bind("Spawning", "SpawnWeightMultiplier", 1f, new ConfigDescription("Multiplier applied to Hushdoll's contextual moon/interior spawn policy. 0 disables natural spawns.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); MaxCount = config.Bind("Spawning", "MaxCount", 1, new ConfigDescription("Maximum number of living Hushdolls at once.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 4), Array.Empty())); PowerLevel = config.Bind("Spawning", "PowerLevel", 2f, new ConfigDescription("Indoor enemy power budget cost for each Hushdoll.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 20f), Array.Empty())); GazeRange = config.Bind("Detection", "GazeRange", 80f, new ConfigDescription("Maximum range at which mutual eye contact can start or maintain hypnosis.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 100f), Array.Empty())); SightRange = config.Bind("Detection", "SightRange", 18f, new ConfigDescription("Maximum range at which Hushdoll can initially notice a player by sight.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 80f), Array.Empty())); HearingRange = config.Bind("Detection", "HearingRange", 20f, new ConfigDescription("Maximum range at which a sufficiently loud noise can make Hushdoll investigate.", (AcceptableValueBase)(object)new AcceptableValueRange(4f, 80f), Array.Empty())); MoveSpeed = config.Bind("Movement", "MoveSpeed", 0.6f, new ConfigDescription("Hushdoll's NavMesh roaming speed in meters per second.", (AcceptableValueBase)(object)new AcceptableValueRange(0.34f, 5f), Array.Empty())); PullSpeed = config.Bind("Movement", "PullSpeed", 0.85f, new ConfigDescription("Speed at which an entranced player is pulled toward Hushdoll.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); AttackCooldown = config.Bind("Combat", "AttackCooldown", 2.4f, new ConfigDescription("Seconds between neck-slash attempts.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 30f), Array.Empty())); NeckSlashRange = config.Bind("Combat", "NeckSlashRange", 2.15f, new ConfigDescription("Distance at which Hushdoll starts the neck-slash sequence.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 5f), Array.Empty())); HypnosisOnsetDelay = config.Bind("Abilities", "HypnosisOnsetDelay", 0.5f, new ConfigDescription("Seconds after mutual gaze is confirmed before hypnosis begins.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); MovementLockDelay = config.Bind("Abilities", "MovementLockDelay", 3f, new ConfigDescription("Seconds after hypnosis begins before movement input is fully locked. Look input locks immediately.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 10f), Array.Empty())); FootstepVolume = config.Bind("Audio and Presentation", "FootstepVolume", 1f, new ConfigDescription("Multiplier for Hushdoll's footstep volume.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 4f), Array.Empty())); MindControlVisualIntensity = config.Bind("Audio and Presentation", "MindControlVisualIntensity", 0.65f, new ConfigDescription("Strength of the local camera pulse while Hushdoll controls the player.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); DebugLogs = config.Bind("Diagnostics", "DebugLogs", false, "Log detailed Hushdoll targeting and setup diagnostics."); } finally { config.SaveOnConfigSet = saveOnConfigSet; if (saveOnConfigSet) { config.Save(); } } } } internal static class CreepyDollConfigMigration { private static readonly ConfigDefinition LegacySpawnWeight = new ConfigDefinition("Spawning", "SpawnWeight"); private static readonly ConfigDefinition[] RetainedLegacyDefinitions = (ConfigDefinition[])(object)new ConfigDefinition[12] { new ConfigDefinition("Movement", "MoveSpeed"), new ConfigDefinition("Gaze", "GazeRange"), new ConfigDefinition("Gaze", "HypnosisOnsetDelaySeconds"), new ConfigDefinition("Possession", "MovementLockDelay"), new ConfigDefinition("Possession", "PossessedWalkSpeed"), new ConfigDefinition("Head Tracking", "HeadSightRange"), new ConfigDefinition("Head Tracking", "HeadHearingRange"), new ConfigDefinition("Combat", "AttackCooldown"), new ConfigDefinition("Combat", "NeckSlashRange"), new ConfigDefinition("Audio", "FootstepVolume"), new ConfigDefinition("Possession", "MindControlVisualIntensity"), new ConfigDefinition("Debug", "DebugLogs") }; private static readonly Dictionary RemovedDefaults = new Dictionary { { new ConfigDefinition("Internal", "ConfigSchemaVersion"), "4" }, { new ConfigDefinition("Movement", "Acceleration"), "22.5" }, { new ConfigDefinition("Movement", "AngularSpeed"), "150" }, { new ConfigDefinition("Gaze", "GazeRequiredSeconds"), "2" }, { new ConfigDefinition("Gaze", "GazeHalfAngleDegrees"), "18" }, { new ConfigDefinition("Gaze", "GazeFrontHalfAngleDegrees"), "85" }, { new ConfigDefinition("Possession", "PossessionStrafeSeconds"), "2" }, { new ConfigDefinition("Possession", "PossessedStrafeSpeed"), "0.75" }, { new ConfigDefinition("Possession", "PossessedLookTurnSpeed"), "280" }, { new ConfigDefinition("Movement", "RoamRadius"), "18" }, { new ConfigDefinition("Movement", "RoamRepathSeconds"), "5" }, { new ConfigDefinition("Head Tracking", "HeadTrackingEnabled"), "true" }, { new ConfigDefinition("Head Tracking", "HeadTrackingRange"), "80" }, { new ConfigDefinition("Head Tracking", "HeadVisionConeDegrees"), "30" }, { new ConfigDefinition("Head Tracking", "HeadProximityAwareness"), "3" }, { new ConfigDefinition("Head Tracking", "HeadRearAwarenessRange"), "4.5" }, { new ConfigDefinition("Head Tracking", "HeadSightHoldSeconds"), "3.5" }, { new ConfigDefinition("Head Tracking", "HeadRearTurnDelaySeconds"), "1.2" }, { new ConfigDefinition("Head Tracking", "SpotConfirmSeconds"), "0.28" }, { new ConfigDefinition("Head Tracking", "SpotConfirmGraceSeconds"), "0.45" }, { new ConfigDefinition("Head Tracking", "HeadYawLimitDegrees"), "78" }, { new ConfigDefinition("Head Tracking", "HeadPitchLimitDegrees"), "32" }, { new ConfigDefinition("Head Tracking", "HeadSnapSpeed"), "520" }, { new ConfigDefinition("Head Tracking", "HeadTrackSpeed"), "120" }, { new ConfigDefinition("Head Tracking", "HeadBodyFollowDelay"), "3" }, { new ConfigDefinition("Head Tracking", "HeadBodyFollowSpeed"), "60" }, { new ConfigDefinition("Combat", "AttackRange"), "2.35" }, { new ConfigDefinition("Combat", "NeckSlashKillDelay"), "2" }, { new ConfigDefinition("Combat", "NeckSlashContactDistance"), "2.75" }, { new ConfigDefinition("Combat", "PlayAttackAnimation"), "true" }, { new ConfigDefinition("Debug", "StaticVisualTestMode"), "false" }, { new ConfigDefinition("Debug", "VisualYawOffsetDegrees"), "0" }, { new ConfigDefinition("Debug", "StabilizeVisualRoot"), "true" }, { new ConfigDefinition("Debug", "StabilizeVisualHorizontal"), "false" }, { new ConfigDefinition("Debug", "VisualGroundOffset"), "-0.04" }, { new ConfigDefinition("Head Tracking", "HeadPoseAuthority"), "0.85" }, { new ConfigDefinition("Head Tracking", "HeadRestPitchTrimDegrees"), "0" }, { new ConfigDefinition("Head Tracking", "HeadRollLimitDegrees"), "18" }, { new ConfigDefinition("Animation", "IdleExamineEnabled"), "true" }, { new ConfigDefinition("Animation", "IdleScanYawRangeDegrees"), "55" }, { new ConfigDefinition("Animation", "IdleScanPitchRangeDegrees"), "12" }, { new ConfigDefinition("Animation", "IdleScanRollDegrees"), "6" }, { new ConfigDefinition("Animation", "IdleScanSpeedDegreesPerSecond"), "26" }, { new ConfigDefinition("Animation", "IdleScanHoldMinSeconds"), "2.5" }, { new ConfigDefinition("Animation", "IdleScanHoldMaxSeconds"), "6" }, { new ConfigDefinition("Animation", "IdleScanGlanceChance"), "0.2" }, { new ConfigDefinition("Animation", "DoorwayDuckEnabled"), "true" }, { new ConfigDefinition("Animation", "DoorwayDuckProbeDistance"), "1.15" }, { new ConfigDefinition("Animation", "DoorwayDuckAngleDegrees"), "32" }, { new ConfigDefinition("Animation", "DoorwayDuckClearanceMargin"), "0.08" }, { new ConfigDefinition("Animation", "DoorwayDuckDegreesPerMeter"), "55" }, { new ConfigDefinition("Animation", "DoorwayPeekEnabled"), "true" }, { new ConfigDefinition("Animation", "DoorwayPeekYawDegrees"), "40" }, { new ConfigDefinition("Animation", "DoorwayPeekRollDegrees"), "14" }, { new ConfigDefinition("Animation", "DoorwayPeekLookaheadDistance"), "3" }, { new ConfigDefinition("Animation", "DoorwayPeekMinimumTurnDegrees"), "45" }, { new ConfigDefinition("Debug", "DevSnapSpawnNearPlayer"), "false" }, { new ConfigDefinition("Debug", "DevSpawnDistance"), "6" } }; internal static bool TryMigrate(ConfigFile config, ManualLogSource log) { string configFilePath = config.ConfigFilePath; if (!File.Exists(configFilePath)) { return false; } Dictionary dictionary = null; string text = null; try { dictionary = ReadValues(configFilePath); if (!ContainsLegacyConfig(dictionary)) { return false; } text = GetBackupPath(configFilePath); File.Copy(configFilePath, text, overwrite: false); File.WriteAllText(configFilePath, BuildMigratedConfig(dictionary), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); config.Reload(); } catch (Exception ex) { string text2 = "The original config was not modified."; if (!string.IsNullOrEmpty(text) && File.Exists(text)) { try { File.Copy(text, configFilePath, overwrite: true); config.Reload(); text2 = "The original config was restored from its backup."; } catch (Exception ex2) { text2 = "Automatic restore also failed: " + ex2.GetBaseException().Message + ". Recover manually from " + text + "."; } } if (log != null) { log.LogWarning((object)("[Hushdoll] Could not migrate legacy config: " + ex.GetBaseException().Message + " " + text2)); } return false; } List list = FindCustomizedDroppedKeys(dictionary); if (log != null) { log.LogInfo((object)("[Hushdoll] Migrated legacy config to the compact DawnLib layout. Backup: " + text)); } if (list.Count > 0 && log != null) { log.LogWarning((object)("[Hushdoll] These customized legacy settings are now authored source tuning and were not carried forward: " + string.Join(", ", list))); } return true; } private static bool ContainsLegacyConfig(Dictionary values) { if (values.ContainsKey(LegacySpawnWeight)) { return true; } for (int i = 0; i < RetainedLegacyDefinitions.Length; i++) { if (values.ContainsKey(RetainedLegacyDefinitions[i])) { return true; } } foreach (ConfigDefinition key in RemovedDefaults.Keys) { if (values.ContainsKey(key)) { return true; } } return false; } private static string BuildMigratedConfig(Dictionary values) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0097: 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_00b5: Expected O, but got Unknown //IL_00b5: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_01c6: 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_01e4: Expected O, but got Unknown //IL_01e4: Expected O, but got Unknown //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Expected O, but got Unknown //IL_021e: Expected O, but got Unknown //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown //IL_0258: Expected O, but got Unknown //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Expected O, but got Unknown //IL_02b5: Expected O, but got Unknown //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Expected O, but got Unknown //IL_0300: Expected O, but got Unknown //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Expected O, but got Unknown //IL_033a: Expected O, but got Unknown //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Expected O, but got Unknown //IL_0385: Expected O, but got Unknown //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Expected O, but got Unknown //IL_03bf: Expected O, but got Unknown //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Expected O, but got Unknown //IL_040a: Expected O, but got Unknown //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Expected O, but got Unknown //IL_0444: Expected O, but got Unknown //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Expected O, but got Unknown //IL_048f: Expected O, but got Unknown string text = GetValue(values, new ConfigDefinition("10 - Spawning", "SpawnWeightMultiplier"), null, null); if (string.IsNullOrWhiteSpace(text)) { text = ((!float.TryParse(GetValue(values, LegacySpawnWeight, null, "0"), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) ? "1" : ((result <= 0f) ? 1f : Math.Max(0f, Math.Min(5f, result / 5f))).ToString("0.###", CultureInfo.InvariantCulture)); } string item = GetValue(values, new ConfigDefinition("40 - Movement", "MoveSpeed"), new ConfigDefinition("Movement", "MoveSpeed"), "0.6"); if (int.TryParse(GetValue(values, new ConfigDefinition("Internal", "ConfigSchemaVersion"), null, "4"), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) && result2 < 4) { item = "0.6"; } StringBuilder stringBuilder = new StringBuilder(); AppendSection(stringBuilder, "00 - General", ("Enabled", GetValue(values, new ConfigDefinition("00 - General", "Enabled"), null, "true"))); AppendSection(stringBuilder, "10 - Spawning", ("SpawnWeightMultiplier", text), ("MaxCount", GetValue(values, new ConfigDefinition("10 - Spawning", "MaxCount"), null, "1")), ("PowerLevel", GetValue(values, new ConfigDefinition("10 - Spawning", "PowerLevel"), null, "2"))); AppendSection(stringBuilder, "30 - Detection", ("GazeRange", GetValue(values, new ConfigDefinition("30 - Detection", "GazeRange"), new ConfigDefinition("Gaze", "GazeRange"), "80")), ("SightRange", GetValue(values, new ConfigDefinition("30 - Detection", "SightRange"), new ConfigDefinition("Head Tracking", "HeadSightRange"), "18")), ("HearingRange", GetValue(values, new ConfigDefinition("30 - Detection", "HearingRange"), new ConfigDefinition("Head Tracking", "HeadHearingRange"), "20"))); AppendSection(stringBuilder, "40 - Movement", ("MoveSpeed", item), ("PullSpeed", GetValue(values, new ConfigDefinition("40 - Movement", "PullSpeed"), new ConfigDefinition("Possession", "PossessedWalkSpeed"), "0.85"))); AppendSection(stringBuilder, "50 - Combat", ("AttackCooldown", GetValue(values, new ConfigDefinition("50 - Combat", "AttackCooldown"), new ConfigDefinition("Combat", "AttackCooldown"), "2.4")), ("NeckSlashRange", GetValue(values, new ConfigDefinition("50 - Combat", "NeckSlashRange"), new ConfigDefinition("Combat", "NeckSlashRange"), "2.15"))); AppendSection(stringBuilder, "60 - Abilities", ("HypnosisOnsetDelay", GetValue(values, new ConfigDefinition("60 - Abilities", "HypnosisOnsetDelay"), new ConfigDefinition("Gaze", "HypnosisOnsetDelaySeconds"), "0.5")), ("MovementLockDelay", GetValue(values, new ConfigDefinition("60 - Abilities", "MovementLockDelay"), new ConfigDefinition("Possession", "MovementLockDelay"), "3"))); AppendSection(stringBuilder, "70 - Audio and Presentation", ("FootstepVolume", GetValue(values, new ConfigDefinition("70 - Audio and Presentation", "FootstepVolume"), new ConfigDefinition("Audio", "FootstepVolume"), "1")), ("MindControlVisualIntensity", GetValue(values, new ConfigDefinition("70 - Audio and Presentation", "MindControlVisualIntensity"), new ConfigDefinition("Possession", "MindControlVisualIntensity"), "0.65"))); AppendSection(stringBuilder, "99 - Diagnostics", ("DebugLogs", GetValue(values, new ConfigDefinition("99 - Diagnostics", "DebugLogs"), new ConfigDefinition("Debug", "DebugLogs"), "false"))); return stringBuilder.ToString(); } private static void AppendSection(StringBuilder output, string section, params (string Key, string Value)[] entries) { output.Append('[').Append(section).AppendLine("]"); for (int i = 0; i < entries.Length; i++) { output.Append(entries[i].Key).Append(" = ").AppendLine(entries[i].Value); } output.AppendLine(); } private static string GetValue(Dictionary values, ConfigDefinition preferred, ConfigDefinition legacy, string fallback) { if (preferred != (ConfigDefinition)null && values.TryGetValue(preferred, out var value)) { return value; } if (legacy != (ConfigDefinition)null && values.TryGetValue(legacy, out value)) { return value; } return fallback; } private static Dictionary ReadValues(string path) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown Dictionary dictionary = new Dictionary(); string text = string.Empty; string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0 || text2.StartsWith("#", StringComparison.Ordinal)) { continue; } if (text2.StartsWith("[", StringComparison.Ordinal) && text2.EndsWith("]", StringComparison.Ordinal)) { text = text2.Substring(1, text2.Length - 2); continue; } int num = text2.IndexOf('='); if (num > 0) { string text3 = text2.Substring(0, num).Trim(); string value = text2.Substring(num + 1).Trim(); dictionary[new ConfigDefinition(text, text3)] = value; } } return dictionary; } private static List FindCustomizedDroppedKeys(Dictionary values) { List list = new List(); foreach (KeyValuePair removedDefault in RemovedDefaults) { if (values.TryGetValue(removedDefault.Key, out var value) && !ValuesEquivalent(value, removedDefault.Value)) { list.Add(removedDefault.Key.Section + "." + removedDefault.Key.Key); } } list.Sort(StringComparer.OrdinalIgnoreCase); return list; } private static bool ValuesEquivalent(string left, string right) { if (string.Equals(left.Trim(), right.Trim(), StringComparison.OrdinalIgnoreCase)) { return true; } if (float.TryParse(left, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(right, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { return Math.Abs(result - result2) < 0.0001f; } return false; } private static string GetBackupPath(string configPath) { string text = configPath + ".pre-dawn.bak"; if (!File.Exists(text)) { return text; } for (int i = 2; i < 1000; i++) { string text2 = configPath + $".pre-dawn.{i}.bak"; if (!File.Exists(text2)) { return text2; } } throw new IOException("Could not allocate a Hushdoll config backup filename."); } } internal sealed class HushdollSpawnWeights : IWeighted, IContextualWeighted { internal const int DefaultWeight = 3; internal const int MaximumWeight = 100; private readonly Func _multiplier; internal HushdollSpawnWeights(Func multiplier) { _multiplier = multiplier ?? throw new ArgumentNullException("multiplier"); } public int GetWeight() { return Scale(3, 1f); } public int GetWeight(SpawnWeightContext context) { int moonWeight = GetMoonWeight(((SpawnWeightContext)(ref context)).Moon); if (moonWeight <= 0) { return 0; } return Scale(moonWeight, GetDungeonMultiplier(((SpawnWeightContext)(ref context)).Dungeon)); } internal static int GetMoonWeight(DawnMoonInfo moon) { if (moon == null) { return 3; } if (((DawnBaseInfo)(object)moon).HasTag(Tags.Company) || ((DawnBaseInfo)(object)moon).HasTag(Tags.Unimplemented) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Test)) { return 0; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Experimentation)) { return 1; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Assurance) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Vow)) { return 3; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Offense) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.March) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Embrion)) { return 5; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Adamance)) { return 7; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Rend) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Dine)) { return 9; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Titan) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Artifice) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Liquidation)) { return 11; } if (((DawnBaseInfo)(object)moon).HasTag(Tags.Paid)) { return 8; } ((DawnBaseInfo)(object)moon).HasTag(Tags.Free); return 3; } internal static float GetDungeonMultiplier(DawnDungeonInfo dungeon) { if (dungeon == null) { return 1f; } if (KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.MansionFlow) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Gothic) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Grand) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Ornate) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Lavish) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Eerie)) { return 1.25f; } if (KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.FacilityFlow) || KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.FacilityFlowThreeExits) || KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.FacilityFlowExtraLarge) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Industrial) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Mechanical) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Factory) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Bunker)) { return 1f; } if (KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.MineshaftFlow) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Cavern) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Quarry) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Flooded)) { return 0.5f; } return 0.75f; } private int Scale(int moonWeight, float dungeonMultiplier) { float num = Mathf.Clamp(_multiplier(), 0f, 5f); return Mathf.Clamp(Mathf.RoundToInt((float)moonWeight * dungeonMultiplier * num), 0, 100); } private static bool KeyEquals(NamespacedKey left, NamespacedKey right) where T : INamespaced { if (left != null && right != null) { return ((object)left).Equals((object?)right); } return false; } } internal static class HushdollTuning { internal const float Acceleration = 22.5f; internal const float AngularSpeed = 150f; internal const float GazeHalfAngleDegrees = 18f; internal const float CloseRangeGazeHalfAngleDegrees = 40f; internal const float CloseRangeGazeFullWidthDistance = 4f; internal const float CloseRangeGazeNarrowDistance = 10f; internal const float PossessionStrafeSeconds = 2f; internal const float PossessedStrafeSpeed = 0.75f; internal const float PossessedLookTurnSpeed = 280f; internal const float PossessionBeginMaxDistance = 12f; internal const float PossessionLosGraceSeconds = 0.6f; internal const float RoamRadius = 18f; internal const float RoamRepathSeconds = 5f; internal const bool HeadTrackingEnabled = true; internal const float HeadTrackingRange = 80f; internal const float HeadVisionConeDegrees = 30f; internal const float HeadProximityAwareness = 3f; internal const float HeadRearAwarenessRange = 4.5f; internal const float HeadSightHoldSeconds = 3.5f; internal const float HeadRearTurnDelaySeconds = 1.2f; internal const float SpotConfirmSeconds = 0.8f; internal const float SpotConfirmGraceSeconds = 0.6f; internal const float HeadYawLimitDegrees = 78f; internal const float HeadPitchLimitDegrees = 32f; internal const float HypnosisHeadPitchLimitDegrees = 55f; internal const float HeadSnapSpeed = 520f; internal const float HeadTrackSpeed = 120f; internal const float HeadBodyFollowDelay = 3f; internal const float HeadBodyFollowSpeed = 60f; internal const float NeckSlashKillDelay = 2f; internal const bool PlayAttackAnimation = true; internal const float NeckSlashMomentumCarrySeconds = 0.45f; internal const float NeckSlashMomentumMinSpeedMetersPerSecond = 1.3f; internal const float NeckSlashMomentumStopDistance = 1.5f; internal const float NeckSlashEntryFadeWalkSeconds = 0.12f; internal const float NeckSlashEntryFadeRunSeconds = 0.35f; internal const bool StaticVisualTestMode = false; internal const float VisualYawOffsetDegrees = 0f; internal const bool StabilizeVisualRoot = true; internal const bool StabilizeVisualHorizontal = false; internal const float VisualGroundOffset = -0.04f; internal const float HeadPoseAuthority = 1f; internal const float HeadRestPitchTrimDegrees = 0f; internal const float HeadRollLimitDegrees = 18f; internal const bool IdleExamineEnabled = true; internal const float IdleScanYawRangeDegrees = 55f; internal const float IdleScanPitchRangeDegrees = 12f; internal const float IdleScanRollDegrees = 6f; internal const float IdleScanSpeedDegreesPerSecond = 26f; internal const float IdleScanHoldMinSeconds = 2.5f; internal const float IdleScanHoldMaxSeconds = 6f; internal const float IdleScanGlanceChance = 0.2f; internal const bool DoorwayDuckEnabled = true; internal const float DoorwayDuckProbeDistance = 1.15f; internal const float DoorwayDuckAngleDegrees = 32f; internal const float DoorwayDuckClearanceMargin = 0.08f; internal const float DoorwayDuckDegreesPerMeter = 55f; internal const bool DoorwayPeekEnabled = true; internal const float DoorwayPeekYawDegrees = 40f; internal const float DoorwayPeekRollDegrees = 14f; internal const float DoorwayPeekLookaheadDistance = 3f; internal const float DoorwayPeekMinimumTurnDegrees = 45f; internal const bool DevSnapSpawnNearPlayer = false; internal const float DevSpawnDistance = 6f; } [BepInPlugin("y4ngz.lethalcompany.creepydoll", "Y4NGZ Creepy Doll", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal const string BundleFilename = "y4ngzcreepydoll.bundle"; internal const string PrefabName = "Y4NGZCreepyDoll"; internal const string EnemyTypeAssetName = "CreepyDollEnemy"; internal const string DawnNamespace = "y4ngz_monsters"; internal const string DawnEnemyKey = "hushdoll"; internal const string ScanNodeSubtitle = "Break eye contact to resist"; internal const string BestiaryText = "Hushdoll\n\nDanger level: high\n\nA possessed robotic doll that lures workers with song and punishes sustained eye contact. Once its gaze takes hold, it turns and pulls the victim toward a neck slash. Breaking eye contact and putting solid cover between you and the doll interrupts the hypnosis.\n\n"; internal static ManualLogSource Log; internal static CreepyDollConfig ModConfig; internal static AssetBundle ModAssets; internal static EnemyType EnemyType; private static bool _netcodeInitialized; private static bool _loggedScanNodeLayer; private static Material _runtimeVisualMaterial; private static Material _runtimeDarkMaterial; private static Mesh _boundsBakeMesh; internal static bool StaticVisualTestMode => false; internal static float VisualYawOffsetDegrees => 0f; internal static bool StabilizeVisualRoot => true; internal static bool StabilizeVisualHorizontal => false; internal static float VisualGroundOffset => -0.04f; internal static bool PlayAttackAnimation => true; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; try { InitializeNetcodeRPCs(); ModConfig = new CreepyDollConfig(((BaseUnityPlugin)this).Config); if (!ModConfig.Enabled.Value) { Log.LogInfo((object)"Y4NGZ Creepy Doll is disabled by config."); } else { if (!LoadBundle()) { return; } GameObject val = LoadBundleAsset("Y4NGZCreepyDoll", "/y4ngzcreepydoll.prefab"); EnemyType = LoadBundleAsset("CreepyDollEnemy", "/creepydollenemy.asset"); if ((Object)(object)EnemyType != (Object)null && (Object)(object)EnemyType.enemyPrefab != (Object)null) { val = EnemyType.enemyPrefab; } if ((Object)(object)val == (Object)null) { Log.LogError((object)"Prefab 'Y4NGZCreepyDoll' not found in y4ngzcreepydoll.bundle."); DumpBundleAssets(); return; } PreparePrefab(val); if ((Object)(object)EnemyType == (Object)null) { EnemyType = CreateEnemyType(val); } else { ConfigureEnemyType(EnemyType, val); } CreepyDollAI component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((EnemyAI)component).enemyType = EnemyType; } RegisterWithDawn(val); Log.LogInfo((object)"Y4NGZ Creepy Doll v0.1.0 loaded. Registered as 'Hushdoll'."); } } catch (Exception arg) { Log.LogError((object)string.Format("[{0}] Initialization failed: {1}", "Y4NGZ Creepy Doll", arg)); } } private static void RegisterWithDawn(GameObject prefab) { HushdollSpawnWeights spawnWeights = new HushdollSpawnWeights(() => ModConfig.SpawnWeightMultiplier.Value); DawnLib.RegisterNetworkPrefab(prefab); DawnLib.DefineEnemy(NamespacedKey.From("y4ngz_monsters", "hushdoll"), EnemyType, (Action)delegate(EnemyInfoBuilder builder) { ((BaseInfoBuilder)(object)builder.DefineInside((Action)delegate(EnemyLocationBuilder location) { location.SetWeights((Action>)delegate(WeightTableBuilder table) { table.SetGlobalWeight((IWeighted)(object)spawnWeights); }); }).CreateBestiaryNode("Hushdoll\n\nDanger level: high\n\nA possessed robotic doll that lures workers with song and punishes sustained eye contact. Once its gaze takes hold, it turns and pulls the victim toward a neck slash. Breaking eye contact and putting solid cover between you and the doll interrupts the hypnosis.\n\n").CreateNameKeyword("hushdoll")).AddTags((IEnumerable)(object)new NamespacedKey[4] { Tags.Hostile, Tags.Mechanical, Tags.Biped, Tags.Medium }); }); } private static void InitializeNetcodeRPCs() { if (_netcodeInitialized) { return; } _netcodeInitialized = true; Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { MethodInfo[] methods; try { methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } catch { continue; } foreach (MethodInfo methodInfo in methods) { if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length == 0) { continue; } try { methodInfo.Invoke(null, null); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[NetcodeInit] " + type.Name + "." + methodInfo.Name + " failed: " + ex.Message)); } } } } } private static bool LoadBundle() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { Log.LogError((object)"Could not resolve plugin assembly directory."); return false; } string text = Path.Combine(directoryName, "y4ngzcreepydoll.bundle"); if (!File.Exists(text)) { Log.LogError((object)("Missing asset bundle: " + text)); return false; } ModAssets = AssetBundle.LoadFromFile(text); if ((Object)(object)ModAssets == (Object)null) { Log.LogError((object)("AssetBundle.LoadFromFile returned null for " + text + ".")); return false; } return true; } private static T LoadBundleAsset(string shortName, string pathEnding) where T : Object { T val = ModAssets.LoadAsset(shortName); if ((Object)(object)val != (Object)null) { return val; } string[] allAssetNames = ModAssets.GetAllAssetNames(); foreach (string text in allAssetNames) { string text2 = text.Replace('\\', '/'); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text2); if (text2.EndsWith(pathEnding, StringComparison.OrdinalIgnoreCase) || string.Equals(fileNameWithoutExtension, shortName, StringComparison.OrdinalIgnoreCase)) { val = ModAssets.LoadAsset(text); if ((Object)(object)val != (Object)null) { return val; } } } return default(T); } private static void PreparePrefab(GameObject prefab) { //IL_048a: Unknown result type (might be due to invalid IL or missing references) AssignUniqueNetworkHash(prefab, "Y4NGZCreepyDoll"); CreepyDollAI creepyDollAI = prefab.GetComponent(); if ((Object)(object)creepyDollAI == (Object)null) { creepyDollAI = prefab.AddComponent(); Log.LogWarning((object)"[CreepyDoll] Prefab was missing CreepyDollAI; added at runtime."); } NavMeshAgent val = prefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent(); Log.LogWarning((object)"[CreepyDoll] Prefab was missing a root NavMeshAgent; added at runtime."); } ((EnemyAI)creepyDollAI).agent = val; val.speed = ModConfig.MoveSpeed.Value; val.acceleration = 22.5f; val.angularSpeed = 150f; val.radius = 0.28f; val.height = 1.05f; val.baseOffset = 0f; val.stoppingDistance = Math.Max(0.5f, ModConfig.NeckSlashRange.Value * 0.72f); val.autoRepath = true; val.obstacleAvoidanceType = (ObstacleAvoidanceType)4; val.avoidancePriority = 45; Animator val2 = prefab.GetComponent() ?? prefab.GetComponentInChildren(true); if ((Object)(object)val2 != (Object)null) { ConfigureAnimatorForCurrentMode(val2, "prefab"); ((EnemyAI)creepyDollAI).creatureAnimator = val2; } RepairVisuals(prefab, "prefab"); ApplyVisualYawOffset(prefab, "prefab"); ((EnemyAI)creepyDollAI).creatureSFX = FindAudioSource(prefab, "CreatureSFX"); ((EnemyAI)creepyDollAI).creatureVoice = FindAudioSource(prefab, "CreatureVoice") ?? ((EnemyAI)creepyDollAI).creatureSFX; creepyDollAI.stepAudioSource = FindAudioSource(prefab, "StepSFX") ?? ((EnemyAI)creepyDollAI).creatureSFX; creepyDollAI.idleAudioSource = FindAudioSource(prefab, "IdleVoice") ?? ((EnemyAI)creepyDollAI).creatureVoice ?? ((EnemyAI)creepyDollAI).creatureSFX; creepyDollAI.constantAudioSource = FindAudioSource(prefab, "ConstantLoopSFX") ?? ((EnemyAI)creepyDollAI).creatureSFX; creepyDollAI.mindControlAudioSource = FindAudioSource(prefab, "MindControlSFX") ?? ((EnemyAI)creepyDollAI).creatureVoice ?? ((EnemyAI)creepyDollAI).creatureSFX; if (creepyDollAI.stepClips == null || creepyDollAI.stepClips.Length == 0) { creepyDollAI.stepClips = LoadBundleAudioClips("step01.wav", "step02.wav", "step03.wav", "step04.wav", "step05.wav", "step06.wav", "step07.wav"); } if (creepyDollAI.stepClipsConcrete == null || creepyDollAI.stepClipsConcrete.Length == 0) { creepyDollAI.stepClipsConcrete = LoadBundleAudioClips("footstep_concrete_a_1.ogg", "footstep_concrete_a_2.ogg", "footstep_concrete_a_3.ogg", "footstep_concrete_a_4.ogg"); } if (creepyDollAI.stepClipsMetal == null || creepyDollAI.stepClipsMetal.Length == 0) { creepyDollAI.stepClipsMetal = LoadBundleAudioClips("footstep_metal_a_1.ogg", "footstep_metal_a_2.ogg", "footstep_metal_a_3.ogg", "footstep_metal_a_4.ogg"); } if (creepyDollAI.stepClipsWood == null || creepyDollAI.stepClipsWood.Length == 0) { creepyDollAI.stepClipsWood = LoadBundleAudioClips("footstep_wood_a_1.ogg", "footstep_wood_a_2.ogg", "footstep_wood_a_3.ogg", "footstep_wood_a_4.ogg"); } if (creepyDollAI.idleClips == null || creepyDollAI.idleClips.Length == 0) { creepyDollAI.idleClips = LoadBundleAudioClips("idle 1.mp3", "idle 2.mp3", "idle noise.wav"); } if (creepyDollAI.folleyClips == null || creepyDollAI.folleyClips.Length == 0) { creepyDollAI.folleyClips = LoadBundleAudioClips("folley01.ogg", "folley02.ogg"); } if ((Object)(object)creepyDollAI.constantClip == (Object)null) { creepyDollAI.constantClip = LoadBundleAudioClip("static_loop_1.ogg"); } if ((Object)(object)creepyDollAI.constantClip == (Object)null) { creepyDollAI.constantClip = LoadBundleAudioClip("constant.mp3"); } if ((Object)(object)creepyDollAI.mindControlClip == (Object)null) { creepyDollAI.mindControlClip = LoadBundleAudioClip("mindcontrol.wav"); } if (creepyDollAI.mindControlClips == null || creepyDollAI.mindControlClips.Length == 0) { creepyDollAI.mindControlClips = LoadBundleAudioClips("doll_siren_v1.wav", "doll_siren_v2.wav", "doll_siren_v3.wav", "doll_siren_v4.wav", "doll_siren_v5.wav"); } if ((Object)(object)creepyDollAI.killClip == (Object)null) { creepyDollAI.killClip = LoadBundleAudioClip("slash_kill.ogg"); } if ((Object)(object)creepyDollAI.killClip == (Object)null) { creepyDollAI.killClip = LoadBundleAudioClip("kill.mp3"); } if ((Object)(object)creepyDollAI.headSnapClip == (Object)null) { creepyDollAI.headSnapClip = LoadBundleAudioClip("head_snap.wav"); } Transform val3 = prefab.transform.Find("Eye"); if ((Object)(object)val3 != (Object)null) { val3.localPosition = new Vector3(0f, 2f, 0.18f); ((EnemyAI)creepyDollAI).eye = val3; } Transform val4 = prefab.transform.Find("AttackOrigin"); if ((Object)(object)val4 != (Object)null) { creepyDollAI.attackOrigin = val4; } EnsureScanNode(prefab); EnsureCollision(prefab, creepyDollAI); RepairKneeHeightMarkers(prefab); DisablePhysicalVisualColliders(prefab); } private static void RepairKneeHeightMarkers(GameObject prefab) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) Transform val = prefab.transform.Find("CollisionDetect") ?? prefab.transform.Find("Collision"); if (MarkerIsKneeHeight(val)) { MoveMarkerTo(val, 1.1f); Collider component = ((Component)val).GetComponent(); CapsuleCollider val2 = (CapsuleCollider)(object)((component is CapsuleCollider) ? component : null); if (val2 != null) { val2.direction = 1; val2.center = Vector3.zero; val2.radius = 0.42f; val2.height = 2.2f; } else { BoxCollider val3 = (BoxCollider)(object)((component is BoxCollider) ? component : null); if (val3 != null) { val3.center = Vector3.zero; val3.size = new Vector3(0.84f, 2.2f, 0.84f); } } } Transform marker = prefab.transform.Find("ScanNode"); if (MarkerIsKneeHeight(marker)) { MoveMarkerTo(marker, 1.4f); } Transform marker2 = prefab.transform.Find("AttackOrigin"); if (MarkerIsKneeHeight(marker2)) { MoveMarkerTo(marker2, 1.5f); } } private static bool MarkerIsKneeHeight(Transform marker) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)marker != (Object)null) { return marker.localPosition.y < 0.7f; } return false; } private static void MoveMarkerTo(Transform marker, float localHeight) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0046: Unknown result type (might be due to invalid IL or missing references) Vector3 localPosition = marker.localPosition; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[CreepyDoll] Repositioned bundled '{((Object)marker).name}' from y={localPosition.y:0.00} to y={localHeight:0.00} (#96)."); } marker.localPosition = new Vector3(localPosition.x, localHeight, localPosition.z); } internal static void EnsureScanNode(GameObject prefab) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) ScanNodeProperties val = null; ScanNodeProperties[] componentsInChildren = prefab.GetComponentsInChildren(true); foreach (ScanNodeProperties val2 in componentsInChildren) { bool flag = val2.creatureScanID >= 0; bool flag2 = (Object)(object)val != (Object)null && val.creatureScanID >= 0; bool flag3 = string.Equals(((Object)((Component)val2).gameObject).name, "ScanNode", StringComparison.Ordinal); bool flag4 = (Object)(object)val != (Object)null && string.Equals(((Object)((Component)val).gameObject).name, "ScanNode", StringComparison.Ordinal); if ((Object)(object)val == (Object)null || (flag && !flag2) || (flag == flag2 && flag3 && !flag4)) { val = val2; } } if (componentsInChildren.Length > 1) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[Hushdoll] Found {componentsInChildren.Length} scan nodes; retiring every duplicate."); } } for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)(object)val) { RetireExtraScanNode(componentsInChildren[j], val, prefab); } } Transform val3 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : FindOrCreateChild(prefab.transform, "ScanNode", new Vector3(0f, 1.4f, 0f))); ((Object)((Component)val3).gameObject).name = "ScanNode"; TrySetTag(((Component)val3).gameObject, "DoNotSet"); TrySetLayer(((Component)val3).gameObject, "ScanNode"); EnsureHierarchyActive(val3, prefab.transform); ((Component)val3).gameObject.SetActive(true); if (!_loggedScanNodeLayer) { _loggedScanNodeLayer = true; ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)($"[Hushdoll] Scan node layer resolved to {((Component)val3).gameObject.layer} " + string.Format("(NameToLayer(\"ScanNode\")={0}, fallback 22); ", LayerMask.NameToLayer("ScanNode")) + $"active={((Component)val3).gameObject.activeInHierarchy}.")); } } BoxCollider obj = ((Component)val3).GetComponent() ?? ((Component)val3).gameObject.AddComponent(); ((Collider)obj).enabled = true; ((Collider)obj).isTrigger = true; obj.center = Vector3.zero; obj.size = new Vector3(0.75f, 1.35f, 0.75f); Rigidbody obj2 = ((Component)val3).GetComponent() ?? ((Component)val3).gameObject.AddComponent(); obj2.isKinematic = true; obj2.useGravity = false; obj2.detectCollisions = true; val = val ?? ((Component)val3).gameObject.AddComponent(); val.headerText = "Hushdoll"; val.subText = "Break eye contact to resist"; val.maxRange = 13; val.minRange = 1; val.requiresLineOfSight = true; val.nodeType = 1; } private static void RetireExtraScanNode(ScanNodeProperties extra, ScanNodeProperties preferred, GameObject root) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0085: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)extra == (Object)null) { return; } Scene scene; if ((Object)(object)((Component)extra).gameObject == (Object)(object)root || ((Object)(object)preferred != (Object)null && (Object)(object)((Component)extra).gameObject == (Object)(object)((Component)preferred).gameObject)) { scene = root.scene; if (((Scene)(ref scene)).IsValid()) { Object.Destroy((Object)(object)extra); } else { Object.DestroyImmediate((Object)(object)extra, true); } return; } GameObject gameObject = ((Component)extra).gameObject; gameObject.SetActive(false); Collider[] components = gameObject.GetComponents(); for (int i = 0; i < components.Length; i++) { components[i].enabled = false; } scene = root.scene; if (((Scene)(ref scene)).IsValid()) { Object.Destroy((Object)(object)gameObject); } else { Object.DestroyImmediate((Object)(object)gameObject, true); } } internal static void EnsureCollision(GameObject prefab, CreepyDollAI ai) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) TrySetTag(prefab, "Enemy"); TrySetLayer(prefab, "Enemies"); CapsuleCollider obj = prefab.GetComponent() ?? prefab.AddComponent(); ((Collider)obj).enabled = true; ((Collider)obj).isTrigger = false; obj.direction = 1; obj.center = new Vector3(0f, 0.6f, 0f); obj.radius = 0.26f; obj.height = 1.25f; Transform val = prefab.transform.Find("CollisionDetect") ?? prefab.transform.Find("Collision") ?? FindOrCreateChild(prefab.transform, "CollisionDetect", new Vector3(0f, 0.7f, 0f)); TrySetTag(((Component)val).gameObject, "Enemy"); TrySetLayer(((Component)val).gameObject, "Enemies"); Collider val2 = ((Component)val).GetComponent(); if ((Object)(object)val2 == (Object)null) { CapsuleCollider obj2 = ((Component)val).gameObject.AddComponent(); obj2.direction = 1; obj2.center = Vector3.zero; obj2.radius = 0.42f; obj2.height = 1.45f; val2 = (Collider)(object)obj2; } val2.enabled = true; val2.isTrigger = true; Collider[] components = ((Component)val).GetComponents(); for (int i = 0; i < components.Length; i++) { if ((Object)(object)components[i] != (Object)null && (Object)(object)components[i] != (Object)(object)val2) { components[i].enabled = false; } } Rigidbody obj3 = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); obj3.isKinematic = true; obj3.useGravity = false; obj3.detectCollisions = true; EnemyAICollisionDetect obj4 = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); obj4.mainScript = (EnemyAI)(object)ai; obj4.alwaysAllowHitting = true; obj4.canCollideWithEnemies = false; obj4.onlyCollideWhenGrounded = false; RepairCollisionDetectMainScripts(prefab, ai); } internal static int RepairCollisionDetectMainScripts(GameObject root, CreepyDollAI ai) { if ((Object)(object)root == (Object)null || (Object)(object)ai == (Object)null) { return 0; } EnemyAICollisionDetect[] componentsInChildren = root.GetComponentsInChildren(true); int num = 0; foreach (EnemyAICollisionDetect val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { if ((Object)(object)val.mainScript != (Object)(object)ai) { val.mainScript = (EnemyAI)(object)ai; num++; } val.alwaysAllowHitting = true; val.canCollideWithEnemies = false; val.onlyCollideWhenGrounded = false; } } return num; } internal static int DisablePhysicalVisualColliders(GameObject root) { if ((Object)(object)root == (Object)null) { return 0; } Transform val = root.transform.Find("VisualRoot"); if ((Object)(object)val == (Object)null) { return 0; } Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); int num = 0; foreach (Collider val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).GetComponentInParent() != (Object)null)) { val2.enabled = false; num++; } } return num; } private static AudioClip LoadBundleAudioClip(string fileName) { AudioClip obj = LoadBundleAsset(Path.GetFileNameWithoutExtension(fileName), "/" + fileName); if ((Object)(object)obj == (Object)null) { ManualLogSource log = Log; if (log == null) { return obj; } log.LogWarning((object)("[CreepyDoll] Missing bundled audio clip '" + fileName + "'.")); } return obj; } private static AudioClip[] LoadBundleAudioClips(params string[] fileNames) { List list = new List(fileNames.Length); for (int i = 0; i < fileNames.Length; i++) { AudioClip val = LoadBundleAudioClip(fileNames[i]); if ((Object)(object)val != (Object)null) { list.Add(val); } } return list.ToArray(); } internal static int RepairVisuals(GameObject root, string context) { //IL_00e8: 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) //IL_0101: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return 0; } Material val = CreateRuntimeVisualMaterial(root); Material val2 = CreateRuntimeDarkMaterial(((Object)(object)val != (Object)null) ? val.shader : null); Renderer[] componentsInChildren = root.GetComponentsInChildren(true); int num = 0; int num2 = 0; int num3 = 0; foreach (Renderer val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent() != (Object)null)) { EnsureHierarchyActive(((Component)val3).transform, root.transform); ((Component)val3).gameObject.layer = 0; val3.enabled = true; val3.forceRenderingOff = false; val3.allowOcclusionWhenDynamic = false; val3.shadowCastingMode = (ShadowCastingMode)1; val3.receiveShadows = true; val3.SetPropertyBlock((MaterialPropertyBlock)null); SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((val3 is SkinnedMeshRenderer) ? val3 : null); if ((Object)(object)val4 != (Object)null) { num2++; val4.updateWhenOffscreen = true; ((Renderer)val4).localBounds = new Bounds(new Vector3(0f, 1.05f, 0f), new Vector3(12f, 12f, 12f)); } else if (val3 is MeshRenderer) { num3++; } if ((Object)(object)val != (Object)null) { AssignMaterial(val3, val, val2); } num++; } } if (Log != null) { string primaryTextureName = GetPrimaryTextureName(val); ManualLogSource log = Log; object[] obj = new object[8] { context, ((Object)root).name, num, num2, num3, null, null, null }; object obj2; if (val == null) { obj2 = null; } else { Shader shader = val.shader; obj2 = ((shader != null) ? ((Object)shader).name : null); } if (obj2 == null) { obj2 = "none"; } obj[5] = obj2; object obj3; if (val2 == null) { obj3 = null; } else { Shader shader2 = val2.shader; obj3 = ((shader2 != null) ? ((Object)shader2).name : null); } if (obj3 == null) { obj3 = "none"; } obj[6] = obj3; obj[7] = primaryTextureName; log.LogInfo((object)string.Format("[CreepyDoll] Visual repair ({0}) on '{1}': renderers={2}, skinned={3}, mesh={4}, material={5} (forced runtime), darkMaterial={6}, texture={7}.", obj)); LogVisualDiagnostics(root, context); } return num; } private static Material FindExistingVisualMaterial(GameObject root) { if ((Object)(object)root == (Object)null) { return null; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponentInParent() != (Object)null) { continue; } Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null) { continue; } foreach (Material val2 in sharedMaterials) { if (MaterialHasVisualTexture(val2)) { return val2; } } } return null; } private static bool MaterialHasVisualTexture(Material material) { if ((Object)(object)material == (Object)null || (Object)(object)material.shader == (Object)null) { return false; } if (!((Object)(object)GetTextureIfPresent(material, "_BaseColorMap") != (Object)null) && !((Object)(object)GetTextureIfPresent(material, "_MainTex") != (Object)null) && !((Object)(object)GetTextureIfPresent(material, "_UnlitColorMap") != (Object)null)) { return (Object)(object)GetTextureIfPresent(material, "_BaseMap") != (Object)null; } return true; } private static string GetPrimaryTextureName(Material material) { Texture val = GetTextureIfPresent(material, "_BaseColorMap") ?? GetTextureIfPresent(material, "_MainTex") ?? GetTextureIfPresent(material, "_UnlitColorMap") ?? GetTextureIfPresent(material, "_BaseMap"); if (!((Object)(object)val != (Object)null)) { return ""; } return ((Object)val).name; } internal static void ApplyVisualYawOffset(GameObject root, string context, bool log = true) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } Transform val = root.transform.Find("VisualRoot"); if ((Object)(object)val == (Object)null) { return; } float visualYawOffsetDegrees = VisualYawOffsetDegrees; val.localRotation = Quaternion.Euler(0f, visualYawOffsetDegrees, 0f); if (log) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)$"[CreepyDoll] Applied visual yaw offset {visualYawOffsetDegrees:0.##} degrees to '{GetHierarchyPath(root.transform, val)}' ({context})."); } } } internal static void StabilizeVisualTransform(GameObject root) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (!StabilizeVisualRoot || (Object)(object)root == (Object)null) { return; } Transform val = root.transform.Find("VisualRoot"); if (!((Object)(object)val == (Object)null) && TryGetVisualRendererBounds(root, out var bounds)) { float num = ResolveGroundY(root) + VisualGroundOffset - ((Bounds)(ref bounds)).min.y; if (!float.IsNaN(num) && !(Mathf.Abs(num) > 2.5f)) { Vector3 localPosition = val.localPosition; localPosition.y = Mathf.Clamp(localPosition.y + num, -2.25f, 0.5f); val.localPosition = localPosition; } } } internal static void ConfigureAnimatorForCurrentMode(Animator animator, string context) { if ((Object)(object)animator == (Object)null) { return; } animator.applyRootMotion = false; animator.cullingMode = (AnimatorCullingMode)0; if (!StaticVisualTestMode) { ((Behaviour)animator).enabled = true; return; } string text = (((Object)(object)animator.runtimeAnimatorController != (Object)null) ? ((Object)animator.runtimeAnimatorController).name : ""); animator.runtimeAnimatorController = null; ((Behaviour)animator).enabled = false; ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[CreepyDoll] Static visual test mode is ON for " + context + "; disabled Animator '" + ((Object)animator).name + "' controller '" + text + "'. This spawn should show the imported/rest doll mesh without pack animation deformation.")); } } internal static void LogVisualDiagnostics(GameObject root, string context) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_0098: 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) if ((Object)(object)root == (Object)null || Log == null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); int num = 0; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null)) { Material sharedMaterial = val.sharedMaterial; string text = (((Object)(object)sharedMaterial != (Object)null && (Object)(object)sharedMaterial.shader != (Object)null) ? ((Object)sharedMaterial.shader).name : ""); Bounds bounds = val.bounds; object arg = ((Bounds)(ref bounds)).center; bounds = val.bounds; string text2 = $"center={arg}, size={((Bounds)(ref bounds)).size}"; SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null); string text3 = (((Object)(object)val2 != (Object)null) ? string.Format(", updateWhenOffscreen={0}, rootBone={1}", val2.updateWhenOffscreen, ((Object)(object)val2.rootBone != (Object)null) ? ((Object)val2.rootBone).name : "") : string.Empty); string materialSlotSummary = GetMaterialSlotSummary(val); Log.LogInfo((object)$"[CreepyDoll] Visual {context} renderer '{GetHierarchyPath(root.transform, ((Component)val).transform)}': active={((Component)val).gameObject.activeInHierarchy}, enabled={val.enabled}, layer={((Component)val).gameObject.layer}, shader={text}, materials={materialSlotSummary}, {text2}{text3}."); num++; if (num >= 4) { break; } } } if (num == 0) { Log.LogWarning((object)("[CreepyDoll] Visual diagnostics (" + context + ") found no non-scan renderers under '" + ((Object)root).name + "'.")); } } private static string GetMaterialSlotSummary(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return "[]"; } Material[] sharedMaterials = renderer.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { return "[]"; } string[] array = new string[sharedMaterials.Length]; for (int i = 0; i < sharedMaterials.Length; i++) { Material val = sharedMaterials[i]; string arg = (((Object)(object)val != (Object)null) ? ((Object)val).name : ""); string arg2 = (((Object)(object)val != (Object)null && (Object)(object)val.shader != (Object)null) ? ((Object)val.shader).name : ""); array[i] = $"{i}:{arg}/{arg2}"; } return "[" + string.Join(", ", array) + "]"; } private static bool TryGetVisualRendererBounds(GameObject root, out Bounds bounds) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) bounds = new Bounds(((Object)(object)root != (Object)null) ? root.transform.position : Vector3.zero, Vector3.zero); if ((Object)(object)root == (Object)null) { return false; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); bool flag = false; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null) && val.enabled && ((Component)val).gameObject.activeInHierarchy && TryGetActualRendererBounds(val, out var bounds2)) { if (!flag) { bounds = bounds2; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(bounds2); } } } return flag; } private static bool TryGetActualRendererBounds(Renderer renderer, out Bounds bounds) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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) //IL_0123: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) bounds = new Bounds(((Object)(object)renderer != (Object)null) ? ((Component)renderer).transform.position : Vector3.zero, Vector3.zero); if ((Object)(object)renderer == (Object)null) { return false; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null && !BoundsLooksUsable(renderer.bounds)) { try { if ((Object)(object)_boundsBakeMesh == (Object)null) { _boundsBakeMesh = new Mesh { name = "CreepyDollBoundsBakeMesh" }; _boundsBakeMesh.MarkDynamic(); } _boundsBakeMesh.Clear(); val.BakeMesh(_boundsBakeMesh); if (_boundsBakeMesh.vertexCount > 0) { bounds = TransformBounds(_boundsBakeMesh.bounds, ((Component)val).transform.localToWorldMatrix); return BoundsLooksUsable(bounds); } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("[CreepyDoll] Failed to bake skinned bounds for '" + ((Object)renderer).name + "': " + ex.Message)); } } } bounds = renderer.bounds; return BoundsLooksUsable(bounds); } private static Bounds TransformBounds(Bounds localBounds, Matrix4x4 localToWorld) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0015: 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_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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Matrix4x4)(ref localToWorld)).MultiplyPoint3x4(((Bounds)(ref localBounds)).center); Vector3 extents = ((Bounds)(ref localBounds)).extents; Vector3 val2 = ((Matrix4x4)(ref localToWorld)).MultiplyVector(new Vector3(extents.x, 0f, 0f)); Vector3 val3 = ((Matrix4x4)(ref localToWorld)).MultiplyVector(new Vector3(0f, extents.y, 0f)); Vector3 val4 = ((Matrix4x4)(ref localToWorld)).MultiplyVector(new Vector3(0f, 0f, extents.z)); ((Vector3)(ref extents))..ctor(Mathf.Abs(val2.x) + Mathf.Abs(val3.x) + Mathf.Abs(val4.x), Mathf.Abs(val2.y) + Mathf.Abs(val3.y) + Mathf.Abs(val4.y), Mathf.Abs(val2.z) + Mathf.Abs(val3.z) + Mathf.Abs(val4.z)); return new Bounds(val, extents * 2f); } private static bool BoundsLooksUsable(Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0022: Unknown result type (might be due to invalid IL or missing references) Vector3 size = ((Bounds)(ref bounds)).size; if (!float.IsNaN(size.x) && !float.IsNaN(size.y) && !float.IsNaN(size.z)) { return ((Vector3)(ref size)).sqrMagnitude > 0.0001f; } return false; } private static float ResolveGroundY(GameObject root) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0089: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return 0f; } NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(root.transform.position, ref val, 8f, -1)) { return ((NavMeshHit)(ref val)).position.y; } RaycastHit[] array = Physics.RaycastAll(root.transform.position + Vector3.up * 3f, Vector3.down, 12f, -1, (QueryTriggerInteraction)1); float num = float.MaxValue; float y = root.transform.position.y; bool flag = false; for (int i = 0; i < array.Length; i++) { RaycastHit val2 = array[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(root.transform) && ((RaycastHit)(ref val2)).distance < num) { num = ((RaycastHit)(ref val2)).distance; y = ((RaycastHit)(ref val2)).point.y; flag = true; } } if (flag) { return y; } return root.transform.position.y; } private static void AssignMaterial(Renderer renderer, Material material, Material darkMaterial) { if ((Object)(object)renderer == (Object)null || (Object)(object)material == (Object)null) { return; } Material[] sharedMaterials = renderer.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { renderer.sharedMaterial = material; return; } for (int i = 0; i < sharedMaterials.Length; i++) { if (IsDarkMaterialSlot(sharedMaterials[i], i, sharedMaterials.Length)) { sharedMaterials[i] = (ShouldPreserveDarkMaterial(sharedMaterials[i]) ? sharedMaterials[i] : (darkMaterial ?? material)); } else { sharedMaterials[i] = material; } } renderer.sharedMaterials = sharedMaterials; } private static bool IsDarkMaterialSlot(Material material, int index, int materialCount) { string text = (((Object)(object)material != (Object)null) ? ((Object)material).name : string.Empty); if (text.IndexOf("dark", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("rigid", StringComparison.OrdinalIgnoreCase) < 0) { if (materialCount > 1) { return index == 0; } return false; } return true; } private static bool ShouldPreserveDarkMaterial(Material material) { if ((Object)(object)material == (Object)null) { return false; } string text = ((Object)material).name ?? string.Empty; if (text.IndexOf("CreepyDollDarkRigid", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("RuntimeDarkRigid", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (text.IndexOf("dark", StringComparison.OrdinalIgnoreCase) < 0) { return text.IndexOf("rigid", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static Material CreateRuntimeVisualMaterial(GameObject root) { //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_runtimeVisualMaterial != (Object)null) { return _runtimeVisualMaterial; } Shader val = Shader.Find("HDRP/Lit") ?? Shader.Find("High Definition Render Pipeline/Lit") ?? Shader.Find("HDRenderPipeline/Lit") ?? Shader.Find("HDRP/Unlit") ?? Shader.Find("High Definition Render Pipeline/Unlit") ?? Shader.Find("HDRenderPipeline/Unlit") ?? Shader.Find("Standard") ?? Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Unlit/Texture") ?? Shader.Find("Unlit/Color"); if ((Object)(object)val == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"[CreepyDoll] Could not find a compatible runtime shader for the visual material."); } return null; } Texture val2 = FindBaseTextureFromPrefab(root); Texture val3 = FindBundledTextureByScore(ScoreNormalTextureAssetName); Texture val4 = FindBundledTextureByScore(ScoreMaskMapTextureAssetName); Texture val5 = FindBundledTextureByScore(ScoreMetallicTextureAssetName); Texture val6 = FindBundledTextureByScore(ScoreAmbientOcclusionTextureAssetName); _runtimeVisualMaterial = new Material(val) { name = "CreepyDoll_RuntimeVisible", doubleSidedGI = true, renderQueue = 2000 }; if ((Object)(object)val2 != (Object)null) { SetTextureIfPresent(_runtimeVisualMaterial, "_BaseColorMap", val2); SetTextureIfPresent(_runtimeVisualMaterial, "_MainTex", val2); SetTextureIfPresent(_runtimeVisualMaterial, "_UnlitColorMap", val2); SetTextureIfPresent(_runtimeVisualMaterial, "_BaseMap", val2); SetColorIfPresent(_runtimeVisualMaterial, "_UnlitColor", Color.white); SetColorIfPresent(_runtimeVisualMaterial, "_BaseColor", Color.white); SetColorIfPresent(_runtimeVisualMaterial, "_Color", Color.white); ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)("[CreepyDoll] Runtime visual material using texture '" + ((Object)val2).name + "' with shader '" + ((Object)val).name + "'.")); } } else { Color value = default(Color); ((Color)(ref value))..ctor(1f, 0.2f, 0.85f, 1f); SetColorIfPresent(_runtimeVisualMaterial, "_UnlitColor", value); SetColorIfPresent(_runtimeVisualMaterial, "_BaseColor", value); SetColorIfPresent(_runtimeVisualMaterial, "_Color", value); ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)("[CreepyDoll] Runtime visual material could not find a texture; using fallback color with shader '" + ((Object)val).name + "'.")); } } if ((Object)(object)val3 != (Object)null) { SetTextureIfPresent(_runtimeVisualMaterial, "_NormalMap", val3); SetTextureIfPresent(_runtimeVisualMaterial, "_BumpMap", val3); SetFloatIfPresent(_runtimeVisualMaterial, "_NormalScale", 1f); SetFloatIfPresent(_runtimeVisualMaterial, "_BumpScale", 1f); SetFloatIfPresent(_runtimeVisualMaterial, "_NormalMapSpace", 0f); _runtimeVisualMaterial.EnableKeyword("_NORMALMAP"); _runtimeVisualMaterial.EnableKeyword("_NORMALMAP_TANGENT_SPACE"); } if ((Object)(object)val4 != (Object)null) { SetTextureIfPresent(_runtimeVisualMaterial, "_MaskMap", val4); _runtimeVisualMaterial.EnableKeyword("_MASKMAP"); } if ((Object)(object)val5 != (Object)null) { SetTextureIfPresent(_runtimeVisualMaterial, "_MetallicGlossMap", val5); } if ((Object)(object)val6 != (Object)null) { SetTextureIfPresent(_runtimeVisualMaterial, "_OcclusionMap", val6); } bool flag = (Object)(object)val4 != (Object)null && ((Object)val4).name != null && ((Object)val4).name.IndexOf("hdrp", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)val4).name.IndexOf("maskmap", StringComparison.OrdinalIgnoreCase) >= 0; SetFloatIfPresent(_runtimeVisualMaterial, "_Metallic", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_Smoothness", flag ? 0.35f : 0.28f); SetFloatIfPresent(_runtimeVisualMaterial, "_SmoothnessRemapMin", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_SmoothnessRemapMax", 0.35f); SetFloatIfPresent(_runtimeVisualMaterial, "_Glossiness", flag ? 0.35f : 0.28f); SetFloatIfPresent(_runtimeVisualMaterial, "_SurfaceType", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_BlendMode", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_AlphaCutoffEnable", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_ZWrite", 1f); SetFloatIfPresent(_runtimeVisualMaterial, "_Cull", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_CullMode", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_CullModeForward", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_OpaqueCullMode", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_TransparentCullMode", 0f); SetFloatIfPresent(_runtimeVisualMaterial, "_DoubleSidedEnable", 1f); SetFloatIfPresent(_runtimeVisualMaterial, "_EmissiveIntensity", 0.25f); SetFloatIfPresent(_runtimeVisualMaterial, "_AlbedoAffectEmissive", 1f); SetColorIfPresent(_runtimeVisualMaterial, "_DoubleSidedConstants", new Color(1f, 1f, -1f, 0f)); SetColorIfPresent(_runtimeVisualMaterial, "_EmissiveColor", new Color(0.12f, 0.12f, 0.12f, 1f)); _runtimeVisualMaterial.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); _runtimeVisualMaterial.DisableKeyword("_ALPHATEST_ON"); _runtimeVisualMaterial.DisableKeyword("_ALPHABLEND_ON"); _runtimeVisualMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON"); if ((Object)(object)val3 == (Object)null) { _runtimeVisualMaterial.DisableKeyword("_NORMALMAP"); _runtimeVisualMaterial.DisableKeyword("_NORMALMAP_TANGENT_SPACE"); } if ((Object)(object)val4 == (Object)null) { _runtimeVisualMaterial.DisableKeyword("_MASKMAP"); } _runtimeVisualMaterial.EnableKeyword("_DOUBLESIDED_ON"); SetFloatIfPresent(_runtimeVisualMaterial, "_EnableGeometricSpecularAA", 1f); SetFloatIfPresent(_runtimeVisualMaterial, "_SpecularAAScreenSpaceVariance", 0.1f); SetFloatIfPresent(_runtimeVisualMaterial, "_SpecularAAThreshold", 0.2f); if (_runtimeVisualMaterial.HasProperty("_EnableGeometricSpecularAA")) { _runtimeVisualMaterial.EnableKeyword("_ENABLE_GEOMETRIC_SPECULAR_AA"); } return _runtimeVisualMaterial; } private static Material CreateRuntimeDarkMaterial(Shader shader) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00ec: 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) //IL_010c: 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) if ((Object)(object)_runtimeDarkMaterial != (Object)null) { return _runtimeDarkMaterial; } shader = shader ?? Shader.Find("HDRP/Lit") ?? Shader.Find("High Definition Render Pipeline/Lit") ?? Shader.Find("HDRenderPipeline/Lit") ?? Shader.Find("HDRP/Unlit") ?? Shader.Find("High Definition Render Pipeline/Unlit") ?? Shader.Find("HDRenderPipeline/Unlit") ?? Shader.Find("Standard") ?? Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Unlit/Color"); if ((Object)(object)shader == (Object)null) { return null; } _runtimeDarkMaterial = new Material(shader) { name = "CreepyDoll_RuntimeDarkRigid", doubleSidedGI = true, renderQueue = 2000 }; Color value = default(Color); ((Color)(ref value))..ctor(0.24f, 0.235f, 0.25f, 1f); SetColorIfPresent(_runtimeDarkMaterial, "_UnlitColor", value); SetColorIfPresent(_runtimeDarkMaterial, "_BaseColor", value); SetColorIfPresent(_runtimeDarkMaterial, "_Color", value); SetFloatIfPresent(_runtimeDarkMaterial, "_Metallic", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_Smoothness", 0.12f); SetFloatIfPresent(_runtimeDarkMaterial, "_SmoothnessRemapMin", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_SmoothnessRemapMax", 0.18f); SetFloatIfPresent(_runtimeDarkMaterial, "_Glossiness", 0.12f); SetFloatIfPresent(_runtimeDarkMaterial, "_SurfaceType", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_BlendMode", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_AlphaCutoffEnable", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_ZWrite", 1f); SetFloatIfPresent(_runtimeDarkMaterial, "_Cull", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_CullMode", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_CullModeForward", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_OpaqueCullMode", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_TransparentCullMode", 0f); SetFloatIfPresent(_runtimeDarkMaterial, "_DoubleSidedEnable", 1f); SetColorIfPresent(_runtimeDarkMaterial, "_DoubleSidedConstants", new Color(1f, 1f, -1f, 0f)); _runtimeDarkMaterial.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); _runtimeDarkMaterial.DisableKeyword("_ALPHATEST_ON"); _runtimeDarkMaterial.DisableKeyword("_ALPHABLEND_ON"); _runtimeDarkMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON"); _runtimeDarkMaterial.DisableKeyword("_NORMALMAP"); _runtimeDarkMaterial.DisableKeyword("_NORMALMAP_TANGENT_SPACE"); _runtimeDarkMaterial.EnableKeyword("_DOUBLESIDED_ON"); return _runtimeDarkMaterial; } private static Texture FindBaseTextureFromPrefab(GameObject root) { if ((Object)(object)root == (Object)null) { return null; } Texture val = FindBestBundledTexture(); if ((Object)(object)val != (Object)null) { return val; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } Material[] sharedMaterials = val2.sharedMaterials; if (sharedMaterials == null) { continue; } foreach (Material val3 in sharedMaterials) { if (!((Object)(object)val3 == (Object)null)) { Texture val4 = GetTextureIfPresent(val3, "_BaseColorMap") ?? GetTextureIfPresent(val3, "_MainTex") ?? GetTextureIfPresent(val3, "_UnlitColorMap") ?? GetTextureIfPresent(val3, "_BaseMap"); if ((Object)(object)val4 != (Object)null) { return val4; } } } } return null; } private static Texture FindBestBundledTexture() { return FindBundledTextureByScore(ScoreTextureAssetName); } private static Texture FindBundledTextureByScore(Func scoreTexture) { if ((Object)(object)ModAssets == (Object)null || scoreTexture == null) { return null; } Texture result = null; int num = int.MinValue; string[] allAssetNames = ModAssets.GetAllAssetNames(); foreach (string text in allAssetNames) { string text2 = text.Replace('\\', '/'); if (!text2.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) && !text2.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) { continue; } int num2 = scoreTexture(text2); if (num2 > num) { Texture val = ModAssets.LoadAsset(text); if ((Object)(object)val != (Object)null) { result = val; num = num2; } } } if (num <= 0) { return null; } return result; } private static int ScoreTextureAssetName(string normalized) { int num = 0; if (normalized.IndexOf("/textures/", StringComparison.OrdinalIgnoreCase) >= 0) { num += 100; } if (normalized.IndexOf("lambert1_albedo", StringComparison.OrdinalIgnoreCase) >= 0) { num += 80; } if (normalized.IndexOf("albedo", StringComparison.OrdinalIgnoreCase) >= 0) { num += 50; } if (normalized.IndexOf("diffuse", StringComparison.OrdinalIgnoreCase) >= 0) { num += 40; } if (normalized.IndexOf("creepydoll_basecolor", StringComparison.OrdinalIgnoreCase) >= 0) { num += 80; } if (normalized.IndexOf("basecolor", StringComparison.OrdinalIgnoreCase) >= 0) { num += 40; } if (normalized.IndexOf("mask", StringComparison.OrdinalIgnoreCase) >= 0) { num -= 80; } if (normalized.IndexOf("texture", StringComparison.OrdinalIgnoreCase) >= 0) { num += 20; } if (normalized.IndexOf("normal", StringComparison.OrdinalIgnoreCase) >= 0) { num -= 100; } if (normalized.IndexOf("roughness", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("metallic", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("_ao", StringComparison.OrdinalIgnoreCase) >= 0) { num -= 80; } return num; } private static int ScoreNormalTextureAssetName(string normalized) { int num = -100; if (normalized.IndexOf("lambert1_normal", StringComparison.OrdinalIgnoreCase) >= 0) { num += 220; } if (normalized.IndexOf("creepydoll_normal", StringComparison.OrdinalIgnoreCase) >= 0) { num += 200; } if (normalized.IndexOf("normal", StringComparison.OrdinalIgnoreCase) >= 0) { num += 80; } if (normalized.IndexOf("mask", StringComparison.OrdinalIgnoreCase) >= 0) { num -= 200; } if (normalized.IndexOf("albedo", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("diffuse", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("roughness", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("metallic", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("_ao", StringComparison.OrdinalIgnoreCase) >= 0) { num -= 200; } return num; } private static int ScoreMaskMapTextureAssetName(string normalized) { int num = -100; if (normalized.IndexOf("creepydoll_hdrp_maskmap", StringComparison.OrdinalIgnoreCase) >= 0) { num += 260; } if (normalized.IndexOf("creepydoll_maskmap", StringComparison.OrdinalIgnoreCase) >= 0) { num += 240; } if (normalized.IndexOf("maskmap", StringComparison.OrdinalIgnoreCase) >= 0) { num += 120; } if (normalized.IndexOf("mask", StringComparison.OrdinalIgnoreCase) >= 0) { num += 90; } if (normalized.IndexOf("metallic", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("_ao", StringComparison.OrdinalIgnoreCase) >= 0) { num -= 200; } if (normalized.IndexOf("normal", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("albedo", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("diffuse", StringComparison.OrdinalIgnoreCase) >= 0) { num -= 200; } return num; } private static int ScoreMetallicTextureAssetName(string normalized) { int num = -100; if (normalized.IndexOf("lambert1_metallic", StringComparison.OrdinalIgnoreCase) >= 0) { num += 220; } if (normalized.IndexOf("metallic", StringComparison.OrdinalIgnoreCase) >= 0) { num += 80; } return num; } private static int ScoreAmbientOcclusionTextureAssetName(string normalized) { int num = -100; if (normalized.IndexOf("lambert1_ao", StringComparison.OrdinalIgnoreCase) >= 0) { num += 220; } if (normalized.IndexOf("_ao", StringComparison.OrdinalIgnoreCase) >= 0 || normalized.IndexOf("occlusion", StringComparison.OrdinalIgnoreCase) >= 0) { num += 80; } return num; } private static Texture GetTextureIfPresent(Material material, string property) { if (!((Object)(object)material != (Object)null) || !material.HasProperty(property)) { return null; } return material.GetTexture(property); } private static void SetTextureIfPresent(Material material, string property, Texture value) { if ((Object)(object)material != (Object)null && (Object)(object)value != (Object)null && material.HasProperty(property)) { material.SetTexture(property, value); } } private static void SetColorIfPresent(Material material, string property, Color value) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetColor(property, value); } } private static void SetFloatIfPresent(Material material, string property, float value) { if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetFloat(property, value); } } private static void EnsureHierarchyActive(Transform child, Transform stopAt) { Transform val = child; while ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(true); if (!((Object)(object)val == (Object)(object)stopAt)) { val = val.parent; continue; } break; } } private static string GetHierarchyPath(Transform root, Transform child) { if ((Object)(object)root == (Object)null || (Object)(object)child == (Object)null) { return ""; } string text = ((Object)child).name; Transform parent = child.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } if ((Object)(object)child == (Object)(object)root) { return ((Object)root).name; } return ((Object)root).name + "/" + text; } private static AudioSource FindAudioSource(GameObject prefab, string name) { Transform val = prefab.transform.Find(name); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent(); } private static Transform FindOrCreateChild(Transform parent, string name, Vector3 localPosition) { //IL_0014: 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) Transform val = parent.Find(name); if ((Object)(object)val != (Object)null) { return val; } val = new GameObject(name).transform; val.SetParent(parent, false); val.localPosition = localPosition; return val; } private static EnemyType CreateEnemyType(GameObject prefab) { EnemyType obj = ScriptableObject.CreateInstance(); ConfigureEnemyType(obj, prefab); return obj; } private static void ConfigureEnemyType(EnemyType enemyType, GameObject prefab) { enemyType.enemyName = "Hushdoll"; enemyType.enemyPrefab = prefab; enemyType.isOutsideEnemy = false; enemyType.isDaytimeEnemy = false; enemyType.PowerLevel = ModConfig.PowerLevel.Value; enemyType.DiversityPowerLevel = 1; enemyType.MaxCount = ModConfig.MaxCount.Value; enemyType.canDie = false; enemyType.canBeStunned = false; enemyType.canBeDestroyed = false; enemyType.destroyOnDeath = false; enemyType.disableAnimatorWhenFar = false; enemyType.pushPlayerForce = 0f; enemyType.pushPlayerDistance = 0f; enemyType.normalizedTimeInDayToLeave = 1f; enemyType.probabilityCurve = AnimationCurve.Constant(0f, 1f, 1f); enemyType.numberSpawnedFalloff = AnimationCurve.Linear(0f, 1f, 1f, 0f); enemyType.useNumberSpawnedFalloff = true; enemyType.stunTimeMultiplier = 1f; enemyType.stunGameDifficultyMultiplier = 1f; enemyType.doorSpeedMultiplier = 1f; } private static void TrySetTag(GameObject gameObject, string tag) { try { gameObject.tag = tag; } catch { } } private static void TrySetLayer(GameObject gameObject, string layerName) { if ((Object)(object)gameObject == (Object)null) { return; } int num = LayerMask.NameToLayer(layerName); string text = "NameToLayer"; if (num < 0) { num = ResolveLayerFallback(layerName); text = "fallback"; } if (num >= 0 && num <= 31) { gameObject.layer = num; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[CreepyDoll] Layer '{layerName}' resolved to {num} via {text} for '{((Object)gameObject).name}'."); } } else { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)$"[CreepyDoll] Layer '{layerName}' unresolved (NameToLayer and fallback both failed); '{((Object)gameObject).name}' stays on layer {gameObject.layer}."); } } } private static int ResolveLayerFallback(string layerName) { if (string.Equals(layerName, "ScanNode", StringComparison.OrdinalIgnoreCase)) { return 22; } if (string.Equals(layerName, "Enemies", StringComparison.OrdinalIgnoreCase)) { return 19; } return -1; } private static void AssignUniqueNetworkHash(GameObject prefab, string key) { try { NetworkObject component = prefab.GetComponent(); if ((Object)(object)component == (Object)null) { return; } uint num = BitConverter.ToUInt32(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("y4ngz.lethalcompany.creepydoll." + key)), 0); PropertyInfo property = typeof(NetworkObject).GetProperty("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(component, num); return; } FieldInfo field = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(component, num); } } catch (Exception ex) { Log.LogWarning((object)("[CreepyDoll] Failed to assign NetworkObject hash: " + ex.Message)); } } private static void DumpBundleAssets() { if (!((Object)(object)ModAssets == (Object)null)) { string[] allAssetNames = ModAssets.GetAllAssetNames(); foreach (string text in allAssetNames) { Log.LogError((object)(" - " + text)); } } } } internal static class PluginInfo { public const string PLUGIN_GUID = "y4ngz.lethalcompany.creepydoll"; public const string PLUGIN_NAME = "Y4NGZ Creepy Doll"; public const string PLUGIN_VERSION = "0.1.0"; } } namespace Y4NGZMonsters.Shared { internal static class ConfigSectionNameMigration { private static readonly IReadOnlyDictionary SectionNames = new Dictionary(StringComparer.Ordinal) { { "00 - General", "General" }, { "10 - Spawning", "Spawning" }, { "20 - Core Stats", "Core Stats" }, { "20 - Video", "Video" }, { "30 - Detection", "Detection" }, { "30 - Encounter Pacing", "Encounter Pacing" }, { "30 - Encounter Rules", "Encounter Rules" }, { "40 - Movement", "Movement" }, { "50 - Combat", "Combat" }, { "60 - Abilities", "Abilities" }, { "60 - Presentation", "Presentation" }, { "60 - Audio", "Audio" }, { "70 - Audio and Presentation", "Audio and Presentation" }, { "99 - Diagnostics", "Diagnostics" } }; private static readonly Regex NumberedSectionHeader = new Regex("^(?[ \\t]*)\\[(?
00 - General|10 - Spawning|20 - Core Stats|20 - Video|30 - Detection|30 - Encounter Pacing|30 - Encounter Rules|40 - Movement|50 - Combat|60 - Abilities|60 - Presentation|60 - Audio|70 - Audio and Presentation|99 - Diagnostics)\\](?[ \\t]*)(?\\r?)$", RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.CultureInvariant); internal static bool TryMigrate(ConfigFile config, ManualLogSource log, string creatureName) { string configFilePath = config.ConfigFilePath; if (!File.Exists(configFilePath)) { return false; } string text = null; try { int replacementCount; string contents = RenameSectionHeaders(File.ReadAllText(configFilePath), out replacementCount); if (replacementCount == 0) { return false; } text = GetBackupPath(configFilePath); File.Copy(configFilePath, text, overwrite: false); File.WriteAllText(configFilePath, contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); config.Reload(); if (log != null) { log.LogInfo((object)($"[{creatureName}] Removed numeric prefixes from {replacementCount} config section header(s). " + "The previous config is backed up at '" + text + "'.")); } return true; } catch (Exception ex) { string text2 = "The original config was not modified."; if (!string.IsNullOrEmpty(text) && File.Exists(text)) { try { File.Copy(text, configFilePath, overwrite: true); config.Reload(); text2 = "The original config was restored from its backup."; } catch (Exception ex2) { text2 = "Automatic restore also failed (" + ex2.Message + "). Restore '" + text + "' manually before editing the config."; } } if (log != null) { log.LogWarning((object)("[" + creatureName + "] Could not remove numeric config section prefixes: " + ex.Message + " " + text2)); } return false; } } internal static string RenameSectionHeaders(string text, out int replacementCount) { int count = 0; string result = NumberedSectionHeader.Replace(text, delegate(Match match) { string value = match.Groups["section"].Value; if (!SectionNames.TryGetValue(value, out var value2)) { return match.Value; } count++; return match.Groups["leading"].Value + "[" + value2 + "]" + match.Groups["trailing"].Value + match.Groups["carriage"].Value; }); replacementCount = count; return result; } private static string GetBackupPath(string configPath) { string text = configPath + ".pre-section-names.bak"; int num = 1; while (File.Exists(text)) { text = configPath + $".pre-section-names.{num}.bak"; num++; } return text; } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable(); } } } namespace Y4NGZCreepyDoll.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }