From b2c910cf3cd0c649cf23e36fa4bc0d881df68425 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Sat, 23 May 2026 15:33:05 -0400 Subject: Misc fixes, work on lights Signed-off-by: Andrew Opalach --- Plugin.cs | 204 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 162 insertions(+), 42 deletions(-) diff --git a/Plugin.cs b/Plugin.cs index 15ba88b..c625090 100755 --- a/Plugin.cs +++ b/Plugin.cs @@ -9,12 +9,15 @@ using System.Diagnostics; using ImGuiNET; using SharpPluginLoader.Core; +using SharpPluginLoader.Core.Rendering; //using SharpPluginLoader.Core.Resources; using SharpPluginLoader.Core.Configuration; using SharpPluginLoader.Core.Memory; using SharpPluginLoader.Core.Entities; // @TODO: +// - Adding new value should not show restore button. +// - Hotload nukes config? // - Remove all parameters deemed mostly useless and/or unsafe. // - SPL Patches: // - Dialoge fix. @@ -47,7 +50,8 @@ namespace WorldTuningTool public bool InitFromLoadedInstance() { - Instance = IPlugin.GetInstance(Plugin.PluginName); + //Instance = IPlugin.GetInstance(Plugin.PluginName); + Instance = null; return Instance != null; } @@ -810,6 +814,11 @@ namespace WorldTuningTool } ImGui.SameLine(); DrawReferenceValue("Original", oValueV, oValueInt); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Will be incorrect if the in-game value was updated to be the same as an override."); + ImGui.EndTooltip(); + } } if (!overrideValue) { @@ -963,14 +972,12 @@ namespace WorldTuningTool Param = param; valueV = v4; valueInt = i1; - sValueV = v4; - sValueInt = i1; + Save(); } public void Save() { - sValueV = valueV; - sValueInt = valueInt; + (sValueV, sValueInt) = (valueV, valueInt); } public void Set() @@ -996,15 +1003,15 @@ namespace WorldTuningTool public void Draw(List? currentOverrides, List? stageOverrides, List? globalOverrides, bool superseded, float width) { - if (currentOverrides == null || superseded) - { - ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); - } - if (superseded) // superseded == !isSet, superseded is more clear in the context of drawing. + if (superseded) // superseded == !isSet. { Assert(!isSet); ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); } + if (currentOverrides == null || superseded) + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + } ImGui.PushItemWidth(width * 0.475f); if (ImGui.BeginCombo("##Parameters", Param != null ? Param.Name : "")) { @@ -1040,8 +1047,8 @@ namespace WorldTuningTool } Param = iterParam; (valueV, valueInt) = Param.GetValue(); - // If this override is superseded, expect this Combo to be disabled. - if (wasSet) + Save(); + if (wasSet) // If this override is superseded, expect this Combo to be disabled. { Set(); } @@ -1052,10 +1059,6 @@ namespace WorldTuningTool ImGui.EndCombo(); } ImGui.PopItemWidth(); - if (superseded) - { - ImGui.PopStyleVar(); - } if (currentOverrides == null || superseded) { ImGui.PopItemFlag(); @@ -1063,25 +1066,29 @@ namespace WorldTuningTool if (Param != null) { ImGui.SameLine(); - if (Param.DrawValue(ref valueV, ref valueInt, width, false) && !superseded) + if (Param.DrawValue(ref valueV, ref valueInt, width, false) && isSet) { Param.OverrideValue(valueV, valueInt); } (Vector4 v4, int i1) = Param.GetValue(); bool valueDiffers = (v4, i1) != (valueV, valueInt); - if ((valueV, valueInt) != (sValueV, sValueInt) || (valueDiffers && !Param.PendingUpdate() && !superseded)) + if ((valueV, valueInt) != (sValueV, sValueInt) || (isSet && valueDiffers && !Param.PendingUpdate())) { ImGui.SameLine(); if (ImGui.Button("⇄")) { valueV = sValueV; valueInt = sValueInt; - if (!superseded) + if (isSet) { Param.OverrideValue(valueV, valueInt); } } } + if (superseded) + { + ImGui.PopStyleVar(); + } if (Param.PendingUpdate()) { ImGui.SameLine(); @@ -1100,6 +1107,10 @@ namespace WorldTuningTool Param.DrawReferenceValue("Current", v4, i1); } } + else if (superseded) + { + ImGui.PopStyleVar(); + } } } @@ -1505,21 +1516,22 @@ namespace WorldTuningTool private class Light { public nint Object; + public int Type; public Parameter[] Parameters = { new Parameter("Group", 0x13C, ParameterType.INT, false, 1, 1, 3), new Parameter("Position", 0x5A0, ParameterType.VECTOR3, true, 0.1f), new Parameter("Color", 0x140, ParameterType.COLOR, true), new Parameter("Intensity", 0x8A8, ParameterType.FLOAT, true, 0.1f), - new Parameter("Radius", 0x6A0, ParameterType.FLOAT, true, 0.01f), - new Parameter("Effective Radius", 0x588, ParameterType.FLOAT, true, 0.01f), + new Parameter("Radius", 0x6A0, ParameterType.FLOAT, true, 0.25f), + new Parameter("Effective Radius", 0x588, ParameterType.FLOAT, true, 0.25f), new Parameter("Min Roughness", 0x58C, ParameterType.FLOAT, true), - new Parameter("Do Volumetric", 0x590, ParameterType.BOOL, true), - new Parameter("Near Clip Distance", 0x1B4, ParameterType.FLOAT, true), new Parameter("Shadow Cast", 0x138, ParameterType.FLAG, false, (1 << 23)), new Parameter("Shadow Map Size", 0x1B8, ParameterType.INT, false), // Aligned to 128. new Parameter("Shadow Depth Bias", 0x57C, ParameterType.FLOAT, true, 0.00001f), new Parameter("Shadow Sloped Depth Bias", 0x580, ParameterType.FLOAT, true, 0.00001f), new Parameter("Shadow Max Depth Bias", 0x584, ParameterType.FLOAT, true, 0.00001f), + new Parameter("Do Volumetric", 0x590, ParameterType.BOOL, true), + new Parameter("Near Clip Distance", 0x1B4, ParameterType.FLOAT, true), //new Parameter("Use Umbra", 0x591, ParameterType.BOOL, true), //new Parameter("Enable Camera LOD", 0x592, ParameterType.BOOL, true), //new Parameter("Llk Intensity", 0x974, ParameterType.FLOAT, true), @@ -1528,6 +1540,7 @@ namespace WorldTuningTool //new Parameter("Cone", 0x5F0, ParameterType.FLOAT, true, 0.1f), //new Parameter("Spread", 0x5F4, ParameterType.FLOAT, true, 0.1f) }; + /* public Parameter[] RandomMoveParameters = { new Parameter("Random Move Radius", 0x8E8, ParameterType.FLOAT, true), new Parameter("Random Move Force To Center", 0x8EC, ParameterType.FLOAT, true), @@ -1537,15 +1550,23 @@ namespace WorldTuningTool new Parameter("Random Move Speed V Max", 0x940, ParameterType.VECTOR3, true), new Parameter("Random Move Force V Max", 0x960, ParameterType.VECTOR3, true) }; + */ - public Light(nint lightObject, Vector3 pos) + public Light(nint lightObject, int type) { Object = lightObject; + Type = type; foreach (Parameter param in Parameters) { - param.OverrideOn(false); + param.Update(lightObject); } - foreach (Parameter param in RandomMoveParameters) + } + + public Light(nint lightObject, int type, Vector3 pos) + { + Object = lightObject; + Type = type; + foreach (Parameter param in Parameters) { param.OverrideOn(false); } @@ -1556,18 +1577,40 @@ namespace WorldTuningTool { param.Update(lightObject); } - foreach (Parameter param in RandomMoveParameters) - { - param.Update(lightObject); - } } } + // Point Light (2): + // Create1: 0x141F875A0 () + // Create2: 0x141F87CD0 (nint) + // Destroy: 0x141F87D90 (nint, int) + // + // Spot Light (3): + // Create1: 0x141F8AE80 () + // Create2: 0x141F8B2D0 (nint) + // Destroy: 0x141F8B390 (nint, int) + // + // Hemi Sphere Light (4): + // Create1: 0x141F84840 () + // Create2: 0x141F84990 (nint) + // Destroy: 0x141F84A40 (nint, int) + // + // Wrapper? (8): + // Create1: 0x141F816C0 () + // Create2: 0x141F81800 () + // Destroy: 0x141F81940 (nint, int) + private int requestLightType = 2; private NativeFunction createLight; + private bool interceptCreateLight = false; private List ourLights = new List(); + private List sceneLights = new List(); private NativeAction addToScene; private NativeAction removeFromScene; + private delegate nint CreateLightObject(int type); + private Hook? createLightObject; + private delegate void DestroyLightObject(nint lightObject, int unknownInt); + private Hook? destroyLightObject; private delegate void UpdateLights(nint lightObject); private Hook? updateLights; @@ -1785,6 +1828,8 @@ namespace WorldTuningTool */ createLight = new NativeFunction(0x1418A3EF0); + //createLightObject = Hook.Create(0x1418A3EF0, CreateLightObjectHook); + destroyLightObject = Hook.Create(0x141F87D90, DestroyLightObjectHook); addToScene = new NativeAction(0x142219070); removeFromScene = new NativeAction(0x142228F10); updateLights = Hook.Create(0x141F88F30, UpdateLightsHook); @@ -2182,21 +2227,70 @@ namespace WorldTuningTool staticShadowParams!.Original(shadowObjectStatic, shadowObjectInternal); } - private void UpdateLightsHook(nint lightObject) + /* + private nint CreateLightObjectHook(int type) + { + nint lightObject = createLightObject!.Original(type); + if (interceptCreateLight) + { + interceptCreateLight = false; + } + //else if (type == 2) + else + { + sceneLights.Add(new Light(lightObject, type)); + } + return lightObject; + } + */ + + private void DestroyLightObjectHook(nint lightObject, int unknownInt) { - Light? ourLight = null; + for (int i = 0; i < sceneLights.Count; i++) + { + if (lightObject == sceneLights[i].Object) + { + sceneLights.RemoveAt(i); + break; + } + } for (int i = 0; i < ourLights.Count; i++) { if (lightObject == ourLights[i].Object) { - ourLight = ourLights[i]; + ourLights.RemoveAt(i); break; } } + destroyLightObject!.Original(lightObject, unknownInt); + } + + private void UpdateLightsHook(nint lightObject) + { + Light? light = null; + for (int i = 0; i < sceneLights.Count; i++) + { + if (lightObject == sceneLights[i].Object) + { + light = sceneLights[i]; + break; + } + } + if (light == null) + { + for (int i = 0; i < ourLights.Count; i++) + { + if (lightObject == ourLights[i].Object) + { + light = ourLights[i]; + break; + } + } + } updateLights!.Original(lightObject); - if (ourLight != null) + if (light != null) { - foreach (Parameter param in ourLight.Parameters) + foreach (Parameter param in light.Parameters) { param.Update(lightObject); } @@ -2736,6 +2830,7 @@ namespace WorldTuningTool */ if (ImGui.Button("New")) { + interceptCreateLight = true; nint lightObject = createLight.Invoke(requestLightType); Vector3 pos = default; Player? player = Player.MainPlayer; @@ -2744,20 +2839,22 @@ namespace WorldTuningTool pos = player.Position; pos.Y += 30.0f; } - ourLights.Add(new Light(lightObject, pos)); - // mov byte ptr[rsp+20],00 unaccounted for, hopefully it doesn't matter. + ourLights.Add(new Light(lightObject, requestLightType, pos)); + // mov byte ptr[rsp+20],00 unaccounted for, hopefully it never matters. addToScene.Invoke(MemoryUtil.Read(0x1451238C8), 0x16, lightObject, 0x0); } ImGui.Separator(); + ImGui.PushID("Ours"); for (int i = 0; i < ourLights.Count; i++) { Light light = ourLights[i]; ImGui.PushID(i); - ImGui.Text($"Address: {light.Object:X}"); + ImGui.Text($"Type: {light.Type}, Address: {light.Object:X}"); foreach (Parameter param in light.Parameters) { param.Draw(width, true); } + /* if (ImGui.CollapsingHeader("Random Move")) { foreach (Parameter param in light.RandomMoveParameters) @@ -2765,6 +2862,7 @@ namespace WorldTuningTool param.Draw(width, true); } } + */ if (ImGui.Button("Remove")) { /* @@ -2774,12 +2872,34 @@ namespace WorldTuningTool */ // removeFromScene triggers destructor. removeFromScene.Invoke(light.Object); - ourLights.RemoveAt(i); - i--; } ImGui.PopID(); ImGui.Separator(); } + ImGui.PopID(); + ImGui.PushID("Scene"); + /* + if (ImGui.CollapsingHeader("Scene Lights")) + { + for (int i = 0; i < sceneLights.Count; i++) + { + Light light = sceneLights[i]; + ImGui.PushID(i); + ImGui.Text($"Type: {light.Type}, Address: {light.Object:X}"); + foreach (Parameter param in light.Parameters) + { + param.Draw(width); + } + if (ImGui.Button("Remove")) + { + removeFromScene.Invoke(light.Object); + } + ImGui.PopID(); + ImGui.Separator(); + } + } + */ + ImGui.PopID(); } if (ImGui.CollapsingHeader("Parameters")) @@ -2852,7 +2972,7 @@ namespace WorldTuningTool ImGui.PopID(); } - if (ImGui.CollapsingHeader("Shadow Parameters")) + if (ImGui.CollapsingHeader("Shadow (a.k.a. \"Infinite Light\") Parameters")) { ImGui.PushID("Shadows"); // MonsterHunterWorld.exe+1AB99E0 - mov rax,[MonsterHunterWorld.exe+500E180] @@ -3028,6 +3148,7 @@ namespace WorldTuningTool Log.Info("Face shader replaced."); } } + /* else if (hash == "18a797dc-9458d333-59e6dff0-9790fcea") { if (replaceShaderFromFile(info, $"{shaderPath}/sssss.shdr")) { @@ -3035,7 +3156,6 @@ namespace WorldTuningTool Log.Info("SSSSS shader replaced."); } } - /* else if (hash == "d7e47ffe-82572c64-795c4698-341e5b91") { if (replaceShaderFromFile(info, $"{shaderPath}/sslr_mips.shdr")) { -- cgit v1.2.3-101-g0448