Hopefully this doesn't break anything, I can't test this properly on my free trial account

Removed "Limit to my creatures", the code now automatically detects this for all owned actors. If you liked to apply edits to minions and stuff of other players... too bad.
Implemented UI for setting profiles to NPC, minions and mounts (still WIP, will probably have to implement multiple characters per profile)
This commit is contained in:
RisaDev
2024-10-08 00:32:58 +03:00
parent d088550574
commit 7a0ee53756
17 changed files with 141 additions and 216 deletions

View File

@@ -13,8 +13,10 @@ using OtterGui.Custom;
using OtterGui.Log;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Data;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.DataContainers.Bases;
using Penumbra.GameData.Gui;
using Penumbra.GameData.Interop;
using Penumbra.GameData.Structs;
using Penumbra.String;
@@ -23,22 +25,18 @@ namespace CustomizePlus.UI.Windows.Controls;
public class ActorAssignmentUi
{
private readonly ActorManager _actorManager;
private readonly DictBNpcENpc _dictBnpcEnpc;
private WorldCombo _worldCombo = null!;
private Penumbra.GameData.Gui.NpcCombo _mountCombo = null!;
private Penumbra.GameData.Gui.NpcCombo _companionCombo = null!;
//private BattleEventNpcCombo _npcCombo = null!;
private Penumbra.GameData.Gui.NpcCombo _npcCombo = null!;
private NpcCombo _mountCombo = null!;
private NpcCombo _companionCombo = null!;
private NpcCombo _bnpcCombo = null!;
private NpcCombo _enpcCombo = null!;
private bool _ready;
private string _newCharacterName = string.Empty;
private ObjectKind _newKind = ObjectKind.BattleNpc;
/* public string CharacterName { get => _newCharacterName; }
public WorldId SelectedWorld { get => _worldCombo.CurrentSelection.Key; }
*/
public ActorIdentifier NpcIdentifier { get; private set; } = ActorIdentifier.Invalid;
public ActorIdentifier PlayerIdentifier { get; private set; } = ActorIdentifier.Invalid;
public ActorIdentifier RetainerIdentifier { get; private set; } = ActorIdentifier.Invalid;
@@ -56,12 +54,11 @@ public class ActorAssignmentUi
public bool CanSetNpc
=> NpcIdentifier.IsValid;
public ActorAssignmentUi(ActorManager actorManager, DictBNpcENpc dictBnpcEnpc)
public ActorAssignmentUi(ActorManager actorManager, DictModelChara dictModelChara, DictBNpcNames bNpcNames, DictBNpc bNpc)
{
_actorManager = actorManager;
_dictBnpcEnpc = dictBnpcEnpc;
_actorManager.Awaiter.ContinueWith(_ => dictBnpcEnpc.Awaiter.ContinueWith(_ => SetupCombos(), TaskScheduler.Default), TaskScheduler.Default);
_actorManager.Awaiter.ContinueWith(_ => SetupCombos(), TaskScheduler.Default);
}
public void DrawWorldCombo(float width)
@@ -92,12 +89,6 @@ public class ActorAssignmentUi
if (!_ready)
return;
/* if(_newKind == ObjectKind.BattleNpc || _newKind == ObjectKind.EventNpc)
{
if (_npcCombo.Draw(width))
UpdateIdentifiersInternal();
}*/
var combo = GetNpcCombo(_newKind);
if (combo.Draw(width))
UpdateIdentifiersInternal();
@@ -114,8 +105,8 @@ public class ActorAssignmentUi
private Penumbra.GameData.Gui.NpcCombo GetNpcCombo(ObjectKind kind)
=> kind switch
{
ObjectKind.BattleNpc => _npcCombo,
ObjectKind.EventNpc => _npcCombo,
ObjectKind.BattleNpc => _bnpcCombo,
ObjectKind.EventNpc => _enpcCombo,
ObjectKind.MountType => _mountCombo,
ObjectKind.Companion => _companionCombo,
_ => throw new NotImplementedException(),
@@ -127,9 +118,8 @@ public class ActorAssignmentUi
_worldCombo = new WorldCombo(_actorManager.Data.Worlds, Plugin.Logger);
_mountCombo = new Penumbra.GameData.Gui.NpcCombo("##mountCombo", _actorManager.Data.Mounts, Plugin.Logger);
_companionCombo = new Penumbra.GameData.Gui.NpcCombo("##companionCombo", _actorManager.Data.Companions, Plugin.Logger);
//_bnpcCombo = new Penumbra.GameData.Gui.NpcCombo("##bnpcCombo", _actorManager.Data.BNpcs, Plugin.Logger);
//_enpcCombo = new Penumbra.GameData.Gui.NpcCombo("##enpcCombo", _actorManager.Data.ENpcs, Plugin.Logger);
_npcCombo = new Penumbra.GameData.Gui.NpcCombo("##npcCombo", _dictBnpcEnpc, Plugin.Logger);
_bnpcCombo = new Penumbra.GameData.Gui.NpcCombo("##bnpcCombo", _actorManager.Data.BNpcs, Plugin.Logger);
_enpcCombo = new Penumbra.GameData.Gui.NpcCombo("##enpcCombo", _actorManager.Data.ENpcs, Plugin.Logger);
_ready = true;
}
@@ -141,41 +131,21 @@ public class ActorAssignmentUi
RetainerIdentifier = _actorManager.CreateRetainer(byteName, ActorIdentifier.RetainerType.Bell);
MannequinIdentifier = _actorManager.CreateRetainer(byteName, ActorIdentifier.RetainerType.Mannequin);
}
var npcCombo = GetNpcCombo(_newKind);
switch(_newKind)
{
case ObjectKind.BattleNpc:
case ObjectKind.EventNpc:
NpcIdentifier = _actorManager.CreateNpc(_newKind, npcCombo.CurrentSelection.Ids[0]);
break;
case ObjectKind.MountType:
case ObjectKind.Companion:
var currentPlayer = _actorManager.GetCurrentPlayer();
NpcIdentifier = _actorManager.CreateOwned(currentPlayer.PlayerName, currentPlayer.HomeWorld, _newKind, npcCombo.CurrentSelection.Ids[0]);
break;
default:
throw new NotImplementedException();
}
}
}
//Todo: Temp
/// <summary> A dictionary that matches BNpcNameId to names. </summary>
public sealed class DictBNpcENpc(IDalamudPluginInterface pluginInterface, Logger log, IDataManager gameData)
: NameDictionary(pluginInterface, log, gameData, "BNpcsENpcs", 7, () => CreateData(gameData))
{
/// <summary> Create the data. </summary>
private static IReadOnlyDictionary<uint, string> CreateData(IDataManager gameData)
{
var sheet = gameData.GetExcelSheet<BNpcName>(gameData.Language)!;
var sheet2 = gameData.GetExcelSheet<ENpcResident>(gameData.Language)!;
var dict = new Dictionary<uint, string>((int)sheet.RowCount + (int)sheet2.RowCount);
foreach (var n in sheet.Where(n => n.Singular.RawData.Length > 0))
dict.TryAdd(n.RowId, DataUtility.ToTitleCaseExtended(n.Singular, n.Article));
foreach (var n in sheet2.Where(e => e.Singular.RawData.Length > 0))
dict.TryAdd(n.RowId, DataUtility.ToTitleCaseExtended(n.Singular, n.Article));
return dict.ToFrozenDictionary();
}
/// <inheritdoc cref="NameDictionary.ContainsKey"/>
public bool ContainsKey(BNpcNameId key)
=> Value.ContainsKey(key.Id);
/// <inheritdoc cref="NameDictionary.TryGetValue"/>
public bool TryGetValue(BNpcNameId key, [NotNullWhen(true)] out string? value)
=> Value.TryGetValue(key.Id, out value);
/// <inheritdoc cref="NameDictionary.this"/>
public string this[BNpcNameId key]
=> Value[key.Id];
}
}

