API 4 updates

This commit is contained in:
Ottermandias 2021-08-27 15:06:58 +02:00
parent 86417ed74f
commit f10280d15d
31 changed files with 359 additions and 367 deletions

View file

@ -1,6 +1,6 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Objects.Types;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
namespace Glamourer.Customization namespace Glamourer.Customization
@ -150,10 +150,10 @@ namespace Glamourer.Customization
} }
} }
public void Read(Actor actor) public void Read(Character actor)
=> Read(actor.Address + CustomizationOffset); => Read(actor.Address + CustomizationOffset);
public ActorCustomization(Actor actor) public ActorCustomization(Character actor)
: this() : this()
{ {
Read(actor.Address + CustomizationOffset); Read(actor.Address + CustomizationOffset);

View file

@ -1,4 +1,5 @@
using Dalamud.Plugin; using Dalamud.Data;
using Dalamud.Plugin;
namespace Glamourer namespace Glamourer
{ {
@ -7,9 +8,9 @@ namespace Glamourer
public readonly Lumina.Data.FileResource File; public readonly Lumina.Data.FileResource File;
public readonly uint[] RgbaColors; public readonly uint[] RgbaColors;
public CmpFile(DalamudPluginInterface pi) public CmpFile(DataManager gameData)
{ {
File = pi.Data.GetFile("chara/xls/charamake/human.cmp"); File = gameData.GetFile("chara/xls/charamake/human.cmp")!;
RgbaColors = new uint[File.Data.Length >> 2]; RgbaColors = new uint[File.Data.Length >> 2];
for (var i = 0; i < File.Data.Length; i += 4) for (var i = 0; i < File.Data.Length; i += 4)
{ {

View file

@ -1,4 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Dalamud;
using Dalamud.Data;
using Dalamud.Plugin; using Dalamud.Plugin;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
@ -11,9 +13,9 @@ namespace Glamourer.Customization
private CustomizationManager() private CustomizationManager()
{ } { }
public static ICustomizationManager Create(DalamudPluginInterface pi) public static ICustomizationManager Create(DalamudPluginInterface pi, DataManager gameData, ClientLanguage language)
{ {
_options ??= new CustomizationOptions(pi); _options ??= new CustomizationOptions(pi, gameData, language);
return new CustomizationManager(); return new CustomizationManager();
} }

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Dalamud; using Dalamud;
using Dalamud.Data;
using Dalamud.Plugin; using Dalamud.Plugin;
using Glamourer.Util; using Glamourer.Util;
using Lumina.Data; using Lumina.Data;
@ -50,7 +51,7 @@ namespace Glamourer.Customization
private Customization[] GetHairStyles(SubRace race, Gender gender) private Customization[] GetHairStyles(SubRace race, Gender gender)
{ {
var row = _hairSheet.GetRow(((uint) race - 1) * 2 - 1 + (uint) gender); var row = _hairSheet.GetRow(((uint) race - 1) * 2 - 1 + (uint) gender)!;
var hairList = new List<Customization>(row.Unknown30); var hairList = new List<Customization>(row.Unknown30);
for (var i = 0; i < row.Unknown30; ++i) for (var i = 0; i < row.Unknown30; ++i)
{ {
@ -129,7 +130,7 @@ namespace Glamourer.Customization
private CustomizationSet GetSet(SubRace race, Gender gender) private CustomizationSet GetSet(SubRace race, Gender gender)
{ {
var (skin, hair) = GetColors(race, gender); var (skin, hair) = GetColors(race, gender);
var row = _listSheet.GetRow(((uint) race - 1) * 2 - 1 + (uint) gender); var row = _listSheet.GetRow(((uint) race - 1) * 2 - 1 + (uint) gender)!;
var set = new CustomizationSet(race, gender) var set = new CustomizationSet(race, gender)
{ {
HairStyles = race.ToRace() == Race.Hrothgar ? HrothgarFaces(row) : GetHairStyles(race, gender), HairStyles = race.ToRace() == Race.Hrothgar ? HrothgarFaces(row) : GetHairStyles(race, gender),
@ -211,7 +212,7 @@ namespace Glamourer.Customization
return textRow?.Text.ToString() ?? c.ToDefaultName(); return textRow?.Text.ToString() ?? c.ToDefaultName();
}).ToArray(); }).ToArray();
set._types = ((CustomizationId[]) Enum.GetValues(typeof(CustomizationId))).Select(c => set.Types = ((CustomizationId[]) Enum.GetValues(typeof(CustomizationId))).Select(c =>
{ {
if (c == CustomizationId.HighlightColor) if (c == CustomizationId.HighlightColor)
return CharaMakeParams.MenuType.ColorPicker; return CharaMakeParams.MenuType.ColorPicker;
@ -255,21 +256,21 @@ namespace Glamourer.Customization
_ => Language.English, _ => Language.English,
}; };
internal CustomizationOptions(DalamudPluginInterface pi) internal CustomizationOptions(DalamudPluginInterface pi, DataManager gameData, ClientLanguage language)
{ {
_cmpFile = new CmpFile(pi); _cmpFile = new CmpFile(gameData);
_customizeSheet = pi.Data.GetExcelSheet<CharaMakeCustomize>(); _customizeSheet = gameData.GetExcelSheet<CharaMakeCustomize>()!;
_lobby = pi.Data.GetExcelSheet<Lobby>(); _lobby = gameData.GetExcelSheet<Lobby>()!;
var tmp = pi.Data.Excel.GetType()!.GetMethod("GetSheet", BindingFlags.Instance | BindingFlags.NonPublic)! var tmp = gameData.Excel.GetType()!.GetMethod("GetSheet", BindingFlags.Instance | BindingFlags.NonPublic)!
.MakeGenericMethod(typeof(CharaMakeParams))!.Invoke(pi.Data.Excel, new object?[] .MakeGenericMethod(typeof(CharaMakeParams))!.Invoke(gameData.Excel, new object?[]
{ {
"charamaketype", "charamaketype",
FromClientLanguage(pi.ClientState.ClientLanguage), FromClientLanguage(language),
null, null,
}) as ExcelSheet<CharaMakeParams>; }) as ExcelSheet<CharaMakeParams>;
_listSheet = tmp!; _listSheet = tmp!;
_hairSheet = pi.Data.GetExcelSheet<HairMakeType>(); _hairSheet = gameData.GetExcelSheet<HairMakeType>()!;
SetNames(pi); SetNames(gameData);
_highlightPicker = CreateColorPicker(CustomizationId.HighlightColor, 256, 192); _highlightPicker = CreateColorPicker(CustomizationId.HighlightColor, 256, 192);
_lipColorPickerDark = CreateColorPicker(CustomizationId.LipColor, 512, 96); _lipColorPickerDark = CreateColorPicker(CustomizationId.LipColor, 512, 96);
@ -279,7 +280,7 @@ namespace Glamourer.Customization
_facePaintColorPickerLight = CreateColorPicker(CustomizationId.FacePaintColor, 1152, 96, true); _facePaintColorPickerLight = CreateColorPicker(CustomizationId.FacePaintColor, 1152, 96, true);
_tattooColorPicker = CreateColorPicker(CustomizationId.TattooColor, 0, 192); _tattooColorPicker = CreateColorPicker(CustomizationId.TattooColor, 0, 192);
_icons = new IconStorage(pi, _list.Length * 50); _icons = new IconStorage(pi, gameData, _list.Length * 50);
foreach (var race in Clans) foreach (var race in Clans)
{ {
foreach (var gender in Genders) foreach (var gender in Genders)
@ -287,9 +288,9 @@ namespace Glamourer.Customization
} }
} }
public void SetNames(DalamudPluginInterface pi) private void SetNames(DataManager gameData)
{ {
var subRace = pi.Data.GetExcelSheet<Tribe>(); var subRace = gameData.GetExcelSheet<Tribe>()!;
_names[(int) CustomName.Clan] = _lobby.GetRow(102)?.Text ?? "Clan"; _names[(int) CustomName.Clan] = _lobby.GetRow(102)?.Text ?? "Clan";
_names[(int) CustomName.Gender] = _lobby.GetRow(103)?.Text ?? "Gender"; _names[(int) CustomName.Gender] = _lobby.GetRow(103)?.Text ?? "Gender";
_names[(int) CustomName.Reverse] = _lobby.GetRow(2135)?.Text ?? "Reverse"; _names[(int) CustomName.Reverse] = _lobby.GetRow(2135)?.Text ?? "Reverse";

View file

@ -69,7 +69,7 @@ namespace Glamourer.Customization
public IReadOnlyList<Customization> LipColorsLight { get; internal set; } = null!; public IReadOnlyList<Customization> LipColorsLight { get; internal set; } = null!;
public IReadOnlyList<Customization> LipColorsDark { get; internal set; } = null!; public IReadOnlyList<Customization> LipColorsDark { get; internal set; } = null!;
public IReadOnlyList<CharaMakeParams.MenuType> _types { get; internal set; } = null!; public IReadOnlyList<CharaMakeParams.MenuType> Types { get; internal set; } = null!;
public string Option(CustomizationId id) public string Option(CustomizationId id)
=> OptionName[(int) id]; => OptionName[(int) id];
@ -154,7 +154,7 @@ namespace Glamourer.Customization
} }
public CharaMakeParams.MenuType Type(CustomizationId id) public CharaMakeParams.MenuType Type(CustomizationId id)
=> _types[(int) id]; => Types[(int) id];
public int Count(CustomizationId id) public int Count(CustomizationId id)

View file

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud.Plugin; using Dalamud.Data;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
namespace Glamourer namespace Glamourer
@ -11,22 +11,22 @@ namespace Glamourer
private static Dictionary<byte, Stain>? _stains; private static Dictionary<byte, Stain>? _stains;
private static Dictionary<EquipSlot, List<Item>>? _itemsBySlot; private static Dictionary<EquipSlot, List<Item>>? _itemsBySlot;
public static IReadOnlyDictionary<byte, Stain> Stains(DalamudPluginInterface pi) public static IReadOnlyDictionary<byte, Stain> Stains(DataManager dataManager)
{ {
if (_stains != null) if (_stains != null)
return _stains; return _stains;
var sheet = pi.Data.GetExcelSheet<Lumina.Excel.GeneratedSheets.Stain>(); var sheet = dataManager.GetExcelSheet<Lumina.Excel.GeneratedSheets.Stain>()!;
_stains = sheet.Where(s => s.Color != 0).ToDictionary(s => (byte) s.RowId, s => new Stain((byte) s.RowId, s)); _stains = sheet.Where(s => s.Color != 0).ToDictionary(s => (byte) s.RowId, s => new Stain((byte) s.RowId, s));
return _stains; return _stains;
} }
public static IReadOnlyDictionary<EquipSlot, List<Item>> ItemsBySlot(DalamudPluginInterface pi) public static IReadOnlyDictionary<EquipSlot, List<Item>> ItemsBySlot(DataManager dataManager)
{ {
if (_itemsBySlot != null) if (_itemsBySlot != null)
return _itemsBySlot; return _itemsBySlot;
var sheet = pi.Data.GetExcelSheet<Lumina.Excel.GeneratedSheets.Item>(); var sheet = dataManager.GetExcelSheet<Lumina.Excel.GeneratedSheets.Item>()!;
Item EmptySlot(EquipSlot slot) Item EmptySlot(EquipSlot slot)
=> new(sheet.First(), "Nothing", slot); => new(sheet.First(), "Nothing", slot);

View file

@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net472</TargetFramework> <TargetFramework>net5.0-windows</TargetFramework>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<PlatformTarget>x64</PlatformTarget>
<RootNamespace>Glamourer</RootNamespace> <RootNamespace>Glamourer</RootNamespace>
<AssemblyName>Glamourer.GameData</AssemblyName> <AssemblyName>Glamourer.GameData</AssemblyName>
<FileVersion>1.0.0.0</FileVersion> <FileVersion>1.0.0.0</FileVersion>

View file

@ -1,7 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Dalamud.Data.LuminaExtensions; using Dalamud.Data;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Utility;
using ImGuiScene; using ImGuiScene;
using Lumina.Data.Files; using Lumina.Data.Files;
@ -9,33 +10,35 @@ namespace Glamourer.Util
{ {
public class IconStorage : IDisposable public class IconStorage : IDisposable
{ {
private readonly DalamudPluginInterface _pi; private readonly DalamudPluginInterface _pi;
private readonly Dictionary<int, TextureWrap> _icons; private readonly DataManager _gameData;
private readonly Dictionary<uint, TextureWrap> _icons;
public IconStorage(DalamudPluginInterface pi, int size = 0) public IconStorage(DalamudPluginInterface pi, DataManager gameData, int size = 0)
{ {
_pi = pi; _pi = pi;
_icons = new Dictionary<int, TextureWrap>(size); _gameData = gameData;
_icons = new Dictionary<uint, TextureWrap>(size);
} }
public TextureWrap this[int id] public TextureWrap this[int id]
=> LoadIcon(id); => LoadIcon(id);
private TexFile? LoadIconHq(int id) private TexFile? LoadIconHq(uint id)
{ {
var path = $"ui/icon/{id / 1000 * 1000:000000}/{id:000000}_hr1.tex"; var path = $"ui/icon/{id / 1000 * 1000:000000}/{id:000000}_hr1.tex";
return _pi.Data.GetFile<TexFile>(path); return _gameData.GetFile<TexFile>(path);
} }
public TextureWrap LoadIcon(uint id)
=> LoadIcon((int) id);
public TextureWrap LoadIcon(int id) public TextureWrap LoadIcon(int id)
=> LoadIcon((uint) id);
public TextureWrap LoadIcon(uint id)
{ {
if (_icons.TryGetValue(id, out var ret)) if (_icons.TryGetValue(id, out var ret))
return ret; return ret;
var icon = LoadIconHq(id) ?? _pi.Data.GetIcon(id); var icon = LoadIconHq(id) ?? _gameData.GetIcon(id)!;
var iconData = icon.GetRgbaImageData(); var iconData = icon.GetRgbaImageData();
ret = _pi.UiBuilder.LoadImageRaw(iconData, icon.Header.Width, icon.Header.Height, 4); ret = _pi.UiBuilder.LoadImageRaw(iconData, icon.Header.Width, icon.Header.Height, 4);

View file

@ -1,8 +1,8 @@
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Objects.Types;
namespace Glamourer namespace Glamourer
{ {
public static class ActorExtensions public static class CharacterExtensions
{ {
public const int WetnessOffset = 0x19A5; public const int WetnessOffset = 0x19A5;
public const byte WetnessFlag = 0x10; public const byte WetnessFlag = 0x10;
@ -13,10 +13,10 @@ namespace Glamourer
public const int WeaponHiddenOffset = 0xF64; public const int WeaponHiddenOffset = 0xF64;
public const byte WeaponHiddenFlag = 0x02; public const byte WeaponHiddenFlag = 0x02;
public static unsafe bool IsWet(this Actor a) public static unsafe bool IsWet(this Character a)
=> (*((byte*) a.Address + WetnessOffset) & WetnessFlag) != 0; => (*((byte*) a.Address + WetnessOffset) & WetnessFlag) != 0;
public static unsafe bool SetWetness(this Actor a, bool value) public static unsafe bool SetWetness(this Character a, bool value)
{ {
var current = a.IsWet(); var current = a.IsWet();
if (current == value) if (current == value)
@ -29,10 +29,10 @@ namespace Glamourer
return true; return true;
} }
public static unsafe ref byte StateFlags(this Actor a) public static unsafe ref byte StateFlags(this Character a)
=> ref *((byte*) a.Address + StateFlagsOffset); => ref *((byte*) a.Address + StateFlagsOffset);
public static bool SetStateFlag(this Actor a, bool value, byte flag) public static bool SetStateFlag(this Character a, bool value, byte flag)
{ {
var current = a.StateFlags(); var current = a.StateFlags();
var previousValue = (current & flag) != 0; var previousValue = (current & flag) != 0;
@ -46,20 +46,20 @@ namespace Glamourer
return true; return true;
} }
public static bool IsHatHidden(this Actor a) public static bool IsHatHidden(this Character a)
=> (a.StateFlags() & HatHiddenFlag) != 0; => (a.StateFlags() & HatHiddenFlag) != 0;
public static unsafe bool IsWeaponHidden(this Actor a) public static unsafe bool IsWeaponHidden(this Character a)
=> (a.StateFlags() & WeaponHiddenFlag) != 0 => (a.StateFlags() & WeaponHiddenFlag) != 0
&& (*((byte*) a.Address + WeaponHiddenOffset) & WeaponHiddenFlag) != 0; && (*((byte*) a.Address + WeaponHiddenOffset) & WeaponHiddenFlag) != 0;
public static bool IsVisorToggled(this Actor a) public static bool IsVisorToggled(this Character a)
=> (a.StateFlags() & VisorToggledFlag) != 0; => (a.StateFlags() & VisorToggledFlag) != 0;
public static bool SetHatHidden(this Actor a, bool value) public static bool SetHatHidden(this Character a, bool value)
=> SetStateFlag(a, value, HatHiddenFlag); => SetStateFlag(a, value, HatHiddenFlag);
public static unsafe bool SetWeaponHidden(this Actor a, bool value) public static unsafe bool SetWeaponHidden(this Character a, bool value)
{ {
var ret = SetStateFlag(a, value, WeaponHiddenFlag); var ret = SetStateFlag(a, value, WeaponHiddenFlag);
var val = *((byte*) a.Address + WeaponHiddenOffset); var val = *((byte*) a.Address + WeaponHiddenOffset);
@ -70,10 +70,10 @@ namespace Glamourer
return ret || (val & WeaponHiddenFlag) != 0 != value; return ret || (val & WeaponHiddenFlag) != 0 != value;
} }
public static bool SetVisorToggled(this Actor a, bool value) public static bool SetVisorToggled(this Character a, bool value)
=> SetStateFlag(a, value, VisorToggledFlag); => SetStateFlag(a, value, VisorToggledFlag);
public static unsafe ref float Alpha(this Actor a) public static unsafe ref float Alpha(this Character a)
=> ref *(float*) ((byte*) a.Address + AlphaOffset); => ref *(float*) ((byte*) a.Address + AlphaOffset);
} }
} }

View file

@ -1,5 +1,5 @@
using System; using System;
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Objects.Types;
using Glamourer.Customization; using Glamourer.Customization;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -121,7 +121,7 @@ namespace Glamourer
public ActorEquipMask WriteEquipment public ActorEquipMask WriteEquipment
{ {
get => (ActorEquipMask) ((ushort) _bytes[2] | ((ushort) _bytes[3] << 8)); get => (ActorEquipMask) (_bytes[2] | (_bytes[3] << 8));
set set
{ {
_bytes[2] = (byte) ((ushort) value & 0xFF); _bytes[2] = (byte) ((ushort) value & 0xFF);
@ -181,17 +181,17 @@ namespace Glamourer
private static void CheckActorMask(byte val1, byte val2) private static void CheckActorMask(byte val1, byte val2)
{ {
var mask = (ActorEquipMask) ((ushort) val1 | ((ushort) val2 << 8)); var mask = (ActorEquipMask) (val1 | (val2 << 8));
if (mask > ActorEquipMask.All) if (mask > ActorEquipMask.All)
throw new Exception($"Can not parse Base64 string into CharacterSave:\n\tInvalid value {mask} in byte 3 and 4."); throw new Exception($"Can not parse Base64 string into CharacterSave:\n\tInvalid value {mask} in byte 3 and 4.");
} }
public void LoadActor(Actor a) public void LoadActor(Character a)
{ {
WriteCustomizations = true; WriteCustomizations = true;
Load(new ActorCustomization(a)); Load(new ActorCustomization(a));
Load(new ActorEquipment(a), ActorEquipMask.All); Load(new ActorEquipment(a));
SetHatState = true; SetHatState = true;
SetVisorState = true; SetVisorState = true;
@ -202,7 +202,7 @@ namespace Glamourer
Alpha = a.Alpha(); Alpha = a.Alpha();
} }
public void Apply(Actor a) public void Apply(Character a)
{ {
if (WriteCustomizations) if (WriteCustomizations)
Customizations.Write(a.Address); Customizations.Write(a.Address);

View file

@ -1,23 +0,0 @@
using Dalamud.Plugin;
namespace Glamourer
{
public class CmpFile
{
public readonly Lumina.Data.FileResource File;
public readonly uint[] RgbaColors;
public CmpFile(DalamudPluginInterface pi)
{
File = pi.Data.GetFile("chara/xls/charamake/human.cmp");
RgbaColors = new uint[File.Data.Length >> 2];
for (var i = 0; i < File.Data.Length; i += 4)
{
RgbaColors[i >> 2] = File.Data[i]
| (uint) (File.Data[i + 1] << 8)
| (uint) (File.Data[i + 2] << 16)
| (uint) (File.Data[i + 3] << 24);
}
}
}
}

56
Glamourer/Dalamud.cs Normal file
View file

@ -0,0 +1,56 @@
using Dalamud.Data;
using Dalamud.Game;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Buddy;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Fates;
using Dalamud.Game.ClientState.JobGauge;
using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Party;
using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.Game.Gui.FlyText;
using Dalamud.Game.Gui.PartyFinder;
using Dalamud.Game.Gui.Toast;
using Dalamud.Game.Libc;
using Dalamud.Game.Network;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.IoC;
using Dalamud.Plugin;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
namespace Glamourer
{
public class Dalamud
{
public static void Initialize(DalamudPluginInterface pluginInterface)
=> pluginInterface.Create<Dalamud>();
// @formatter:off
[PluginService][RequiredVersion("1.0")] public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static CommandManager Commands { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static SigScanner SigScanner { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static DataManager GameData { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static ClientState ClientState { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static ChatGui Chat { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static SeStringManager SeStrings { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static ChatHandlers ChatHandlers { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static Framework Framework { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static GameNetwork Network { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static Condition Conditions { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static KeyState Keys { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static GameGui GameGui { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static FlyTextGui FlyTexts { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static ToastGui Toasts { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static JobGauges Gauges { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static PartyFinderGui PartyFinder { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static BuddyList Buddies { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static PartyList Party { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static TargetManager Targets { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static ObjectTable Objects { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static FateTable Fates { get; private set; } = null!;
//[PluginService][RequiredVersion("1.0")] public static LibcFunction LibC { get; private set; } = null!;
// @formatter:on
}
}

View file

@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Dalamud.Plugin; using Dalamud.Logging;
using Glamourer.FileSystem; using Glamourer.FileSystem;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -16,9 +16,9 @@ namespace Glamourer.Designs
public SortedList<string, CharacterSave> Designs = null!; public SortedList<string, CharacterSave> Designs = null!;
public FileSystem.FileSystem FileSystem { get; } = new(); public FileSystem.FileSystem FileSystem { get; } = new();
public DesignManager(DalamudPluginInterface pi) public DesignManager()
{ {
var saveFolder = new DirectoryInfo(pi.GetPluginConfigDirectory()); var saveFolder = new DirectoryInfo(Dalamud.PluginInterface.GetPluginConfigDirectory());
if (!saveFolder.Exists) if (!saveFolder.Exists)
Directory.CreateDirectory(saveFolder.FullName); Directory.CreateDirectory(saveFolder.FullName);
@ -31,24 +31,21 @@ namespace Glamourer.Designs
{ {
FileSystem.Clear(); FileSystem.Clear();
var anyChanges = false; var anyChanges = false;
foreach (var kvp in Designs.ToArray()) foreach (var (path, save) in Designs.ToArray())
{ {
var path = kvp.Key;
var save = kvp.Value;
try try
{ {
var (folder, name) = FileSystem.CreateAllFolders(path); var (folder, name) = FileSystem.CreateAllFolders(path);
var design = new Design(folder, name) { Data = save }; var design = new Design(folder, name) { Data = save };
folder.FindOrAddChild(design); folder.FindOrAddChild(design);
var fixedPath = design.FullName(); var fixedPath = design.FullName();
if (!string.Equals(fixedPath, path, StringComparison.InvariantCultureIgnoreCase)) if (string.Equals(fixedPath, path, StringComparison.InvariantCultureIgnoreCase))
{ continue;
Designs.Remove(path);
Designs[fixedPath] = save; Designs.Remove(path);
anyChanges = true; Designs[fixedPath] = save;
PluginLog.Debug($"Problem loading saved designs, {path} was renamed to {fixedPath}."); anyChanges = true;
} PluginLog.Debug($"Problem loading saved designs, {path} was renamed to {fixedPath}.");
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Linq; using Dalamud.Logging;
using Dalamud.Plugin;
using ImGuiNET; using ImGuiNET;
namespace Glamourer.FileSystem namespace Glamourer.FileSystem
@ -12,7 +11,7 @@ namespace Glamourer.FileSystem
private static unsafe bool IsDropping(string name) private static unsafe bool IsDropping(string name)
=> ImGui.AcceptDragDropPayload(name).NativePtr != null; => ImGui.AcceptDragDropPayload(name).NativePtr != null;
private static IFileSystemBase? _draggedObject = null; private static IFileSystemBase? _draggedObject;
public static bool DragDropTarget(FileSystem fs, IFileSystemBase child, out string oldPath, out IFileSystemBase? draggedChild) public static bool DragDropTarget(FileSystem fs, IFileSystemBase child, out string oldPath, out IFileSystemBase? draggedChild)
{ {

View file

@ -1,17 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Glamourer.Designs;
namespace Glamourer.FileSystem namespace Glamourer.FileSystem
{ {
internal class FolderStructureComparer : IComparer<IFileSystemBase> internal class FolderStructureComparer : IComparer<IFileSystemBase>
{ {
// Compare only the direct folder names since this is only used inside an enumeration of children of one folder. // Compare only the direct folder names since this is only used inside an enumeration of children of one folder.
public static int Cmp(IFileSystemBase x, IFileSystemBase y) public static int Cmp(IFileSystemBase? x, IFileSystemBase? y)
=> ReferenceEquals(x, y) ? 0 : string.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase); => ReferenceEquals(x, y) ? 0 : string.Compare(x?.Name, y?.Name, StringComparison.InvariantCultureIgnoreCase);
public int Compare(IFileSystemBase x, IFileSystemBase y) public int Compare(IFileSystemBase? x, IFileSystemBase? y)
=> Cmp(x, y); => Cmp(x, y);
internal static readonly FolderStructureComparer Default = new(); internal static readonly FolderStructureComparer Default = new();

View file

@ -1,11 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net472</TargetFramework> <TargetFramework>net5.0-windows</TargetFramework>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<PlatformTarget>x64</PlatformTarget>
<RootNamespace>Glamourer</RootNamespace> <RootNamespace>Glamourer</RootNamespace>
<AssemblyName>Glamourer</AssemblyName> <AssemblyName>Glamourer</AssemblyName>
<FileVersion>0.0.3.0</FileVersion> <FileVersion>0.0.4.0</FileVersion>
<AssemblyVersion>0.0.3.0</AssemblyVersion> <AssemblyVersion>0.0.4.0</AssemblyVersion>
<Company>SoftOtter</Company> <Company>SoftOtter</Company>
<Product>Glamourer</Product> <Product>Glamourer</Product>
<Copyright>Copyright © 2020</Copyright> <Copyright>Copyright © 2020</Copyright>
@ -63,25 +64,15 @@
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath> <HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
</Reference> </Reference>
<Reference Include="Penumbra.GameData"> <Reference Include="Penumbra.GameData">
<HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\net472\Penumbra.GameData.dll</HintPath> <HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\$(TargetFramework)\Penumbra.GameData.dll</HintPath>
</Reference> </Reference>
<Reference Include="Penumbra.Api"> <Reference Include="Penumbra.Api">
<HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\net472\Penumbra.Api.dll</HintPath> <HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\$(TargetFramework)\Penumbra.Api.dll</HintPath>
</Reference> </Reference>
<Reference Include="Penumbra.PlayerWatch"> <Reference Include="Penumbra.PlayerWatch">
<HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\net472\Penumbra.PlayerWatch.dll</HintPath> <HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\$(TargetFramework)\Penumbra.PlayerWatch.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> </ItemGroup>
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json"> <PackageReference Include="Newtonsoft.Json">

View file

@ -6,6 +6,6 @@
"AssemblyVersion": "0.0.3.0", "AssemblyVersion": "0.0.3.0",
"RepoUrl": "https://github.com/Ottermandias/Glamourer", "RepoUrl": "https://github.com/Ottermandias/Glamourer",
"ApplicableVersion": "any", "ApplicableVersion": "any",
"DalamudApiLevel": 3, "DalamudApiLevel": 4,
"LoadPriority": -100 "LoadPriority": -100
} }

View file

@ -20,17 +20,15 @@ namespace Glamourer
public uint EquipmentColor { get; set; } = DefaultEquipmentColor; public uint EquipmentColor { get; set; } = DefaultEquipmentColor;
public void Save() public void Save()
=> Glamourer.PluginInterface.SavePluginConfig(this); => Dalamud.PluginInterface.SavePluginConfig(this);
public static GlamourerConfig Create() public static GlamourerConfig Load()
{ {
var config = Glamourer.PluginInterface.GetPluginConfig() as GlamourerConfig; if (Dalamud.PluginInterface.GetPluginConfig() is GlamourerConfig config)
if (config == null) return config;
{
config = new GlamourerConfig();
Glamourer.PluginInterface.SavePluginConfig(config);
}
config = new GlamourerConfig();
config.Save();
return config; return config;
} }
} }

View file

@ -20,12 +20,12 @@ namespace Glamourer.Gui
private readonly IReadOnlyList<string> _itemNamesLower; private readonly IReadOnlyList<string> _itemNamesLower;
private readonly Func<T, string> _itemToName; private readonly Func<T, string> _itemToName;
public Action? PrePreview = null; public Action? PrePreview;
public Action? PostPreview = null; public Action? PostPreview;
public Func<T, bool>? CreateSelectable = null; public Func<T, bool>? CreateSelectable;
public Action? PreList = null; public Action? PreList;
public Action? PostList = null; public Action? PostList;
public float? HeightPerItem = null; public float? HeightPerItem;
private float _heightPerItem; private float _heightPerItem;
@ -99,7 +99,7 @@ namespace Glamourer.Gui
{ {
nodeIdx = i; nodeIdx = i;
var item = _items[i]!; var item = _items[i]!;
var success = false; bool success;
if (CreateSelectable != null) if (CreateSelectable != null)
{ {
success = CreateSelectable(item); success = CreateSelectable(item);
@ -151,7 +151,7 @@ namespace Glamourer.Gui
_heightPerItem = HeightPerItem ?? ImGui.GetTextLineHeightWithSpacing(); _heightPerItem = HeightPerItem ?? ImGui.GetTextLineHeightWithSpacing();
var ret = false; bool ret;
try try
{ {
ImGui.SetNextItemWidth(-1); ImGui.SetNextItemWidth(-1);

View file

@ -7,15 +7,12 @@ namespace Glamourer.Gui
{ {
public sealed class ImGuiRaii : IDisposable public sealed class ImGuiRaii : IDisposable
{ {
private int _colorStack = 0; private int _colorStack;
private int _fontStack = 0; private int _fontStack;
private int _styleStack = 0; private int _styleStack;
private float _indentation = 0f; private float _indentation;
private Stack<Action>? _onDispose = null; private Stack<Action>? _onDispose;
public ImGuiRaii()
{ }
public static ImGuiRaii NewGroup() public static ImGuiRaii NewGroup()
=> new ImGuiRaii().Group(); => new ImGuiRaii().Group();
@ -51,6 +48,7 @@ namespace Glamourer.Gui
ImGui.PopStyleColor(actualN); ImGui.PopStyleColor(actualN);
_colorStack -= actualN; _colorStack -= actualN;
} }
return this; return this;
} }
@ -76,6 +74,7 @@ namespace Glamourer.Gui
ImGui.PopStyleVar(actualN); ImGui.PopStyleVar(actualN);
_styleStack -= actualN; _styleStack -= actualN;
} }
return this; return this;
} }
@ -95,6 +94,7 @@ namespace Glamourer.Gui
ImGui.PopFont(); ImGui.PopFont();
--_fontStack; --_fontStack;
} }
return this; return this;
} }
@ -105,6 +105,7 @@ namespace Glamourer.Gui
ImGui.Indent(width); ImGui.Indent(width);
_indentation += width; _indentation += width;
} }
return this; return this;
} }
@ -134,7 +135,7 @@ namespace Glamourer.Gui
public void End(int n = 1) public void End(int n = 1)
{ {
var actualN = Math.Min(n, _onDispose?.Count ?? 0); var actualN = Math.Min(n, _onDispose?.Count ?? 0);
while(actualN-- > 0) while (actualN-- > 0)
_onDispose!.Pop()(); _onDispose!.Pop()();
} }

View file

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Game.ClientState.Actors;
using Glamourer.Designs; using Glamourer.Designs;
using ImGuiNET; using ImGuiNET;
using Penumbra.GameData; using Penumbra.GameData;
@ -19,7 +18,6 @@ namespace Glamourer.Gui
private readonly string _glamourerHeader; private readonly string _glamourerHeader;
private readonly IReadOnlyDictionary<byte, Stain> _stains; private readonly IReadOnlyDictionary<byte, Stain> _stains;
private readonly ActorTable _actors;
private readonly IObjectIdentifier _identifier; private readonly IObjectIdentifier _identifier;
private readonly Dictionary<EquipSlot, (ComboWithFilter<Item>, ComboWithFilter<Stain>)> _combos; private readonly Dictionary<EquipSlot, (ComboWithFilter<Item>, ComboWithFilter<Stain>)> _combos;
private readonly ImGuiScene.TextureWrap? _legacyTattooIcon; private readonly ImGuiScene.TextureWrap? _legacyTattooIcon;
@ -27,8 +25,8 @@ namespace Glamourer.Gui
private readonly DesignManager _designs; private readonly DesignManager _designs;
private readonly Glamourer _plugin; private readonly Glamourer _plugin;
private bool _visible = false; private bool _visible;
private bool _inGPose = false; private bool _inGPose;
public Interface(Glamourer plugin) public Interface(Glamourer plugin)
{ {
@ -37,31 +35,30 @@ namespace Glamourer.Gui
_glamourerHeader = Glamourer.Version.Length > 0 _glamourerHeader = Glamourer.Version.Length > 0
? $"{PluginName} v{Glamourer.Version}###{PluginName}Main" ? $"{PluginName} v{Glamourer.Version}###{PluginName}Main"
: $"{PluginName}###{PluginName}Main"; : $"{PluginName}###{PluginName}Main";
Glamourer.PluginInterface.UiBuilder.DisableGposeUiHide = true; Dalamud.PluginInterface.UiBuilder.DisableGposeUiHide = true;
Glamourer.PluginInterface.UiBuilder.OnBuildUi += Draw; Dalamud.PluginInterface.UiBuilder.Draw += Draw;
Glamourer.PluginInterface.UiBuilder.OnOpenConfigUi += ToggleVisibility; Dalamud.PluginInterface.UiBuilder.OpenConfigUi += ToggleVisibility;
_equipSlotNames = GetEquipSlotNames(); _equipSlotNames = GetEquipSlotNames();
_stains = GameData.Stains(Glamourer.PluginInterface); _stains = GameData.Stains(Dalamud.GameData);
_identifier = Penumbra.GameData.GameData.GetIdentifier(Glamourer.PluginInterface); _identifier = Penumbra.GameData.GameData.GetIdentifier(Dalamud.GameData, Dalamud.ClientState.ClientLanguage);
_actors = Glamourer.PluginInterface.ClientState.Actors;
var stainCombo = CreateDefaultStainCombo(_stains.Values.ToArray()); var stainCombo = CreateDefaultStainCombo(_stains.Values.ToArray());
var equip = GameData.ItemsBySlot(Glamourer.PluginInterface); var equip = GameData.ItemsBySlot(Dalamud.GameData);
_combos = equip.ToDictionary(kvp => kvp.Key, kvp => CreateCombos(kvp.Key, kvp.Value, stainCombo)); _combos = equip.ToDictionary(kvp => kvp.Key, kvp => CreateCombos(kvp.Key, kvp.Value, stainCombo));
_legacyTattooIcon = GetLegacyTattooIcon(); _legacyTattooIcon = GetLegacyTattooIcon();
} }
public void ToggleVisibility(object _, object _2) public void ToggleVisibility()
=> _visible = !_visible; => _visible = !_visible;
public void Dispose() public void Dispose()
{ {
_legacyTattooIcon?.Dispose(); _legacyTattooIcon?.Dispose();
Glamourer.PluginInterface.UiBuilder.OnBuildUi -= Draw; Dalamud.PluginInterface.UiBuilder.Draw -= Draw;
Glamourer.PluginInterface.UiBuilder.OnOpenConfigUi -= ToggleVisibility; Dalamud.PluginInterface.UiBuilder.OpenConfigUi -= ToggleVisibility;
} }
private void Draw() private void Draw()
@ -80,7 +77,7 @@ namespace Glamourer.Gui
if (!raii.Begin(() => ImGui.BeginTabBar("##tabBar"), ImGui.EndTabBar)) if (!raii.Begin(() => ImGui.BeginTabBar("##tabBar"), ImGui.EndTabBar))
return; return;
_inGPose = _actors[GPoseActorId] != null; _inGPose = Dalamud.Objects[GPoseActorId] != null;
_iconSize = Vector2.One * ImGui.GetTextLineHeightWithSpacing() * 2; _iconSize = Vector2.One * ImGui.GetTextLineHeightWithSpacing() * 2;
_actualIconSize = _iconSize + 2 * ImGui.GetStyle().FramePadding; _actualIconSize = _iconSize + 2 * ImGui.GetStyle().FramePadding;
_comboSelectorSize = 4 * _actualIconSize.X + 3 * ImGui.GetStyle().ItemSpacing.X; _comboSelectorSize = 4 * _actualIconSize.X + 3 * ImGui.GetStyle().ItemSpacing.X;

View file

@ -1,9 +1,9 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Windows.Forms; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Plugin; using Dalamud.Logging;
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.FileSystem; using Glamourer.FileSystem;
using ImGuiNET; using ImGuiNET;
@ -12,9 +12,9 @@ namespace Glamourer.Gui
{ {
internal partial class Interface internal partial class Interface
{ {
private readonly CharacterSave _currentSave = new(); private readonly CharacterSave _currentSave = new();
private string _newDesignName = string.Empty; private string _newDesignName = string.Empty;
private bool _keyboardFocus = false; private bool _keyboardFocus;
private const string DesignNamePopupLabel = "Save Design As..."; private const string DesignNamePopupLabel = "Save Design As...";
private const uint RedHeaderColor = 0xFF1818C0; private const uint RedHeaderColor = 0xFF1818C0;
private const uint GreenHeaderColor = 0xFF18C018; private const uint GreenHeaderColor = 0xFF18C018;
@ -37,7 +37,7 @@ namespace Glamourer.Gui
{ {
ImGui.PushFont(UiBuilder.IconFont); ImGui.PushFont(UiBuilder.IconFont);
if (ImGui.Button(FontAwesomeIcon.Clipboard.ToIconString())) if (ImGui.Button(FontAwesomeIcon.Clipboard.ToIconString()))
Clipboard.SetText(save.ToBase64()); ImGui.SetClipboardText(save.ToBase64());
ImGui.PopFont(); ImGui.PopFont();
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
ImGui.SetTooltip("Copy customization code to clipboard."); ImGui.SetTooltip("Copy customization code to clipboard.");
@ -54,7 +54,7 @@ namespace Glamourer.Gui
if (!applyButton) if (!applyButton)
return false; return false;
var text = Clipboard.GetText(); var text = ImGui.GetClipboardText();
if (!text.Any()) if (!text.Any())
return false; return false;
@ -88,41 +88,41 @@ namespace Glamourer.Gui
private void DrawTargetPlayerButton() private void DrawTargetPlayerButton()
{ {
if (ImGui.Button("Target Player")) if (ImGui.Button("Target Player"))
Glamourer.PluginInterface.ClientState.Targets.SetCurrentTarget(_player); Dalamud.Targets.SetTarget(_player);
} }
private void DrawApplyToPlayerButton(CharacterSave save) private void DrawApplyToPlayerButton(CharacterSave save)
{ {
if (ImGui.Button("Apply to Self")) if (!ImGui.Button("Apply to Self"))
{ return;
var player = _inGPose
? Glamourer.PluginInterface.ClientState.Actors[GPoseActorId] var player = _inGPose
: Glamourer.PluginInterface.ClientState.LocalPlayer; ? (Character?) Dalamud.Objects[GPoseActorId]
var fallback = _inGPose ? Glamourer.PluginInterface.ClientState.LocalPlayer : null; : Dalamud.ClientState.LocalPlayer;
if (player != null) var fallback = _inGPose ? Dalamud.ClientState.LocalPlayer : null;
{ if (player == null)
save.Apply(player); return;
if (_inGPose)
save.Apply(fallback!); save.Apply(player);
_plugin.UpdateActors(player, fallback); if (_inGPose)
} save.Apply(fallback!);
} _plugin.UpdateActors(player, fallback);
} }
private void DrawApplyToTargetButton(CharacterSave save) private void DrawApplyToTargetButton(CharacterSave save)
{ {
if (ImGui.Button("Apply to Target")) if (!ImGui.Button("Apply to Target"))
{ return;
var player = Glamourer.PluginInterface.ClientState.Targets.CurrentTarget;
if (player != null) var player = Dalamud.Targets.Target as Character;
{ if (player == null)
var fallBackActor = _playerNames[player.Name]; return;
save.Apply(player);
if (fallBackActor != null) var fallBackActor = _playerNames[player.Name.ToString()];
save.Apply(fallBackActor); save.Apply(player);
_plugin.UpdateActors(player, fallBackActor); if (fallBackActor != null)
} save.Apply(fallBackActor);
} _plugin.UpdateActors(player, fallBackActor);
} }
private void SaveNewDesign(CharacterSave save) private void SaveNewDesign(CharacterSave save)
@ -130,13 +130,13 @@ namespace Glamourer.Gui
try try
{ {
var (folder, name) = _designs.FileSystem.CreateAllFolders(_newDesignName); var (folder, name) = _designs.FileSystem.CreateAllFolders(_newDesignName);
if (name.Any()) if (!name.Any())
{ return;
var newDesign = new Design(folder, name) { Data = save };
folder.AddChild(newDesign); var newDesign = new Design(folder, name) { Data = save };
_designs.Designs[newDesign.FullName()] = save; folder.AddChild(newDesign);
_designs.SaveToFile(); _designs.Designs[newDesign.FullName()] = save;
} _designs.SaveToFile();
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -1,8 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Game.ClientState.Actors; using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Interface; using Dalamud.Interface;
using ImGuiNET; using ImGuiNET;
@ -10,11 +10,11 @@ namespace Glamourer.Gui
{ {
internal partial class Interface internal partial class Interface
{ {
private Actor? _player; private Character? _player;
private string _currentActorName = string.Empty; private string _currentActorName = string.Empty;
private string _actorFilter = string.Empty; private string _actorFilter = string.Empty;
private string _actorFilterLower = string.Empty; private string _actorFilterLower = string.Empty;
private readonly Dictionary<string, Actor?> _playerNames = new(400); private readonly Dictionary<string, Character?> _playerNames = new(400);
private void DrawActorFilter() private void DrawActorFilter()
{ {
@ -26,9 +26,9 @@ namespace Glamourer.Gui
_actorFilterLower = _actorFilter.ToLowerInvariant(); _actorFilterLower = _actorFilter.ToLowerInvariant();
} }
private void DrawActorSelectable(Actor actor, bool gPose) private void DrawActorSelectable(Character actor, bool gPose)
{ {
var actorName = actor.Name; var actorName = actor.Name.ToString();
if (!actorName.Any()) if (!actorName.Any())
return; return;
@ -50,7 +50,7 @@ namespace Glamourer.Gui
return; return;
} }
if (_currentActorName == actor.Name) if (_currentActorName == actorName)
{ {
_currentSave.LoadActor(actor); _currentSave.LoadActor(actor);
_player = actor; _player = actor;
@ -63,10 +63,10 @@ namespace Glamourer.Gui
.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) .PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
.PushStyle(ImGuiStyleVar.FrameRounding, 0) .PushStyle(ImGuiStyleVar.FrameRounding, 0)
.PushFont(UiBuilder.IconFont); .PushFont(UiBuilder.IconFont);
Actor? select = null; Character? select = null;
var buttonWidth = Vector2.UnitX * SelectorWidth / 2; var buttonWidth = Vector2.UnitX * SelectorWidth / 2;
if (ImGui.Button(FontAwesomeIcon.UserCircle.ToIconString(), buttonWidth)) if (ImGui.Button(FontAwesomeIcon.UserCircle.ToIconString(), buttonWidth))
select = Glamourer.PluginInterface.ClientState.LocalPlayer; select = Dalamud.ClientState.LocalPlayer;
raii.PopFonts(); raii.PopFonts();
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
ImGui.SetTooltip("Select the local player character."); ImGui.SetTooltip("Select the local player character.");
@ -81,7 +81,7 @@ namespace Glamourer.Gui
else else
{ {
if (ImGui.Button(FontAwesomeIcon.HandPointer.ToIconString(), buttonWidth)) if (ImGui.Button(FontAwesomeIcon.HandPointer.ToIconString(), buttonWidth))
select = Glamourer.PluginInterface.ClientState.Targets.CurrentTarget; select = Dalamud.Targets.Target as Character;
} }
raii.PopFonts(); raii.PopFonts();
@ -92,7 +92,7 @@ namespace Glamourer.Gui
return; return;
_player = select; _player = select;
_currentActorName = _player.Name; _currentActorName = _player.Name.ToString();
_currentSave.LoadActor(_player); _currentSave.LoadActor(_player);
} }
@ -107,7 +107,7 @@ namespace Glamourer.Gui
_playerNames.Clear(); _playerNames.Clear();
for (var i = GPoseActorId; i < GPoseActorId + 48; ++i) for (var i = GPoseActorId; i < GPoseActorId + 48; ++i)
{ {
var actor = _actors[i]; var actor = Dalamud.Objects[i] as Character;
if (actor == null) if (actor == null)
break; break;
@ -117,13 +117,13 @@ namespace Glamourer.Gui
for (var i = 0; i < GPoseActorId; i += 2) for (var i = 0; i < GPoseActorId; i += 2)
{ {
var actor = _actors[i]; var actor = Dalamud.Objects[i] as Character;
if (actor != null && actor.ObjectKind == ObjectKind.Player) if (actor != null && actor.ObjectKind == ObjectKind.Player)
DrawActorSelectable(actor, false); DrawActorSelectable(actor, false);
} }
using (var raii = new ImGuiRaii().PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)) using (var _ = new ImGuiRaii().PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
{ {
ImGui.EndChild(); ImGui.EndChild();
} }

View file

@ -53,7 +53,7 @@ namespace Glamourer.Gui
return; return;
} }
if (ImGui.Button(buttonLabel) && _plugin.GetPenumbra()) if (ImGui.Button(buttonLabel) && Glamourer.GetPenumbra())
{ {
_plugin.UnregisterFunctions(); _plugin.UnregisterFunctions();
_plugin.RegisterFunctions(); _plugin.RegisterFunctions();
@ -88,7 +88,7 @@ namespace Glamourer.Gui
cfg.AttachToPenumbra = v; cfg.AttachToPenumbra = v;
if (v) if (v)
{ {
if (_plugin.GetPenumbra()) if (Glamourer.GetPenumbra())
_plugin.RegisterFunctions(); _plugin.RegisterFunctions();
} }
else else

View file

@ -2,7 +2,7 @@
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Plugin; using Dalamud.Logging;
using Glamourer.Customization; using Glamourer.Customization;
using ImGuiNET; using ImGuiNET;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
@ -39,13 +39,13 @@ namespace Glamourer.Gui
return ret; return ret;
} }
private Vector2 _iconSize = Vector2.Zero; private Vector2 _iconSize = Vector2.Zero;
private Vector2 _actualIconSize = Vector2.Zero; private Vector2 _actualIconSize = Vector2.Zero;
private float _raceSelectorWidth = 0; private float _raceSelectorWidth;
private float _inputIntSize = 0; private float _inputIntSize;
private float _comboSelectorSize = 0; private float _comboSelectorSize;
private float _percentageSize = 0; private float _percentageSize;
private float _itemComboWidth = 0; private float _itemComboWidth;
private bool InputInt(string label, ref int value, int minValue, int maxValue) private bool InputInt(string label, ref int value, int minValue, int maxValue)
{ {
@ -93,7 +93,7 @@ namespace Glamourer.Gui
ImGui.SameLine(); ImGui.SameLine();
using (var group = ImGuiRaii.NewGroup()) using (var _ = ImGuiRaii.NewGroup())
{ {
if (InputInt($"##text_{id}", ref current, 1, count)) if (InputInt($"##text_{id}", ref current, 1, count))
{ {

View file

@ -1,9 +1,8 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Windows.Forms;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Plugin; using Dalamud.Logging;
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.FileSystem; using Glamourer.FileSystem;
using ImGuiNET; using ImGuiNET;
@ -12,9 +11,9 @@ namespace Glamourer.Gui
{ {
internal partial class Interface internal partial class Interface
{ {
private int _totalObject = 0; private int _totalObject;
private Design? _selection = null; private Design? _selection;
private string _newChildName = string.Empty; private string _newChildName = string.Empty;
private void DrawDesignSelector() private void DrawDesignSelector()
@ -50,7 +49,7 @@ namespace Glamourer.Gui
if (_selection!.Data.WriteProtected || !applyButton) if (_selection!.Data.WriteProtected || !applyButton)
return; return;
var text = Clipboard.GetText(); var text = ImGui.GetClipboardText();
if (!text.Any()) if (!text.Any())
return; return;
@ -280,7 +279,6 @@ namespace Glamourer.Gui
private void ContextMenu(IFileSystemBase child) private void ContextMenu(IFileSystemBase child)
{ {
var label = $"##fsPopup{child.FullName()}"; var label = $"##fsPopup{child.FullName()}";
var renameLabel = $"{label}_rename";
if (ImGui.BeginPopup(label)) if (ImGui.BeginPopup(label))
{ {
if (ImGui.MenuItem("Delete")) if (ImGui.MenuItem("Delete"))
@ -289,7 +287,7 @@ namespace Glamourer.Gui
RenameChildInput(child); RenameChildInput(child);
if (child is Design d && ImGui.MenuItem("Copy to Clipboard")) if (child is Design d && ImGui.MenuItem("Copy to Clipboard"))
Clipboard.SetText(d.Data.ToBase64()); ImGui.SetClipboardText(d.Data.ToBase64());
ImGui.EndPopup(); ImGui.EndPopup();
} }

View file

@ -1,11 +1,8 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Windows.Forms; using Dalamud.Logging;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Plugin;
using Glamourer.Customization; using Glamourer.Customization;
using ImGuiNET; using ImGuiNET;
using Penumbra.Api;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
namespace Glamourer.Gui namespace Glamourer.Gui
@ -46,7 +43,7 @@ namespace Glamourer.Gui
break; break;
default: default:
var count = set.Count(id); var count = set.Count(id);
if (set.DataByValue(id, customization[id], out var value) < 0) if (set.DataByValue(id, customization[id], out _) < 0)
if (count == 0) if (count == 0)
customization[id] = 0; customization[id] = 0;
else else
@ -173,7 +170,7 @@ namespace Glamourer.Gui
case DesignNameUse.FromClipboard: case DesignNameUse.FromClipboard:
try try
{ {
var text = Clipboard.GetText(); var text = ImGui.GetClipboardText();
var save = CharacterSave.FromString(text); var save = CharacterSave.FromString(text);
SaveNewDesign(save); SaveNewDesign(save);
} }

View file

@ -53,7 +53,7 @@ namespace Glamourer.Gui
{ {
var rawImage = new byte[resource.Length]; var rawImage = new byte[resource.Length];
resource.Read(rawImage, 0, (int) resource.Length); resource.Read(rawImage, 0, (int) resource.Length);
return Glamourer.PluginInterface.UiBuilder.LoadImageRaw(rawImage, 192, 192, 4); return Dalamud.PluginInterface.UiBuilder.LoadImageRaw(rawImage, 192, 192, 4);
} }
return null; return null;
@ -61,7 +61,7 @@ namespace Glamourer.Gui
private static Dictionary<EquipSlot, string> GetEquipSlotNames() private static Dictionary<EquipSlot, string> GetEquipSlotNames()
{ {
var sheet = Glamourer.PluginInterface.Data.GetExcelSheet<Addon>(); var sheet = Dalamud.GameData.GetExcelSheet<Addon>()!;
var ret = new Dictionary<EquipSlot, string>(12) var ret = new Dictionary<EquipSlot, string>(12)
{ {
[EquipSlot.MainHand] = sheet.GetRow(738)?.Text.ToString() ?? "Main Hand", [EquipSlot.MainHand] = sheet.GetRow(738)?.Text.ToString() ?? "Main Hand",

View file

@ -1,5 +1,5 @@
using System; using System;
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Objects.Types;
using ImGuiNET; using ImGuiNET;
namespace Glamourer.Gui namespace Glamourer.Gui
@ -18,7 +18,7 @@ namespace Glamourer.Gui
return false; return false;
} }
private static bool DrawMiscellaneous(CharacterSave save, Actor? player) private static bool DrawMiscellaneous(CharacterSave save, Character? player)
{ {
var ret = false; var ret = false;
if (!ImGui.CollapsingHeader("Miscellaneous")) if (!ImGui.CollapsingHeader("Miscellaneous"))

View file

@ -1,10 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Logging;
using Dalamud.Plugin; using Dalamud.Plugin;
using Glamourer.Customization; using Glamourer.Customization;
using Glamourer.Designs; using Glamourer.Designs;
@ -18,36 +17,23 @@ namespace Glamourer
{ {
public class Glamourer : IDalamudPlugin public class Glamourer : IDalamudPlugin
{ {
public const int RequiredPenumbraShareVersion = 1; public const int RequiredPenumbraShareVersion = 3;
private const string HelpString = "[Copy|Apply|Save],[Name or PlaceHolder],<Name for Save>"; private const string HelpString = "[Copy|Apply|Save],[Name or PlaceHolder],<Name for Save>";
public string Name public string Name
=> "Glamourer"; => "Glamourer";
public static DalamudPluginInterface PluginInterface = null!; public static GlamourerConfig Config = null!;
public static GlamourerConfig Config = null!; private Interface _interface = null!;
private Interface _interface = null!; public static ICustomizationManager Customization = null!;
public static ICustomizationManager Customization = null!; public DesignManager Designs = null!;
public DesignManager Designs = null!; public IPlayerWatcher PlayerWatcher = null!;
public IPlayerWatcher PlayerWatcher = null!;
public static string Version = string.Empty; public static string Version = string.Empty;
public static IPenumbraApi? Penumbra; public static IPenumbraApi? Penumbra;
private Dalamud.Dalamud _dalamud = null!;
private List<(IDalamudPlugin Plugin, PluginDefinition Definition, DalamudPluginInterface PluginInterface, bool IsRaw)> _plugins = null!;
private void SetDalamud(DalamudPluginInterface pi)
{
var dalamud = (Dalamud.Dalamud?) pi.GetType()
?.GetField("dalamud", BindingFlags.NonPublic | BindingFlags.Instance)
?.GetValue(pi);
_dalamud = dalamud ?? throw new Exception("Could not obtain Dalamud.");
}
private static void PenumbraTooltip(object? it) private static void PenumbraTooltip(object? it)
{ {
if (it is Lumina.Excel.GeneratedSheets.Item) if (it is Lumina.Excel.GeneratedSheets.Item)
@ -56,22 +42,21 @@ namespace Glamourer
private void PenumbraRightClick(MouseButton button, object? it) private void PenumbraRightClick(MouseButton button, object? it)
{ {
if (button == MouseButton.Right && it is Lumina.Excel.GeneratedSheets.Item item) if (button != MouseButton.Right || it is not Lumina.Excel.GeneratedSheets.Item item)
return;
var gPose = Dalamud.Objects[Interface.GPoseActorId] as Character;
var player = Dalamud.Objects[0] as Character;
var writeItem = new Item(item, string.Empty);
if (gPose != null)
{ {
var actors = PluginInterface.ClientState.Actors; writeItem.Write(gPose.Address);
var gPose = actors[Interface.GPoseActorId]; UpdateActors(gPose, player);
var player = actors[0]; }
var writeItem = new Item(item, string.Empty); else if (player != null)
if (gPose != null) {
{ writeItem.Write(player.Address);
writeItem.Write(gPose.Address); UpdateActors(player);
UpdateActors(gPose, player);
}
else if (player != null)
{
writeItem.Write(player.Address);
UpdateActors(player);
}
} }
} }
@ -93,61 +78,51 @@ namespace Glamourer
Penumbra!.ChangedItemClicked -= PenumbraRightClick; Penumbra!.ChangedItemClicked -= PenumbraRightClick;
} }
private void SetPlugins(DalamudPluginInterface pi) internal static bool GetPenumbra()
{ {
var pluginManager = _dalamud?.GetType() try
?.GetProperty("PluginManager", BindingFlags.Instance | BindingFlags.NonPublic) {
?.GetValue(_dalamud); var subscriber = Dalamud.PluginInterface.GetIpcSubscriber<IPenumbraApiBase>("Penumbra.Api");
var penumbraApiBase = subscriber.InvokeFunc();
if (penumbraApiBase.ApiVersion != RequiredPenumbraShareVersion)
{
PluginLog.Debug("Could not get Penumbra because API version {penumbraApiBase.ApiVersion} does not equal the required version {RequiredPenumbraShareVersion}.");
Penumbra = null;
return false;
}
if (pluginManager == null) Penumbra = penumbraApiBase as IPenumbraApi;
throw new Exception("Could not obtain plugin manager."); }
catch (IpcNotReadyError ipc)
var pluginsList = {
(List<(IDalamudPlugin Plugin, PluginDefinition Definition, DalamudPluginInterface PluginInterface, bool IsRaw)>?) pluginManager
?.GetType()
?.GetProperty("Plugins", BindingFlags.Instance | BindingFlags.Public)
?.GetValue(pluginManager);
_plugins = pluginsList ?? throw new Exception("Could not obtain Dalamud.");
}
public bool GetPenumbra()
{
if (Penumbra?.Valid ?? false)
return true;
var plugin = _plugins.Find(p
=> p.Definition.InternalName == "Penumbra"
&& string.Compare(p.Definition.AssemblyVersion, "0.4.0.3", StringComparison.Ordinal) >= 0).Plugin;
var penumbra = (IPenumbraApiBase?) plugin?.GetType().GetProperty("Api", BindingFlags.Instance | BindingFlags.Public)
?.GetValue(plugin);
if (penumbra != null && penumbra.Valid && penumbra.ApiVersion >= RequiredPenumbraShareVersion)
Penumbra = (IPenumbraApi) penumbra!;
else
Penumbra = null; Penumbra = null;
PluginLog.Debug($"Could not get Penumbra because IPC not registered:\n{ipc}");
}
catch (Exception e)
{
Penumbra = null;
PluginLog.Debug($"Could not get Penumbra for unknown reason:\n{e}");
}
return Penumbra != null; return Penumbra != null;
} }
public void Initialize(DalamudPluginInterface pluginInterface) public Glamourer(DalamudPluginInterface pluginInterface)
{ {
Version = Assembly.GetExecutingAssembly()?.GetName().Version.ToString() ?? ""; Dalamud.Initialize(pluginInterface);
PluginInterface = pluginInterface; Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "";
Config = GlamourerConfig.Create(); Config = GlamourerConfig.Load();
Customization = CustomizationManager.Create(PluginInterface); Customization = CustomizationManager.Create(Dalamud.PluginInterface, Dalamud.GameData, Dalamud.ClientState.ClientLanguage);
SetDalamud(PluginInterface); Designs = new DesignManager();
SetPlugins(PluginInterface);
Designs = new DesignManager(PluginInterface);
if (GetPenumbra() && Config.AttachToPenumbra) if (GetPenumbra() && Config.AttachToPenumbra)
RegisterFunctions(); RegisterFunctions();
PlayerWatcher = PlayerWatchFactory.Create(PluginInterface); PlayerWatcher = PlayerWatchFactory.Create(Dalamud.Framework, Dalamud.ClientState, Dalamud.Objects);
PluginInterface.CommandManager.AddHandler("/glamourer", new CommandInfo(OnGlamourer) Dalamud.Commands.AddHandler("/glamourer", new CommandInfo(OnGlamourer)
{ {
HelpMessage = "Open or close the Glamourer window.", HelpMessage = "Open or close the Glamourer window.",
}); });
PluginInterface.CommandManager.AddHandler("/glamour", new CommandInfo(OnGlamour) Dalamud.Commands.AddHandler("/glamour", new CommandInfo(OnGlamour)
{ {
HelpMessage = $"Use Glamourer Functions: {HelpString}", HelpMessage = $"Use Glamourer Functions: {HelpString}",
}); });
@ -156,48 +131,48 @@ namespace Glamourer
} }
public void OnGlamourer(string command, string arguments) public void OnGlamourer(string command, string arguments)
=> _interface?.ToggleVisibility(null!, null!); => _interface.ToggleVisibility();
private Actor? GetActor(string name) private static GameObject? GetActor(string name)
{ {
var lowerName = name.ToLowerInvariant(); var lowerName = name.ToLowerInvariant();
return lowerName switch return lowerName switch
{ {
"" => null, "" => null,
"<me>" => PluginInterface.ClientState.Actors[Interface.GPoseActorId] ?? PluginInterface.ClientState.LocalPlayer, "<me>" => Dalamud.Objects[Interface.GPoseActorId] ?? Dalamud.ClientState.LocalPlayer,
"self" => PluginInterface.ClientState.Actors[Interface.GPoseActorId] ?? PluginInterface.ClientState.LocalPlayer, "self" => Dalamud.Objects[Interface.GPoseActorId] ?? Dalamud.ClientState.LocalPlayer,
"<t>" => PluginInterface.ClientState.Targets.CurrentTarget, "<t>" => Dalamud.Targets.Target,
"target" => PluginInterface.ClientState.Targets.CurrentTarget, "target" => Dalamud.Targets.Target,
"<f>" => PluginInterface.ClientState.Targets.FocusTarget, "<f>" => Dalamud.Targets.FocusTarget,
"focus" => PluginInterface.ClientState.Targets.FocusTarget, "focus" => Dalamud.Targets.FocusTarget,
"<mo>" => PluginInterface.ClientState.Targets.MouseOverTarget, "<mo>" => Dalamud.Targets.MouseOverTarget,
"mouseover" => PluginInterface.ClientState.Targets.MouseOverTarget, "mouseover" => Dalamud.Targets.MouseOverTarget,
_ => PluginInterface.ClientState.Actors.LastOrDefault( _ => Dalamud.Objects.LastOrDefault(
a => string.Equals(a.Name, lowerName, StringComparison.InvariantCultureIgnoreCase)), a => string.Equals(a.Name.ToString(), lowerName, StringComparison.InvariantCultureIgnoreCase)),
}; };
} }
public void CopyToClipboard(Actor actor) public void CopyToClipboard(Character actor)
{ {
var save = new CharacterSave(); var save = new CharacterSave();
save.LoadActor(actor); save.LoadActor(actor);
Clipboard.SetText(save.ToBase64()); ImGui.SetClipboardText(save.ToBase64());
} }
public void ApplyCommand(Actor actor, string target) public void ApplyCommand(Character actor, string target)
{ {
CharacterSave? save = null; CharacterSave? save = null;
if (target.ToLowerInvariant() == "clipboard") if (target.ToLowerInvariant() == "clipboard")
try try
{ {
save = CharacterSave.FromString(Clipboard.GetText()); save = CharacterSave.FromString(ImGui.GetClipboardText());
} }
catch (Exception) catch (Exception)
{ {
PluginInterface.Framework.Gui.Chat.PrintError("Clipboard does not contain a valid customization string."); Dalamud.Chat.PrintError("Clipboard does not contain a valid customization string.");
} }
else if (!Designs.FileSystem.Find(target, out var child) || child is not Design d) else if (!Designs.FileSystem.Find(target, out var child) || child is not Design d)
PluginInterface.Framework.Gui.Chat.PrintError("The given path to a saved design does not exist or does not point to a design."); Dalamud.Chat.PrintError("The given path to a saved design does not exist or does not point to a design.");
else else
save = d.Data; save = d.Data;
@ -205,7 +180,7 @@ namespace Glamourer
UpdateActors(actor); UpdateActors(actor);
} }
public void SaveCommand(Actor actor, string path) public void SaveCommand(Character actor, string path)
{ {
var save = new CharacterSave(); var save = new CharacterSave();
save.LoadActor(actor); save.LoadActor(actor);
@ -219,8 +194,8 @@ namespace Glamourer
} }
catch (Exception e) catch (Exception e)
{ {
PluginInterface.Framework.Gui.Chat.PrintError("Could not save file:"); Dalamud.Chat.PrintError("Could not save file:");
PluginInterface.Framework.Gui.Chat.PrintError($" {e.Message}"); Dalamud.Chat.PrintError($" {e.Message}");
} }
} }
@ -228,8 +203,8 @@ namespace Glamourer
{ {
static void PrintHelp() static void PrintHelp()
{ {
PluginInterface.Framework.Gui.Chat.Print("Usage:"); Dalamud.Chat.Print("Usage:");
PluginInterface.Framework.Gui.Chat.Print($" {HelpString}"); Dalamud.Chat.Print($" {HelpString}");
} }
arguments = arguments.Trim(); arguments = arguments.Trim();
@ -250,10 +225,10 @@ namespace Glamourer
return; return;
} }
var actor = GetActor(split[1]); var actor = GetActor(split[1]) as Character;
if (actor == null) if (actor == null)
{ {
PluginInterface.Framework.Gui.Chat.Print($"Could not find actor for {split[1]}."); Dalamud.Chat.Print($"Could not find actor for {split[1]} or it was not a Character.");
return; return;
} }
@ -266,7 +241,7 @@ namespace Glamourer
{ {
if (split.Length < 3) if (split.Length < 3)
{ {
PluginInterface.Framework.Gui.Chat.Print("Applying requires a name for the save to be applied or 'clipboard'."); Dalamud.Chat.Print("Applying requires a name for the save to be applied or 'clipboard'.");
return; return;
} }
@ -278,7 +253,7 @@ namespace Glamourer
{ {
if (split.Length < 3) if (split.Length < 3)
{ {
PluginInterface.Framework.Gui.Chat.Print("Saving requires a name for the save."); Dalamud.Chat.Print("Saving requires a name for the save.");
return; return;
} }
@ -296,25 +271,24 @@ namespace Glamourer
PlayerWatcher?.Dispose(); PlayerWatcher?.Dispose();
UnregisterFunctions(); UnregisterFunctions();
_interface?.Dispose(); _interface?.Dispose();
PluginInterface.CommandManager.RemoveHandler("/glamour"); Dalamud.Commands.RemoveHandler("/glamour");
PluginInterface.CommandManager.RemoveHandler("/glamourer"); Dalamud.Commands.RemoveHandler("/glamourer");
PluginInterface.Dispose();
} }
// Update actors without triggering PlayerWatcher Events, // Update actors without triggering PlayerWatcher Events,
// then manually redraw using Penumbra. // then manually redraw using Penumbra.
public void UpdateActors(Actor actor, Actor? gPoseOriginalActor = null) public void UpdateActors(Character actor, Character? gPoseOriginalActor = null)
{ {
var newEquip = PlayerWatcher.UpdateActorWithoutEvent(actor); var newEquip = PlayerWatcher.UpdateActorWithoutEvent(actor);
Penumbra?.RedrawActor(actor, RedrawType.WithSettings); Penumbra?.RedrawObject(actor, RedrawType.WithSettings);
// Special case for carrying over changes to the gPose actor to the regular player actor, too. // Special case for carrying over changes to the gPose actor to the regular player actor, too.
if (gPoseOriginalActor != null) if (gPoseOriginalActor == null)
{ return;
newEquip.Write(gPoseOriginalActor.Address);
PlayerWatcher.UpdateActorWithoutEvent(gPoseOriginalActor); newEquip.Write(gPoseOriginalActor.Address);
Penumbra?.RedrawActor(gPoseOriginalActor, RedrawType.AfterGPoseWithSettings); PlayerWatcher.UpdateActorWithoutEvent(gPoseOriginalActor);
} Penumbra?.RedrawObject(gPoseOriginalActor, RedrawType.AfterGPoseWithSettings);
} }
} }
} }

View file

@ -4,11 +4,11 @@
"Name": "Glamourer", "Name": "Glamourer",
"Description": "Adds functionality to change appearance of actors. Requires Penumbra to be installed and activated to work.", "Description": "Adds functionality to change appearance of actors. Requires Penumbra to be installed and activated to work.",
"InternalName": "Glamourer", "InternalName": "Glamourer",
"AssemblyVersion": "0.0.3.0", "AssemblyVersion": "0.0.4.0",
"TestingAssemblyVersion": "0.0.3.0", "TestingAssemblyVersion": "0.0.4.0",
"RepoUrl": "https://github.com/Ottermandias/Glamourer", "RepoUrl": "https://github.com/Ottermandias/Glamourer",
"ApplicableVersion": "any", "ApplicableVersion": "any",
"DalamudApiLevel": 3, "DalamudApiLevel": 4,
"IsHide": "False", "IsHide": "False",
"IsTestingExclusive": "false", "IsTestingExclusive": "false",
"DownloadCount": 1, "DownloadCount": 1,