diff options
| author | 2026-10-09 13:03:46 -0400 | |
|---|---|---|
| committer | 2026-10-09 13:05:03 -0400 | |
| commit | aeb22677767008e995dd2f8390433b918a2cf301 (patch) | |
| tree | a73be802011f8e9e0462d1f3178689119e51b5f3 /Lights.cs | |
| parent | f06c2496b80bf0dd26b8790318eaf194f362b8e2 (diff) | |
| download | WorldTuningTool-aeb22677767008e995dd2f8390433b918a2cf301.tar.gz WorldTuningTool-aeb22677767008e995dd2f8390433b918a2cf301.tar.bz2 WorldTuningTool-aeb22677767008e995dd2f8390433b918a2cf301.zip | |
Add patches, exposure parameters and cleanup
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'Lights.cs')
| -rw-r--r-- | Lights.cs | 216 |
1 files changed, 98 insertions, 118 deletions
@@ -11,10 +11,8 @@ namespace WorldTuningTool { using static Plugin; - public class Lights + public static class Lights { - public Lights() { } - private class BaseLight { public nint Object = 0x0; @@ -497,89 +495,66 @@ namespace WorldTuningTool private delegate nint CreateMhObjectLight(); private delegate nint CreateMhObjectLight2(nint unknownPtr); private delegate nint DestroyMhObjectLight(nint mhObjectLightInternal, int unknownInt); - private Hook<CreateMhObjectLight>? createMhObjectLight; - private Hook<CreateMhObjectLight2>? createMhObjectLight2; - private Hook<DestroyMhObjectLight>? destroyMhObjectLight; + private static Hook<CreateMhObjectLight>? createMhObjectLight; + private static Hook<CreateMhObjectLight2>? createMhObjectLight2; + private static Hook<DestroyMhObjectLight>? destroyMhObjectLight; private delegate nint CreateLlkObjectLight(); private delegate nint CreateLlkObjectLight2(nint unknownPtr); private delegate nint DestroyLlkObjectLight(nint llkObjectLightInternal, int unknownInt); - private Hook<CreateLlkObjectLight>? createLlkObjectLight; - private Hook<CreateLlkObjectLight2>? createLlkObjectLight2; - private Hook<DestroyLlkObjectLight>? destroyLlkObjectLight; + private static Hook<CreateLlkObjectLight>? createLlkObjectLight; + private static Hook<CreateLlkObjectLight2>? createLlkObjectLight2; + private static Hook<DestroyLlkObjectLight>? destroyLlkObjectLight; #endif private delegate nint CreateLightObject(nint lightObject); private delegate nint DestroyLightObject(nint lightObjectInternal, int unknownInt); - private Hook<CreateLightObject>? createLightObject; - private static Dictionary<nint, Func<nint, uLight>> lightTypes = new Dictionary<nint, Func<nint, uLight>>() + private static Hook<CreateLightObject>? createLightObject; + private static Dictionary<long, Func<nint, uLight>> lightTypes = new Dictionary<long, Func<nint, uLight>>() { - { lton(0x143514168), (x) => new uLight(x) }, - { lton(0x143514288), (x) => new uInfiniteLight(x) }, - { lton(0x1434994D0), (x) => new uMhInfiniteLight(x) }, - { lton(0x1434954F0), (x) => new uMhActorInfiniteLight(x) }, - { lton(0x143494150), (x) => new uLlkInfiniteLight(x) }, - { lton(0x1434936A0), (x) => new uLlkActorInfiniteLight(x) }, - { lton(0x143493E30), (x) => new uLlkFollowCameraInfiniteLight(x) }, - { lton(0x1435143A8), (x) => new uPointLight(x) }, - { lton(0x14349A6C8), (x) => new uMhPointLight(x) }, - { lton(0x1434952B0), (x) => new uMhActorPointLight(x) }, - { lton(0x1434944E8), (x) => new uLlkPointLight(x) }, - { lton(0x143493460), (x) => new uLlkActorPointLight(x) }, - { lton(0x143493BF0), (x) => new uLlkFollowCameraPointLight(x) }, - { lton(0x1435144C8), (x) => new uSpotLight(x) }, - { lton(0x14349E280), (x) => new uMhSpotLight(x) }, - { lton(0x1434953D0), (x) => new uMhActorSpotLight(x) }, - { lton(0x143494888), (x) => new uLlkSpotLight(x) }, - { lton(0x143493580), (x) => new uLlkActorSpotLight(x) }, - { lton(0x1434937C0), (x) => new uLlkNullAngleSpotLight(x) }, - { lton(0x143493D10), (x) => new uLlkFollowCameraSpotLight(x) }, - { lton(0x1435145E8), (x) => new uHemiSphereLight(x) }, - { lton(0x143499378), (x) => new uMhHemiSphereLight(x) }, - { lton(0x143493F98), (x) => new uLlkHemiSphereLight(x) } - + { 0x143514168, (x) => new uLight(x) }, + { 0x143514288, (x) => new uInfiniteLight(x) }, + { 0x1434994D0, (x) => new uMhInfiniteLight(x) }, + { 0x1434954F0, (x) => new uMhActorInfiniteLight(x) }, + { 0x143494150, (x) => new uLlkInfiniteLight(x) }, + { 0x1434936A0, (x) => new uLlkActorInfiniteLight(x) }, + { 0x143493E30, (x) => new uLlkFollowCameraInfiniteLight(x) }, + { 0x1435143A8, (x) => new uPointLight(x) }, + { 0x14349A6C8, (x) => new uMhPointLight(x) }, + { 0x1434952B0, (x) => new uMhActorPointLight(x) }, + { 0x1434944E8, (x) => new uLlkPointLight(x) }, + { 0x143493460, (x) => new uLlkActorPointLight(x) }, + { 0x143493BF0, (x) => new uLlkFollowCameraPointLight(x) }, + { 0x1435144C8, (x) => new uSpotLight(x) }, + { 0x14349E280, (x) => new uMhSpotLight(x) }, + { 0x1434953D0, (x) => new uMhActorSpotLight(x) }, + { 0x143494888, (x) => new uLlkSpotLight(x) }, + { 0x143493580, (x) => new uLlkActorSpotLight(x) }, + { 0x1434937C0, (x) => new uLlkNullAngleSpotLight(x) }, + { 0x143493D10, (x) => new uLlkFollowCameraSpotLight(x) }, + { 0x1435145E8, (x) => new uHemiSphereLight(x) }, + { 0x143499378, (x) => new uMhHemiSphereLight(x) }, + { 0x143493F98, (x) => new uLlkHemiSphereLight(x) } }; - private static nint[] lightObjectDestructors = { - lton(0x142311FF0), // # uLight - lton(0x142311F40), // # uInfiniteLight - lton(0x141FB8F50), // # uMhInfiniteLight - lton(0x141F91DE0), // # uMhActorInfiniteLight - lton(0x141F855A0), // # uLlkInfiniteLight - lton(0x141F81940), // # uLlkActorInfiniteLight - lton(0x141F83B00), // # uLlkFollowCameraInfiniteLight - lton(0x142312070), // # uPointLight - lton(0x141FC0950), // # uMhPointLight - lton(0x141F91E80), // # uMhActorPointLight - lton(0x141F87D90), // # uLlkPointLight - lton(0x141F819B0), // # uLlkActorPointLight - lton(0x141F83B70), // # uLlkFollowCameraPointLight - lton(0x1423120F0), // # uSpotLight - lton(0x141FDE0D0), // # uMhSpotLight - lton(0x141F91F20), // # uMhActorSpotLight - lton(0x141F8B390), // # uLlkSpotLight - lton(0x141F81A20), // # uLlkActorSpotLight - lton(0x141F81A90), // # uLlkNullAngleSpotLight - lton(0x141F83BE0), // # uLlkFollowCameraSpotLight - lton(0x142311EC0), // # uHemiSphereLight - lton(0x141FB8C20), // # uMhHemiSphereLight - lton(0x141F84A40) // # uLlkHemiSphereLight - }; - private Hook<DestroyLightObject>[] lightObjectDestructorHooks = new Hook<DestroyLightObject>[lightObjectDestructors.Length]; + private static Hook<DestroyLightObject>[] lightObjectDestructorHooks = new Hook<DestroyLightObject>[lightTypes.Count()]; - private List<uLight> newLights = new List<uLight>(); - private List<uLight> sceneLights = new List<uLight>(); - private bool sortByDistanceToPlayerPoint = false; - private bool sortByDistanceToPlayerSpot = false; + private static List<uLight> newLights = new List<uLight>(); + private static List<uLight> sceneLights = new List<uLight>(); + private static bool sortByDistanceToPlayerPoint = false; + private static bool sortByDistanceToPlayerSpot = false; - private NativeAction<nint, int, nint, int> addToScene; - private NativeAction<nint> removeFromScene; - private List<uLight> ourLights = new List<uLight>(); + private static NativeFunction<nint> newPointLight; + private static NativeFunction<nint> newSpotLight; + private static NativeFunction<nint> newHemiSphereLight; + private static NativeAction<nint, int, nint, int> addToScene; + private static NativeAction<nint> removeFromScene; + private static List<uLight> ourLights = new List<uLight>(); #if HOOK_OBJECT_LIGHTS - private List<BaseLight> objectLights = new List<BaseLight>(); + private static List<BaseLight> objectLights = new List<BaseLight>(); #endif - public void Initialize() + public static void Initialize() { createLightObject = Hook.Create<CreateLightObject>(0x142311420, CreateLightObjectHook); DestroyLightObject[] destructorHookFuncs = { @@ -607,26 +582,29 @@ namespace WorldTuningTool DestroyLightObjectHook21, DestroyLightObjectHook22 }; - for (int i = 0; i < lightObjectDestructors.Length; i++) + for (int i = 0; i < lightTypes.Count(); i++) // Not ordered. { - lightObjectDestructorHooks[i] = Hook.Create<DestroyLightObject>(lightObjectDestructors[i], destructorHookFuncs[i]); + nint destructor = MemoryUtil.Read<nint>(lightTypes.Keys.ElementAt(i)); + lightObjectDestructorHooks[i] = Hook.Create<DestroyLightObject>(destructor, destructorHookFuncs[i]); } #if HOOK_OBJECT_LIGHTS createMhObjectLight = Hook.Create<CreateMhObjectLight>(0x141FBF290, CreateMhObjectLightHook); createMhObjectLight2 = Hook.Create<CreateMhObjectLight2>(0x141FBF500, CreateMhObjectLight2Hook); destroyMhObjectLight = Hook.Create<DestroyMhObjectLight>(0x141FBF6B0, DestroyMhObjectLightHook); - createLlkObjectLight = Hook.Create<CreateLlkObjectLight>(0x141F85DF0, CreateLlkObjectLightHook); createLlkObjectLight2 = Hook.Create<CreateLlkObjectLight2>(0x141F86090, CreateLlkObjectLight2Hook); destroyLlkObjectLight = Hook.Create<DestroyLlkObjectLight>(0x141F86270, DestroyLlkObjectLightHook); #endif + newPointLight = new NativeFunction<nint>(0x141FC0780); + newSpotLight = new NativeFunction<nint>(0x141FDDF00); + newHemiSphereLight = new NativeFunction<nint>(0x141FB8A50); addToScene = new NativeAction<nint, int, nint, int>(0x142219070); removeFromScene = new NativeAction<nint>(0x142228F10); } - public void PostUpdateLightLinker() + public static void PostUpdateLightLinker() { foreach (uLight light in sceneLights) { @@ -637,8 +615,10 @@ namespace WorldTuningTool } } - public void OnUpdate() + public static void OnUpdate() { + // @TODO: Safe to check newLights.Count > 0? + // Apparently that read would be guaranteed atomic in c#. lock (newLights) { for (int i = newLights.Count - 1; i >= 0; i--) @@ -648,7 +628,7 @@ namespace WorldTuningTool nint vTable = MemoryUtil.Read<nint>(light.Object); if (lightTypes.ContainsKey(vTable)) { - if (vTable == lton(0x143514168)) + if (vTable == 0x143514168) { Log.Error("Light is still uLight OnUpdate()."); } @@ -662,7 +642,7 @@ namespace WorldTuningTool } } - private nint CreateLightObjectHook(nint lightObject) + private static nint CreateLightObjectHook(nint lightObject) { lightObject = createLightObject!.Original(lightObject); uLight light = new uLight(lightObject); @@ -673,7 +653,7 @@ namespace WorldTuningTool return lightObject; } - private void cleanupCommon(nint lightObject) + private static void cleanupCommon(nint lightObject) { for (int i = 0; i < sceneLights.Count; i++) { @@ -707,138 +687,138 @@ namespace WorldTuningTool } } - private nint DestroyLightObjectHook0(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook0(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[0]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook1(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook1(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[1]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook2(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook2(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[2]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook3(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook3(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[3]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook4(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook4(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[4]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook5(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook5(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[5]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook6(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook6(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[6]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook7(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook7(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[7]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook8(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook8(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[8]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook9(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook9(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[9]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook10(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook10(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[10]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook11(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook11(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[11]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook12(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook12(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[12]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook13(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook13(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[13]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook14(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook14(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[14]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook15(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook15(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[15]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook16(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook16(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[16]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook17(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook17(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[17]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook18(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook18(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[18]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook19(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook19(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[19]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook20(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook20(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[20]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook21(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook21(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[21]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook22(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook22(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[22]!.Original(lightObject, unknownInt); } #if HOOK_OBJECT_LIGHTS - private nint CreateMhObjectLightHook() + private static nint CreateMhObjectLightHook() { nint objectLight = createMhObjectLight!.Original(); objectLights.Add(new uMhObjectLight(objectLight)); return objectLight; } - private nint CreateMhObjectLight2Hook(nint unknownPtr) + private static nint CreateMhObjectLight2Hook(nint unknownPtr) { nint objectLight = createMhObjectLight2!.Original(unknownPtr); objectLights.Add(new uMhObjectLight(objectLight)); return objectLight; } - private nint DestroyMhObjectLightHook(nint mhObjectLightInternal, int unknownInt) + private static nint DestroyMhObjectLightHook(nint mhObjectLightInternal, int unknownInt) { Assert(unknownInt == 1); for (int i = 0; i < objectLights.Count; i++) @@ -853,21 +833,21 @@ namespace WorldTuningTool return destroyMhObjectLight!.Original(mhObjectLightInternal, unknownInt); } - private nint CreateLlkObjectLightHook() + private static nint CreateLlkObjectLightHook() { nint objectLight = createLlkObjectLight!.Original(); objectLights.Add(new uLlkObjectLight(objectLight)); return objectLight; } - private nint CreateLlkObjectLight2Hook(nint unknownPtr) + private static nint CreateLlkObjectLight2Hook(nint unknownPtr) { nint objectLight = createLlkObjectLight2!.Original(unknownPtr); objectLights.Add(new uLlkObjectLight(objectLight)); return objectLight; } - private nint DestroyLlkObjectLightHook(nint llkObjectLightInternal, int unknownInt) + private static nint DestroyLlkObjectLightHook(nint llkObjectLightInternal, int unknownInt) { Assert(unknownInt == 1); for (int i = 0; i < objectLights.Count; i++) @@ -883,7 +863,7 @@ namespace WorldTuningTool } #endif - private void DrawLights(IEnumerable<BaseLight> lights, float width) + private static void DrawLights(IEnumerable<BaseLight> lights, float width) { bool disableAll = ImGui.Button("Disable All"); if (ImGui.BeginItemTooltip()) @@ -964,26 +944,26 @@ namespace WorldTuningTool } } - public unsafe void DrawUI(float width) + public static unsafe void DrawUI(float width) { int lightType = -1; nint lightObject = 0x0; if (ImGui.Button("New Point Light")) { lightType = 2; - lightObject = new NativeFunction<nint>(0x141FC0780).Invoke(); + lightObject = newPointLight.Invoke(); } ImGui.SameLine(); if (ImGui.Button("New Spot Light")) { lightType = 3; - lightObject = new NativeFunction<nint>(0x141FDDF00).Invoke(); + lightObject = newSpotLight.Invoke(); } ImGui.SameLine(); if (ImGui.Button("New Hemi Sphere Light")) { lightType = 4; - lightObject = new NativeFunction<nint>(0x141FB8A50).Invoke(); + lightObject = newHemiSphereLight.Invoke(); } bool lightTook = false; lock (newLights) @@ -1051,7 +1031,7 @@ namespace WorldTuningTool ImGui.PushID("Infinite"); if (ImGui.CollapsingHeader("Infinite")) { - DrawLights(sceneLights.Where(x => (x.Type == 1)), width); + DrawLights(sceneLights.Where((x) => x.Type == 1), width); ImGui.Separator(); } ImGui.PopID(); @@ -1065,7 +1045,7 @@ namespace WorldTuningTool Vector3 pos = default; Player? player = Player.MainPlayer; if (player != null) pos = player.Position; - DrawLights(Enumerable.OrderBy<uLight, uLight>(sceneLights.Where(x => (x.Type == 2)), x => x, Comparer<uLight>.Create((x, y) => + DrawLights(Enumerable.OrderBy<uLight, uLight>(sceneLights.Where((x) => x.Type == 2), (x) => x, Comparer<uLight>.Create((x, y) => { Vector3 xPos = ((uPointLight)x).Position; if (((uPointLight)x).Parent != 0x0) @@ -1086,7 +1066,7 @@ namespace WorldTuningTool } else { - DrawLights(sceneLights.Where(x => (x.Type == 2)), width); + DrawLights(sceneLights.Where((x) => x.Type == 2), width); } ImGui.Separator(); } @@ -1101,7 +1081,7 @@ namespace WorldTuningTool Vector3 pos = default; Player? player = Player.MainPlayer; if (player != null) pos = player.Position; - DrawLights(Enumerable.OrderBy<uLight, uLight>(sceneLights.Where(x => (x.Type == 3)), x => x, Comparer<uLight>.Create((x, y) => + DrawLights(Enumerable.OrderBy<uLight, uLight>(sceneLights.Where((x) => x.Type == 3), (x) => x, Comparer<uLight>.Create((x, y) => { Vector3 xPos = ((uSpotLight)x).Position; if (((uSpotLight)x).Parent != 0x0) @@ -1122,7 +1102,7 @@ namespace WorldTuningTool } else { - DrawLights(sceneLights.Where(x => (x.Type == 3)), width); + DrawLights(sceneLights.Where((x) => x.Type == 3), width); } ImGui.Separator(); } @@ -1130,7 +1110,7 @@ namespace WorldTuningTool ImGui.PushID("HemiSphere"); if (ImGui.CollapsingHeader("Hemi Sphere")) { - DrawLights(sceneLights.Where(x => (x.Type == 4)), width); + DrawLights(sceneLights.Where((x) => x.Type == 4), width); ImGui.Separator(); } ImGui.PopID(); |