From 944bb7d135b0733b0c00a82d36ad674c3f33b498 Mon Sep 17 00:00:00 2001 From: Craig Banks Date: Sat, 18 Feb 2023 20:23:20 +0000 Subject: [PATCH] Fix and add features --- .gitignore | 3 + project/Terkoiz.Freecam.sln | 16 ++ project/Terkoiz.Freecam/Freecam.cs | 27 +-- project/Terkoiz.Freecam/FreecamController.cs | 162 ++++++------------ project/Terkoiz.Freecam/FreecamPatch.cs | 27 +++ project/Terkoiz.Freecam/FreecamPlugin.cs | 26 +-- .../Properties/AssemblyInfo.cs | 36 ---- .../Terkoiz.Freecam/Terkoiz.Freecam.csproj | 149 +++++----------- project/Terkoiz.Freecam/app.config | 11 -- project/Terkoiz.Freecam/packages.config | 9 - 10 files changed, 167 insertions(+), 299 deletions(-) create mode 100644 project/Terkoiz.Freecam.sln create mode 100644 project/Terkoiz.Freecam/FreecamPatch.cs delete mode 100644 project/Terkoiz.Freecam/Properties/AssemblyInfo.cs delete mode 100644 project/Terkoiz.Freecam/app.config delete mode 100644 project/Terkoiz.Freecam/packages.config diff --git a/.gitignore b/.gitignore index ee096f6..1af21c3 100644 --- a/.gitignore +++ b/.gitignore @@ -241,6 +241,9 @@ ClientBin/ *.pfx *.publishsettings orleans.codegen.cs +.idea +Freecam.sln.DotSettings.user +Project/.idea/ # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) diff --git a/project/Terkoiz.Freecam.sln b/project/Terkoiz.Freecam.sln new file mode 100644 index 0000000..0c43e91 --- /dev/null +++ b/project/Terkoiz.Freecam.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Terkoiz.Freecam", "Terkoiz.Freecam\Terkoiz.Freecam.csproj", "{BC26F21D-2987-4504-BBE6-0867001DFEB3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BC26F21D-2987-4504-BBE6-0867001DFEB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC26F21D-2987-4504-BBE6-0867001DFEB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC26F21D-2987-4504-BBE6-0867001DFEB3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC26F21D-2987-4504-BBE6-0867001DFEB3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/project/Terkoiz.Freecam/Freecam.cs b/project/Terkoiz.Freecam/Freecam.cs index b9d11fc..a865504 100644 --- a/project/Terkoiz.Freecam/Freecam.cs +++ b/project/Terkoiz.Freecam/Freecam.cs @@ -1,4 +1,3 @@ -using JetBrains.Annotations; using UnityEngine; namespace Terkoiz.Freecam @@ -13,8 +12,7 @@ namespace Terkoiz.Freecam public class Freecam : MonoBehaviour { public bool IsActive = false; - - [UsedImplicitly] + public void Update() { if (!IsActive) @@ -27,44 +25,44 @@ namespace Terkoiz.Freecam if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow)) { - transform.position += (-transform.right * movementSpeed * Time.deltaTime); + transform.position += (-transform.right * (movementSpeed * Time.deltaTime)); } if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)) { - transform.position += (transform.right * movementSpeed * Time.deltaTime); + transform.position += (transform.right * (movementSpeed * Time.deltaTime)); } if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)) { - transform.position += (transform.forward * movementSpeed * Time.deltaTime); + transform.position += (transform.forward * (movementSpeed * Time.deltaTime)); } if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow)) { - transform.position += (-transform.forward * movementSpeed * Time.deltaTime); + transform.position += (-transform.forward * (movementSpeed * Time.deltaTime)); } if (FreecamPlugin.CameraHeightMovement.Value) { if (Input.GetKey(KeyCode.Q)) { - transform.position += (transform.up * movementSpeed * Time.deltaTime); + transform.position += (transform.up * (movementSpeed * Time.deltaTime)); } if (Input.GetKey(KeyCode.E)) { - transform.position += (-transform.up * movementSpeed * Time.deltaTime); + transform.position += (-transform.up * (movementSpeed * Time.deltaTime)); } if (Input.GetKey(KeyCode.R) || Input.GetKey(KeyCode.PageUp)) { - transform.position += (Vector3.up * movementSpeed * Time.deltaTime); + transform.position += (Vector3.up * (movementSpeed * Time.deltaTime)); } if (Input.GetKey(KeyCode.F) || Input.GetKey(KeyCode.PageDown)) { - transform.position += (-Vector3.up * movementSpeed * Time.deltaTime); + transform.position += (-Vector3.up * (movementSpeed * Time.deltaTime)); } } @@ -78,9 +76,14 @@ namespace Terkoiz.Freecam if (axis != 0) { var zoomSensitivity = fastMode ? FreecamPlugin.CameraFastZoomSpeed.Value : FreecamPlugin.CameraZoomSpeed.Value; - transform.position += transform.forward * axis * zoomSensitivity; + transform.position += transform.forward * (axis * zoomSensitivity); } } } + + private void OnDestroy() + { + Destroy(this); + } } } \ No newline at end of file diff --git a/project/Terkoiz.Freecam/FreecamController.cs b/project/Terkoiz.Freecam/FreecamController.cs index 46a0234..ccd6937 100644 --- a/project/Terkoiz.Freecam/FreecamController.cs +++ b/project/Terkoiz.Freecam/FreecamController.cs @@ -1,11 +1,8 @@ -using System.Reflection; using Comfort.Common; using EFT; using EFT.CameraControl; using EFT.UI; using HarmonyLib; -using JetBrains.Annotations; -using MonoMod.RuntimeDetour; using UnityEngine; namespace Terkoiz.Freecam @@ -17,11 +14,9 @@ namespace Terkoiz.Freecam private BattleUIScreen _playerUi; private bool _uiHidden; + private bool _fallDamageToggle = false; - private MethodInfo _playerMoveMethod; - private MethodInfo _playerRotateMethod; - private Detour _moveDetour; - private Detour _rotateDetour; + private GamePlayerOwner _gamePlayerOwner; private Vector3? _lastPosition; private Quaternion? _lastRotation; @@ -31,25 +26,24 @@ namespace Terkoiz.Freecam // Button to toggle between camera and player movement // Independent FoV setting for Freecam mode (_mainCamera.GetComponent().fieldOfView = ...) - [UsedImplicitly] public void Start() { - // We locate and get the MethodInfo for the Move method that we will later detour to prevent the player from moving during Freecam - _playerMoveMethod = typeof(Player).GetMethod("Move"); - if (_playerMoveMethod == null) - { - FreecamPlugin.Logger.LogError("Failed to locate the Player.Move method!"); - } + // Find Main Camera + _mainCamera = GameObject.Find("FPS Camera"); + if (_mainCamera == null) + FreecamPlugin.Logger.LogError("Failed to locate main camera"); - // Same deal here, but for player rotation - _playerRotateMethod = typeof(Player).GetMethod("Rotate"); - if (_playerRotateMethod == null) - { - FreecamPlugin.Logger.LogError("Failed to locate the Player.Rotate method!"); - } + // Add Freecam script to main camera in scene + _freeCamScript = _mainCamera.AddComponent(); + if (_freeCamScript == null) + FreecamPlugin.Logger.LogError("Failed to add Freecam script to Camera"); + + // Get GamePlayerOwner component + _gamePlayerOwner = GetLocalPlayerFromWorld().GetComponentInChildren(); + if (_gamePlayerOwner == null) + FreecamPlugin.Logger.LogError("Failed to locate GamePlayerOwner"); } - - [UsedImplicitly] + public void Update() { if (FreecamPlugin.ToggleUi.Value.IsDown()) @@ -66,6 +60,29 @@ namespace Terkoiz.Freecam { MovePlayerToCamera(); } + + if (_fallDamageToggle != FreecamPlugin.FallDamageToggle.Value) + { + _fallDamageToggle = ToggleFallDamage(FreecamPlugin.FallDamageToggle.Value); + } + } + + private bool ToggleFallDamage(bool config) + { + var localPlayer = GetLocalPlayerFromWorld(); + if (localPlayer == null) + return false; + + // Set Safe fall height to 99999 + if (config) + { + localPlayer.ActiveHealthController.FallSafeHeight = 99999; + return true; + } + + // Set Safe fall height to 3 + localPlayer.ActiveHealthController.FallSafeHeight = 3; + return false; } /// @@ -76,29 +93,7 @@ namespace Terkoiz.Freecam // Get our own Player instance. Null means we're not in a raid var localPlayer = GetLocalPlayerFromWorld(); if (localPlayer == null) - { return; - } - - // If we don't have the main camera object cached, go look for it in the scene - if (_mainCamera == null) - { - // Finding a GameObject by name directly is apparently better than searching for objects of a type. - // 'FPS Camera' is our main camera instance - so we just grab that - _mainCamera = GameObject.Find("FPS Camera"); - if (_mainCamera == null) - { - FreecamPlugin.Logger.LogError("Failed to locate main camera"); - return; - } - } - - // Create the Freecam script and attach it to the main camera - if (_freeCamScript == null) - { - ClearDetours(); - _freeCamScript = _mainCamera.AddComponent(); - } if (!_freeCamScript.IsActive) { @@ -117,15 +112,7 @@ namespace Terkoiz.Freecam { var localPlayer = GetLocalPlayerFromWorld(); if (localPlayer == null) - { return; - } - - // If we don't have the main camera cached, it means we have yet to enter Freecam mode and there is nowhere to teleport to - if (_mainCamera == null) - { - return; - } // Move the player to the camera's current position and switch to First Person mode if (_freeCamScript.IsActive) @@ -133,6 +120,7 @@ namespace Terkoiz.Freecam // We grab the camera's position, but we subtract a bit off the Y axis, because the players coordinate origin is at the feet var position = new Vector3(_mainCamera.transform.position.x, _mainCamera.transform.position.y - 1.8f, _mainCamera.transform.position.z); localPlayer.gameObject.transform.SetPositionAndRotation(position, Quaternion.Euler(0, _mainCamera.transform.rotation.y, 0)); + // localPlayer.gameObject.transform.SetPositionAndRotation(position, _mainCamera.transform.rotation); SetPlayerToFirstPersonMode(localPlayer); } @@ -145,9 +133,7 @@ namespace Terkoiz.Freecam { // Check if we're currently in a raid if (GetLocalPlayerFromWorld() == null) - { return; - } // If we don't have the UI Component cached, go look for it in the scene if (_playerUi == null) @@ -194,17 +180,8 @@ namespace Terkoiz.Freecam FreecamPlugin.Logger.LogError("Failed to get the PlayerBody field"); } - // Detour the Player.Move method into an empty one, preventing the character from moving during Freecam mode - if (_playerMoveMethod != null) - { - _moveDetour = new Detour(_playerMoveMethod, typeof(FreecamController).GetMethod(nameof(DisabledMove))); - } - - // Same deal here, but for player rotation - if (_playerRotateMethod != null) - { - _rotateDetour = new Detour(_playerRotateMethod, typeof(FreecamController).GetMethod(nameof(DisabledRotate))); - } + // Instead of Detouring, just turn off _gamePlayerOwner which takes the input + _gamePlayerOwner.enabled = false; if (FreecamPlugin.CameraRememberLastPosition.Value && _lastPosition != null && _lastRotation != null) { @@ -228,8 +205,9 @@ namespace Terkoiz.Freecam _lastPosition = _mainCamera.transform.position; _lastRotation = _mainCamera.transform.rotation; } - - ClearDetours(); + + // re-enable _gamePlayerOwner + _gamePlayerOwner.enabled = true; localPlayer.PointOfView = EPointOfView.FirstPerson; } @@ -242,56 +220,18 @@ namespace Terkoiz.Freecam { // If the GameWorld instance is null or has no RegisteredPlayers, it most likely means we're not in a raid var gameWorld = Singleton.Instance; - if (gameWorld == null || gameWorld.RegisteredPlayers == null) - { + if (gameWorld == null || gameWorld.MainPlayer == null) return null; - } // One of the RegisteredPlayers will have the IsYourPlayer flag set, which will be our own Player instance - return gameWorld.RegisteredPlayers.Find(p => p.IsYourPlayer); + return gameWorld.MainPlayer; } - [UsedImplicitly] - public void OnDestroy() - { - _freeCamScript.IsActive = false; - - // Making sure no stray Detours are left - ClearDetours(); - - _lastPosition = null; - _lastRotation = null; - } - - public void ClearDetours() - { - if (_moveDetour != null) - { - _moveDetour.Dispose(); - _moveDetour = null; - } - - if (_rotateDetour != null) - { - _rotateDetour.Dispose(); - _rotateDetour = null; - } - } - - /// - /// An empty method that's used to detour the player Move method, preventing movement during Freecam mode - /// - [UsedImplicitly] - public static void DisabledMove(Player self, Vector2 direction) - { - } - - /// - /// An empty method that's used to detour the player Rotate method, preventing rotation during Freecam mode - /// - [UsedImplicitly] - public static void DisabledRotate(Player self, Vector2 deltaRotation, bool ignoreClamp = false) + private void OnDestroy() { + // Destroy FreeCamScript before FreeCamController if exists + Destroy(_freeCamScript); + Destroy(this); } } } \ No newline at end of file diff --git a/project/Terkoiz.Freecam/FreecamPatch.cs b/project/Terkoiz.Freecam/FreecamPatch.cs new file mode 100644 index 0000000..04fd939 --- /dev/null +++ b/project/Terkoiz.Freecam/FreecamPatch.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using Aki.Reflection.Patching; +using Comfort.Common; +using EFT; + +namespace Terkoiz.Freecam +{ + public class FreecamPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return typeof(GameWorld).GetMethod("OnGameStarted", BindingFlags.Public | BindingFlags.Instance); + } + + [PatchPostfix] + public static void PatchPostFix() + { + var gameworld = Singleton.Instance; + + if (gameworld == null) + return; + + // Add FreeCamController to GameWorld GameObject + gameworld.GetOrAddComponent(); + } + } +} \ No newline at end of file diff --git a/project/Terkoiz.Freecam/FreecamPlugin.cs b/project/Terkoiz.Freecam/FreecamPlugin.cs index 1127c4b..2bc6ee4 100644 --- a/project/Terkoiz.Freecam/FreecamPlugin.cs +++ b/project/Terkoiz.Freecam/FreecamPlugin.cs @@ -1,24 +1,23 @@ using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; -using JetBrains.Annotations; using UnityEngine; +using KeyboardShortcut = BepInEx.Configuration.KeyboardShortcut; namespace Terkoiz.Freecam { - [BepInPlugin("com.terkoiz.freecam", "Terkoiz.Freecam", "1.2.0")] + [BepInPlugin("com.terkoiz.freecam", "Terkoiz.Freecam", "1.3.0")] public class FreecamPlugin : BaseUnityPlugin { internal new static ManualLogSource Logger { get; private set; } - private static GameObject HookObject; - // Keyboard shortcut config entries private const string KeybindSectionName = "Keybinds"; internal static ConfigEntry ToggleFreecamMode; internal static ConfigEntry TeleportToCamera; internal static ConfigEntry ToggleUi; + // Camera settings config entries private const string CameraSettingsSectionName = "CameraSettings"; internal static ConfigEntry CameraMoveSpeed; @@ -31,19 +30,14 @@ namespace Terkoiz.Freecam internal static ConfigEntry CameraHeightMovement; internal static ConfigEntry CameraMousewheelZoom; internal static ConfigEntry CameraRememberLastPosition; - - // TODO: Hook into camera OnDestroy to run the OnDestroy from FreecamController - - [UsedImplicitly] + public static ConfigEntry FallDamageToggle; + internal void Start() { + new FreecamPatch().Enable(); + Logger = base.Logger; - InitConfiguration(); - - HookObject = new GameObject(); - HookObject.AddComponent(); - DontDestroyOnLoad(HookObject); } private void InitConfiguration() @@ -124,6 +118,12 @@ namespace Terkoiz.Freecam "CameraRememberLastPosition", false, "If enabled, returning to Freecam mode will put the camera to it's last position which was saved when exiting Freecam mode."); + + FallDamageToggle = Config.Bind( + TogglesSectionName, + "FallHeightToggle", + true, + "True disables fall damage, False doesn't simplez"); } } } diff --git a/project/Terkoiz.Freecam/Properties/AssemblyInfo.cs b/project/Terkoiz.Freecam/Properties/AssemblyInfo.cs deleted file mode 100644 index 92fb4d3..0000000 --- a/project/Terkoiz.Freecam/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Terkoiz.Freecam")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Terkoiz.Freecam")] -[assembly: AssemblyCopyright("Copyright © 2021")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("be2de623-48ff-4807-9696-167a17787718")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/project/Terkoiz.Freecam/Terkoiz.Freecam.csproj b/project/Terkoiz.Freecam/Terkoiz.Freecam.csproj index 04b8d39..37a2632 100644 --- a/project/Terkoiz.Freecam/Terkoiz.Freecam.csproj +++ b/project/Terkoiz.Freecam/Terkoiz.Freecam.csproj @@ -1,109 +1,44 @@ - - - - - Debug - AnyCPU - {BE2DE623-48FF-4807-9696-167A17787718} - Library - Properties - Terkoiz.Freecam - Terkoiz.Freecam - v4.7.2 - 512 - true - - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - false - - - - - - - - ..\packages\HarmonyX.2.7.0\lib\net45\0Harmony.dll - - - ..\Shared\Hollowed\Assembly-CSharp.dll - - - ..\packages\BepInEx.BaseLib.5.4.19\lib\net35\BepInEx.dll - - - ..\Shared\Managed\Comfort.dll - - - ..\Shared\Managed\ItemComponent.Types.dll - - - ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.dll - - - ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Mdb.dll - - - ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Pdb.dll - - - ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Rocks.dll - - - ..\packages\MonoMod.RuntimeDetour.21.12.13.1\lib\net452\MonoMod.RuntimeDetour.dll - - - ..\packages\MonoMod.Utils.21.12.13.1\lib\net452\MonoMod.Utils.dll - - - - ..\Shared\Managed\UnityEngine.dll - - - ..\Shared\Managed\UnityEngine.CoreModule.dll - - - ..\Shared\Managed\UnityEngine.InputLegacyModule.dll - - - ..\Shared\Managed\UnityEngine.UIModule.dll - - - - - - - - - - - - - - - + + - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + net472 + 1.3.0 - - - \ No newline at end of file + + + + ..\..\Shared\0Harmony.dll + + + ..\..\Shared\Aki.Reflection.dll + + + ..\..\Shared\Assembly-CSharp.dll + + + ..\..\Shared\BepInEx.dll + + + ..\..\Shared\Comfort.dll + + + ..\..\Shared\ConfigurationManager.dll + + + ..\..\Shared\ItemComponent.Types.dll + + + ..\..\Shared\UnityEngine.dll + + + ..\..\Shared\UnityEngine.CoreModule.dll + + + ..\..\Shared\UnityEngine.InputLegacyModule.dll + + + ..\..\Shared\UnityEngine.UIModule.dll + + + + diff --git a/project/Terkoiz.Freecam/app.config b/project/Terkoiz.Freecam/app.config deleted file mode 100644 index 2a4bf25..0000000 --- a/project/Terkoiz.Freecam/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/project/Terkoiz.Freecam/packages.config b/project/Terkoiz.Freecam/packages.config deleted file mode 100644 index 47859cc..0000000 --- a/project/Terkoiz.Freecam/packages.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file