Skip to content

Commit

Permalink
Bunch of work
Browse files Browse the repository at this point in the history
  • Loading branch information
AsgardXIV committed Jan 16, 2023
1 parent e8a43fb commit 92ba5b5
Show file tree
Hide file tree
Showing 19 changed files with 572 additions and 107 deletions.
52 changes: 34 additions & 18 deletions Brio/Brio.cs
Original file line number Diff line number Diff line change
@@ -1,52 +1,68 @@
using Brio.Game.Actor;
using Brio.Config;
using Brio.Game.Actor;
using Brio.Game.Chat;
using Brio.Game.GPose;
using Brio.UI.Windows;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
using System;
using Brio.Game.Render;
using Brio.UI;

namespace Brio;

public static class Brio
{
public const string PluginName = "Brio";
public static string PluginVersion = typeof(Brio).Assembly.GetName().Version!.ToString(fieldCount: 3);

public static WindowSystem WindowSystem { get; private set; } = null!;

public static Configuration Configuration { get; private set; } = null!;
public static GPoseService GPoseService { get; private set; } = null!;
public static ActorSpawnService ActorSpawnService { get; private set; } = null!;
public static ActorRedrawService ActorRedrawService { get; private set; } = null!;

public static UIContainer UI { get; private set; } = null!;
public static RenderHooks RenderHooks { get; set; } = null!;

private static CommandHandler CommandHandler { get; set; } = null!;
private static BrioWindow BrioWindow { get; set; } = null!;

public static void Initialize()
{
WindowSystem = new(PluginName);
Configuration = Dalamud.PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();

CommandHandler = new();

GPoseService = new GPoseService();
ActorSpawnService = new ActorSpawnService();
ActorRedrawService = new ActorRedrawService();
RenderHooks= new RenderHooks();

UI = new UIContainer();

BrioWindow = new();
WindowSystem.AddWindow(BrioWindow);
StartupLogic();
}

public static void Destroy()
private static void StartupLogic()
{
CommandHandler.Dispose();
if(Configuration.IsFirstTimeUser)
{
UI.InfoWindow.IsOpen = true;
Configuration.IsFirstTimeUser = false;
}

ActorSpawnService.Dispose();
GPoseService.Dispose();
if(Configuration.OpenBrioBehavior == OpenBrioBehavior.OnPluginStartup)
UI.MainWindow.IsOpen = true;

WindowSystem.RemoveWindow(BrioWindow);
if (Configuration.OpenBrioBehavior == OpenBrioBehavior.OnGPoseEnter && GPoseService.IsInGPose)
UI.MainWindow.IsOpen = true;
}

public static void Toggle()
public static void Destroy()
{
BrioWindow.Toggle();
Dalamud.PluginInterface.SavePluginConfig(Configuration);

UI.Dispose();

RenderHooks.Dispose();
GPoseService.Dispose();
ActorSpawnService.Dispose();
ActorRedrawService.Dispose();
CommandHandler.Dispose();
}
}
36 changes: 36 additions & 0 deletions Brio/Config/Configuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Dalamud.Configuration;
using System;

namespace Brio.Config;

[Serializable]
public class Configuration : IPluginConfiguration
{
public const int CurrentVersion = 1;
public int Version { get; set; } = CurrentVersion;

// First Time User
public bool IsFirstTimeUser { get; set; } = true;

// Interface
public OpenBrioBehavior OpenBrioBehavior { get; set; } = OpenBrioBehavior.OnGPoseEnter;
public bool ShowInCutscene { get; set; } = false;
public bool ShowWhenUIHidden { get; set; } = false;

// Hooks
public ApplyNPCHack ApplyNPCHack { get; set; } = ApplyNPCHack.InGPose;
}

public enum OpenBrioBehavior
{
Manual,
OnGPoseEnter,
OnPluginStartup
}

public enum ApplyNPCHack
{
Manual,
InGPose,
Always
}
47 changes: 47 additions & 0 deletions Brio/Game/Actor/ActorRedrawService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Dalamud.Game.ClientState.Objects.Enums;
using System;
using DalamudGameObject = Dalamud.Game.ClientState.Objects.Types.GameObject;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;

