diff options
| -rwxr-xr-x | Config.cs | 2 | ||||
| -rwxr-xr-x | Plugin.cs | 294 | ||||
| -rw-r--r-- | README.txt | 2 |
3 files changed, 169 insertions, 129 deletions
@@ -119,7 +119,7 @@ namespace MHWNewCamera public bool HigherShadowDetailInHoarfrost { get; set; } = false;
public bool DisableLodLimits { get; set; } = false;
public bool ApplyLodFactors { get; set; } = false;
- public float FoliageLodBias { get; set; } = 3.5f;
+ public float FoliageLodBias { get; set; } = 3.0f;
public float TerrainLodBias { get; set; } = 6.0f;
public float FoliageLodFactor { get; set; } = 0.0f;
public float TerrainLodFactor { get; set; } = 0.0f;
@@ -18,11 +18,16 @@ using System.Diagnostics; #endif
// @TODO:
-// - Bind to switch camera preset.
-// - More multiple controller testing.
+// - Find a way to enable crouching and crawling on command.
+// - Option to ignore camera change (update position, test open book and close).
+// - Simplify and document input handling/blocking logic.
+// - Find a way to block other inputs while button1 is down (and blocked).
+// - More multiple controller testing (3 controllers, steam input, windows).
// - Thoroughly test "Disable Mod".
// - Improve AOB scans.
-// - Glass objects in research base and on the botanical research center table still fade.
+// - Some objects still fade.
+// - Glass objects in research base and on the botanical research center table.
+// - Decals on floor near Astera lift.
// - Snow LOD pop-in.
// - Stop animation rate lowering at distance.
// - Manully set freecam viewport index.
@@ -31,8 +36,8 @@ using System.Diagnostics; // Known Issues:
// - Camera pitch wrap around while in the tent will sometimes flicker at the point of wrapping.
-// Likely due to the unpredictable position of SetCameraTentHook() in the chain of hooks.
-// Updating the free camera state within SetCameraTentHook() is not a solution because it comes out laggy.
+// - Likely due to the unpredictable position of SetCameraTentHook() in the chain of hooks. Updating
+// free camera state within SetCameraTentHook() is not a solution because it comes out laggy.
// Steam proton launch command:
// env DOTNET_ROOT="" WINEDLLOVERRIDES="msvcrt,dinput8=n,b" %command%
@@ -75,7 +80,7 @@ using System.Diagnostics; // If this is broken, two of them will be invisible.
//
// 2x Shadow Resolution:
-// - The shadow of the \"Waterfall Bridge\" lift in Astera.
+// - The shadow of the "Waterfall Bridge" lift in Astera.
// - Walk up the stairs towards the canteen and the shadow of the lift will fade-out. Move the camera
// back and forth and make sure the lower resolution shadow aligns with the higher res one.
@@ -153,6 +158,7 @@ namespace MHWNewCamera private uint lastPadDown = 0;
private uint? prevPadDown = null;
private bool unlockInputToggled = false;
+ private bool inputBlockedForToggle = false;
private bool buttonWasDown(Button button)
{
return (lastPadDown & (uint)button) == (uint)button;
@@ -249,10 +255,12 @@ namespace MHWNewCamera shadowRes4_3x.Disable();
}
- private float foliageLodBias = 3.0f;
- private float terrainLodBias = 3.0f;
- private float foliageLodFactor = 1.0f;
- private float terrainLodFactor = 1.0f;
+ private float foliageLodBias;
+ private float terrainLodBias;
+ private float prevFoliageLodBias = 0.0f;
+ private float prevTerrainLodBias = 0.0f;
+ private float foliageLodFactor;
+ private float terrainLodFactor;
private bool disableLodLimits = false;
private Patch defaultViewModeLodLimit;
@@ -675,75 +683,28 @@ namespace MHWNewCamera nint baseAddr = MemoryUtil.Read<nint>(0x1451C4368);
if (toggleOn)
{
+ if (prevFoliageLodBias <= 0.0f) {
+ prevFoliageLodBias = MemoryUtil.Read<float>(baseAddr + 0x21C);
+ if (prevFoliageLodBias > 3.0f) prevFoliageLodBias = 3.0f;
+ }
MemoryUtil.WriteBytes(baseAddr + 0x21C, BitConverter.GetBytes(foliageLodBias));
+ if (prevTerrainLodBias <= 0.0f) {
+ prevTerrainLodBias = MemoryUtil.Read<float>(baseAddr + 0x220);
+ if (prevTerrainLodBias > 3.0f) prevTerrainLodBias = 3.0f;
+ }
MemoryUtil.WriteBytes(baseAddr + 0x220, BitConverter.GetBytes(terrainLodBias));
MemoryUtil.WriteBytes(baseAddr + 0x224, BitConverter.GetBytes(foliageLodFactor));
MemoryUtil.WriteBytes(baseAddr + 0x228, BitConverter.GetBytes(terrainLodFactor));
}
else
{
- MemoryUtil.WriteBytes(baseAddr + 0x21C, BitConverter.GetBytes(3.0f)); // LOD Bias: "High".
- MemoryUtil.WriteBytes(baseAddr + 0x220, BitConverter.GetBytes(3.0f)); // LOD Bias: "High".
+ MemoryUtil.WriteBytes(baseAddr + 0x21C, BitConverter.GetBytes(prevFoliageLodBias));
+ MemoryUtil.WriteBytes(baseAddr + 0x220, BitConverter.GetBytes(prevTerrainLodBias));
MemoryUtil.WriteBytes(baseAddr + 0x224, BitConverter.GetBytes(1.0f));
MemoryUtil.WriteBytes(baseAddr + 0x228, BitConverter.GetBytes(1.0f));
}
}
- /*
- private bool areLodLimitsDisabled()
- {
- nint addrAddr = MemoryUtil.Read<nint>(0x1451C4148);
- nint baseAddr = MemoryUtil.Read<nint>(addrAddr + 0xAF828);
- nint addrStart = baseAddr + 0xEB9C;
- bool faceLimit = MemoryUtil.Read<byte>(addrStart) == 0x0;
- bool faceShadowLimit = MemoryUtil.Read<byte>(addrStart + 0x4) == 0x0;
- bool playerLimit = MemoryUtil.Read<byte>(addrStart + 0x8) == 0x0;
- bool playerShadowLimit = MemoryUtil.Read<byte>(addrStart + 0xC) == 0x0;
- bool otomoLimit = MemoryUtil.Read<byte>(addrStart + 0x10) == 0x0;
- bool otomoShadowLimit = MemoryUtil.Read<byte>(addrStart + 0x14) == 0x0;
- bool npcLimit = MemoryUtil.Read<byte>(addrStart + 0x18) == 0x0;
- bool npcShadowLimit = MemoryUtil.Read<byte>(addrStart + 0x1C) == 0x0;
- bool simpleNpcLimit = MemoryUtil.Read<byte>(addrStart + 0x20) == 0x0;
- bool simpleNpcShadowLimit = MemoryUtil.Read<byte>(addrStart + 0x24) == 0x0;
- return faceLimit && faceShadowLimit && playerLimit && playerShadowLimit &&
- otomoLimit && otomoShadowLimit && npcLimit && npcShadowLimit &&
- simpleNpcLimit && simpleNpcShadowLimit;
- }
-
- private void setLodLimits(bool limitOn)
- {
- nint addrAddr = MemoryUtil.Read<nint>(0x1451C4148);
- nint baseAddr = MemoryUtil.Read<nint>(addrAddr + 0xAF828);
- nint addrStart = baseAddr + 0xEB9C;
- if (limitOn)
- {
- MemoryUtil.WriteBytes(addrStart, [0x1]);
- MemoryUtil.WriteBytes(addrStart + 0x4, [0x3]);
- MemoryUtil.WriteBytes(addrStart + 0x8, [0x1]);
- MemoryUtil.WriteBytes(addrStart + 0xC, [0x3]);
- MemoryUtil.WriteBytes(addrStart + 0x10, [0x1]);
- MemoryUtil.WriteBytes(addrStart + 0x14, [0x3]);
- MemoryUtil.WriteBytes(addrStart + 0x18, [0x1]);
- MemoryUtil.WriteBytes(addrStart + 0x1C, [0x3]);
- MemoryUtil.WriteBytes(addrStart + 0x20, [0x2]);
- MemoryUtil.WriteBytes(addrStart + 0x24, [0x3]);
- }
- else
- {
- MemoryUtil.WriteBytes(addrStart, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0x4, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0x8, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0xC, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0x10, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0x14, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0x18, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0x1C, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0x20, [0x0]);
- MemoryUtil.WriteBytes(addrStart + 0x24, [0x0]);
- }
- }
- */
-
public void OnLoad()
{
Config config = ConfigManager.GetConfig<Config>(this);
@@ -868,6 +829,7 @@ namespace MHWNewCamera private void disableFreeCamera()
{
freeCamera = false;
+ unlockInputToggled = false;
if (preDetachFov != null)
{
cameraFov = (double)preDetachFov;
@@ -1177,6 +1139,7 @@ namespace MHWNewCamera }
if (vCamera != camera)
{
+ // We're assuming vCamera isn't an invalid pointer, but there's no assurance of that.
if (vCamera != null)
{
camera.NearClip = vCamera.NearClip;
@@ -1433,6 +1396,27 @@ namespace MHWNewCamera }
}
+ private void setPerspectivePreset(Config.Preset preset)
+ {
+ cameraFov = preset.FOV;
+ cameraForward = preset.Forward;
+ cameraRight = preset.Right;
+ cameraXOffset = 0.0f;
+ cameraYOffset = preset.Up;
+ cameraZOffset = 0.0f;
+ cameraRoll = preset.Roll;
+ if (preDetachRoll != null)
+ {
+ preDetachRoll = cameraRoll;
+ }
+ disableFading = preset.DisableFading;
+ if (pCameraViewportIndex >= 0)
+ {
+ setDisableFadingObjects(pCameraViewportIndex, disableFading);
+ }
+ setDisableCharacterFade(disableFading);
+ }
+
// This can undoubtedly be simplified.
private void WritePadInputHook(nint unknownPtr, nint unknownPtr2, nint unknownPtr3)
{
@@ -1517,25 +1501,48 @@ namespace MHWNewCamera lastPadDown = PadDown;
}
- bool blockInput = !unlockInputToggled;
- if (buttonWasDown(Button.L2))
+ if ((comboButton1Down || (!disableComboButton1 && buttonWasDown(b1))))
{
- if (buttonWasReleased(Button.R1))
+ if (buttonWasPressed(b2))
{
- unlockInputToggled = !unlockInputToggled;
- blockInput = true;
+ enableFreeCamera = !enableFreeCamera;
}
- else if (buttonWasDown(Button.R1))
+ int presetSelect = (buttonWasPressed(Button.Up) ? -1 : 0) + (buttonWasPressed(Button.Down) ? 1 : 0);
+ if (presetSelect != 0)
{
- blockInput = true;
+ Config config = ConfigManager.GetConfig<Config>(this);
+ Dictionary<string, Config.Preset>.KeyCollection presetKeys = config.Presets.Keys;
+ if (presetKeys.Count > 0)
+ {
+ if (config.Selected != "")
+ {
+ int selectedIndex;
+ for (selectedIndex = 0; selectedIndex < presetKeys.Count; selectedIndex++)
+ {
+ string presetKey = presetKeys.ElementAt(selectedIndex);
+ if (presetKey == config.Selected) break;
+ }
+ selectedIndex += presetSelect;
+ if (selectedIndex >= presetKeys.Count)
+ {
+ selectedIndex -= presetKeys.Count;
+ }
+ else if (selectedIndex < 0)
+ {
+ selectedIndex += presetKeys.Count;
+ }
+ config.Selected = presetKeys.ElementAt(selectedIndex);
+ }
+ else
+ {
+ config.Selected = presetKeys.ElementAt((presetSelect == 1) ? 0 : presetKeys.Count - 1);
+ }
+ setPerspectivePreset(config.Presets[config.Selected]);
+ ConfigManager.SaveConfig<Config>(this);
+ }
}
}
- if ((comboButton1Down || (!disableComboButton1 && buttonWasDown(b1))) && buttonWasPressed(b2))
- {
- enableFreeCamera = !enableFreeCamera;
- }
-
if (unlockMovementHeld && buttonWasReleased(Button.R2))
{
unlockMovementHeld = false;
@@ -1544,6 +1551,31 @@ namespace MHWNewCamera if (enableFreeCamera)
{
+ bool blockInput = !unlockInputToggled;
+
+ // Hold both buttons and release either. We have to block until
+ // release or it will get annoying to toggle input while on a menu.
+ if (buttonWasDown(Button.R2))
+ {
+ if (buttonWasReleased(Button.R1))
+ {
+ unlockInputToggled = !unlockInputToggled;
+ inputBlockedForToggle = false;
+ blockInput = true;
+ }
+ else if (buttonWasDown(Button.R1))
+ {
+ inputBlockedForToggle = true;
+ blockInput = true;
+ }
+ }
+ else if (buttonWasReleased(Button.R2) && inputBlockedForToggle)
+ {
+ unlockInputToggled = !unlockInputToggled;
+ inputBlockedForToggle = false;
+ blockInput = true;
+ }
+
if (blockInput)
{
if (!readInputsPostHook)
@@ -1715,6 +1747,11 @@ namespace MHWNewCamera debugLog($"EvalDepthOfFieldHook({unknownPtr}, {unknownPtr2}) @ {frameTick}");
#endif
// Possibly of interest: +0x1DE, +0x1DF.
+ // We're assuming the previous dofPointer will still be valid, but that might not be true.
+ if (dofPointer != 0x0 && unknownPtr != dofPointer && wasDofAllowed != null) {
+ MemoryUtil.WriteBytes(dofPointer + 0x1DD, ((bool)wasDofAllowed) ? [0x1] : [0x0]);
+ wasDofAllowed = null;
+ }
dofPointer = unknownPtr;
if (!forceOffDof)
{
@@ -1787,11 +1824,12 @@ namespace MHWNewCamera }
if (vp.Camera != null)
{
- var camera = vp.Camera;
+ Camera camera = vp.Camera;
+ bool usedByFreeCamera = freeCamera && enableFreeCamera && camera == vCamera;
if (debug) ImGui.Text($"Camera Pointer: {camera.Instance:x}");
if (ImGui.DragFloat("FOV", ref camera.FieldOfView, 0.1f))
{
- if (freeCamera && i == vCameraViewportIndex)
+ if (usedByFreeCamera)
{
cameraFov = camera.FieldOfView;
}
@@ -1808,7 +1846,7 @@ namespace MHWNewCamera if (debug) ImGui.InputFloat("Aspect Ratio", ref camera.AspectRatio);
ImGui.InputFloat("Near Clip", ref camera.NearClip);
ImGui.InputFloat("Far Clip", ref camera.FarClip);
- if (freeCamera && i == vCameraViewportIndex)
+ if (usedByFreeCamera)
{
ImGui.DragFloat3("Position", ref cameraPosition, 0.425f);
}
@@ -1887,7 +1925,7 @@ namespace MHWNewCamera ConfigManager.SaveConfig<Config>(this);
}
}
- if (debug || !(freeCamera && i == vCameraViewportIndex))
+ if (debug)
{
bool move = camera.Move;
if (ImGui.Checkbox("Move", ref move))
@@ -1899,9 +1937,6 @@ namespace MHWNewCamera ImGui.Text("Uncheck this to allow manually overriding the camera position.\nIf your camera is frozen, make sure this is checked.");
ImGui.EndTooltip();
}
- }
- if (debug)
- {
ImGui.SameLine();
bool fix = camera.Fix;
if (ImGui.Checkbox("Fix", ref fix))
@@ -1911,6 +1946,11 @@ namespace MHWNewCamera }
if (camera == vCamera)
{
+ if (!usedByFreeCamera)
+ {
+ ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
+ }
+ // If our camera hooks aren't being run, these values won't be updated.
float yaw = (float)cameraYaw;
if (ImGui.DragFloat("Yaw", ref yaw, 0.2f))
{
@@ -1926,11 +1966,16 @@ namespace MHWNewCamera {
cameraRoll = offsetRoll;
}
- if (camera == pCamera && !freeCamera)
+ if (!usedByFreeCamera)
{
- ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ ImGui.PopItemFlag();
}
+ // Try to grey out offsets when they probably have no effect.
+ if ((camera == pCamera && !usedByFreeCamera) && camera.Move)
+ {
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ }
ImGui.Text("Offsets");
float offsetForward = 0.0f;
if (ImGui.DragFloat("Forward", ref offsetForward, 0.425f))
@@ -1940,7 +1985,7 @@ namespace MHWNewCamera camera.Position.X += forward.X * offsetForward;
camera.Position.Y += forward.Y * offsetForward;
camera.Position.Z += forward.Z * offsetForward;
- cameraPosition = camera.Position;
+ if (usedByFreeCamera) cameraPosition = camera.Position;
}
float offsetRight = 0.0f;
if (ImGui.DragFloat("Right", ref offsetRight, 0.425f))
@@ -1951,15 +1996,15 @@ namespace MHWNewCamera right = Quaternion.Normalize(right);
camera.Position.X += right.X * offsetRight;
camera.Position.Z += right.Z * offsetRight;
- cameraPosition = camera.Position;
+ if (usedByFreeCamera) cameraPosition = camera.Position;
}
float offsetUp = 0.0f;
if (ImGui.DragFloat("Up", ref offsetUp, 0.425f))
{
camera.Position.Y += offsetUp;
- cameraPosition = camera.Position;
+ if (usedByFreeCamera) cameraPosition = camera.Position;
}
- if (camera == pCamera && !freeCamera)
+ if (camera == pCamera && !(freeCamera || enableFreeCamera))
{
ImGui.PopStyleVar();
}
@@ -2182,25 +2227,8 @@ namespace MHWNewCamera if (ImGui.Selectable(presetKey, isSelected))
{
config.Selected = presetKey;
+ setPerspectivePreset(config.Presets[config.Selected]);
ConfigManager.SaveConfig<Config>(this);
- Config.Preset preset = config.Presets[config.Selected];
- cameraFov = preset.FOV;
- cameraForward = preset.Forward;
- cameraRight = preset.Right;
- cameraXOffset = 0.0f;
- cameraYOffset = preset.Up;
- cameraZOffset = 0.0f;
- cameraRoll = preset.Roll;
- if (preDetachRoll != null)
- {
- preDetachRoll = cameraRoll;
- }
- disableFading = preset.DisableFading;
- if (pCameraViewportIndex >= 0)
- {
- setDisableFadingObjects(pCameraViewportIndex, disableFading);
- }
- setDisableCharacterFade(disableFading);
}
if (isSelected) ImGui.SetItemDefaultFocus();
}
@@ -2299,16 +2327,16 @@ namespace MHWNewCamera {
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
}
- ImGui.Checkbox("Unlock Player Movement", ref unlockMovementToggled);
+ ImGui.Checkbox("Unlock Input to the Game", ref unlockInputToggled);
if (ImGui.BeginItemTooltip())
{
- ImGui.Text("Hold RT + Press LB.");
+ ImGui.Text("Hold RT + RB, Release Either.");
ImGui.EndTooltip();
}
- ImGui.Checkbox("Unlock Input to the Game", ref unlockInputToggled);
+ ImGui.Checkbox("Unlock Player Movement", ref unlockMovementToggled);
if (ImGui.BeginItemTooltip())
{
- ImGui.Text("Hold LT + Press RB.");
+ ImGui.Text("Hold RT + Press LB.");
ImGui.EndTooltip();
}
ImGui.Checkbox("Lock Vertical Movement and Apply Speed Modifier", ref lockVerticalToggled);
@@ -2466,7 +2494,12 @@ namespace MHWNewCamera ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
- ImGui.Text("Hold LT + Press RB");
+ ImGui.Text("Hold RT + RB, Release Either");
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("Can effectively be treated as press RT + RB, but you probably want to press RT first in you're on a menu.");
+ ImGui.EndTooltip();
+ }
ImGui.TableSetColumnIndex(1);
ImGui.Text("Toggle Unlock Input to the Game");
if (ImGui.BeginItemTooltip())
@@ -2517,7 +2550,7 @@ namespace MHWNewCamera ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
- ImGui.Text("Hold LT & RT");
+ ImGui.Text("Hold LT + RT");
ImGui.TableSetColumnIndex(1);
ImGui.Text("Zoom with Left Stick Up/Down");
if (ImGui.BeginItemTooltip())
@@ -2959,14 +2992,13 @@ namespace MHWNewCamera {
if (pCamera != null)
{
+ ImGui.Text("Perspective Camera");
ImGui.Text($"Player Camera: {pCamera.Instance:x}");
ImGui.Text($"Applying Offset: {applyPerspective}");
ImGui.Text($"previousCameraAnimState: {previousCameraAnimState}");
- ImGui.Text($"dofPointer: {dofPointer:x}");
- ImGui.Text($"shadowCascadeValue: {lastShadowCascadeValue}");
- ImGui.Text($"shadowBias: {lastShadowBias}");
- ImGui.Text($"shadowRadius: {lastShadowRadius}");
- ImGui.Text($"shadowSampleNum: {lastShadowSampleNum}");
+ ImGui.DragFloat("X Offset", ref cameraXOffset, 0.425f);
+ ImGui.DragFloat("Y Offset", ref cameraYOffset, 0.425f);
+ ImGui.DragFloat("Z Offset", ref cameraZOffset, 0.425f);
ImGui.Separator();
}
@@ -3036,14 +3068,11 @@ namespace MHWNewCamera ImGui.Text("Palico/Otomo");
ImGui.Text($"Pointer: {sOtomo.Instance:x}");
ImGui.PopID();
+
+ ImGui.Separator();
}
- ImGui.Separator();
- ImGui.PushID("Camera");
- ImGui.Text("Perspective Camera");
- ImGui.DragFloat("X Offset", ref cameraXOffset, 0.425f);
- ImGui.DragFloat("Y Offset", ref cameraYOffset, 0.425f);
- ImGui.DragFloat("Z Offset", ref cameraZOffset, 0.425f);
+ ImGui.PushID("Viewports");
ImGui.Text("Viewports");
for (int i = 0; i < 8; i++)
{
@@ -3058,6 +3087,17 @@ namespace MHWNewCamera ImGui.Separator();
+ ImGui.Text("Graphics");
+ ImGui.Text($"dofPointer: {dofPointer:x}");
+ ImGui.Text($"prevFoliageLodBias: {prevFoliageLodBias}");
+ ImGui.Text($"prevTerrainLodBias: {prevTerrainLodBias}");
+ ImGui.Text($"shadowCascadeValue: {lastShadowCascadeValue}");
+ ImGui.Text($"shadowBias: {lastShadowBias}");
+ ImGui.Text($"shadowRadius: {lastShadowRadius}");
+ ImGui.Text($"shadowSampleNum: {lastShadowSampleNum}");
+
+ ImGui.Separator();
+
ImGui.PushID("Pad");
ImGui.Text("Pad");
ImGui.Text($"Pointer: {controllerAddr():x}");
@@ -2,4 +2,4 @@ https://www.nexusmods.com/monsterhunterworld/mods/8300 + https://www.nexusmods.com/monsterhunterworld/mods/8366 + -// vim: set ft=asciidoc: +// vim: set syntax=asciidoc: |