Update CutsceneService and ObjectManager from upstream
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using CustomizePlus.GameData.Hooks.Objects;
|
using CustomizePlus.GameData.Hooks.Objects;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
@@ -9,23 +10,23 @@ using System.Diagnostics;
|
|||||||
|
|
||||||
namespace CustomizePlus.GameData.Services;
|
namespace CustomizePlus.GameData.Services;
|
||||||
|
|
||||||
public class CutsceneService : IService, IDisposable
|
public sealed class CutsceneService : IRequiredService, IDisposable
|
||||||
{
|
{
|
||||||
public const int CutsceneStartIdx = (int)ScreenActor.CutsceneStart;
|
public const int CutsceneStartIdx = (int)ScreenActor.CutsceneStart;
|
||||||
public const int CutsceneEndIdx = (int)ScreenActor.CutsceneEnd;
|
public const int CutsceneEndIdx = (int)ScreenActor.CutsceneEnd;
|
||||||
public const int CutsceneSlots = CutsceneEndIdx - CutsceneStartIdx;
|
public const int CutsceneSlots = CutsceneEndIdx - CutsceneStartIdx;
|
||||||
|
|
||||||
private readonly IObjectTable _objects;
|
private readonly ObjectManager _objects;
|
||||||
private readonly CopyCharacter _copyCharacter;
|
private readonly CopyCharacter _copyCharacter;
|
||||||
private readonly CharacterDestructor _characterDestructor;
|
private readonly CharacterDestructor _characterDestructor;
|
||||||
private readonly short[] _copiedCharacters = Enumerable.Repeat((short)-1, CutsceneSlots).ToArray();
|
private readonly short[] _copiedCharacters = Enumerable.Repeat((short)-1, CutsceneSlots).ToArray();
|
||||||
|
|
||||||
public IEnumerable<KeyValuePair<int, Dalamud.Game.ClientState.Objects.Types.IGameObject>> Actors
|
public IEnumerable<KeyValuePair<int, IGameObject>> Actors
|
||||||
=> Enumerable.Range(CutsceneStartIdx, CutsceneSlots)
|
=> Enumerable.Range(CutsceneStartIdx, CutsceneSlots)
|
||||||
.Where(i => _objects[i] != null)
|
.Where(i => _objects[i].Valid)
|
||||||
.Select(i => KeyValuePair.Create(i, this[i] ?? _objects[i]!));
|
.Select(i => KeyValuePair.Create(i, this[i] ?? _objects.GetDalamudObject(i)!));
|
||||||
|
|
||||||
public unsafe CutsceneService(IObjectTable objects, CopyCharacter copyCharacter, CharacterDestructor characterDestructor,
|
public unsafe CutsceneService(ObjectManager objects, CopyCharacter copyCharacter, CharacterDestructor characterDestructor,
|
||||||
IClientState clientState)
|
IClientState clientState)
|
||||||
{
|
{
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
@@ -43,13 +44,13 @@ public class CutsceneService : IService, IDisposable
|
|||||||
/// Does not check for valid input index.
|
/// Does not check for valid input index.
|
||||||
/// Returns null if no connected actor is set or the actor does not exist anymore.
|
/// Returns null if no connected actor is set or the actor does not exist anymore.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dalamud.Game.ClientState.Objects.Types.IGameObject? this[int idx]
|
private IGameObject? this[int idx]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Debug.Assert(idx is >= CutsceneStartIdx and < CutsceneEndIdx);
|
Debug.Assert(idx is >= CutsceneStartIdx and < CutsceneEndIdx);
|
||||||
idx = _copiedCharacters[idx - CutsceneStartIdx];
|
idx = _copiedCharacters[idx - CutsceneStartIdx];
|
||||||
return idx < 0 ? null : _objects[idx];
|
return idx < 0 ? null : _objects.GetDalamudObject(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,10 +66,10 @@ public class CutsceneService : IService, IDisposable
|
|||||||
if (parentIdx is < -1 or >= CutsceneEndIdx)
|
if (parentIdx is < -1 or >= CutsceneEndIdx)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (_objects.GetObjectAddress(copyIdx) == nint.Zero)
|
if (!_objects[copyIdx].Valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (parentIdx != -1 && _objects.GetObjectAddress(parentIdx) == nint.Zero)
|
if (parentIdx != -1 && !_objects[parentIdx].Valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_copiedCharacters[copyIdx - CutsceneStartIdx] = (short)parentIdx;
|
_copiedCharacters[copyIdx - CutsceneStartIdx] = (short)parentIdx;
|
||||||
@@ -100,9 +101,9 @@ public class CutsceneService : IService, IDisposable
|
|||||||
{
|
{
|
||||||
// A hack to deal with GPose actors leaving and thus losing the link, we just set the home world instead.
|
// A hack to deal with GPose actors leaving and thus losing the link, we just set the home world instead.
|
||||||
// I do not think this breaks anything?
|
// I do not think this breaks anything?
|
||||||
var address = (GameObject*)_objects.GetObjectAddress(i + CutsceneStartIdx);
|
var address = _objects[i + CutsceneStartIdx];
|
||||||
if (address != null && address->GetObjectKind() is ObjectKind.Pc)
|
if (address.IsPlayer)
|
||||||
((Character*)address)->HomeWorld = character->HomeWorld;
|
address.AsCharacter->HomeWorld = character->HomeWorld;
|
||||||
|
|
||||||
_copiedCharacters[i] = -1;
|
_copiedCharacters[i] = -1;
|
||||||
}
|
}
|
||||||
@@ -126,7 +127,7 @@ public class CutsceneService : IService, IDisposable
|
|||||||
|
|
||||||
/// <summary> Try to recover GPose actors on reloads into a running game. </summary>
|
/// <summary> Try to recover GPose actors on reloads into a running game. </summary>
|
||||||
/// <remarks> This is not 100% accurate due to world IDs, minions etc., but will be mostly sane. </remarks>
|
/// <remarks> This is not 100% accurate due to world IDs, minions etc., but will be mostly sane. </remarks>
|
||||||
private unsafe void RecoverGPoseActors()
|
private void RecoverGPoseActors()
|
||||||
{
|
{
|
||||||
Dictionary<ByteString, short>? actors = null;
|
Dictionary<ByteString, short>? actors = null;
|
||||||
|
|
||||||
@@ -144,11 +145,11 @@ public class CutsceneService : IService, IDisposable
|
|||||||
bool TryGetName(int idx, out ByteString name)
|
bool TryGetName(int idx, out ByteString name)
|
||||||
{
|
{
|
||||||
name = ByteString.Empty;
|
name = ByteString.Empty;
|
||||||
var address = (GameObject*)_objects.GetObjectAddress(idx);
|
var address = _objects[idx];
|
||||||
if (address == null)
|
if (!address.Valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
name = new ByteString(address->Name);
|
name = address.Utf8Name;
|
||||||
return !name.IsEmpty;
|
return !name.IsEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class ObjectManager(
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
_identifierUpdate = LastUpdate;
|
_identifierUpdate = LastUpdate;
|
||||||
World = (ushort)(this[0].Valid ? this[0].HomeWorld : 0);
|
World = (ushort)(Player.Valid ? Player.HomeWorld : 0);
|
||||||
_identifiers.Clear();
|
_identifiers.Clear();
|
||||||
_allWorldIdentifiers.Clear();
|
_allWorldIdentifiers.Clear();
|
||||||
_nonOwnedIdentifiers.Clear();
|
_nonOwnedIdentifiers.Clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user