From bea196e4b63af688019071c2fa3145b083b8371b Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Thu, 28 Jan 2021 11:37:36 +0100 Subject: [PATCH] added function to redraw all actors or actors with specific names (inspired by / shamelessly stolen from Anamnesis). --- Penumbra/Game/RefreshActors.cs | 62 ++++++++++++++++++++++++++++++++++ Penumbra/Plugin.cs | 9 +++++ Penumbra/UI/TabSettings.cs | 1 + 3 files changed, 72 insertions(+) create mode 100644 Penumbra/Game/RefreshActors.cs diff --git a/Penumbra/Game/RefreshActors.cs b/Penumbra/Game/RefreshActors.cs new file mode 100644 index 00000000..c5da4c47 --- /dev/null +++ b/Penumbra/Game/RefreshActors.cs @@ -0,0 +1,62 @@ +using System.Runtime.InteropServices; +using Dalamud.Game.ClientState.Actors; +using Dalamud.Game.ClientState.Actors.Types; +using System.Threading.Tasks; + +namespace Penumbra +{ + public static class RefreshActors + { + private const int ObjectKindOffset = 0x008C; + private const int RenderModeOffset = 0x0104; + private const int RenderTaskDelay = 75; + + private enum RenderMode : int + { + Draw = 0, + Unload = 2 + } + + private static async void Redraw(Actor actor) + { + var ptr = actor.Address; + var objectKindPtr = ptr + ObjectKindOffset; + var renderModePtr = ptr + RenderModeOffset; + + async void DrawObject() + { + Marshal.WriteInt32(renderModePtr, (int) RenderMode.Unload); + await Task.Delay(RenderTaskDelay); + Marshal.WriteInt32(renderModePtr, (int) RenderMode.Draw); + } + + if (actor.ObjectKind == Dalamud.Game.ClientState.Actors.ObjectKind.Player) + { + Marshal.WriteByte(objectKindPtr, (byte) Dalamud.Game.ClientState.Actors.ObjectKind.BattleNpc); + DrawObject(); + await Task.Delay(RenderTaskDelay); + Marshal.WriteByte(objectKindPtr, (byte) Dalamud.Game.ClientState.Actors.ObjectKind.Player); + Marshal.WriteInt32(renderModePtr, (int) RenderMode.Draw); + } + else + DrawObject(); + await Task.Delay(RenderTaskDelay); + } + + public static void RedrawSpecific(ActorTable actors, string name) + { + if (name?.Length == 0) + RedrawAll(actors); + + foreach (var actor in actors) + if (actor.Name == name) + Redraw(actor); + } + + public static void RedrawAll(ActorTable actors) + { + foreach (var actor in actors) + Redraw(actor); + } + } +} diff --git a/Penumbra/Plugin.cs b/Penumbra/Plugin.cs index 1bf4bf39..b8ee98b2 100644 --- a/Penumbra/Plugin.cs +++ b/Penumbra/Plugin.cs @@ -1,3 +1,4 @@ +using System.Linq; using Dalamud.Game.Command; using Dalamud.Plugin; using EmbedIO; @@ -118,6 +119,14 @@ namespace Penumbra $"Reloaded Penumbra mods. You have {ModManager.Mods.ModSettings.Count} mods, {ModManager.Mods.EnabledMods.Length} of which are enabled." ); break; + } + case "redraw": + { + if (args.Length > 1) + RefreshActors.RedrawSpecific(PluginInterface.ClientState.Actors, string.Join(" ", args.Skip(1))); + else + RefreshActors.RedrawAll(PluginInterface.ClientState.Actors); + break; } } diff --git a/Penumbra/UI/TabSettings.cs b/Penumbra/UI/TabSettings.cs index 2ebab4d4..a6e4d389 100644 --- a/Penumbra/UI/TabSettings.cs +++ b/Penumbra/UI/TabSettings.cs @@ -64,6 +64,7 @@ namespace Penumbra.UI { _config.IsEnabled = enabled; _configChanged = true; + RefreshActors.RedrawAll(_base._plugin.PluginInterface.ClientState.Actors); } }