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:
Ottermandias 2021-11-15 13:35:40 +01:00
parent 65e3ab3cb4
commit 33cb4c6c99
5 changed files with 114 additions and 29 deletions

View file

@ -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);

View file

@ -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()

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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