refactor: try allowing multiple actors
This commit is contained in:
parent
97eeab1129
commit
1d5a85d188
@ -1,13 +1,14 @@
|
|||||||
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;
|
||||||
|
using FFXIVClientStructs.Interop;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
|
||||||
namespace OrangeGuidanceTomestone.Util;
|
namespace OrangeGuidanceTomestone.Util;
|
||||||
|
|
||||||
internal class ActorManager : IDisposable {
|
internal class ActorManager : IDisposable {
|
||||||
private Plugin Plugin { get; }
|
private Plugin Plugin { get; }
|
||||||
private uint? _idx;
|
private readonly Stack<uint> _idx = [];
|
||||||
private readonly Queue<BaseActorAction> _tasks = [];
|
private readonly Queue<BaseActorAction> _tasks = [];
|
||||||
|
|
||||||
internal ActorManager(Plugin plugin) {
|
internal ActorManager(Plugin plugin) {
|
||||||
@ -22,10 +23,9 @@ internal class ActorManager : IDisposable {
|
|||||||
this.Plugin.ClientState.TerritoryChanged -= this.OnTerritoryChange;
|
this.Plugin.ClientState.TerritoryChanged -= this.OnTerritoryChange;
|
||||||
this.Plugin.Framework.Update -= this.OnFramework;
|
this.Plugin.Framework.Update -= this.OnFramework;
|
||||||
|
|
||||||
if (this._idx != null) {
|
if (this._idx.Count > 0) {
|
||||||
unsafe {
|
unsafe {
|
||||||
var objMan = ClientObjectManager.Instance();
|
var objMan = ClientObjectManager.Instance();
|
||||||
new DisableAction().Run(this, objMan);
|
|
||||||
new DeleteAction().Run(this, objMan);
|
new DeleteAction().Run(this, objMan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ internal class ActorManager : IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void OnTerritoryChange(ushort obj) {
|
private void OnTerritoryChange(ushort obj) {
|
||||||
this._idx = null;
|
this._idx.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnView(Message? message) {
|
private void OnView(Message? message) {
|
||||||
@ -75,11 +75,6 @@ internal class ActorManager : IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void Despawn() {
|
internal void Despawn() {
|
||||||
if (this._idx == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._tasks.Enqueue(new DisableAction());
|
|
||||||
this._tasks.Enqueue(new DeleteAction());
|
this._tasks.Enqueue(new DeleteAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,36 +87,28 @@ internal class ActorManager : IDisposable {
|
|||||||
|
|
||||||
public int Tries { get; set; }
|
public int Tries { get; set; }
|
||||||
|
|
||||||
protected bool TryGetBattleChara(
|
protected IEnumerable<Pointer<BattleChara>> GetBattleCharas(
|
||||||
ActorManager manager,
|
ActorManager manager,
|
||||||
ClientObjectManager* objMan,
|
Pointer<ClientObjectManager> objMan
|
||||||
out BattleChara* chara
|
|
||||||
) {
|
) {
|
||||||
chara = null;
|
foreach (var idx in manager._idx) {
|
||||||
|
Pointer<BattleChara> ptr;
|
||||||
if (manager._idx is not { } idx) {
|
unsafe {
|
||||||
Plugin.Log.Warning("tried to get battlechara but idx was null");
|
var obj = (BattleChara*) objMan.Value->GetObjectByIndex((ushort) idx);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var obj = objMan->GetObjectByIndex((ushort) idx);
|
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
Plugin.Log.Warning("tried to get battlechara but it was null");
|
continue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chara = (BattleChara*) obj;
|
ptr = obj;
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
yield return ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe class SpawnAction(Message message) : BaseActorAction {
|
private unsafe class SpawnAction(Message message) : BaseActorAction {
|
||||||
public override bool Run(ActorManager manager, ClientObjectManager* objMan) {
|
public override bool Run(ActorManager manager, ClientObjectManager* objMan) {
|
||||||
if (manager._idx != null) {
|
|
||||||
Plugin.Log.Warning("refusing to spawn a second actor");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.Emote == null) {
|
if (message.Emote == null) {
|
||||||
Plugin.Log.Warning("refusing to spawn an actor for a message without an emote");
|
Plugin.Log.Warning("refusing to spawn an actor for a message without an emote");
|
||||||
return true;
|
return true;
|
||||||
@ -133,7 +120,7 @@ internal class ActorManager : IDisposable {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
manager._idx = idx;
|
manager._idx.Push(idx);
|
||||||
var emote = message.Emote;
|
var emote = message.Emote;
|
||||||
var emoteRow = manager.GetValidEmote(emote.Id);
|
var emoteRow = manager.GetValidEmote(emote.Id);
|
||||||
|
|
||||||
@ -211,43 +198,29 @@ internal class ActorManager : IDisposable {
|
|||||||
|
|
||||||
private unsafe class EnableAction : BaseActorAction {
|
private unsafe class EnableAction : BaseActorAction {
|
||||||
public override bool Run(ActorManager manager, ClientObjectManager* objMan) {
|
public override bool Run(ActorManager manager, ClientObjectManager* objMan) {
|
||||||
if (!this.TryGetBattleChara(manager, objMan, out var chara)) {
|
var allReady = true;
|
||||||
return true;
|
foreach (var chara in this.GetBattleCharas(manager, objMan)) {
|
||||||
|
if (!chara.Value->IsReadyToDraw()) {
|
||||||
|
allReady = false;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chara->IsReadyToDraw()) {
|
chara.Value->EnableDraw();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chara->EnableDraw();
|
return allReady;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private unsafe class DisableAction : BaseActorAction {
|
|
||||||
public override bool Run(ActorManager manager, ClientObjectManager* objMan) {
|
|
||||||
if (!this.TryGetBattleChara(manager, objMan, out var chara)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
chara->DisableDraw();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe class DeleteAction : BaseActorAction {
|
private unsafe class DeleteAction : BaseActorAction {
|
||||||
public override bool Run(ActorManager manager, ClientObjectManager* objMan) {
|
public override bool Run(ActorManager manager, ClientObjectManager* objMan) {
|
||||||
if (manager._idx is not { } idx) {
|
foreach (var wrapper in this.GetBattleCharas(manager, objMan)) {
|
||||||
Plugin.Log.Warning("delete action but idx was null");
|
wrapper.Value->DisableDraw();
|
||||||
return true;
|
var idx = objMan->GetIndexByObject((GameObject*) wrapper.Value);
|
||||||
|
objMan->DeleteObjectByIndex((ushort) idx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objMan->GetObjectByIndex((ushort) idx) == null) {
|
manager._idx.Clear();
|
||||||
Plugin.Log.Warning("delete action but object at idx was null");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
manager._idx = null;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user