From 097923f5ff7bad4b13b1035a77b5fa85b8e1dd35 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Mon, 3 Oct 2022 11:36:17 +0200 Subject: [PATCH] Several small fixes. --- OtterGui | 2 +- Penumbra.GameData/Enums/RspAttribute.cs | 159 +++++++------ Penumbra.GameData/Enums/WeaponCategory.cs | 209 ++++++++++++++++++ Penumbra/Import/Textures/TexFileParser.cs | 6 + Penumbra/Import/Textures/Texture.cs | 2 +- Penumbra/UI/Classes/ModEditWindow.FileEdit.cs | 2 +- Penumbra/UI/ConfigWindow.CollectionsTab.cs | 27 ++- 7 files changed, 314 insertions(+), 93 deletions(-) create mode 100644 Penumbra.GameData/Enums/WeaponCategory.cs diff --git a/OtterGui b/OtterGui index 9df97a04..750f7415 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 9df97a04115eb08804e5d15fb3b05063e537fed2 +Subproject commit 750f7415d07334530ad12db10f3dd28fd7e1f130 diff --git a/Penumbra.GameData/Enums/RspAttribute.cs b/Penumbra.GameData/Enums/RspAttribute.cs index 07d03b67..c4016bb6 100644 --- a/Penumbra.GameData/Enums/RspAttribute.cs +++ b/Penumbra.GameData/Enums/RspAttribute.cs @@ -1,92 +1,91 @@ using System.ComponentModel; -namespace Penumbra.GameData.Enums +namespace Penumbra.GameData.Enums; + +public enum RspAttribute : byte { - public enum RspAttribute : byte + MaleMinSize, + MaleMaxSize, + MaleMinTail, + MaleMaxTail, + FemaleMinSize, + FemaleMaxSize, + FemaleMinTail, + FemaleMaxTail, + BustMinX, + BustMinY, + BustMinZ, + BustMaxX, + BustMaxY, + BustMaxZ, + NumAttributes, +} + +public static class RspAttributeExtensions +{ + public static Gender ToGender( this RspAttribute attribute ) { - MaleMinSize, - MaleMaxSize, - MaleMinTail, - MaleMaxTail, - FemaleMinSize, - FemaleMaxSize, - FemaleMinTail, - FemaleMaxTail, - BustMinX, - BustMinY, - BustMinZ, - BustMaxX, - BustMaxY, - BustMaxZ, - NumAttributes, + return attribute switch + { + RspAttribute.MaleMinSize => Gender.Male, + RspAttribute.MaleMaxSize => Gender.Male, + RspAttribute.MaleMinTail => Gender.Male, + RspAttribute.MaleMaxTail => Gender.Male, + RspAttribute.FemaleMinSize => Gender.Female, + RspAttribute.FemaleMaxSize => Gender.Female, + RspAttribute.FemaleMinTail => Gender.Female, + RspAttribute.FemaleMaxTail => Gender.Female, + RspAttribute.BustMinX => Gender.Female, + RspAttribute.BustMinY => Gender.Female, + RspAttribute.BustMinZ => Gender.Female, + RspAttribute.BustMaxX => Gender.Female, + RspAttribute.BustMaxY => Gender.Female, + RspAttribute.BustMaxZ => Gender.Female, + _ => Gender.Unknown, + }; } - public static class RspAttributeExtensions + public static string ToUngenderedString( this RspAttribute attribute ) { - public static Gender ToGender( this RspAttribute attribute ) + return attribute switch { - return attribute switch - { - RspAttribute.MaleMinSize => Gender.Male, - RspAttribute.MaleMaxSize => Gender.Male, - RspAttribute.MaleMinTail => Gender.Male, - RspAttribute.MaleMaxTail => Gender.Male, - RspAttribute.FemaleMinSize => Gender.Female, - RspAttribute.FemaleMaxSize => Gender.Female, - RspAttribute.FemaleMinTail => Gender.Female, - RspAttribute.FemaleMaxTail => Gender.Female, - RspAttribute.BustMinX => Gender.Female, - RspAttribute.BustMinY => Gender.Female, - RspAttribute.BustMinZ => Gender.Female, - RspAttribute.BustMaxX => Gender.Female, - RspAttribute.BustMaxY => Gender.Female, - RspAttribute.BustMaxZ => Gender.Female, - _ => Gender.Unknown, - }; - } + RspAttribute.MaleMinSize => "MinSize", + RspAttribute.MaleMaxSize => "MaxSize", + RspAttribute.MaleMinTail => "MinTail", + RspAttribute.MaleMaxTail => "MaxTail", + RspAttribute.FemaleMinSize => "MinSize", + RspAttribute.FemaleMaxSize => "MaxSize", + RspAttribute.FemaleMinTail => "MinTail", + RspAttribute.FemaleMaxTail => "MaxTail", + RspAttribute.BustMinX => "BustMinX", + RspAttribute.BustMinY => "BustMinY", + RspAttribute.BustMinZ => "BustMinZ", + RspAttribute.BustMaxX => "BustMaxX", + RspAttribute.BustMaxY => "BustMaxY", + RspAttribute.BustMaxZ => "BustMaxZ", + _ => "", + }; + } - public static string ToUngenderedString( this RspAttribute attribute ) + public static string ToFullString( this RspAttribute attribute ) + { + return attribute switch { - return attribute switch - { - RspAttribute.MaleMinSize => "MinSize", - RspAttribute.MaleMaxSize => "MaxSize", - RspAttribute.MaleMinTail => "MinTail", - RspAttribute.MaleMaxTail => "MaxTail", - RspAttribute.FemaleMinSize => "MinSize", - RspAttribute.FemaleMaxSize => "MaxSize", - RspAttribute.FemaleMinTail => "MinTail", - RspAttribute.FemaleMaxTail => "MaxTail", - RspAttribute.BustMinX => "BustMinX", - RspAttribute.BustMinY => "BustMinY", - RspAttribute.BustMinZ => "BustMinZ", - RspAttribute.BustMaxX => "BustMaxX", - RspAttribute.BustMaxY => "BustMaxY", - RspAttribute.BustMaxZ => "BustMaxZ", - _ => "", - }; - } - - public static string ToFullString( this RspAttribute attribute ) - { - return attribute switch - { - RspAttribute.MaleMinSize => "Male Minimum Size", - RspAttribute.MaleMaxSize => "Male Maximum Size", - RspAttribute.FemaleMinSize => "Female Minimum Size", - RspAttribute.FemaleMaxSize => "Female Maximum Size", - RspAttribute.BustMinX => "Bust Minimum X-Axis", - RspAttribute.BustMaxX => "Bust Maximum X-Axis", - RspAttribute.BustMinY => "Bust Minimum Y-Axis", - RspAttribute.BustMaxY => "Bust Maximum Y-Axis", - RspAttribute.BustMinZ => "Bust Minimum Z-Axis", - RspAttribute.BustMaxZ => "Bust Maximum Z-Axis", - RspAttribute.MaleMinTail => "Male Minimum Tail Length", - RspAttribute.MaleMaxTail => "Male Maximum Tail Length", - RspAttribute.FemaleMinTail => "Female Minimum Tail Length", - RspAttribute.FemaleMaxTail => "Female Maximum Tail Length", - _ => throw new InvalidEnumArgumentException(), - }; - } + RspAttribute.MaleMinSize => "Male Minimum Size", + RspAttribute.MaleMaxSize => "Male Maximum Size", + RspAttribute.FemaleMinSize => "Female Minimum Size", + RspAttribute.FemaleMaxSize => "Female Maximum Size", + RspAttribute.BustMinX => "Bust Minimum X-Axis", + RspAttribute.BustMaxX => "Bust Maximum X-Axis", + RspAttribute.BustMinY => "Bust Minimum Y-Axis", + RspAttribute.BustMaxY => "Bust Maximum Y-Axis", + RspAttribute.BustMinZ => "Bust Minimum Z-Axis", + RspAttribute.BustMaxZ => "Bust Maximum Z-Axis", + RspAttribute.MaleMinTail => "Male Minimum Tail Length", + RspAttribute.MaleMaxTail => "Male Maximum Tail Length", + RspAttribute.FemaleMinTail => "Female Minimum Tail Length", + RspAttribute.FemaleMaxTail => "Female Maximum Tail Length", + _ => throw new InvalidEnumArgumentException(), + }; } } \ No newline at end of file diff --git a/Penumbra.GameData/Enums/WeaponCategory.cs b/Penumbra.GameData/Enums/WeaponCategory.cs new file mode 100644 index 00000000..f7b1fc91 --- /dev/null +++ b/Penumbra.GameData/Enums/WeaponCategory.cs @@ -0,0 +1,209 @@ +using System; + +namespace Penumbra.GameData.Enums; + +public enum WeaponCategory : byte +{ + Unknown = 0, + Pugilist, + Gladiator, + Marauder, + Archer, + Lancer, + Thaumaturge1, + Thaumaturge2, + Conjurer1, + Conjurer2, + Arcanist, + Shield, + CarpenterMain, + CarpenterOff, + BlacksmithMain, + BlacksmithOff, + ArmorerMain, + ArmorerOff, + GoldsmithMain, + GoldsmithOff, + LeatherworkerMain, + LeatherworkerOff, + WeaverMain, + WeaverOff, + AlchemistMain, + AlchemistOff, + CulinarianMain, + CulinarianOff, + MinerMain, + MinerOff, + BotanistMain, + BotanistOff, + FisherMain, + Rogue = 84, + DarkKnight = 87, + Machinist = 88, + Astrologian = 89, + Samurai = 96, + RedMage = 97, + Scholar = 98, + FisherOff = 99, + BlueMage = 105, + Gunbreaker = 106, + Dancer = 107, + Reaper = 108, + Sage = 109, +} + +public static class WeaponCategoryExtensions +{ + public static WeaponCategory AllowsOffHand( this WeaponCategory category ) + => category switch + { + WeaponCategory.Pugilist => WeaponCategory.Pugilist, + WeaponCategory.Gladiator => WeaponCategory.Shield, + WeaponCategory.Marauder => WeaponCategory.Unknown, + WeaponCategory.Archer => WeaponCategory.Unknown, + WeaponCategory.Lancer => WeaponCategory.Unknown, + WeaponCategory.Thaumaturge1 => WeaponCategory.Shield, + WeaponCategory.Thaumaturge2 => WeaponCategory.Unknown, + WeaponCategory.Conjurer1 => WeaponCategory.Shield, + WeaponCategory.Conjurer2 => WeaponCategory.Unknown, + WeaponCategory.Arcanist => WeaponCategory.Unknown, + WeaponCategory.Shield => WeaponCategory.Unknown, + WeaponCategory.CarpenterMain => WeaponCategory.CarpenterOff, + WeaponCategory.CarpenterOff => WeaponCategory.Unknown, + WeaponCategory.BlacksmithMain => WeaponCategory.BlacksmithOff, + WeaponCategory.BlacksmithOff => WeaponCategory.Unknown, + WeaponCategory.ArmorerMain => WeaponCategory.ArmorerOff, + WeaponCategory.ArmorerOff => WeaponCategory.Unknown, + WeaponCategory.GoldsmithMain => WeaponCategory.GoldsmithOff, + WeaponCategory.GoldsmithOff => WeaponCategory.Unknown, + WeaponCategory.LeatherworkerMain => WeaponCategory.LeatherworkerOff, + WeaponCategory.LeatherworkerOff => WeaponCategory.Unknown, + WeaponCategory.WeaverMain => WeaponCategory.WeaverOff, + WeaponCategory.WeaverOff => WeaponCategory.Unknown, + WeaponCategory.AlchemistMain => WeaponCategory.AlchemistOff, + WeaponCategory.AlchemistOff => WeaponCategory.Unknown, + WeaponCategory.CulinarianMain => WeaponCategory.CulinarianOff, + WeaponCategory.CulinarianOff => WeaponCategory.Unknown, + WeaponCategory.MinerMain => WeaponCategory.MinerOff, + WeaponCategory.MinerOff => WeaponCategory.Unknown, + WeaponCategory.BotanistMain => WeaponCategory.BotanistOff, + WeaponCategory.BotanistOff => WeaponCategory.Unknown, + WeaponCategory.FisherMain => WeaponCategory.FisherOff, + WeaponCategory.Rogue => WeaponCategory.Rogue, + WeaponCategory.DarkKnight => WeaponCategory.Unknown, + WeaponCategory.Machinist => WeaponCategory.Machinist, + WeaponCategory.Astrologian => WeaponCategory.Astrologian, + WeaponCategory.Samurai => WeaponCategory.Unknown, + WeaponCategory.RedMage => WeaponCategory.RedMage, + WeaponCategory.Scholar => WeaponCategory.Unknown, + WeaponCategory.FisherOff => WeaponCategory.Unknown, + WeaponCategory.BlueMage => WeaponCategory.Unknown, + WeaponCategory.Gunbreaker => WeaponCategory.Unknown, + WeaponCategory.Dancer => WeaponCategory.Dancer, + WeaponCategory.Reaper => WeaponCategory.Unknown, + WeaponCategory.Sage => WeaponCategory.Unknown, + _ => WeaponCategory.Unknown, + }; + + public static EquipSlot ToSlot( this WeaponCategory category ) + => category switch + { + WeaponCategory.Pugilist => EquipSlot.MainHand, + WeaponCategory.Gladiator => EquipSlot.MainHand, + WeaponCategory.Marauder => EquipSlot.MainHand, + WeaponCategory.Archer => EquipSlot.MainHand, + WeaponCategory.Lancer => EquipSlot.MainHand, + WeaponCategory.Thaumaturge1 => EquipSlot.MainHand, + WeaponCategory.Thaumaturge2 => EquipSlot.MainHand, + WeaponCategory.Conjurer1 => EquipSlot.MainHand, + WeaponCategory.Conjurer2 => EquipSlot.MainHand, + WeaponCategory.Arcanist => EquipSlot.MainHand, + WeaponCategory.Shield => EquipSlot.OffHand, + WeaponCategory.CarpenterMain => EquipSlot.MainHand, + WeaponCategory.CarpenterOff => EquipSlot.OffHand, + WeaponCategory.BlacksmithMain => EquipSlot.MainHand, + WeaponCategory.BlacksmithOff => EquipSlot.OffHand, + WeaponCategory.ArmorerMain => EquipSlot.MainHand, + WeaponCategory.ArmorerOff => EquipSlot.OffHand, + WeaponCategory.GoldsmithMain => EquipSlot.MainHand, + WeaponCategory.GoldsmithOff => EquipSlot.OffHand, + WeaponCategory.LeatherworkerMain => EquipSlot.MainHand, + WeaponCategory.LeatherworkerOff => EquipSlot.OffHand, + WeaponCategory.WeaverMain => EquipSlot.MainHand, + WeaponCategory.WeaverOff => EquipSlot.OffHand, + WeaponCategory.AlchemistMain => EquipSlot.MainHand, + WeaponCategory.AlchemistOff => EquipSlot.OffHand, + WeaponCategory.CulinarianMain => EquipSlot.MainHand, + WeaponCategory.CulinarianOff => EquipSlot.OffHand, + WeaponCategory.MinerMain => EquipSlot.MainHand, + WeaponCategory.MinerOff => EquipSlot.OffHand, + WeaponCategory.BotanistMain => EquipSlot.MainHand, + WeaponCategory.BotanistOff => EquipSlot.OffHand, + WeaponCategory.FisherMain => EquipSlot.MainHand, + WeaponCategory.Rogue => EquipSlot.MainHand, + WeaponCategory.DarkKnight => EquipSlot.MainHand, + WeaponCategory.Machinist => EquipSlot.MainHand, + WeaponCategory.Astrologian => EquipSlot.MainHand, + WeaponCategory.Samurai => EquipSlot.MainHand, + WeaponCategory.RedMage => EquipSlot.MainHand, + WeaponCategory.Scholar => EquipSlot.MainHand, + WeaponCategory.FisherOff => EquipSlot.OffHand, + WeaponCategory.BlueMage => EquipSlot.MainHand, + WeaponCategory.Gunbreaker => EquipSlot.MainHand, + WeaponCategory.Dancer => EquipSlot.MainHand, + WeaponCategory.Reaper => EquipSlot.MainHand, + WeaponCategory.Sage => EquipSlot.MainHand, + _ => EquipSlot.Unknown, + }; + + public static int ToIndex( this WeaponCategory category ) + => category switch + { + WeaponCategory.Pugilist => 0, + WeaponCategory.Gladiator => 1, + WeaponCategory.Marauder => 2, + WeaponCategory.Archer => 3, + WeaponCategory.Lancer => 4, + WeaponCategory.Thaumaturge1 => 5, + WeaponCategory.Thaumaturge2 => 6, + WeaponCategory.Conjurer1 => 7, + WeaponCategory.Conjurer2 => 8, + WeaponCategory.Arcanist => 9, + WeaponCategory.Shield => 10, + WeaponCategory.CarpenterMain => 11, + WeaponCategory.CarpenterOff => 12, + WeaponCategory.BlacksmithMain => 13, + WeaponCategory.BlacksmithOff => 14, + WeaponCategory.ArmorerMain => 15, + WeaponCategory.ArmorerOff => 16, + WeaponCategory.GoldsmithMain => 17, + WeaponCategory.GoldsmithOff => 18, + WeaponCategory.LeatherworkerMain => 19, + WeaponCategory.LeatherworkerOff => 20, + WeaponCategory.WeaverMain => 21, + WeaponCategory.WeaverOff => 22, + WeaponCategory.AlchemistMain => 23, + WeaponCategory.AlchemistOff => 24, + WeaponCategory.CulinarianMain => 25, + WeaponCategory.CulinarianOff => 26, + WeaponCategory.MinerMain => 27, + WeaponCategory.MinerOff => 28, + WeaponCategory.BotanistMain => 29, + WeaponCategory.BotanistOff => 30, + WeaponCategory.FisherMain => 31, + WeaponCategory.Rogue => 32, + WeaponCategory.DarkKnight => 33, + WeaponCategory.Machinist => 34, + WeaponCategory.Astrologian => 35, + WeaponCategory.Samurai => 36, + WeaponCategory.RedMage => 37, + WeaponCategory.Scholar => 38, + WeaponCategory.FisherOff => 39, + WeaponCategory.BlueMage => 40, + WeaponCategory.Gunbreaker => 41, + WeaponCategory.Dancer => 42, + WeaponCategory.Reaper => 43, + WeaponCategory.Sage => 44, + _ => -1, + }; +} \ No newline at end of file diff --git a/Penumbra/Import/Textures/TexFileParser.cs b/Penumbra/Import/Textures/TexFileParser.cs index 700acc37..6b77bd0e 100644 --- a/Penumbra/Import/Textures/TexFileParser.cs +++ b/Penumbra/Import/Textures/TexFileParser.cs @@ -25,6 +25,10 @@ public static class TexFileParser } meta.MipLevels = CountMipLevels( data, in meta, in header ); + if( meta.MipLevels == 0 ) + { + throw new Exception( "Could not load file. Image is corrupted and does not contain enough data for its size." ); + } var scratch = ScratchImage.Initialize( meta ); @@ -142,7 +146,9 @@ public static class TexFileParser } for( ; idx < 13; ++idx ) + { header.OffsetToSurface[ idx ] = 0; + } header.LodOffset[ 0 ] = 0; header.LodOffset[ 1 ] = 1; diff --git a/Penumbra/Import/Textures/Texture.cs b/Penumbra/Import/Textures/Texture.cs index 1f2997ee..b3df03f0 100644 --- a/Penumbra/Import/Textures/Texture.cs +++ b/Penumbra/Import/Textures/Texture.cs @@ -138,7 +138,7 @@ public sealed class Texture : IDisposable try { - var _ = System.IO.Path.GetExtension( Path ) switch + var _ = System.IO.Path.GetExtension( Path ).ToLowerInvariant() switch { ".dds" => LoadDds(), ".png" => LoadPng(), diff --git a/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs b/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs index cc4ef1c9..170b710e 100644 --- a/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs +++ b/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs @@ -349,7 +349,7 @@ public partial class ModEditWindow fixed( byte* ptr = data ) { file.ColorSets[ colorSetIdx ].Rows[ rowIdx ] = *( MtrlFile.ColorSet.Row* )ptr; - if( file.ColorDyeSets.Length <= colorSetIdx ) + if( colorSetIdx < file.ColorDyeSets.Length ) { file.ColorDyeSets[ colorSetIdx ].Rows[ rowIdx ] = *( MtrlFile.ColorDyeSet.Row* )( ptr + MtrlFile.ColorSet.Row.Size ); } diff --git a/Penumbra/UI/ConfigWindow.CollectionsTab.cs b/Penumbra/UI/ConfigWindow.CollectionsTab.cs index 41b85245..bf8b0107 100644 --- a/Penumbra/UI/ConfigWindow.CollectionsTab.cs +++ b/Penumbra/UI/ConfigWindow.CollectionsTab.cs @@ -5,6 +5,7 @@ using Dalamud.Interface; using Dalamud.Interface.Components; using ImGuiNET; using OtterGui; +using OtterGui.Classes; using OtterGui.Raii; using OtterGui.Widgets; using Penumbra.Collections; @@ -143,30 +144,36 @@ public partial class ConfigWindow $"Mods in the {InterfaceCollection} are loaded for any file that the game categorizes as an UI file. This is mostly icons as well as the tiles that generate the user interface windows themselves." ); } - private sealed class SpecialCombo : FilteredCombo< (CollectionType, string, string) > + private sealed class SpecialCombo : FilterComboBase< (CollectionType, string, string) > { public (CollectionType, string, string)? CurrentType => CollectionTypeExtensions.Special[ CurrentIdx ]; - public int CurrentIdx = 0; + public int CurrentIdx = 0; + private readonly float _unscaledWidth; + private readonly string _label; public SpecialCombo( string label, float unscaledWidth ) - : base( label, unscaledWidth, CollectionTypeExtensions.Special ) - { } + : base( CollectionTypeExtensions.Special, false ) + { + _label = label; + _unscaledWidth = unscaledWidth; + } public void Draw() - => Draw( CurrentIdx ); - - protected override void Select( int globalIdx ) { - CurrentIdx = globalIdx; + var preview = CurrentIdx >= 0 ? Items[ CurrentIdx ].Item2 : string.Empty; + Draw(_label, preview, ref CurrentIdx, _unscaledWidth * ImGuiHelpers.GlobalScale, ImGui.GetTextLineHeightWithSpacing()); } protected override string ToString( (CollectionType, string, string) obj ) => obj.Item2; - protected override bool IsVisible( (CollectionType, string, string) obj ) - => Filter.IsContained( obj.Item2 ) && Penumbra.CollectionManager.ByType( obj.Item1 ) == null; + protected override bool IsVisible( int globalIdx, LowerString filter ) + { + var obj = Items[ globalIdx ]; + return filter.IsContained( obj.Item2 ) && Penumbra.CollectionManager.ByType( obj.Item1 ) == null; + } } private readonly SpecialCombo _specialCollectionCombo = new("##NewSpecial", 350);