mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Show ui actors (non-modifiable) to copy and apply. Use Ctrl and Shift to only apply/save/copy Equipment or Customization respectively.
This commit is contained in:
parent
65e3ab3cb4
commit
33cb4c6c99
5 changed files with 114 additions and 29 deletions
|
|
@ -298,6 +298,7 @@ namespace Glamourer
|
||||||
Alpha = a.Alpha();
|
Alpha = a.Alpha();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Apply(Character a)
|
public void Apply(Character a)
|
||||||
{
|
{
|
||||||
Glamourer.RevertableDesigns.Add(a);
|
Glamourer.RevertableDesigns.Add(a);
|
||||||
|
|
@ -323,6 +324,30 @@ namespace Glamourer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ApplyOnlyEquipment(Character a)
|
||||||
|
{
|
||||||
|
var oldState = _bytes[1];
|
||||||
|
WriteCustomizations = false;
|
||||||
|
SetHatState = false;
|
||||||
|
SetVisorState = false;
|
||||||
|
SetWeaponState = false;
|
||||||
|
Apply(a);
|
||||||
|
_bytes[1] = oldState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyOnlyCustomizations(Character a)
|
||||||
|
{
|
||||||
|
var oldState = _bytes[1];
|
||||||
|
SetHatState = false;
|
||||||
|
SetVisorState = false;
|
||||||
|
SetWeaponState = false;
|
||||||
|
var oldEquip = WriteEquipment;
|
||||||
|
WriteEquipment = CharacterEquipMask.None;
|
||||||
|
Apply(a);
|
||||||
|
_bytes[1] = oldState;
|
||||||
|
WriteEquipment = oldEquip;
|
||||||
|
}
|
||||||
|
|
||||||
public void Load(string base64)
|
public void Load(string base64)
|
||||||
{
|
{
|
||||||
var bytes = Convert.FromBase64String(base64);
|
var bytes = Convert.FromBase64String(base64);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using Glamourer.Customization;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.FileSystem;
|
using Glamourer.FileSystem;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.PlayerWatch;
|
using Penumbra.PlayerWatch;
|
||||||
|
|
||||||
namespace Glamourer.Gui
|
namespace Glamourer.Gui
|
||||||
|
|
@ -47,12 +48,45 @@ namespace Glamourer.Gui
|
||||||
ImGuiCustom.HoverTooltip("Copy customization code to clipboard.");
|
ImGuiCustom.HoverTooltip("Copy customization code to clipboard.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ConditionalApply(CharacterSave save, Character player)
|
||||||
|
{
|
||||||
|
if (ImGui.GetIO().KeyShift)
|
||||||
|
save.ApplyOnlyCustomizations(player);
|
||||||
|
else if (ImGui.GetIO().KeyCtrl)
|
||||||
|
save.ApplyOnlyEquipment(player);
|
||||||
|
else
|
||||||
|
save.Apply(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharacterSave ConditionalCopy(CharacterSave save)
|
||||||
|
{
|
||||||
|
var copy = save.Copy();
|
||||||
|
if (ImGui.GetIO().KeyShift)
|
||||||
|
{
|
||||||
|
copy.Load(new CharacterEquipment());
|
||||||
|
copy.SetHatState = false;
|
||||||
|
copy.SetVisorState = false;
|
||||||
|
copy.SetWeaponState = false;
|
||||||
|
copy.WriteEquipment = CharacterEquipMask.None;
|
||||||
|
}
|
||||||
|
else if (ImGui.GetIO().KeyCtrl)
|
||||||
|
{
|
||||||
|
copy.Load(CharacterCustomization.Default);
|
||||||
|
copy.SetHatState = false;
|
||||||
|
copy.SetVisorState = false;
|
||||||
|
copy.SetWeaponState = false;
|
||||||
|
copy.WriteCustomizations = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return save.Copy();
|
||||||
|
}
|
||||||
|
|
||||||
private bool DrawApplyClipboardButton()
|
private bool DrawApplyClipboardButton()
|
||||||
{
|
{
|
||||||
ImGui.PushFont(UiBuilder.IconFont);
|
ImGui.PushFont(UiBuilder.IconFont);
|
||||||
var applyButton = ImGui.Button(FontAwesomeIcon.Paste.ToIconString()) && _player != null;
|
var applyButton = ImGui.Button(FontAwesomeIcon.Paste.ToIconString()) && _player != null;
|
||||||
ImGui.PopFont();
|
ImGui.PopFont();
|
||||||
ImGuiCustom.HoverTooltip("Apply customization code from clipboard.");
|
ImGuiCustom.HoverTooltip("Apply customization code from clipboard.\nHold Shift to apply only customizations.\nHold Control to apply only equipment.");
|
||||||
|
|
||||||
if (!applyButton)
|
if (!applyButton)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -64,7 +98,7 @@ namespace Glamourer.Gui
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var save = CharacterSave.FromString(text);
|
var save = CharacterSave.FromString(text);
|
||||||
save.Apply(_player!);
|
ConditionalApply(save, _player!);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -82,7 +116,7 @@ namespace Glamourer.Gui
|
||||||
OpenDesignNamePopup(DesignNameUse.SaveCurrent);
|
OpenDesignNamePopup(DesignNameUse.SaveCurrent);
|
||||||
|
|
||||||
ImGui.PopFont();
|
ImGui.PopFont();
|
||||||
ImGuiCustom.HoverTooltip("Save the current design.");
|
ImGuiCustom.HoverTooltip("Save the current design.\nHold Shift to save only customizations.\nHold Control to save only equipment.");
|
||||||
|
|
||||||
DrawDesignNamePopup(DesignNameUse.SaveCurrent);
|
DrawDesignNamePopup(DesignNameUse.SaveCurrent);
|
||||||
}
|
}
|
||||||
|
|
@ -105,9 +139,9 @@ namespace Glamourer.Gui
|
||||||
if (player == null)
|
if (player == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
save.Apply(player);
|
ConditionalApply(save, player);
|
||||||
if (_inGPose)
|
if (_inGPose)
|
||||||
save.Apply(fallback!);
|
ConditionalApply(save, fallback!);
|
||||||
Glamourer.Penumbra.UpdateCharacters(player, fallback);
|
Glamourer.Penumbra.UpdateCharacters(player, fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,9 +169,9 @@ namespace Glamourer.Gui
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var fallBackCharacter = _gPoseActors.TryGetValue(player.Name.ToString(), out var f) ? f : null;
|
var fallBackCharacter = _gPoseActors.TryGetValue(player.Name.ToString(), out var f) ? f : null;
|
||||||
save.Apply(player);
|
ConditionalApply(save, player);
|
||||||
if (fallBackCharacter != null)
|
if (fallBackCharacter != null)
|
||||||
save.Apply(fallBackCharacter);
|
ConditionalApply(save, fallBackCharacter!);
|
||||||
Glamourer.Penumbra.UpdateCharacters(player, fallBackCharacter);
|
Glamourer.Penumbra.UpdateCharacters(player, fallBackCharacter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +244,7 @@ namespace Glamourer.Gui
|
||||||
{
|
{
|
||||||
DrawCopyClipboardButton(_currentSave);
|
DrawCopyClipboardButton(_currentSave);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var changes = DrawApplyClipboardButton();
|
var changes = !_currentSave.WriteProtected && DrawApplyClipboardButton();
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
DrawSaveDesignButton();
|
DrawSaveDesignButton();
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
@ -219,28 +253,39 @@ namespace Glamourer.Gui
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
DrawApplyToTargetButton(_currentSave);
|
DrawApplyToTargetButton(_currentSave);
|
||||||
if (_player != null)
|
if (_player != null && !_currentSave.WriteProtected)
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
DrawTargetPlayerButton();
|
DrawTargetPlayerButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
var data = _currentSave;
|
||||||
DrawRevertButton();
|
if (!_currentSave.WriteProtected)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
DrawRevertButton();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, 0.8f);
|
||||||
|
data = data.Copy();
|
||||||
|
}
|
||||||
|
|
||||||
if (DrawCustomization(ref _currentSave.Customizations) && _player != null)
|
if (DrawCustomization(ref data.Customizations) && _player != null)
|
||||||
{
|
{
|
||||||
Glamourer.RevertableDesigns.Add(_player);
|
Glamourer.RevertableDesigns.Add(_player);
|
||||||
_currentSave.Customizations.Write(_player.Address);
|
_currentSave.Customizations.Write(_player.Address);
|
||||||
changes = true;
|
changes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
changes |= DrawEquip(_currentSave.Equipment);
|
changes |= DrawEquip(data.Equipment);
|
||||||
changes |= DrawMiscellaneous(_currentSave, _player);
|
changes |= DrawMiscellaneous(data, _player);
|
||||||
|
|
||||||
if (_player != null && changes)
|
if (_player != null && changes)
|
||||||
Glamourer.Penumbra.UpdateCharacters(_player);
|
Glamourer.Penumbra.UpdateCharacters(_player);
|
||||||
|
if (_currentSave.WriteProtected)
|
||||||
|
ImGui.PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawActorPanel()
|
private void DrawActorPanel()
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,17 @@ namespace Glamourer.Gui
|
||||||
{
|
{
|
||||||
internal partial class Interface
|
internal partial class Interface
|
||||||
{
|
{
|
||||||
|
public const int CharacterScreenIndex = 240;
|
||||||
|
public const int ExamineScreenIndex = 241;
|
||||||
|
public const int FittingRoomIndex = 242;
|
||||||
|
public const int DyePreviewIndex = 243;
|
||||||
|
|
||||||
private Character? _player;
|
private Character? _player;
|
||||||
private string _currentLabel = string.Empty;
|
private string _currentLabel = string.Empty;
|
||||||
private string _playerFilter = string.Empty;
|
private string _playerFilter = string.Empty;
|
||||||
private string _playerFilterLower = string.Empty;
|
private string _playerFilterLower = string.Empty;
|
||||||
private readonly Dictionary<string, int> _playerNames = new(100);
|
private readonly Dictionary<string, int> _playerNames = new(100);
|
||||||
private readonly Dictionary<string, Character?> _gPoseActors = new(48);
|
private readonly Dictionary<string, Character?> _gPoseActors = new(CharacterScreenIndex - GPoseObjectId);
|
||||||
|
|
||||||
private void DrawPlayerFilter()
|
private void DrawPlayerFilter()
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +41,7 @@ namespace Glamourer.Gui
|
||||||
|
|
||||||
_gPoseActors[playerName] = null;
|
_gPoseActors[playerName] = null;
|
||||||
|
|
||||||
DrawSelectable(player, $"{playerName} (GPose)");
|
DrawSelectable(player, $"{playerName} (GPose)", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetLabel(Character player, string playerName, int num)
|
private static string GetLabel(Character player, string playerName, int num)
|
||||||
|
|
@ -50,9 +55,16 @@ namespace Glamourer.Gui
|
||||||
return num == 1 ? $"{playerName} (Monster)" : $"{playerName} #{num} (Monster)";
|
return num == 1 ? $"{playerName} (Monster)" : $"{playerName} #{num} (Monster)";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawPlayerSelectable(Character player)
|
private void DrawPlayerSelectable(Character player, int idx = 0)
|
||||||
{
|
{
|
||||||
var playerName = player.Name.ToString();
|
var (playerName, modifiable) = idx switch
|
||||||
|
{
|
||||||
|
CharacterScreenIndex => ("Character Screen Actor", false),
|
||||||
|
ExamineScreenIndex => ("Examine Screen Actor", false),
|
||||||
|
FittingRoomIndex => ("Fitting Room Actor", false),
|
||||||
|
DyePreviewIndex => ("Dye Preview Actor", false),
|
||||||
|
_ => (player.Name.ToString(), true),
|
||||||
|
};
|
||||||
if (!playerName.Any())
|
if (!playerName.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -68,18 +80,19 @@ namespace Glamourer.Gui
|
||||||
}
|
}
|
||||||
|
|
||||||
var label = GetLabel(player, playerName, num);
|
var label = GetLabel(player, playerName, num);
|
||||||
DrawSelectable(player, label);
|
DrawSelectable(player, label, modifiable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void DrawSelectable(Character player, string label)
|
private void DrawSelectable(Character player, string label, bool modifiable)
|
||||||
{
|
{
|
||||||
if (!_playerFilterLower.Any() || label.ToLowerInvariant().Contains(_playerFilterLower))
|
if (!_playerFilterLower.Any() || label.ToLowerInvariant().Contains(_playerFilterLower))
|
||||||
if (ImGui.Selectable(label, _currentLabel == label))
|
if (ImGui.Selectable(label, _currentLabel == label))
|
||||||
{
|
{
|
||||||
_currentLabel = label;
|
_currentLabel = label;
|
||||||
_currentSave.LoadCharacter(player);
|
_currentSave.LoadCharacter(player);
|
||||||
_player = player;
|
_player = player;
|
||||||
|
_currentSave.WriteProtected = !modifiable;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +100,8 @@ namespace Glamourer.Gui
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_currentSave.LoadCharacter(player);
|
_currentSave.LoadCharacter(player);
|
||||||
_player = player;
|
_player = player;
|
||||||
|
_currentSave.WriteProtected = !modifiable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawSelectionButtons()
|
private void DrawSelectionButtons()
|
||||||
|
|
@ -125,6 +139,7 @@ namespace Glamourer.Gui
|
||||||
_player = select;
|
_player = select;
|
||||||
_currentLabel = _player.Name.ToString();
|
_currentLabel = _player.Name.ToString();
|
||||||
_currentSave.LoadCharacter(_player);
|
_currentSave.LoadCharacter(_player);
|
||||||
|
_currentSave.WriteProtected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawPlayerSelector()
|
private void DrawPlayerSelector()
|
||||||
|
|
@ -152,16 +167,16 @@ namespace Glamourer.Gui
|
||||||
|
|
||||||
for (var i = 0; i < GPoseObjectId; ++i)
|
for (var i = 0; i < GPoseObjectId; ++i)
|
||||||
{
|
{
|
||||||
var player = CharacterFactory.Convert(Dalamud.Objects[i])!;
|
var player = CharacterFactory.Convert(Dalamud.Objects[i]);
|
||||||
if (player != null)
|
if (player != null)
|
||||||
DrawPlayerSelectable(player);
|
DrawPlayerSelectable(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = GPoseObjectId + 48; i < Dalamud.Objects.Length; ++i)
|
for (var i = CharacterScreenIndex; i < Dalamud.Objects.Length; ++i)
|
||||||
{
|
{
|
||||||
var player = CharacterFactory.Convert(Dalamud.Objects[i])!;
|
var player = CharacterFactory.Convert(Dalamud.Objects[i]);
|
||||||
if (player != null)
|
if (player != null)
|
||||||
DrawPlayerSelectable(player);
|
DrawPlayerSelectable(player, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ namespace Glamourer.Gui
|
||||||
ImGui.PopFont();
|
ImGui.PopFont();
|
||||||
if (_selection == null)
|
if (_selection == null)
|
||||||
ImGui.PopStyleVar();
|
ImGui.PopStyleVar();
|
||||||
ImGuiCustom.HoverTooltip("Clone the currently selected Design.");
|
ImGuiCustom.HoverTooltip("Clone the currently selected Design.\nHold Shift to only clone the customizations.\nHold Control to only clone the equipment.");
|
||||||
|
|
||||||
DrawDesignNamePopup(DesignNameUse.DuplicateDesign);
|
DrawDesignNamePopup(DesignNameUse.DuplicateDesign);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ namespace Glamourer.Gui
|
||||||
switch (use)
|
switch (use)
|
||||||
{
|
{
|
||||||
case DesignNameUse.SaveCurrent:
|
case DesignNameUse.SaveCurrent:
|
||||||
SaveNewDesign(_currentSave.Copy());
|
SaveNewDesign(ConditionalCopy(_currentSave));
|
||||||
break;
|
break;
|
||||||
case DesignNameUse.NewDesign:
|
case DesignNameUse.NewDesign:
|
||||||
var empty = new CharacterSave();
|
var empty = new CharacterSave();
|
||||||
|
|
@ -161,7 +161,7 @@ namespace Glamourer.Gui
|
||||||
SaveNewDesign(empty);
|
SaveNewDesign(empty);
|
||||||
break;
|
break;
|
||||||
case DesignNameUse.DuplicateDesign:
|
case DesignNameUse.DuplicateDesign:
|
||||||
SaveNewDesign(_selection!.Data.Copy());
|
SaveNewDesign(ConditionalCopy(_selection!.Data));
|
||||||
break;
|
break;
|
||||||
case DesignNameUse.NewFolder:
|
case DesignNameUse.NewFolder:
|
||||||
_designs.FileSystem
|
_designs.FileSystem
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue