From 980636ce566ae1d83e553f0ec6f96c292bd31c15 Mon Sep 17 00:00:00 2001 From: Liza Carvelli Date: Wed, 15 Dec 2021 23:46:53 +0100 Subject: [PATCH] Clean up some code --- SliceIsRight.csproj | 2 +- SlightIsRightPlugin.cs | 178 +++++++++++++++-------------------------- 2 files changed, 67 insertions(+), 113 deletions(-) diff --git a/SliceIsRight.csproj b/SliceIsRight.csproj index 517278e..2b6af19 100644 --- a/SliceIsRight.csproj +++ b/SliceIsRight.csproj @@ -3,7 +3,7 @@ - 2 + 3 Slice is Right. https://github.com/carvelli/SliceIsRight diff --git a/SlightIsRightPlugin.cs b/SlightIsRightPlugin.cs index b6922d9..c9241d3 100644 --- a/SlightIsRightPlugin.cs +++ b/SlightIsRightPlugin.cs @@ -16,6 +16,11 @@ namespace SliceIsRight { public sealed class SliceIsRightPlugin : IDalamudPlugin { + private const float HALF_PI = (float)Math.PI / 2f; + private uint COLOUR_BLUE = ImGui.GetColorU32(ImGui.ColorConvertFloat4ToU32(new Vector4(0.0f, 0.0f, 1f, 0.15f))); + private uint COLOUR_GREEN = ImGui.GetColorU32(ImGui.ColorConvertFloat4ToU32(new Vector4(0.0f, 1f, 0.0f, 0.15f))); + private uint COLOUR_RED = ImGui.GetColorU32(ImGui.ColorConvertFloat4ToU32(new Vector4(1, 0, 0, 0.4f))); + public string Name => "Slice is Right"; [PluginService] @@ -30,7 +35,7 @@ namespace SliceIsRight [PluginService] private ClientState ClientState { get; set; } - + private const ushort GoldSaucerTerritoryId = 144; private bool IsInGoldSaucer { get; set; } @@ -39,12 +44,14 @@ namespace SliceIsRight private const float MaxDistance = 30f; +#pragma warning disable CS8618 public SliceIsRightPlugin() { PluginInterface!.UiBuilder.Draw += DrawUI; ClientState!.TerritoryChanged += TerritoryChanged; IsInGoldSaucer = ClientState.TerritoryType == GoldSaucerTerritoryId; } +#pragma warning restore CS8618 private void TerritoryChanged(object? sender, ushort e) { @@ -59,14 +66,6 @@ namespace SliceIsRight private void DrawUI() { - /* - if (ImGui.Begin("Debug", ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoInputs)) - { - ImGui.Text("Current zone: " + this.ClientState.TerritoryType); - ImGui.Text("Logged in: " + this.ClientState.IsLoggedIn + ", InGS: " + this.IsInGoldSaucer); - ImGui.End(); - } - */ if (!ClientState.IsLoggedIn || !IsInGoldSaucer || ObjectTable == null) return; @@ -79,14 +78,14 @@ namespace SliceIsRight int model = Marshal.ReadInt32(obj.Address + 128); if (obj.ObjectKind == ObjectKind.EventObj && (model >= 2010777 && model <= 2010779)) { - //DebugObject(index, obj, model); RenderObject(index, obj, model); } else if (ClientState.LocalPlayer?.ObjectId == obj.ObjectId) { // local player - //DebugObject(index, obj, model); - //RenderObject(index, obj, 2010779); + //RenderObject(index, obj, 2010779, 0.1f); // circle + //RenderObject(index, obj, 2010778, 30f); // falls to both sides + //RenderObject(index, obj, 2010777, 30f); // falls to one side } } @@ -95,52 +94,7 @@ namespace SliceIsRight objectsToMatch.Clear(); } - - private void DebugObject(int index, GameObject obj, int model) - { - if (GameGui.WorldToScreen(obj.Position, out var screenCoords)) - { - // So, while WorldToScreen will return false if the point is off of game client screen, to - // to avoid performance issues, we have to manually determine if creating a window would - // produce a new viewport, and skip rendering it if so - float distance = DistanceToPlayer(obj.Position); - var objectText = $"{obj.Address.ToInt64():X}:{obj.ObjectId:X}[{index}] - {obj.ObjectKind} - {model}: {obj.Name} - {distance:F2}"; - - var screenPos = ImGui.GetMainViewport().Pos; - var screenSize = ImGui.GetMainViewport().Size; - - var windowSize = ImGui.CalcTextSize(objectText); - - // Add some extra safety padding - windowSize.X += ImGui.GetStyle().WindowPadding.X + 10; - windowSize.Y += ImGui.GetStyle().WindowPadding.Y + 10; - - if (screenCoords.X + windowSize.X > screenPos.X + screenSize.X || - screenCoords.Y + windowSize.Y > screenPos.Y + screenSize.Y) - return; - - if (distance > MaxDistance) - return; - - ImGui.SetNextWindowPos(new Vector2(screenCoords.X, screenCoords.Y)); - - ImGui.SetNextWindowBgAlpha(Math.Max(1f - (distance / MaxDistance), 0.2f)); - if (ImGui.Begin( - $"Actor{index}##ActorWindow{index}", - ImGuiWindowFlags.NoDecoration | - ImGuiWindowFlags.AlwaysAutoResize | - ImGuiWindowFlags.NoSavedSettings | - ImGuiWindowFlags.NoMove | - ImGuiWindowFlags.NoMouseInputs | - ImGuiWindowFlags.NoDocking | - ImGuiWindowFlags.NoFocusOnAppearing | - ImGuiWindowFlags.NoNav)) - ImGui.Text(objectText); - ImGui.End(); - } - } - - private void RenderObject(int index, GameObject obj, int model) + private void RenderObject(int index, GameObject obj, int model, float? radius = null) { objectsToMatch.Remove(obj.ObjectId); @@ -155,104 +109,104 @@ namespace SliceIsRight return; } - - ImGui.PushID("booWindow" + index); - - ImGui.PushStyleVar((ImGuiStyleVar)1, new Vector2(0.0f, 0.0f)); - ImGuiHelpers.SetNextWindowPosRelativeMainViewport(new Vector2(0.0f, 0.0f), ImGuiCond.None, new Vector2()); - ImGui.Begin("drawCtx" + index, ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoInputs); - ImGui.SetWindowSize(ImGui.GetIO().DisplaySize); switch (model) { case 2010777: - DrawRectWorld(obj.Position, obj.Rotation + 1.570796f, 25f, 5f, ImGui.GetColorU32(ImGui.ColorConvertFloat4ToU32(new Vector4(0.0f, 0.0f, 1f, 0.15f)))); + DrawRectWorld(obj, obj.Rotation + HALF_PI, radius ?? 25f, 5f, COLOUR_BLUE); break; case 2010778: - DrawRectWorld(obj.Position, obj.Rotation + 1.570796f, 25f, 5f, ImGui.GetColorU32(ImGui.ColorConvertFloat4ToU32(new Vector4(0.0f, 1f, 0.0f, 0.15f)))); - DrawRectWorld(obj.Position, obj.Rotation - 1.570796f, 25f, 5f, ImGui.GetColorU32(ImGui.ColorConvertFloat4ToU32(new Vector4(0.0f, 1f, 0.0f, 0.15f)))); + DrawRectWorld(obj, obj.Rotation + HALF_PI, radius ?? 25f, 5f, COLOUR_GREEN); + DrawRectWorld(obj, obj.Rotation - HALF_PI, radius ?? 25f, 5f, COLOUR_GREEN); break; case 2010779: - DrawFilledCircleWorld(obj.Position, 11f, ImGui.GetColorU32(ImGui.ColorConvertFloat4ToU32(new Vector4(1, 0, 0, 0.4f)))); + //default: + DrawFilledCircleWorld(obj, radius ?? 11f, COLOUR_RED); break; } + } + private void BeginRender(string name) + { + ImGui.PushID("sliceWindowI" + name); + + ImGui.PushStyleVar((ImGuiStyleVar)1, new Vector2(0.0f, 0.0f)); + ImGuiHelpers.SetNextWindowPosRelativeMainViewport(new Vector2(0.0f, 0.0f), ImGuiCond.None, new Vector2()); + ImGui.Begin("sliceWindow" + name, ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoInputs); + ImGui.SetWindowSize(ImGui.GetIO().DisplaySize); + } + + private void EndRender() + { ImGui.End(); ImGui.PopStyleVar(); ImGui.PopID(); } - private void DrawFilledCircleWorld(Vector3 center, float radius, uint colour) + private void DrawFilledCircleWorld(GameObject obj, float radius, uint colour) { + BeginRender(obj.Address.ToString()); + + var center = obj.Position; int segmentCount = 100; + bool onScreen = false; for (int index = 0; index <= 2 * segmentCount; ++index) { - GameGui.WorldToScreen(new Vector3(center.X + radius * (float)Math.Sin(Math.PI / segmentCount * index), center.Y, center.Z + radius * (float)Math.Cos(Math.PI / segmentCount * index)), out Vector2 vector2); + onScreen |= GameGui.WorldToScreen(new Vector3(center.X + radius * (float)Math.Sin(Math.PI / segmentCount * index), center.Y, center.Z + radius * (float)Math.Cos(Math.PI / segmentCount * index)), out Vector2 vector2); ImGui.GetWindowDrawList().PathLineTo(vector2); } - ImGui.GetWindowDrawList().PathFillConvex(colour); + + if (onScreen) + ImGui.GetWindowDrawList().PathFillConvex(colour); + else + ImGui.GetWindowDrawList().PathClear(); + + EndRender(); } - private void DrawRectWorld(Vector3 center, float rotation, float length, float width, uint colour) + private void DrawRectWorld(GameObject obj, float rotation, float length, float width, uint colour) { + BeginRender(obj.Address.ToString() + obj.Rotation.ToString()); + + var center = obj.Position; Vector2 displaySize = ImGui.GetIO().DisplaySize; - Vector3 near1 = new Vector3(center.X + width * 0.5f * (float)Math.Sin(Math.PI / 2.0 + rotation), center.Y, center.Z + width * 0.5f * (float)Math.Cos(Math.PI / 2.0 + rotation)); - Vector3 near2 = new Vector3(center.X + width * 0.5f * (float)Math.Sin(rotation - Math.PI / 2.0), center.Y, center.Z + width * 0.5f * (float)Math.Cos(rotation - Math.PI / 2.0)); + Vector3 near1 = new Vector3(center.X + width / 2 * (float)Math.Sin(HALF_PI + rotation), center.Y, center.Z + width / 2 * (float)Math.Cos(HALF_PI + rotation)); + Vector3 near2 = new Vector3(center.X + width / 2 * (float)Math.Sin(rotation - HALF_PI), center.Y, center.Z + width / 2 * (float)Math.Cos(rotation - HALF_PI)); Vector3 nearCenter = new Vector3(center.X, center.Y, center.Z); int rectangleCount = 20; + float lengthSlice = length / rectangleCount; var drawList = ImGui.GetWindowDrawList(); for (int index = 1; index <= rectangleCount; ++index) { - Vector3 far1 = new Vector3((float)(near1.X + length / (double)rectangleCount * Math.Sin(0.0 + rotation)), near1.Y, (float)(near1.Z + length / (double)rectangleCount * Math.Cos(0.0 + rotation))); - Vector3 far2 = new Vector3((float)(near2.X + length / (double)rectangleCount * Math.Sin(0.0 + rotation)), near2.Y, (float)(near2.Z + length / (double)rectangleCount * Math.Cos(0.0 + rotation))); - Vector3 farCenter = new Vector3((float)(nearCenter.X + length / (double)rectangleCount * Math.Sin(0.0 + rotation)), nearCenter.Y, (float)(nearCenter.Z + length / (double)rectangleCount * Math.Cos(0.0 + rotation))); + Vector3 far1 = new Vector3(near1.X + lengthSlice * (float)Math.Sin(rotation), near1.Y, near1.Z + lengthSlice * (float)Math.Cos(rotation)); + Vector3 far2 = new Vector3(near2.X + lengthSlice * (float)Math.Sin(rotation), near2.Y, near2.Z + lengthSlice * (float)Math.Cos(rotation)); + Vector3 farCenter = new Vector3(nearCenter.X + lengthSlice * (float)Math.Sin(rotation), nearCenter.Y, nearCenter.Z + lengthSlice * (float)Math.Cos(rotation)); - GameGui.WorldToScreen(far2, out Vector2 vector2_2); - if (vector2_2.X > 0.0 & vector2_2.X < (double)displaySize.X | vector2_2.Y > 0.0 & vector2_2.Y < (double)displaySize.Y) + bool onScreen = false; + foreach (Vector3 v in new[]{ far2, farCenter, far1, near1, nearCenter, near2}) { - drawList.PathLineTo(new Vector2((float)vector2_2.X, (float)vector2_2.Y)); + onScreen |= GameGui.WorldToScreen(v, out Vector2 nextVertex); + if ((nextVertex.X > 0 & nextVertex.X < displaySize.X) || (nextVertex.Y > 0 & nextVertex.Y < displaySize.Y)) + { + drawList.PathLineTo(nextVertex); + } } - GameGui.WorldToScreen(farCenter, out vector2_2); - if (vector2_2.X > 0.0 & vector2_2.X < (double)displaySize.X | vector2_2.Y > 0.0 & vector2_2.Y < (double)displaySize.Y) - { - drawList.PathLineTo(new Vector2((float)vector2_2.X, (float)vector2_2.Y)); - } - - GameGui.WorldToScreen(far1, out vector2_2); - if (vector2_2.X > 0.0 & vector2_2.X < (double)displaySize.X | vector2_2.Y > 0.0 & vector2_2.Y < (double)displaySize.Y) - { - drawList.PathLineTo(new Vector2((float)vector2_2.X, (float)vector2_2.Y)); - } - - GameGui.WorldToScreen(near1, out vector2_2); - if (vector2_2.X > 0.0 & vector2_2.X < (double)displaySize.X | vector2_2.Y > 0.0 & vector2_2.Y < (double)displaySize.Y) - { - drawList.PathLineTo(new Vector2((float)vector2_2.X, (float)vector2_2.Y)); - } - - GameGui.WorldToScreen(nearCenter, out vector2_2); - if (vector2_2.X > 0.0 & vector2_2.X < (double)displaySize.X | vector2_2.Y > 0.0 & vector2_2.Y < (double)displaySize.Y) - { - drawList.PathLineTo(new Vector2((float)vector2_2.X, (float)vector2_2.Y)); - } - - GameGui.WorldToScreen(near2, out vector2_2); - if (vector2_2.X > 0.0 & vector2_2.X < (double)displaySize.X | vector2_2.Y > 0.0 & vector2_2.Y < (double)displaySize.Y) - { - drawList.PathLineTo(new Vector2((float)vector2_2.X, (float)vector2_2.Y)); - } - - drawList.PathFillConvex(colour); + if (onScreen) + drawList.PathFillConvex(colour); + else + drawList.PathClear(); near1 = far1; near2 = far2; nearCenter = farCenter; } + + EndRender(); } private float DistanceToPlayer(Vector3 center)