fix: change vfx spawn/remove methods

This commit is contained in:
Anna 2024-07-05 17:24:50 -04:00
parent 4976a2e0df
commit bcfd8411f0
Signed by: anna
GPG Key ID: D0943384CD9F87D1
2 changed files with 51 additions and 25 deletions

View File

@ -199,7 +199,7 @@ internal class Messages : IDisposable {
return; return;
} }
this.RemoveVfx(null, null); this.RemoveVfx();
Task.Run(async () => { Task.Run(async () => {
try { try {
@ -243,10 +243,6 @@ internal class Messages : IDisposable {
} }
} }
private void RemoveVfx(object? sender, EventArgs? e) {
this.RemoveVfx();
}
internal void RemoveVfx() { internal void RemoveVfx() {
this.Plugin.Vfx.RemoveAll(); this.Plugin.Vfx.RemoveAll();
} }

View File

@ -1,43 +1,68 @@
using System.Numerics; using System.Numerics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Dalamud.Memory;
using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
namespace OrangeGuidanceTomestone; namespace OrangeGuidanceTomestone;
internal unsafe class Vfx : IDisposable { internal unsafe class Vfx : IDisposable {
private static readonly byte[] Pool = "Client.System.Scheduler.Instance.VfxObject"u8.ToArray(); private static readonly byte[] Pool = "Client.System.Scheduler.Instance.VfxObject\0"u8.ToArray();
[Signature("E8 ?? ?? ?? ?? F3 0F 10 35 ?? ?? ?? ?? 48 89 43 08")] [Signature("E8 ?? ?? ?? ?? F3 0F 10 35 ?? ?? ?? ?? 48 89 43 08")]
private delegate* unmanaged<byte*, byte*, VfxStruct*> _staticVfxCreate; private delegate* unmanaged<byte*, byte*, VfxStruct*> _staticVfxCreate;
[Signature("E8 ?? ?? ?? ?? 8B 4B 7C 85 C9")] [Signature("E8 ?? ?? ?? ?? 8B 4B 7C 85 C9")]
private delegate* unmanaged<VfxStruct*, float, uint, ulong> _staticVfxRun; private delegate* unmanaged<VfxStruct*, float, int, ulong> _staticVfxRun;
[Signature("40 53 48 83 EC 20 48 8B D9 48 8B 89 ?? ?? ?? ?? 48 85 C9 74 28 33 D2 E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9")] [Signature("40 53 48 83 EC 20 48 8B D9 48 8B 89 ?? ?? ?? ?? 48 85 C9 74 28 33 D2 E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9")]
private delegate* unmanaged<VfxStruct*, void> _staticVfxRemove; private delegate* unmanaged<VfxStruct*, nint> _staticVfxRemove;
private Dictionary<Guid, IntPtr> Spawned { get; } = new(); private Plugin Plugin { get; }
private Dictionary<Guid, nint> Spawned { get; } = [];
private Queue<nint> RemoveQueue { get; } = [];
private bool _disposed;
internal Vfx(Plugin plugin) { internal Vfx(Plugin plugin) {
plugin.GameInteropProvider.InitializeFromAttributes(this); this.Plugin = plugin;
this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
this.Plugin.Framework.Update += this.OnFrameworkUpdate;
} }
public void Dispose() { public void Dispose() {
if (this._disposed) {
return;
}
this._disposed = true;
this.RemoveAll(); this.RemoveAll();
} }
internal void RemoveAll() { private void OnFrameworkUpdate(IFramework framework) {
foreach (var spawned in this.Spawned.Values) { if (this._disposed && this.RemoveQueue.Count == 0) {
this.RemoveStatic((VfxStruct*) spawned); this.Plugin.Framework.Update -= this.OnFrameworkUpdate;
} }
this.Spawned.Clear(); if (!this.RemoveQueue.TryDequeue(out var vfx)) {
return;
}
if (!this.RemoveStatic((VfxStruct*) vfx)) {
this.RemoveQueue.Enqueue(vfx);
}
}
internal void RemoveAll() {
foreach (var spawned in this.Spawned.Keys.ToArray()) {
this.RemoveStatic(spawned);
}
} }
internal VfxStruct* SpawnStatic(Guid id, string path, Vector3 pos, Quaternion rotation) { internal VfxStruct* SpawnStatic(Guid id, string path, Vector3 pos, Quaternion rotation) {
VfxStruct* vfx; VfxStruct* vfx;
fixed (byte* p = Encoding.UTF8.GetBytes(path)) { fixed (byte* p = Encoding.UTF8.GetBytes(path).NullTerminate()) {
fixed (byte* pool = Pool) { fixed (byte* pool = Pool) {
vfx = this._staticVfxCreate(p, pool); vfx = this._staticVfxCreate(p, pool);
} }
@ -47,11 +72,6 @@ internal unsafe class Vfx : IDisposable {
return null; return null;
} }
if (this._staticVfxRun(vfx, 0.0f, 0xFFFFFFFF) != 0) {
this.RemoveStatic(vfx);
return null;
}
// update position // update position
vfx->Position = new Vector3(pos.X, pos.Y, pos.Z); vfx->Position = new Vector3(pos.X, pos.Y, pos.Z);
// update rotation // update rotation
@ -60,19 +80,29 @@ internal unsafe class Vfx : IDisposable {
// update // update
vfx->Flags |= 2; vfx->Flags |= 2;
this.Spawned[id] = (IntPtr) vfx; this._staticVfxRun(vfx, 0.0f, -1);
this.Spawned[id] = (nint) vfx;
return vfx; return vfx;
} }
internal void RemoveStatic(VfxStruct* vfx) { internal bool RemoveStatic(VfxStruct* vfx) {
this._staticVfxRemove(vfx); var result = this._staticVfxRemove(vfx);
var success = result != 0;
if (!success) {
this.RemoveQueue.Enqueue((nint) vfx);
}
return success;
} }
internal void RemoveStatic(Guid id) { internal void RemoveStatic(Guid id) {
if (this.Spawned.TryGetValue(id, out var vfx)) { if (!this.Spawned.Remove(id, out var vfx)) {
this.RemoveStatic((VfxStruct*) vfx); return;
} }
this.RemoveStatic((VfxStruct*) vfx);
} }
[StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)]