From 077dc958fa15457356b695a050aae5be3011081c Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 5 Aug 2026 15:11:19 -0400 Subject: Add Sky, Fog, and Water Waves objects Signed-off-by: Andrew Opalach --- Plugin.cs | 554 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 498 insertions(+), 56 deletions(-) (limited to 'Plugin.cs') diff --git a/Plugin.cs b/Plugin.cs index 7b867e6..d93625d 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -63,7 +63,7 @@ namespace WorldTuningTool public string Author => "Akon City Software"; private static bool loggedAssertFailed = false; - private static void Assert(bool condition, [CallerLineNumber] int line = 0) + public static void Assert(bool condition, [CallerLineNumber] int line = 0) { if (!condition && !loggedAssertFailed) { @@ -107,6 +107,14 @@ namespace WorldTuningTool private static string BooleanToString(bool b) { return b.ToString(CultureInfo.InvariantCulture); } private static string Int32ToString(int i, string? format = null) { return i.ToString(format, CultureInfo.InvariantCulture); } + public static Vector2 StringToVector2(string s, char delim = ',') + { + if (String.IsNullOrEmpty(s)) throw new FormatException(); + string[] sp = s.Split(delim).Select(v => v.Trim()).ToArray(); + if (sp.Length != 2) throw new FormatException(); + return new Vector2(StringToSingle(sp[0]), StringToSingle(sp[1])); + } + public static Vector3 StringToVector3(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); @@ -115,11 +123,29 @@ namespace WorldTuningTool return new Vector3(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2])); } + public static Vector4 StringToVector4(string s, char delim = ',') + { + if (String.IsNullOrEmpty(s)) throw new FormatException(); + string[] sp = s.Split(delim).Select(v => v.Trim()).ToArray(); + if (sp.Length != 4) throw new FormatException(); + return new Vector4(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2]), StringToSingle(sp[3])); + } + + private static string Vector2ToString(Vector2 v) + { + return string.Format(CultureInfo.InvariantCulture, "{0},{1}", v.X, v.Y); + } + private static string Vector3ToString(Vector3 v) { return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", v.X, v.Y, v.Z); } + private static string Vector4ToString(Vector4 v) + { + return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", v.X, v.Y, v.Z, v.W); + } + public enum ParameterType { BOOL, @@ -129,8 +155,10 @@ namespace WorldTuningTool ALIGNED_INT, HEX, COLOR, + COLOR_FACTOR, FLOAT, VECTOR3, + VECTOR2, VECTOR4, PATCH_FLOAT, SHADOW_RESOLUTION @@ -258,13 +286,17 @@ namespace WorldTuningTool return superseded; } + private static class ParameterFlags + { + public const int PerFrame = 1; + public const int NoOverride = 1 << 1; + } + public abstract class Parameter { public string Name; private string hiddenName; public ParameterType Type; - public bool PerFrame; - public bool NoOverride; private nint offset; private int mask; @@ -273,9 +305,14 @@ namespace WorldTuningTool private bool overrideForStage = false; private bool overrideWasOn = false; + private int flags; + public bool NoOverride => (flags & ParameterFlags.NoOverride) == ParameterFlags.NoOverride; + public bool PerFrame => (flags & ParameterFlags.PerFrame) == ParameterFlags.PerFrame; + protected float stepf, minf, maxf; protected int step, min, max; + private bool fallbackUpdate = true; private bool pendingWrite = false; private Vector4 valueV = default; private int valueInt = 0; @@ -292,13 +329,14 @@ namespace WorldTuningTool private Vector4 bValueV; // B value in A/B. private int bValueInt; - public Parameter(string name, nint offset, int mask, ParameterType type, bool perFrame, bool noOverride) + public Parameter(string name, nint offset, int mask, ParameterType type, int flags) { Name = name; hiddenName = "##" + Name; + Type = type; this.offset = offset; this.mask = mask; - Type = type; + this.flags = flags; if (Type == ParameterType.PATCH_FLOAT) { valueV.X = MemoryUtil.Read(offset); @@ -309,8 +347,6 @@ namespace WorldTuningTool valueInt = 1; pendingUpdate = false; } - PerFrame = perFrame; - NoOverride = noOverride; } public bool PendingUpdate() @@ -396,7 +432,11 @@ namespace WorldTuningTool case ParameterType.FLOAT: MemoryUtil.GetRef(lastAddr + offset) = valueV.X; break; + case ParameterType.VECTOR2: + MemoryUtil.GetRef(lastAddr + offset) = new Vector2(valueV.X, valueV.Y); + break; case ParameterType.VECTOR3: + case ParameterType.COLOR_FACTOR: MemoryUtil.GetRef(lastAddr + offset) = new Vector3(valueV.X, valueV.Y, valueV.Z); break; case ParameterType.VECTOR4: @@ -487,7 +527,12 @@ namespace WorldTuningTool } } - public void Update(nint baseObject) + private int bitIndex(int mask) + { + return BitOperations.Log2((uint)(mask & (-mask))); + } + + public void Update(nint baseObject, bool fromHook = false) { lastAddr = baseObject; @@ -497,6 +542,16 @@ namespace WorldTuningTool return; } + if (fromHook) + { + fallbackUpdate = false; + } + else if (!fallbackUpdate) + { + fallbackUpdate = true; + return; + } + // Trying to track changes to the original value is a "best effort" // approach because it can't work if the in-game value is updated // to the same value as a current override. @@ -506,12 +561,12 @@ namespace WorldTuningTool case ParameterType.BYTE: { ref byte b1 = ref MemoryUtil.GetRef(baseObject + offset); - if (b1 != (byte)valueInt) - { - oValueInt = (byte)b1; - } if (overrideValue) { + if (b1 != (byte)valueInt) + { + oValueInt = b1; + } b1 = (byte)valueInt; } else @@ -524,12 +579,12 @@ namespace WorldTuningTool { ref int i1 = ref MemoryUtil.GetRef(baseObject + offset); int b1 = ByteFlag((i1 & mask) == mask); - if (b1 != valueInt) - { - oValueInt = b1; - } if (overrideValue) { + if (b1 != valueInt) + { + oValueInt = b1; + } if (valueInt != 0) { i1 |= mask; @@ -551,12 +606,16 @@ namespace WorldTuningTool case ParameterType.COLOR: { ref int i1 = ref MemoryUtil.GetRef(baseObject + offset); - if (i1 != valueInt) + if (mask != 0) { - oValueInt = i1; + i1 = (i1 & mask) >> bitIndex(mask); } if (overrideValue) { + if (i1 != valueInt) + { + oValueInt = i1; + } i1 = valueInt; } else @@ -568,12 +627,12 @@ namespace WorldTuningTool case ParameterType.FLOAT: { ref float f1 = ref MemoryUtil.GetRef(baseObject + offset); - if (f1 != valueV.X) - { - oValueV.X = f1; - } if (overrideValue) { + if (f1 != valueV.X) + { + oValueV.X = f1; + } f1 = valueV.X; } else @@ -582,16 +641,35 @@ namespace WorldTuningTool } break; } + case ParameterType.VECTOR2: + { + ref Vector2 v2 = ref MemoryUtil.GetRef(baseObject + offset); + Vector2 valueV2 = new Vector2(valueV.X, valueV.Y); + if (overrideValue) + { + if (v2 != valueV2) + { + oValueV = new Vector4(v2.X, v2.Y, 0.0f, 0.0f); + } + v2 = valueV2; + } + else + { + valueV = new Vector4(v2.X, v2.Y, 0.0f, 0.0f); + } + break; + } case ParameterType.VECTOR3: + case ParameterType.COLOR_FACTOR: { ref Vector3 v3 = ref MemoryUtil.GetRef(baseObject + offset); Vector3 valueV3 = new Vector3(valueV.X, valueV.Y, valueV.Z); - if (v3 != valueV3) - { - oValueV = new Vector4(v3.X, v3.Y, v3.Z, 0.0f); - } if (overrideValue) { + if (v3 != valueV3) + { + oValueV = new Vector4(v3.X, v3.Y, v3.Z, 0.0f); + } v3 = valueV3; } else @@ -603,12 +681,12 @@ namespace WorldTuningTool case ParameterType.VECTOR4: { ref Vector4 v4 = ref MemoryUtil.GetRef(baseObject + offset); - if (v4 != valueV) - { - oValueV = v4; - } if (overrideValue) { + if (v4 != valueV) + { + oValueV = v4; + } v4 = valueV; } else @@ -664,7 +742,9 @@ namespace WorldTuningTool break; case ParameterType.FLOAT: case ParameterType.PATCH_FLOAT: + case ParameterType.VECTOR2: case ParameterType.VECTOR3: + case ParameterType.COLOR_FACTOR: case ParameterType.VECTOR4: v4 = new Vector4( Math.Clamp(v4.X, minf, maxf), @@ -697,8 +777,8 @@ namespace WorldTuningTool } case ParameterType.BYTE: { - ImGui.SetNextItemWidth(width * defaultParamWidth); ImGuiInputTextFlags flags = ImGuiInputTextFlags.EnterReturnsTrue; + ImGui.SetNextItemWidth(width * defaultParamWidth); if (ImGui.InputInt(label, ref i1, step, 0, flags)) { valueChanged = true; @@ -710,12 +790,12 @@ namespace WorldTuningTool case ParameterType.HEX: case ParameterType.SHADOW_RESOLUTION: { - ImGui.SetNextItemWidth(width * defaultParamWidth); ImGuiInputTextFlags flags = ImGuiInputTextFlags.EnterReturnsTrue; if (Type == ParameterType.HEX) { flags |= ImGuiInputTextFlags.CharsHexadecimal; } + ImGui.SetNextItemWidth(width * defaultParamWidth); if (ImGui.InputInt(label, ref i1, step, 0, flags)) { valueChanged = true; @@ -724,8 +804,8 @@ namespace WorldTuningTool } case ParameterType.COLOR: { - ImGui.SetNextItemWidth(width * defaultParamWidth * 3.0f); Vector4 colorV = ColorVectorFromInt(i1); + ImGui.SetNextItemWidth(width * defaultParamWidth * 3.0f); if (ImGui.ColorEdit4(label, ref colorV)) { i1 = ColorVectorToInt(colorV); @@ -736,8 +816,8 @@ namespace WorldTuningTool case ParameterType.FLOAT: case ParameterType.PATCH_FLOAT: { - ImGui.SetNextItemWidth(width * defaultParamWidth); float f1 = v4.X; + ImGui.SetNextItemWidth(width * defaultParamWidth); if (ImGui.DragFloat(label, ref f1, stepf, displayMinf, displayMaxf, "%.6f", ImGuiSliderFlags.NoRoundToFormat)) { v4 = new Vector4(f1, 0.0f, 0.0f, 0.0f); @@ -745,10 +825,33 @@ namespace WorldTuningTool } break; } + case ParameterType.VECTOR2: + { + Vector2 v2 = new Vector2(v4.X, v4.Y); + ImGui.SetNextItemWidth(width * defaultParamWidth * 2.0f); + if (ImGui.DragFloat2(label, ref v2, stepf, displayMinf, displayMaxf, "%.5f", ImGuiSliderFlags.NoRoundToFormat)) + { + v4 = new Vector4(v2.X, v2.Y, 0.0f, 0.0f); + valueChanged = true; + } + break; + } case ParameterType.VECTOR3: + case ParameterType.COLOR_FACTOR: { - ImGui.SetNextItemWidth(width * defaultParamWidth * 3.0f); Vector3 v3 = new Vector3(v4.X, v4.Y, v4.Z); + if (Type == ParameterType.COLOR_FACTOR) + { + Vector3 v3Scale = Vector3.Abs(v3); + float max = MathF.Max(v3.X, MathF.Max(v3.Y, v3.Z)); + if (max != 0.0f) + { + v3Scale = (v3Scale / max) * v3Scale; + } + ImGui.ColorEdit3(label, ref v3Scale, ImGuiColorEditFlags.NoPicker | ImGuiColorEditFlags.NoLabel | ImGuiColorEditFlags.NoInputs); + ImGui.SameLine(); + } + ImGui.SetNextItemWidth(width * defaultParamWidth * 3.0f); if (ImGui.DragFloat3(label, ref v3, stepf, displayMinf, displayMaxf, "%.5f", ImGuiSliderFlags.NoRoundToFormat)) { v4 = new Vector4(v3.X, v3.Y, v3.Z, 0.0f); @@ -796,7 +899,11 @@ namespace WorldTuningTool case ParameterType.PATCH_FLOAT: ImGui.Text($"({name}: {v4.X:0.000000})"); break; + case ParameterType.VECTOR2: + ImGui.Text($"({name}: {v4.X:0.00000}, {v4.Y:0.00000})"); + break; case ParameterType.VECTOR3: + case ParameterType.COLOR_FACTOR: ImGui.Text($"({name}: {v4.X:0.00000}, {v4.Y:0.00000}, {v4.Z:0.00000})"); break; case ParameterType.VECTOR4: @@ -1018,7 +1125,7 @@ namespace WorldTuningTool public class Parameter : Parameter where T : unmanaged { - public Parameter(string name, nint offset, int mask, ParameterType type, T? min, T? max, T? step, bool perFrame, bool noOverride) : base(name, offset, mask, type, perFrame, noOverride) + public Parameter(string name, nint offset, int mask, ParameterType type, T? min, T? max, T? step, int flags) : base(name, offset, mask, type, flags) { if (typeof(T) == typeof(float)) { @@ -1048,6 +1155,23 @@ namespace WorldTuningTool } } + public static int pFlags(string s) + { + int flags = 0; + for (int i = 0; i < s.Length; i++) + { + switch (s[i]) + { + case 'f': + flags |= ParameterFlags.PerFrame; + break; + default: + break; + } + } + return flags; + } + public static (float?, float?, float?) pStep(float step) { return (null, null, step); } public static (float?, float?, float?) pMin(float min) { return (min, null, null); } public static (float?, float?, float?) pMax(float max) { return (null, max, null); } @@ -1064,22 +1188,27 @@ namespace WorldTuningTool public static Parameter newParameter(string name, nint offset, ParameterType type, (T? min, T? max, T? step) m = default) where T : unmanaged { - return new Parameter(name, offset, 0, type, m.min, m.max, m.step, false, false); + return new Parameter(name, offset, 0, type, m.min, m.max, m.step, 0); + } + + public static Parameter P(string name, nint offset, ParameterType type, int flags, (T? min, T? max, T? step) m = default) where T : unmanaged + { + return new Parameter(name, offset, 0, type, m.min, m.max, m.step, flags); } public static Parameter newFrameParameter(string name, nint offset, ParameterType type, (T? min, T? max, T? step) m = default) where T : unmanaged { - return new Parameter(name, offset, 0, type, m.min, m.max, m.step, true, false); + return new Parameter(name, offset, 0, type, m.min, m.max, m.step, ParameterFlags.PerFrame); } public static Parameter newParameterView(string name, nint offset, ParameterType type, (T? min, T? max, T? step) m = default) where T : unmanaged { - return new Parameter(name, offset, 0, type, m.min, m.max, m.step, false, true); + return new Parameter(name, offset, 0, type, m.min, m.max, m.step, ParameterFlags.NoOverride); } public static Parameter newFlag(string name, nint offset, ParameterType type, int mask) where T : unmanaged { - return new Parameter(name, offset, mask, type, null, null, null, false, false); + return new Parameter(name, offset, mask, type, null, null, null, 0); } private static Parameter? getParameterByName(string name) @@ -1124,11 +1253,15 @@ namespace WorldTuningTool case ParameterType.FLOAT: case ParameterType.PATCH_FLOAT: return SingleToString(sValueV.X); + case ParameterType.VECTOR2: + Vector2 sValueV2 = new Vector2(sValueV.X, sValueV.Y); + return Vector2ToString(sValueV2); case ParameterType.VECTOR3: + case ParameterType.COLOR_FACTOR: Vector3 sValueV3 = new Vector3(sValueV.X, sValueV.Y, sValueV.Z); return Vector3ToString(sValueV3); case ParameterType.VECTOR4: - break; + return Vector4ToString(sValueV); } } return ""; @@ -1158,11 +1291,17 @@ namespace WorldTuningTool case ParameterType.PATCH_FLOAT: valueV.X = StringToSingle(value); break; + case ParameterType.VECTOR2: + Vector2 valueV2 = StringToVector2(value); + valueV = new Vector4(valueV2.X, valueV2.Y, 0.0f, 0.0f); + break; case ParameterType.VECTOR3: + case ParameterType.COLOR_FACTOR: Vector3 valueV3 = StringToVector3(value); valueV = new Vector4(valueV3.X, valueV3.Y, valueV3.Z, 0.0f); break; case ParameterType.VECTOR4: + valueV = StringToVector4(value); break; } } @@ -1541,7 +1680,7 @@ namespace WorldTuningTool private static Parameter[] shadowParameters2 = { newFrameParameter("Sunlight Group", 0x14, ParameterType.INT, pMinMaxStep(1, 255, 1)), newFrameParameter("Sunlight Direction", 0x110, ParameterType.VECTOR3, pStep(0.00025f)), - newFrameParameter("Sunlight Color", 0xE0, ParameterType.FLOAT, pStep(0.001f)), + newFrameParameter("Sunlight Color", 0xE0, ParameterType.COLOR_FACTOR, pMaxStep(1.0f, 0.001f)), newFrameParameter("Sunlight Intensity", 0xF4, ParameterType.FLOAT), newParameter("Sunlight Min Roughness", 0x58C, ParameterType.FLOAT, pStep(0.0025f)), // +0xFC in params but is never read. newFrameParameter("Sunlight Is Primary", 0x1D, ParameterType.BOOL), @@ -1624,7 +1763,7 @@ namespace WorldTuningTool newParameter("Hdr Is Gui Hdr Gamma", 0x228, ParameterType.BOOL) }; private static MtObject? sLightProbes = null; - private static Parameter[] lightProbesParameters = { + private static Parameter[] sLightProbesParameters = { newParameter("Debug Mode", 0x98, ParameterType.INT, pStep(1)) }; @@ -1697,6 +1836,143 @@ namespace WorldTuningTool newParameter("Motion Blur Threshold", 0x18C, ParameterType.FLOAT, pMinStep(0.0f, 0.01f)) }; + private delegate nint CreateSimpleSkyObject(nint unknownPtr); + private delegate nint DestroySimpleSkyObject(nint simpleSkyObjectInternal, int unknownInt); + private delegate void RenderSimpleSky(nint simpleSkyObjectInternal, nint unknownPtr); + private Hook? createSimpleSkyObject; + private Hook? destroySimpleSkyObject; + private Hook? renderSimpleSky; + private nint simpleSkyObject = 0x0; + private static Parameter[] simpleSkyParameters = { + newParameter("Sky Global Intensity", 0x270, ParameterType.COLOR_FACTOR, pStep(0.001f)), + newParameter("Sky Global Cloud Speed", 0x3A8, ParameterType.FLOAT), + newParameter("Sky Top Cloud UV Scale[0]", 0x3D0, ParameterType.FLOAT), + newParameter("Sky Top Cloud UV Scale[1]", 0x3D8, ParameterType.FLOAT), + newParameter("Sky Blend", 0x3B0, ParameterType.FLOAT), + newParameter("Sky Water Reflection Factor", 0x7A0, ParameterType.COLOR_FACTOR, pStep(0.001f)), + newParameter("Sky Fog", 0x3B4, ParameterType.BOOL), + newParameter("Sky Fog Blend", 0x3B8, ParameterType.FLOAT), + newParameter("Sky DeGamma", 0x3BC, ParameterType.BOOL), + newParameter("Sky DeGamma Value", 0x3C0, ParameterType.FLOAT), + newParameter("Sky Cloud Highlight Intensity", 0x3C4, ParameterType.FLOAT), + newParameter("Sky Cloud Shadow Intensity", 0x3C8, ParameterType.FLOAT), + newParameter("Sky Cloud Contrast", 0x3CC, ParameterType.FLOAT), + newParameter("Sky Sun Map Factor", 0x280, ParameterType.COLOR_FACTOR), + newParameter("Sky Sun Size", 0x2A8, ParameterType.FLOAT), + newParameter("Sky Sun Rotation Y", 0x3A4, ParameterType.FLOAT), + newParameter("Sky Sun Height", 0x39C, ParameterType.FLOAT, pStep(0.0001f)), + newParameter("Sky Sun Light Mask Height Adjustment", 0x3A0, ParameterType.FLOAT), + newParameter("Sky Sun Light Mask Transparency", 0x2CC, ParameterType.FLOAT), + newParameter("Sky Sun Light Mask UV Scale", 0x2D0, ParameterType.FLOAT), + newParameter("Sky Sun Bloom Intensity", 0x2AC, ParameterType.FLOAT), + newParameter("Sky Sun Bloom Transparency Coefficient", 0x2B0, ParameterType.FLOAT), + newParameter("Sky Sun Bloom Threshold", 0x2B4, ParameterType.FLOAT), + newParameter("Sky Sun Bloom Dispersion", 0x2B8, ParameterType.FLOAT), + newParameter("Sky Sun Bloom Downsample Count", 0x2C0, ParameterType.FLOAT), + newParameter("Sky Sun Bloom Reduction Resolution", 0x2C4, ParameterType.FLOAT), + newParameter("Sky Sun Light Sky Color", 0x2E0, ParameterType.COLOR_FACTOR, pStep(0.001f)), + newParameter("Sky Sun Light Sky Mask UV Scale", 0x2F0, ParameterType.FLOAT), + newParameter("Sky Base Fov", 0x2BC, ParameterType.FLOAT), + newParameter("Sky Base Map Factor", 0x3E0, ParameterType.COLOR_FACTOR, pStep(0.001f)), + newParameter("Sky Base Side Cloud UV Offset", 0x3F0, ParameterType.FLOAT), + newParameter("Sky Base Top Cloud0 UV Offset", 0x3F8, ParameterType.FLOAT), + newParameter("Sky Base Top Cloud1 UV Offset", 0x400, ParameterType.FLOAT), + newParameter("Sky Base Sun Cloud Highlight Color[0]", 0x440, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Sun Cloud Shadow Color[0]", 0x480, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Middle Highlight Color[0]", 0x4C0, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Middle Shadow Color[0]", 0x500, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Background Highlight Color[0]", 0x540, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Background Shadow Color[0]", 0x580, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Cloud Speed[0]", 0x408, ParameterType.VECTOR2), + newParameter("Sky Base Cloud Alpha[0]", 0x428, ParameterType.FLOAT), + newParameter("Sky Base Sun Cloud Highlight Color[1]", 0x450, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Sun Cloud Shadow Color[1]", 0x490, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Middle Highlight Color[1]", 0x4D0, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Middle Shadow Color[1]", 0x510, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Background Highlight Color[1]", 0x550, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Background Shadow Color[1]", 0x590, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Cloud Speed[1]", 0x410, ParameterType.VECTOR2), + newParameter("Sky Base Cloud Alpha[1]", 0x42C, ParameterType.FLOAT), + newParameter("Sky Base Sun Cloud Highlight Color[2]", 0x460, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Sun Cloud Shadow Color[2]", 0x4A0, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Middle Highlight Color[2]", 0x4E0, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Middle Shadow Color[2]", 0x520, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Background Highlight Color[2]", 0x560, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Background Shadow Color[2]", 0x5A0, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Cloud Speed[2]", 0x418, ParameterType.VECTOR2), + newParameter("Sky Base Cloud Alpha[2]", 0x430, ParameterType.FLOAT), + newParameter("Sky Base Sun Cloud Highlight Color[3]", 0x470, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Sun Cloud Shadow Color[3]", 0x4B0, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Middle Highlight Color[3]", 0x4F0, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Middle Shadow Color[3]", 0x530, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Background Highlight Color[3]", 0x570, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Background Shadow Color[3]", 0x5B0, ParameterType.COLOR_FACTOR), + newParameter("Sky Base Cloud Speed[3]", 0x420, ParameterType.VECTOR2), + newParameter("Sky Base Cloud Alpha[3]", 0x434, ParameterType.FLOAT), + newParameter("Sky Blend Base Map Factor", 0x5C0, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Side Cloud UV Offset", 0x5D0, ParameterType.FLOAT), + newParameter("Sky Blend Top Cloud0 UV Offset", 0x5D8, ParameterType.FLOAT), + newParameter("Sky Blend Top Cloud1 UV Offset", 0x5E0, ParameterType.FLOAT), + newParameter("Sky Blend Sun Cloud Highlight Color[0]", 0x620, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Sun Cloud Shadow Color[0]", 0x660, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Middle Highlight Color[0]", 0x6A0, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Middle Shadow Color[0]", 0x6E0, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Background Highlight Color[0]", 0x720, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Background Shadow Color[0]", 0x760, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Cloud Speed[0]", 0x5E8, ParameterType.VECTOR2), + newParameter("Sky Blend Cloud Alpha[0]", 0x608, ParameterType.FLOAT), + newParameter("Sky Blend Sun Cloud Highlight Color[1]", 0x630, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Sun Cloud Shadow Color[1]", 0x670, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Middle Highlight Color[1]", 0x6B0, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Middle Shadow Color[1]", 0x6F0, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Background Highlight Color[1]", 0x730, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Background Shadow Color[1]", 0x770, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Cloud Speed[1]", 0x5F0, ParameterType.VECTOR2), + newParameter("Sky Blend Cloud Alpha[1]", 0x60C, ParameterType.FLOAT), + newParameter("Sky Blend Sun Cloud Highlight Color[2]", 0x640, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Sun Cloud Shadow Color[2]", 0x680, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Middle Highlight Color[2]", 0x6C0, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Middle Shadow Color[2]", 0x700, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Background Highlight Color[2]", 0x740, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Background Shadow Color[2]", 0x780, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Cloud Speed[2]", 0x5F8, ParameterType.VECTOR2), + newParameter("Sky Blend Cloud Alpha[2]", 0x610, ParameterType.FLOAT), + newParameter("Sky Blend Sun Cloud Highlight Color[3]", 0x650, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Sun Cloud Shadow Color[3]", 0x690, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Middle Highlight Color[3]", 0x6D0, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Middle Shadow Color[3]", 0x710, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Background Highlight Color[3]", 0x750, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Background Shadow Color[3]", 0x790, ParameterType.COLOR_FACTOR), + newParameter("Sky Blend Cloud Speed[3]", 0x600, ParameterType.VECTOR2), + newParameter("Sky Blend Cloud Alpha[3]", 0x614, ParameterType.FLOAT), + newParameter("Sky Starry Sky Map Factor", 0x290, ParameterType.COLOR_FACTOR, pStep(0.001f)), + }; + + private delegate nint CreateFogObject(); + private delegate nint CreateFogObject2(nint unknownPtr); + private delegate nint DestroyFogObject(nint fogObjectInternal, int unknownInt); + private Hook? createFogObject; + private Hook? createFogObject2; + private Hook? destroyFogObject; + private delegate void UpdateFogParams(nint unknownPtr, int unknownInt); + private Hook? updateFogParams; + private nint fogObject = 0x0; + private static Parameter[] fogParameters = { + newParameter("Fog Mip Fog Intensity", 0x2C0, ParameterType.FLOAT, pStep(0.001f)), + newParameter("Fog Mip Fog Color", 0x330, ParameterType.COLOR_FACTOR, pStep(0.001f)) + }; + + private delegate nint CreateWaterWaveObject(nint unknownPtr); + private delegate nint DestroyWaterWaveObject(nint waterWaveObjectInternal, int unknownInt); + private Hook? createWaterWaveObject; + private Hook? destroyWaterWaveObject; + private nint waterWaveObject = 0x0; + private static Parameter[] waterWaveParameters = { + newParameter("Water Murkiness", 0x40C, ParameterType.FLOAT), + newParameter("Water Color", 0x404, ParameterType.COLOR), + newParameter("Water Scattering Intensity", 0x408, ParameterType.FLOAT, pStep(0.001f)) + }; + private delegate nint CreateFXAAObject(); private delegate nint CreateFXAAObject2(nint unknownPtr); private delegate nint DestroyFXAAObject(nint fxaaObjectInternal, int unknownInt); @@ -1741,9 +2017,13 @@ namespace WorldTuningTool .Concat(passthroughParameters) .Concat(lightingParameters) .Concat(brightnessParameters) + .Concat(sLightProbesParameters) .Concat(bloomParameters) .Concat(dofParameters) .Concat(motionBlurParameters) + .Concat(simpleSkyParameters) + .Concat(fogParameters) + .Concat(waterWaveParameters) .Concat(fxaaParameters) .Concat(taaParameters) .ToArray(); @@ -2087,6 +2367,18 @@ namespace WorldTuningTool destroyMotionBlurObject = Hook.Create(0x1424C97E0, DestroyMotionBlurObjectHook); // nint, int updateMotionBlurParams = Hook.Create(0x1424CADF0, UpdateMotionBlurParamsHook); // nint, nint + createSimpleSkyObject = Hook.Create(0x141FCCC20, CreateSimpleSkyObjectHook); // nint + destroySimpleSkyObject = Hook.Create(0x141FCD840, DestroySimpleSkyObjectHook); // nint, int + renderSimpleSky = Hook.Create(0x141FD58E0, RenderSimpleSkyHook); // nint, nint + + createFogObject = Hook.Create(0x141FADB50, CreateFogObjectHook); + createFogObject2 = Hook.Create(0x141FADC80, CreateFogObject2Hook); // nint + destroyFogObject = Hook.Create(0x141FADD50, DestroyFogObjectHook); // nint, int + updateFogParams = Hook.Create(0x1416D8F00, UpdateFogParamsHook); // nint, int + + createWaterWaveObject = Hook.Create(0x1423F0850, CreateWaterWaveObjectHook); // nint + destroyWaterWaveObject = Hook.Create(0x1423F0EE0, DestroyWaterWaveObjectHook); // nint, int + createFXAAObject = Hook.Create(0x142393560, CreateFXAAObjectHook); createFXAAObject2 = Hook.Create(0x142393680, CreateFXAAObject2Hook); // nint destroyFXAAObject = Hook.Create(0x142393740, DestroyFXAAObjectHook); // nint, int @@ -2483,7 +2775,7 @@ namespace WorldTuningTool } } - foreach (Parameter param in lightProbesParameters) + foreach (Parameter param in sLightProbesParameters) { param.Update(sLightProbes!.Instance); } @@ -2538,13 +2830,21 @@ namespace WorldTuningTool param.Update(taaObject); } } + + if (waterWaveObject != 0x0) + { + foreach (Parameter param in waterWaveParameters) + { + param.Update(waterWaveObject); + } + } } private void EvalSceneParamsHook(nint unknownPtr, nint unknownPtr2, int unknownInt, nint unknownPtr3) { foreach (Parameter param in broadAreaShadowParameters) { - param.Update(sMhScene!.Instance); + param.Update(sMhScene!.Instance, true); } evalSceneParams!.Original(unknownPtr, unknownPtr2, unknownInt, unknownPtr3); } @@ -2554,7 +2854,7 @@ namespace WorldTuningTool updateCapsuleAoParams!.Original(sceneObjectInternal); foreach (Parameter param in capsuleLightParameters) { - param.Update(sMhScene!.Instance); + param.Update(sMhScene!.Instance, true); } } @@ -2563,7 +2863,7 @@ namespace WorldTuningTool updateSSAOParams!.Original(stackOffset); foreach (Parameter param in ssaoParameters) { - param.Update(sMhScene!.Instance); + param.Update(sMhScene!.Instance, true); } } @@ -2572,7 +2872,7 @@ namespace WorldTuningTool updateSSLRParams!.Original(stackOffset); foreach (Parameter param in sslrParameters) { - param.Update(sMhScene!.Instance); + param.Update(sMhScene!.Instance, true); } } @@ -2583,7 +2883,7 @@ namespace WorldTuningTool { foreach (Parameter param in lightingParameters) { - param.Update(lightingObject); + param.Update(lightingObject, true); } } } @@ -2621,7 +2921,7 @@ namespace WorldTuningTool { if (param.PerFrame) { - param.Update(lightingObject); + param.Update(lightingObject, true); } } } @@ -2702,7 +3002,7 @@ namespace WorldTuningTool { if (param.PerFrame) { - param.Update(dofObject); + param.Update(dofObject, true); } } } @@ -2747,12 +3047,112 @@ namespace WorldTuningTool { if (param.PerFrame) { - param.Update(motionBlurObject); + param.Update(motionBlurObject, true); } } updateMotionBlurParams!.Original(unknownPtr, unknownPtr2); } + private nint CreateSimpleSkyObjectHook(nint unknownPtr) + { + simpleSkyObject = createSimpleSkyObject!.Original(unknownPtr); + foreach (Parameter param in simpleSkyParameters) + { + param.Update(simpleSkyObject); + } + return simpleSkyObject; + } + + private nint DestroySimpleSkyObjectHook(nint simpleSkyObjectInternal, int unknownInt) + { + Assert(unknownInt == 1); + if (simpleSkyObjectInternal == simpleSkyObject) + { + simpleSkyObject = 0x0; + foreach (Parameter param in simpleSkyParameters) + { + param.Update(simpleSkyObject); + } + } + return destroySimpleSkyObject!.Original(simpleSkyObjectInternal, unknownInt); + } + + private void RenderSimpleSkyHook(nint simpleSkyObjectInternal, nint unknownPtr) + { + foreach (Parameter param in simpleSkyParameters) + { + param.Update(simpleSkyObject, true); + } + renderSimpleSky!.Original(simpleSkyObjectInternal, unknownPtr); + } + + private nint CreateFogObjectHook() + { + fogObject = createFogObject!.Original(); + foreach (Parameter param in fogParameters) + { + param.Update(fogObject); + } + return fogObject; + } + + private nint CreateFogObject2Hook(nint unknownPtr) + { + fogObject = createFogObject2!.Original(unknownPtr); + foreach (Parameter param in fogParameters) + { + param.Update(fogObject); + } + return fogObject; + } + + private nint DestroyFogObjectHook(nint fogObjectInternal, int unknownInt) + { + Assert(unknownInt == 1); + if (fogObject == fogObjectInternal) + { + fogObject = 0x0; + foreach (Parameter param in fogParameters) + { + param.Update(fogObject); + } + } + return destroyFogObject!.Original(fogObjectInternal, unknownInt); + } + + private void UpdateFogParamsHook(nint unknownPtr, int unknownInt) + { + updateFogParams!.Original(unknownPtr, unknownInt); + foreach (Parameter param in fogParameters) + { + param.Update(fogObject, true); + } + } + + private nint CreateWaterWaveObjectHook(nint unknownPtr) + { + waterWaveObject = createWaterWaveObject!.Original(unknownPtr); + foreach (Parameter param in waterWaveParameters) + { + param.Update(waterWaveObject); + } + return waterWaveObject; + } + + private nint DestroyWaterWaveObjectHook(nint waterWaveObjectInternal, int unknownInt) + { + Assert(unknownInt == 1); + if (waterWaveObjectInternal == waterWaveObject) + { + waterWaveObject = 0x0; + foreach (Parameter param in waterWaveParameters) + { + param.Update(waterWaveObject); + } + } + return destroyWaterWaveObject!.Original(waterWaveObjectInternal, unknownInt); + } + private nint CreateFXAAObjectHook() { fxaaObject = createFXAAObject!.Original(); @@ -2830,7 +3230,7 @@ namespace WorldTuningTool { if (param.PerFrame) { - param.Update(stackOffset); + param.Update(stackOffset, true); } } } @@ -2846,7 +3246,7 @@ namespace WorldTuningTool { if (param.PerFrame) { - param.Update(shadowParamsStatic); + param.Update(shadowParamsStatic, true); } } } @@ -2856,7 +3256,7 @@ namespace WorldTuningTool { if (!param.PerFrame) { - param.Update(shadowObjectInternal); + param.Update(shadowObjectInternal, true); } } } @@ -3633,7 +4033,7 @@ namespace WorldTuningTool } ImGui.Separator(); ImGui.Text($"Address: 0x{sLightProbes!.Instance:X}"); - foreach (Parameter param in lightProbesParameters) + foreach (Parameter param in sLightProbesParameters) { param.Draw(width); } @@ -3682,6 +4082,48 @@ namespace WorldTuningTool } ImGui.PopID(); + ImGui.PushID("Sky"); + if (ImGui.CollapsingHeader("Sky")) + { + ImGui.Text($"Address: 0x{simpleSkyObject:X}"); + if (simpleSkyObject != 0x0) + { + foreach (Parameter param in simpleSkyParameters) + { + param.Draw(width); + } + } + } + ImGui.PopID(); + + ImGui.PushID("Fog"); + if (ImGui.CollapsingHeader("Fog")) + { + ImGui.Text($"Address: 0x{fogObject:X}"); + if (fogObject != 0x0) + { + foreach (Parameter param in fogParameters) + { + param.Draw(width); + } + } + } + ImGui.PopID(); + + ImGui.PushID("Water"); + if (ImGui.CollapsingHeader("Water")) + { + ImGui.Text($"Address: 0x{waterWaveObject:X}"); + if (waterWaveObject != 0x0) + { + foreach (Parameter param in waterWaveParameters) + { + param.Draw(width); + } + } + } + ImGui.PopID(); + ImGui.PushID("FXAA"); if (ImGui.CollapsingHeader("FXAA")) { -- cgit v1.2.3-101-g0448