From 2273cb92c98e221ee372c48bc505d70f36ef0da3 Mon Sep 17 00:00:00 2001 From: Phenrei Date: Thu, 18 Aug 2022 23:12:12 -0400 Subject: [PATCH 1/5] Default scales without lag for all, cutscene, and retainers. Configs for use on NPCs. Fix for CC intro screen. --- .editorconfig | 18 ++- CustomizePlus/BodyScale.cs | 23 ++- CustomizePlus/Configuration.cs | 5 + .../Interface/ConfigurationInterface.cs | 32 ++++ CustomizePlus/Interface/EditInterface.cs | 8 +- CustomizePlus/Plugin.cs | 145 +++++++++++++++--- 6 files changed, 196 insertions(+), 35 deletions(-) diff --git a/.editorconfig b/.editorconfig index 7442d08..3fe5d45 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,7 +23,7 @@ dotnet_diagnostic.IDE0011.severity = none dotnet_diagnostic.IDE0022.severity = none dotnet_diagnostic.IDE0023.severity = none dotnet_diagnostic.IDE1006.severity = warning -dotnet_diagnostic.IDE0044.severity = warning +dotnet_diagnostic.IDE0044.severity = suggestion dotnet_diagnostic.IDE0058.severity = none dotnet_diagnostic.IDE0073.severity = warning dotnet_diagnostic.IDE0025.severity = none @@ -78,6 +78,10 @@ csharp_style_prefer_index_operator = true:suggestion csharp_style_prefer_range_operator = true:suggestion csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion csharp_style_prefer_tuple_swap = true:suggestion + +# SA1101: Prefix local calls with this +dotnet_diagnostic.SA1101.severity = silent + [*.{cs,vb}] dotnet_style_operator_placement_when_wrapping = beginning_of_line tab_width = 4 @@ -145,3 +149,15 @@ dotnet_naming_style.pascal_case.required_prefix = dotnet_naming_style.pascal_case.required_suffix = dotnet_naming_style.pascal_case.word_separator = dotnet_naming_style.pascal_case.capitalization = pascal_case + +# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.SpacingRules' +dotnet_analyzer_diagnostic.category-StyleCop.CSharp.SpacingRules.severity = silent + +# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.ReadabilityRules' +dotnet_analyzer_diagnostic.category-StyleCop.CSharp.ReadabilityRules.severity = silent + +# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.LayoutRules' +dotnet_analyzer_diagnostic.category-StyleCop.CSharp.LayoutRules.severity = silent + +# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.OrderingRules' +dotnet_analyzer_diagnostic.category-StyleCop.CSharp.OrderingRules.severity = silent diff --git a/CustomizePlus/BodyScale.cs b/CustomizePlus/BodyScale.cs index bd816f4..731f12e 100644 --- a/CustomizePlus/BodyScale.cs +++ b/CustomizePlus/BodyScale.cs @@ -22,11 +22,15 @@ public class BodyScale public HkVector4 RootScale { get; set; } = HkVector4.Zero; // This works fine on generic GameObject if previously checked for correct types. - public unsafe void Apply(GameObject character) + public unsafe void Apply(GameObject character, bool applyRootScale) { RenderObject* obj = null; obj = RenderObject.FromActor(character); - + if (obj == null) + { + //PluginLog.Debug($"{character.Address} missing skeleton!"); + return; + } for (int i = 0; i < obj->Skeleton->Length; i++) { if (!this.poses.ContainsKey(i)) @@ -39,9 +43,18 @@ public unsafe void Apply(GameObject character) if (this.RootScale.X != 0 && this.RootScale.Y != 0 && this.RootScale.Z != 0) { HkVector4 rootScale = obj->Scale; - rootScale.X = MathF.Max(this.RootScale.X, 0.01f); - rootScale.Y = MathF.Max(this.RootScale.Y, 0.01f); - rootScale.Z = MathF.Max(this.RootScale.Z, 0.01f); + if (applyRootScale) + { + rootScale.X = MathF.Max(this.RootScale.X, 0.01f); + rootScale.Y = MathF.Max(this.RootScale.Y, 0.01f); + rootScale.Z = MathF.Max(this.RootScale.Z, 0.01f); + } + else + { + rootScale.X = obj->Scale.X; + rootScale.Y = obj->Scale.Y; + rootScale.Z = obj->Scale.Z; + } obj->Scale = rootScale; } } diff --git a/CustomizePlus/Configuration.cs b/CustomizePlus/Configuration.cs index f1e1091..ba1a202 100644 --- a/CustomizePlus/Configuration.cs +++ b/CustomizePlus/Configuration.cs @@ -14,6 +14,11 @@ public class Configuration : IPluginConfiguration public List BodyScales { get; set; } = new(); public bool Enable { get; set; } = true; public bool AutomaticEditMode { get; set; } = false; + + public bool ApplyToNpcs { get; set; } = false; + public bool ApplyToNpcsInBusyAreas { get; set; } = false; + public bool ApplyToNpcsInCutscenes { get; set; } = false; + // Upcoming feature /* diff --git a/CustomizePlus/Interface/ConfigurationInterface.cs b/CustomizePlus/Interface/ConfigurationInterface.cs index 2f5faae..0e47db3 100644 --- a/CustomizePlus/Interface/ConfigurationInterface.cs +++ b/CustomizePlus/Interface/ConfigurationInterface.cs @@ -68,6 +68,38 @@ protected override void DrawContents() if (ImGui.IsItemHovered()) ImGui.SetTooltip($"Applies changes automatically without saving."); + ImGui.SameLine(); + + bool applyToNpcs = config.ApplyToNpcs; + if (ImGui.Checkbox("Apply to NPCS", ref applyToNpcs)) + { + config.ApplyToNpcs = applyToNpcs; + } + + if (ImGui.IsItemHovered()) + ImGui.SetTooltip($"Applies to NPCS (overrides next settings)."); + + ImGui.SameLine(); + + bool applyToNpcsInBusyAreas = config.ApplyToNpcsInBusyAreas; + if (ImGui.Checkbox("Apply to NPCS in Busy Areas", ref applyToNpcsInBusyAreas)) + { + config.ApplyToNpcsInBusyAreas = applyToNpcsInBusyAreas; + } + + if (ImGui.IsItemHovered()) + ImGui.SetTooltip($"Applies to NPCs in busy areas (when NPCs are in index > 200, which occurs when up to 100 characters are rendered."); + + ImGui.SameLine(); + + bool applyToNpcsInCutscenes = config.ApplyToNpcsInCutscenes; + if (ImGui.Checkbox("Apply to NPCs in Cutscenes", ref applyToNpcsInCutscenes)) + { + config.ApplyToNpcsInCutscenes = applyToNpcsInCutscenes; + } + + if (ImGui.IsItemHovered()) + ImGui.SetTooltip($"Applies to NPCs in busy areas (when NPCs are in index > 200, which occurs when up to 100 characters are rendered."); ImGui.SameLine(); diff --git a/CustomizePlus/Interface/EditInterface.cs b/CustomizePlus/Interface/EditInterface.cs index 4e7cc13..8bb119f 100644 --- a/CustomizePlus/Interface/EditInterface.cs +++ b/CustomizePlus/Interface/EditInterface.cs @@ -39,8 +39,8 @@ public class EditInterface : WindowBase private BodyScale? scaleStart; private Dictionary? boneValuesOriginal = new Dictionary(); private Dictionary? boneValuesNew = new Dictionary(); - private List boneNamesLegacy = LegacyBoneNameConverter.GetLegacyNames(); - private List boneNamesModern = LegacyBoneNameConverter.GetModernNames(); + private readonly List boneNamesLegacy = LegacyBoneNameConverter.GetLegacyNames(); + private readonly List boneNamesModern = LegacyBoneNameConverter.GetModernNames(); private List boneNamesModernUsed = new List(); private List boneNamesLegacyUsed = new List(); private bool scaleEnabled = false; @@ -142,7 +142,7 @@ protected override void DrawContents() Vector4 rootScaleLocalTemp = new Vector4((float)rootScaleLocal.X, (float)rootScaleLocal.Y, (float)rootScaleLocal.Z, (float)rootScaleLocal.W); - if (ImGui.DragFloat4("Root", ref rootScaleLocalTemp, 0.1f, 0f, 10f)) + if (ImGui.DragFloat4("Root", ref rootScaleLocalTemp, 0.001f, 0f, 10f)) { if (this.reset) { @@ -185,7 +185,7 @@ protected override void DrawContents() ImGui.BeginChild("scrolling", new Vector2(0, ImGui.GetFrameHeightWithSpacing() - 56), false); - for (int i = 0; i < this.boneValuesNew.Count; i++) + for (int i = 0; i < boneValuesNew.Count; i++) { string boneNameLocalLegacy = this.boneNamesLegacyUsed[i]; diff --git a/CustomizePlus/Plugin.cs b/CustomizePlus/Plugin.cs index d8afacd..5ac7cc5 100644 --- a/CustomizePlus/Plugin.cs +++ b/CustomizePlus/Plugin.cs @@ -30,7 +30,11 @@ namespace CustomizePlus public sealed class Plugin : IDalamudPlugin { private static readonly Dictionary NameToScale = new(); + private static Dictionary scaleByObject = new(); private static Hook? renderManagerHook; + private static BodyScale? defaultScale; + private static BodyScale? defaultRetainerScale; + private static BodyScale? defaultCutsceneScale; public Plugin() { @@ -66,6 +70,8 @@ public Plugin() [PluginService] [RequiredVersion("1.0")] public static SigScanner SigScanner { get; private set; } = null!; [PluginService] [RequiredVersion("1.0")] public static GameGui GameGui { get; private set; } = null!; + [PluginService][RequiredVersion("1.0")] public static TargetManager TargetManager { get; private set; } = null!; + public static InterfaceManager InterfaceManager { get; private set; } = new InterfaceManager(); public static Configuration Configuration { get; private set; } = null!; @@ -78,10 +84,28 @@ public static void LoadConfig() { NameToScale.Clear(); + defaultScale = null; + foreach (BodyScale bodyScale in Configuration.BodyScales) { bodyScale.ClearCache(); + if (bodyScale.CharacterName == "Default" && bodyScale.BodyScaleEnabled) + { + defaultScale = bodyScale; + PluginLog.Debug($"Default scale with name {defaultScale.ScaleName} being used."); + continue; + } else if (bodyScale.CharacterName == "DefaultRetainer" && bodyScale.BodyScaleEnabled) + { + defaultRetainerScale = bodyScale; + PluginLog.Debug($"Default retainer scale with name {defaultRetainerScale.ScaleName} being used."); + } + else if (bodyScale.CharacterName == "DefaultCutscene" && bodyScale.BodyScaleEnabled) + { + defaultCutsceneScale = bodyScale; + PluginLog.Debug($"Default cutscene scale with name {defaultCutsceneScale.ScaleName} being used."); + } + if (NameToScale.ContainsKey(bodyScale.CharacterName)) continue; @@ -97,7 +121,8 @@ public static void LoadConfig() { // "Render::Manager::Render" IntPtr renderAddress = SigScanner.ScanText("E8 ?? ?? ?? ?? 48 81 C3 ?? ?? ?? ?? BE ?? ?? ?? ?? 45 33 F6"); - renderManagerHook = new Hook(renderAddress, OnRender); + //renderManagerHook = new Hook(renderAddress, OnRender); + renderManagerHook = Hook.FromAddress(renderAddress, OnRender); } renderManagerHook.Enable(); @@ -125,28 +150,88 @@ public static unsafe void Update() { for (var i = 0; i < ObjectTable.Length; i++) { + /* + if (i == 407) + { + var obj2 = ObjectTable[i]; + if (obj2 == null) + continue; + //ObjectStruct* obj3 = (ObjectStruct*)ObjectTable[i]; + //PluginLog.Information(obj3.IsValid().ToString()); + //Character player = (Character)ObjectTable[0]; + TargetManager.SetTarget(obj2); + + }*/ + if (i == 245) //Always filler Event obj + continue; + var obj = ObjectTable[i]; + //try + //{ + // (Character)obj.Name + //} + //if (TryGetValue()) BodyScale? scale = null; scale = IdentifyBodyScale((ObjectStruct*)ObjectTable.GetObjectAddress(i)); - - if (scale == null || obj == null) + + if (obj == null)// || scale == null) { continue; } - + try { switch (obj.ObjectKind) { case ObjectKind.Player: - case ObjectKind.EventNpc: + case ObjectKind.Companion: + if (scale == null && defaultScale != null) + { + scale = defaultScale; + } + else if (scale == null) { continue; } + //Apply(obj, scale); + scale.Apply(obj, true); + continue; case ObjectKind.Retainer: + if (scale == null && defaultRetainerScale != null) + { + scale = defaultRetainerScale; + } + else if (scale == null && defaultScale != null) + { + scale = defaultScale; + } + else if (scale == null) { continue; } + //Apply(obj, scale); + scale.Apply(obj, true); + continue; + case ObjectKind.EventNpc: case ObjectKind.BattleNpc: - case ObjectKind.Cutscene: - case ObjectKind.Companion: - case ObjectKind.EventObj: - Apply(obj, scale); + //case ObjectKind.Cutscene: + //case ObjectKind.EventObj: + bool finalApplyToNpcs = Configuration.ApplyToNpcs && (Configuration.ApplyToNpcsInBusyAreas && i >= 245); + bool finalApplyToNpcsCutscene = Configuration.ApplyToNpcsInCutscenes && ObjectTable[201] != null; + if (finalApplyToNpcs && scale == null && defaultScale != null && ObjectTable[201] == null) + { + scale = defaultScale; + } + else if (finalApplyToNpcsCutscene && scale == null && defaultCutsceneScale != null) + { + scale = defaultCutsceneScale; + } + else if (!Configuration.ApplyToNpcs || scale == null) + { + continue; + } + //Apply(obj, scale); + scale.Apply(obj, false); continue; + + /*if (scale == null) + continue; + scale.Apply(obj, false); + continue;*/ default: continue; } @@ -186,12 +271,11 @@ private static void Apply(GameObject character, BodyScale scale) { try { - if (character != null && scale != null) - scale.Apply(character); + scale.Apply(character, true); } catch (Exception ex) { - PluginLog.Debug($"Error in applying: {ex}"); + PluginLog.Debug($"Error in applying scale: {scale.ScaleName} to character {character.ObjectKind}: {ex}"); } } @@ -238,22 +322,33 @@ private static IntPtr OnRender(IntPtr a1, int a2, IntPtr a3, byte a4, IntPtr a5, } else { - actorName = new Utf8String(gameObject->Name).ToString(); - + //actorName = new Utf8String(gameObject->Name).ToString(); + string? actualName = null; // All these special cases are relevant for an empty name, so never collide with the above setting. // Only OwnerName can be applied to something with a non-empty name, and that is the specific case we want to handle. - var actualName = gameObject->ObjectIndex switch - { - 240 => GetPlayerName(), // character window - 241 => GetInspectName() ?? GetGlamourName(), // GetCardName() ?? // inspect, character card, glamour plate editor. - Card removed due to logic issues - 242 => GetPlayerName(), // try-on - 243 => GetPlayerName(), // dye preview - 244 => GetPlayerName(), // portrait preview - >= 200 => GetCutsceneName(gameObject), - _ => null, + if (GameGui.GetAddonByName("PvPMKSIntroduction", 1) == IntPtr.Zero) { + actualName = gameObject->ObjectIndex switch + { + 240 => GetPlayerName(), // character window + 241 => GetInspectName() ?? GetGlamourName(), // GetCardName() ?? // inspect, character card, glamour plate editor. - Card removed due to logic issues + 242 => GetPlayerName(), // try-on + 243 => GetPlayerName(), // dye preview + 244 => GetPlayerName(), // portrait preview + >= 200 => GetCutsceneName(gameObject), + _ => null, + } ?? new Utf8String(gameObject->Name).ToString(); + } else + { + actualName = gameObject->ObjectIndex switch + { + 240 => GetPlayerName(), // character window + _ => null, + } ?? new Utf8String(gameObject->Name).ToString(); } - - ?? actorName ?? new Utf8String(gameObject->Name).ToString(); + //TODO: Ensure player side only (first group, one of the node textures is blue. Alternately, look for hidden party list UI and get names from there. + //else if (((AtkUnitBase*)GameGui.GetAddonByName("PvPMKSIntroduction", 1))->UldManager.NodeList[]) + //?? + //actorName ?? new Utf8String(gameObject->Name).ToString(); if (actualName == null) { From d63e897fd3ba6b51465008367c05251c6edf50a2 Mon Sep 17 00:00:00 2001 From: Phenrei Date: Wed, 24 Aug 2022 20:58:57 -0400 Subject: [PATCH 2/5] 6.2 support: API7 and .net6; Additional UI improvements; Mess cleanup --- CustomizePlus/Configuration.cs | 2 +- CustomizePlus/CustomizePlus.csproj | 242 +----------------- CustomizePlus/DalamudPackager.targets | 10 + .../Interface/ConfigurationInterface.cs | 27 +- CustomizePlus/Interface/EditInterface.cs | 55 +++- CustomizePlus/Plugin.cs | 127 +++++---- repo.json | 12 +- 7 files changed, 149 insertions(+), 326 deletions(-) create mode 100644 CustomizePlus/DalamudPackager.targets diff --git a/CustomizePlus/Configuration.cs b/CustomizePlus/Configuration.cs index ba1a202..307a391 100644 --- a/CustomizePlus/Configuration.cs +++ b/CustomizePlus/Configuration.cs @@ -16,7 +16,7 @@ public class Configuration : IPluginConfiguration public bool AutomaticEditMode { get; set; } = false; public bool ApplyToNpcs { get; set; } = false; - public bool ApplyToNpcsInBusyAreas { get; set; } = false; + // public bool ApplyToNpcsInBusyAreas { get; set; } = false; public bool ApplyToNpcsInCutscenes { get; set; } = false; diff --git a/CustomizePlus/CustomizePlus.csproj b/CustomizePlus/CustomizePlus.csproj index 5733d20..acf52dc 100644 --- a/CustomizePlus/CustomizePlus.csproj +++ b/CustomizePlus/CustomizePlus.csproj @@ -3,7 +3,7 @@ - 0.0.0.7 + 0.0.1.80 CustomizePlus https://github.com/XIV-Tools/CustomizePlus @@ -11,7 +11,7 @@ - net5.0-windows + net6.0-windows x64 enable latest @@ -34,58 +34,11 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive - - ..\..\..\Dalamud\bin\Debug\CheapLoc.dll - - - ..\..\..\Dalamud\bin\Debug\Costura.dll - - - ..\..\..\Dalamud\bin\Debug\Dalamud.Injector.dll - - - ..\..\..\Dalamud\bin\Debug\FFXIVClientStructs.dll - - - ..\..\..\Dalamud\bin\Debug\Iced.dll - - - ..\..\..\Dalamud\bin\Debug\JetBrains.Annotations.dll - - - ..\..\..\Dalamud\bin\Debug\Microsoft.Bcl.HashCode.dll - - - ..\..\..\Dalamud\bin\Debug\Microsoft.DotNet.PlatformAbstractions.dll - - - ..\..\..\Dalamud\bin\Debug\Microsoft.Extensions.DependencyModel.dll - - - ..\..\..\Dalamud\bin\Debug\MinSharp.dll - - - ..\..\..\Dalamud\bin\Debug\Mono.Cecil.dll - - - ..\..\..\Dalamud\bin\Debug\Mono.Cecil.Mdb.dll - - - ..\..\..\Dalamud\bin\Debug\Mono.Cecil.Pdb.dll - - - ..\..\..\Dalamud\bin\Debug\Mono.Cecil.Rocks.dll - - - ..\..\..\Dalamud\bin\Debug\MonoMod.RuntimeDetour.dll - - - ..\..\..\Dalamud\bin\Debug\MonoMod.Utils.dll - $(DalamudLibPath)Newtonsoft.Json.dll false @@ -110,186 +63,17 @@ $(DalamudLibPath)Lumina.Excel.dll false - - ..\..\..\Dalamud\bin\Debug\PeNet.dll - - - ..\..\..\Dalamud\bin\Debug\PeNet.Asn1.dll - - - ..\..\..\Penumbra\Penumbra.GameData\bin\Debug\net5.0-windows\Penumbra.GameData.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.AdvApi32.dll + + $(DalamudLibPath)FFXIVClientStructs.dll + false + + + ..\..\..\Penumbra\Penumbra\bin\Debug\Penumbra.dll + false + + + ..\..\..\Penumbra\Penumbra\bin\Debug\Penumbra.GameData.dll - - ..\..\..\Dalamud\bin\Debug\PInvoke.BCrypt.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Cabinet.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.CfgMgr32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Crypt32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.DbgHelp.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.DwmApi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Gdi32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Hid.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.ImageHlp.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.IPHlpApi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Kernel32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Magnification.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Msi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.NCrypt.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.NetApi32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.NewDev.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.NTDll.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Ole32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Psapi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.SetupApi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.SHCore.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Shell32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.User32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Userenv.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.UxTheme.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Windows.Core.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Windows.ShellScalingApi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.WinUsb.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.WtsApi32.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Assembler.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Hooks.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Hooks.Definitions.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Memory.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Memory.Buffers.dll - - - ..\..\..\Dalamud\bin\Debug\SDL2-CS.dll - - - ..\..\..\Dalamud\bin\Debug\Serilog.dll - - - ..\..\..\Dalamud\bin\Debug\Serilog.Sinks.Async.dll - - - ..\..\..\Dalamud\bin\Debug\Serilog.Sinks.Console.dll - - - ..\..\..\Dalamud\bin\Debug\Serilog.Sinks.File.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDisasm.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDX.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDX.Direct3D11.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDX.DXGI.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDX.Mathematics.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Core.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.GLFW.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Maths.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.OpenGL.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.SDL.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Windowing.Common.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Windowing.Glfw.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Windowing.Sdl.dll - - - ..\..\..\Dalamud\bin\Debug\StbiSharp.dll - - - ..\..\..\Dalamud\bin\Debug\System.Reflection.MetadataLoadContext.dll - - - ..\..\..\Dalamud\bin\Debug\System.Security.Cryptography.Pkcs.dll - - - ..\..\..\Dalamud\bin\Debug\Validation.dll - diff --git a/CustomizePlus/DalamudPackager.targets b/CustomizePlus/DalamudPackager.targets new file mode 100644 index 0000000..789e0da --- /dev/null +++ b/CustomizePlus/DalamudPackager.targets @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/CustomizePlus/Interface/ConfigurationInterface.cs b/CustomizePlus/Interface/ConfigurationInterface.cs index 0e47db3..2f8da5d 100644 --- a/CustomizePlus/Interface/ConfigurationInterface.cs +++ b/CustomizePlus/Interface/ConfigurationInterface.cs @@ -52,6 +52,11 @@ protected override void DrawContents() if (ImGui.Checkbox("Enable", ref enable)) { config.Enable = enable; + if (config.AutomaticEditMode) + { + config.Save(); + Plugin.LoadConfig(); + } } if (ImGui.IsItemHovered()) @@ -77,10 +82,11 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Applies to NPCS (overrides next settings)."); + ImGui.SetTooltip($"Apply scales to NPCs.\nSpecify a scale with the name 'Default' for it to apply to all NPCs and non-specified players."); ImGui.SameLine(); - + /* + * May not be needed, was intended for possible FPS fixes bool applyToNpcsInBusyAreas = config.ApplyToNpcsInBusyAreas; if (ImGui.Checkbox("Apply to NPCS in Busy Areas", ref applyToNpcsInBusyAreas)) { @@ -91,7 +97,7 @@ protected override void DrawContents() ImGui.SetTooltip($"Applies to NPCs in busy areas (when NPCs are in index > 200, which occurs when up to 100 characters are rendered."); ImGui.SameLine(); - + */ bool applyToNpcsInCutscenes = config.ApplyToNpcsInCutscenes; if (ImGui.Checkbox("Apply to NPCs in Cutscenes", ref applyToNpcsInCutscenes)) { @@ -99,7 +105,10 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Applies to NPCs in busy areas (when NPCs are in index > 200, which occurs when up to 100 characters are rendered."); + ImGui.SetTooltip($"Apply scales to NPCs in cutscenes.\nSpecify a scale with the name 'CutsceneDefault' to apply it to all generic characters."); + + ImGui.Separator(); + ImGui.Text("Characters:"); ImGui.SameLine(); @@ -108,7 +117,6 @@ protected override void DrawContents() ImGui.Text("Character Name:"); ImGui.InputText(string.Empty, ref this.newScaleCharacter, 1024); - if (ImGui.Button("OK")) { string characterName = this.newScaleCharacter; @@ -141,9 +149,6 @@ protected override void DrawContents() if (ImGui.IsItemHovered()) ImGui.SetTooltip("Add a character"); - ImGui.Separator(); - ImGui.Text("Characters:"); - ImGui.BeginChild("scrolling", new Vector2(0, ImGui.GetFrameHeightWithSpacing() - 56), false); for (int i = 0; i < config.BodyScales.Count; i++) @@ -189,7 +194,7 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Enable and disable scale"); + ImGui.SetTooltip($"Enable and disable scale.\nWill disable all other scales for the same character."); ImGui.SameLine(); if (ImGuiComponents.IconButton(FontAwesomeIcon.Pen)) @@ -199,7 +204,7 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Edit body scale"); + ImGui.SetTooltip($"Edit body scale (WIP)"); ImGui.SameLine(); if (ImGuiComponents.IconButton(FontAwesomeIcon.FileImport)) @@ -429,7 +434,7 @@ private BodyScale BuildFromJSON(BodyScale scale, string json) return scale; } - private readonly string defaultFile = @"{""FileExtension"": "".pose"", ""TypeName"": ""Default"", ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 0"", ""Scale"": ""1, 1, 1"", ""Bones"": { + private readonly string defaultFile = @"{""FileExtension"": "".pose"", ""TypeName"": ""Default"", ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 0"", ""Scale"": ""0, 0, 0"", ""Bones"": { ""Root"": { ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 1"", ""Scale"": ""1, 1, 1""}, ""Abdomen"": { ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 1"", ""Scale"": ""1, 1, 1"" }, ""Throw"": { ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 1"", ""Scale"": ""1, 1, 1"" }, diff --git a/CustomizePlus/Interface/EditInterface.cs b/CustomizePlus/Interface/EditInterface.cs index 8bb119f..ee9e3d0 100644 --- a/CustomizePlus/Interface/EditInterface.cs +++ b/CustomizePlus/Interface/EditInterface.cs @@ -22,7 +22,7 @@ public class EditInterface : WindowBase { protected BodyScale? Scale { get; private set; } - protected override string Title => $"Edit Scale: {this.originalScaleName}"; + protected override string Title => $"(WIP) Edit Scale: {this.originalScaleName}"; protected BodyScale? ScaleUpdated { get; private set; } private int scaleIndex = -1; @@ -33,7 +33,7 @@ public class EditInterface : WindowBase private string originalScaleCharacter = string.Empty; private HkVector4 originalScaleValue = HkVector4.One; private Vector4 newScaleValue = HkVector4.One.GetAsNumericsVector(); - private Vector4 originalRootScale = new Vector4(1f,1f,1f,0f); + private Vector4 originalRootScale = new Vector4(1f, 1f, 1f, 0f); private Vector4 newRootScale = HkVector4.One.GetAsNumericsVector(); private BodyScale? scaleStart; @@ -65,10 +65,10 @@ public void Show(BodyScale scale) editWnd.scaleEnabled = scale.BodyScaleEnabled; - for (int i=0; i 245 && !Configuration.ApplyToNpcsInBusyAreas) + // continue; + + // Don't affect the cutscene object range, by configuration + if (i >= 202 && i < 240 && !Configuration.ApplyToNpcsInCutscenes) continue; var obj = ObjectTable[i]; - //try - //{ - // (Character)obj.Name - //} - //if (TryGetValue()) + BodyScale? scale = null; scale = IdentifyBodyScale((ObjectStruct*)ObjectTable.GetObjectAddress(i)); - if (obj == null)// || scale == null) + if (obj == null) { continue; } @@ -190,7 +182,6 @@ public static unsafe void Update() scale = defaultScale; } else if (scale == null) { continue; } - //Apply(obj, scale); scale.Apply(obj, true); continue; case ObjectKind.Retainer: @@ -203,35 +194,28 @@ public static unsafe void Update() scale = defaultScale; } else if (scale == null) { continue; } - //Apply(obj, scale); scale.Apply(obj, true); continue; case ObjectKind.EventNpc: case ObjectKind.BattleNpc: - //case ObjectKind.Cutscene: - //case ObjectKind.EventObj: - bool finalApplyToNpcs = Configuration.ApplyToNpcs && (Configuration.ApplyToNpcsInBusyAreas && i >= 245); - bool finalApplyToNpcsCutscene = Configuration.ApplyToNpcsInCutscenes && ObjectTable[201] != null; - if (finalApplyToNpcs && scale == null && defaultScale != null && ObjectTable[201] == null) + // case ObjectKind.Cutscene: + // case ObjectKind.EventObj: + if (scale == null && defaultScale != null && (i < 201 || i > 246)) { scale = defaultScale; } - else if (finalApplyToNpcsCutscene && scale == null && defaultCutsceneScale != null) + else if (scale == null && defaultCutsceneScale != null && (i > 200 || i < 245)) { scale = defaultCutsceneScale; } - else if (!Configuration.ApplyToNpcs || scale == null) + if (!Configuration.ApplyToNpcs || scale == null) { continue; } - //Apply(obj, scale); + scale.Apply(obj, false); continue; - /*if (scale == null) - continue; - scale.Apply(obj, false); - continue;*/ default: continue; } @@ -300,7 +284,7 @@ private static IntPtr OnRender(IntPtr a1, int a2, IntPtr a3, byte a4, IntPtr a5, return original(a1, a2, a3, a4, a5, a6); } - // All functions related to this process for non-named objects adapted from Penumbra logic. + // All functions related to this process for non-named objects adapted from Penumbra logic. Credit to Ottermandias et al. private static unsafe BodyScale? IdentifyBodyScale(ObjectStruct* gameObject) { if (gameObject == null) @@ -322,40 +306,47 @@ private static IntPtr OnRender(IntPtr a1, int a2, IntPtr a3, byte a4, IntPtr a5, } else { - //actorName = new Utf8String(gameObject->Name).ToString(); - string? actualName = null; - // All these special cases are relevant for an empty name, so never collide with the above setting. - // Only OwnerName can be applied to something with a non-empty name, and that is the specific case we want to handle. - if (GameGui.GetAddonByName("PvPMKSIntroduction", 1) == IntPtr.Zero) { - actualName = gameObject->ObjectIndex switch - { - 240 => GetPlayerName(), // character window - 241 => GetInspectName() ?? GetGlamourName(), // GetCardName() ?? // inspect, character card, glamour plate editor. - Card removed due to logic issues - 242 => GetPlayerName(), // try-on - 243 => GetPlayerName(), // dye preview - 244 => GetPlayerName(), // portrait preview - >= 200 => GetCutsceneName(gameObject), - _ => null, - } ?? new Utf8String(gameObject->Name).ToString(); - } else - { - actualName = gameObject->ObjectIndex switch - { - 240 => GetPlayerName(), // character window - _ => null, - } ?? new Utf8String(gameObject->Name).ToString(); - } - //TODO: Ensure player side only (first group, one of the node textures is blue. Alternately, look for hidden party list UI and get names from there. - //else if (((AtkUnitBase*)GameGui.GetAddonByName("PvPMKSIntroduction", 1))->UldManager.NodeList[]) - //?? - //actorName ?? new Utf8String(gameObject->Name).ToString(); + actorName = new Utf8String(gameObject->Name).ToString(); - if (actualName == null) + if (actorName != null) { - return null; + NameToScale.TryGetValue(actorName, out scale); } + else + { + string? actualName = null; + + // Check if in pvp intro sequence, which uses 240-244 for the 5 players, and only affect the first if so + // TODO: Ensure player side only. First group, where one of the node textures is blue. Alternately, look for hidden party list UI and get names from there. + if (GameGui.GetAddonByName("PvPMKSIntroduction", 1) == IntPtr.Zero) + { + actualName = gameObject->ObjectIndex switch + { + 240 => GetPlayerName(), // character window + 241 => GetInspectName() ?? GetGlamourName(), // GetCardName() ?? // inspect, character card, glamour plate editor. - Card removed due to logic issues + 242 => GetPlayerName(), // try-on + 243 => GetPlayerName(), // dye preview + 244 => GetPlayerName(), // portrait preview + >= 200 => GetCutsceneName(gameObject), + _ => null, + } ?? new Utf8String(gameObject->Name).ToString(); + } + else + { + actualName = gameObject->ObjectIndex switch + { + 240 => GetPlayerName(), // character window + _ => null, + } ?? new Utf8String(gameObject->Name).ToString(); + } + + if (actualName == null) + { + return null; + } - NameToScale.TryGetValue(actualName, out scale); + NameToScale.TryGetValue(actualName, out scale); + } } } catch (Exception e) diff --git a/repo.json b/repo.json index 9206044..55e016f 100644 --- a/repo.json +++ b/repo.json @@ -4,19 +4,19 @@ "Name": "Customize+", "Description": "A plugin that allows you to create and apply Anamnesis-style body scaling full time.", "InternalName": "CustomizePlus", - "AssemblyVersion": "0.0.0.7", - "TestingAssemblyVersion": "0.0.0.7", + "AssemblyVersion": "0.0.1.0", + "TestingAssemblyVersion": "0.0.1.0", "RepoUrl": "https://github.com/XIV-Tools/CustomizePlus", "ApplicableVersion": "any", - "DalamudApiLevel": 6, + "DalamudApiLevel": 7, "IsHide": "False", "IsTestingExclusive": "False", "DownloadCount": 0, "LastUpdate": 0, "LoadPriority": 0, - "DownloadLinkInstall": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.0.7/CustomizePlus.zip", - "DownloadLinkTesting": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.0.7/CustomizePlus.zip", - "DownloadLinkUpdate": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.0.7/CustomizePlus.zip", + "DownloadLinkInstall": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.1.0/CustomizePlus.zip", + "DownloadLinkTesting": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.1.0/CustomizePlus.zip", + "DownloadLinkUpdate": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.1.0/CustomizePlus.zip", "IconUrl": "https://raw.githubusercontent.com/XIV-Tools/CustomizePlus/main/Data/icon.png" } ] From 10d38578cb81e9d4808b7258b593eced3e7e426c Mon Sep 17 00:00:00 2001 From: Phenrei Date: Wed, 24 Aug 2022 21:00:32 -0400 Subject: [PATCH 3/5] Typo: Version number fix --- CustomizePlus/CustomizePlus.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CustomizePlus/CustomizePlus.csproj b/CustomizePlus/CustomizePlus.csproj index acf52dc..619eefc 100644 --- a/CustomizePlus/CustomizePlus.csproj +++ b/CustomizePlus/CustomizePlus.csproj @@ -3,7 +3,7 @@ - 0.0.1.80 + 0.0.1.0 CustomizePlus https://github.com/XIV-Tools/CustomizePlus From 6c35f35e369f51d25e16b78ba08742ac9575b17f Mon Sep 17 00:00:00 2001 From: Phenrei Date: Wed, 24 Aug 2022 21:05:52 -0400 Subject: [PATCH 4/5] 6.2 support: API7 and .net6; Additional UI improvements; Mess cleanup --- CustomizePlus/Configuration.cs | 2 +- CustomizePlus/CustomizePlus.csproj | 242 +----------------- CustomizePlus/DalamudPackager.targets | 10 + .../Interface/ConfigurationInterface.cs | 25 +- CustomizePlus/Interface/EditInterface.cs | 55 +++- CustomizePlus/Plugin.cs | 127 +++++---- repo.json | 12 +- 7 files changed, 149 insertions(+), 324 deletions(-) create mode 100644 CustomizePlus/DalamudPackager.targets diff --git a/CustomizePlus/Configuration.cs b/CustomizePlus/Configuration.cs index ba1a202..307a391 100644 --- a/CustomizePlus/Configuration.cs +++ b/CustomizePlus/Configuration.cs @@ -16,7 +16,7 @@ public class Configuration : IPluginConfiguration public bool AutomaticEditMode { get; set; } = false; public bool ApplyToNpcs { get; set; } = false; - public bool ApplyToNpcsInBusyAreas { get; set; } = false; + // public bool ApplyToNpcsInBusyAreas { get; set; } = false; public bool ApplyToNpcsInCutscenes { get; set; } = false; diff --git a/CustomizePlus/CustomizePlus.csproj b/CustomizePlus/CustomizePlus.csproj index 5733d20..619eefc 100644 --- a/CustomizePlus/CustomizePlus.csproj +++ b/CustomizePlus/CustomizePlus.csproj @@ -3,7 +3,7 @@ - 0.0.0.7 + 0.0.1.0 CustomizePlus https://github.com/XIV-Tools/CustomizePlus @@ -11,7 +11,7 @@ - net5.0-windows + net6.0-windows x64 enable latest @@ -34,58 +34,11 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive - - ..\..\..\Dalamud\bin\Debug\CheapLoc.dll - - - ..\..\..\Dalamud\bin\Debug\Costura.dll - - - ..\..\..\Dalamud\bin\Debug\Dalamud.Injector.dll - - - ..\..\..\Dalamud\bin\Debug\FFXIVClientStructs.dll - - - ..\..\..\Dalamud\bin\Debug\Iced.dll - - - ..\..\..\Dalamud\bin\Debug\JetBrains.Annotations.dll - - - ..\..\..\Dalamud\bin\Debug\Microsoft.Bcl.HashCode.dll - - - ..\..\..\Dalamud\bin\Debug\Microsoft.DotNet.PlatformAbstractions.dll - - - ..\..\..\Dalamud\bin\Debug\Microsoft.Extensions.DependencyModel.dll - - - ..\..\..\Dalamud\bin\Debug\MinSharp.dll - - - ..\..\..\Dalamud\bin\Debug\Mono.Cecil.dll - - - ..\..\..\Dalamud\bin\Debug\Mono.Cecil.Mdb.dll - - - ..\..\..\Dalamud\bin\Debug\Mono.Cecil.Pdb.dll - - - ..\..\..\Dalamud\bin\Debug\Mono.Cecil.Rocks.dll - - - ..\..\..\Dalamud\bin\Debug\MonoMod.RuntimeDetour.dll - - - ..\..\..\Dalamud\bin\Debug\MonoMod.Utils.dll - $(DalamudLibPath)Newtonsoft.Json.dll false @@ -110,186 +63,17 @@ $(DalamudLibPath)Lumina.Excel.dll false - - ..\..\..\Dalamud\bin\Debug\PeNet.dll - - - ..\..\..\Dalamud\bin\Debug\PeNet.Asn1.dll - - - ..\..\..\Penumbra\Penumbra.GameData\bin\Debug\net5.0-windows\Penumbra.GameData.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.AdvApi32.dll + + $(DalamudLibPath)FFXIVClientStructs.dll + false + + + ..\..\..\Penumbra\Penumbra\bin\Debug\Penumbra.dll + false + + + ..\..\..\Penumbra\Penumbra\bin\Debug\Penumbra.GameData.dll - - ..\..\..\Dalamud\bin\Debug\PInvoke.BCrypt.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Cabinet.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.CfgMgr32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Crypt32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.DbgHelp.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.DwmApi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Gdi32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Hid.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.ImageHlp.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.IPHlpApi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Kernel32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Magnification.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Msi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.NCrypt.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.NetApi32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.NewDev.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.NTDll.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Ole32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Psapi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.SetupApi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.SHCore.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Shell32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.User32.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Userenv.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.UxTheme.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Windows.Core.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.Windows.ShellScalingApi.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.WinUsb.dll - - - ..\..\..\Dalamud\bin\Debug\PInvoke.WtsApi32.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Assembler.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Hooks.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Hooks.Definitions.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Memory.dll - - - ..\..\..\Dalamud\bin\Debug\Reloaded.Memory.Buffers.dll - - - ..\..\..\Dalamud\bin\Debug\SDL2-CS.dll - - - ..\..\..\Dalamud\bin\Debug\Serilog.dll - - - ..\..\..\Dalamud\bin\Debug\Serilog.Sinks.Async.dll - - - ..\..\..\Dalamud\bin\Debug\Serilog.Sinks.Console.dll - - - ..\..\..\Dalamud\bin\Debug\Serilog.Sinks.File.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDisasm.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDX.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDX.Direct3D11.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDX.DXGI.dll - - - ..\..\..\Dalamud\bin\Debug\SharpDX.Mathematics.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Core.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.GLFW.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Maths.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.OpenGL.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.SDL.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Windowing.Common.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Windowing.Glfw.dll - - - ..\..\..\Dalamud\bin\Debug\Silk.NET.Windowing.Sdl.dll - - - ..\..\..\Dalamud\bin\Debug\StbiSharp.dll - - - ..\..\..\Dalamud\bin\Debug\System.Reflection.MetadataLoadContext.dll - - - ..\..\..\Dalamud\bin\Debug\System.Security.Cryptography.Pkcs.dll - - - ..\..\..\Dalamud\bin\Debug\Validation.dll - diff --git a/CustomizePlus/DalamudPackager.targets b/CustomizePlus/DalamudPackager.targets new file mode 100644 index 0000000..789e0da --- /dev/null +++ b/CustomizePlus/DalamudPackager.targets @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/CustomizePlus/Interface/ConfigurationInterface.cs b/CustomizePlus/Interface/ConfigurationInterface.cs index 0e47db3..9103bad 100644 --- a/CustomizePlus/Interface/ConfigurationInterface.cs +++ b/CustomizePlus/Interface/ConfigurationInterface.cs @@ -52,6 +52,11 @@ protected override void DrawContents() if (ImGui.Checkbox("Enable", ref enable)) { config.Enable = enable; + if (config.AutomaticEditMode) + { + config.Save(); + Plugin.LoadConfig(); + } } if (ImGui.IsItemHovered()) @@ -77,10 +82,11 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Applies to NPCS (overrides next settings)."); + ImGui.SetTooltip($"Apply scales to NPCs.\nSpecify a scale with the name 'Default' for it to apply to all NPCs and non-specified players."); ImGui.SameLine(); - + /* + * May not be needed, was intended for possible FPS fixes bool applyToNpcsInBusyAreas = config.ApplyToNpcsInBusyAreas; if (ImGui.Checkbox("Apply to NPCS in Busy Areas", ref applyToNpcsInBusyAreas)) { @@ -91,7 +97,7 @@ protected override void DrawContents() ImGui.SetTooltip($"Applies to NPCs in busy areas (when NPCs are in index > 200, which occurs when up to 100 characters are rendered."); ImGui.SameLine(); - + */ bool applyToNpcsInCutscenes = config.ApplyToNpcsInCutscenes; if (ImGui.Checkbox("Apply to NPCs in Cutscenes", ref applyToNpcsInCutscenes)) { @@ -99,7 +105,10 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Applies to NPCs in busy areas (when NPCs are in index > 200, which occurs when up to 100 characters are rendered."); + ImGui.SetTooltip($"Apply scales to NPCs in cutscenes.\nSpecify a scale with the name 'CutsceneDefault' to apply it to all generic characters."); + + ImGui.Separator(); + ImGui.Text("Characters:"); ImGui.SameLine(); @@ -108,7 +117,6 @@ protected override void DrawContents() ImGui.Text("Character Name:"); ImGui.InputText(string.Empty, ref this.newScaleCharacter, 1024); - if (ImGui.Button("OK")) { string characterName = this.newScaleCharacter; @@ -142,7 +150,6 @@ protected override void DrawContents() ImGui.SetTooltip("Add a character"); ImGui.Separator(); - ImGui.Text("Characters:"); ImGui.BeginChild("scrolling", new Vector2(0, ImGui.GetFrameHeightWithSpacing() - 56), false); @@ -189,7 +196,7 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Enable and disable scale"); + ImGui.SetTooltip($"Enable and disable scale.\nWill disable all other scales for the same character."); ImGui.SameLine(); if (ImGuiComponents.IconButton(FontAwesomeIcon.Pen)) @@ -199,7 +206,7 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Edit body scale"); + ImGui.SetTooltip($"Edit body scale (WIP)"); ImGui.SameLine(); if (ImGuiComponents.IconButton(FontAwesomeIcon.FileImport)) @@ -429,7 +436,7 @@ private BodyScale BuildFromJSON(BodyScale scale, string json) return scale; } - private readonly string defaultFile = @"{""FileExtension"": "".pose"", ""TypeName"": ""Default"", ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 0"", ""Scale"": ""1, 1, 1"", ""Bones"": { + private readonly string defaultFile = @"{""FileExtension"": "".pose"", ""TypeName"": ""Default"", ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 0"", ""Scale"": ""0, 0, 0"", ""Bones"": { ""Root"": { ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 1"", ""Scale"": ""1, 1, 1""}, ""Abdomen"": { ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 1"", ""Scale"": ""1, 1, 1"" }, ""Throw"": { ""Position"": ""0, 0, 0"", ""Rotation"": ""0, 0, 0, 1"", ""Scale"": ""1, 1, 1"" }, diff --git a/CustomizePlus/Interface/EditInterface.cs b/CustomizePlus/Interface/EditInterface.cs index 8bb119f..ee9e3d0 100644 --- a/CustomizePlus/Interface/EditInterface.cs +++ b/CustomizePlus/Interface/EditInterface.cs @@ -22,7 +22,7 @@ public class EditInterface : WindowBase { protected BodyScale? Scale { get; private set; } - protected override string Title => $"Edit Scale: {this.originalScaleName}"; + protected override string Title => $"(WIP) Edit Scale: {this.originalScaleName}"; protected BodyScale? ScaleUpdated { get; private set; } private int scaleIndex = -1; @@ -33,7 +33,7 @@ public class EditInterface : WindowBase private string originalScaleCharacter = string.Empty; private HkVector4 originalScaleValue = HkVector4.One; private Vector4 newScaleValue = HkVector4.One.GetAsNumericsVector(); - private Vector4 originalRootScale = new Vector4(1f,1f,1f,0f); + private Vector4 originalRootScale = new Vector4(1f, 1f, 1f, 0f); private Vector4 newRootScale = HkVector4.One.GetAsNumericsVector(); private BodyScale? scaleStart; @@ -65,10 +65,10 @@ public void Show(BodyScale scale) editWnd.scaleEnabled = scale.BodyScaleEnabled; - for (int i=0; i 245 && !Configuration.ApplyToNpcsInBusyAreas) + // continue; + + // Don't affect the cutscene object range, by configuration + if (i >= 202 && i < 240 && !Configuration.ApplyToNpcsInCutscenes) continue; var obj = ObjectTable[i]; - //try - //{ - // (Character)obj.Name - //} - //if (TryGetValue()) + BodyScale? scale = null; scale = IdentifyBodyScale((ObjectStruct*)ObjectTable.GetObjectAddress(i)); - if (obj == null)// || scale == null) + if (obj == null) { continue; } @@ -190,7 +182,6 @@ public static unsafe void Update() scale = defaultScale; } else if (scale == null) { continue; } - //Apply(obj, scale); scale.Apply(obj, true); continue; case ObjectKind.Retainer: @@ -203,35 +194,28 @@ public static unsafe void Update() scale = defaultScale; } else if (scale == null) { continue; } - //Apply(obj, scale); scale.Apply(obj, true); continue; case ObjectKind.EventNpc: case ObjectKind.BattleNpc: - //case ObjectKind.Cutscene: - //case ObjectKind.EventObj: - bool finalApplyToNpcs = Configuration.ApplyToNpcs && (Configuration.ApplyToNpcsInBusyAreas && i >= 245); - bool finalApplyToNpcsCutscene = Configuration.ApplyToNpcsInCutscenes && ObjectTable[201] != null; - if (finalApplyToNpcs && scale == null && defaultScale != null && ObjectTable[201] == null) + // case ObjectKind.Cutscene: + // case ObjectKind.EventObj: + if (scale == null && defaultScale != null && (i < 201 || i > 246)) { scale = defaultScale; } - else if (finalApplyToNpcsCutscene && scale == null && defaultCutsceneScale != null) + else if (scale == null && defaultCutsceneScale != null && (i > 200 || i < 245)) { scale = defaultCutsceneScale; } - else if (!Configuration.ApplyToNpcs || scale == null) + if (!Configuration.ApplyToNpcs || scale == null) { continue; } - //Apply(obj, scale); + scale.Apply(obj, false); continue; - /*if (scale == null) - continue; - scale.Apply(obj, false); - continue;*/ default: continue; } @@ -300,7 +284,7 @@ private static IntPtr OnRender(IntPtr a1, int a2, IntPtr a3, byte a4, IntPtr a5, return original(a1, a2, a3, a4, a5, a6); } - // All functions related to this process for non-named objects adapted from Penumbra logic. + // All functions related to this process for non-named objects adapted from Penumbra logic. Credit to Ottermandias et al. private static unsafe BodyScale? IdentifyBodyScale(ObjectStruct* gameObject) { if (gameObject == null) @@ -322,40 +306,47 @@ private static IntPtr OnRender(IntPtr a1, int a2, IntPtr a3, byte a4, IntPtr a5, } else { - //actorName = new Utf8String(gameObject->Name).ToString(); - string? actualName = null; - // All these special cases are relevant for an empty name, so never collide with the above setting. - // Only OwnerName can be applied to something with a non-empty name, and that is the specific case we want to handle. - if (GameGui.GetAddonByName("PvPMKSIntroduction", 1) == IntPtr.Zero) { - actualName = gameObject->ObjectIndex switch - { - 240 => GetPlayerName(), // character window - 241 => GetInspectName() ?? GetGlamourName(), // GetCardName() ?? // inspect, character card, glamour plate editor. - Card removed due to logic issues - 242 => GetPlayerName(), // try-on - 243 => GetPlayerName(), // dye preview - 244 => GetPlayerName(), // portrait preview - >= 200 => GetCutsceneName(gameObject), - _ => null, - } ?? new Utf8String(gameObject->Name).ToString(); - } else - { - actualName = gameObject->ObjectIndex switch - { - 240 => GetPlayerName(), // character window - _ => null, - } ?? new Utf8String(gameObject->Name).ToString(); - } - //TODO: Ensure player side only (first group, one of the node textures is blue. Alternately, look for hidden party list UI and get names from there. - //else if (((AtkUnitBase*)GameGui.GetAddonByName("PvPMKSIntroduction", 1))->UldManager.NodeList[]) - //?? - //actorName ?? new Utf8String(gameObject->Name).ToString(); + actorName = new Utf8String(gameObject->Name).ToString(); - if (actualName == null) + if (actorName != null) { - return null; + NameToScale.TryGetValue(actorName, out scale); } + else + { + string? actualName = null; + + // Check if in pvp intro sequence, which uses 240-244 for the 5 players, and only affect the first if so + // TODO: Ensure player side only. First group, where one of the node textures is blue. Alternately, look for hidden party list UI and get names from there. + if (GameGui.GetAddonByName("PvPMKSIntroduction", 1) == IntPtr.Zero) + { + actualName = gameObject->ObjectIndex switch + { + 240 => GetPlayerName(), // character window + 241 => GetInspectName() ?? GetGlamourName(), // GetCardName() ?? // inspect, character card, glamour plate editor. - Card removed due to logic issues + 242 => GetPlayerName(), // try-on + 243 => GetPlayerName(), // dye preview + 244 => GetPlayerName(), // portrait preview + >= 200 => GetCutsceneName(gameObject), + _ => null, + } ?? new Utf8String(gameObject->Name).ToString(); + } + else + { + actualName = gameObject->ObjectIndex switch + { + 240 => GetPlayerName(), // character window + _ => null, + } ?? new Utf8String(gameObject->Name).ToString(); + } + + if (actualName == null) + { + return null; + } - NameToScale.TryGetValue(actualName, out scale); + NameToScale.TryGetValue(actualName, out scale); + } } } catch (Exception e) diff --git a/repo.json b/repo.json index 9206044..55e016f 100644 --- a/repo.json +++ b/repo.json @@ -4,19 +4,19 @@ "Name": "Customize+", "Description": "A plugin that allows you to create and apply Anamnesis-style body scaling full time.", "InternalName": "CustomizePlus", - "AssemblyVersion": "0.0.0.7", - "TestingAssemblyVersion": "0.0.0.7", + "AssemblyVersion": "0.0.1.0", + "TestingAssemblyVersion": "0.0.1.0", "RepoUrl": "https://github.com/XIV-Tools/CustomizePlus", "ApplicableVersion": "any", - "DalamudApiLevel": 6, + "DalamudApiLevel": 7, "IsHide": "False", "IsTestingExclusive": "False", "DownloadCount": 0, "LastUpdate": 0, "LoadPriority": 0, - "DownloadLinkInstall": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.0.7/CustomizePlus.zip", - "DownloadLinkTesting": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.0.7/CustomizePlus.zip", - "DownloadLinkUpdate": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.0.7/CustomizePlus.zip", + "DownloadLinkInstall": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.1.0/CustomizePlus.zip", + "DownloadLinkTesting": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.1.0/CustomizePlus.zip", + "DownloadLinkUpdate": "https://github.com/XIV-Tools/CustomizePlus/releases/download/0.0.1.0/CustomizePlus.zip", "IconUrl": "https://raw.githubusercontent.com/XIV-Tools/CustomizePlus/main/Data/icon.png" } ] From 38c9e6b6ca69ec21ce9198e5c27cf3f4751a7b09 Mon Sep 17 00:00:00 2001 From: Phenrei Date: Thu, 25 Aug 2022 01:32:46 -0400 Subject: [PATCH 5/5] Improvements to cutscene logic; Minor fix to edit and configuration UIs Cleaner code around the cutscene logic as well --- CustomizePlus/Configuration.cs | 4 +- CustomizePlus/CustomizePlus.csproj | 4 +- .../Interface/ConfigurationInterface.cs | 2 +- CustomizePlus/Interface/EditInterface.cs | 6 + CustomizePlus/Plugin.cs | 138 ++++++++---------- 5 files changed, 68 insertions(+), 86 deletions(-) diff --git a/CustomizePlus/Configuration.cs b/CustomizePlus/Configuration.cs index 307a391..35ced70 100644 --- a/CustomizePlus/Configuration.cs +++ b/CustomizePlus/Configuration.cs @@ -15,9 +15,9 @@ public class Configuration : IPluginConfiguration public bool Enable { get; set; } = true; public bool AutomaticEditMode { get; set; } = false; - public bool ApplyToNpcs { get; set; } = false; + public bool ApplyToNpcs { get; set; } = true; // public bool ApplyToNpcsInBusyAreas { get; set; } = false; - public bool ApplyToNpcsInCutscenes { get; set; } = false; + public bool ApplyToNpcsInCutscenes { get; set; } = true; // Upcoming feature diff --git a/CustomizePlus/CustomizePlus.csproj b/CustomizePlus/CustomizePlus.csproj index 619eefc..bea8852 100644 --- a/CustomizePlus/CustomizePlus.csproj +++ b/CustomizePlus/CustomizePlus.csproj @@ -68,11 +68,11 @@ false - ..\..\..\Penumbra\Penumbra\bin\Debug\Penumbra.dll + ..\..\Penumbra\Penumbra\bin\Debug\Penumbra.dll false - ..\..\..\Penumbra\Penumbra\bin\Debug\Penumbra.GameData.dll + ..\..\Penumbra\Penumbra\bin\Debug\Penumbra.GameData.dll diff --git a/CustomizePlus/Interface/ConfigurationInterface.cs b/CustomizePlus/Interface/ConfigurationInterface.cs index 9103bad..2a7df95 100644 --- a/CustomizePlus/Interface/ConfigurationInterface.cs +++ b/CustomizePlus/Interface/ConfigurationInterface.cs @@ -105,7 +105,7 @@ protected override void DrawContents() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Apply scales to NPCs in cutscenes.\nSpecify a scale with the name 'CutsceneDefault' to apply it to all generic characters."); + ImGui.SetTooltip($"Apply scales to NPCs in cutscenes.\nSpecify a scale with the name 'DefaultCutscene' to apply it to all generic characters while in a cutscene."); ImGui.Separator(); ImGui.Text("Characters:"); diff --git a/CustomizePlus/Interface/EditInterface.cs b/CustomizePlus/Interface/EditInterface.cs index ee9e3d0..8c80b9a 100644 --- a/CustomizePlus/Interface/EditInterface.cs +++ b/CustomizePlus/Interface/EditInterface.cs @@ -101,6 +101,12 @@ protected override void DrawContents() if (ImGui.Checkbox("Enable", ref enabledTemp)) { this.scaleEnabled = enabledTemp; + if (config.AutomaticEditMode) + { + AddToConfig(this.newScaleName, this.newScaleCharacter); + config.Save(); + Plugin.LoadConfig(); + } } ImGui.SameLine(); diff --git a/CustomizePlus/Plugin.cs b/CustomizePlus/Plugin.cs index c218a3f..133e2dd 100644 --- a/CustomizePlus/Plugin.cs +++ b/CustomizePlus/Plugin.cs @@ -83,11 +83,12 @@ public static void LoadConfig() NameToScale.Clear(); defaultScale = null; + defaultRetainerScale = null; + defaultCutsceneScale = null; foreach (BodyScale bodyScale in Configuration.BodyScales) { bodyScale.ClearCache(); - if (bodyScale.CharacterName == "Default" && bodyScale.BodyScaleEnabled) { defaultScale = bodyScale; @@ -157,68 +158,53 @@ public static unsafe void Update() // if (i > 245 && !Configuration.ApplyToNpcsInBusyAreas) // continue; - // Don't affect the cutscene object range, by configuration + // Don't affect the cutscene object range, by configuration. + // 202 gives leeway as player is not always put in 200 like they should be. if (i >= 202 && i < 240 && !Configuration.ApplyToNpcsInCutscenes) continue; var obj = ObjectTable[i]; + + if (obj == null) + continue; BodyScale? scale = null; scale = IdentifyBodyScale((ObjectStruct*)ObjectTable.GetObjectAddress(i)); - - if (obj == null) - { - continue; - } - + try { + bool isCutsceneNpc = false; switch (obj.ObjectKind) { case ObjectKind.Player: case ObjectKind.Companion: - if (scale == null && defaultScale != null) - { - scale = defaultScale; - } - else if (scale == null) { continue; } - scale.Apply(obj, true); - continue; + scale = scale ?? defaultScale ?? null; + break; case ObjectKind.Retainer: - if (scale == null && defaultRetainerScale != null) - { - scale = defaultRetainerScale; - } - else if (scale == null && defaultScale != null) - { - scale = defaultScale; - } - else if (scale == null) { continue; } - scale.Apply(obj, true); - continue; + scale = scale ?? defaultRetainerScale ?? defaultScale ?? null; + break; case ObjectKind.EventNpc: case ObjectKind.BattleNpc: - // case ObjectKind.Cutscene: - // case ObjectKind.EventObj: - if (scale == null && defaultScale != null && (i < 201 || i > 246)) - { - scale = defaultScale; - } - else if (scale == null && defaultCutsceneScale != null && (i > 200 || i < 245)) - { - scale = defaultCutsceneScale; - } - if (!Configuration.ApplyToNpcs || scale == null) - { + isCutsceneNpc = i >= 200 && i < 246; + // Stop if NPCs disabled by config. Have to double check cutscene range due to the 200/201 issue. + if (!Configuration.ApplyToNpcs && !isCutsceneNpc) continue; - } - - scale.Apply(obj, false); - continue; - + else if (isCutsceneNpc && !Configuration.ApplyToNpcsInCutscenes) + continue; + // Choose most appropriate default, or fallback to null. + if (isCutsceneNpc) + scale = defaultCutsceneScale ?? defaultScale ?? null; + else + scale = defaultScale ?? null; + break; default: continue; } + // No scale to apply, move on. + if (scale == null) + continue; + // Don't apply root scales to NPCs in cutscenes or battle NPCs. Both cause animation or camera issues. + scale.Apply(obj, !(isCutsceneNpc || (obj.ObjectKind == ObjectKind.BattleNpc))); } catch (Exception ex) { @@ -297,56 +283,46 @@ private static IntPtr OnRender(IntPtr a1, int a2, IntPtr a3, byte a4, IntPtr a5, try { - // Login screen. Names are populated after actors are drawn, - // so it is not possible to fetch names from the ui list. - // Actors are also not named. So use "Player" - if (!ClientState.IsLoggedIn) + actorName = new Utf8String(gameObject->Name).ToString(); + + if (!string.IsNullOrEmpty(actorName)) { - NameToScale.TryGetValue("Player", out scale); + NameToScale.TryGetValue(actorName, out scale); } else { - actorName = new Utf8String(gameObject->Name).ToString(); + string? actualName = null; - if (actorName != null) + // Check if in pvp intro sequence, which uses 240-244 for the 5 players, and only affect the first if so + // TODO: Ensure player side only. First group, where one of the node textures is blue. Alternately, look for hidden party list UI and get names from there. + if (GameGui.GetAddonByName("PvPMKSIntroduction", 1) == IntPtr.Zero) { - NameToScale.TryGetValue(actorName, out scale); + actualName = gameObject->ObjectIndex switch + { + 240 => GetPlayerName(), // character window + 241 => GetInspectName() ?? GetGlamourName(), // GetCardName() ?? // inspect, character card, glamour plate editor. - Card removed due to logic issues + 242 => GetPlayerName(), // try-on + 243 => GetPlayerName(), // dye preview + 244 => GetPlayerName(), // portrait preview + >= 200 => GetCutsceneName(gameObject), + _ => null, + } ?? new Utf8String(gameObject->Name).ToString(); } else { - string? actualName = null; - - // Check if in pvp intro sequence, which uses 240-244 for the 5 players, and only affect the first if so - // TODO: Ensure player side only. First group, where one of the node textures is blue. Alternately, look for hidden party list UI and get names from there. - if (GameGui.GetAddonByName("PvPMKSIntroduction", 1) == IntPtr.Zero) + actualName = gameObject->ObjectIndex switch { - actualName = gameObject->ObjectIndex switch - { - 240 => GetPlayerName(), // character window - 241 => GetInspectName() ?? GetGlamourName(), // GetCardName() ?? // inspect, character card, glamour plate editor. - Card removed due to logic issues - 242 => GetPlayerName(), // try-on - 243 => GetPlayerName(), // dye preview - 244 => GetPlayerName(), // portrait preview - >= 200 => GetCutsceneName(gameObject), - _ => null, - } ?? new Utf8String(gameObject->Name).ToString(); - } - else - { - actualName = gameObject->ObjectIndex switch - { - 240 => GetPlayerName(), // character window - _ => null, - } ?? new Utf8String(gameObject->Name).ToString(); - } - - if (actualName == null) - { - return null; - } + 240 => GetPlayerName(), // character window + _ => null, + } ?? new Utf8String(gameObject->Name).ToString(); + } - NameToScale.TryGetValue(actualName, out scale); + if (actualName == null) + { + return null; } + + NameToScale.TryGetValue(actualName, out scale); } } catch (Exception e)