using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak; using Photon.Pun; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Thanks.I_am_a_BigGhost")] [assembly: AssemblyDescription("Client-side controllable big-ghost form for PEAK. Press B in the Airport lobby to become the big ghost that rises from the misty swamp.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Thanks")] [assembly: AssemblyProduct("I'm a Ghost")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3a7b9c51-4d2e-4f6a-8b10-2c3d4e5f6a7b")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ImGhost { [BepInPlugin("com.github.Thanks.ImGhost", "I'm a Ghost", "0.1.0")] public sealed class GhostPlugin : BaseUnityPlugin { public const string Id = "com.github.Thanks.ImGhost"; public const string Name = "I'm a Ghost"; public const string Version = "0.1.0"; public const string LobbySceneName = "Airport"; internal static ManualLogSource Log; internal static ConfigEntry ToggleKey; internal static ConfigEntry AttackKey; internal static ConfigEntry UpKey; internal static ConfigEntry DownKey; internal static ConfigEntry SprintKey; internal static ConfigEntry MovementSpeed; internal static ConfigEntry VerticalSpeed; internal static ConfigEntry SprintMultiplier; internal static ConfigEntry AttackChargeSeconds; internal static ConfigEntry AttackRevertSeconds; internal static ConfigEntry AttackRadius; internal static ConfigEntry KnockbackForce; internal static ConfigEntry CameraDistance; internal static ConfigEntry CameraHeight; internal static ConfigEntry CameraFov; internal static ConfigEntry ShowGhostVisual; private readonly Harmony _harmony = new Harmony("com.github.Thanks.ImGhost"); private GhostController _controller; private bool _switching; private bool _lastTogglePressed; internal static bool IsInLobby() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) try { Scene activeScene = SceneManager.GetActiveScene(); return ((Scene)(ref activeScene)).name == "Airport"; } catch { return false; } } private void Awake() { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Expected O, but got Unknown //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Expected O, but got Unknown //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Expected O, but got Unknown //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _harmony.PatchAll(typeof(GhostHarmonyPatches).Assembly); ConfigureOptionalCharacterPatches(); ToggleKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "ToggleKey", (KeyCode)98, "Press to become the big ghost (only in the Airport lobby). Press again to return to normal."); AttackKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "AttackKey", (KeyCode)324, "Right-click while in ghost form to trigger the ghost explosion attack. The player reverts after the attack."); UpKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "UpKey", (KeyCode)32, "Hold Space to fly up while in ghost form."); DownKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "DownKey", (KeyCode)306, "Hold Ctrl to fly down while in ghost form."); SprintKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "SprintKey", (KeyCode)304, "Hold Shift to sprint (move faster) while in ghost form."); MovementSpeed = ((BaseUnityPlugin)this).Config.Bind("Ghost", "MovementSpeed", 14f, new ConfigDescription("How fast the ghost glides with WASD.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 40f), Array.Empty())); VerticalSpeed = ((BaseUnityPlugin)this).Config.Bind("Ghost", "VerticalSpeed", 12f, new ConfigDescription("How fast the ghost rises and sinks.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 30f), Array.Empty())); SprintMultiplier = ((BaseUnityPlugin)this).Config.Bind("Ghost", "SprintMultiplier", 2f, new ConfigDescription("Speed multiplier while holding the sprint key.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 5f), Array.Empty())); AttackChargeSeconds = ((BaseUnityPlugin)this).Config.Bind("Ghost", "AttackChargeSeconds", 0.8f, new ConfigDescription("How long the ghost glows before exploding after the attack is triggered.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 3f), Array.Empty())); AttackRevertSeconds = ((BaseUnityPlugin)this).Config.Bind("Ghost", "AttackRevertSeconds", 1f, new ConfigDescription("Seconds after the explosion until the player automatically reverts to normal.", (AcceptableValueBase)(object)new AcceptableValueRange(0.3f, 6f), Array.Empty())); AttackRadius = ((BaseUnityPlugin)this).Config.Bind("Ghost", "AttackRadius", 10f, new ConfigDescription("Radius in which nearby players are knocked down by the ghost explosion.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 30f), Array.Empty())); KnockbackForce = ((BaseUnityPlugin)this).Config.Bind("Ghost", "KnockbackForce", 15f, new ConfigDescription("How strongly nearby players are launched by the ghost explosion.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 40f), Array.Empty())); CameraDistance = ((BaseUnityPlugin)this).Config.Bind("Camera", "Distance", 16f, new ConfigDescription("Third-person ghost camera distance.", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 30f), Array.Empty())); CameraHeight = ((BaseUnityPlugin)this).Config.Bind("Camera", "Height", 5f, new ConfigDescription("Third-person ghost camera height above the player.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 14f), Array.Empty())); CameraFov = ((BaseUnityPlugin)this).Config.Bind("Camera", "Fov", 80f, new ConfigDescription("Field of view while in ghost form.", (AcceptableValueBase)(object)new AcceptableValueRange(60f, 110f), Array.Empty())); ShowGhostVisual = ((BaseUnityPlugin)this).Config.Bind("Ghost", "ShowGhostVisual", true, "Show the big ghost visual while transformed."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm a Ghost] Loaded version 0.1.0."); } private void ConfigureOptionalCharacterPatches() { TryPatchOptionalCharacterMethod("RPCA_Die", Type.EmptyTypes, "CharacterRpcDiePrefix", "Character.RPCA_Die()"); TryPatchOptionalCharacterMethod("RPCA_SetDead", Type.EmptyTypes, "CharacterRpcSetDeadPrefix", "Character.RPCA_SetDead()"); TryPatchOptionalCharacterMethod("RPCA_PassOut", Type.EmptyTypes, "CharacterRpcPassOutPrefix", "Character.RPCA_PassOut()"); TryPatchOptionalCharacterMethod("DieInstantly", Type.EmptyTypes, "CharacterDieInstantlyPrefix", "Character.DieInstantly()"); TryPatchOptionalCharacterMethod("HandleDeath", Type.EmptyTypes, "CharacterHandleDeathPrefix", "Character.HandleDeath()"); TryPatchOptionalCharacterMethod("WarpPlayerRPC", new Type[2] { typeof(Vector3), typeof(bool) }, "CharacterWarpPlayerRpcPrefix", "Character.WarpPlayerRPC(Vector3,bool)"); TryPatchOptionalCharacterMethod("WarpPlayer", new Type[2] { typeof(Vector3), typeof(bool) }, "CharacterWarpPlayerPrefix", "Character.WarpPlayer(Vector3,bool)"); TryPatchOptionalCharacterMethod("Fall", new Type[2] { typeof(float), typeof(float) }, "CharacterFallPrefix", "Character.Fall(float,float)"); TryPatchOptionalCharacterMethod("RPCA_Fall", new Type[2] { typeof(float), typeof(float) }, "CharacterRpcFallPrefix", "Character.RPCA_Fall(float,float)"); } private void TryPatchOptionalCharacterMethod(string methodName, Type[] parameterTypes, string prefixName, string description) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(typeof(Character), methodName, parameterTypes, (Type[])null); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[I'm a Ghost] Optional " + description + " patch skipped; method is not present in this game build.")); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(GhostHarmonyPatches), prefixName, (Type[])null, (Type[])null); if (methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm a Ghost] Optional " + description + " patch skipped; prefix method was not found.")); } else { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm a Ghost] Optional " + description + " patch failed: " + ex.Message)); } } private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) try { if ((int)ToggleKey.Value != 0) { bool key = Input.GetKey(ToggleKey.Value); if (key && !_lastTogglePressed) { ToggleGhostForm(); } _lastTogglePressed = key; if ((Object)(object)_controller != (Object)null && _controller.Active && !_controller.IsValid()) { ForceExit(); } if ((Object)(object)_controller != (Object)null && _controller.Active && !IsInLobby()) { ForceExit(); } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("[I'm a Ghost] Plugin.Update: " + ex)); } } } private void OnDestroy() { try { ForceExit(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm a Ghost] Exit during cleanup failed: " + ex.Message)); } } try { _harmony.UnpatchSelf(); } catch (Exception ex2) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("[I'm a Ghost] Harmony unpatch failed (non-fatal): " + ex2.Message)); } } } private void ToggleGhostForm() { if (_switching) { return; } if ((Object)(object)_controller != (Object)null && _controller.Active) { ExitGhost(); return; } Character localCharacter = Character.localCharacter; if (CanTransform(localCharacter)) { _switching = true; ((MonoBehaviour)this).StartCoroutine(EnterGhostRoutine(localCharacter)); } } private static bool CanTransform(Character character) { if (!IsInLobby()) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"[I'm a Ghost] Ghost form is only available in the Airport lobby."); } return false; } if ((Object)(object)character == (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)"[I'm a Ghost] No local character found."); } return false; } if (GhostController.IsLocalGhostCharacter(character)) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)"[I'm a Ghost] Already in ghost form."); } return false; } if (character.isZombie || character.isBot || character.isScoutmaster) { ManualLogSource log4 = Log; if (log4 != null) { log4.LogWarning((object)"[I'm a Ghost] Cannot transform while in another special form."); } return false; } if ((Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)((MonoBehaviourPun)character).photonView == (Object)null) { ManualLogSource log5 = Log; if (log5 != null) { log5.LogWarning((object)"[I'm a Ghost] Local character is not ready yet."); } return false; } if (character.data.dead || character.data.passedOut || character.data.fullyPassedOut || character.data.fallSeconds > 0f || character.data.isClimbing || character.data.isRopeClimbing || character.data.isVineClimbing) { ManualLogSource log6 = Log; if (log6 != null) { log6.LogWarning((object)"[I'm a Ghost] Local character is not in a valid state to transform."); } return false; } return true; } private IEnumerator EnterGhostRoutine(Character character) { try { _controller = ((Component)character).gameObject.GetComponent(); if ((Object)(object)_controller == (Object)null) { _controller = ((Component)character).gameObject.AddComponent(); } _controller.EnterGhost(character); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("[I'm a Ghost] Failed to enter ghost form:\n" + ex)); } _controller = null; } finally { _switching = false; } yield break; } private void ExitGhost() { _switching = true; try { _controller?.ExitGhost(); _controller = null; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("[I'm a Ghost] Failed to exit ghost form:\n" + ex)); } } finally { _switching = false; } } private void ForceExit() { if ((Object)(object)_controller == (Object)null) { return; } try { _controller.ExitGhost(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm a Ghost] ForceExit failed: " + ex.Message)); } } _controller = null; } } [DefaultExecutionOrder(600)] public sealed class GhostController : MonoBehaviour { private const float VelocitySharpness = 7f; private const float MaxVelocity = 55f; private const float AngularVelocityDamping = 0.92f; private const float MaxAngularVelocity = 10f; private const float GroundClearanceMin = 0.8f; private const float BallFaceMoveSharpness = 6f; private const float CameraLookAhead = 4f; private const float CameraCollisionRadius = 0.35f; private const float CameraTerrainClearance = 0.8f; private const float CameraSmoothTime = 0.08f; private const float CameraRotationSharpness = 12f; private const float DefaultCameraDistance = 16f; private const float DefaultCameraHeight = 5f; private const float DefaultCameraFov = 80f; private Character _character; private Vector3 _prevCenter; private Vector3 _cameraVelocity; private Vector3 _cameraSmoothedPosition; private Quaternion _cameraSmoothedRotation; private bool _cameraHasSmoothedPosition; private Vector3 _moveDirection; private GameObject _ghostVisualRoot; private GhostBall _ghostBall; private PhotonView _ghostPhotonView; private Rigidbody _ghostRigidbody; private Animator _ghostAnimator; private bool _ghostIsNetworked; private bool _attacking; private float _attackStartedAt; private bool _attackExploded; internal const string NetworkVisualMarker = "ImGhost.Visual"; private static readonly FieldInfo ReadyToExplodeField = typeof(GhostBall).GetField("_readyToExplode", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo ExplodingField = typeof(GhostBall).GetField("exploding", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo TickUntilDespawnField = typeof(GhostBall).GetField("tickUntilDespawn", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly int AnReadyToExplode = Animator.StringToHash("ReadyToExplode"); private static readonly int AnFadeOut = Animator.StringToHash("FadeOut"); private static readonly int AnExploded = Animator.StringToHash("Exploded"); private readonly Dictionary _hiddenHudStates = new Dictionary(); public static GhostBall ActiveGhostBall { get; private set; } public static Character ActiveGhostCharacter { get; private set; } public bool Active { get; private set; } public Character CharacterRef => _character; public bool IsValid() { if (!Active || (Object)(object)_character == (Object)null || (Object)(object)_character.data == (Object)null) { return false; } if (!_character.data.dead) { return !_character.data.fullyPassedOut; } return false; } private static void LogInfo(string message) { ManualLogSource log = GhostPlugin.Log; if (log != null) { log.LogInfo((object)("[I'm a Ghost] " + message)); } } private static void LogError(string entryPoint, Exception ex) { ManualLogSource log = GhostPlugin.Log; if (log != null) { log.LogError((object)("[I'm a Ghost] " + entryPoint + ": " + ex)); } } public static bool IsLocalGhostCharacter(Character character) { if ((Object)(object)character == (Object)null || !character.IsLocal) { return false; } GhostController component = ((Component)character).GetComponent(); if ((Object)(object)component != (Object)null) { return component.Active; } return false; } public void EnterGhost(Character character) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_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) _character = character; _prevCenter = character.Center; _cameraVelocity = Vector3.zero; _cameraHasSmoothedPosition = false; _attacking = false; _attackExploded = false; _attackStartedAt = 0f; Active = true; ActiveGhostCharacter = character; ((Behaviour)this).enabled = true; BuildGhostVisual(); HideHud(); LogInfo("Entered ghost form."); } public void ExitGhost() { if (Active || !((Object)(object)_ghostVisualRoot == (Object)null)) { Active = false; ActiveGhostCharacter = null; ((Behaviour)this).enabled = false; _attacking = false; _attackExploded = false; _attackStartedAt = 0f; DestroyGhostVisual(); RestoreHud(); LogInfo("Exited ghost form."); } } private void Update() { if (!Active || (Object)(object)_character == (Object)null) { return; } try { ClearNonMovementInput(); KeepPlayerAlive(); UpdateAttack(); if (Active) { UpdateGhostVisual(); HideHud(); } } catch (Exception ex) { LogError("GhostController.Update", ex); } } private void FixedUpdate() { if (!Active || (Object)(object)_character == (Object)null || _character.refs == null || (Object)(object)_character.refs.ragdoll == (Object)null) { return; } try { ApplyMovementVelocity(); StabilizeRagdoll(); } catch (Exception ex) { LogError("GhostController.FixedUpdate", ex); } } private void LateUpdate() { if (!Active || (Object)(object)_character == (Object)null) { return; } try { SyncCharacterData(); RefreshCamera(); } catch (Exception ex) { LogError("GhostController.LateUpdate", ex); } } private void OnDestroy() { if (Active) { Active = false; ActiveGhostCharacter = null; DestroyGhostVisual(); RestoreHud(); } } private void HideHud() { if (_hiddenHudStates.Count < 2) { TryHideCanvas("Canvas_HUD"); TryHideCanvas("Canvas_Names"); } } private void TryHideCanvas(string canvasName) { GameObject val = GameObject.Find(canvasName); if (!((Object)(object)val == (Object)null) && !_hiddenHudStates.ContainsKey(val)) { _hiddenHudStates[val] = val.activeSelf; if (val.activeSelf) { val.SetActive(false); } } } private void RestoreHud() { if (_hiddenHudStates.Count == 0) { return; } foreach (KeyValuePair hiddenHudState in _hiddenHudStates) { if ((Object)(object)hiddenHudState.Key != (Object)null) { hiddenHudState.Key.SetActive(hiddenHudState.Value); } } _hiddenHudStates.Clear(); } private void ClearNonMovementInput() { if (!((Object)(object)_character == (Object)null) && !((Object)(object)_character.input == (Object)null)) { _character.input.jumpWasPressed = false; _character.input.jumpIsPressed = false; _character.input.sprintIsPressed = false; _character.input.sprintWasPressed = false; _character.input.sprintToggleWasPressed = false; _character.input.usePrimaryWasPressed = false; _character.input.usePrimaryIsPressed = false; _character.input.useSecondaryWasPressed = false; _character.input.useSecondaryIsPressed = false; _character.input.crouchWasPressed = false; _character.input.crouchIsPressed = false; _character.input.crouchToggleWasPressed = false; _character.input.dropWasPressed = false; _character.input.dropIsPressed = false; _character.input.interactWasPressed = false; _character.input.interactIsPressed = false; } } private void KeepPlayerAlive() { if (!((Object)(object)_character == (Object)null) && !((Object)(object)_character.data == (Object)null)) { _character.data.dead = false; _character.data.zombified = false; _character.data.passedOut = false; _character.data.fullyPassedOut = false; _character.data.fallSeconds = 0f; _character.data.isSprinting = false; } } private Vector2 GetMovementInput() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0070: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_character == (Object)null || (Object)(object)_character.input == (Object)null) { return Vector2.zero; } Vector2 movementInput = _character.input.movementInput; movementInput.x = Mathf.Clamp(movementInput.x, -1f, 1f); movementInput.y = Mathf.Clamp(movementInput.y, -1f, 1f); return movementInput; } private void ApplyMovementVelocity() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) if (_attacking) { _moveDirection = Vector3.zero; Vector3 zero = Vector3.zero; { foreach (Bodypart part in _character.refs.ragdoll.partList) { Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null); if (!((Object)(object)val == (Object)null) && !val.isKinematic) { val.linearVelocity = Vector3.Lerp(val.linearVelocity, zero, Time.fixedDeltaTime * 7f); } } return; } } Vector3 val2 = (((Object)(object)_character.data != (Object)null) ? _character.data.lookDirection_Flat : Vector3.zero); if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.ProjectOnPlane(((Component)this).transform.forward, Vector3.up); } Vector3 val3 = Vector3.ProjectOnPlane(val2, Vector3.up); val2 = ((Vector3)(ref val3)).normalized; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.forward; } Vector2 movementInput = GetMovementInput(); val3 = Vector3.Cross(Vector3.up, val2); Vector3 normalized = ((Vector3)(ref val3)).normalized; Vector3 val4 = val2 * movementInput.y + normalized * movementInput.x; if (((Vector3)(ref val4)).sqrMagnitude > 1f) { ((Vector3)(ref val4)).Normalize(); } float num = 0f; if ((int)GhostPlugin.UpKey.Value != 0 && Input.GetKey(GhostPlugin.UpKey.Value)) { num += 1f; } if ((int)GhostPlugin.DownKey.Value != 0 && Input.GetKey(GhostPlugin.DownKey.Value)) { num -= 1f; } float num2 = 1f; if ((int)GhostPlugin.SprintKey.Value != 0 && Input.GetKey(GhostPlugin.SprintKey.Value)) { num2 = Mathf.Max(1f, GhostPlugin.SprintMultiplier.Value); } Vector3 val5 = (val4 * GhostPlugin.MovementSpeed.Value + Vector3.up * (num * GhostPlugin.VerticalSpeed.Value)) * num2; if (num < 0f) { float groundHeight = GetGroundHeight(_character.Center); if (!float.IsNaN(groundHeight) && _character.Center.y <= groundHeight + 0.8f) { val5.y = Mathf.Max(val5.y, 0f); } } _moveDirection = ((((Vector3)(ref val4)).sqrMagnitude > 0.0001f) ? val4 : Vector3.zero); foreach (Bodypart part2 in _character.refs.ragdoll.partList) { Rigidbody val6 = (((Object)(object)part2 != (Object)null) ? part2.Rig : null); if (!((Object)(object)val6 == (Object)null) && !val6.isKinematic) { Vector3 val7 = Vector3.Lerp(val6.linearVelocity, val5, Time.fixedDeltaTime * 7f); val6.linearVelocity = Vector3.ClampMagnitude(val7, 55f); } } } private float GetGroundHeight(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) try { RaycastHit groundPosRaycast = HelperFunctions.GetGroundPosRaycast(position + Vector3.up * 400f, (LayerType)2, 0f); if ((Object)(object)((RaycastHit)(ref groundPosRaycast)).transform != (Object)null) { return ((RaycastHit)(ref groundPosRaycast)).point.y; } } catch { } try { RaycastHit groundPosRaycast2 = HelperFunctions.GetGroundPosRaycast(position + Vector3.up * 400f, (LayerType)1, 0f); if ((Object)(object)((RaycastHit)(ref groundPosRaycast2)).transform != (Object)null) { return ((RaycastHit)(ref groundPosRaycast2)).point.y; } } catch { } return float.NaN; } private void StabilizeRagdoll() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_character.refs.ragdoll == (Object)null) { return; } foreach (Bodypart part in _character.refs.ragdoll.partList) { Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null); if (!((Object)(object)val == (Object)null) && !val.isKinematic) { val.useGravity = false; part.forcesToAdd = Vector3.zero; val.angularVelocity *= 0.92f; Vector3 angularVelocity = val.angularVelocity; if (((Vector3)(ref angularVelocity)).magnitude > 10f) { val.angularVelocity = Vector3.ClampMagnitude(val.angularVelocity, 10f); } if (val.linearVelocity.y < -55f) { Vector3 linearVelocity = val.linearVelocity; linearVelocity.y = -55f; val.linearVelocity = linearVelocity; } } } } private void SyncCharacterData() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_0062: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_character == (Object)null) && !((Object)(object)_character.data == (Object)null)) { Vector3 center = _character.Center; Vector3 avarageVelocity = ((((Vector3)(ref _prevCenter)).sqrMagnitude > 0f) ? ((center - _prevCenter) / Mathf.Max(Time.deltaTime, 0.0001f)) : Vector3.zero); _prevCenter = center; _character.data.avarageLastFrameVelocity = _character.data.avarageVelocity; _character.data.avarageVelocity = avarageVelocity; _character.data.worldMovementInput = (_character.data.worldMovementInput_Grounded = Vector3.zero); _character.data.sinceGrounded = Mathf.Min(_character.data.sinceGrounded, 0.1f); } } private void UpdateAttack() { //IL_000d: 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) if (!_attacking) { if ((int)GhostPlugin.AttackKey.Value != 0 && Input.GetKeyDown(GhostPlugin.AttackKey.Value)) { StartAttack(); } return; } float num = Time.unscaledTime - _attackStartedAt; if (!_attackExploded && num >= GhostPlugin.AttackChargeSeconds.Value) { _attackExploded = true; DoExplode(); } if (num >= GhostPlugin.AttackChargeSeconds.Value + GhostPlugin.AttackRevertSeconds.Value) { ExitGhost(); } } private void StartAttack() { _attacking = true; _attackExploded = false; _attackStartedAt = Time.unscaledTime; SetGhostValue(ReadyToExplodeField, true); if ((Object)(object)_ghostAnimator != (Object)null) { _ghostAnimator.SetBool(AnReadyToExplode, true); } LogInfo("Ghost attack charging..."); } private void DoExplode() { //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) LogInfo("Ghost attack exploded!"); if ((Object)(object)_ghostBall != (Object)null && (Object)(object)_ghostBall.explosionPrefab != (Object)null) { try { Object.Instantiate(_ghostBall.explosionPrefab, _character.Center, Quaternion.identity); } catch (Exception ex) { LogError("GhostController.DoExplode (explosion prefab)", ex); } } SetGhostValue(ExplodingField, true); if ((Object)(object)_ghostAnimator != (Object)null) { _ghostAnimator.SetBool(AnExploded, true); } KnockDownNearbyPlayers(); } private void KnockDownNearbyPlayers() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) float value = GhostPlugin.AttackRadius.Value; float value2 = GhostPlugin.KnockbackForce.Value; Vector3 center = _character.Center; foreach (Character allCharacter in Character.AllCharacters) { if ((Object)(object)allCharacter == (Object)null || (Object)(object)allCharacter == (Object)(object)_character || (Object)(object)allCharacter.data == (Object)null || !allCharacter.data.fullyConscious || allCharacter.refs == null || (Object)(object)allCharacter.refs.view == (Object)null) { continue; } Vector3 val = allCharacter.Center - center; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude > value) && !(magnitude < 0.001f)) { Vector3 val2 = val / magnitude * value2 + Vector3.up * (value2 * 0.55f); try { allCharacter.refs.view.RPC("RPCA_AddForceAtPosition", (RpcTarget)0, new object[3] { val2, center, value }); } catch (Exception ex) { LogError("GhostController.KnockDownNearbyPlayers (force)", ex); } try { allCharacter.refs.view.RPC("RPCA_Fall", (RpcTarget)0, new object[2] { 1.2f, 0.25f }); } catch (Exception ex2) { LogError("GhostController.KnockDownNearbyPlayers (fall)", ex2); } } } } private static void SetGhostValue(FieldInfo field, object value) { try { if (field != null && (Object)(object)ActiveGhostBall != (Object)null) { field.SetValue(ActiveGhostBall, value); } } catch { } } private void BuildGhostVisual() { if ((Object)(object)_ghostVisualRoot != (Object)null || (Object)(object)_character == (Object)null) { return; } try { GameObject val = Resources.Load("GhostBall"); if ((Object)(object)val == (Object)null) { LogInfo("Resources.Load(\"GhostBall\") returned null; no ghost visual will be shown."); } else if (PhotonNetwork.InRoom && (Object)(object)((MonoBehaviourPun)_character).photonView != (Object)null && ((MonoBehaviourPun)_character).photonView.ViewID > 0) { BuildNetworkedGhost(val); } else { BuildLocalGhost(val); } } catch (Exception ex) { LogError("GhostController.BuildGhostVisual", ex); DestroyGhostVisual(); } } private void BuildNetworkedGhost(GameObject prefab) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) GameObject val = PhotonNetwork.Instantiate("GhostBall", _character.Center, Quaternion.identity, (byte)0, new object[2] { "ImGhost.Visual", ((MonoBehaviourPun)_character).photonView.ViewID }); ((Object)val).name = "ImGhostNetworked"; _ghostVisualRoot = val; _ghostIsNetworked = true; _ghostBall = val.GetComponent(); ActiveGhostBall = _ghostBall; _ghostPhotonView = val.GetComponent(); _ghostRigidbody = val.GetComponent(); _ghostAnimator = val.GetComponent(); if ((Object)(object)_ghostRigidbody != (Object)null) { _ghostRigidbody.isKinematic = true; } KeepGhostAliveIndefinitely(); val.SetActive(GhostPlugin.ShowGhostVisual.Value); LogInfo("Spawned networked ghost visual with vanilla GhostBall prefab."); } private void BuildLocalGhost(GameObject prefab) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(prefab, _character.Center, Quaternion.identity); ((Object)val).name = "ImGhostLocal"; _ghostVisualRoot = val; _ghostIsNetworked = false; _ghostBall = val.GetComponent(); ActiveGhostBall = _ghostBall; _ghostRigidbody = val.GetComponent(); _ghostAnimator = val.GetComponent(); if ((Object)(object)_ghostBall != (Object)null) { ((Behaviour)_ghostBall).enabled = false; } if ((Object)(object)_ghostRigidbody != (Object)null) { _ghostRigidbody.isKinematic = true; } IgnoreCollisionWithOwnRagdoll(val); KeepGhostAliveIndefinitely(); val.SetActive(GhostPlugin.ShowGhostVisual.Value); LogInfo("Spawned local-only ghost visual (offline / single-player)."); } private void KeepGhostAliveIndefinitely() { SetGhostValue(TickUntilDespawnField, -1000f); if ((Object)(object)_ghostBall != (Object)null) { _ghostBall.lifetime = 9999f; } } private static void IgnoreCollisionWithOwnRagdoll(GameObject ghostRoot) { Character activeGhostCharacter = ActiveGhostCharacter; if ((Object)(object)activeGhostCharacter == (Object)null || activeGhostCharacter.refs == null || (Object)(object)activeGhostCharacter.refs.ragdoll == (Object)null) { return; } Collider[] componentsInChildren = ghostRoot.GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { return; } foreach (Bodypart part in activeGhostCharacter.refs.ragdoll.partList) { if ((Object)(object)part == (Object)null) { continue; } Collider[] componentsInChildren2 = ((Component)part).GetComponentsInChildren(true); Collider[] array = componentsInChildren; foreach (Collider val in array) { Collider[] array2 = componentsInChildren2; foreach (Collider val2 in array2) { if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && val.enabled && val2.enabled) { try { Physics.IgnoreCollision(val, val2, true); } catch { } } } } } } internal static void IgnoreCollisionWithCharacter(GameObject ghostRoot, Character character) { if ((Object)(object)ghostRoot == (Object)null || (Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.ragdoll == (Object)null) { return; } Collider[] componentsInChildren = ghostRoot.GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { return; } foreach (Bodypart part in character.refs.ragdoll.partList) { if ((Object)(object)part == (Object)null) { continue; } Collider[] componentsInChildren2 = ((Component)part).GetComponentsInChildren(true); Collider[] array = componentsInChildren; foreach (Collider val in array) { Collider[] array2 = componentsInChildren2; foreach (Collider val2 in array2) { if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && val.enabled && val2.enabled) { try { Physics.IgnoreCollision(val, val2, true); } catch { } } } } } } private void UpdateGhostVisual() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ae: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_ghostVisualRoot == (Object)null) && !((Object)(object)_character == (Object)null)) { if (_ghostVisualRoot.activeSelf != GhostPlugin.ShowGhostVisual.Value) { _ghostVisualRoot.SetActive(GhostPlugin.ShowGhostVisual.Value); } _ghostVisualRoot.transform.position = _character.Center; if (((Vector3)(ref _moveDirection)).sqrMagnitude > 0.01f) { Quaternion val = Quaternion.LookRotation(_moveDirection, Vector3.up); _ghostVisualRoot.transform.rotation = Quaternion.Slerp(_ghostVisualRoot.transform.rotation, val, Time.deltaTime * 6f); } } } private void DestroyGhostVisual() { ActiveGhostBall = null; if ((Object)(object)_ghostVisualRoot != (Object)null) { if (_ghostIsNetworked && PhotonNetwork.InRoom) { try { PhotonNetwork.Destroy(_ghostVisualRoot); } catch { } } else { Object.Destroy((Object)(object)_ghostVisualRoot); } } _ghostVisualRoot = null; _ghostBall = null; _ghostPhotonView = null; _ghostRigidbody = null; _ghostAnimator = null; _ghostIsNetworked = false; } private void RefreshCamera() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) try { Camera main = Camera.main; if (!((Object)(object)main == (Object)null)) { Vector3 thirdPersonCameraLookTarget = GetThirdPersonCameraLookTarget(_character); Vector3 val = ResolveCameraCollision(thirdPersonCameraLookTarget, GetThirdPersonCameraPosition(_character)); if (!_cameraHasSmoothedPosition) { _cameraSmoothedPosition = val; _cameraSmoothedRotation = GetCameraRotation(_cameraSmoothedPosition, thirdPersonCameraLookTarget); _cameraHasSmoothedPosition = true; } else { _cameraSmoothedPosition = Vector3.SmoothDamp(_cameraSmoothedPosition, val, ref _cameraVelocity, 0.08f); Quaternion cameraRotation = GetCameraRotation(_cameraSmoothedPosition, thirdPersonCameraLookTarget); float num = 1f - Mathf.Exp(-12f * Time.deltaTime); _cameraSmoothedRotation = Quaternion.Slerp(_cameraSmoothedRotation, cameraRotation, num); } ((Component)main).transform.SetPositionAndRotation(_cameraSmoothedPosition, _cameraSmoothedRotation); main.fieldOfView = Mathf.Lerp(main.fieldOfView, GetCameraFov(), Time.deltaTime * 4f); } } catch (Exception ex) { LogError("GhostController.RefreshCamera", ex); } } private static Vector3 GetThirdPersonCameraPosition(Character character) { //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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Vector3 cameraForward = GetCameraForward(character); return character.Center + Vector3.up * (GetCameraHeight() + 2f) - cameraForward * GetCameraDistance(); } private static Vector3 GetThirdPersonCameraLookTarget(Character character) { //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_0023: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //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) Vector3 cameraForward = GetCameraForward(character); float num = Mathf.Clamp((((Object)(object)character.data != (Object)null) ? ((Vector3)(ref character.data.lookDirection)).normalized : cameraForward).y, -0.35f, 0.65f); return character.Center + Vector3.up * (GetCameraHeight() + num * 3f) + cameraForward * 4f; } private static float GetCameraDistance() { return Mathf.Clamp((GhostPlugin.CameraDistance != null) ? GhostPlugin.CameraDistance.Value : 16f, 8f, 30f); } private static float GetCameraHeight() { return Mathf.Clamp((GhostPlugin.CameraHeight != null) ? GhostPlugin.CameraHeight.Value : 5f, 2f, 14f); } private static float GetCameraFov() { return Mathf.Clamp((GhostPlugin.CameraFov != null) ? GhostPlugin.CameraFov.Value : 80f, 60f, 110f); } private static Vector3 GetCameraForward(Character character) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)character.data != (Object)null) ? character.data.lookDirection_Flat : Vector3.zero); val = Vector3.ProjectOnPlane(val, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)Camera.main != (Object)null) { val = Vector3.ProjectOnPlane(((Component)Camera.main).transform.forward, Vector3.up); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.ProjectOnPlane(((Component)character).transform.forward, Vector3.up); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } return ((Vector3)(ref val)).normalized; } private Vector3 ResolveCameraCollision(Vector3 lookTarget, Vector3 desiredPosition) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0027: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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) RaycastHit val = HelperFunctions.LineCheck(lookTarget, desiredPosition, (LayerType)1, 0.35f, (QueryTriggerInteraction)1); if ((Object)(object)((RaycastHit)(ref val)).transform != (Object)null) { desiredPosition = ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * 0.8f; } float groundHeight = GetGroundHeight(desiredPosition); if (!float.IsNaN(groundHeight) && desiredPosition.y < groundHeight + 0.8f) { desiredPosition.y = groundHeight + 0.8f; } return desiredPosition; } private static Quaternion GetCameraRotation(Vector3 cameraPosition, Vector3 lookTarget) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = lookTarget - cameraPosition; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); } } [HarmonyPatch] public static class GhostHarmonyPatches { private static readonly HashSet CollisionIgnoredInstances = new HashSet(); private static bool IsGhostVisual(GhostBall ghostBall) { if ((Object)(object)ghostBall == (Object)null) { return false; } PhotonView component = ((Component)ghostBall).GetComponent(); object[] array = (((Object)(object)component != (Object)null) ? component.InstantiationData : null); if (array != null && array.Length != 0 && array[0] is string text) { return text == "ImGhost.Visual"; } return false; } private static bool IsGhost(Character character) { return GhostController.IsLocalGhostCharacter(character); } [HarmonyPatch(typeof(GhostBall), "Update")] [HarmonyPrefix] private static bool GhostBallUpdatePrefix(GhostBall __instance) { if (!IsGhostVisual(__instance)) { return true; } return false; } [HarmonyPatch(typeof(GhostBall), "FixedUpdate")] [HarmonyPrefix] private static bool GhostBallFixedUpdatePrefix(GhostBall __instance) { if (!IsGhostVisual(__instance)) { return true; } TrySetupCollisionIgnore(__instance); return false; } private static void TrySetupCollisionIgnore(GhostBall ghostBall) { try { GameObject gameObject = ((Component)ghostBall).gameObject; int instanceID = ((Object)gameObject).GetInstanceID(); if (CollisionIgnoredInstances.Contains(instanceID)) { return; } PhotonView component = ((Component)ghostBall).GetComponent(); object[] array = (((Object)(object)component != (Object)null) ? component.InstantiationData : null); if (array != null && array.Length >= 2 && array[1] is int num) { PhotonView val = PhotonView.Find(num); Character val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if (!((Object)(object)val2 == (Object)null)) { GhostController.IgnoreCollisionWithCharacter(gameObject, val2); CollisionIgnoredInstances.Add(instanceID); } } } catch { } } internal static bool CharacterRpcDiePrefix(Character __instance) { return !IsGhost(__instance); } internal static bool CharacterRpcSetDeadPrefix(Character __instance) { return !IsGhost(__instance); } internal static bool CharacterRpcPassOutPrefix(Character __instance) { return !IsGhost(__instance); } internal static bool CharacterDieInstantlyPrefix(Character __instance) { return !IsGhost(__instance); } internal static bool CharacterHandleDeathPrefix(Character __instance) { return !IsGhost(__instance); } internal static bool CharacterWarpPlayerRpcPrefix(Character __instance) { return !IsGhost(__instance); } internal static bool CharacterWarpPlayerPrefix(Character __instance) { return !IsGhost(__instance); } internal static bool CharacterFallPrefix(Character __instance) { return !IsGhost(__instance); } internal static bool CharacterRpcFallPrefix(Character __instance) { return !IsGhost(__instance); } } }