summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2026-09-15 14:32:10 -0400
committerAndrew Opalach <andrew@akon.city> 2026-09-15 14:32:10 -0400
commit6073c6ef3a85557e3a1ff3ab03abe0b3e0d93f7c (patch)
tree54a16daf8ffc43826d1ac346b4fc7d48592ec877
parentb4a9dca02cc3d7f741c295bb7aaa2a9db63519f0 (diff)
downloadWorldTuningTool-6073c6ef3a85557e3a1ff3ab03abe0b3e0d93f7c.tar.gz
WorldTuningTool-6073c6ef3a85557e3a1ff3ab03abe0b3e0d93f7c.tar.bz2
WorldTuningTool-6073c6ef3a85557e3a1ff3ab03abe0b3e0d93f7c.zip
Fix disableLights, lock in CreateLightObject()
Also keep some temporary asserts around for now Signed-off-by: Andrew Opalach <andrew@akon.city>
-rw-r--r--Lights.cs153
-rw-r--r--Plugin.cs15
2 files changed, 118 insertions, 50 deletions
diff --git a/Lights.cs b/Lights.cs
index c0409d1..b592d67 100644
--- a/Lights.cs
+++ b/Lights.cs
@@ -539,7 +539,6 @@ namespace WorldTuningTool
private NativeAction<nint, int, nint, int> addToScene;
private NativeAction<nint> removeFromScene;
- private bool interceptCreateLight = false;
private List<uLight> ourLights = new List<uLight>();
public void Initialize()
@@ -584,90 +583,116 @@ namespace WorldTuningTool
public void PostUpdateLightLinker()
{
- for (int i = 0; i < sceneLights.Count; i++)
+ if (Monitor.TryEnter(sceneLights))
{
- uLight light = sceneLights[i];
- foreach (Parameter param in light.Parameters)
+ try
{
- param.Update(light.Object);
+ PostUpdateLightLinkerN();
}
+ finally
+ {
+ Monitor.Exit(sceneLights);
+ }
+ }
+ else
+ {
+ Assert(false);
}
}
- public void OnUpdate()
+ public void PostUpdateLightLinkerN()
{
- for (int i = newLights.Count - 1; i >= 0; i--)
+ foreach (uLight light in sceneLights)
{
- uLight light = newLights[i];
- nint vTable = MemoryUtil.Read<nint>(light.Object);
- newLights.RemoveAt(i);
- if (lightTypes.ContainsKey(vTable))
- {
- sceneLights.Add(lightTypes[vTable](light.Object));
- }
- else
+ foreach (Parameter param in light.Parameters)
{
- Log.Error($"Unknown Light Type: 0x{vTable:X}.");
+ param.Update(light.Object);
}
}
}
- private bool lightObjectIsTracked(nint lightObject)
+ public void OnUpdate()
{
- for (int i = 0; i < newLights.Count; i++)
+ if (Monitor.TryEnter(sceneLights))
{
- if (lightObject == newLights[i].Object)
+ try
{
- return true;
+ OnUpdateN();
}
- }
- for (int i = 0; i < sceneLights.Count; i++)
- {
- if (lightObject == sceneLights[i].Object)
+ finally
{
- return true;
+ Monitor.Exit(sceneLights);
}
}
- for (int i = 0; i < ourLights.Count; i++)
+ else
+ {
+ Assert(false);
+ }
+ }
+
+ public void OnUpdateN()
+ {
+ lock (newLights)
{
- if (lightObject == ourLights[i].Object)
+ for (int i = newLights.Count - 1; i >= 0; i--)
{
- return true;
+ uLight light = newLights[i];
+ newLights.RemoveAt(i);
+ nint vTable = MemoryUtil.Read<nint>(light.Object);
+ if (lightTypes.ContainsKey(vTable))
+ {
+ if (vTable == lton(0x143514168))
+ {
+ Log.Error("Light is still uLight OnUpdate().");
+ }
+ sceneLights.Add(lightTypes[vTable](light.Object));
+ }
+ else
+ {
+ Log.Error($"Unknown Light Type: 0x{vTable:X}.");
+ }
}
}
- return false;
}
private nint CreateLightObjectHook(nint lightObject)
{
lightObject = createLightObject!.Original(lightObject);
- if (!interceptCreateLight)
+ uLight light = new uLight(lightObject);
+ lock (newLights)
{
- Assert(!lightObjectIsTracked(lightObject));
- newLights.Add(new uLight(lightObject));
+ newLights.Add(light);
}
return lightObject;
}
private void cleanupCommon(nint lightObject)
{
- for (int i = 0; i < newLights.Count; i++)
+ if (Monitor.TryEnter(sceneLights))
{
- uLight light = newLights[i];
- if (lightObject == light.Object)
+ try
{
- newLights.RemoveAt(i);
- Assert(!lightObjectIsTracked(lightObject));
- return;
+ cleanupCommonN(lightObject);
+ }
+ finally
+ {
+ Monitor.Exit(sceneLights);
}
}
+ else
+ {
+ Assert(false);
+ }
+ }
+
+ private void cleanupCommonN(nint lightObject)
+ {
for (int i = 0; i < sceneLights.Count; i++)
{
uLight light = sceneLights[i];
if (lightObject == light.Object)
{
sceneLights.RemoveAt(i);
- Assert(!lightObjectIsTracked(lightObject));
return;
}
}
@@ -677,10 +702,21 @@ namespace WorldTuningTool
if (lightObject == light.Object)
{
ourLights.RemoveAt(i);
- Assert(!lightObjectIsTracked(lightObject));
return;
}
}
+ lock (newLights)
+ {
+ for (int i = 0; i < newLights.Count; i++)
+ {
+ uLight light = newLights[i];
+ if (lightObject == light.Object)
+ {
+ newLights.RemoveAt(i);
+ return;
+ }
+ }
+ }
}
private nint DestroyLightObjectHook0(nint lightObject, int unknownInt)
@@ -897,7 +933,25 @@ namespace WorldTuningTool
public unsafe void DrawUI(float width)
{
- interceptCreateLight = true;
+ if (Monitor.TryEnter(sceneLights))
+ {
+ try
+ {
+ DrawUIN(width);
+ }
+ finally
+ {
+ Monitor.Exit(sceneLights);
+ }
+ }
+ else
+ {
+ Assert(false);
+ }
+ }
+
+ public unsafe void DrawUIN(float width)
+ {
int lightType = -1;
nint lightObject = 0x0;
if (ImGui.Button("New Point Light"))
@@ -917,8 +971,21 @@ namespace WorldTuningTool
lightType = 4;
lightObject = new NativeFunction<nint>(0x141FB8A50).Invoke();
}
- interceptCreateLight = false;
- if (lightObject != 0x0)
+ bool lightTook = false;
+ lock (newLights)
+ {
+ for (int i = newLights.Count - 1; i >= 0; i--)
+ {
+ uLight light = newLights[i];
+ if (light.Object == lightObject)
+ {
+ newLights.RemoveAt(i);
+ lightTook = true;
+ break;
+ }
+ }
+ }
+ if (lightTook && lightObject != 0x0)
{
Vector3 pos = default;
Player? player = Player.MainPlayer;
diff --git a/Plugin.cs b/Plugin.cs
index 318f0a3..984b3ad 100644
--- a/Plugin.cs
+++ b/Plugin.cs
@@ -25,6 +25,7 @@ using SharpPluginLoader.Core.Resources;
#endif
// @TODO:
+// - https://dev.epicgames.com/community/learning/tutorials/34xz/unreal-engine-ocio-3d-luts-applying-3d-luts-when-using-ocio
// - Add built-in LUT list.
// - Configurable Broad Area Shadow Resolution.
// - Hook sMhScene constructor to set hqMode.
@@ -47,6 +48,7 @@ using SharpPluginLoader.Core.Resources;
// - Special Arena.
// - Elder's Recess Lavasioth area.
// - Hoarfrost pit area with wedge beetles.
+// - Xeno starting area (Confluence of Fates) corner next to water.
//
// Known issues to think about:
// - Hair clipping when character looks down.
@@ -70,7 +72,7 @@ namespace WorldTuningTool
if (!condition && !loggedAssertFailed)
{
Log.Error($"Assert failed on line {line}.");
- loggedAssertFailed = true;
+ //loggedAssertFailed = true;
}
#if ENABLE_ASSERTS
Trace.Assert(condition);
@@ -2472,11 +2474,6 @@ namespace WorldTuningTool
createTAAObject2 = Hook.Create<CreateTAAObject2>(0x142391320, CreateTAAObject2Hook); // nint
destroyTAAObject = Hook.Create<DestroyTAAObject>(0x1423916E0, DestroyTAAObjectHook); // nint, int
- if (!disableLightsFeature)
- {
- lights.Initialize();
- }
-
nint 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"));
Assert(addr == 0x141AB2260); // nint, nint
updateShadowParams = Hook.Create<UpdateShadowParams>(addr, UpdateShadowParamsHook);
@@ -2675,6 +2672,10 @@ namespace WorldTuningTool
{
Config config = getConfig();
disableLightsFeature = config.DisableLightsFeature;
+ if (!disableLightsFeature)
+ {
+ lights.Initialize();
+ }
PatchConfig patches = config.Patches;
#if SHADER_FEATURES
fullResSSLR = patches.FullResolutionSSLR;
@@ -3470,7 +3471,7 @@ namespace WorldTuningTool
}
if (!config.Overrides.ContainsKey(stage))
{
- Log.Error($"Unknown stage: {stage}");
+ Log.Error($"Unknown stage: {stage}.");
stage = globalStage;
}
if (stage != globalStage)