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 Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Thanks.ImTornado")] [assembly: AssemblyDescription("Client-side controllable tornado form for PEAK. Press H to become a tornado.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Thanks")] [assembly: AssemblyProduct("I'm a Tornado")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e7f2c4a1-8b3d-4e5f-9a60-1c2d3e4f5a6b")] [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 ImTornado { [BepInPlugin("com.github.Thanks.ImTornado", "I'm a Tornado", "0.1.0")] public sealed class WindPlugin : BaseUnityPlugin { public const string Id = "com.github.Thanks.ImTornado"; public const string Name = "I'm a Tornado"; public const string Version = "0.1.0"; internal static ManualLogSource Log; internal static ConfigEntry ToggleKey; internal static ConfigEntry WindStrength; internal static ConfigEntry MovementSpeed; internal static ConfigEntry HoverHeight; internal static ConfigEntry CameraDistance; internal static ConfigEntry CameraHeight; internal static ConfigEntry CameraFov; internal static ConfigEntry ShowTornadoVisual; private readonly Harmony _harmony = new Harmony("com.github.Thanks.ImTornado"); private TornadoController _controller; private bool _switching; private bool _lastTogglePressed; private void Awake() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _harmony.PatchAll(typeof(WindHarmonyPatches).Assembly); ConfigureOptionalCharacterPatches(); ToggleKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "ToggleKey", (KeyCode)104, "Press to toggle tornado form. Press again to return to normal."); WindStrength = ((BaseUnityPlugin)this).Config.Bind("Wind", "WindStrength", 1f, new ConfigDescription("Wind force multiplier applied to pushed players. (Push force now comes from the vanilla Tornado prefab; kept for config compatibility.)", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); MovementSpeed = ((BaseUnityPlugin)this).Config.Bind("Wind", "MovementSpeed", 12f, new ConfigDescription("How fast the tornado moves with WASD.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 40f), Array.Empty())); HoverHeight = ((BaseUnityPlugin)this).Config.Bind("Wind", "HoverHeight", 7f, new ConfigDescription("How high the tornado hovers above the ground.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 25f), Array.Empty())); CameraDistance = ((BaseUnityPlugin)this).Config.Bind("Camera", "Distance", 18f, new ConfigDescription("Third-person tornado camera distance.", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 30f), Array.Empty())); CameraHeight = ((BaseUnityPlugin)this).Config.Bind("Camera", "Height", 6f, new ConfigDescription("Third-person tornado camera height above the player.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 14f), Array.Empty())); CameraFov = ((BaseUnityPlugin)this).Config.Bind("Camera", "Fov", 82f, new ConfigDescription("Field of view while in tornado form.", (AcceptableValueBase)(object)new AcceptableValueRange(60f, 110f), Array.Empty())); ShowTornadoVisual = ((BaseUnityPlugin)this).Config.Bind("Wind", "ShowTornadoVisual", true, "Show a spinning tornado visual while transformed."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm a Tornado] 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)"); } 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 Tornado] Optional " + description + " patch skipped; method is not present in this game build.")); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(WindHarmonyPatches), prefixName, (Type[])null, (Type[])null); if (methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm a Tornado] 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 Tornado] 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) { ToggleTornadoForm(); } _lastTogglePressed = key; if ((Object)(object)_controller != (Object)null && _controller.Active && !_controller.IsValid()) { ForceExit(); } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("[I'm a Tornado] Plugin.Update: " + ex)); } } } private void OnDestroy() { try { ForceExit(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm a Tornado] Exit during cleanup failed: " + ex.Message)); } } try { _harmony.UnpatchSelf(); } catch (Exception ex2) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("[I'm a Tornado] Harmony unpatch failed (non-fatal): " + ex2.Message)); } } } private void ToggleTornadoForm() { if (_switching) { return; } if ((Object)(object)_controller != (Object)null && _controller.Active) { ExitTornado(); return; } Character localCharacter = Character.localCharacter; if (CanTransform(localCharacter)) { _switching = true; ((MonoBehaviour)this).StartCoroutine(EnterTornadoRoutine(localCharacter)); } } private static bool CanTransform(Character character) { if ((Object)(object)character == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"[I'm a Tornado] No local character found."); } return false; } if (TornadoController.IsLocalTornadoCharacter(character)) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)"[I'm a Tornado] Already in tornado form."); } return false; } if (character.isZombie || character.isBot || character.isScoutmaster) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)"[I'm a Tornado] 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 log4 = Log; if (log4 != null) { log4.LogWarning((object)"[I'm a Tornado] 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 log5 = Log; if (log5 != null) { log5.LogWarning((object)"[I'm a Tornado] Local character is not in a valid state to transform."); } return false; } return true; } private IEnumerator EnterTornadoRoutine(Character character) { try { _controller = ((Component)character).gameObject.GetComponent(); if ((Object)(object)_controller == (Object)null) { _controller = ((Component)character).gameObject.AddComponent(); } _controller.EnterTornado(character); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("[I'm a Tornado] Failed to enter tornado form:\n" + ex)); } _controller = null; } finally { _switching = false; } yield break; } private void ExitTornado() { _switching = true; try { _controller?.ExitTornado(); _controller = null; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("[I'm a Tornado] Failed to exit tornado form:\n" + ex)); } } finally { _switching = false; } } private void ForceExit() { if ((Object)(object)_controller == (Object)null) { return; } try { _controller.ExitTornado(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm a Tornado] ForceExit failed: " + ex.Message)); } } _controller = null; } } [DefaultExecutionOrder(600)] public sealed class TornadoController : MonoBehaviour { private const float HoverLerpRate = 4f; private const float HoverSnapDistance = 1.2f; private const float HoverMaxClimbSpeed = 6f; private const float VelocitySharpness = 7f; private const float MaxVelocity = 34f; private const float AngularVelocityDamping = 0.92f; private const float MaxAngularVelocity = 10f; private const float SpinAngularSpeed = 3.2f; private const float DefaultCameraDistance = 18f; private const float DefaultCameraHeight = 6f; private const float CameraLookAhead = 5f; 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 DefaultCameraFov = 82f; private Character _character; private Vector3 _prevCenter; private Vector3 _cameraVelocity; private Vector3 _cameraSmoothedPosition; private Quaternion _cameraSmoothedRotation; private bool _cameraHasSmoothedPosition; private float _lastGroundY; private GameObject _tornadoVisualRoot; private Tornado _tornadoAI; private PhotonView _tornadoPhotonView; private bool _tornadoIsNetworked; private float _nextTornadoVisualSync; internal const string NetworkVisualMarker = "ImTornado.Visual"; private const float NetworkVisualSyncInterval = 0.25f; private static readonly FieldInfo TornadoLifeTimeField = typeof(Tornado).GetField("lifeTime", BindingFlags.Instance | BindingFlags.NonPublic); private readonly Dictionary _hiddenHudStates = new Dictionary(); public static Tornado ActiveTornadoAI { get; private set; } public static Character ActiveTornadoCharacter { 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 = WindPlugin.Log; if (log != null) { log.LogInfo((object)("[I'm a Tornado] " + message)); } } private static void LogError(string entryPoint, Exception ex) { ManualLogSource log = WindPlugin.Log; if (log != null) { log.LogError((object)("[I'm a Tornado] " + entryPoint + ": " + ex)); } } public static bool IsLocalTornadoCharacter(Character character) { if ((Object)(object)character == (Object)null || !character.IsLocal) { return false; } TornadoController component = ((Component)character).GetComponent(); if ((Object)(object)component != (Object)null) { return component.Active; } return false; } public void EnterTornado(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; Active = true; ActiveTornadoCharacter = character; ((Behaviour)this).enabled = true; BuildTornadoVisual(); HideHud(); LogInfo("Entered tornado form."); } public void ExitTornado() { Active = false; ActiveTornadoCharacter = null; ((Behaviour)this).enabled = false; DestroyTornadoVisual(); RestoreHud(); LogInfo("Exited tornado form."); } private void Update() { if (!Active || (Object)(object)_character == (Object)null) { return; } try { ClearNonMovementInput(); KeepPlayerAlive(); UpdateTornadoVisual(); HideHud(); } catch (Exception ex) { LogError("TornadoController.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(); ApplyHoverVelocity(); ApplySpinningMotion(); StabilizeRagdoll(); } catch (Exception ex) { LogError("TornadoController.FixedUpdate", ex); } } private void LateUpdate() { if (!Active || (Object)(object)_character == (Object)null) { return; } try { SyncCharacterData(); RefreshCamera(); } catch (Exception ex) { LogError("TornadoController.LateUpdate", ex); } } private void OnDestroy() { if (Active) { Active = false; ActiveTornadoCharacter = null; DestroyTornadoVisual(); 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_0025: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_013b: 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_014b: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.ProjectOnPlane(((Component)this).transform.forward, Vector3.up); } Vector3 val2 = Vector3.ProjectOnPlane(val, Vector3.up); val = ((Vector3)(ref val2)).normalized; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } Vector2 movementInput = GetMovementInput(); val2 = Vector3.Cross(Vector3.up, val); Vector3 normalized = ((Vector3)(ref val2)).normalized; Vector3 val3 = val * movementInput.y + normalized * movementInput.x; if (((Vector3)(ref val3)).sqrMagnitude > 1f) { ((Vector3)(ref val3)).Normalize(); } float value = WindPlugin.MovementSpeed.Value; Vector3 val4 = val3 * value; foreach (Bodypart part in _character.refs.ragdoll.partList) { Rigidbody val5 = (((Object)(object)part != (Object)null) ? part.Rig : null); if (!((Object)(object)val5 == (Object)null) && !val5.isKinematic) { Vector3 linearVelocity = val5.linearVelocity; Vector3 val6 = linearVelocity; val6.y = 0f; Vector3 val7 = Vector3.Lerp(val6, val4, Time.fixedDeltaTime * 7f) + Vector3.up * linearVelocity.y; val5.linearVelocity = Vector3.ClampMagnitude(val7, 34f); } } } private void ApplyHoverVelocity() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_00cb: 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_00dc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_character == (Object)null) { return; } Vector3 center = _character.Center; float num = GetGroundHeight(center); if (float.IsNaN(num)) { num = _lastGroundY; } else { _lastGroundY = num; } float num2 = num + WindPlugin.HoverHeight.Value - center.y; float y = 0f; if (Mathf.Abs(num2) > 1.2f) { y = Mathf.Clamp(num2 * 4f, -6f, 6f); } 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) { Vector3 linearVelocity = val.linearVelocity; linearVelocity.y = y; val.linearVelocity = linearVelocity; } } } 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 ApplySpinningMotion() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a3: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0197: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_character == (Object)null || _character.refs == null || (Object)(object)_character.refs.ragdoll == (Object)null) { return; } Vector3 center = _character.Center; float num = 3.2f; 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) { Vector3 val2 = val.position - center; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { Vector3 val3 = Vector3.Cross(Vector3.up, ((Vector3)(ref val2)).normalized); Vector3 val4 = ((Vector3)(ref val3)).normalized * num; Vector3 angularVelocity = val.angularVelocity; angularVelocity.y = Mathf.Lerp(angularVelocity.y, val4.y + num, Time.fixedDeltaTime * 2f); angularVelocity.x = Mathf.Lerp(angularVelocity.x, val4.x, Time.fixedDeltaTime * 2f); angularVelocity.z = Mathf.Lerp(angularVelocity.z, val4.z, Time.fixedDeltaTime * 2f); val.angularVelocity = Vector3.ClampMagnitude(angularVelocity, 10f); } else { val.angularVelocity = Vector3.Lerp(val.angularVelocity, Vector3.up * num, Time.fixedDeltaTime * 2f); } } } } 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 < -34f) { Vector3 linearVelocity = val.linearVelocity; linearVelocity.y = -34f; 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 BuildTornadoVisual() { if ((Object)(object)_tornadoVisualRoot != (Object)null || (Object)(object)_character == (Object)null) { return; } try { GameObject val = Resources.Load("Tornado"); if ((Object)(object)val == (Object)null) { LogInfo("Resources.Load(\"Tornado\") returned null; no tornado visual will be shown."); } else if (PhotonNetwork.InRoom && (Object)(object)((MonoBehaviourPun)_character).photonView != (Object)null && ((MonoBehaviourPun)_character).photonView.ViewID > 0) { BuildNetworkedTornado(val); } else { BuildLocalTornado(val); } } catch (Exception ex) { LogError("TornadoController.BuildTornadoVisual", ex); DestroyTornadoVisual(); } } private void BuildNetworkedTornado(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) //IL_006c: Unknown result type (might be due to invalid IL or missing references) GameObject val = PhotonNetwork.Instantiate("Tornado", _character.Center, Quaternion.identity, (byte)0, new object[1] { "ImTornado.Visual" }); ((Object)val).name = "WindTornadoNetworked"; _tornadoVisualRoot = val; _tornadoIsNetworked = true; _tornadoAI = val.GetComponent(); ActiveTornadoAI = _tornadoAI; _tornadoPhotonView = val.GetComponent(); val.transform.localScale = Vector3.one; val.SetActive(WindPlugin.ShowTornadoVisual.Value); SyncNetworkTornadoVisual(force: true); LogInfo("Spawned networked tornado visual with vanilla Tornado prefab."); } private void BuildLocalTornado(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) //IL_00a0: 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) GameObject val = Object.Instantiate(prefab, _character.Center, Quaternion.identity); ((Object)val).name = "WindTornadoVisual"; MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren(true); foreach (MonoBehaviour val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { Type type = ((object)val2).GetType(); if (!(type == typeof(Animator)) && !(type == typeof(ParticleSystem))) { Object.DestroyImmediate((Object)(object)val2); } } } Collider[] componentsInChildren2 = val.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } val.transform.localScale = Vector3.one; ParticleSystem[] componentsInChildren3 = val.GetComponentsInChildren(true); foreach (ParticleSystem obj in componentsInChildren3) { MainModule main = obj.main; ((MainModule)(ref main)).playOnAwake = true; obj.Play(); } _tornadoVisualRoot = val; _tornadoIsNetworked = false; val.SetActive(WindPlugin.ShowTornadoVisual.Value); LogInfo("Spawned local-only tornado visual (offline / single-player)."); } private void UpdateTornadoVisual() { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) if ((Object)(object)_tornadoVisualRoot == (Object)null || (Object)(object)_character == (Object)null) { return; } if (_tornadoVisualRoot.activeSelf != WindPlugin.ShowTornadoVisual.Value) { _tornadoVisualRoot.SetActive(WindPlugin.ShowTornadoVisual.Value); } if (_tornadoIsNetworked) { _tornadoVisualRoot.transform.position = _character.Center; _tornadoVisualRoot.transform.localScale = Vector3.one; SyncNetworkTornadoVisual(); if ((Object)(object)_tornadoAI != (Object)null && TornadoLifeTimeField != null) { TornadoLifeTimeField.SetValue(_tornadoAI, 9999f); } } else { _tornadoVisualRoot.transform.position = _character.Center; _tornadoVisualRoot.transform.localScale = Vector3.one; } } private void DestroyTornadoVisual() { ActiveTornadoAI = null; _tornadoAI = null; _tornadoPhotonView = null; if ((Object)(object)_tornadoVisualRoot != (Object)null) { if (_tornadoIsNetworked && PhotonNetwork.InRoom) { try { PhotonNetwork.Destroy(_tornadoVisualRoot); } catch { } } else { Object.Destroy((Object)(object)_tornadoVisualRoot); } } _tornadoVisualRoot = null; _tornadoIsNetworked = false; } private void SyncNetworkTornadoVisual(bool force = false) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_tornadoPhotonView == (Object)null || (Object)(object)_character == (Object)null || !PhotonNetwork.InRoom || (!force && Time.unscaledTime < _nextTornadoVisualSync)) { return; } _nextTornadoVisualSync = Time.unscaledTime + 0.25f; try { _tornadoPhotonView.RPC("RPCA_SyncTornado", (RpcTarget)0, new object[1] { _character.Center }); } catch (Exception ex) { LogError("TornadoController.SyncNetworkTornadoVisual", ex); } } 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("TornadoController.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 * 5f; } private static float GetCameraDistance() { return Mathf.Clamp((WindPlugin.CameraDistance != null) ? WindPlugin.CameraDistance.Value : 18f, 8f, 30f); } private static float GetCameraHeight() { return Mathf.Clamp((WindPlugin.CameraHeight != null) ? WindPlugin.CameraHeight.Value : 6f, 2f, 14f); } private static float GetCameraFov() { return Mathf.Clamp((WindPlugin.CameraFov != null) ? WindPlugin.CameraFov.Value : 82f, 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 WindHarmonyPatches { private static readonly FieldInfo BananaPeelItemField = typeof(BananaPeel).GetField("item", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo ItemVfxItemField = typeof(ItemVFX).GetField("item", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo TornadoIgnoredCharactersField = typeof(Tornado).GetField("ignoredCharacters", BindingFlags.Instance | BindingFlags.NonPublic); private static bool IsTornado(Character character) { return TornadoController.IsLocalTornadoCharacter(character); } private static bool HasUsableLocalCharacter() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.refs.view != (Object)null) { return (Object)(object)((MonoBehaviourPun)localCharacter).photonView != (Object)null; } return false; } private static Item GetOrCacheBananaItem(BananaPeel banana) { if ((Object)(object)banana == (Object)null || BananaPeelItemField == null) { return null; } object? value = BananaPeelItemField.GetValue(banana); Item val = (Item)((value is Item) ? value : null); if ((Object)(object)val != (Object)null) { return val; } val = ((Component)banana).GetComponent(); if ((Object)(object)val != (Object)null) { BananaPeelItemField.SetValue(banana, val); } return val; } private static Item GetOrCacheItemVfxItem(ItemVFX itemVfx) { if ((Object)(object)itemVfx == (Object)null || ItemVfxItemField == null) { return null; } object? value = ItemVfxItemField.GetValue(itemVfx); Item val = (Item)((value is Item) ? value : null); if ((Object)(object)val != (Object)null) { return val; } val = ((Component)itemVfx).GetComponent(); if ((Object)(object)val != (Object)null) { ItemVfxItemField.SetValue(itemVfx, val); } return val; } private static bool IsWindNetworkVisual(Tornado tornado) { if ((Object)(object)tornado == (Object)null) { return false; } PhotonView component = ((Component)tornado).GetComponent(); object[] array = (((Object)(object)component != (Object)null) ? component.InstantiationData : null); if (array != null && array.Length != 0 && array[0] is string text) { return text == "ImTornado.Visual"; } return false; } [HarmonyPatch(typeof(Tornado), "Update")] [HarmonyPrefix] private static bool TornadoUpdatePrefix(Tornado __instance) { //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_002b: Unknown result type (might be due to invalid IL or missing references) if (!IsWindNetworkVisual(__instance)) { return true; } ((Component)__instance).transform.localScale = Vector3.Lerp(((Component)__instance).transform.localScale, Vector3.one, Time.deltaTime * 0.25f); return false; } [HarmonyPatch(typeof(Tornado), "FixedUpdate")] [HarmonyPrefix] private static bool TornadoFixedUpdatePrefix(Tornado __instance) { if (!IsWindNetworkVisual(__instance)) { return true; } Character activeTornadoCharacter = TornadoController.ActiveTornadoCharacter; if ((Object)(object)activeTornadoCharacter != (Object)null && TornadoIgnoredCharactersField != null && TornadoIgnoredCharactersField.GetValue(__instance) is List list && !list.Contains(activeTornadoCharacter)) { list.Add(activeTornadoCharacter); } return true; } [HarmonyPatch(typeof(Tornado), "RPCA_TornadoDie")] [HarmonyPrefix] private static bool TornadoDiePrefix(Tornado __instance) { return !IsWindNetworkVisual(__instance); } [HarmonyPatch(typeof(Tornado), "RPCA_SyncTornado")] [HarmonyPostfix] private static void TornadoSyncPostfix(Tornado __instance, Vector3 syncVel) { //IL_000f: 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 (IsWindNetworkVisual(__instance)) { ((Component)__instance).transform.position = syncVel; ((Component)__instance).transform.localScale = Vector3.one; } } [HarmonyPatch(typeof(BananaPeel), "Update")] [HarmonyPrefix] private static bool BananaPeelUpdatePrefix(BananaPeel __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Item orCacheBananaItem = GetOrCacheBananaItem(__instance); if ((Object)(object)orCacheBananaItem == (Object)null) { return false; } if ((int)orCacheBananaItem.itemState != 0) { return false; } return HasUsableLocalCharacter(); } [HarmonyPatch(typeof(VineShooter), "Update")] [HarmonyPrefix] private static bool VineShooterUpdatePrefix(VineShooter __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)((ItemComponent)__instance).item != (Object)null && HasUsableLocalCharacter()) { return (Object)(object)MainCamera.instance != (Object)null; } return false; } [HarmonyPatch(typeof(DispelFogField), "Update")] [HarmonyPrefix] private static bool DispelFogFieldUpdatePrefix() { if ((Object)(object)Object.FindAnyObjectByType() == (Object)null) { return false; } Character observedCharacter = Character.observedCharacter; if ((Object)(object)observedCharacter != (Object)null) { return (Object)(object)observedCharacter.data != (Object)null; } return false; } [HarmonyPatch(typeof(WarpCompassVFX), "OnUpdatedFeedData")] [HarmonyPrefix] private static bool WarpCompassOnUpdatedFeedDataPrefix(WarpCompassVFX __instance) { if ((Object)(object)GameUtils.instance != (Object)null && (Object)(object)GetOrCacheItemVfxItem((ItemVFX)(object)__instance) != (Object)null) { return HasUsableLocalCharacter(); } return false; } internal static bool CharacterRpcDiePrefix(Character __instance) { return !IsTornado(__instance); } internal static bool CharacterRpcSetDeadPrefix(Character __instance) { return !IsTornado(__instance); } internal static bool CharacterRpcPassOutPrefix(Character __instance) { return !IsTornado(__instance); } internal static bool CharacterDieInstantlyPrefix(Character __instance) { return !IsTornado(__instance); } internal static bool CharacterHandleDeathPrefix(Character __instance) { return !IsTornado(__instance); } internal static bool CharacterWarpPlayerRpcPrefix(Character __instance) { return !IsTornado(__instance); } internal static bool CharacterWarpPlayerPrefix(Character __instance) { return !IsTornado(__instance); } } }