summaryrefslogtreecommitdiff
path: root/Lights.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Lights.cs')
-rw-r--r--Lights.cs264
1 files changed, 264 insertions, 0 deletions
diff --git a/Lights.cs b/Lights.cs
new file mode 100644
index 0000000..0eed477
--- /dev/null
+++ b/Lights.cs
@@ -0,0 +1,264 @@
+using System.Numerics;
+
+using ImGuiNET;
+using SharpPluginLoader.Core;
+using SharpPluginLoader.Core.Memory;
+using SharpPluginLoader.Core.Entities;
+
+namespace WorldTuningTool
+{
+ using static Plugin;
+
+ public class Lights
+ {
+ public Lights() { }
+
+ private class Light
+ {
+ public nint Object;
+ public int Type;
+ public Parameter[] Parameters = {
+ newParameter<int>("Group", 0x13C, ParameterType.INT, pMinMaxStep(1, 255, 1)), // 1 = World, (1 << 1) = Player/Palico, (1 << 2) = NPCs
+ newFrameParameter<float>("Position", 0x5A0, ParameterType.VECTOR3, pStep(0.15f)),
+ newFrameParameter<int>("Color", 0x140, ParameterType.COLOR),
+ newFrameParameter<float>("Intensity", 0x8A8, ParameterType.FLOAT),
+ newFrameParameter<float>("Radius", 0x6A0, ParameterType.FLOAT, pStep(0.25f)),
+ newFrameParameter<float>("Effective Radius", 0x588, ParameterType.FLOAT, pStep(0.25f)),
+ newFrameParameter<float>("Min Roughness", 0x58C, ParameterType.FLOAT, pStep(0.0025f)),
+ newParameter<bool>("Do Volumetric", 0x590, ParameterType.BOOL),
+ newFlag<bool>("Shadow Cast", 0x138, ParameterType.FLAG, (1 << 23)),
+ newParameter<int>("Shadow Map Size", 0x1B8, ParameterType.ALIGNED_INT, pMinStep(0, 128)),
+ newParameter<float>("Shadow Near Clip Distance", 0x1B4, ParameterType.FLOAT),
+ newFrameParameter<float>("Shadow Depth Bias", 0x57C, ParameterType.FLOAT, pStep(0.00001f)),
+ newFrameParameter<float>("Shadow Sloped Depth Bias", 0x580, ParameterType.FLOAT, pStep(0.00001f)),
+ newFrameParameter<float>("Shadow Max Depth Bias", 0x584, ParameterType.FLOAT, pStep(0.00001f)),
+ };
+
+ public Light(nint lightObject, int type)
+ {
+ Object = lightObject;
+ Type = type;
+ foreach (Parameter param in Parameters)
+ {
+ param.Update(lightObject);
+ }
+ }
+
+ public Light(nint lightObject, int type, Vector3 pos)
+ {
+ Object = lightObject;
+ Type = type;
+ foreach (Parameter param in Parameters)
+ {
+ param.OverrideOn(false);
+ }
+ Parameters[0].SetOverrideValue(default, 255);
+ Parameters[1].SetOverrideValue(new Vector4(pos.X, pos.Y, pos.Z, 0.0f), 0);
+ Parameters[3].SetOverrideValue(new Vector4(10.0f, 0.0f, 0.0f, 0.0f), 0);
+ foreach (Parameter param in Parameters)
+ {
+ 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<int, nint> createLight;
+ //private bool interceptCreateLight = false;
+ private List<Light> ourLights = new List<Light>();
+ //private List<Light> sceneLights = new List<Light>();
+ private NativeAction<nint, int, nint, int> addToScene;
+ private NativeAction<nint> removeFromScene;
+ //private delegate nint CreateLightObject(int type);
+ //private Hook<CreateLightObject>? createLightObject;
+ private delegate void DestroyLightObject(nint lightObject, int unknownInt);
+ private Hook<DestroyLightObject>? destroyLightObject;
+ private delegate void UpdateLights(nint lightObject);
+ private Hook<UpdateLights>? updateLights;
+
+ public void Initialize()
+ {
+ createLight = new NativeFunction<int, nint>(0x1418A3EF0);
+ //createLightObject = Hook.Create<CreateLightObject>(0x1418A3EF0, CreateLightObjectHook);
+ destroyLightObject = Hook.Create<DestroyLightObject>(0x141F87D90, DestroyLightObjectHook);
+ addToScene = new NativeAction<nint, int, nint, int>(0x142219070);
+ removeFromScene = new NativeAction<nint>(0x142228F10);
+ updateLights = Hook.Create<UpdateLights>(0x141F88F30, UpdateLightsHook);
+ }
+
+ /*
+ 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 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 (light != null)
+ {
+ foreach (Parameter param in light.Parameters)
+ {
+ param.Update(lightObject);
+ }
+ }
+ }
+
+ private void DestroyLightObjectHook(nint lightObject, int unknownInt)
+ {
+ /*
+ 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)
+ {
+ ourLights.RemoveAt(i);
+ break;
+ }
+ }
+ destroyLightObject!.Original(lightObject, unknownInt);
+ }
+
+ public unsafe void DrawUI(float width)
+ {
+ /*
+ ImGui.NextItemWidth(width * 0.25f);
+ ImGui.InputInt("Type", ref requestLightType, 1);
+ ImGui.SameLine();
+ */
+ if (ImGui.Button("New"))
+ {
+ //interceptCreateLight = true;
+ nint lightObject = createLight.Invoke(requestLightType);
+ Vector3 pos = default;
+ Player? player = Player.MainPlayer;
+ if (player != null)
+ {
+ pos = player.Position;
+ pos.Y += 30.0f;
+ }
+ ourLights.Add(new Light(lightObject, requestLightType, pos));
+ // mov byte ptr[rsp+20],00 unaccounted for, hopefully it never matters.
+ addToScene.Invoke(MemoryUtil.Read<nint>(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($"Type: {light.Type}, Address: 0x{light.Object:X}");
+ foreach (Parameter param in light.Parameters)
+ {
+ param.Draw(width, true);
+ }
+ /*
+ if (ImGui.CollapsingHeader("Random Move"))
+ {
+ foreach (Parameter param in light.RandomMoveParameters)
+ {
+ param.Draw(width, true);
+ }
+ }
+ */
+ if (ImGui.Button("Remove"))
+ {
+ /*
+ nint vTable = MemoryUtil.Read<nint>(lightObject);
+ NativeAction<nint, int> freeLight = new NativeAction<nint, int>(MemoryUtil.Read<nint>(vTable));
+ freeLight.Invoke(lightObject, 1);
+ */
+ // removeFromScene triggers destructor.
+ removeFromScene.Invoke(light.Object);
+ }
+ 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: 0x{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();
+ }
+ }
+}