namespace Brio.Game.Actor;

public class ActorRedrawService : IDisposable
{
public unsafe void StandardRedraw(DalamudGameObject gameObject)
{
GameObject* raw = (GameObject*)gameObject.Address;
raw->DisableDraw();
raw->EnableDraw();
}

public unsafe void ModernNPCHackRedraw(DalamudGameObject gameObject)
{
var wasEnabled = Brio.RenderHooks.ApplyNPCOverride;

Brio.RenderHooks.ApplyNPCOverride = true;

GameObject* raw = (GameObject*)gameObject.Address;
raw->DisableDraw();
raw->EnableDraw();

Brio.RenderHooks.ApplyNPCOverride = wasEnabled;

}

public unsafe void LegacyNPCHackRedraw(DalamudGameObject gameObject)
{
GameObject* raw = (GameObject*)gameObject.Address;
if (raw->ObjectKind == (byte)ObjectKind.Player)
{
raw->DisableDraw();
raw->ObjectKind = (byte)ObjectKind.BattleNpc;
raw->EnableDraw();
raw->ObjectKind = (byte)ObjectKind.Player;
}
}

public void Dispose()
{

}
}
2 changes: 1 addition & 1 deletion Brio/Game/Chat/CommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public CommandHandler()

private void OnCommand(string command, string arguments)
{
Brio.Toggle();
Brio.UI.MainWindow.Toggle();
}

public void Dispose()
Expand Down
17 changes: 15 additions & 2 deletions Brio/Game/GPose/GPoseService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public class GPoseService : IDisposable
public delegate void OnGPoseStateChangeDelegate(bool isInGpose);
public event OnGPoseStateChangeDelegate? OnGPoseStateChange;

private const int GPoseFirstActor = 201;
private const int GPoseActorCount = 39;

public GPoseService()
{
Expand All @@ -26,16 +28,27 @@ private void Framework_Update(global::Dalamud.Game.Framework framework)
if(_lastGPoseState != IsInGPose)
{
_lastGPoseState = IsInGPose;
OnGPoseStateChange?.Invoke(_lastGPoseState);
HandleGPoseChange(_lastGPoseState);
}
}

private void HandleGPoseChange(bool newGPoseState)
{
if(newGPoseState)
{
if (Brio.Configuration.OpenBrioBehavior == Config.OpenBrioBehavior.OnGPoseEnter)
Brio.UI.MainWindow.IsOpen = true;
}

OnGPoseStateChange?.Invoke(newGPoseState);
}

