Add ability to apply profiles on character selection (lobby) screen
This commit is contained in:
@@ -3,10 +3,12 @@ using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Control;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using OtterGui.Log;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Interop;
|
||||
using Penumbra.String;
|
||||
|
||||
namespace CustomizePlus.GameData.Services;
|
||||
|
||||
@@ -25,6 +27,8 @@ public class ObjectManager(
|
||||
|
||||
private DateTime _identifierUpdate;
|
||||
public bool IsInGPose { get; private set; }
|
||||
//c+ custom
|
||||
public bool IsInLobby { get; private set; }
|
||||
public ushort World { get; private set; }
|
||||
|
||||
private readonly Dictionary<ActorIdentifier, ActorData> _identifiers = new(200);
|
||||
@@ -78,6 +82,10 @@ public class ObjectManager(
|
||||
|
||||
var gPose = GPosePlayer;
|
||||
IsInGPose = gPose.Utf8Name.Length > 0;
|
||||
|
||||
//C+ custom
|
||||
IsInLobby = AddLobbyCharacter();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -128,6 +136,10 @@ public class ObjectManager(
|
||||
}
|
||||
}
|
||||
|
||||
//c+ custom
|
||||
public Actor LobbyActor
|
||||
=> IsInLobby ? this[200] : nint.Zero;
|
||||
|
||||
public Actor GPosePlayer
|
||||
=> this[(int)ScreenActor.GPosePlayer];
|
||||
|
||||
@@ -204,4 +216,25 @@ public class ObjectManager(
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
//c+ custom
|
||||
private unsafe bool AddLobbyCharacter()
|
||||
{
|
||||
var agent = AgentLobby.Instance();
|
||||
if (agent == null || agent->LobbyData.CharaSelectEntries.Size() == 0)
|
||||
return false;
|
||||
|
||||
var chara = agent->LobbyData.CharaSelectEntries.Get((ulong)agent->SelectedCharacterIndex).Value;
|
||||
if (chara == null)
|
||||
return false;
|
||||
|
||||
var actor = CutsceneCharacters.FirstOrDefault();
|
||||
|
||||
if (!actor.Valid)
|
||||
return false;
|
||||
|
||||
HandleIdentifier(actors.CreatePlayer(new ByteString(chara->Name), chara->HomeWorldId), actor);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ public class PluginConfiguration : IPluginConfiguration, ISavable
|
||||
public bool ApplyInTryOn { get; set; } = true;
|
||||
public bool ApplyInCards { get; set; } = true;
|
||||
public bool ApplyInInspect { get; set; } = true;
|
||||
public bool ApplyInLobby { get; set; } = true;
|
||||
}
|
||||
|
||||
public ProfileApplicationSettingsEntries ProfileApplicationSettings { get; set; } = new();
|
||||
|
||||
@@ -10,6 +10,10 @@ using DalamudGameObject = Dalamud.Game.ClientState.Objects.Types.GameObject;
|
||||
using ECommons.Configuration;
|
||||
using System;
|
||||
using CustomizePlus.Configuration.Data;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.String;
|
||||
using Dalamud.Logging;
|
||||
|
||||
namespace CustomizePlus.Game.Services;
|
||||
|
||||
@@ -92,7 +96,6 @@ public class GameObjectService
|
||||
return _objectTable.CreateObjectReference(actor);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get "true" actor for special actors.
|
||||
/// This should be used everywhere where resolving proper actor is crucial for proper profile application
|
||||
|
||||
@@ -27,6 +27,7 @@ using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Interop;
|
||||
using System.Runtime.Serialization;
|
||||
using CustomizePlus.Game.Services;
|
||||
using ObjectManager = CustomizePlus.GameData.Services.ObjectManager;
|
||||
|
||||
namespace CustomizePlus.Profiles;
|
||||
|
||||
@@ -42,6 +43,7 @@ public class ProfileManager : IDisposable
|
||||
private readonly PluginConfiguration _configuration;
|
||||
private readonly ActorManager _actorManager;
|
||||
private readonly GameObjectService _gameObjectService;
|
||||
private readonly ObjectManager _objectManager;
|
||||
private readonly ProfileChanged _event;
|
||||
private readonly TemplateChanged _templateChangedEvent;
|
||||
private readonly ReloadEvent _reloadEvent;
|
||||
@@ -59,6 +61,7 @@ public class ProfileManager : IDisposable
|
||||
PluginConfiguration configuration,
|
||||
ActorManager actorManager,
|
||||
GameObjectService gameObjectService,
|
||||
ObjectManager objectManager,
|
||||
ProfileChanged @event,
|
||||
TemplateChanged templateChangedEvent,
|
||||
ReloadEvent reloadEvent,
|
||||
@@ -71,6 +74,7 @@ public class ProfileManager : IDisposable
|
||||
_configuration = configuration;
|
||||
_actorManager = actorManager;
|
||||
_gameObjectService = gameObjectService;
|
||||
_objectManager = objectManager;
|
||||
_event = @event;
|
||||
_templateChangedEvent = templateChangedEvent;
|
||||
_templateChangedEvent.Subscribe(OnTemplateChange, TemplateChanged.Priority.ProfileManager);
|
||||
@@ -481,6 +485,12 @@ public class ProfileManager : IDisposable
|
||||
//performance: using textual override for ProfileAppliesTo here to not call
|
||||
//GetGameObjectName every time we are trying to check object against profiles
|
||||
|
||||
if (_objectManager.LobbyActor.Valid &&
|
||||
_objectManager.TryGetValue(actorIdentifier, out var actorData) &&
|
||||
actorData.Objects.Count == 1 &&
|
||||
_objectManager.LobbyActor == actorData.Objects[0] && !_configuration.ProfileApplicationSettings.ApplyInLobby)
|
||||
yield break;
|
||||
|
||||
(actorIdentifier, _) = _gameObjectService.GetTrueActorForSpecialTypeActor(actorIdentifier);
|
||||
|
||||
if (!actorIdentifier.IsValid)
|
||||
@@ -499,7 +509,6 @@ public class ProfileManager : IDisposable
|
||||
actorIdentifier.PlayerName != _actorManager.GetCurrentPlayer().PlayerName));
|
||||
}
|
||||
|
||||
|
||||
if (_templateEditorManager.IsEditorActive && _templateEditorManager.EditorProfile.Enabled && IsProfileAppliesToCurrentActor(_templateEditorManager.EditorProfile))
|
||||
yield return _templateEditorManager.EditorProfile;
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ public class StateMonitoringTab
|
||||
ImGui.Text($"Count: {kvPair.Value.Objects.Count}");
|
||||
foreach (var item in kvPair.Value.Objects)
|
||||
{
|
||||
ImGui.Text($"{item}, valid: {item.Valid}");
|
||||
ImGui.Text($"[{item.Index}] - {item}, valid: {item.Valid}");
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
@@ -104,6 +104,7 @@ public class SettingsTab
|
||||
DrawApplyInTryOnCheckbox();
|
||||
DrawApplyInCardsCheckbox();
|
||||
DrawApplyInInspectCheckbox();
|
||||
DrawApplyInLobbyCheckbox();
|
||||
}
|
||||
|
||||
private void DrawApplyInCharacterWindowCheckbox()
|
||||
@@ -157,6 +158,19 @@ public class SettingsTab
|
||||
_armatureManager.RebindAllArmatures();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawApplyInLobbyCheckbox()
|
||||
{
|
||||
var isChecked = _configuration.ProfileApplicationSettings.ApplyInLobby;
|
||||
|
||||
if (CtrlHelper.CheckboxWithTextAndHelp("##applyinlobby", "Apply Profiles on Character Select Screen",
|
||||
"Apply appropriate profile for the character you have currently selected on character select screen during login.", ref isChecked))
|
||||
{
|
||||
_configuration.ProfileApplicationSettings.ApplyInLobby = isChecked;
|
||||
_configuration.Save();
|
||||
_armatureManager.RebindAllArmatures();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Chat Commands Settings
|
||||
|
||||
Reference in New Issue
Block a user