Chara file data export (#38)
* add rudimentary saving of chara file data * fix building * working prototype for MCDF import and application * adjust code to use streams * rename cache -> storage add ui for import/export mcdf * minor wording adjustments, version bump Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com> Co-authored-by: Stanley Dimant <stanley.dimant@varian.com>
This commit is contained in:
@@ -8,11 +8,14 @@ using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Control;
|
||||
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
|
||||
|
||||
|
||||
namespace MareSynchronos.Utils;
|
||||
|
||||
public delegate void PlayerChange(Dalamud.Game.ClientState.Objects.Types.Character actor);
|
||||
@@ -35,8 +38,12 @@ public class DalamudUtil : IDisposable
|
||||
public event VoidDelegate? DelayedFrameworkUpdate;
|
||||
public event VoidDelegate? ZoneSwitchStart;
|
||||
public event VoidDelegate? ZoneSwitchEnd;
|
||||
public event VoidDelegate? GposeStart;
|
||||
public event VoidDelegate? GposeEnd;
|
||||
public event VoidDelegate? GposeFrameworkUpdate;
|
||||
private DateTime _delayedFrameworkUpdateCheck = DateTime.Now;
|
||||
private bool _sentBetweenAreas = false;
|
||||
public bool IsInGpose { get; private set; } = false;
|
||||
|
||||
public unsafe bool IsGameObjectPresent(IntPtr key)
|
||||
{
|
||||
@@ -84,8 +91,21 @@ public class DalamudUtil : IDisposable
|
||||
_chatGui.Print(se.BuiltString);
|
||||
}
|
||||
|
||||
private void FrameworkOnUpdate(Framework framework)
|
||||
private unsafe void FrameworkOnUpdate(Framework framework)
|
||||
{
|
||||
if (GposeTarget != null && !IsInGpose)
|
||||
{
|
||||
Logger.Debug("Gpose start");
|
||||
IsInGpose = true;
|
||||
GposeStart?.Invoke();
|
||||
}
|
||||
else if (GposeTarget == null && IsInGpose)
|
||||
{
|
||||
Logger.Debug("Gpose end");
|
||||
IsInGpose = false;
|
||||
GposeEnd?.Invoke();
|
||||
}
|
||||
|
||||
if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51] || IsInGpose)
|
||||
{
|
||||
if (!_sentBetweenAreas)
|
||||
@@ -95,6 +115,8 @@ public class DalamudUtil : IDisposable
|
||||
ZoneSwitchStart?.Invoke();
|
||||
}
|
||||
|
||||
if (IsInGpose) GposeFrameworkUpdate?.Invoke();
|
||||
|
||||
return;
|
||||
}
|
||||
else if (_sentBetweenAreas)
|
||||
@@ -175,6 +197,10 @@ public class DalamudUtil : IDisposable
|
||||
return _objectTable.CreateObjectReference(reference);
|
||||
}
|
||||
|
||||
public unsafe GameObject* GposeTarget => TargetSystem.Instance()->GPoseTarget;
|
||||
|
||||
public unsafe Dalamud.Game.ClientState.Objects.Types.GameObject? GposeTargetGameObject => GposeTarget == null ? null : _objectTable[GposeTarget->ObjectIndex];
|
||||
|
||||
public bool IsLoggedIn { get; private set; }
|
||||
|
||||
public bool IsPlayerPresent => _clientState.LocalPlayer != null && _clientState.LocalPlayer.IsValid();
|
||||
@@ -186,21 +212,21 @@ public class DalamudUtil : IDisposable
|
||||
|
||||
public unsafe IntPtr GetMinion()
|
||||
{
|
||||
return (IntPtr)((Character*)PlayerPointer)->CompanionObject;
|
||||
return (IntPtr)((FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)PlayerPointer)->CompanionObject;
|
||||
}
|
||||
|
||||
public unsafe IntPtr GetPet(IntPtr? playerPointer = null)
|
||||
{
|
||||
var mgr = CharacterManager.Instance();
|
||||
if (playerPointer == null) playerPointer = PlayerPointer;
|
||||
return (IntPtr)mgr->LookupPetByOwnerObject((BattleChara*)playerPointer);
|
||||
return (IntPtr)mgr->LookupPetByOwnerObject((FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara*)playerPointer);
|
||||
}
|
||||
|
||||
public unsafe IntPtr GetCompanion(IntPtr? playerPointer = null)
|
||||
{
|
||||
var mgr = CharacterManager.Instance();
|
||||
if (playerPointer == null) playerPointer = PlayerPointer;
|
||||
return (IntPtr)mgr->LookupBuddyByOwnerObject((BattleChara*)playerPointer);
|
||||
return (IntPtr)mgr->LookupBuddyByOwnerObject((FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara*)playerPointer);
|
||||
}
|
||||
|
||||
public string PlayerName => _clientState.LocalPlayer?.Name.ToString() ?? "--";
|
||||
@@ -211,8 +237,6 @@ public class DalamudUtil : IDisposable
|
||||
|
||||
public string PlayerNameHashed => Crypto.GetHash256(PlayerName + _clientState.LocalPlayer!.HomeWorld.Id);
|
||||
|
||||
public bool IsInGpose => _objectTable[201] != null;
|
||||
|
||||
public List<PlayerCharacter> GetPlayerCharacters()
|
||||
{
|
||||
return _objectTable.Where(obj =>
|
||||
@@ -275,6 +299,30 @@ public class DalamudUtil : IDisposable
|
||||
Thread.Sleep(tick);
|
||||
}
|
||||
|
||||
public unsafe void DisableDraw(IntPtr characterAddress)
|
||||
{
|
||||
var obj = (GameObject*)characterAddress;
|
||||
obj->DisableDraw();
|
||||
}
|
||||
|
||||
public unsafe void WaitWhileGposeCharacterIsDrawing(IntPtr characterAddress, int timeOut = 5000)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
var obj = (GameObject*)characterAddress;
|
||||
const int tick = 250;
|
||||
int curWaitTime = 0;
|
||||
Logger.Verbose("RenderFlags:" + obj->RenderFlags.ToString("X"));
|
||||
// ReSharper disable once LoopVariableIsNeverChangedInsideLoop
|
||||
while (obj->RenderFlags != 0x00 && curWaitTime < timeOut)
|
||||
{
|
||||
Logger.Verbose($"Waiting for gpose actor to finish drawing");
|
||||
curWaitTime += tick;
|
||||
Thread.Sleep(tick);
|
||||
}
|
||||
|
||||
Thread.Sleep(tick * 2);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_clientState.Login -= ClientStateOnLogin;
|
||||
|
||||
Reference in New Issue
Block a user