diff --git a/ModernCamera/Behaviours/CameraBehaviour.cs b/ModernCamera/Behaviours/CameraBehaviour.cs index 69d728a..944f296 100644 --- a/ModernCamera/Behaviours/CameraBehaviour.cs +++ b/ModernCamera/Behaviours/CameraBehaviour.cs @@ -53,9 +53,6 @@ internal virtual unsafe void HandleInput(ref InputState inputState) // Update zoom if MaxZoom is changed if (TargetZoom > Settings.MaxZoom) TargetZoom = Settings.MaxZoom; - - if (Settings.InvertY) - inputState.SetAnalogValue(AnalogInput.RotateCameraY, -inputState.GetAnalogValue(AnalogInput.RotateCameraY)); } internal virtual void UpdateCameraInputs(ref TopdownCameraState state, ref TopdownCamera data) diff --git a/ModernCamera/Hooks/TopdownCameraSystem_Hook.cs b/ModernCamera/Hooks/TopdownCameraSystem_Hook.cs index dab848b..db65569 100644 --- a/ModernCamera/Hooks/TopdownCameraSystem_Hook.cs +++ b/ModernCamera/Hooks/TopdownCameraSystem_Hook.cs @@ -1,5 +1,4 @@ -using BepInEx.Unity.IL2CPP.Hook; -using MonoMod.RuntimeDetour; +using MonoMod.RuntimeDetour; using ProjectM; using Silkworm.Utils; using System; @@ -11,12 +10,12 @@ namespace ModernCamera.Hooks; internal static class TopdownCameraSystem_Hook { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private unsafe delegate void HandleInput(IntPtr _this, InputState* inputState); + private unsafe delegate void HandleInput(IntPtr _this, ref InputState inputState); private static HandleInput? HandleInputOriginal; private static NativeDetour? HandleInputDetour; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private unsafe delegate void UpdateCameraInputs(IntPtr _this, TopdownCameraState* cameraState, TopdownCamera* cameraData); + private unsafe delegate void UpdateCameraInputs(IntPtr _this, ref TopdownCameraState cameraState, ref TopdownCamera cameraData); private static UpdateCameraInputs? UpdateCameraInputsOriginal; private static NativeDetour? UpdateCameraInputsDetour; @@ -44,58 +43,58 @@ internal static void Dispose() HandleInputDetour?.Dispose(); } - private static unsafe void HandleInputHook(IntPtr _this, InputState* inputState) + private static unsafe void HandleInputHook(IntPtr _this, ref InputState inputState) { if (Settings.Enabled) { - ModernCameraState.CurrentCameraBehaviour!.HandleInput(ref *inputState); + ModernCameraState.CurrentCameraBehaviour!.HandleInput(ref inputState); } - HandleInputOriginal!(_this, inputState); + HandleInputOriginal!(_this, ref inputState); } - private static unsafe void UpdateCameraInputsHook(IntPtr _this, TopdownCameraState* cameraState, TopdownCamera* cameraData) + private static unsafe void UpdateCameraInputsHook(IntPtr _this, ref TopdownCameraState cameraState, ref TopdownCamera cameraData) { if (Settings.Enabled) { if (!DefaultZoomSettingsSaved) { - DefaultZoomSettings = cameraState->ZoomSettings; - DefaultStandardZoomSettings = cameraData->StandardZoomSettings; + DefaultZoomSettings = cameraState.ZoomSettings; + DefaultStandardZoomSettings = cameraData.StandardZoomSettings; DefaultZoomSettingsSaved = true; } UsingDefaultZoomSettings = false; // Set zoom settings - cameraState->ZoomSettings.MaxZoom = Settings.MaxZoom; - cameraState->ZoomSettings.MinZoom = 0f; + cameraState.ZoomSettings.MaxZoom = Settings.MaxZoom; + cameraState.ZoomSettings.MinZoom = 0f; // Check camera behaviours for activation foreach (var behaviour in ModernCameraState.CameraBehaviours.Values) { - if (behaviour.ShouldActivate(ref *cameraState)) + if (behaviour.ShouldActivate(ref cameraState)) { ModernCameraState.CurrentCameraBehaviour!.Deactivate(); - behaviour.Activate(ref *cameraState); + behaviour.Activate(ref cameraState); break; } } // Update current camera behaviour if (!ModernCameraState.CurrentCameraBehaviour!.Active) - ModernCameraState.CurrentCameraBehaviour!.Activate(ref *cameraState); + ModernCameraState.CurrentCameraBehaviour!.Activate(ref cameraState); - ModernCameraState.CurrentCameraBehaviour!.UpdateCameraInputs(ref *cameraState, ref *cameraData); + ModernCameraState.CurrentCameraBehaviour!.UpdateCameraInputs(ref cameraState, ref cameraData); - cameraData->StandardZoomSettings = cameraState->ZoomSettings; + cameraData.StandardZoomSettings = cameraState.ZoomSettings; } else if (DefaultZoomSettingsSaved && !UsingDefaultZoomSettings) { - cameraState->ZoomSettings = DefaultZoomSettings; - cameraData->StandardZoomSettings = DefaultStandardZoomSettings; + cameraState.ZoomSettings = DefaultZoomSettings; + cameraData.StandardZoomSettings = DefaultStandardZoomSettings; UsingDefaultZoomSettings = true; } - UpdateCameraInputsOriginal!(_this, cameraState, cameraData); + UpdateCameraInputsOriginal!(_this, ref cameraState, ref cameraData); } } diff --git a/ModernCamera/ModernCamera.cs b/ModernCamera/ModernCamera.cs index 3bb05bd..8730784 100644 --- a/ModernCamera/ModernCamera.cs +++ b/ModernCamera/ModernCamera.cs @@ -23,6 +23,9 @@ public class ModernCamera : MonoBehaviour private static PrefabCollectionSystem PrefabCollectionSystem; private static UIDataSystem UIDataSystem; + private static GameObject hudCanvas; + private static Camera GameCamera; + private static bool GameFocused; public static void Enabled(bool enabled) @@ -44,6 +47,22 @@ private static void UpdateEnabled(bool enabled) if (Crosshair != null) Crosshair.active = enabled && Settings.AlwaysShowCrosshair && !ModernCameraState.InBuildMode; + + if (!enabled) + { + Cursor.visible = true; + ActionMode(false); + } + } + + private static void UpdateFieldOfView(float fov) + { + if (GameCamera != null) GameCamera.fieldOfView = fov; + } + + private static void ToggleUI() + { + if (hudCanvas != null) hudCanvas.SetActive(!hudCanvas.activeInHierarchy); } private void Awake() @@ -53,6 +72,8 @@ private void Awake() ModernCameraState.CurrentBehaviourType = BehaviourType.ThirdPerson; Settings.AddEnabledListener(UpdateEnabled); + Settings.AddFieldOfViewListener(UpdateFieldOfView); + Settings.AddHideUIListener(ToggleUI); } private void Update() @@ -64,11 +85,24 @@ private void Update() if (WorldUtils.ClientWorldExists) { + if (GameCamera == null) + { + var cameraObject = GameObject.Find("Main_GameToolCamera(Clone)"); + if (cameraObject != null) + GameCamera = cameraObject.GetComponent(); + } + + if (hudCanvas == null) + hudCanvas = GameObject.Find("HUDCanvas(Clone)"); + GatherSystems(); UpdateSystems(); + UpdateCrosshair(); + } + else + { + Cursor.visible = true; } - - UpdateCrosshair(); } private void OnApplicationFocus(bool hasFocus) @@ -105,7 +139,7 @@ private void BuildCrosshair() } } - public void GatherSystems() + private void GatherSystems() { if (ZoomModifierSystem == null) { @@ -126,7 +160,7 @@ public void GatherSystems() } } - public void UpdateSystems() + private void UpdateSystems() { if (UIDataSystem == null || PrefabCollectionSystem == null) return; @@ -170,7 +204,7 @@ public void UpdateSystems() } } - public void UpdateCrosshair() + private void UpdateCrosshair() { try { diff --git a/ModernCamera/ModernCamera.csproj b/ModernCamera/ModernCamera.csproj index f89fd41..d288bbe 100644 --- a/ModernCamera/ModernCamera.csproj +++ b/ModernCamera/ModernCamera.csproj @@ -4,7 +4,7 @@ net6.0 ModernCamera Makes the camera more like a mmo camera and removes the limits - 1.5.0 + 1.5.1 true latest VRising diff --git a/ModernCamera/Patches/FadeOutUpperRoomPartsSystem_Patch.cs b/ModernCamera/Patches/FadeOutUpperRoomPartsSystem_Patch.cs deleted file mode 100644 index e2a84ef..0000000 --- a/ModernCamera/Patches/FadeOutUpperRoomPartsSystem_Patch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using HarmonyLib; -using ProjectM.Presentation; - -namespace ModernCamera.Patches; - -[HarmonyPatch] -internal static class FadeOutUpperRoomPartsSystem_Patch -{ - [HarmonyPrefix] - [HarmonyPatch(typeof(FadeOutUpperRoomPartsSystem), nameof(FadeOutUpperRoomPartsSystem.OnUpdate))] - private static void OnUpdate(FadeOutUpperRoomPartsSystem __instance) - { - if (!Settings.Enabled) return; - if (ModernCameraState.IsFirstPerson || Settings.ThirdPersonRoof) - __instance.SetFadeOutMode(FadeOutModeEnum.None); - else - __instance.SetFadeOutMode(FadeOutModeEnum.Full); - } -} diff --git a/ModernCamera/Settings.cs b/ModernCamera/Settings.cs index afb4159..f8c543b 100644 --- a/ModernCamera/Settings.cs +++ b/ModernCamera/Settings.cs @@ -11,12 +11,11 @@ namespace ModernCamera; internal static class Settings { internal static bool Enabled { get => EnabledOption.Value; set => EnabledOption.SetValue(value); } - internal static bool InvertY { get => InvertYOption.Value; set => InvertYOption.SetValue(value); } - internal static bool AlwaysShowCrosshair { get => AlwaysShowCrosshairOption.Value; set => AlwaysShowCrosshairOption.SetValue(value); } - internal static bool ActionModeCrosshair { get => ActionModeCrosshairOption.Value; set => ActionModeCrosshairOption.SetValue(value); } internal static bool FirstPersonEnabled { get => FirstPersonEnabledOption.Value; set => FirstPersonEnabledOption.SetValue(value); } internal static bool DefaultBuildMode { get => DefaultBuildModeOption.Value; set => DefaultBuildModeOption.SetValue(value); } - internal static bool ThirdPersonRoof { get => ThirdPersonRoofOption.Value; set => ThirdPersonRoofOption.SetValue(value); } + internal static bool AlwaysShowCrosshair { get => AlwaysShowCrosshairOption.Value; set => AlwaysShowCrosshairOption.SetValue(value); } + internal static bool ActionModeCrosshair { get => ActionModeCrosshairOption.Value; set => ActionModeCrosshairOption.SetValue(value); } + internal static float FieldOfView { get => FieldOfViewOption.Value; set => FieldOfViewOption.SetValue(value); } internal static int AimOffsetX { get => (int)(Screen.width * (AimOffsetXOption.Value / 100)); set => AimOffsetXOption.SetValue(Mathf.Clamp(value / Screen.width, -25, 25)); } internal static int AimOffsetY { get => (int)(Screen.height * (AimOffsetYOption.Value / 100)); set => AimOffsetYOption.SetValue(Mathf.Clamp(value / Screen.width, -25, 25)); } @@ -57,12 +56,11 @@ internal static class Settings private static float ZoomOffset = 2; private static ToggleOption EnabledOption; - private static ToggleOption InvertYOption; + private static SliderOption FieldOfViewOption; private static ToggleOption AlwaysShowCrosshairOption; private static ToggleOption ActionModeCrosshairOption; private static ToggleOption FirstPersonEnabledOption; private static ToggleOption DefaultBuildModeOption; - private static ToggleOption ThirdPersonRoofOption; private static DropdownOption CameraAimModeOption; private static SliderOption AimOffsetXOption; @@ -84,6 +82,7 @@ internal static class Settings private static Keybinding EnabledKeybind; private static Keybinding ActionModeKeybind; + private static Keybinding HideUIKeybind; internal static void Init() { @@ -92,17 +91,18 @@ internal static void Init() } internal static void AddEnabledListener(Action action) => EnabledOption.AddListener(action); + internal static void AddFieldOfViewListener(Action action) => FieldOfViewOption.AddListener(action); + internal static void AddHideUIListener(Action action) => HideUIKeybind.AddKeyDownListener(action); private static void SetupOptions() { var category = OptionsManager.AddCategory("Modern Camera"); EnabledOption = category.AddToggle("moderncamera.enabled", "Enabled", true); - InvertYOption = category.AddToggle("moderncamera.inverty", "Invert Y", false); - AlwaysShowCrosshairOption = category.AddToggle("moderncamera.alwaysshowcrosshair", "Always show Crosshair", false); - ActionModeCrosshairOption = category.AddToggle("moderncamera.actionmodecrosshair", "Show Crosshair in Action Mode", false); FirstPersonEnabledOption = category.AddToggle("moderncamera.firstperson", "Enable First Person", true); DefaultBuildModeOption = category.AddToggle("moderncamera.defaultbuildmode", "Use Default Build Mode Camera", true); - ThirdPersonRoofOption = category.AddToggle("moderncamera.thirdpersonroof", "Show Castle Roof in Third Person", false); + AlwaysShowCrosshairOption = category.AddToggle("moderncamera.alwaysshowcrosshair", "Always show Crosshair", false); + ActionModeCrosshairOption = category.AddToggle("moderncamera.actionmodecrosshair", "Show Crosshair in Action Mode", false); + FieldOfViewOption = category.AddSlider("moderncamera.fieldofview", "Field of View", 50, 90, 60); category.AddDivider("Third Person Aiming"); CameraAimModeOption = category.AddDropdown("moderncamera.aimmode", "Aim Mode", (int)CameraAimMode.Default, Enum.GetNames(typeof(CameraAimMode))); @@ -175,5 +175,7 @@ private static void SetupKeybinds() ModernCameraState.IsActionMode = !ModernCameraState.IsActionMode; } }); + + HideUIKeybind = category.AddKeyBinding("moderncamera.hideui", "Hide UI"); } } diff --git a/README.md b/README.md index c23a4aa..6d45021 100644 --- a/README.md +++ b/README.md @@ -31,39 +31,68 @@ Makes the camera more like an action MMO camera - Option to show interior castle roof - Option to lock aim mode forward + ### Installation - Install [BepInEx](https://v-rising.thunderstore.io/package/BepInEx/BepInExPack_V_Rising/) - Extract _Silkworm.dll_ into _(VRising folder)/BepInEx/plugins_ - Extract _ModernCamera.dll_ into _(VRising folder)/BepInEx/plugins_ + ### Configuration All configuration is done with the in game options menu + ### Known Issues -- Action mode can be enabled/disabled on the main menu +- Can see through floors/roofs from below (this cannot be fixed because objects are missing Mesh faces) - Shadows flicker when looking directly horizontal (Due to fake cloud shadows) + +### FAQ +**Q: Why is my characters name and healthbar always shown at top of screen?** + +**A:** Because the mouse is locked over the character. Use an over-the-shoulder offset in options to move the mouse off-center so that the mouse is not over the character. + +**Q: Why can I see objects popping (loading) in and out in the distance now?** + +**A:** This is done for performance by the game. Normally you don't see this because you are looking down at your character. ModernCamera cannot change this. + +**Q: Why can't I rotate the camera after hiding the UI?** + +**A:** You may have pressed "Enter" which causes the game to lock the camera because the chatbox should normally be open. To fix this, toggle the UI back on, click in the chat box, and press "Enter" again. + + ### Support Join the [modding discord](https://vrisingmods.com/discord) for support and tag `@iZastic#0365` Submit a ticket on [GitHub](https://github.com/v-rising/ModernCamera/issues) + ### Contributors - iZastic: `@iZastic#0365` on Discord - Dimentox: `@Dimentox#1154` on Discord - Kunogi: `@牧瀬紅莉栖#1570` on Discord + ### Silkworm Source code for the Silkworm library [https://github.com/iZastic/vrising-silkworm](https://github.com/iZastic/vrising-silkworm). I am not officially supporting this as a library for use in other mods, but I wanted to add a link to the source for those who are interested. + ### Changelog -`1.5.0` -- Updated for Gloomrot +`1.5.1` +- Removed InvertY option (this is now supported by the game under Camera Settings) +- Removed ThirdPersonRoof option (no longer affective) +- Added Field of View option +- Added keybind to hide all UI elements +- Fixed crash after leaving and joining a server +- Fixed issue where mouse stayed locked after disabling ModernCamera
+`1.5.0` +- Updated for Gloomrot + `1.4.1` - Fixed no fading of wrong UI elements (like chat) - Fixed bug causing game to crash when leaving game