mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Add even more handling for stupid banners and some debug info for them.
This commit is contained in:
parent
fe561f39c2
commit
5997ddca02
3 changed files with 165 additions and 18 deletions
|
|
@ -205,18 +205,23 @@ public sealed partial class ActorManager : IDisposable
|
||||||
public unsafe bool ResolvePartyBannerPlayer(ScreenActor type, out ActorIdentifier id)
|
public unsafe bool ResolvePartyBannerPlayer(ScreenActor type, out ActorIdentifier id)
|
||||||
{
|
{
|
||||||
id = ActorIdentifier.Invalid;
|
id = ActorIdentifier.Invalid;
|
||||||
var addon = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.BannerParty);
|
var module = Framework.Instance()->GetUiModule()->GetAgentModule();
|
||||||
if (addon == null || !addon->IsAgentActive())
|
if (module == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var idx = (ushort)type - (ushort)ScreenActor.CharacterScreen;
|
var agent = (AgentBannerInterface*)module->GetAgentByInternalId(AgentId.BannerParty);
|
||||||
if (idx is < 0 or > 7)
|
if (agent == null || !agent->AgentInterface.IsAgentActive())
|
||||||
|
agent = (AgentBannerInterface*)module->GetAgentByInternalId(AgentId.BannerMIP);
|
||||||
|
if (agent == null || !agent->AgentInterface.IsAgentActive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var idx = (ushort)type - (ushort)ScreenActor.CharacterScreen;
|
||||||
|
var character = agent->Character(idx);
|
||||||
|
if (character == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var obj = GroupManager.Instance()->GetPartyMemberByIndex(idx);
|
var name = new ByteString(character->Name1.StringPtr);
|
||||||
if (obj != null)
|
id = CreatePlayer(name, (ushort)character->WorldId);
|
||||||
id = CreatePlayer(new ByteString(obj->Name), obj->HomeWorld);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
91
Penumbra.GameData/Actors/AgentBannerParty.cs
Normal file
91
Penumbra.GameData/Actors/AgentBannerParty.cs
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.System.String;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
||||||
|
|
||||||
|
namespace Penumbra;
|
||||||
|
|
||||||
|
[StructLayout( LayoutKind.Explicit )]
|
||||||
|
public unsafe struct AgentBannerInterface
|
||||||
|
{
|
||||||
|
[FieldOffset( 0x0 )] public AgentInterface AgentInterface;
|
||||||
|
[FieldOffset( 0x28 )] public BannerInterfaceStorage* Data;
|
||||||
|
|
||||||
|
public BannerInterfaceStorage.CharacterData* Character( int idx )
|
||||||
|
=> idx switch
|
||||||
|
{
|
||||||
|
_ when Data == null => null,
|
||||||
|
0 => &Data->Character1,
|
||||||
|
1 => &Data->Character2,
|
||||||
|
2 => &Data->Character3,
|
||||||
|
3 => &Data->Character4,
|
||||||
|
4 => &Data->Character5,
|
||||||
|
5 => &Data->Character6,
|
||||||
|
6 => &Data->Character7,
|
||||||
|
7 => &Data->Character8,
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public unsafe struct AgentBannerParty
|
||||||
|
{
|
||||||
|
public static AgentBannerParty* Instance() => ( AgentBannerParty* )Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId( AgentId.BannerParty );
|
||||||
|
|
||||||
|
[FieldOffset( 0x0 )] public AgentBannerInterface AgentBannerInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout( LayoutKind.Explicit )]
|
||||||
|
public unsafe struct AgentBannerMIP
|
||||||
|
{
|
||||||
|
public static AgentBannerMIP* Instance() => ( AgentBannerMIP* )Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId( AgentId.BannerMIP );
|
||||||
|
[FieldOffset( 0x0 )] public AgentBannerInterface AgentBannerInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client::UI::Agent::AgentBannerInterface::Storage
|
||||||
|
// destructed in Client::UI::Agent::AgentBannerInterface::dtor
|
||||||
|
[StructLayout( LayoutKind.Explicit, Size = 0x3BB0 )]
|
||||||
|
public unsafe struct BannerInterfaceStorage
|
||||||
|
{
|
||||||
|
// vtable: 48 8D 05 ?? ?? ?? ?? 48 89 01 48 8B F9 7E
|
||||||
|
// dtor: E8 ?? ?? ?? ?? 48 83 EF ?? 75 ?? BA ?? ?? ?? ?? 48 8B CE E8 ?? ?? ?? ?? 48 89 7D
|
||||||
|
[StructLayout( LayoutKind.Explicit, Size = 0x770 )]
|
||||||
|
public struct CharacterData
|
||||||
|
{
|
||||||
|
[FieldOffset( 0x000 )] public void** VTable;
|
||||||
|
|
||||||
|
[FieldOffset( 0x018 )] public Utf8String Name1;
|
||||||
|
[FieldOffset( 0x080 )] public Utf8String Name2;
|
||||||
|
[FieldOffset( 0x0E8 )] public Utf8String UnkString1;
|
||||||
|
[FieldOffset( 0x150 )] public Utf8String UnkString2;
|
||||||
|
[FieldOffset( 0x1C0 )] public Utf8String Job;
|
||||||
|
[FieldOffset( 0x238 )] public uint WorldId;
|
||||||
|
[FieldOffset( 0x240 )] public Utf8String UnkString3;
|
||||||
|
|
||||||
|
[FieldOffset( 0x2B0 )] public void* CharaView;
|
||||||
|
[FieldOffset( 0x5D0 )] public AtkTexture AtkTexture;
|
||||||
|
|
||||||
|
[FieldOffset( 0x6F8 )] public Utf8String Title;
|
||||||
|
[FieldOffset( 0x768 )] public void* SomePointer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[FieldOffset( 0x0000 )] public void* Agent; // AgentBannerParty, maybe other Banner agents
|
||||||
|
[FieldOffset( 0x0008 )] public UIModule* UiModule;
|
||||||
|
[FieldOffset( 0x0010 )] public uint Unk1; // Maybe count or bitfield, but probably not
|
||||||
|
[FieldOffset( 0x0014 )] public uint Unk2;
|
||||||
|
|
||||||
|
[FieldOffset( 0x0020 )] public CharacterData Character1;
|
||||||
|
[FieldOffset( 0x0790 )] public CharacterData Character2;
|
||||||
|
[FieldOffset( 0x0F00 )] public CharacterData Character3;
|
||||||
|
[FieldOffset( 0x1670 )] public CharacterData Character4;
|
||||||
|
[FieldOffset( 0x1DE0 )] public CharacterData Character5;
|
||||||
|
[FieldOffset( 0x2550 )] public CharacterData Character6;
|
||||||
|
[FieldOffset( 0x2CC0 )] public CharacterData Character7;
|
||||||
|
[FieldOffset( 0x3430 )] public CharacterData Character8;
|
||||||
|
|
||||||
|
[FieldOffset( 0x3BA0 )] public long Unk3;
|
||||||
|
[FieldOffset( 0x3BA8 )] public long Unk4;
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,11 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game.Group;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
|
@ -17,6 +19,7 @@ using Penumbra.Interop.Resolver;
|
||||||
using Penumbra.Interop.Structs;
|
using Penumbra.Interop.Structs;
|
||||||
using Penumbra.String;
|
using Penumbra.String;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
|
using static OtterGui.Raii.ImRaii;
|
||||||
using CharacterUtility = Penumbra.Interop.CharacterUtility;
|
using CharacterUtility = Penumbra.Interop.CharacterUtility;
|
||||||
using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
|
using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
|
||||||
|
|
||||||
|
|
@ -223,7 +226,8 @@ public partial class ConfigWindow
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TextUnformatted( $"Last Game Object: 0x{_window._penumbra.PathResolver.LastGameObject:X} ({_window._penumbra.PathResolver.LastGameObjectData.ModCollection.Name})" );
|
ImGui.TextUnformatted(
|
||||||
|
$"Last Game Object: 0x{_window._penumbra.PathResolver.LastGameObject:X} ({_window._penumbra.PathResolver.LastGameObjectData.ModCollection.Name})" );
|
||||||
using( var drawTree = ImRaii.TreeNode( "Draw Object to Object" ) )
|
using( var drawTree = ImRaii.TreeNode( "Draw Object to Object" ) )
|
||||||
{
|
{
|
||||||
if( drawTree )
|
if( drawTree )
|
||||||
|
|
@ -317,18 +321,65 @@ public partial class ConfigWindow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using var cutsceneTree = ImRaii.TreeNode( "Cutscene Actors" );
|
using( var cutsceneTree = ImRaii.TreeNode( "Cutscene Actors" ) )
|
||||||
if( cutsceneTree )
|
|
||||||
{
|
{
|
||||||
using var table = ImRaii.Table( "###PCutsceneResolverTable", 2, ImGuiTableFlags.SizingFixedFit );
|
if( cutsceneTree )
|
||||||
if( table )
|
|
||||||
{
|
{
|
||||||
foreach( var (idx, actor) in _window._penumbra.PathResolver.CutsceneActors )
|
using var table = ImRaii.Table( "###PCutsceneResolverTable", 2, ImGuiTableFlags.SizingFixedFit );
|
||||||
|
if( table )
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
foreach( var (idx, actor) in _window._penumbra.PathResolver.CutsceneActors )
|
||||||
ImGui.TextUnformatted( $"Cutscene Actor {idx}" );
|
{
|
||||||
ImGui.TableNextColumn();
|
ImGuiUtil.DrawTableColumn( $"Cutscene Actor {idx}" );
|
||||||
ImGui.TextUnformatted( actor.Name.ToString() );
|
ImGuiUtil.DrawTableColumn( actor.Name.ToString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using( var groupTree = ImRaii.TreeNode( "Group" ) )
|
||||||
|
{
|
||||||
|
if( groupTree )
|
||||||
|
{
|
||||||
|
using var table = ImRaii.Table( "###PGroupTable", 2, ImGuiTableFlags.SizingFixedFit );
|
||||||
|
if( table )
|
||||||
|
{
|
||||||
|
ImGuiUtil.DrawTableColumn( "Group Members" );
|
||||||
|
ImGuiUtil.DrawTableColumn( GroupManager.Instance()->MemberCount.ToString() );
|
||||||
|
for( var i = 0; i < 8; ++i )
|
||||||
|
{
|
||||||
|
ImGuiUtil.DrawTableColumn( $"Member #{i}" );
|
||||||
|
var member = GroupManager.Instance()->GetPartyMemberByIndex( i );
|
||||||
|
ImGuiUtil.DrawTableColumn( member == null ? "NULL" : new ByteString( member->Name ).ToString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using( var bannerTree = ImRaii.TreeNode( "Party Banner" ) )
|
||||||
|
{
|
||||||
|
if( bannerTree )
|
||||||
|
{
|
||||||
|
var agent = &AgentBannerParty.Instance()->AgentBannerInterface;
|
||||||
|
if( agent->Data == null )
|
||||||
|
agent = &AgentBannerMIP.Instance()->AgentBannerInterface;
|
||||||
|
if( agent->Data != null )
|
||||||
|
{
|
||||||
|
using var table = ImRaii.Table( "###PBannerTable", 2, ImGuiTableFlags.SizingFixedFit );
|
||||||
|
if( table )
|
||||||
|
{
|
||||||
|
for( var i = 0; i < 8; ++i )
|
||||||
|
{
|
||||||
|
var c = agent->Character( i );
|
||||||
|
ImGuiUtil.DrawTableColumn( $"Character {i}" );
|
||||||
|
var name = c->Name1.ToString();
|
||||||
|
ImGuiUtil.DrawTableColumn( name.Length == 0 ? "NULL" : $"{name} ({c->WorldId})" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted( "INACTIVE" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue