summaryrefslogtreecommitdiff
path: root/Plugin.cs
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2026-05-19 19:30:13 -0400
committerAndrew Opalach <andrew@akon.city> 2026-05-19 19:30:13 -0400
commit3ff2dff147b24d9c64d92609f866a2fcd7b6b197 (patch)
tree6f9cc1a26b01e40e428cd873b172d81815728620 /Plugin.cs
parent4f31c9e16b58eeb1e914d58a4e92b8adc6529450 (diff)
downloadWorldTuningTool-3ff2dff147b24d9c64d92609f866a2fcd7b6b197.tar.gz
WorldTuningTool-3ff2dff147b24d9c64d92609f866a2fcd7b6b197.tar.bz2
WorldTuningTool-3ff2dff147b24d9c64d92609f866a2fcd7b6b197.zip
Add preset function, improve restore button logic
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'Plugin.cs')
-rwxr-xr-xPlugin.cs882
1 files changed, 605 insertions, 277 deletions
diff --git a/Plugin.cs b/Plugin.cs
index 30d9a88..15ba88b 100755
--- a/Plugin.cs
+++ b/Plugin.cs
@@ -1,12 +1,11 @@
-//#define ENABLE_ASSERTS
-//#define ADDR_ASSERTS
-//#define SHADER_FEATURES
+#define ENABLE_ASSERTS
+#define SHADER_FEATURES
using System.Numerics;
-using System.Reflection;
-using System.Diagnostics;
-using System.Runtime.Loader;
using System.Runtime.InteropServices;
+#if ENABLE_ASSERTS
+using System.Diagnostics;
+#endif
using ImGuiNET;
using SharpPluginLoader.Core;
@@ -16,23 +15,63 @@ using SharpPluginLoader.Core.Memory;
using SharpPluginLoader.Core.Entities;
// @TODO:
+// - Remove all parameters deemed mostly useless and/or unsafe.
+// - SPL Patches:
+// - Dialoge fix.
+// - No crash on empty config.
+// - Style change
+// - Optimized update logic.
+// - Only update non-override values when ui is shown.
+// - Tune parameter settings (step, min/max, format, etc).
+// - PerFrame.
+// - Create light hook.
// - Inter-op.
// - Lights.
-// - float format.
-// - Override presets.
-// - Centeralize transition from global to stage.
// - Try to understand shadow distance vs backforward distance vs bias.
-// - Re-evaluate volume upsample shaders.
-// - Guiding lands?
// - Shadow distance retuning.
// - Weird shadow area in Rotten Vale.
+// - float format.
// - Descriptions.
+//
+// Known issues to think about:
+// - Volume rendering can look really bad with multiple sources(?) (Guding lands vines).
+// - Screen space reflections often look bad.
+// - Facial contact shadows incorrectly move based on camera position.
namespace WorldTuningTool
{
- public unsafe class Plugin : IPlugin
+ public class Interop
{
- public string Name => "World Tuning Tool";
+ public static string PluginName = "World Tuning Tool";
+ private static dynamic? Instance = null;
+
+ public bool InitFromLoadedInstance()
+ {
+ Instance = IPlugin.GetInstance(Plugin.PluginName);
+ return Instance != null;
+ }
+
+ public virtual int AddOverride(string name, Vector4 v4, int i1)
+ {
+ if (Instance != null)
+ {
+ return Instance.AddOverride(name, v4, i1);
+ }
+ return 0;
+ }
+
+ public virtual void RemoveOverride(int id)
+ {
+ if (Instance != null)
+ {
+ Instance.RemoveOverride(id);
+ }
+ }
+ }
+
+ public unsafe class Plugin : Interop, IPlugin
+ {
+ public string Name => PluginName;
public string Author => "Akon City Software";
private static void Assert(bool condition)
@@ -84,11 +123,59 @@ namespace WorldTuningTool
private const float defaultParamWidth = 0.215f;
- private static Stage selectedStage = Stage.InfinityOfNothingHandler;
+ private const Stage globalStage = Stage.InfinityOfNothingHandler;
+ private static Stage currentStage => Area.CurrentStage;
+ private static Stage selectedStage = globalStage;
private static Stage previousStage = selectedStage;
- private static bool stageIsGlobal(Stage stage)
+
+ private List<Override>? maybeGetStageOverrides(Config config)
+ {
+ return currentStage != 0 ? config.Overrides[currentStage] : null;
+ }
+
+ private static string selectedPreset = "";
+ private static bool renamingPreset = false;
+ private static string typedPresetName = "";
+
+ private static Dictionary<int, Override> externalOverrides = new Dictionary<int, Override>();
+ private static int externalId = 0;
+
+ private static bool overridesContainsParam(IEnumerable<Override> overrides, Parameter param)
{
- return stage == Stage.InfinityOfNothingHandler;
+ foreach (Override ov in overrides)
+ {
+ if (ov.Param == param)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static bool unsetIfOverridesContainsParam(IEnumerable<Override> overrides, Parameter param)
+ {
+ foreach (Override ov in overrides)
+ {
+ if (ov.Param == param)
+ {
+ ov.Unset();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static bool setIfOverridesContainsParam(IEnumerable<Override> overrides, Parameter param)
+ {
+ foreach (Override ov in overrides)
+ {
+ if (ov.Param == param)
+ {
+ ov.Set();
+ return true;
+ }
+ }
+ return false;
}
public abstract class Parameter
@@ -263,18 +350,18 @@ namespace WorldTuningTool
overrideForStage = false;
}
- public void OverrideValue(Vector4 v, int i)
+ public void OverrideValue(Vector4 v4, int i1)
{
if (queuedOverride)
{
- qValueV = v;
- qValueInt = i;
+ qValueV = v4;
+ qValueInt = i1;
queuedValue = true;
}
else
{
- valueV = v;
- valueInt = i;
+ valueV = v4;
+ valueInt = i1;
if (!PerFrame)
{
writeCurrentValue();
@@ -510,13 +597,11 @@ namespace WorldTuningTool
{
ImGui.SetNextItemWidth(width * defaultParamWidth);
float f1 = v4.X;
+ // Ideally we want ImGuiInputTextFlags.EnterReturnsTrue behavior here.
if (ImGui.DragFloat(label, ref f1, stepf, minf, maxf, "%.5f", ImGuiSliderFlags.NoRoundToFormat))
{
- //if (ImGui.IsItemDeactivatedAfterEdit())
- //{
- v4.X = f1;
- valueChanged = true;
- //}
+ v4.X = f1;
+ valueChanged = true;
}
break;
}
@@ -557,6 +642,60 @@ namespace WorldTuningTool
return valueChanged;
}
+ public void DrawReferenceValue(string name, Vector4 v4, int i1)
+ {
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.7f);
+ switch (Type)
+ {
+ case ParameterType.BOOL:
+ {
+ ImGui.Text($"({name}: {i1 == 0x1})");
+ break;
+ }
+ case ParameterType.BYTE:
+ {
+ ImGui.Text($"({name}: {i1})");
+ break;
+ }
+ case ParameterType.FLAG:
+ {
+ ImGui.Text($"({name}: {i1 != 0})");
+ break;
+ }
+ case ParameterType.INT:
+ case ParameterType.HEX:
+ case ParameterType.COLOR:
+ {
+ if (Type == ParameterType.INT)
+ {
+ ImGui.Text($"({name}: {i1})");
+ }
+ else
+ {
+ ImGui.Text($"({name}: {i1:X})");
+ }
+ break;
+ }
+ case ParameterType.FLOAT:
+ case ParameterType.PATCH_FLOAT:
+ {
+ ImGui.Text($"({name}: {v4.X:0.00000})");
+ break;
+ }
+ case ParameterType.VECTOR3:
+ {
+ ImGui.Text($"({name}: {v4.X:0.0000}, {v4.Y:0.0000}, {v4.Z:0.0000})");
+ break;
+ }
+ case ParameterType.VECTOR4:
+ {
+ ImGui.Text($"({name}: {v4.X:0.0000}, {v4.Y:0.0000}, {v4.Z:0.0000}, {v4.W:0.00000})");
+ break;
+ }
+ }
+ ImGui.PopStyleVar();
+ }
+
public void Draw(float width, bool assumeOverride = false)
{
Draw(ref valueV, ref valueInt, width, assumeOverride);
@@ -588,11 +727,11 @@ namespace WorldTuningTool
{
if (overrideForStage)
{
- ImGui.Text("Set by Config/Preset");
+ ImGui.Text("Set by an Override");
}
else
{
- ImGui.Text("Override Value");
+ ImGui.Text("Override");
}
ImGui.EndTooltip();
}
@@ -611,20 +750,30 @@ namespace WorldTuningTool
{
writeCurrentValue();
}
- if (!assumeOverride && overrideValue && !overrideForStage)
+ Config config = getConfig();
+ List<Override> selectedOverrides = config.Overrides[selectedStage];
+ if (!assumeOverride && overrideValue && !overridesContainsParam(selectedOverrides, this))
{
ImGui.SameLine();
if (ImGui.Button("▲"))
{
- Config config = getConfig();
- List<Override> stageOverrides = config.Overrides[selectedStage];
+ // Create override before unsetting global.
Override ov = new Override(this, v4, i1);
- ov.Set();
- stageOverrides.Add(ov);
+ if (selectedStage != globalStage)
+ {
+ unsetIfOverridesContainsParam(config.Overrides[globalStage], this);
+ }
+ bool superseded = selectedPreset != "" && overridesContainsParam(config.Presets[selectedPreset], this);
+ superseded |= overridesContainsParam(externalOverrides.Values, this);
+ if (!superseded)
+ {
+ ov.Set();
+ }
+ selectedOverrides.Add(ov);
}
if (ImGui.BeginItemTooltip())
{
- ImGui.Text("Add to Selected Stage");
+ ImGui.Text($"Add to {Config.StageToString(selectedStage)}");
ImGui.EndTooltip();
}
}
@@ -660,58 +809,7 @@ namespace WorldTuningTool
}
}
ImGui.SameLine();
- ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.7f);
- switch (Type)
- {
- case ParameterType.BOOL:
- {
- ImGui.Text($"(Original: {oValueInt == 0x1})");
- break;
- }
- case ParameterType.BYTE:
- {
- ImGui.Text($"(Original: {oValueInt})");
- break;
- }
- case ParameterType.FLAG:
- {
- ImGui.Text($"(Original: {oValueInt != 0})");
- break;
- }
- case ParameterType.INT:
- case ParameterType.HEX:
- case ParameterType.COLOR:
- {
- if (Type == ParameterType.INT)
- {
- ImGui.Text($"(Original: {oValueInt})");
- }
- else
- {
- ImGui.Text($"(Original: {oValueInt:X})");
- }
- break;
- }
- case ParameterType.FLOAT:
- case ParameterType.PATCH_FLOAT:
- {
- ImGui.Text($"(Original: {oValueV.X:0.00000})");
- break;
- }
- case ParameterType.VECTOR3:
- {
- ImGui.Text($"(Original: {oValueV.X:0.0000}, {oValueV.Y:0.0000}, {oValueV.Z:0.0000})");
- break;
- }
- case ParameterType.VECTOR4:
- {
- ImGui.Text($"(Original: {oValueV.X:0.0000}, {oValueV.Y:0.0000}, {oValueV.Z:0.0000}, {oValueV.W:0.00000})");
- break;
- }
- }
- //ImGui.SameLine();
- //ImGui.Text($"(Address: {lastAddr:X})");
- ImGui.PopStyleVar();
+ DrawReferenceValue("Original", oValueV, oValueInt);
}
if (!overrideValue)
{
@@ -730,6 +828,10 @@ namespace WorldTuningTool
this.stepf = step != null ? Convert.ToSingle(step) : 0.01f;
this.minf = Convert.ToSingle(min);
this.maxf = Convert.ToSingle(max);
+ if (type == ParameterType.FLOAT && this.minf == 0.0f && this.maxf == 0.0f)
+ {
+ this.maxf = Single.MaxValue;
+ }
}
else if (typeof(T) == typeof(int) || typeof(T) == typeof(byte))
{
@@ -746,42 +848,6 @@ namespace WorldTuningTool
}
}
- private static bool overridesContainsParam(List<Override> overrides, Parameter param)
- {
- foreach (Override ov in overrides)
- {
- if (ov.Param == param)
- {
- return true;
- }
- }
- return false;
- }
-
- private static void unsetIfOverridesContainsParam(List<Override> overrides, Parameter param)
- {
- foreach (Override ov in overrides)
- {
- if (ov.Param == param)
- {
- ov.Unset();
- break;
- }
- }
- }
-
- private static void setIfOverridesContainsParam(List<Override> overrides, Parameter param)
- {
- foreach (Override ov in overrides)
- {
- if (ov.Param == param)
- {
- ov.Set();
- break;
- }
- }
- }
-
private static Parameter? getParameterByName(string name)
{
foreach (Parameter param in allParameters)
@@ -873,6 +939,8 @@ namespace WorldTuningTool
case ParameterType.VECTOR4:
break;
}
+ sValueV = valueV;
+ sValueInt = valueInt;
}
catch (FormatException)
{
@@ -885,6 +953,8 @@ namespace WorldTuningTool
private Vector4 valueV = default;
private int valueInt = 0;
private bool isSet = false;
+ private Vector4 sValueV = default;
+ private int sValueInt = 0;
public Override() { }
@@ -893,6 +963,14 @@ namespace WorldTuningTool
Param = param;
valueV = v4;
valueInt = i1;
+ sValueV = v4;
+ sValueInt = i1;
+ }
+
+ public void Save()
+ {
+ sValueV = valueV;
+ sValueInt = valueInt;
}
public void Set()
@@ -916,42 +994,57 @@ namespace WorldTuningTool
}
}
- public void Draw(List<Override>? currentOverrides, List<Override>? globalOverrides, float width)
+ public void Draw(List<Override>? currentOverrides, List<Override>? stageOverrides, List<Override>? globalOverrides, bool superseded, float width)
{
- if (currentOverrides == null)
+ if (currentOverrides == null || superseded)
{
ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
}
+ if (superseded) // superseded == !isSet, superseded is more clear in the context of drawing.
+ {
+ Assert(!isSet);
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ }
ImGui.PushItemWidth(width * 0.475f);
if (ImGui.BeginCombo("##Parameters", Param != null ? Param.Name : ""))
{
if (currentOverrides != null)
{
- foreach (Parameter param in allParameters)
+ foreach (Parameter iterParam in allParameters)
{
- if (overridesContainsParam(currentOverrides, param))
- {
- continue;
- }
- bool isSelected = Param == param;
- if (ImGui.Selectable(param.Name, isSelected))
+ if (overridesContainsParam(currentOverrides, iterParam)) continue;
+ bool isSelected = Param == iterParam;
+ if (ImGui.Selectable(iterParam.Name, isSelected))
{
bool wasSet = isSet;
if (wasSet)
{
Unset();
- if (globalOverrides != null)
+ if (Param != null)
+ {
+ if (!(stageOverrides != null && setIfOverridesContainsParam(stageOverrides, Param)))
+ {
+ if (globalOverrides != null)
+ {
+ setIfOverridesContainsParam(globalOverrides, Param);
+ }
+ }
+ }
+ if (!(stageOverrides != null && unsetIfOverridesContainsParam(stageOverrides, iterParam)))
{
- if (Param != null)
+ if (globalOverrides != null)
{
- setIfOverridesContainsParam(globalOverrides, Param);
+ unsetIfOverridesContainsParam(globalOverrides, iterParam);
}
- unsetIfOverridesContainsParam(globalOverrides, param);
}
}
- Param = param;
+ Param = iterParam;
(valueV, valueInt) = Param.GetValue();
- if (wasSet) Set();
+ // If this override is superseded, expect this Combo to be disabled.
+ if (wasSet)
+ {
+ Set();
+ }
}
if (isSelected) ImGui.SetItemDefaultFocus();
}
@@ -959,25 +1052,53 @@ namespace WorldTuningTool
ImGui.EndCombo();
}
ImGui.PopItemWidth();
- if (currentOverrides == null)
+ if (superseded)
+ {
+ ImGui.PopStyleVar();
+ }
+ if (currentOverrides == null || superseded)
{
ImGui.PopItemFlag();
}
if (Param != null)
{
ImGui.SameLine();
- if (Param.DrawValue(ref valueV, ref valueInt, width, false) && isSet)
+ if (Param.DrawValue(ref valueV, ref valueInt, width, false) && !superseded)
{
Param.OverrideValue(valueV, valueInt);
}
- if (isSet && !Param.PendingUpdate() && (valueV, valueInt) != Param.GetValue())
+ (Vector4 v4, int i1) = Param.GetValue();
+ bool valueDiffers = (v4, i1) != (valueV, valueInt);
+ if ((valueV, valueInt) != (sValueV, sValueInt) || (valueDiffers && !Param.PendingUpdate() && !superseded))
+ {
+ ImGui.SameLine();
+ if (ImGui.Button("⇄"))
+ {
+ valueV = sValueV;
+ valueInt = sValueInt;
+ if (!superseded)
+ {
+ Param.OverrideValue(valueV, valueInt);
+ }
+ }
+ }
+ if (Param.PendingUpdate())
{
ImGui.SameLine();
- if (ImGui.Button("Restore"))
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.7f);
+ ImGui.Text("(Pending)");
+ ImGui.PopStyleVar();
+ if (ImGui.BeginItemTooltip())
{
- Param.OverrideValue(valueV, valueInt);
+ ImGui.Text("The object this parameter belongs to has no current object");
+ ImGui.EndTooltip();
}
}
+ else if (valueDiffers || superseded)
+ {
+ ImGui.SameLine();
+ Param.DrawReferenceValue("Current", v4, i1);
+ }
}
}
}
@@ -1046,17 +1167,6 @@ namespace WorldTuningTool
new Parameter<float>("LOD Culling Length Bias", 0x224, ParameterType.FLOAT, false),
new Parameter<float>("LOD Culling Pixel Bias", 0x228, ParameterType.FLOAT, false),
new Parameter<byte>("Is Calc LOD Bias Use Boundary", 0x218, ParameterType.BOOL, false),
- /*
- new Parameter<int>("Debug View", 0x264, ParameterType.INT, false, 1),
- new Parameter<int>("Debug View Channel", 0x268, ParameterType.INT, false, 1),
- new Parameter<float>("Debug View Bg Alpha", 0x26C, ParameterType.FLOAT, false),
- new Parameter<float>("Debug View Fg Alpha", 0x270, ParameterType.FLOAT, false),
- new Parameter<int>("Debug Texture", 0x274, ParameterType.INT, false, 1),
- new Parameter<int>("Debug Sampler", 0x278, ParameterType.INT, false, 1),
- new Parameter<int>("Debug Cluster", 0x27C, ParameterType.INT, false, 1),
- new Parameter<int>("Debug Light Max Count", 0x280, ParameterType.INT, false, 1),
- new Parameter<byte>("Wireframe", 0x284, ParameterType.BOOL, false),
- */
new Parameter<byte>("Material Draw SS Normal", 0x5626, ParameterType.BOOL, false),
new Parameter<float>("Material Height Factor", 0x5628, ParameterType.FLOAT, false),
new Parameter<int>("Model Detail", 0x190, ParameterType.INT, false, 1),
@@ -1086,7 +1196,6 @@ namespace WorldTuningTool
new Parameter<byte>("Force Disable Capsule AO", 0xB503, ParameterType.BOOL, false),
new Parameter<float>("Capsule AO Distance Fall Coef", 0xE5B4, ParameterType.FLOAT, false),
new Parameter<int>("Capsule AO Light Channel Mask", 0xE5BC, ParameterType.INT, false),
- //new Parameter<float>("Capsule AO Null Parent Matrix", 0xE570, ParameterType.FLOAT, false),
new Parameter<float>("Capsule Light Dir XZY", 0xE548, ParameterType.VECTOR3, false),
new Parameter<float>("Capsule Light W Dir", 0xE560, ParameterType.FLOAT, false),
new Parameter<float>("Capsule Light Angle", 0xE5B0, ParameterType.FLOAT, false),
@@ -1096,9 +1205,6 @@ namespace WorldTuningTool
new Parameter<float>("Broad Area Shadow Center", 0x5540, ParameterType.VECTOR3, false),
new Parameter<float>("Broad Area Shadow Range", 0x5560, ParameterType.VECTOR3, false),
new Parameter<float>("Broad Area Shadow Dir", 0x5550, ParameterType.VECTOR4, false),
- //new Parameter<float>("Broad Area Shadow Depth Bias", 0x5570, ParameterType.FLOAT, false, 0.00001f),
- //new Parameter<float>("Broad Area Shadow Sloped Depth Bias", 0x5574, ParameterType.FLOAT, false, 0.00001f),
- //new Parameter<float>("Broad Area Shadow Max Depth Bias", 0x5578, ParameterType.FLOAT, false, 0.00001f),
new Parameter<float>("Broad Area Shadow Max LOD Level", 0x5524, ParameterType.FLOAT, false),
new Parameter<float>("Broad Area Shadow Culling Size", 0x5528, ParameterType.FLOAT, false),
new Parameter<int>("Broad Area Shadow Precision", 0x5518, ParameterType.INT, false, 1, 0, 2), // Maybe 3?
@@ -1158,7 +1264,6 @@ namespace WorldTuningTool
new Parameter<float>("Vignetting Offset", 0x1F8, ParameterType.FLOAT, true),
new Parameter<float>("Vignetting Pow", 0x1FC, ParameterType.FLOAT, true),
new Parameter<int>("Vignetting Color", 0x208, ParameterType.COLOR, true),
- //new Parameter<int>("Target Joint No", 0x240, ParameterType.INT, true, 1),
};
private delegate nint CreateMotionBlurObject();
@@ -1202,27 +1307,13 @@ namespace WorldTuningTool
private static MtObject? sLightProbes = null;
private static Parameter[] lightProbesParameters = {
- //new Parameter<byte>("Enable Neighbor Search", 0x40, ParameterType.BOOL, false),
- //new Parameter<int>("WF Count", 0x90, ParameterType.INT, false, 1),
- //new Parameter<int>("CU Mask", 0x94, ParameterType.HEX, false),
new Parameter<int>("Debug Mode", 0x98, ParameterType.INT, false, 1),
- //new Parameter<int>("Daytime State", 0x9C, ParameterType.INT, true, 1),
- //new Parameter<float>("Daytime Interpolation", 0xA0, ParameterType.FLOAT, false),
- //new Parameter<int>("Max Iter", 0xA4, ParameterType.INT, true, 1)
};
private delegate nint CreateLightingObject();
private delegate nint DestroyLightingObject(nint lightingObjectInternal, int unknownInt);
private Hook<CreateLightingObject>? createLightingObject;
private Hook<DestroyLightingObject>? destroyLightingObject;
private nint lightingObject = 0x0;
- /*
- Compute Luminance (bool) +0x170
- Luminance Version (int) +0x168
- LUT Blend (bool) +0x1C8
- Vfx LUT Blend (bool) +0x1D0
- Input Color Linear to PQ (bool) +0x1A1
- Output Color PQ to Linear (bool) +0x1A0
- */
private static Parameter[] lightingParameters = {
new Parameter<int>("Tone Map Type", 0x16C, ParameterType.INT, false, 1, 1, 7),
new Parameter<float>("Shoulder Strength", 0x168, ParameterType.FLOAT, false),
@@ -1233,7 +1324,7 @@ namespace WorldTuningTool
new Parameter<float>("White Point", 0x18C, ParameterType.FLOAT, false),
new Parameter<byte>("Enable Color Grading", 0x1D8, ParameterType.BOOL, false),
new Parameter<float>("Dispersion", 0x19C, ParameterType.FLOAT, false),
- new Parameter<float>("Edge Sharpness", 0x198, ParameterType.FLOAT, false),
+ new Parameter<float>("Edge Sharpness", 0x198, ParameterType.FLOAT, false, 0.00001f),
new Parameter<byte>("Downsample Volume", 0x210, ParameterType.BOOL, false)
};
@@ -1318,7 +1409,7 @@ namespace WorldTuningTool
private Patch shadowRes1_3;
private Patch shadowRes2;
private Patch shadowRes3;
- private Patch shadowRes4_Limit;
+ //private Patch shadowRes4_Limit;
private void tripleShadowResEnable()
{
@@ -1328,7 +1419,6 @@ namespace WorldTuningTool
shadowRes1_3.Enable();
shadowRes2.Enable();
shadowRes3.Enable();
- //shadowRes4_Limit.Enable();
}
private void tripleShadowResDisable()
@@ -1339,7 +1429,6 @@ namespace WorldTuningTool
shadowRes1_3.Disable();
shadowRes2.Disable();
shadowRes3.Disable();
- //shadowRes4_Limit.Disable();
}
private bool fullResVolumeBlur = false;
@@ -1482,18 +1571,24 @@ namespace WorldTuningTool
private delegate void UpdateLights(nint lightObject);
private Hook<UpdateLights>? updateLights;
- private Dictionary<int, Override> externalOverrides = new Dictionary<int, Override>();
- private int externalId = 0;
-
- public int AddOverride(string name, Vector4 v4, int i1)
+ public override int AddOverride(string name, Vector4 v4, int i1)
{
foreach (Parameter param in allParameters)
{
if (param.Name == name)
{
- externalId++;
Override ov = new Override(param, v4, i1);
+ Config config = getConfig();
+ if (!(selectedPreset != "" && unsetIfOverridesContainsParam(config.Presets[selectedPreset], param)))
+ {
+ List<Override>? stageOverrides = maybeGetStageOverrides(config);
+ if (!(stageOverrides != null && unsetIfOverridesContainsParam(stageOverrides, param)))
+ {
+ unsetIfOverridesContainsParam(config.Overrides[globalStage], param);
+ }
+ }
ov.Set();
+ externalId++;
externalOverrides.Add(externalId, ov);
return externalId;
}
@@ -1501,15 +1596,21 @@ namespace WorldTuningTool
return 0;
}
- public void RemoveOverride(int id)
+ public override void RemoveOverride(int id)
{
if (externalOverrides.ContainsKey(id))
{
- Config config = getConfig();
- List<Override> globalOverrides = config.Overrides[Stage.InfinityOfNothingHandler];
Override ovE = externalOverrides[id];
ovE.Unset();
- setIfOverridesContainsParam(globalOverrides, ovE.Param!);
+ Config config = getConfig();
+ if (!(selectedPreset != "" && setIfOverridesContainsParam(config.Presets[selectedPreset], ovE.Param!)))
+ {
+ List<Override>? stageOverrides = maybeGetStageOverrides(config);
+ if (!(stageOverrides != null && setIfOverridesContainsParam(stageOverrides, ovE.Param!)))
+ {
+ setIfOverridesContainsParam(config.Overrides[globalStage], ovE.Param!);
+ }
+ }
externalOverrides.Remove(id);
}
}
@@ -1546,41 +1647,33 @@ namespace WorldTuningTool
destroyLightingObject = Hook.Create<DestroyLightingObject>(0x1424CE380, DestroyLightingObjectHook); // nint, int
IntPtr addr = PatternScanner.FindFirst(Pattern.FromString("48 89 5C 24 10 48 89 74 24 18 48 89 7C 24 20 55 41 56 41 57 48 8B EC 48 83 EC 30 48 8B FA 48 8B D9 E8 AA B6 C1 FF 48 8B 47 10 48 8D 57 50"));
-#if ADDR_ASSERTS
Assert(addr == 0x141AB2260); // nint, nint
-#endif
updateShadowParams = Hook.Create<UpdateShadowParams>(addr, UpdateShadowParamsHook);
staticShadowParams = Hook.Create<UpdateShadowParams>(0x1416D94F0, StaticShadowParamsHook); // nint, nint
setShadowQuality = new NativeAction<int>(0x14043FF80);
addr = PatternScanner.FindFirst(Pattern.FromString("48 83 EC 28 F3 0F 10 0D ?? ?? ?? ?? 80 F9 04 75 2F 48 8B 0D ?? ?? ?? ?? E8 D3 8A E4 01 48 8B 0D ?? ?? ?? ?? 33 D2 E8 ?? ?? ?? ??"));
-#if ADDR_ASSERTS
Assert(addr == 0x14043FF80);
Assert(MemoryUtil.Read<float>(0x142E4FE5C) == 3.0f);
-#endif
shadowRes1_3x = new Patch(addr + 0x8, [0xD0, 0xFE, 0xA0, 0x02]); // 3.0.
shadowRes1_1 = new Patch(addr + 0x65, [0x17]); // Always set "Value is not 1.0" flag.
shadowRes1_2 = new Patch(addr + 0x68, [0x59]); // movss -> mulss.
shadowRes1_3 = new Patch(addr + 0x77, [0x59]); // movss -> mulss.
- // shadowRes2/3 control the detail of the infrequently updated fallback shadows.
+ // shadowRes2/3 control the detail of the infrequently updated fallback shadows (Broad Area).
addr = PatternScanner.FindFirst(Pattern.FromString("83 FA FF 74 06 89 91 1C 55 00 00 8B 91 30 55 00 00 83 FA FF 7F 06 8B 91 1C 55 00 00 85 D2 74 4B 83 EA 01 74 3B 83 EA 01 74 2B 83 EA 01 74 1B 83 FA 01 74 0B C7 81 20 55 00 00 01 00 00 00 C3 C7 81 20 55 00 00 00 10 00 00"));
-#if ADDR_ASSERTS
Assert(addr == 0x142287A50);
-#endif
shadowRes2 = new Patch(addr + 0x3F, [
0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
- 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3, // High.
- 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xC3, // Mid.
- 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xC3 // Low.
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3, // High (8192x8192).
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xC3, // Mid (6144x6144).
+ 0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xC3 // Low (4096x4096).
]);
addr = PatternScanner.FindFirst(Pattern.FromString("89 91 30 55 00 00 83 FA FF 7F 06 8B 91 1C 55 00 00 85 D2 74 4B 83 EA 01 74 3B 83 EA 01 74 2B 83 EA 01 74 1B 83 FA 01 74 0B C7 81 20 55 00 00 01 00 00 00 C3 C7 81 20 55 00 00 00 10 00 00"));
-#if ADDR_ASSERTS
Assert(addr == 0x142287AD0);
-#endif
shadowRes3 = new Patch(addr + 0x34, [
0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
0xC7, 0x81, 0x20, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC3,
@@ -1590,15 +1683,15 @@ namespace WorldTuningTool
]);
addr = PatternScanner.FindFirst(Pattern.FromString("89 91 00 55 00 00 83 FA 05 77 41 48 63 C2 4C 8D 05 ?? ?? ?? ?? 41 8B 94 80 84 8B 28 02 49 03 D0 FF E2 B8 00 08 00 00"));
-#if ADDR_ASSERTS
Assert(addr == 0x142288B00);
-#endif
// This value controls the shadow map texture resolution. 16384x16384 is likely the limit for many drivers
// and any value higher would crash. Keeping this at the default value (unpatched) *should* work unless the
// game does something unpredictable. At 3x Shadow Resolution + High, the shadow map will be 8448x8448.
+ /* Results in 16320x16320, not sure why not 16128.
shadowRes4_Limit = new Patch(addr + 0x29, [ // N/64 = 255, fractional values closer to 256 not tested.
0xB8, 0x40, 0x15, 0x00, 0x00, 0xEB, 0x21 // This case is used for Low, Medium and High in-game.
]);
+ */
// The volume blur filter is created at a different place in the code and happens at a different
// time (area change/createLightingObject() vs change of Volume Quality setting). It's also rendered
@@ -1633,23 +1726,17 @@ namespace WorldTuningTool
// Gameplay.
addr = PatternScanner.FindFirst(Pattern.FromString("80 BB 34 EC 00 00 00 88 8B 31 EC 00 00 C6 83 30 EC 00 00 00 74 1C C6 83 34 EC 00 00 00 48 8B 0D 68 4B 4F 03 80 B9 58 02 00 00 00 75 05 E8 5A F5 01 00 48 8B CB E8 E2 05 00 00 83 BB DC EB 00 00 06 74 0A C7 83 DC EB 00 00 06 00 00 00"));
-#if ADDR_ASSERTS
Assert(addr == 0x141B1A0B4);
-#endif
defaultViewModeLODLimit = new Patch(addr + 0x40, [0x07, 0x74, 0x0A, 0xC7, 0x83, 0xDC, 0xEB, 0x00, 0x00, 0x07]);
// In room.
addr = PatternScanner.FindFirst(Pattern.FromString("8B 9F CC 00 00 00 81 FB F9 01 00 00 74 0C 8B CB E8 95 3F 65 01 83 F8 05 75 11 48 8B 0D 61 C8 F6 04 BA 02 00 00 00 E8 DF 2D 8C 01 48 8B 0D A0 C7 F6 04 8B D3"));
-#if ADDR_ASSERTS
Assert(addr == 0x140257AE6);
-#endif
defaultViewModeLODLimit_1 = new Patch(addr + 0x22, [0x07]);
// Forging/Changing Equipment.
addr = PatternScanner.FindFirst(Pattern.FromString("BA 02 00 00 00 E8 6E C0 80 00 48 8B 74 24 38 48 8B 57 28 48 8D 4F 30 E8 4C 79 B4 FE 48 8B 0D 0D FF A6 03 BA 04 00 00 00 E8 8B 64 3C 00 48 8B 05 D4 01 A7 03 80 B8 FD 46 01 00 00"));
-#if ADDR_ASSERTS
Assert(addr == 0x141754438);
-#endif
defaultViewModeLODLimit_2 = new Patch(addr + 0x24, [0x07]);
// Unknown.
@@ -1659,9 +1746,7 @@ namespace WorldTuningTool
defaultViewModeLODLimit_4 = new Patch(new IntPtr(0x14128F1AC) + 0xF, [0x07]);
addr = PatternScanner.FindFirst(Pattern.FromString("74 4D 33 C0 48 81 C1 00 02 00 00 F3 0F 10 11 0F 2F CA 72 0C FF C0 48 83 C1 04 83 F8 03 72 EC C3"));
-#if ADDR_ASSERTS
Assert(addr == 0x1426D89CA);
-#endif
addressHigherValueForFoliageSway = new Patch(addr + 0x7, [0x04]);
// Found using mFrameSkipNum annotation from MHW-DTI-Dumps.
@@ -1704,9 +1789,6 @@ namespace WorldTuningTool
removeFromScene = new NativeAction<nint>(0x142228F10);
updateLights = Hook.Create<UpdateLights>(0x141F88F30, UpdateLightsHook);
- // Gui animation rate?
- //new Patch(new IntPtr(0x142F15C90), BitConverter.GetBytes(60.0f)).Enable();
-
return new PluginData();
}
@@ -1761,8 +1843,7 @@ namespace WorldTuningTool
config.Overrides.Add(area, new List<Override>());
}
}
- List<Override> globalOverrides = config.Overrides[Stage.InfinityOfNothingHandler];
- foreach (Override ovG in globalOverrides)
+ foreach (Override ovG in config.Overrides[globalStage])
{
ovG.Set();
}
@@ -1795,10 +1876,7 @@ namespace WorldTuningTool
{
foreach (Parameter param in fxaaParameters)
{
- if (!param.PerFrame)
- {
- param.Update(fxaaObject);
- }
+ param.Update(fxaaObject);
}
}
if (dofObject != 0x0)
@@ -2104,29 +2182,56 @@ namespace WorldTuningTool
staticShadowParams!.Original(shadowObjectStatic, shadowObjectInternal);
}
- private void OnAreaChangeHook(nint unknownPtr)
+ private void UpdateLightsHook(nint lightObject)
{
- onAreaChange!.Original(unknownPtr);
- Stage stage = Area.CurrentStage;
- if (stage == 0x0)
+ Light? ourLight = null;
+ for (int i = 0; i < ourLights.Count; i++)
{
- stage = Stage.InfinityOfNothingHandler;
+ if (lightObject == ourLights[i].Object)
+ {
+ ourLight = ourLights[i];
+ break;
+ }
+ }
+ updateLights!.Original(lightObject);
+ if (ourLight != null)
+ {
+ foreach (Parameter param in ourLight.Parameters)
+ {
+ param.Update(lightObject);
+ }
}
+ }
+
+ private void OnAreaChangeHook(nint unknownPtr)
+ {
+ onAreaChange!.Original(unknownPtr);
+ Stage stage = currentStage;
+ if (stage == 0) stage = globalStage;
if (stage == previousStage) return;
Config config = getConfig();
List<Override> prevOverrides = config.Overrides[previousStage];
previousStage = stage;
List<Override>? globalOverrides = null;
- if (!stageIsGlobal(stage))
+ if (stage != globalStage)
{
- globalOverrides = config.Overrides[Stage.InfinityOfNothingHandler];
+ globalOverrides = config.Overrides[globalStage];
}
- foreach (Override ovP in prevOverrides)
+ foreach (Override ovR in prevOverrides)
{
- ovP.Unset();
- if (globalOverrides != null && ovP.Param != null)
+ bool superseded = false;
+ if (ovR.Param != null)
{
- setIfOverridesContainsParam(globalOverrides, ovP.Param);
+ superseded |= selectedPreset != "" && overridesContainsParam(config.Presets[selectedPreset], ovR.Param);
+ superseded |= overridesContainsParam(externalOverrides.Values, ovR.Param);
+ }
+ if (!superseded)
+ {
+ ovR.Unset();
+ if (globalOverrides != null && ovR.Param != null)
+ {
+ setIfOverridesContainsParam(globalOverrides, ovR.Param);
+ }
}
}
if (globalOverrides != null) // Stage isn't global.
@@ -2134,32 +2239,20 @@ namespace WorldTuningTool
List<Override> stageOverrides = config.Overrides[stage];
foreach (Override ovS in stageOverrides)
{
+ bool superseded = false;
if (ovS.Param != null)
{
- unsetIfOverridesContainsParam(globalOverrides, ovS.Param);
+ superseded |= selectedPreset != "" && overridesContainsParam(config.Presets[selectedPreset], ovS.Param);
+ superseded |= overridesContainsParam(externalOverrides.Values, ovS.Param);
+ }
+ if (!superseded)
+ {
+ if (ovS.Param != null)
+ {
+ unsetIfOverridesContainsParam(globalOverrides, ovS.Param);
+ }
+ ovS.Set();
}
- ovS.Set();
- }
- }
- }
-
- private void UpdateLightsHook(nint lightObject)
- {
- Light? ourLight = null;
- for (int i = 0; i < ourLights.Count; i++)
- {
- if (lightObject == ourLights[i].Object)
- {
- ourLight = ourLights[i];
- break;
- }
- }
- updateLights!.Original(lightObject);
- if (ourLight != null)
- {
- foreach (Parameter param in ourLight.Parameters)
- {
- param.Update(lightObject);
}
}
}
@@ -2167,22 +2260,22 @@ namespace WorldTuningTool
public void OnImGuiRender()
{
float width = ImGui.GetWindowWidth();
- width /= (width / 600.0f);
+ width /= width / 600.0f;
/*
- if (ImGui.TextLink($"Current Stage: {Config.StageToString(Area.CurrentStage)}"))
+ if (ImGui.TextLink($"Current Stage: {Config.StageToString(currentStage)}"))
{
- if (Area.CurrentStage == 0)
+ if (currentStage == 0)
{
- selectedStage = Stage.InfinityOfNothingHandler;
+ selectedStage = globalStage;
}
else
{
- selectedStage = Area.CurrentStage;
+ selectedStage = currentStage;
}
}
*/
- ImGui.Text($"Current Stage: {Config.StageToString(Area.CurrentStage)}");
+ ImGui.Text($"Current Stage: {Config.StageToString(currentStage)}");
ImGui.PushItemWidth(width * 0.35f);
if (ImGui.BeginCombo("##Stage", Config.StageToString(selectedStage)))
@@ -2202,80 +2295,308 @@ namespace WorldTuningTool
ImGui.SameLine();
if (ImGui.Button("Current"))
{
- if (Area.CurrentStage != 0x0)
+ if (currentStage != 0)
{
- selectedStage = Area.CurrentStage;
+ selectedStage = currentStage;
}
else
{
- selectedStage = Stage.InfinityOfNothingHandler;
+ selectedStage = globalStage;
}
}
ImGui.SameLine();
if (ImGui.Button("Global"))
{
- selectedStage = Stage.InfinityOfNothingHandler;
+ selectedStage = globalStage;
}
Config config = getConfig();
- List<Override> stageOverrides = config.Overrides[selectedStage];
+ List<Override> selectedOverrides = config.Overrides[selectedStage];
+ List<Override>? stageOverrides = maybeGetStageOverrides(config);
List<Override>? globalOverrides = null;
- if (!stageIsGlobal(selectedStage))
+ if (selectedStage != globalStage)
{
- globalOverrides = config.Overrides[Stage.InfinityOfNothingHandler];
+ globalOverrides = config.Overrides[globalStage];
}
if (ImGui.Button("Add override"))
{
Override ov = new Override();
- if (Area.CurrentStage == selectedStage || stageIsGlobal(selectedStage))
+ if (currentStage == selectedStage || selectedStage == globalStage)
{
- ov.Set();
+ ov.Set(); // Empty override never superseded.
}
- stageOverrides.Add(ov);
+ selectedOverrides.Add(ov);
}
ImGui.PopItemWidth();
- for (int i = 0; i < stageOverrides.Count; i++)
+ for (int i = 0; i < selectedOverrides.Count; i++)
{
- Override ovS = stageOverrides[i];
ImGui.PushID(i);
+ Override ovS = selectedOverrides[i];
+ bool superseded = false;
+ if (ovS.Param != null)
+ {
+ superseded |= globalOverrides == null && stageOverrides != null &&
+ overridesContainsParam(stageOverrides, ovS.Param);
+ superseded |= selectedPreset != "" && overridesContainsParam(config.Presets[selectedPreset], ovS.Param);
+ superseded |= overridesContainsParam(externalOverrides.Values, ovS.Param);
+ }
bool requestRemove = ImGui.Button("X");
ImGui.SameLine();
bool requestUp = ImGui.Button("▲");
ImGui.SameLine();
bool requestDown = ImGui.Button("▼");
ImGui.SameLine();
- if (requestDown && i < stageOverrides.Count - 1)
+ if (requestDown && i < selectedOverrides.Count - 1)
{
- (stageOverrides[i], stageOverrides[i + 1]) = (stageOverrides[i + 1], stageOverrides[i]);
+ (selectedOverrides[i], selectedOverrides[i + 1]) = (selectedOverrides[i + 1], selectedOverrides[i]);
}
- ovS.Draw(stageOverrides, globalOverrides, width);
+ ovS.Draw(selectedOverrides, null, globalOverrides, superseded, width);
if (requestUp && i > 0)
{
- (stageOverrides[i], stageOverrides[i - 1]) = (stageOverrides[i - 1], stageOverrides[i]);
+ (selectedOverrides[i], selectedOverrides[i - 1]) = (selectedOverrides[i - 1], selectedOverrides[i]);
}
if (requestRemove)
{
- ovS.Unset();
- if (globalOverrides != null && ovS.Param != null)
+ if (!superseded)
{
- setIfOverridesContainsParam(globalOverrides, ovS.Param);
+ ovS.Unset();
+ if (ovS.Param != null && globalOverrides != null)
+ {
+ setIfOverridesContainsParam(globalOverrides, ovS.Param);
+ }
}
- stageOverrides.RemoveAt(i);
+ selectedOverrides.RemoveAt(i);
i--;
}
ImGui.PopID();
}
if (ImGui.Button("Save"))
{
+ for (int i = 0; i < selectedOverrides.Count; i++)
+ {
+ Override ovS = selectedOverrides[i];
+ if (ovS.Param == null)
+ {
+ selectedOverrides.RemoveAt(i);
+ i--;
+ continue;
+ }
+ ovS.Save();
+ }
ConfigManager.SaveConfig<Config>(this);
}
ImGui.Separator();
+ // Global overrides and presets could now be show at the same time.
+ globalOverrides = config.Overrides[globalStage];
+
+ ImGui.PushID("Preset");
+ ImGui.Text("Quick Presets:");
+ ImGui.PushItemWidth(width * 0.35f);
+ if (ImGui.Button("+"))
+ {
+ string presetName = "New Set";
+ int presetDup = 0;
+ while (config.Presets.ContainsKey(presetName))
+ {
+ presetDup++;
+ presetName = $"New Set ({presetDup})";
+ }
+ config.Presets[presetName] = new List<Override>();
+ selectedPreset = presetName;
+ }
+ ImGui.SameLine();
+ if (renamingPreset)
+ {
+ ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ }
+ string prevPreset = selectedPreset;
+ if (ImGui.BeginCombo("##Presets", selectedPreset))
+ {
+ if (ImGui.Selectable("(None)", false))
+ {
+ selectedPreset = "";
+ }
+ foreach ((string name, List<Override> overrides) in config.Presets)
+ {
+ bool isSelected = name == selectedPreset;
+ if (ImGui.Selectable(name, isSelected))
+ {
+ selectedPreset = name;
+ }
+ }
+ ImGui.EndCombo();
+ }
+ if (prevPreset != selectedPreset)
+ {
+ if (prevPreset != "")
+ {
+ List<Override> prevOverrides = config.Presets[prevPreset];
+ foreach (Override ovR in prevOverrides)
+ {
+ bool superseded = false;
+ if (ovR.Param != null)
+ {
+ superseded |= overridesContainsParam(externalOverrides.Values, ovR.Param);
+ }
+ if (!superseded)
+ {
+ ovR.Unset();
+ if (ovR.Param != null)
+ {
+ if (!(stageOverrides != null && setIfOverridesContainsParam(stageOverrides, ovR.Param)))
+ {
+ setIfOverridesContainsParam(globalOverrides, ovR.Param);
+ }
+ }
+ }
+ }
+ }
+ if (selectedPreset != "")
+ {
+ List<Override> newOverrides = config.Presets[selectedPreset];
+ foreach (Override ovN in newOverrides)
+ {
+ bool superseded = false;
+ if (ovN.Param != null)
+ {
+ superseded |= overridesContainsParam(externalOverrides.Values, ovN.Param);
+ }
+ if (!superseded)
+ {
+ if (ovN.Param != null)
+ {
+ if (!(stageOverrides != null && unsetIfOverridesContainsParam(stageOverrides, ovN.Param)))
+ {
+ unsetIfOverridesContainsParam(globalOverrides, ovN.Param);
+ }
+ }
+ ovN.Set();
+ }
+ }
+ }
+ }
+ if (renamingPreset)
+ {
+ ImGui.PopStyleVar();
+ ImGui.PopItemFlag();
+ }
+ ImGui.PopItemWidth();
+ if (selectedPreset != "")
+ {
+ ImGui.SameLine();
+ ImGui.PushItemWidth(width * 0.2f);
+ if (renamingPreset)
+ {
+ ImGui.InputText("##Preset Name", ref typedPresetName, 99);
+ ImGui.SameLine();
+ if (typedPresetName == "")
+ {
+ ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ }
+ if (ImGui.Button("Save"))
+ {
+ string presetName = typedPresetName;
+ int presetDup = 0;
+ while (config.Presets.ContainsKey(presetName))
+ {
+ presetDup++;
+ presetName = $"{typedPresetName} ({presetDup})";
+ }
+ List<Override> tmpOverrides = config.Presets[selectedPreset];
+ config.Presets.Remove(selectedPreset);
+ config.Presets[presetName] = tmpOverrides;
+ selectedPreset = presetName;
+ renamingPreset = false;
+ }
+ if (typedPresetName == "")
+ {
+ ImGui.PopStyleVar();
+ ImGui.PopItemFlag();
+ }
+ }
+ else if (ImGui.Button("Rename"))
+ {
+ renamingPreset = true;
+ typedPresetName = selectedPreset;
+ }
+ ImGui.PopItemWidth();
+ List<Override> presetOverrides = config.Presets[selectedPreset];
+ if (ImGui.Button("Add override"))
+ {
+ Override ov = new Override();
+ ov.Set(); // Empty override never superseded.
+ presetOverrides.Add(ov);
+ }
+ for (int i = 0; i < presetOverrides.Count; i++)
+ {
+ ImGui.PushID(i);
+ Override ovP = presetOverrides[i];
+ bool superseded = false;
+ if (ovP.Param != null)
+ {
+ superseded |= overridesContainsParam(externalOverrides.Values, ovP.Param);
+ }
+ bool requestRemove = ImGui.Button("X");
+ ImGui.SameLine();
+ bool requestUp = ImGui.Button("▲");
+ ImGui.SameLine();
+ bool requestDown = ImGui.Button("▼");
+ ImGui.SameLine();
+ if (requestDown && i < presetOverrides.Count - 1)
+ {
+ (presetOverrides[i], presetOverrides[i + 1]) = (presetOverrides[i + 1], presetOverrides[i]);
+ }
+ ovP.Draw(presetOverrides, stageOverrides, globalOverrides, superseded, width);
+ if (requestUp && i > 0)
+ {
+ (presetOverrides[i], presetOverrides[i - 1]) = (presetOverrides[i - 1], presetOverrides[i]);
+ }
+ if (requestRemove)
+ {
+ if (!superseded)
+ {
+ ovP.Unset();
+ if (ovP.Param != null)
+ {
+ if (!(stageOverrides != null && setIfOverridesContainsParam(stageOverrides, ovP.Param)))
+ {
+ setIfOverridesContainsParam(globalOverrides, ovP.Param);
+ }
+ }
+ }
+ presetOverrides.RemoveAt(i);
+ i--;
+ }
+ ImGui.PopID();
+ }
+ if (ImGui.Button("Save"))
+ {
+ for (int i = 0; i < presetOverrides.Count; i++)
+ {
+ Override ovP = presetOverrides[i];
+ if (ovP.Param == null)
+ {
+ presetOverrides.RemoveAt(i);
+ i--;
+ continue;
+ }
+ ovP.Save();
+ }
+ ConfigManager.SaveConfig<Config>(this);
+ }
+ }
+ ImGui.PopID();
+
+ ImGui.Separator();
+
ImGui.PushID("External");
ImGui.Text("External:");
foreach (Override ovE in externalOverrides.Values)
{
- ovE.Draw(null, null, width);
+ ovE.Draw(null, null, null, false, width);
}
ImGui.PopID();
@@ -2707,6 +3028,13 @@ namespace WorldTuningTool
Log.Info("Face shader replaced.");
}
}
+ else if (hash == "18a797dc-9458d333-59e6dff0-9790fcea")
+ {
+ if (replaceShaderFromFile(info, $"{shaderPath}/sssss.shdr")) {
+ info->Replacement.Type = ShaderSourceType.BINARY;
+ Log.Info("SSSSS shader replaced.");
+ }
+ }
/*
else if (hash == "d7e47ffe-82572c64-795c4698-341e5b91")
{