diff options
Diffstat (limited to 'Lights.cs')
| -rw-r--r-- | Lights.cs | 264 |
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(); + } + } +} |