diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs index 5f47780..c765584 100644 --- a/Glamourer/Automation/AutoDesignApplier.cs +++ b/Glamourer/Automation/AutoDesignApplier.cs @@ -156,9 +156,9 @@ public class AutoDesignApplier : IDisposable private unsafe void Reduce(Actor actor, ActorState state, AutoDesignSet set, bool respectManual) { - EquipFlag totalEquipFlags = 0; - var totalCustomizeFlags = _code.EnabledMesmer ? 0 : CustomizeFlagExtensions.RedrawRequired; - byte totalMetaFlags = 0; + EquipFlag totalEquipFlags = 0; + CustomizeFlag totalCustomizeFlags = 0; + byte totalMetaFlags = 0; foreach (var design in set.Designs) { if (!design.IsActive(actor)) @@ -202,7 +202,7 @@ public class AutoDesignApplier : IDisposable if (equipFlags.HasFlag(flag)) { var item = design.Item(slot); - if (_code.EnabledInventory || _itemUnlocks.IsUnlocked(item.ItemId, out _)) + if (!_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.ItemId, out _)) { if (!respectManual || state[slot, false] is not StateChanged.Source.Manual) _state.ChangeItem(state, slot, item, StateChanged.Source.Fixed); @@ -223,7 +223,7 @@ public class AutoDesignApplier : IDisposable { var item = design.Item(EquipSlot.MainHand); if (state.ModelData.Item(EquipSlot.MainHand).Type == item.Type - && (_code.EnabledInventory || _itemUnlocks.IsUnlocked(item.ItemId, out _))) + && (!_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.ItemId, out _))) { if (!respectManual || state[EquipSlot.MainHand, false] is not StateChanged.Source.Manual) _state.ChangeItem(state, EquipSlot.MainHand, item, StateChanged.Source.Fixed); @@ -235,7 +235,7 @@ public class AutoDesignApplier : IDisposable { var item = design.Item(EquipSlot.OffHand); if (state.ModelData.Item(EquipSlot.OffHand).Type == item.Type - && (_code.EnabledInventory || _itemUnlocks.IsUnlocked(item.ItemId, out _))) + && (!_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.ItemId, out _))) { if (!respectManual || state[EquipSlot.OffHand, false] is not StateChanged.Source.Manual) _state.ChangeItem(state, EquipSlot.OffHand, item, StateChanged.Source.Fixed); @@ -274,7 +274,6 @@ public class AutoDesignApplier : IDisposable // Skip invalid designs entirely. if (_config.SkipInvalidCustomizations - && !_code.EnabledMesmer && (customize.Clan != design.Customize.Clan || customize.Gender != design.Customize.Gender || customize.Face != design.Customize.Face)) @@ -320,7 +319,7 @@ public class AutoDesignApplier : IDisposable var value = design.Customize[index]; if (CustomizationService.IsCustomizationValid(set, face, index, value, out var data) - && (_code.EnabledInventory || _customizeUnlocks.IsUnlocked(data.Value, out _))) + && (!_config.UnlockedItemMode || _customizeUnlocks.IsUnlocked(data.Value, out _))) { if (!respectManual || state[index] is not StateChanged.Source.Manual) _state.ChangeCustomize(state, index, value, StateChanged.Source.Fixed); diff --git a/Glamourer/Configuration.cs b/Glamourer/Configuration.cs index 9bfe41d..f950782 100644 --- a/Glamourer/Configuration.cs +++ b/Glamourer/Configuration.cs @@ -27,6 +27,7 @@ public class Configuration : IPluginConfiguration, ISavable public bool SkipInvalidCustomizations { get; set; } = false; public bool HideApplyCheckmarks { get; set; } = false; public bool SmallEquip { get; set; } = false; + public bool UnlockedItemMode { get; set; } = false; public MainWindow.TabType SelectedTab { get; set; } = MainWindow.TabType.Settings; public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift); @@ -86,10 +87,7 @@ public class Configuration : IPluginConfiguration, ISavable "Error reading Configuration, reverting to default.\nYou may be able to restore your configuration using the rolling backups in the XIVLauncher/backups/Glamourer directory.", "Error reading Configuration", "Error", NotificationType.Error); } - if (Codes.All(p => p.Code != CodeService.CodeInventoryString)) - Codes.Insert(0, (CodeService.CodeInventoryString, false)); - if (Codes.All(p => p.Code != CodeService.CodeMesmerString)) - Codes.Insert(0, (CodeService.CodeMesmerString, false)); + migrator.Migrate(this); } diff --git a/Glamourer/Glamourer.csproj b/Glamourer/Glamourer.csproj index 24551af..82e9962 100644 --- a/Glamourer/Glamourer.csproj +++ b/Glamourer/Glamourer.csproj @@ -5,8 +5,8 @@ x64 Glamourer Glamourer - 0.2.0.4 - 0.2.0.4 + 0.2.0.5 + 0.2.0.5 SoftOtter Glamourer Copyright © 2020 diff --git a/Glamourer/Glamourer.json b/Glamourer/Glamourer.json index 25ead5e..2efd3a2 100644 --- a/Glamourer/Glamourer.json +++ b/Glamourer/Glamourer.json @@ -5,7 +5,7 @@ "Description": "Adds functionality to change and store appearance of players, customization and equip. Requires Penumbra to be installed and activated to work. Can also add preview options to the Changed Items tab for Penumbra.", "Tags": [ "Appearance", "Glamour", "Race", "Outfit", "Armor", "Clothes", "Skins", "Customization", "Design", "Character" ], "InternalName": "Glamourer", - "AssemblyVersion": "0.2.0.4", + "AssemblyVersion": "0.2.0.5", "RepoUrl": "https://github.com/Ottermandias/Glamourer", "ApplicableVersion": "any", "DalamudApiLevel": 8, diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs b/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs index 059ad8d..23f8c8d 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs @@ -22,10 +22,10 @@ public partial class CustomizationDrawer var clan = _service.AwaitedService.GetName(CustomName.Clan); if (_withApply) { - if (UiHelpers.DrawCheckbox("##applyGender", "Apply gender of this design.", _currentApply, out var applyGender, _locked)) + if (UiHelpers.DrawCheckbox("##applyGender", "Apply gender of this design.", ChangeApply.HasFlag(CustomizeFlag.Gender), out var applyGender, _locked)) ChangeApply = applyGender ? ChangeApply | CustomizeFlag.Gender : ChangeApply & ~CustomizeFlag.Gender; ImGui.SameLine(); - if (UiHelpers.DrawCheckbox("##applyClan", "Apply clan of this design.", _currentApply, out var applyClan, _locked)) + if (UiHelpers.DrawCheckbox("##applyClan", "Apply clan of this design.", ChangeApply.HasFlag(CustomizeFlag.Clan), out var applyClan, _locked)) ChangeApply = applyClan ? ChangeApply | CustomizeFlag.Clan : ChangeApply & ~CustomizeFlag.Clan; ImGui.SameLine(); } diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs index a6f7265..8bd9eff 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs @@ -28,6 +28,7 @@ public class SetPanel private readonly CustomizeUnlockManager _customizeUnlocks; private readonly CustomizationService _customizations; + private readonly Configuration _config; private readonly DesignCombo _designCombo; private readonly JobGroupCombo _jobGroupCombo; private readonly IdentifierDrawer _identifierDrawer; @@ -40,7 +41,7 @@ public class SetPanel public SetPanel(SetSelector selector, AutoDesignManager manager, DesignManager designs, JobService jobs, ItemUnlockManager itemUnlocks, CustomizeUnlockManager customizeUnlocks, CustomizationService customizations, IdentifierDrawer identifierDrawer, - CodeService codeService) + CodeService codeService, Configuration config) { _selector = selector; _manager = manager; @@ -49,6 +50,7 @@ public class SetPanel _customizations = customizations; _identifierDrawer = identifierDrawer; _codeService = codeService; + _config = config; _designCombo = new DesignCombo(_manager, designs); _jobGroupCombo = new JobGroupCombo(manager, jobs); } @@ -105,7 +107,7 @@ public class SetPanel ImGui.TableSetupColumn("Design", ImGuiTableColumnFlags.WidthFixed, 220 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Application", ImGuiTableColumnFlags.WidthFixed, 5 * ImGui.GetFrameHeight() + 4 * 2 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Job Restrictions", ImGuiTableColumnFlags.WidthStretch); - ImGui.TableSetupColumn("Warnings", ImGuiTableColumnFlags.WidthFixed, 4 * ImGui.GetFrameHeight() + 3 * 2 * ImGuiHelpers.GlobalScale); + ImGui.TableSetupColumn("Warnings", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Warnings").X); ImGui.TableHeadersRow(); foreach (var (design, idx) in Selection.Designs.WithIndex()) @@ -159,7 +161,7 @@ public class SetPanel var item = design.Design.DesignData.Item(slot); if (!_itemUnlocks.IsUnlocked(item.ItemId, out _)) - sb.AppendLine($"{item.Name} in {slot.ToName()} slot is not unlocked but should be applied."); + sb.AppendLine($"{item.Name} in {slot.ToName()} slot is not unlocked. Consider obtaining it via gameplay means!"); } using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(2 * ImGuiHelpers.GlobalScale, 0)); @@ -185,10 +187,10 @@ public class SetPanel } } - var tt = _codeService.EnabledInventory - ? "\nThese items will still be applied, because you have enabled a cheat code." - : $"\nThese items will be skipped when applied automatically.\n\nTo change this, enable the \"{CodeService.CodeInventoryString}\" Cheat Code in Settings."; - DrawWarning(sb, !_codeService.EnabledInventory ? 0xA03030F0 : 0x0, size, tt, "All equipment to be applied is unlocked."); + var tt = _config.UnlockedItemMode + ? "\nThese items will be skipped when applied automatically.\n\nTo change this, disable the Obtained Item Mode setting." + : string.Empty; + DrawWarning(sb, _config.UnlockedItemMode ? 0xA03030F0 : 0x0, size, tt, "All equipment to be applied is unlocked."); sb.Clear(); var sb2 = new StringBuilder(); @@ -213,17 +215,11 @@ public class SetPanel } ImGui.SameLine(); - tt = _codeService.EnabledInventory - ? "\nThese customizations will still be applied, because you have enabled a cheat code." - : $"\nThese customizations will be skipped when applied automatically.\n\nTo change this, enable the \"{CodeService.CodeInventoryString}\" Cheat Code in Settings."; - DrawWarning(sb2, !_codeService.EnabledInventory ? 0xA03030F0 : 0x0, size, tt, "All customizations to be applied are unlocked."); + tt = _config.UnlockedItemMode + ? "\nThese customizations will be skipped when applied automatically.\n\nTo change this, disable the Obtained Item Mode setting." + : string.Empty; + DrawWarning(sb2, _config.UnlockedItemMode ? 0xA03030F0 : 0x0, size, tt, "All customizations to be applied are unlocked."); ImGui.SameLine(); - - tt = _codeService.EnabledMesmer - ? "\nThese customizations will still be applied, because you have enabled a cheat code." - : $"\nThese customizations will be skipped when applied automatically.\n\nTo change this, enable the \"{CodeService.CodeMesmerString}\" Cheat Code in Settings."; - DrawWarning(sb, !_codeService.EnabledMesmer ? 0xA03030F0 : 0x0, size, tt, - "No customizations unable to be applied automatically are set to be applied."); // TODO } private void DrawDragDrop(AutoDesignSet set, int index) diff --git a/Glamourer/Gui/Tabs/SettingsTab.cs b/Glamourer/Gui/Tabs/SettingsTab.cs index e2542e1..c4cf5cb 100644 --- a/Glamourer/Gui/Tabs/SettingsTab.cs +++ b/Glamourer/Gui/Tabs/SettingsTab.cs @@ -50,6 +50,9 @@ public class SettingsTab : ITab Checkbox("Restricted Gear Protection", "Use gender- and race-appropriate models when detecting certain items not available for a characters current gender and race.", _config.UseRestrictedGearProtection, v => _config.UseRestrictedGearProtection = v); + Checkbox("Unlocked Item Mode", + "Enable this if you want automatically applied designs to only consider items and customizations you have actually unlocked once, and skip those you have not.", + _config.UnlockedItemMode, v => _config.UnlockedItemMode = v); Checkbox("Auto-Reload Gear", "Automatically reload equipment pieces on your own character when changing any mod options in Penumbra in their associated collection.", _config.AutoRedrawEquipOnChanges, _autoRedraw.SetState); diff --git a/Glamourer/Services/CodeService.cs b/Glamourer/Services/CodeService.cs index 49c1531..af94ab0 100644 --- a/Glamourer/Services/CodeService.cs +++ b/Glamourer/Services/CodeService.cs @@ -23,10 +23,8 @@ public class CodeService public bool EnabledEmperor { get; private set; } public bool EnabledIndividual { get; private set; } public Sizing EnabledSizing { get; private set; } - public Race EnabledOops { get; private set; } - public bool EnabledMesmer { get; private set; } - public bool EnabledInventory { get; private set; } - public bool EnabledArtisan { get; private set; } + public Race EnabledOops { get; private set; } + public bool EnabledArtisan { get; private set; } public CodeService(Configuration config) { @@ -42,8 +40,7 @@ public class CodeService var enabled = CheckCode(_config.Codes[i].Code); if (enabled == null) { - --i; - _config.Codes.RemoveAt(i); + _config.Codes.RemoveAt(i--); changes = true; } else @@ -64,7 +61,6 @@ public class CodeService _config.Codes.Add((name, false)); _config.Save(); return true; - } public Action? CheckCode(string name) @@ -78,7 +74,6 @@ public class CodeService _ when CodeIndividual.SequenceEqual(sha) => v => EnabledIndividual = v, _ when CodeDwarf.SequenceEqual(sha) => v => EnabledSizing = v ? Sizing.Dwarf : Sizing.None, _ when CodeGiant.SequenceEqual(sha) => v => EnabledSizing = v ? Sizing.Giant : Sizing.None, - _ when CodeMesmer.SequenceEqual(sha) => v => EnabledMesmer = v, _ when CodeOops1.SequenceEqual(sha) => v => EnabledOops = v ? Race.Hyur : Race.Unknown, _ when CodeOops2.SequenceEqual(sha) => v => EnabledOops = v ? Race.Elezen : Race.Unknown, _ when CodeOops3.SequenceEqual(sha) => v => EnabledOops = v ? Race.Lalafell : Race.Unknown, @@ -87,22 +82,17 @@ public class CodeService _ when CodeOops6.SequenceEqual(sha) => v => EnabledOops = v ? Race.AuRa : Race.Unknown, _ when CodeOops7.SequenceEqual(sha) => v => EnabledOops = v ? Race.Hrothgar : Race.Unknown, _ when CodeOops8.SequenceEqual(sha) => v => EnabledOops = v ? Race.Viera : Race.Unknown, - _ when CodeInventory.SequenceEqual(sha) => v => EnabledInventory = v, _ when CodeArtisan.SequenceEqual(sha) => v => EnabledArtisan = v, _ => null, }; } - public const string CodeInventoryString = "I found this secret cheat code and all I got was all the lousy t-shirts."; - public const string CodeMesmerString = "With the power of cheats, you can be anything you want!"; - // @formatter:off private static ReadOnlySpan CodeClown => new byte[] { 0xC4, 0xEE, 0x1D, 0x6F, 0xC5, 0x5D, 0x47, 0xBE, 0x78, 0x63, 0x66, 0x86, 0x81, 0x15, 0xEB, 0xFA, 0xF6, 0x4A, 0x90, 0xEA, 0xC0, 0xE4, 0xEE, 0x86, 0x69, 0x01, 0x8E, 0xDB, 0xCC, 0x69, 0xD1, 0xBD }; private static ReadOnlySpan CodeEmperor => new byte[] { 0xE2, 0x2D, 0x3E, 0x57, 0x16, 0x82, 0x65, 0x98, 0x7E, 0xE6, 0x8F, 0x45, 0x14, 0x7D, 0x65, 0x31, 0xE9, 0xD8, 0xDB, 0xEA, 0xDC, 0xBF, 0xEE, 0x2A, 0xBA, 0xD5, 0x69, 0x96, 0x78, 0x34, 0x3B, 0x57 }; private static ReadOnlySpan CodeIndividual => new byte[] { 0x95, 0xA4, 0x71, 0xAC, 0xA3, 0xC2, 0x34, 0x94, 0xC1, 0x65, 0x07, 0xF3, 0x7F, 0x93, 0x57, 0xEE, 0xE3, 0x04, 0xC0, 0xE8, 0x1B, 0xA0, 0xE2, 0x08, 0x68, 0x02, 0x8D, 0xAD, 0x76, 0x03, 0x9B, 0xC5 }; private static ReadOnlySpan CodeDwarf => new byte[] { 0x55, 0x97, 0xFE, 0xE9, 0x78, 0x64, 0xE8, 0x2F, 0xCD, 0x25, 0xD1, 0xAE, 0xDF, 0x35, 0xE6, 0xED, 0x03, 0x78, 0x54, 0x1D, 0x56, 0x22, 0x34, 0x75, 0x4B, 0x96, 0x6F, 0xBA, 0xAC, 0xEC, 0x00, 0x46 }; private static ReadOnlySpan CodeGiant => new byte[] { 0x6E, 0xBB, 0x91, 0x1D, 0x67, 0xE3, 0x00, 0x07, 0xA1, 0x0F, 0x2A, 0xF0, 0x26, 0x91, 0x38, 0x63, 0xD3, 0x52, 0x82, 0xF7, 0x5D, 0x93, 0xE8, 0x83, 0xB1, 0xF6, 0xB9, 0x69, 0x78, 0x20, 0xC4, 0xCE }; - private static ReadOnlySpan CodeMesmer => new byte[] { 0x6A, 0x84, 0x12, 0xEA, 0x3B, 0x03, 0x2E, 0xD9, 0xA3, 0x51, 0xB0, 0x4F, 0xE7, 0x4D, 0x59, 0x87, 0xA9, 0xA1, 0x6E, 0x08, 0xC7, 0x3E, 0xD3, 0x15, 0xEE, 0x40, 0x2C, 0xB3, 0x44, 0x78, 0x1F, 0xA0 }; private static ReadOnlySpan CodeOops1 => new byte[] { 0x4C, 0x51, 0xE2, 0x38, 0xEF, 0xAD, 0x84, 0x0E, 0x4E, 0x11, 0x0F, 0x5E, 0xDE, 0x45, 0x41, 0x9F, 0x6A, 0xF6, 0x5F, 0x5B, 0xA8, 0x91, 0x64, 0x22, 0xEE, 0x62, 0x97, 0x3C, 0x78, 0x18, 0xCD, 0xAF }; private static ReadOnlySpan CodeOops2 => new byte[] { 0x3D, 0x5B, 0xA9, 0x62, 0xCE, 0xBE, 0x52, 0xF5, 0x94, 0x2A, 0xF9, 0xB7, 0xCF, 0xD9, 0x24, 0x2B, 0x38, 0xC7, 0x4F, 0x28, 0x97, 0x29, 0x1D, 0x01, 0x13, 0x53, 0x44, 0x11, 0x15, 0x6F, 0x9B, 0x56 }; private static ReadOnlySpan CodeOops3 => new byte[] { 0x85, 0x8D, 0x5B, 0xC2, 0x66, 0x53, 0x2E, 0xB9, 0xE9, 0x85, 0xE5, 0xF8, 0xD3, 0x75, 0x18, 0x7C, 0x58, 0x55, 0xD4, 0x8C, 0x8E, 0x5F, 0x58, 0x2E, 0xF3, 0xF1, 0xAE, 0xA8, 0xA0, 0x81, 0xC6, 0x0E }; @@ -111,7 +101,6 @@ public class CodeService private static ReadOnlySpan CodeOops6 => new byte[] { 0x69, 0x93, 0xAF, 0xE4, 0xB8, 0xEC, 0x5F, 0x40, 0xEB, 0x8A, 0x6F, 0xD1, 0x9B, 0xD9, 0x56, 0x0B, 0xEA, 0x64, 0x79, 0x9B, 0x54, 0xA1, 0x41, 0xED, 0xBC, 0x3E, 0x6E, 0x5C, 0xF1, 0x23, 0x60, 0xF8 }; private static ReadOnlySpan CodeOops7 => new byte[] { 0x41, 0xEC, 0x65, 0x05, 0x8D, 0x20, 0x68, 0x5A, 0xB7, 0xEB, 0x92, 0x15, 0x43, 0xCF, 0x15, 0x05, 0x27, 0x51, 0xFE, 0x20, 0xC9, 0xB6, 0x2B, 0x84, 0xD9, 0x6A, 0x49, 0x5A, 0x5B, 0x7F, 0x2E, 0xE7 }; private static ReadOnlySpan CodeOops8 => new byte[] { 0x16, 0xFF, 0x63, 0x85, 0x1C, 0xF5, 0x34, 0x33, 0x67, 0x8C, 0x46, 0x8E, 0x3E, 0xE3, 0xA6, 0x94, 0xF9, 0x74, 0x47, 0xAA, 0xC7, 0x29, 0x59, 0x1F, 0x6C, 0x6E, 0xF2, 0xF5, 0x87, 0x24, 0x9E, 0x2B }; - private static ReadOnlySpan CodeInventory => new byte[] { 0xD1, 0x35, 0xD7, 0x18, 0xBE, 0x45, 0x42, 0xBD, 0x88, 0x77, 0x7E, 0xC4, 0x41, 0x06, 0x34, 0x4D, 0x71, 0x3A, 0xC5, 0xCC, 0xA4, 0x1B, 0x7D, 0x3F, 0x3B, 0x86, 0x07, 0xCB, 0x63, 0xD7, 0xF9, 0xDB }; private static ReadOnlySpan CodeArtisan => new byte[] { 0xDE, 0x01, 0x32, 0x1E, 0x7F, 0x22, 0x80, 0x3D, 0x76, 0xDF, 0x74, 0x0E, 0xEC, 0x33, 0xD3, 0xF4, 0x1A, 0x98, 0x9E, 0x9D, 0x22, 0x5C, 0xAC, 0x3B, 0xFE, 0x0B, 0xC2, 0x13, 0xB9, 0x91, 0x24, 0x61 }; // @formatter:on } diff --git a/GlamourerTest.zip b/GlamourerTest.zip index d57e835..f41961c 100644 Binary files a/GlamourerTest.zip and b/GlamourerTest.zip differ diff --git a/repo.json b/repo.json index 1a910f0..5e40415 100644 --- a/repo.json +++ b/repo.json @@ -7,7 +7,7 @@ "Tags": [ "Appearance", "Glamour", "Race", "Outfit", "Armor", "Clothes", "Skins", "Customization", "Design", "Character" ], "InternalName": "Glamourer", "AssemblyVersion": "0.1.3.1", - "TestingAssemblyVersion": "0.2.0.4", + "TestingAssemblyVersion": "0.2.0.5", "RepoUrl": "https://github.com/Ottermandias/Glamourer", "ApplicableVersion": "any", "DalamudApiLevel": 8,