Skip to content

Commit

Permalink
Removed InvertY option (this is now supported by the game under Camer…
Browse files Browse the repository at this point in the history
…a 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
  • Loading branch information
iZastic committed May 25, 2023
1 parent 9dca232 commit 9220e0d
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 61 deletions.
3 changes: 0 additions & 3 deletions ModernCamera/Behaviours/CameraBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
39 changes: 19 additions & 20 deletions ModernCamera/Hooks/TopdownCameraSystem_Hook.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using BepInEx.Unity.IL2CPP.Hook;
using MonoMod.RuntimeDetour;
using MonoMod.RuntimeDetour;
using ProjectM;
using Silkworm.Utils;
using System;
Expand All @@ -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;

Expand Down Expand Up @@ -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);
}
}
44 changes: 39 additions & 5 deletions ModernCamera/ModernCamera.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()
Expand All @@ -53,6 +72,8 @@ private void Awake()
ModernCameraState.CurrentBehaviourType = BehaviourType.ThirdPerson;

Settings.AddEnabledListener(UpdateEnabled);
Settings.AddFieldOfViewListener(UpdateFieldOfView);
Settings.AddHideUIListener(ToggleUI);
}

private void Update()
Expand All @@ -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<Camera>();
}

if (hudCanvas == null)
hudCanvas = GameObject.Find("HUDCanvas(Clone)");

GatherSystems();
UpdateSystems();
UpdateCrosshair();
}
else
{
Cursor.visible = true;
}

UpdateCrosshair();
}

private void OnApplicationFocus(bool hasFocus)
Expand Down Expand Up @@ -105,7 +139,7 @@ private void BuildCrosshair()
}
}

public void GatherSystems()
private void GatherSystems()
{
if (ZoomModifierSystem == null)
{
Expand All @@ -126,7 +160,7 @@ public void GatherSystems()
}
}

public void UpdateSystems()
private void UpdateSystems()
{
if (UIDataSystem == null || PrefabCollectionSystem == null) return;

Expand Down Expand Up @@ -170,7 +204,7 @@ public void UpdateSystems()
}
}

public void UpdateCrosshair()
private void UpdateCrosshair()
{
try
{
Expand Down
2 changes: 1 addition & 1 deletion ModernCamera/ModernCamera.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>ModernCamera</AssemblyName>
<Description>Makes the camera more like a mmo camera and removes the limits</Description>
<Version>1.5.0</Version>
<Version>1.5.1</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<Authors>VRising</Authors>
Expand Down
19 changes: 0 additions & 19 deletions ModernCamera/Patches/FadeOutUpperRoomPartsSystem_Patch.cs

This file was deleted.

22 changes: 12 additions & 10 deletions ModernCamera/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)); }
Expand Down Expand Up @@ -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;
Expand All @@ -84,6 +82,7 @@ internal static class Settings

private static Keybinding EnabledKeybind;
private static Keybinding ActionModeKeybind;
private static Keybinding HideUIKeybind;

internal static void Init()
{
Expand All @@ -92,17 +91,18 @@ internal static void Init()
}

internal static void AddEnabledListener(Action<bool> action) => EnabledOption.AddListener(action);
internal static void AddFieldOfViewListener(Action<float> 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)));
Expand Down Expand Up @@ -175,5 +175,7 @@ private static void SetupKeybinds()
ModernCameraState.IsActionMode = !ModernCameraState.IsActionMode;
}
});

HideUIKeybind = category.AddKeyBinding("moderncamera.hideui", "Hide UI");
}
}
35 changes: 32 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<details>

`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
Expand Down

0 comments on commit 9220e0d

Please sign in to comment.