View File

@@ -149,7 +149,6 @@ public class StateMonitoringTab
ImGui.Text($"ID: {profile.UniqueId}");
ImGui.Text($"Enabled: {(profile.Enabled ? "Enabled" : "Disabled")}");
ImGui.Text($"State : {(profile.IsTemporary ? "Temporary" : "Permanent")}");
ImGui.Text($"Lookup: {(profile.LimitLookupToOwnedObjects ? "Limited lookup" : "Global lookup")}");
var showTemplates = ImGui.CollapsingHeader($"Templates###{prefix}-profile-{profile.UniqueId}-templates");
if (showTemplates)

View File

@@ -16,6 +16,7 @@ using CustomizePlus.Configuration.Data;
using CustomizePlus.Profiles.Data;
using CustomizePlus.Game.Services;
using CustomizePlus.Profiles.Events;
using CustomizePlus.GameData.Extensions;
namespace CustomizePlus.UI.Windows.MainWindow.Tabs.Profiles;
@@ -239,9 +240,9 @@ public class ProfileFileSystemSelector : FileSystemSelector<Profile, ProfileStat
}
if (leaf.Value.Enabled)
state.Color = leaf.Value.Character.Matches(_gameObjectService.GetCurrentPlayerActorIdentifier()) ? ColorId.LocalCharacterEnabledProfile : ColorId.EnabledProfile;
state.Color = leaf.Value.Character.CompareIgnoringOwnership(_gameObjectService.GetCurrentPlayerActorIdentifier()) ? ColorId.LocalCharacterEnabledProfile : ColorId.EnabledProfile;
else
state.Color = leaf.Value.Character.Matches(_gameObjectService.GetCurrentPlayerActorIdentifier()) ? ColorId.LocalCharacterDisabledProfile : ColorId.DisabledProfile;
state.Color = leaf.Value.Character.CompareIgnoringOwnership(_gameObjectService.GetCurrentPlayerActorIdentifier()) ? ColorId.LocalCharacterDisabledProfile : ColorId.DisabledProfile;
return ApplyStringFilters(leaf, leaf.Value);
}

