Decompiled source of IamScoutmaster v0.6.3
plugins/Thanks.I_am_Scoutmaster.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Thanks.I_am_Scoutmaster")] [assembly: AssemblyDescription("Control the PEAK Scoutmaster as the local player.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Thanks")] [assembly: AssemblyProduct("I'm Scoutmaster")] [assembly: AssemblyCopyright("Copyright 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0ee091f4-9b49-4593-a95d-af67533313c8")] [assembly: AssemblyFileVersion("0.7.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.7.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ImScoutmaster { public sealed class ControlledScoutmasterVisualSync : MonoBehaviour { private Character _character; private PhotonView _view; public void Initialize(Character character, PhotonView view) { _character = (((Object)(object)character != (Object)null) ? character : ((Component)this).GetComponent<Character>()); _view = (((Object)(object)view != (Object)null) ? view : ((Component)this).GetComponent<PhotonView>()); } private void Awake() { Initialize(_character, _view); } private void Update() { if ((Object)(object)_character == (Object)null) { _character = ((Component)this).GetComponent<Character>(); } if ((Object)(object)_character != (Object)null) { Plugin.EnsureControlledScoutmasterRegistered(_character); } } private void OnDestroy() { Plugin.UnregisterControlledScoutmasterInstance(_character, _view); } } [BepInPlugin("com.github.Thanks.ImScoutmaster", "I'm Scoutmaster", "0.7.0")] public sealed class Plugin : BaseUnityPlugin { private enum ConfigKey { ToggleKey, StaminaRefill, ThrowForce, ThrowUpBias, ThrowFallSeconds, ThirdPersonHeightOffset, ThirdPersonDistance, SourceStashDistance, RestoreAtScoutmasterPosition, RestoreGroundOffset, HideHudWhileTransformed, VerboseLogs } private readonly struct RendererVisualState { public readonly bool Enabled; public readonly bool ForceRenderingOff; public RendererVisualState(bool enabled, bool forceRenderingOff) { Enabled = enabled; ForceRenderingOff = forceRenderingOff; } } private sealed class ActiveScoutmasterSession { private readonly struct BodypartPhysicsState { public readonly Rigidbody Rig; public readonly bool IsKinematic; public readonly bool DetectCollisions; public readonly bool UseGravity; public BodypartPhysicsState(Rigidbody rig) { Rig = rig; IsKinematic = (Object)(object)rig != (Object)null && rig.isKinematic; DetectCollisions = (Object)(object)rig != (Object)null && rig.detectCollisions; UseGravity = (Object)(object)rig != (Object)null && rig.useGravity; } } [CompilerGenerated] private sealed class <Enter>d__15 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ActiveScoutmasterSession <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Enter>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ActiveScoutmasterSession activeScoutmasterSession = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; activeScoutmasterSession.PreconfigureScoutmasterForLocalControl(); activeScoutmasterSession._controller = activeScoutmasterSession._scoutmasterObject.GetComponent<PlayerScoutmasterController>() ?? activeScoutmasterSession._scoutmasterObject.AddComponent<PlayerScoutmasterController>(); activeScoutmasterSession._controller.Initialize(activeScoutmasterSession._sourceCharacter, activeScoutmasterSession._scoutmaster, activeScoutmasterSession._scoutmasterCharacter); RegisterControlledScoutmaster(activeScoutmasterSession._scoutmaster); Character.localCharacter = activeScoutmasterSession._scoutmasterCharacter; SetGameObjectActive(activeScoutmasterSession._scoutmasterObject, active: true); activeScoutmasterSession.AlignScoutmasterBodyToSource(); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; activeScoutmasterSession.AlignScoutmasterBodyToSource(); activeScoutmasterSession.PrepareScoutmaster(); SetCameraOverride(activeScoutmasterSession._scoutmasterCharacter); _viewScoutmasterObject = activeScoutmasterSession._scoutmasterObject; UpdateScoutmasterHudState(); RestoreRendererVisibility(activeScoutmasterSession._scoutmasterObject); activeScoutmasterSession._controller.ActivateDynamicRagdollControl(); activeScoutmasterSession.HideSourceCharacter(); Character.localCharacter = activeScoutmasterSession._scoutmasterCharacter; LogVerbose("Entered Scoutmaster form."); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private readonly Character _sourceCharacter; private readonly GameObject _scoutmasterObject; private readonly Scoutmaster _scoutmaster; private readonly Character _scoutmasterCharacter; private readonly Vector3 _sourceStartPosition; private readonly Vector3 _sourceStashPosition; private readonly Quaternion _sourceStartRotation; private readonly bool _sourceWasActive; private readonly List<BodypartPhysicsState> _sourceBodypartPhysicsStates = new List<BodypartPhysicsState>(); private PlayerScoutmasterController _controller; private bool _sourcePhysicsSuspended; public bool IsActive { get { if ((Object)(object)_sourceCharacter != (Object)null && (Object)(object)_scoutmasterObject != (Object)null && (Object)(object)_scoutmaster != (Object)null) { return (Object)(object)_scoutmasterCharacter != (Object)null; } return false; } } public ActiveScoutmasterSession(Character sourceCharacter, GameObject scoutmasterObject, Scoutmaster scoutmaster, Character scoutmasterCharacter, bool sourceWasActive) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_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) _sourceCharacter = sourceCharacter; _scoutmasterObject = scoutmasterObject; _scoutmaster = scoutmaster; _scoutmasterCharacter = scoutmasterCharacter; _sourceStartPosition = sourceCharacter.Center; _sourceStashPosition = _sourceStartPosition + Vector3.down * Mathf.Max(SourceStashDistance.Value, 10f); _sourceStartRotation = ((Component)sourceCharacter).transform.rotation; _sourceWasActive = sourceWasActive; } [IteratorStateMachine(typeof(<Enter>d__15))] public IEnumerator Enter() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Enter>d__15(0) { <>4__this = this }; } private void PreconfigureScoutmasterForLocalControl() { _scoutmasterCharacter.isScoutmaster = true; _scoutmasterCharacter.isZombie = false; EnableScoutmasterPhysics(); } private void AlignScoutmasterBodyToSource() { //IL_0038: 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_00ef: 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_00f4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_scoutmasterCharacter == (Object)null || (Object)(object)_scoutmasterObject == (Object)null) { return; } try { SetCharacterPositionImmediate(_scoutmasterCharacter, _sourceCharacter.Center, _sourceStartRotation); AlignCharacterFeetToGround(_scoutmasterCharacter, _sourceCharacter); _scoutmasterCharacter.data.currentRagdollControll = 1f; _scoutmasterCharacter.data.fallSeconds = 0f; _scoutmasterCharacter.data.isGrounded = (Object)(object)_sourceCharacter.data != (Object)null && _sourceCharacter.data.isGrounded; _scoutmasterCharacter.data.groundPos = (((Object)(object)_sourceCharacter.data != (Object)null) ? _sourceCharacter.data.groundPos : _sourceCharacter.Center); EnableScoutmasterPhysics(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to align controlled body: " + ex.Message)); } } } private void EnableScoutmasterPhysics() { if ((Object)(object)_scoutmasterCharacter == (Object)null || _scoutmasterCharacter.refs?.ragdoll?.partList == null) { return; } try { foreach (Bodypart part in _scoutmasterCharacter.refs.ragdoll.partList) { Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null); if (!((Object)(object)val == (Object)null)) { val.isKinematic = false; val.detectCollisions = true; val.useGravity = true; val.WakeUp(); } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to enable controlled physics: " + ex.Message)); } } } public void Tick() { if (!IsActive) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"[I'm Scoutmaster] Session became inactive."); } Instance?.ExitScoutmasterForm(restorePlayer: true); } else { Character.localCharacter = _scoutmasterCharacter; KeepScoutmasterAwake(); KeepSourceOutOfPlay(); } } public void Exit(bool restorePlayer) { //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_0060: 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_0068: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ResolveRestorePosition(); Quaternion val = ResolveRestoreRotation(); if ((Object)(object)_controller != (Object)null) { ((Behaviour)_controller).enabled = false; } RestoreRendererVisibility(_scoutmasterObject); ClearCameraOverride(); _viewScoutmasterObject = null; RestoreHudAfterScoutmaster(); if (restorePlayer && (Object)(object)_sourceCharacter != (Object)null) { CopyLookStateForRestore(_scoutmasterCharacter, _sourceCharacter, val); RestoreSourceCharacter(position, val); ForcePlayerCharacterLookup(_sourceCharacter); Character.localCharacter = _sourceCharacter; BeginCameraRestoreAssist(_sourceCharacter); } UnregisterStashedSourceCharacter(_sourceCharacter); UnregisterControlledScoutmaster(_scoutmaster); BeginPeakStatsCleanupGraceWindow(); CleanupPeakStatsUi(aggressive: true); DestroyScoutmasterObject(_scoutmasterObject); LogVerbose("Exited Scoutmaster form."); } private Vector3 ResolveRestorePosition() { //IL_0040: 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_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_001a: 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_0035: 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_003d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scoutmasterCharacter != (Object)null) { Vector3 center = _scoutmasterCharacter.Center; if (IsFiniteVector(center)) { return center; } Vector3 position = ((Component)_scoutmasterCharacter).transform.position; if (IsFiniteVector(position)) { return position; } } return ResolveSafeRestorePosition(_sourceStartPosition, _scoutmasterCharacter, _sourceCharacter, _sourceStartPosition); } private Quaternion ResolveRestoreRotation() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_000f: 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_006b: 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_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_00b7: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scoutmasterCharacter == (Object)null) { return _sourceStartRotation; } Vector3 val = Vector3.ProjectOnPlane(((Component)_scoutmasterCharacter).transform.rotation * Vector3.forward, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)_scoutmasterCharacter.data != (Object)null) { val = _scoutmasterCharacter.data.lookDirection_Flat; } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)_scoutmasterCharacter.data != (Object)null) { val = Vector3.ProjectOnPlane(_scoutmasterCharacter.data.lookDirection, Vector3.up); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return _sourceStartRotation; } return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); } private static Vector3 GetRestoreAnchor(Character character) { //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_0009: 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_002a: 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_008e: 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_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_0042: 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_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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_0068: 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)character == (Object)null) { return Vector3.zero; } Vector3 center = character.Center; if ((Object)(object)character.data != (Object)null && IsFiniteVector(character.data.groundPos)) { Vector3 groundPos = character.data.groundPos; Vector3 val = Vector3.ProjectOnPlane(groundPos - center, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude <= 64f && Mathf.Abs(groundPos.y - center.y) <= 12f) { return groundPos; } } if (IsFiniteVector(center)) { return center; } Vector3 head = character.Head; if (!IsFiniteVector(head)) { return ((Component)character).transform.position; } return head; } private static void AlignCharacterFeetToGround(Character controlledCharacter, Character sourceCharacter) { //IL_005a: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)controlledCharacter == (Object)null) && !((Object)(object)sourceCharacter == (Object)null) && TryGetCharacterGroundY(sourceCharacter, out var groundY) && TryGetCharacterGroundY(controlledCharacter, out var groundY2)) { float num = groundY - groundY2; if (!float.IsNaN(num) && !float.IsInfinity(num) && !(Mathf.Abs(num) > 3f) && !(Mathf.Abs(num) <= 0.001f)) { SetCharacterPositionImmediate(controlledCharacter, controlledCharacter.Center + Vector3.up * num, ((Component)controlledCharacter).transform.rotation); } } } private static bool TryGetCharacterGroundY(Character character, out float groundY) { //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_002d: 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_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_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) //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_0056: 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_00b0: 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_009c: 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_006b: 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_007f: Unknown result type (might be due to invalid IL or missing references) groundY = 0f; if ((Object)(object)character == (Object)null) { return false; } Vector3 center = character.Center; if ((Object)(object)character.data != (Object)null && IsFiniteVector(character.data.groundPos)) { Vector3 groundPos = character.data.groundPos; Vector3 val = Vector3.ProjectOnPlane(groundPos - center, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude <= 64f && Mathf.Abs(groundPos.y - center.y) <= 12f) { groundY = groundPos.y; return true; } } if (TryGetCharacterColliderBottomY(character, out groundY)) { return true; } if (IsFiniteVector(center)) { groundY = center.y; return true; } Vector3 position = ((Component)character).transform.position; if (!IsFiniteVector(position)) { return false; } groundY = position.y; return true; } private static bool TryGetCharacterColliderBottomY(Character character, out float bottomY) { //IL_00f0: 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_00f5: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0098: 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_009f: 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_00ab: Unknown result type (might be due to invalid IL or missing references) bottomY = 0f; if (character?.refs?.ragdoll?.partList == null) { return false; } bool flag = false; foreach (Bodypart part in character.refs.ragdoll.partList) { if ((Object)(object)part == (Object)null) { continue; } Collider[] componentsInChildren = ((Component)part).GetComponentsInChildren<Collider>(true); if (componentsInChildren != null) { Collider[] array = componentsInChildren; foreach (Collider val in array) { if (!((Object)(object)val == (Object)null) && val.enabled) { Bounds bounds = val.bounds; Vector3 min = ((Bounds)(ref bounds)).min; if (IsFiniteVector(min) && (!flag || min.y < bottomY)) { bottomY = min.y; flag = true; } } } } Vector3 val2 = (((Object)(object)part.Rig != (Object)null) ? part.Rig.position : ((Component)part).transform.position); if (IsFiniteVector(val2) && (!flag || val2.y < bottomY)) { bottomY = val2.y; flag = true; } } return flag; } private static Vector3 ResolveSafeRestorePosition(Vector3 requestedPosition, Character scoutmasterCharacter, Character sourceCharacter, Vector3 fallbackPosition) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_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_00bc: 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_00c7: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a5: 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_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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(RestoreGroundOffset.Value, 0.2f, 5f); Vector3 val = (IsFiniteVector(requestedPosition) ? requestedPosition : fallbackPosition); if (!IsFiniteVector(val)) { val = (((Object)(object)sourceCharacter != (Object)null) ? ((Component)sourceCharacter).transform.position : Vector3.zero); } if (TryFindRestoreGround(val + Vector3.up * 5f, 30f, scoutmasterCharacter, sourceCharacter, out var groundHit) || TryFindRestoreGround(val + Vector3.up * 12f, 80f, scoutmasterCharacter, sourceCharacter, out groundHit) || TryFindRestoreGround(fallbackPosition + Vector3.up * 5f, 30f, scoutmasterCharacter, sourceCharacter, out groundHit)) { return ((RaycastHit)(ref groundHit)).point + Vector3.up * num; } return val + Vector3.up * num; } private static bool TryFindRestoreGround(Vector3 origin, float distance, Character scoutmasterCharacter, Character sourceCharacter, out RaycastHit groundHit) { //IL_0002: 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_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_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_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_00a7: 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) groundHit = default(RaycastHit); if (!IsFiniteVector(origin)) { return false; } RaycastHit[] array; try { array = Physics.RaycastAll(origin, Vector3.down, distance, -1, (QueryTriggerInteraction)1); } catch { return false; } Array.Sort(array, (RaycastHit left, RaycastHit right) => ((RaycastHit)(ref left)).distance.CompareTo(((RaycastHit)(ref right)).distance)); RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val = array2[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((RaycastHit)(ref val)).collider.isTrigger && !(Vector3.Dot(((RaycastHit)(ref val)).normal, Vector3.up) < 0.2f) && !IsRestoreIgnoredCollider(((RaycastHit)(ref val)).collider, scoutmasterCharacter, sourceCharacter)) { groundHit = val; return true; } } return false; } private static bool IsRestoreIgnoredCollider(Collider collider, Character scoutmasterCharacter, Character sourceCharacter) { if ((Object)(object)collider == (Object)null) { return true; } Transform transform = ((Component)collider).transform; if (!IsColliderOwnedBy(transform, scoutmasterCharacter)) { return IsColliderOwnedBy(transform, sourceCharacter); } return true; } private static bool IsColliderOwnedBy(Transform colliderTransform, Character character) { if ((Object)(object)colliderTransform == (Object)null || (Object)(object)character == (Object)null) { return false; } Transform transform = ((Component)character).transform; if (!((Object)(object)colliderTransform == (Object)(object)transform)) { return colliderTransform.IsChildOf(transform); } return true; } private static bool IsFiniteVector(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (IsFiniteFloat(value.x) && IsFiniteFloat(value.y)) { return IsFiniteFloat(value.z); } return false; } private static bool IsFiniteFloat(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private void PrepareScoutmaster() { ClearScoutmasterAiState(_scoutmaster); _scoutmasterCharacter.isScoutmaster = true; _scoutmasterCharacter.isZombie = false; _scoutmasterCharacter.data.isScoutmaster = true; SetCharacterDeadWithoutReconnect(_scoutmasterCharacter, dead: false); _scoutmasterCharacter.data.zombified = false; _scoutmasterCharacter.data.passedOut = false; _scoutmasterCharacter.data.fullyPassedOut = false; _scoutmasterCharacter.data.fallSeconds = 0f; _scoutmasterCharacter.data.currentRagdollControll = 1f; _scoutmasterCharacter.data.currentStamina = Mathf.Max(_scoutmasterCharacter.data.currentStamina, GetControlledStaminaFill()); _scoutmasterCharacter.data.extraStamina = 0f; ClearAssistJumpState(_scoutmasterCharacter); } private void HideSourceCharacter() { //IL_009a: 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_00bb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null) { return; } try { RegisterStashedSourceCharacter(_sourceCharacter); _sourceCharacter.data.fallSeconds = 0f; _sourceCharacter.data.passedOut = false; _sourceCharacter.data.fullyPassedOut = false; ClearAssistJumpState(_sourceCharacter); if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf) { ((Component)_sourceCharacter).gameObject.SetActive(true); } HideSourceRenderers(((Component)_sourceCharacter).gameObject); SendSourceCharacterOutOfPlay(_sourceStashPosition); SetCharacterPositionImmediate(_sourceCharacter, _sourceStashPosition, ((Component)_sourceCharacter).transform.rotation); SuspendSourcePhysics(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to stash source character: " + ex.Message)); } } } private void RestoreSourceCharacter(Vector3 position, Quaternion rotation) { //IL_00fb: 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_0111: 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_0126: 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_0143: 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) try { if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf) { ((Component)_sourceCharacter).gameObject.SetActive(true); } SetCharacterDeadWithoutReconnect(_sourceCharacter, dead: false); _sourceCharacter.data.zombified = false; _sourceCharacter.isZombie = false; _sourceCharacter.data.passedOut = false; _sourceCharacter.data.fullyPassedOut = false; _sourceCharacter.data.fallSeconds = 0f; _sourceCharacter.data.deathTimer = 0f; _sourceCharacter.data.currentRagdollControll = 1f; _sourceCharacter.data.isGrounded = false; _sourceCharacter.data.sinceGrounded = 0f; _sourceCharacter.data.groundedFor = 0f; _sourceCharacter.data.groundPos = position; _sourceCharacter.data.avarageVelocity = Vector3.zero; _sourceCharacter.data.avarageLastFrameVelocity = Vector3.zero; ClearAssistJumpState(_sourceCharacter); SendSourceCharacterRestore(position); SetCharacterPositionImmediate(_sourceCharacter, position, rotation); RestoreSourcePhysics(); RestoreSourceRenderers(((Component)_sourceCharacter).gameObject); UnregisterStashedSourceCharacter(_sourceCharacter); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to restore source character: " + ex.Message)); } } } private void SendSourceCharacterOutOfPlay(Vector3 stashPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendSourceCharacterStateRpc(stashPosition, "[I'm Scoutmaster] Failed to move source character out of play: "); } private void SendSourceCharacterRestore(Vector3 restorePosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendSourceCharacterStateRpc(restorePosition, "[I'm Scoutmaster] Failed to restore source character over network: "); } private void SendSourceCharacterStateRpc(Vector3 position, string warningPrefix) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode)) { return; } try { PhotonView photonView = ((MonoBehaviourPun)_sourceCharacter).photonView; photonView.RPC("RPCA_UnFall", (RpcTarget)1, Array.Empty<object>()); photonView.RPC("RPCA_Revive", (RpcTarget)1, new object[1] { false }); photonView.RPC("WarpPlayerRPC", (RpcTarget)1, new object[2] { position, false }); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)(warningPrefix + ex.Message)); } } } private void SuspendSourcePhysics() { //IL_00ab: 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) if ((Object)(object)_sourceCharacter == (Object)null || _sourceCharacter.refs?.ragdoll?.partList == null) { return; } try { if (!_sourcePhysicsSuspended) { _sourceBodypartPhysicsStates.Clear(); } foreach (Bodypart part in _sourceCharacter.refs.ragdoll.partList) { Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null); if (!((Object)(object)val == (Object)null)) { if (!_sourcePhysicsSuspended) { _sourceBodypartPhysicsStates.Add(new BodypartPhysicsState(val)); } if (!val.isKinematic) { val.linearVelocity = Vector3.zero; val.angularVelocity = Vector3.zero; } val.detectCollisions = false; val.useGravity = false; val.isKinematic = true; } } _sourcePhysicsSuspended = true; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to suspend source physics: " + ex.Message)); } } } private void RestoreSourcePhysics() { //IL_0045: 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) if (!_sourcePhysicsSuspended) { return; } try { foreach (BodypartPhysicsState sourceBodypartPhysicsState in _sourceBodypartPhysicsStates) { Rigidbody rig = sourceBodypartPhysicsState.Rig; if (!((Object)(object)rig == (Object)null)) { rig.isKinematic = sourceBodypartPhysicsState.IsKinematic; if (!rig.isKinematic) { rig.linearVelocity = Vector3.zero; rig.angularVelocity = Vector3.zero; } rig.detectCollisions = sourceBodypartPhysicsState.DetectCollisions; rig.useGravity = sourceBodypartPhysicsState.UseGravity; } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to restore source physics: " + ex.Message)); } } finally { _sourceBodypartPhysicsStates.Clear(); _sourcePhysicsSuspended = false; } } private static void SetCharacterPositionImmediate(Character character, Vector3 position, Quaternion rotation) { //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_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_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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: 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) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_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) //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_00db: 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) //IL_0107: 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) if ((Object)(object)character == (Object)null) { return; } try { Transform transform = ((Component)character).transform; Vector3 center = character.Center; Quaternion rotation2 = transform.rotation; Vector3 val = position - center; Quaternion val2 = rotation * Quaternion.Inverse(rotation2); transform.SetPositionAndRotation(transform.position + val, rotation); if (character.refs?.ragdoll?.partList == null) { return; } foreach (Bodypart part in character.refs.ragdoll.partList) { if ((Object)(object)part == (Object)null) { continue; } if ((Object)(object)part.Rig != (Object)null) { part.Rig.position = position + val2 * (part.Rig.position - center); part.Rig.rotation = val2 * part.Rig.rotation; if (!part.Rig.isKinematic) { part.Rig.linearVelocity = Vector3.zero; part.Rig.angularVelocity = Vector3.zero; } } else { ((Component)part).transform.SetPositionAndRotation(position + val2 * (((Component)part).transform.position - center), val2 * ((Component)part).transform.rotation); } } } catch { ((Component)character).transform.SetPositionAndRotation(position, rotation); } } private void KeepScoutmasterAwake() { if (!((Object)(object)_scoutmasterCharacter?.data == (Object)null)) { ClearScoutmasterAiState(_scoutmaster); SetCharacterDeadWithoutReconnect(_scoutmasterCharacter, dead: false); _scoutmasterCharacter.isScoutmaster = true; _scoutmasterCharacter.isZombie = false; _scoutmasterCharacter.data.isScoutmaster = true; _scoutmasterCharacter.data.zombified = false; if (!IsControlledScoutmasterIncapacitated(_scoutmasterCharacter)) { _scoutmasterCharacter.data.passedOut = false; _scoutmasterCharacter.data.fullyPassedOut = false; _scoutmasterCharacter.data.fallSeconds = 0f; _scoutmasterCharacter.data.currentRagdollControll = 1f; _scoutmasterCharacter.data.currentStamina = Mathf.Max(_scoutmasterCharacter.data.currentStamina, GetControlledStaminaFill()); _scoutmasterCharacter.data.extraStamina = 0f; ClearAssistJumpState(_scoutmasterCharacter); } } } private void KeepSourceOutOfPlay() { if (!((Object)(object)_sourceCharacter == (Object)null) && !((Object)(object)_sourceCharacter.data == (Object)null)) { if ((Object)(object)_sourceCharacter == (Object)(object)Character.localCharacter && (Object)(object)_scoutmasterCharacter != (Object)null) { Character.localCharacter = _scoutmasterCharacter; } SetCharacterDeadWithoutReconnect(_sourceCharacter, dead: false); _sourceCharacter.data.zombified = false; _sourceCharacter.data.passedOut = false; _sourceCharacter.data.fullyPassedOut = false; _sourceCharacter.data.fallSeconds = 0f; ClearAssistJumpState(_sourceCharacter); HideSourceRenderers(((Component)_sourceCharacter).gameObject); SuspendSourcePhysics(); } } } [CompilerGenerated] private sealed class <EnterScoutmasterFormRoutine>d__198 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Plugin <>4__this; private Character <sourceCharacter>5__2; private bool <sourceWasActive>5__3; private GameObject <scoutmasterObject>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnterScoutmasterFormRoutine>d__198(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <sourceCharacter>5__2 = null; <scoutmasterObject>5__4 = null; <>1__state = -2; } private bool MoveNext() { //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_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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; Plugin plugin = <>4__this; Scoutmaster component; Character component2; switch (num) { default: return false; case 0: { <>1__state = -1; plugin._switching = true; <sourceCharacter>5__2 = Character.localCharacter; if (!CanTransform(<sourceCharacter>5__2)) { plugin._switching = false; return false; } Vector3 center = <sourceCharacter>5__2.Center; Quaternion spawnRotation = GetSpawnRotation(<sourceCharacter>5__2); <sourceWasActive>5__3 = ((Component)<sourceCharacter>5__2).gameObject.activeSelf; <scoutmasterObject>5__4 = CreateScoutmaster(center, spawnRotation); if ((Object)(object)<scoutmasterObject>5__4 == (Object)null) { ((BaseUnityPlugin)plugin).Logger.LogWarning((object)"[I'm Scoutmaster] Could not create Character_Scoutmaster prefab."); plugin._switching = false; return false; } component = <scoutmasterObject>5__4.GetComponent<Scoutmaster>(); component2 = <scoutmasterObject>5__4.GetComponent<Character>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { <>2__current = null; <>1__state = 1; return true; } goto IL_0112; } case 1: <>1__state = -1; component = <scoutmasterObject>5__4.GetComponent<Scoutmaster>(); component2 = <scoutmasterObject>5__4.GetComponent<Character>(); goto IL_0112; case 2: { <>1__state = -1; plugin._switching = false; return false; } IL_0112: if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { ((BaseUnityPlugin)plugin).Logger.LogWarning((object)"[I'm Scoutmaster] Created object is missing Scoutmaster or Character."); DestroyScoutmasterObject(<scoutmasterObject>5__4); plugin._switching = false; return false; } if (!CanTransform(<sourceCharacter>5__2)) { DestroyScoutmasterObject(<scoutmasterObject>5__4); plugin._switching = false; return false; } plugin._session = new ActiveScoutmasterSession(<sourceCharacter>5__2, <scoutmasterObject>5__4, component, component2, <sourceWasActive>5__3); <>2__current = plugin._session.Enter(); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <EnumerateCandidateTransforms>d__371 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IDisposable, IEnumerator { private int <>1__state; private Transform <>2__current; private int <>l__initialThreadId; private object menuInstance; public object <>3__menuInstance; private Type menuType; public Type <>3__menuType; Transform IEnumerator<Transform>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateCandidateTransforms>d__371(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { object? obj2; Transform val2; switch (<>1__state) { default: return false; case 0: { <>1__state = -1; object obj = menuInstance; Component val = (Component)((obj is Component) ? obj : null); if (val != null) { <>2__current = val.transform; <>1__state = 1; return true; } goto IL_004d; } case 1: <>1__state = -1; goto IL_004d; case 2: { <>1__state = -1; break; } IL_004d: obj2 = menuType?.GetProperty("Content", InstanceFlags)?.GetValue(menuInstance); val2 = (Transform)((obj2 is Transform) ? obj2 : null); if (val2 != null) { <>2__current = val2; <>1__state = 2; return true; } break; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator() { <EnumerateCandidateTransforms>d__371 <EnumerateCandidateTransforms>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateCandidateTransforms>d__ = this; } else { <EnumerateCandidateTransforms>d__ = new <EnumerateCandidateTransforms>d__371(0); } <EnumerateCandidateTransforms>d__.menuInstance = <>3__menuInstance; <EnumerateCandidateTransforms>d__.menuType = <>3__menuType; return <EnumerateCandidateTransforms>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Transform>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <EnumerateModConfigUiRoots>d__370 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IDisposable, IEnumerator { private int <>1__state; private Transform <>2__current; private int <>l__initialThreadId; private object menuInstance; public object <>3__menuInstance; private Type menuType; public Type <>3__menuType; private HashSet<int> <visited>5__2; private IEnumerator<Transform> <>7__wrap2; Transform IEnumerator<Transform>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateModConfigUiRoots>d__370(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <visited>5__2 = null; <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <visited>5__2 = new HashSet<int>(); <>7__wrap2 = EnumerateCandidateTransforms(menuInstance, menuType).GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap2.MoveNext()) { Transform current = <>7__wrap2.Current; if ((Object)(object)current != (Object)null && <visited>5__2.Add(((Object)current).GetInstanceID())) { <>2__current = current; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap2 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap2 != null) { <>7__wrap2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator() { <EnumerateModConfigUiRoots>d__370 <EnumerateModConfigUiRoots>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateModConfigUiRoots>d__ = this; } else { <EnumerateModConfigUiRoots>d__ = new <EnumerateModConfigUiRoots>d__370(0); } <EnumerateModConfigUiRoots>d__.menuInstance = <>3__menuInstance; <EnumerateModConfigUiRoots>d__.menuType = <>3__menuType; return <EnumerateModConfigUiRoots>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Transform>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetAliasDefinitions>d__350 : IEnumerable<ConfigDefinition>, IEnumerable, IEnumerator<ConfigDefinition>, IDisposable, IEnumerator { private int <>1__state; private ConfigDefinition <>2__current; private int <>l__initialThreadId; private ConfigKey configKey; public ConfigKey <>3__configKey; private string <canonicalKey>5__2; private string <chineseKey>5__3; private string <canonicalSection>5__4; private string <chineseSection>5__5; ConfigDefinition IEnumerator<ConfigDefinition>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetAliasDefinitions>d__350(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <canonicalKey>5__2 = null; <chineseKey>5__3 = null; <canonicalSection>5__4 = null; <chineseSection>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <canonicalKey>5__2 = GetConfigKeyName(configKey); <chineseKey>5__3 = GetKeyName(configKey, isChineseLanguage: true); <canonicalSection>5__4 = GetConfigSectionName(configKey); <chineseSection>5__5 = GetSectionName(configKey, isChineseLanguage: true); <>2__current = new ConfigDefinition(<canonicalSection>5__4, <canonicalKey>5__2); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = new ConfigDefinition(<canonicalSection>5__4, <chineseKey>5__3); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = new ConfigDefinition(<chineseSection>5__5, <canonicalKey>5__2); <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = new ConfigDefinition(<chineseSection>5__5, <chineseKey>5__3); <>1__state = 4; return true; case 4: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<ConfigDefinition> IEnumerable<ConfigDefinition>.GetEnumerator() { <GetAliasDefinitions>d__350 <GetAliasDefinitions>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetAliasDefinitions>d__ = this; } else { <GetAliasDefinitions>d__ = new <GetAliasDefinitions>d__350(0); } <GetAliasDefinitions>d__.configKey = <>3__configKey; return <GetAliasDefinitions>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<ConfigDefinition>)this).GetEnumerator(); } } public const string Id = "com.github.Thanks.ImScoutmaster"; public const string Name = "I'm Scoutmaster"; public const string Version = "0.7.0"; private const string ScoutmasterResourceName = "Character_Scoutmaster"; private const float ToggleHoldSeconds = 1f; private const float ManualFallShortPressMaxSeconds = 0.3f; private const float ToggleDebounceSeconds = 0.35f; private const int SimplifiedChineseLanguageIndex = 9; private const string ControlsConfigSectionName = "Controls"; private const string ScoutmasterControlConfigSectionName = "Scoutmaster Control"; private const string CameraConfigSectionName = "Camera"; private const string PlayerRestoreConfigSectionName = "Player Restore"; private const string HudConfigSectionName = "HUD"; private const string DiagnosticsConfigSectionName = "Diagnostics"; private const string ModConfigPluginGuid = "com.github.PEAKModding.PEAKLib.ModConfig"; private const float ModConfigUiLocalizationIntervalSeconds = 0.25f; private const float CameraRestoreAssistSeconds = 0.4f; private const float ThirdPersonHeadTargetLiftMin = 0.35f; private const float ThirdPersonHeadTargetLiftMax = 1.35f; private const float ThirdPersonConfiguredTargetBlend = 0.25f; private const float ThirdPersonGroundMinHeight = 1.55f; private const float ThirdPersonCrouchGroundMinHeight = 1.15f; private const float ThirdPersonBodyFrameBlendStart = 0.45f; private const float ThirdPersonBodyFrameBlendFull = 0.95f; private const float ThirdPersonBodyFrameDownMaxBlend = 0.42f; private const float ThirdPersonBodyFrameUpMaxBlend = 0.3f; private const float ThirdPersonFocusForwardMin = 1.75f; private const float ThirdPersonFocusForwardMax = 4.25f; private const float ThirdPersonDownFocusDropMax = 1.15f; private const float ThirdPersonUpFocusLiftMax = 0.8f; private const float ThirdPartyCompatibilityRetryIntervalSeconds = 1f; private const float ClearBoostReticleTimer = 10f; private const float ControlledScoutmasterJumpVelocity = 10.5f; private const float ControlledScoutmasterJumpGroundClearance = 0.12f; private const float ControlledScoutmasterManualFallSeconds = 1.25f; private const float ControlledGrabAttachPointMaxHandDistance = 3.5f; private const string ControlledScoutmasterInstantiationMarker = "ImScoutmaster.ControlledScoutmaster"; private const int ControlledScoutmasterNetworkProtocol = 1; private static readonly BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly PropertyInfo ConfigFileEntriesProperty = typeof(ConfigFile).GetProperty("Entries", InstanceFlags); private static readonly FieldInfo CharacterViewField = typeof(Character).GetField("view", InstanceFlags); private static readonly FieldInfo CharacterStartedField = typeof(Character).GetField("started", InstanceFlags); private static readonly FieldInfo CharacterSmoothedCamPosField = typeof(Character).GetField("smoothedCamPos", InstanceFlags); private static readonly MethodInfo CharacterGetBodypartMethod = typeof(Character).GetMethod("GetBodypart", InstanceFlags); private static readonly MethodInfo CharacterGetPartTypeMethod = typeof(Character).GetMethod("GetPartType", InstanceFlags); private static readonly FieldInfo CharacterDataCharacterField = typeof(CharacterData).GetField("character", InstanceFlags); private static readonly FieldInfo CharacterDataDeadField = typeof(CharacterData).GetField("_dead", InstanceFlags); private static readonly FieldInfo CharacterDataGrabbedPlayerField = typeof(CharacterData).GetField("grabbedPlayer", InstanceFlags); private static readonly MethodInfo CharacterFallMethod = typeof(Character).GetMethod("Fall", InstanceFlags, null, new Type[2] { typeof(float), typeof(float) }, null); private static readonly FieldInfo CharacterCustomizationCharacterField = typeof(CharacterCustomization).GetField("_character", InstanceFlags); private static readonly FieldInfo BodypartCharacterField = typeof(Bodypart).GetField("character", InstanceFlags); private static readonly FieldInfo ScoutmasterCurrentTargetField = typeof(Scoutmaster).GetField("_currentTarget", InstanceFlags); private static readonly FieldInfo ScoutmasterTargetForcedUntilField = typeof(Scoutmaster).GetField("targetForcedUntil", InstanceFlags); private static readonly FieldInfo ScoutmasterChillForSecondsField = typeof(Scoutmaster).GetField("chillForSeconds", InstanceFlags); private static readonly FieldInfo ScoutmasterIsThrowingField = typeof(Scoutmaster).GetField("isThrowing", InstanceFlags); private static readonly PropertyInfo MainCameraSpecCharacterProperty = typeof(MainCameraMovement).GetProperty("specCharacter", StaticFlags); private static readonly FieldInfo MainCameraIsSpectatingField = typeof(MainCameraMovement).GetField("isSpectating", InstanceFlags); private static readonly FieldInfo MainCameraRagdollCamField = typeof(MainCameraMovement).GetField("ragdollCam", InstanceFlags); private static readonly FieldInfo MainCameraCurrentForwardOffsetField = typeof(MainCameraMovement).GetField("currentForwardOffset", InstanceFlags); private static readonly FieldInfo MainCameraTargetPlayerPovPositionField = typeof(MainCameraMovement).GetField("targetPlayerPovPosition", InstanceFlags); private static readonly FieldInfo MainCameraPhysicsRotField = typeof(MainCameraMovement).GetField("physicsRot", InstanceFlags); private static readonly MethodInfo FindObjectsOfTypeByTypeMethod = typeof(Object).GetMethod("FindObjectsOfType", new Type[1] { typeof(Type) }); private static readonly MethodInfo CharacterClimbingCanClimbMethod = typeof(CharacterClimbing).GetMethod("CanClimb", InstanceFlags, null, Type.EmptyTypes, null); private static readonly MethodInfo CharacterClimbingStartClimbRpcMethod = FindCharacterClimbingStartClimbRpcMethod(); private static readonly FieldInfo CharacterClimbingClimbToggledOnField = typeof(CharacterClimbing).GetField("climbToggledOn", InstanceFlags); private static readonly FieldInfo CharacterClimbingSinceLastClimbStartedField = typeof(CharacterClimbing).GetField("sinceLastClimbStarted", InstanceFlags); private static readonly FieldInfo CharacterClimbingPlayerSlideField = typeof(CharacterClimbing).GetField("playerSlide", InstanceFlags); private static readonly MethodInfo CharacterGrabbingGrabAttachMethod = typeof(CharacterGrabbing).GetMethod("RPCA_GrabAttach", InstanceFlags); private static readonly PropertyInfo PlayerHandlerInstanceProperty = typeof(PlayerHandler).GetProperty("Instance", StaticFlags); private static readonly FieldInfo PlayerHandlerCharacterLookupField = typeof(PlayerHandler).GetField("m_playerCharacterLookup", InstanceFlags); private static readonly FieldInfo CharacterItemsCurrentSelectedSlotField = typeof(CharacterItems).GetField("currentSelectedSlot", InstanceFlags); private static readonly FieldInfo CharacterItemsLastSelectedSlotField = typeof(CharacterItems).GetField("lastSelectedSlot", InstanceFlags); private static readonly FieldInfo CharacterAfflictionsCharacterField = typeof(CharacterAfflictions).GetField("character", InstanceFlags); private static readonly object CharacterItemsNoneSlotValue = CreateOptionableNoneValue(CharacterItemsCurrentSelectedSlotField?.FieldType); private static FieldInfo PeakStatsStaminaBarsField; private static FieldInfo PeakStatsObservedCharacterField; private static FieldInfo PeakStatsAfflictionBarField; private static Type PeakStatsStaminaBarType; private static Type PeakStatsAfflictionType; private static float _peakStatsCleanupGraceUntil; private static bool _skipControlledCharacterFixedUpdate; private bool _characterFixedUpdateCompatibilityConfigured; private bool _loggedWaitingForPeakerHook; private float _nextPeakerGuardAttemptTime; private bool _peakStatsCompatibilityConfigured; private float _nextThirdPartyCompatibilityAttemptTime; private readonly Harmony _harmony = new Harmony("com.github.Thanks.ImScoutmaster"); private ActiveScoutmasterSession _session; private bool _switching; private float _lastToggleTime; private float _toggleHoldStartTime = -1f; private bool _toggleHoldTriggered; private bool _lastDetectedChineseLanguage; private bool _isRefreshingLanguage; private bool _pendingConfigFileLocalizationRefresh; private bool _pendingConfigFileLocalizationSave; private float _nextModConfigUiLocalizationTime; private static Transform _controlledScoutmasterCreationRoot; private static readonly HashSet<int> _controlledScoutmasterInstanceIds = new HashSet<int>(); private static readonly HashSet<int> _controlledScoutmasterViewIds = new HashSet<int>(); private static readonly HashSet<int> _controlledScoutmasterCharacterInstanceIds = new HashSet<int>(); private static readonly Dictionary<int, int> _controlledScoutmasterOwnerActorNumbersByViewId = new Dictionary<int, int>(); private static readonly HashSet<int> _stashedSourceCharacterIds = new HashSet<int>(); private static readonly Dictionary<int, RendererVisualState> _rendererVisualStates = new Dictionary<int, RendererVisualState>(); private static readonly Dictionary<int, RendererVisualState> _sourceRendererVisualStates = new Dictionary<int, RendererVisualState>(); private static Character _cameraOverrideCharacter; private static Character _cameraRestoreCharacter; private static float _cameraRestoreUntil; private static GameObject _viewScoutmasterObject; private static bool _hasSmoothedThirdPersonCameraPose; private static Vector3 _smoothedThirdPersonCameraPosition; private static Quaternion _smoothedThirdPersonCameraRotation = Quaternion.identity; private static GameObject _hudCanvasObject; private static GameObject _namesCanvasObject; private static bool _hudPreviousKnown; private static bool _namesPreviousKnown; private static bool _hudPreviousActive; private static bool _namesPreviousActive; private static bool _hudHiddenForScoutmaster; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ConfigEntry<KeyCode> ToggleKey { get; private set; } internal static ConfigEntry<float> StaminaRefill { get; private set; } internal static ConfigEntry<float> ThrowForce { get; private set; } internal static ConfigEntry<float> ThrowUpBias { get; private set; } internal static ConfigEntry<float> ThrowFallSeconds { get; private set; } internal static ConfigEntry<float> ThirdPersonHeightOffset { get; private set; } internal static ConfigEntry<float> ThirdPersonDistance { get; private set; } internal static ConfigEntry<float> SourceStashDistance { get; private set; } internal static ConfigEntry<bool> RestoreAtScoutmasterPosition { get; private set; } internal static ConfigEntry<float> RestoreGroundOffset { get; private set; } internal static ConfigEntry<bool> HideHudWhileTransformed { get; private set; } internal static ConfigEntry<bool> VerboseLogs { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; _lastDetectedChineseLanguage = DetectChineseLanguage(); BindConfig(_lastDetectedChineseLanguage); RegisterConfigChangeHandlers(); MarkConfigFileLocalizationDirty(saveConfigFile: true); _harmony.PatchAll(typeof(ScoutmasterHarmonyPatches).Assembly); ConfigureCharacterFixedUpdateCompatibility(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Loaded version 0.7.0."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[I'm Scoutmaster] Config language: " + BuildLanguageDetectionSummary(_lastDetectedChineseLanguage))); } private void OnDestroy() { try { ExitScoutmasterForm(restorePlayer: true); RestoreHudAfterScoutmaster(); UnregisterConfigChangeHandlers(); _harmony.UnpatchSelf(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm Scoutmaster] Cleanup failed: " + ex.Message)); } finally { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } private void Update() { if (!_characterFixedUpdateCompatibilityConfigured && Time.unscaledTime >= _nextPeakerGuardAttemptTime) { _nextPeakerGuardAttemptTime = Time.unscaledTime + 0.5f; ConfigureCharacterFixedUpdateCompatibility(); } if (!_peakStatsCompatibilityConfigured && Time.unscaledTime >= _nextThirdPartyCompatibilityAttemptTime) { _nextThirdPartyCompatibilityAttemptTime = Time.unscaledTime + 1f; ConfigureThirdPartyCompatibility(); } HandleLanguageChangeIfNeeded(); HandlePendingConfigFileLocalizationRefresh(); TryLocalizeVisibleModConfigUiThrottled(); RefreshRestoredPlayerCamera(); ActiveScoutmasterSession session = _session; if (session != null && session.IsActive) { _session.Tick(); UpdateScoutmasterHudState(); } else { RestoreHudAfterScoutmaster(); } HandleToggleHold(); } private void ConfigureCharacterFixedUpdateCompatibility() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown if (_characterFixedUpdateCompatibilityConfigured) { return; } try { Type type = FindLoadedType("PEAKER.Testing"); if (type == null) { if (!_loggedWaitingForPeakerHook) { _loggedWaitingForPeakerHook = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Waiting for PEAKER ragdoll hook; controlled Scoutmaster Character.FixedUpdate remains enabled."); } return; } MethodInfo method = type.GetMethod("PostCharacterGetTargetRagdollControll", StaticFlags, null, new Type[2] { typeof(CharacterData), typeof(float).MakeByRefType() }, null); MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "PeakerRagdollControlPostfixPrefix", (Type[])null, (Type[])null); if (method == null || methodInfo == null) { _skipControlledCharacterFixedUpdate = false; _characterFixedUpdateCompatibilityConfigured = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)"[I'm Scoutmaster] Could not install PEAKER ragdoll guard; controlled Scoutmaster Character.FixedUpdate remains enabled."); } else { _harmony.Patch((MethodBase)method, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _skipControlledCharacterFixedUpdate = false; _characterFixedUpdateCompatibilityConfigured = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Installed PEAKER ragdoll guard; controlled Scoutmaster Character.FixedUpdate enabled."); } } catch (Exception ex) { _skipControlledCharacterFixedUpdate = false; ((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm Scoutmaster] Failed to install PEAKER ragdoll guard; will retry while keeping controlled Scoutmaster Character.FixedUpdate enabled: " + ex.Message)); } } private static Type FindLoadedType(string fullName) { if (string.IsNullOrEmpty(fullName)) { return null; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(fullName, throwOnError: false); if (type != null) { return type; } } } catch { } return null; } private static MethodInfo FindMethod(Type type, string name, bool preferStatic, params Type[] parameterTypes) { if (type == null || string.IsNullOrEmpty(name)) { return null; } BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic | (preferStatic ? BindingFlags.Static : BindingFlags.Instance); try { MethodInfo method = type.GetMethod(name, bindingAttr, null, parameterTypes ?? Type.EmptyTypes, null); if (method != null) { return method; } } catch { } try { MethodInfo[] methods = type.GetMethods(bindingAttr); foreach (MethodInfo methodInfo in methods) { if (methodInfo == null || methodInfo.Name != name) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); int num = ((parameterTypes != null) ? parameterTypes.Length : 0); if (parameters.Length != num) { continue; } bool flag = true; for (int j = 0; j < num; j++) { Type type2 = parameterTypes[j]; Type parameterType = parameters[j].ParameterType; if (!(type2 == null) && !(parameterType == type2) && !string.Equals(parameterType.FullName, type2.FullName, StringComparison.Ordinal)) { flag = false; break; } } if (flag) { return methodInfo; } } } catch { } return null; } private void ConfigureThirdPartyCompatibility() { //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Expected O, but got Unknown //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Expected O, but got Unknown //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Expected O, but got Unknown //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Expected O, but got Unknown if (_peakStatsCompatibilityConfigured) { return; } try { Type type = FindLoadedType("PeakStats.MonoBehaviours.ProximityStaminaManager"); Type type2 = FindLoadedType("PeakStats.MonoBehaviours.CharacterStaminaBar"); Type type3 = FindLoadedType("PeakStats.MonoBehaviours.CharacterBarAffliction"); if (type == null || type2 == null || type3 == null) { LogVerbose("[I'm Scoutmaster] PeakStats types not found yet, will retry. ProximityManager=" + (type != null) + " StaminaBar=" + (type2 != null) + " BarAffliction=" + (type3 != null)); return; } MethodInfo methodInfo = FindMethod(type, "Update", preferStatic: false, Type.EmptyTypes); MethodInfo methodInfo2 = FindMethod(type, "CreateStaminaBar", true, typeof(Character)); MethodInfo methodInfo3 = FindMethod(type2, "Update", preferStatic: false, Type.EmptyTypes); MethodInfo methodInfo4 = FindMethod(type3, "FetchReferences", preferStatic: false, Type.EmptyTypes); FieldInfo field = type.GetField("staminaBars", InstanceFlags); FieldInfo field2 = type2.GetField("_observedCharacter", InstanceFlags); FieldInfo field3 = type3.GetField("characterStaminaBar", InstanceFlags); MethodInfo methodInfo5 = AccessTools.Method(typeof(Plugin), "PeakStatsProximityManagerUpdatePrefix", (Type[])null, (Type[])null); MethodInfo methodInfo6 = AccessTools.Method(typeof(Plugin), "PeakStatsCreateStaminaBarPrefix", (Type[])null, (Type[])null); MethodInfo methodInfo7 = AccessTools.Method(typeof(Plugin), "PeakStatsCharacterStaminaBarUpdatePrefix", (Type[])null, (Type[])null); MethodInfo methodInfo8 = AccessTools.Method(typeof(Plugin), "PeakStatsCharacterBarAfflictionFetchReferencesPrefix", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo3 == null || methodInfo4 == null || field == null || field2 == null || field3 == null || methodInfo5 == null || methodInfo7 == null || methodInfo8 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm Scoutmaster] PeakStats types found but some members missing. Update=" + (methodInfo != null) + " CreateStaminaBar=" + (methodInfo2 != null) + " StaminaBarUpdate=" + (methodInfo3 != null) + " FetchReferences=" + (methodInfo4 != null) + " staminaBars=" + (field != null) + " _observedCharacter=" + (field2 != null) + " characterStaminaBar=" + (field3 != null))); } else { PeakStatsStaminaBarsField = field; PeakStatsObservedCharacterField = field2; PeakStatsAfflictionBarField = field3; PeakStatsStaminaBarType = type2; PeakStatsAfflictionType = type3; _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (methodInfo2 != null && methodInfo6 != null) { _harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } _harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo7), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); CleanupPeakStatsUi(); _peakStatsCompatibilityConfigured = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Installed PeakStats compatibility guard for controlled Scoutmaster."); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm Scoutmaster] Failed to install PeakStats compatibility guard: " + ex.Message)); } } private static bool PeakerRagdollControlPostfixPrefix([HarmonyArgument("__instance")] CharacterData data, [HarmonyArgument("__result")] ref float ragdollControl) { try { object? obj = CharacterDataCharacterField?.GetValue(data); Character val = (Character)((obj is Character) ? obj : null); if ((Object)(object)val == (Object)null && (Object)(object)data != (Object)null) { val = ((Component)data).GetComponent<Character>(); } if (IsStashedSourceCharacter(val) || (IsControlledScoutmasterCharacter(val) && !IsControlledScoutmasterIncapacitated(val))) { ragdollControl = 1f; return false; } } catch { } return true; } internal static void SetCharacterDeadWithoutReconnect(Character character, bool dead) { if ((Object)(object)character?.data == (Object)null) { return; } try { if (CharacterDataDeadField != null) { CharacterDataDeadField.SetValue(character.data, dead); return; } } catch { } try { if (character.data.dead != dead) { character.data.dead = dead; } } catch { } } internal static bool ShouldSkipReconnectDataUpdate(Character character) { if ((Object)(object)character == (Object)null) { return true; } if (IsControlledScoutmasterCharacter(character) || IsStashedSourceCharacter(character) || IsCharacterInControlledCreationRoot(character)) { return true; } try { if ((Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null || (Object)(object)character.refs.stats == (Object)null) { return true; } return (Object)(object)character.player == (Object)null; } catch { return true; } } internal static bool ShouldSuppressSlipperyJellyfishSend(Collider other) { if ((Object)(object)other == (Object)null) { return false; } try { Character val = default(Character); if (!CharacterRagdoll.TryGetCharacterFromCollider(other, ref val)) { return false; } if (IsStashedSourceCharacter(val) || IsCharacterInControlledCreationRoot(val)) { return true; } if ((Object)(object)val == (Object)(object)Character.localCharacter && ((Object)(object)val.refs?.view == (Object)null || val.refs.view.ViewID <= 0)) { return true; } } catch { } return false; } internal static bool ShouldSkipSlipperyJellyfishTrigger(int targetID) { if (targetID <= 0) { return true; } try { PhotonView val = PhotonView.Find(targetID); if ((Object)(object)val == (Object)null) { return true; } Character component = ((Component)val).GetComponent<Character>(); if ((Object)(object)component == (Object)null || (Object)(object)component.data == (Object)null || component.refs == null || (Object)(object)component.refs.afflictions == (Object)null) { return true; } if (IsStashedSourceCharacter(component) || IsCharacterInControlledCreationRoot(component)) { return true; } Bodypart bodypart = GetBodypart(component, (BodypartType)16); int result; if (!((Object)(object)((bodypart != null) ? bodypart.Rig : null) == (Object)null)) { Bodypart bodypart2 = GetBodypart(component, (BodypartType)13); if (!((Object)(object)((bodypart2 != null) ? bodypart2.Rig : null) == (Object)null)) { Bodypart bodypart3 = GetBodypart(component, (BodypartType)0); if (!((Object)(object)((bodypart3 != null) ? bodypart3.Rig : null) == (Object)null)) { Bodypart bodypart4 = GetBodypart(component, (BodypartType)4); result = (((Object)(object)((bodypart4 != null) ? bodypart4.Rig : null) == (Object)null) ? 1 : 0); goto IL_00e1; } } } result = 1; goto IL_00e1; IL_00e1: return (byte)result != 0; } catch { return true; } } private void LateUpdate() { RefreshControlledScoutmasterVisuals(); ActiveScoutmasterSession session = _session; if (session != null && session.IsActive) { UpdateScoutmasterHudState(); } RefreshRestoredPlayerCamera(); } private void BindConfig(bool isChineseLanguage) { ToggleKey = BindEntry<KeyCode>(ConfigKey.ToggleKey, (KeyCode)103, isChineseLanguage); StaminaRefill = BindEntry(ConfigKey.StaminaRefill, 1f, isChineseLanguage); ThrowForce = BindEntry(ConfigKey.ThrowForce, 1500f, isChineseLanguage); ThrowUpBias = BindEntry(ConfigKey.ThrowUpBias, 0.3f, isChineseLanguage); ThrowFallSeconds = BindEntry(ConfigKey.ThrowFallSeconds, 3f, isChineseLanguage); ThirdPersonHeightOffset = BindEntry(ConfigKey.ThirdPersonHeightOffset, 1.35f, isChineseLanguage); ThirdPersonDistance = BindEntry(ConfigKey.ThirdPersonDistance, 7.5f, isChineseLanguage); SourceStashDistance = BindEntry(ConfigKey.SourceStashDistance, 30f, isChineseLanguage); RestoreAtScoutmasterPosition = BindEntry(ConfigKey.RestoreAtScoutmasterPosition, defaultValue: true, isChineseLanguage); RestoreGroundOffset = BindEntry(ConfigKey.RestoreGroundOffset, 1.2f, isChineseLanguage); HideHudWhileTransformed = BindEntry(ConfigKey.HideHudWhileTransformed, defaultValue: true, isChineseLanguage); VerboseLogs = BindEntry(ConfigKey.VerboseLogs, defaultValue: false, isChineseLanguage); MigrateLocalizedConfigEntries(); ClampConfigValues(); } private ConfigEntry<T> BindEntry<T>(ConfigKey configKey, T defaultValue, bool isChineseLanguage) { return ((BaseUnityPlugin)this).Config.Bind<T>(GetSectionName(configKey, isChineseLanguage), GetKeyName(configKey, isChineseLanguage), defaultValue, CreateConfigDescription(configKey, isChineseLanguage)); } private ConfigDescription CreateConfigDescription(ConfigKey configKey, bool isChineseLanguage) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown string localizedDescription = GetLocalizedDescription(configKey, isChineseLanguage); return (ConfigDescription)(configKey switch { ConfigKey.StaminaRefill => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()), ConfigKey.ThrowForce => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 5000f), Array.Empty<object>()), ConfigKey.ThrowUpBias => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()), ConfigKey.ThrowFallSeconds => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()), ConfigKey.ThirdPersonHeightOffset => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 6f), Array.Empty<object>()), ConfigKey.ThirdPersonDistance => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 16f), Array.Empty<object>()), ConfigKey.SourceStashDistance => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 200f), Array.Empty<object>()), ConfigKey.RestoreGroundOffset => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 5f), Array.Empty<object>()), _ => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)null, Array.Empty<object>()), }); } internal static float GetControlledStaminaFill() { return Mathf.Clamp(StaminaRefill?.Value ?? 1f, 0.1f, 1f); } private void ToggleScoutmasterForm() { if (!_switching) { ActiveScoutmasterSession session = _session; if (session != null && session.IsActive) { ExitScoutmasterForm(restorePlayer: true); } else { ((MonoBehaviour)this).StartCoroutine(EnterScoutmasterFormRoutine()); } } } private void HandleToggleHold() { //IL_0005: 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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) KeyCode value = ToggleKey.Value; if (Input.GetKeyDown(value)) { _toggleHoldStartTime = Time.unscaledTime; _toggleHoldTriggered = false; } if (Input.GetKeyUp(value)) { float num = ((_toggleHoldStartTime >= 0f) ? (Time.unscaledTime - _toggleHoldStartTime) : 0f); bool num2 = !_toggleHoldTriggered && num > 0f && num <= 0.3f; _toggleHoldStartTime = -1f; _toggleHoldTriggered = false; if (num2) { ActiveScoutmasterSession session = _session; if (session != null && session.IsActive && Time.unscaledTime - _lastToggleTime >= 0.35f) { _lastToggleTime = Time.unscaledTime; TriggerControlledScoutmasterManualFall(); } } } else if (!Input.GetKey(value)) { _toggleHoldStartTime = -1f; _toggleHoldTriggered = false; } else if (!_toggleHoldTriggered && !(_toggleHoldStartTime < 0f) && !(Time.unscaledTime - _toggleHoldStartTime < 1f) && !(Time.unscaledTime - _lastToggleTime < 0.35f)) { _toggleHoldTriggered = true; _lastToggleTime = Time.unscaledTime; ToggleScoutmasterForm(); } } private void TriggerControlledScoutmasterManualFall() { Character controlledScoutmasterCharacter = GetControlledScoutmasterCharacter(); if (!((Object)(object)controlledScoutmasterCharacter == (Object)null)) { TriggerControlledScoutmasterManualFall(controlledScoutmasterCharacter); } } [IteratorStateMachine(typeof(<EnterScoutmasterFormRoutine>d__198))] private IEnumerator EnterScoutmasterFormRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnterScoutmasterFormRoutine>d__198(0) { <>4__this = this }; } private static bool CanTransform(Character sourceCharacter) { if ((Object)(object)sourceCharacter == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"[I'm Scoutmaster] No local character found."); } return false; } if ((Object)(object)sourceCharacter.data == (Object)null || sourceCharacter.refs == null || (Object)(object)((MonoBehaviourPun)sourceCharacter).photonView == (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)"[I'm Scoutmaster] Local character is not ready yet."); } return false; } if (IsDeadForTransform(sourceCharacter)) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)"[I'm Scoutmaster] Cannot transform after the player has died."); } return false; } if (IsControlledScoutmasterCharacter(sourceCharacter)) { ManualLogSource log4 = Log; if (log4 != null) { log4.LogWarning((object)"[I'm Scoutmaster] Already controlling Scoutmaster."); } return false; } return true; } private static bool IsDeadForTransform(Character character) { if ((Object)(object)character?.data == (Object)null) { return false; } try { if (character.data.dead) { return true; } } catch { } try { return character.data.fullyPassedOut && character.data.deathTimer >= 1f; } catch { return false; } } private static Quaternion GetSpawnRotation(Character sourceCharacter) { //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_0026: 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) //IL_0031: 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_0025: 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_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_0040: 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 val = sourceCharacter.data.lookDirection_Flat; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = ((Component)sourceCharacter).transform.forward; } val = Vector3.ProjectOnPlane(val, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); } private static GameObject CreateScoutmaster(Vector3 position, Quaternion rotation) { //IL_0005: 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_001e: Unknown result type (might be due to invalid IL or missing references) GameObject val = TryCreateNetworkScoutmaster("Character_Scoutmaster", position, rotation); if ((Object)(object)val != (Object)null) { return val; } return TryCreateLocalScoutmaster("Character_Scoutmaster", position, rotation); } private static GameObject TryCreateNetworkScoutmaster(string resourceName, Vector3 position, Quaternion rotation) { //IL_001a: 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) if (string.IsNullOrWhiteSpace(resourceName) || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode)) { return null; } try { return PhotonNetwork.Instantiate(resourceName, position, rotation, (byte)0, BuildControlledScoutmasterInstantiationData()); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Photon instantiate failed for " + resourceName + ": " + ex.Message)); } return null; } } private static object[] BuildControlledScoutmasterInstantiationData() { int num = 0; try { Player localPlayer = Player.localPlayer; if ((Object)(object)((localPlayer != null) ? ((MonoBehaviourPun)localPlayer).photonView : null) != (Object)null) { num = ((MonoBehaviourPun)Player.localPlayer).photonView.OwnerActorNr; } else if (PhotonNetwork.LocalPlayer != null) { num = PhotonNetwork.LocalPlayer.ActorNumber; } } catch { num = 0; } return new object[3] { "ImScoutmaster.ControlledScoutmaster", 1, num }; } private static GameObject TryCreateLocalScoutmaster(string resourceName, Vector3 position, Quaternion rotation) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //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) try { GameObject val = Resources.Load<GameObject>(resourceName); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = new GameObject("ImScoutmaster_LocalScoutmaster_Staging"); val2.SetActive(false); _controlledScoutmasterCreationRoot = val2.transform; try { GameObject obj = Object.Instantiate<GameObject>(val, position, rotation, val2.transform); obj.SetActive(false); obj.transform.SetParent((Transform)null, true); return obj; } finally { _controlledScoutmasterCreationRoot = null; Object.Destroy((Object)(object)val2); } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Local instantiate failed for " + resourceName + ": " + ex.Message)); } return null; } } internal void ExitScoutmasterForm(bool restorePlayer) { if (_session == null) { return; } _switching = true; try { _session.Exit(restorePlayer); } finally { _session = null; ClearCameraOverride(); _viewScoutmasterObject = null; RestoreHudAfterScoutmaster(); _switching = false; } } internal static bool ShouldUseIsolatedCharacterLifecycle(Character character) { if ((Object)(object)character != (Object)null && HasScoutmasterComponent(character)) { if (!IsCharacterInControlledCreationRoot(character)) { return IsControlledScoutmasterCharacter(character); } return true; } return false; } internal static bool ShouldSkipCharacterRegistration(Character character) { if ((Object)(object)character == (Object)null || !HasScoutmasterComponent(character)) { return false; } if (!IsCharacterInControlledCreationRoot(character) && !IsControlledScoutmasterCharacter(character)) { return false; } LogVerbose("Skipped PlayerHandler registra