fix: prevent vfx from spawning invisible

This commit is contained in:
Anna 2024-07-08 23:44:26 -04:00
parent 689984ee3e
commit 8d8cf0b99b
Signed by: anna
GPG Key ID: D0943384CD9F87D1
3 changed files with 89 additions and 37 deletions

View File

@ -1,3 +1,4 @@
using System.Numerics;
using Dalamud.Interface.Utility;
using ImGuiNET;
using OrangeGuidanceTomestone.Ui;
@ -102,11 +103,11 @@ public class PluginUi : IDisposable {
var label = msg.Id.ToString("N");
var size = ImGui.CalcTextSize(label);
ImGui.GetBackgroundDrawList().AddRectFilled(
screen,
screen + size,
screen - Vector2.One * 4 * ImGuiHelpers.GlobalScale,
screen + size + Vector2.One * 4 * ImGuiHelpers.GlobalScale,
0xff000000
);
ImGui.GetForegroundDrawList().AddText(screen, 0xffffffff, label);
ImGui.GetBackgroundDrawList().AddText(screen, 0xffffffff, label);
}
}
}

View File

@ -4,6 +4,7 @@ using Dalamud.Utility;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using OrangeGuidanceTomestone.Helpers;
using OrangeGuidanceTomestone.Util;
namespace OrangeGuidanceTomestone.Ui.MainWindowTabs;
@ -21,6 +22,7 @@ internal class Settings : ITab {
private IReadOnlyList<(string, DrawSettingsDelegate)> Tabs { get; }
private string _filter = string.Empty;
private string _debugFilter = string.Empty;
internal Settings(Plugin plugin) {
this.Plugin = plugin;
@ -230,6 +232,47 @@ internal class Settings : ITab {
private void DrawDebug(ref bool anyChanged, ref bool vfx) {
ImGui.Checkbox("Show debug information", ref this.Plugin.Ui.Debug);
ImGui.InputText("Filter", ref this._debugFilter, 64);
if (ImGui.BeginTable("###debug-info", 2)) {
using var endTable = new OnDispose(ImGui.EndTable);
ImGui.TableSetupColumn("ID", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("VFX pointer");
ImGui.TableHeadersRow();
using var guard = this.Plugin.Vfx.Mutex.With();
foreach (var (id, ptr) in this.Plugin.Vfx.Spawned) {
var idLabel = id.ToString("N");
var ptrLabel = ptr.ToString("X");
if (!string.IsNullOrWhiteSpace(this._debugFilter)) {
if (
!idLabel.Contains(this._debugFilter, StringComparison.CurrentCultureIgnoreCase)
&& !ptrLabel.Contains(this._debugFilter, StringComparison.CurrentCultureIgnoreCase)
) {
continue;
}
}
ImGui.TableNextRow();
if (ImGui.TableSetColumnIndex(0)) {
ImGui.TextUnformatted(id.ToString("N"));
if (ImGui.IsItemClicked()) {
ImGui.SetClipboardText(id.ToString("N"));
}
}
if (ImGui.TableSetColumnIndex(1)) {
ImGui.TextUnformatted(ptr.ToString("X"));
if (ImGui.IsItemClicked()) {
ImGui.SetClipboardText(ptr.ToString("X"));
}
}
}
}
}
private void ExtraCodeInput() {

View File

@ -1,3 +1,4 @@
using System.Diagnostics;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
@ -21,15 +22,11 @@ internal unsafe class Vfx : IDisposable {
private readonly delegate* unmanaged<VfxStruct*, nint> _staticVfxRemove;
private Plugin Plugin { get; }
private SemaphoreSlim Mutex { get; } = new(1, 1);
private Dictionary<Guid, nint> Spawned { get; } = [];
internal SemaphoreSlim Mutex { get; } = new(1, 1);
internal Dictionary<Guid, nint> Spawned { get; } = [];
private Queue<IQueueAction> Queue { get; } = [];
private bool _disposed;
private enum Mode {
Add,
Remove,
}
private readonly Stopwatch _queueTimer = Stopwatch.StartNew();
internal Vfx(Plugin plugin) {
this.Plugin = plugin;
@ -49,6 +46,9 @@ internal unsafe class Vfx : IDisposable {
}
private void HandleQueues(IFramework framework) {
this._queueTimer.Restart();
while (this._queueTimer.Elapsed < TimeSpan.FromMilliseconds(1)) {
if (!this.Queue.TryDequeue(out var action)) {
return;
}
@ -62,7 +62,7 @@ internal unsafe class Vfx : IDisposable {
this.Queue.Enqueue(new RemoveRawQueueAction(existing));
}
var vfx = this.SpawnStatic(add.Id, add.Path, add.Position, add.Rotation);
var vfx = this.SpawnStatic(add.Path, add.Position, add.Rotation);
this.Spawned[add.Id] = (nint) vfx;
break;
}
@ -76,7 +76,8 @@ internal unsafe class Vfx : IDisposable {
this.RemoveStatic((VfxStruct*) ptr);
break;
};
}
;
case RemoveRawQueueAction remove: {
Plugin.Log.Debug($"removing raw vfx at {remove.Pointer:X}");
@ -85,6 +86,7 @@ internal unsafe class Vfx : IDisposable {
}
}
}
}
internal void RemoveAllSync() {
using var guard = this.Mutex.With();
@ -114,7 +116,7 @@ internal unsafe class Vfx : IDisposable {
}
}
private VfxStruct* SpawnStatic(Guid id, string path, Vector3 pos, Quaternion rotation) {
private VfxStruct* SpawnStatic(string path, Vector3 pos, Quaternion rotation) {
VfxStruct* vfx;
fixed (byte* p = Encoding.UTF8.GetBytes(path).NullTerminate()) {
fixed (byte* pool = Pool) {
@ -131,6 +133,9 @@ internal unsafe class Vfx : IDisposable {
// update rotation
vfx->Rotation = new Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);
// remove flag that sometimes causes vfx to not appear?
vfx->SomeFlags &= 0xF7;
// update
vfx->Flags |= 2;
@ -168,6 +173,9 @@ internal unsafe class Vfx : IDisposable {
[FieldOffset(0x1C0)]
public int StaticTarget;
[FieldOffset(0x248)]
public byte SomeFlags;
}
}