View File

@@ -16,6 +16,7 @@ using CustomizePlus.Templates.Events;
using Penumbra.GameData.Actors;
using Penumbra.String;
using static FFXIVClientStructs.FFXIV.Client.LayoutEngine.ILayoutInstance;
using CustomizePlus.GameData.Extensions;
namespace CustomizePlus.UI.Windows.MainWindow.Tabs.Profiles;
@@ -216,68 +217,46 @@ public class ProfilePanel
if (!_selector.IncognitoMode)
{
bool showMultipleMessage = false;
if (_manager.DefaultProfile != _selector.Selected)
if (_manager.DefaultProfile != _selector.Selected && !_selector.Selected!.ApplyToCurrentlyActiveCharacter)
{
if (!_selector.Selected!.ApplyToCurrentlyActiveCharacter)
{
/* if (ImGui.InputText("##CharacterName", ref name, 128))
{
_newCharacterName = name;
_changedProfile = _selector.Selected;
}
ImGui.Text(_selector.Selected!.Character.IsValid ? $"Applies to {_selector.Selected?.Character.ToNameWithoutOwnerName()}" : "No valid character selected for the profile");
ImGui.Text($"Legacy: {_selector.Selected!.CharacterName.Text ?? "None"}");
ImGui.Separator();
if (ImGui.IsItemDeactivatedAfterEdit() && _changedProfile != null)
{
_manager.ChangeCharacterName(_changedProfile, name);
_newCharacterName = null;
_changedProfile = null;
}
ImGui.Separator();*/
ImGui.Text(_selector.Selected!.Character.IsValid ? $"Applies to {_selector.Selected?.Character.ToString()}" : "No valid character selected for the profile");
ImGui.Text($"Legacy: {_selector.Selected!.CharacterName.Text ?? "None"}");
ImGui.Separator();
_actorAssignmentUi.DrawWorldCombo(width.X / 2);
ImGui.SameLine();
_actorAssignmentUi.DrawPlayerInput(width.X / 2);
_actorAssignmentUi.DrawWorldCombo(width.X / 2);
ImGui.SameLine();
_actorAssignmentUi.DrawPlayerInput(width.X / 2);
var buttonWidth = new Vector2(165 * ImGuiHelpers.GlobalScale - ImGui.GetStyle().ItemSpacing.X / 2, 0);
var buttonWidth = new Vector2(165 * ImGuiHelpers.GlobalScale - ImGui.GetStyle().ItemSpacing.X / 2, 0);
if (ImGuiUtil.DrawDisabledButton("Apply to player character", buttonWidth, string.Empty, !_actorAssignmentUi.CanSetPlayer))
_manager.ChangeCharacter(_selector.Selected!, _actorAssignmentUi.PlayerIdentifier);
if (ImGuiUtil.DrawDisabledButton("Apply to player character", buttonWidth, string.Empty, !_actorAssignmentUi.CanSetPlayer))
_manager.ChangeCharacter(_selector.Selected!, _actorAssignmentUi.PlayerIdentifier);
ImGui.SameLine();
ImGui.SameLine();
if (ImGuiUtil.DrawDisabledButton("Apply to retainer", buttonWidth, string.Empty, !_actorAssignmentUi.CanSetRetainer))
_manager.ChangeCharacter(_selector.Selected!, _actorAssignmentUi.RetainerIdentifier);
if (ImGuiUtil.DrawDisabledButton("Apply to retainer", buttonWidth, string.Empty, !_actorAssignmentUi.CanSetRetainer))
_manager.ChangeCharacter(_selector.Selected!, _actorAssignmentUi.RetainerIdentifier);
ImGui.SameLine();
ImGui.SameLine();
if (ImGuiUtil.DrawDisabledButton("Apply to mannequin", buttonWidth, string.Empty, !_actorAssignmentUi.CanSetMannequin))
_manager.ChangeCharacter(_selector.Selected!, _actorAssignmentUi.MannequinIdentifier);
if (ImGuiUtil.DrawDisabledButton("Apply to mannequin", buttonWidth, string.Empty, !_actorAssignmentUi.CanSetMannequin))
_manager.ChangeCharacter(_selector.Selected!, _actorAssignmentUi.MannequinIdentifier);
var currentPlayer = _actorManager.GetCurrentPlayer();
if (ImGuiUtil.DrawDisabledButton("Apply to current character", buttonWidth, string.Empty, !currentPlayer.IsValid))
_manager.ChangeCharacter(_selector.Selected!, currentPlayer);
var currentPlayer = _actorManager.GetCurrentPlayer();
if (ImGuiUtil.DrawDisabledButton("Apply to current character", buttonWidth, string.Empty, !currentPlayer.IsValid))
_manager.ChangeCharacter(_selector.Selected!, currentPlayer);
ImGui.Separator();
ImGui.Separator();
_actorAssignmentUi.DrawObjectKindCombo(width.X / 2);
ImGui.SameLine();
_actorAssignmentUi.DrawNpcInput(width.X / 2);
_actorAssignmentUi.DrawObjectKindCombo(width.X / 2);
ImGui.SameLine();
_actorAssignmentUi.DrawNpcInput(width.X / 2);
if (ImGuiUtil.DrawDisabledButton("Apply to selected NPC", buttonWidth, string.Empty, !_actorAssignmentUi.CanSetNpc))
_manager.ChangeCharacter(_selector.Selected!, _actorAssignmentUi.NpcIdentifier);
if (ImGui.Button("Apply to selected non-player character"))
{
}
}
else
showMultipleMessage = true;
}
else
showMultipleMessage = true;
if(showMultipleMessage)
ImGui.TextUnformatted("Applies to multiple targets");
}
else
@@ -308,13 +287,6 @@ public class ProfilePanel
ImGui.PopStyleColor();
ImGuiUtil.HoverTooltip("Can only be changed when both currently selected and profile where this checkbox is checked are disabled.");
}
//ImGui.SameLine();
var enabled = _selector.Selected?.LimitLookupToOwnedObjects ?? false;
if (ImGui.Checkbox("##LimitLookupToOwnedObjects", ref enabled))
_manager.SetLimitLookupToOwned(_selector.Selected!, enabled);
ImGuiUtil.LabeledHelpMarker("Limit to my creatures",
"When enabled limits the character search to only your own summons, mounts and minions.\nUseful when there is possibility there will be another character with that name owned by another player.\n* For battle chocobo use \"Chocobo\" as character name.");
}
}
}