public List<GameObject> GPoseObjects
{
get
{
List<GameObject> objects = new();
for(int i = 201; i < 240; ++i)
for(int i = GPoseFirstActor; i < GPoseFirstActor + GPoseActorCount; ++i)
{
var go = Dalamud.ObjectTable[i];
if (go != null)
Expand Down
47 changes: 47 additions & 0 deletions Brio/Game/Render/RenderHooks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Dalamud.Hooking;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using System;

namespace Brio.Game.Render;

public unsafe class RenderHooks : IDisposable
{
public bool ApplyNPCOverride { get; set; } = false;

private delegate long EnforceKindRestrictionsDelegate(void* a1, void* a2);
private Hook<EnforceKindRestrictionsDelegate> EnforceKindRestrictionsHook = null!;

public RenderHooks()
{
var proj = Dalamud.SigScanner.ScanText("E8 ?? ?? ?? ?? 41 B0 ?? 48 8B D3 48 8B CD");
EnforceKindRestrictionsHook = Hook<EnforceKindRestrictionsDelegate>.FromAddress(proj, EnforceKindRestrictionsDetour);

EnforceKindRestrictionsHook.Enable();

Brio.GPoseService.OnGPoseStateChange += GPoseService_OnGPoseStateChange;

GPoseService_OnGPoseStateChange(Brio.GPoseService.IsInGPose);
}

private void GPoseService_OnGPoseStateChange(bool isInGpose)
{
var npcOverrideBehavior = Brio.Configuration.ApplyNPCHack;
if (npcOverrideBehavior == Config.ApplyNPCHack.InGPose)
{
ApplyNPCOverride = isInGpose;
}
}

private long EnforceKindRestrictionsDetour(void* a1, void* a2)
{
if (ApplyNPCOverride || Brio.Configuration.ApplyNPCHack == Config.ApplyNPCHack.Always)
return 0;

return EnforceKindRestrictionsHook.Original(a1, a2);
}

public void Dispose()
{
EnforceKindRestrictionsHook.Dispose();
}
}
7 changes: 0 additions & 7 deletions Brio/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,9 @@ public Plugin(DalamudPluginInterface pluginInterface)
{
Dalamud.Initialize(pluginInterface);
Brio.Initialize();
Dalamud.PluginInterface.UiBuilder.Draw += Brio.WindowSystem.Draw;

Dalamud.PluginInterface.UiBuilder.DisableGposeUiHide = true;
Dalamud.PluginInterface.UiBuilder.DisableCutsceneUiHide = true;
Dalamud.PluginInterface.UiBuilder.DisableUserUiHide = true;
}

public void Dispose()
{
Dalamud.PluginInterface.UiBuilder.Draw -= Brio.WindowSystem.Draw;
Brio.Destroy();
Dalamud.Destroy();
}
Expand Down
26 changes: 26 additions & 0 deletions Brio/UI/Components/ActorPropertyControls.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Brio.Utils;
using Dalamud.Game.ClientState.Objects.Types;
using ImGuiNET;

namespace Brio.UI.Components;

public static class ActorPropertyControls
{
public unsafe static void Draw(GameObject gameObject)
{
string name = gameObject.Name.ToString();
string originalName = name;

ImGui.PushItemWidth(ImGui.GetContentRegionAvail().X - ImGui.CalcTextSize("Name").X);

if (ImGui.InputText("Name", ref name, 63))
{
if (name != originalName)
{
gameObject.SetName(name);
}
}

ImGui.PopItemWidth();
}
}
21 changes: 21 additions & 0 deletions Brio/UI/Components/ActorRedrawControls.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Dalamud.Game.ClientState.Objects.Types;
using ImGuiNET;

namespace Brio.UI.Components;

public static class ActorRedrawControls
{
public unsafe static void Draw(GameObject gameObject)
{
if(ImGui.Button("Redraw"))
Brio.ActorRedrawService.StandardRedraw(gameObject);

ImGui.SameLine();

if (ImGui.Button("Modern NPC Redraw"))
Brio.ActorRedrawService.ModernNPCHackRedraw(gameObject);

if (ImGui.Button("Legacy NPC Redraw"))
Brio.ActorRedrawService.LegacyNPCHackRedraw(gameObject);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Brio.UI.Components;

public static class GPoseGlobalControls
public static class ActorTabControls
{
private static GPoseActorSelector _selector = new GPoseActorSelector();

Expand All @@ -16,7 +16,7 @@ public unsafe static void Draw()

if (!inGPose) ImGui.BeginDisabled();

if (ImGui.CollapsingHeader("GPose Actors", ImGuiTreeNodeFlags.DefaultOpen))
if (ImGui.CollapsingHeader("Actors", ImGuiTreeNodeFlags.DefaultOpen))
{
_selector.Draw();

Expand Down Expand Up @@ -65,7 +65,19 @@ public unsafe static void Draw()
{
if(_selector.SelectedObject != null)
{
GPoseActorPropertyControls.Draw(_selector.SelectedObject);
ActorPropertyControls.Draw(_selector.SelectedObject);
}
else
{
ImGui.Text("No actor selected.");
}
}

if (ImGui.CollapsingHeader("Actor Redraw"))
{
if (_selector.SelectedObject != null)
{
ActorRedrawControls.Draw(_selector.SelectedObject);
}
else
{
Expand All @@ -74,5 +86,6 @@ public unsafe static void Draw()
}

if (!inGPose) ImGui.EndDisabled();

}
}
Loading

0 comments on commit 92ba5b5

Please sign in to comment.