fix: prevent vfx from spawning invisible
This commit is contained in:
parent
689984ee3e
commit
8d8cf0b99b
@ -1,3 +1,4 @@
|
|||||||
|
using System.Numerics;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OrangeGuidanceTomestone.Ui;
|
using OrangeGuidanceTomestone.Ui;
|
||||||
@ -102,11 +103,11 @@ public class PluginUi : IDisposable {
|
|||||||
var label = msg.Id.ToString("N");
|
var label = msg.Id.ToString("N");
|
||||||
var size = ImGui.CalcTextSize(label);
|
var size = ImGui.CalcTextSize(label);
|
||||||
ImGui.GetBackgroundDrawList().AddRectFilled(
|
ImGui.GetBackgroundDrawList().AddRectFilled(
|
||||||
screen,
|
screen - Vector2.One * 4 * ImGuiHelpers.GlobalScale,
|
||||||
screen + size,
|
screen + size + Vector2.One * 4 * ImGuiHelpers.GlobalScale,
|
||||||
0xff000000
|
0xff000000
|
||||||
);
|
);
|
||||||
ImGui.GetForegroundDrawList().AddText(screen, 0xffffffff, label);
|
ImGui.GetBackgroundDrawList().AddText(screen, 0xffffffff, label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using Dalamud.Utility;
|
|||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using OrangeGuidanceTomestone.Helpers;
|
using OrangeGuidanceTomestone.Helpers;
|
||||||
|
using OrangeGuidanceTomestone.Util;
|
||||||
|
|
||||||
namespace OrangeGuidanceTomestone.Ui.MainWindowTabs;
|
namespace OrangeGuidanceTomestone.Ui.MainWindowTabs;
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ internal class Settings : ITab {
|
|||||||
private IReadOnlyList<(string, DrawSettingsDelegate)> Tabs { get; }
|
private IReadOnlyList<(string, DrawSettingsDelegate)> Tabs { get; }
|
||||||
|
|
||||||
private string _filter = string.Empty;
|
private string _filter = string.Empty;
|
||||||
|
private string _debugFilter = string.Empty;
|
||||||
|
|
||||||
internal Settings(Plugin plugin) {
|
internal Settings(Plugin plugin) {
|
||||||
this.Plugin = plugin;
|
this.Plugin = plugin;
|
||||||
@ -230,6 +232,47 @@ internal class Settings : ITab {
|
|||||||
|
|
||||||
private void DrawDebug(ref bool anyChanged, ref bool vfx) {
|
private void DrawDebug(ref bool anyChanged, ref bool vfx) {
|
||||||
ImGui.Checkbox("Show debug information", ref this.Plugin.Ui.Debug);
|
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() {
|
private void ExtraCodeInput() {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -21,15 +22,11 @@ internal unsafe class Vfx : IDisposable {
|
|||||||
private readonly delegate* unmanaged<VfxStruct*, nint> _staticVfxRemove;
|
private readonly delegate* unmanaged<VfxStruct*, nint> _staticVfxRemove;
|
||||||
|
|
||||||
private Plugin Plugin { get; }
|
private Plugin Plugin { get; }
|
||||||
private SemaphoreSlim Mutex { get; } = new(1, 1);
|
internal SemaphoreSlim Mutex { get; } = new(1, 1);
|
||||||
private Dictionary<Guid, nint> Spawned { get; } = [];
|
internal Dictionary<Guid, nint> Spawned { get; } = [];
|
||||||
private Queue<IQueueAction> Queue { get; } = [];
|
private Queue<IQueueAction> Queue { get; } = [];
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
private readonly Stopwatch _queueTimer = Stopwatch.StartNew();
|
||||||
private enum Mode {
|
|
||||||
Add,
|
|
||||||
Remove,
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Vfx(Plugin plugin) {
|
internal Vfx(Plugin plugin) {
|
||||||
this.Plugin = plugin;
|
this.Plugin = plugin;
|
||||||
@ -49,39 +46,44 @@ internal unsafe class Vfx : IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void HandleQueues(IFramework framework) {
|
private void HandleQueues(IFramework framework) {
|
||||||
if (!this.Queue.TryDequeue(out var action)) {
|
this._queueTimer.Restart();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (action) {
|
while (this._queueTimer.Elapsed < TimeSpan.FromMilliseconds(1)) {
|
||||||
case AddQueueAction add: {
|
if (!this.Queue.TryDequeue(out var action)) {
|
||||||
using var guard = this.Mutex.With();
|
return;
|
||||||
Plugin.Log.Debug($"adding vfx for {add.Id}");
|
|
||||||
if (this.Spawned.Remove(add.Id, out var existing)) {
|
|
||||||
Plugin.Log.Warning($"vfx for {add.Id} already exists, queuing remove");
|
|
||||||
this.Queue.Enqueue(new RemoveRawQueueAction(existing));
|
|
||||||
}
|
|
||||||
|
|
||||||
var vfx = this.SpawnStatic(add.Id, add.Path, add.Position, add.Rotation);
|
|
||||||
this.Spawned[add.Id] = (nint) vfx;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case RemoveQueueAction remove: {
|
switch (action) {
|
||||||
using var guard = this.Mutex.With();
|
case AddQueueAction add: {
|
||||||
Plugin.Log.Debug($"removing vfx for {remove.Id}");
|
using var guard = this.Mutex.With();
|
||||||
if (!this.Spawned.Remove(remove.Id, out var ptr)) {
|
Plugin.Log.Debug($"adding vfx for {add.Id}");
|
||||||
|
if (this.Spawned.Remove(add.Id, out var existing)) {
|
||||||
|
Plugin.Log.Warning($"vfx for {add.Id} already exists, queuing remove");
|
||||||
|
this.Queue.Enqueue(new RemoveRawQueueAction(existing));
|
||||||
|
}
|
||||||
|
|
||||||
|
var vfx = this.SpawnStatic(add.Path, add.Position, add.Rotation);
|
||||||
|
this.Spawned[add.Id] = (nint) vfx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.RemoveStatic((VfxStruct*) ptr);
|
case RemoveQueueAction remove: {
|
||||||
break;
|
using var guard = this.Mutex.With();
|
||||||
};
|
Plugin.Log.Debug($"removing vfx for {remove.Id}");
|
||||||
|
if (!this.Spawned.Remove(remove.Id, out var ptr)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case RemoveRawQueueAction remove: {
|
this.RemoveStatic((VfxStruct*) ptr);
|
||||||
Plugin.Log.Debug($"removing raw vfx at {remove.Pointer:X}");
|
break;
|
||||||
this.RemoveStatic((VfxStruct*) remove.Pointer);
|
}
|
||||||
break;
|
;
|
||||||
|
|
||||||
|
case RemoveRawQueueAction remove: {
|
||||||
|
Plugin.Log.Debug($"removing raw vfx at {remove.Pointer:X}");
|
||||||
|
this.RemoveStatic((VfxStruct*) remove.Pointer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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;
|
VfxStruct* vfx;
|
||||||
fixed (byte* p = Encoding.UTF8.GetBytes(path).NullTerminate()) {
|
fixed (byte* p = Encoding.UTF8.GetBytes(path).NullTerminate()) {
|
||||||
fixed (byte* pool = Pool) {
|
fixed (byte* pool = Pool) {
|
||||||
@ -131,6 +133,9 @@ internal unsafe class Vfx : IDisposable {
|
|||||||
// update rotation
|
// update rotation
|
||||||
vfx->Rotation = new Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);
|
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
|
// update
|
||||||
vfx->Flags |= 2;
|
vfx->Flags |= 2;
|
||||||
|
|
||||||
@ -168,6 +173,9 @@ internal unsafe class Vfx : IDisposable {
|
|||||||
|
|
||||||
[FieldOffset(0x1C0)]
|
[FieldOffset(0x1C0)]
|
||||||
public int StaticTarget;
|
public int StaticTarget;
|
||||||
|
|
||||||
|
[FieldOffset(0x248)]
|
||||||
|
public byte SomeFlags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user