View File

@@ -65,7 +65,7 @@ public class BoneEditorPanel
{
if (_editorManager.EnableEditor(template))
{
_editorManager.SetLimitLookupToOwned(_configuration.EditorConfiguration.LimitLookupToOwnedObjects);
//_editorManager.SetLimitLookupToOwned(_configuration.EditorConfiguration.LimitLookupToOwnedObjects);
return true;
}
@@ -96,53 +96,48 @@ public class BoneEditorPanel
using (var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0, 0.5f)))
{
using (var table = ImRaii.Table("BasicSettings", 2))
{
ImGui.TableSetupColumn("BasicCol1", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Show editor preview on").X);
//using (var table = ImRaii.Table("BasicSettings", 2))
//{
/* ImGui.TableSetupColumn("BasicCol1", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Show editor preview on").X);
ImGui.TableSetupColumn("BasicCol2", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableNextRow();
ImGuiUtil.DrawFrameColumn("Show editor preview on");
ImGui.TableNextColumn();
ImGui.TableNextColumn();*/
var width = new Vector2(ImGui.GetContentRegionAvail().X - ImGui.CalcTextSize("Limit to my creatures").X - 68, 0);
var name = _newCharacterName ?? _editorManager.CharacterName;
ImGui.SetNextItemWidth(width.X);
//ImGui.SetNextItemWidth(width.X);
using (var disabled = ImRaii.Disabled(!IsEditorActive || IsEditorPaused))
var isShouldDraw = ImGui.CollapsingHeader("Preview settings");
if (isShouldDraw)
{
if (!_templateFileSystemSelector.IncognitoMode)
using (var disabled = ImRaii.Disabled(!IsEditorActive || IsEditorPaused))
{
if (ImGui.InputText("##PreviewCharacterName", ref name, 128))
if (!_templateFileSystemSelector.IncognitoMode)
{
_newCharacterName = name;
}
if (ImGui.IsItemDeactivatedAfterEdit())
{
if (string.IsNullOrWhiteSpace(_newCharacterName))
_newCharacterName = _gameObjectService.GetCurrentPlayerName();
_editorManager.ChangeEditorCharacter(_newCharacterName);
_newCharacterName = null;
if (ImGui.InputText("##PreviewCharacterName", ref name, 128))
{
_newCharacterName = name;
}
if (ImGui.IsItemDeactivatedAfterEdit())
{
if (string.IsNullOrWhiteSpace(_newCharacterName))
_newCharacterName = _gameObjectService.GetCurrentPlayerName();
_editorManager.ChangeEditorCharacter(_newCharacterName);
_newCharacterName = null;
}
}
else
ImGui.TextUnformatted("Incognito active");
}
else
ImGui.TextUnformatted("Incognito active");
ImGui.SameLine();
var enabled = _editorManager.EditorProfile.LimitLookupToOwnedObjects;
if (ImGui.Checkbox("##LimitLookupToOwnedObjects", ref enabled))
{
_editorManager.SetLimitLookupToOwned(enabled);
_configuration.EditorConfiguration.LimitLookupToOwnedObjects = enabled;
_configuration.Save();
}
ImGuiUtil.LabeledHelpMarker("Limit to my creatures",
"When enabled limits the character search to only your own summons, mounts and minions.\nUseful when there is possibility there will be another character with that name owned by another player.\n* For battle chocobo use \"Chocobo\" as character name.");
}
}
//}
ImGui.Separator();
using (var table = ImRaii.Table("BoneEditorMenu", 2))
{