diff --git a/.luacheckrc b/.luacheckrc index 7305f9d..aec5f7a 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -100,6 +100,7 @@ stds.wow = { "ClearAllPendingSituations", "ClearAllPendingTransmogs", "CommitAndApplyAllPending", + "GetItemModifiedAppearanceEffectiveCategory", }, }, @@ -579,6 +580,12 @@ stds.wow = { }, }, + Transmog = { + fields = { + "NoTransmogID", + }, + }, + TransmogOutfitDataConsts = { fields = { "EQUIP_TRANSMOG_OUTFIT_MANUAL_SPELL_ID", @@ -979,6 +986,7 @@ stds.wow = { C_PaperDollInfo = { fields = { "CanCursorCanGoInSlot", + "IsRangedSlotShown", }, }, @@ -1612,6 +1620,12 @@ stds.wow = { }, }, + TransmogOutfitSlotWarning = { + fields = { + "WeaponDoesNotSupportIllusions", + }, + }, + TransmogPendingType = { fields = { "Apply", @@ -1707,6 +1721,12 @@ stds.wow = { }, }, + ItemUtil = { + fields = { + "CreateItemTransmogInfo", + }, + }, + Menu = { fields = { "ModifyMenu", diff --git a/Initialization.lua b/Initialization.lua index 6d3ee60..96add87 100644 --- a/Initialization.lua +++ b/Initialization.lua @@ -247,7 +247,7 @@ local DefaultValues = { HuntTable = true, --Replace generic quest icons with difficulties and add achievement indicators. PreyQuestSuperTrack = true, --During the final stage, clicking the Prey widget also super track the target location. TransmogRaestorePending = true, --Restore unsaved transmog changes - + TransmogRaestorePending_AlwaysMoveChanges = false, --Tooltip TooltipChestKeys = true, --Show keys that unlocked the current chest or door diff --git a/Locales/deDE.lua b/Locales/deDE.lua index 746ab81..15f5f42 100644 --- a/Locales/deDE.lua +++ b/Locales/deDE.lua @@ -702,6 +702,18 @@ L["Missing Appearances Format"] = "%d |4Vorlage:Vorlagen fehlen;"; L["Press Key To Copy Format"] = "Zum Kopieren auf die |cffffd100%s|r-Taste drücken"; +--TransmogRaestorePending +L["ModuleName TransmogRaestorePending"] = "Transmog-UI: Ausstehende Änderungen wiederherstellen"; +L["ModuleDescription TransmogRaestorePending"] = "Ausstehende Transmog-Änderungen werden automatisch wiederhergestellt, wenn Ihr das Fenster erneut öffnet.\n\nAusstehende Änderungen können auf ein anderes Outfit übertragen werden."; +L["Outfit Popup Warning"] = "Das aktuelle Outfit hat ausstehende Änderungen.\n\nMöchtet Ihr diese Änderungen auf das neue Outfit übertragen oder verwerfen?"; +L["Outfit Popup Move Changes"] = "Übertragen"; +L["Outfit Popup Move Changes Tooltip"] = "Überträgt die ausstehenden Änderungen auf das neu ausgewählte Outfit."; +L["Outfit Popup Always Move Changes Over"] = "Änderungen immer übertragen"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "Überträgt die ausstehenden Änderungen immer auf das neu ausgewählte Outfit.\n\nDieses Fenster wird nicht mehr angezeigt."; +L["Outfit Popup Discard Changes"] = "Verwerfen"; +L["Outfit Popup Discard Changes Tooltip"] = "Verwirft die ausstehenden Änderungen."; + + --QuestWatchCycle L["ModuleName QuestWatchCycle"] = "Tastenkürzel: Auf ein Quest focussieren"; L["ModuleDescription QuestWatchCycle"] = "Per Tastendruck kann man das vorherige oder nächste Quest im Questzielverfolgungs-Menü auswählen und verfolgen.\n\n|cffd4641cDas Tastenkürzel kann unter \'Optionen> Tastaturbelegung>Plumber Addon\' festgelegt werden.|r"; diff --git a/Locales/enUS.lua b/Locales/enUS.lua index 3082e0c..df3bf04 100755 --- a/Locales/enUS.lua +++ b/Locales/enUS.lua @@ -807,7 +807,14 @@ L["Quick Access Outfit Button Tooltip"] = "Click and drag this button to your ac --TransmogRaestorePending L["ModuleName TransmogRaestorePending"] = "Transmog UI: Restore Pending Changes"; -L["ModuleDescription TransmogRaestorePending"] = "Pending Transmog changes are automatically restored when reopening the window."; +L["ModuleDescription TransmogRaestorePending"] = "Pending Transmog changes are automatically restored when reopening the window.\n\nPending changes can be moved over to another outfit."; +L["Outfit Popup Warning"] = "The current outfit has pending changes.\n\nDo you wish to move these changes over to the new outfit or discard them?"; +L["Outfit Popup Move Changes"] = "Move"; +L["Outfit Popup Move Changes Tooltip"] = "Move the pending changes over to the newly selected outfit."; +L["Outfit Popup Always Move Changes Over"] = "Always Move Changes Over"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "Always move the pending changes to the newly selected outfit.\n\nYou will stop seeing this popup window."; +L["Outfit Popup Discard Changes"] = "Discard"; +L["Outfit Popup Discard Changes Tooltip"] = "Discard the pending changes."; --QuestWatchCycle diff --git a/Locales/esES.lua b/Locales/esES.lua index 23ec13e..f249315 100644 --- a/Locales/esES.lua +++ b/Locales/esES.lua @@ -762,6 +762,18 @@ L["Quick Access Outfit Button"] = "Acceso rápido"; L["Quick Access Outfit Button Tooltip"] = "Haz click y arrastra este botón a tus barras de acción para poder cambiar de atuendo en cualquier lugar."; +--TransmogRaestorePending +L["ModuleName TransmogRaestorePending"] = "Interfaz de transfiguración: restaurar cambios pendientes"; +L["ModuleDescription TransmogRaestorePending"] = "Los cambios de transfiguración pendientes se restauran automáticamente al volver a abrir la ventana.\n\nLos cambios pendientes se pueden trasladar a otro atuendo."; +L["Outfit Popup Warning"] = "El atuendo actual tiene cambios pendientes.\n\n¿Deseas trasladar estos cambios al nuevo atuendo o descartarlos?"; +L["Outfit Popup Move Changes"] = "Trasladar"; +L["Outfit Popup Move Changes Tooltip"] = "Traslada los cambios pendientes al atuendo recién seleccionado."; +L["Outfit Popup Always Move Changes Over"] = "Trasladar Siempre los Cambios"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "Traslada siempre los cambios pendientes al atuendo recién seleccionado.\n\nDejarás de ver esta ventana emergente."; +L["Outfit Popup Discard Changes"] = "Descartar"; +L["Outfit Popup Discard Changes Tooltip"] = "Descarta los cambios pendientes."; + + --QuestWatchCycle L["ModuleName QuestWatchCycle"] = "Atajos de teclado: Centrarse en la misión"; L["ModuleDescription QuestWatchCycle"] = "Te permite presionar teclas de acceso rápido para centrarse en la siguiente/anterior misión en el rastreador de objetivos.\n\n|cffd4641cConfigura tus teclas de acceso rápido en Opciones/Atajos de teclado/Plumber.|r"; diff --git a/Locales/frFR.lua b/Locales/frFR.lua index 6fa6add..7e4e608 100644 --- a/Locales/frFR.lua +++ b/Locales/frFR.lua @@ -805,6 +805,18 @@ L["Quick Access Outfit Button"] = "Accès rapide"; L["Quick Access Outfit Button Tooltip"] = "Cliquez sur ce bouton et faites-le glisser vers vos barres d'action afin de pouvoir changer de tenue où que vous soyez."; +--TransmogRaestorePending +L["ModuleName TransmogRaestorePending"] = "Interface de transmogrification : restaurer les modifications en attente"; +L["ModuleDescription TransmogRaestorePending"] = "Les modifications de transmogrification en attente sont automatiquement restaurées lorsque vous rouvrez la fenêtre.\n\nLes modifications en attente peuvent être transférées vers une autre tenue."; +L["Outfit Popup Warning"] = "La tenue actuelle comporte des modifications en attente.\n\nSouhaitez-vous transférer ces modifications vers la nouvelle tenue ou les abandonner ?"; +L["Outfit Popup Move Changes"] = "Transférer"; +L["Outfit Popup Move Changes Tooltip"] = "Transfère les modifications en attente vers la tenue nouvellement sélectionnée."; +L["Outfit Popup Always Move Changes Over"] = "Toujours transférer les modifications"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "Transfère toujours les modifications en attente vers la tenue nouvellement sélectionnée.\n\nCette fenêtre ne s'affichera plus."; +L["Outfit Popup Discard Changes"] = "Abandonner"; +L["Outfit Popup Discard Changes Tooltip"] = "Abandonne les modifications en attente."; + + --QuestWatchCycle L["ModuleName QuestWatchCycle"] = "Raccourcis clavier : focalisation sur la quête"; L["ModuleDescription QuestWatchCycle"] = "Permet d'utiliser des raccourcis clavier pour passer à la quête suivante/précédente dans le suivi des objectifs.\n\n|cffd4641cConfigurer vos raccourcis clavier dans Raccourcis clavier > Plumber.|r"; diff --git a/Locales/koKR.lua b/Locales/koKR.lua index d2a6251..b3831b5 100644 --- a/Locales/koKR.lua +++ b/Locales/koKR.lua @@ -805,6 +805,18 @@ L["Quick Access Outfit Button"] = "빠른 접근"; L["Quick Access Outfit Button Tooltip"] = "의상을 어디서나 변경할 수 있도록 이 버튼을 행동 단축바로 클릭하여 드래그하세요."; +--TransmogRaestorePending +L["ModuleName TransmogRaestorePending"] = "형상변환 UI: 대기 중인 변경 사항 복원"; +L["ModuleDescription TransmogRaestorePending"] = "형상변환 창을 다시 열면 대기 중인 변경 사항이 자동으로 복원됩니다.\n\n대기 중인 변경 사항을 다른 의상으로 옮길 수 있습니다."; +L["Outfit Popup Warning"] = "현재 의상에 대기 중인 변경 사항이 있습니다.\n\n이 변경 사항을 새 의상으로 옮기시겠습니까, 아니면 폐기하시겠습니까?"; +L["Outfit Popup Move Changes"] = "이동"; +L["Outfit Popup Move Changes Tooltip"] = "대기 중인 변경 사항을 새로 선택한 의상으로 옮깁니다."; +L["Outfit Popup Always Move Changes Over"] = "항상 변경 사항 이동"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "대기 중인 변경 사항을 항상 새로 선택한 의상으로 옮깁니다.\n\n이 창이 더 이상 표시되지 않습니다."; +L["Outfit Popup Discard Changes"] = "폐기"; +L["Outfit Popup Discard Changes Tooltip"] = "대기 중인 변경 사항을 폐기합니다."; + + --QuestWatchCycle L["ModuleName QuestWatchCycle"] = "단축키: 퀘스트 추적 대상 지정"; L["ModuleDescription QuestWatchCycle"] = "단축키를 눌러 목표 추적기에서 다음/이전 퀘스트를 대상으로 지정할 수 있습니다.\n\n|cffd4641c단축키 설정은 단축키 > Plumber 애드온에서 하세요.|r"; diff --git a/Locales/ptBR.lua b/Locales/ptBR.lua index aab0e30..70a4574 100644 --- a/Locales/ptBR.lua +++ b/Locales/ptBR.lua @@ -807,7 +807,14 @@ L["Quick Access Outfit Button Tooltip"] = "Clique e arraste este botão para sua --TransmogRaestorePending L["ModuleName TransmogRaestorePending"] = "Transmogrificação: Restaurar alterações"; -L["ModuleDescription TransmogRaestorePending"] = "As alterações de transmogrificação pendentes são automaticamente restauradas ao reabrir a janela."; +L["ModuleDescription TransmogRaestorePending"] = "As alterações de transmogrificação pendentes são automaticamente restauradas ao reabrir a janela.\n\nAs alterações pendentes podem ser movidas para outra roupa."; +L["Outfit Popup Warning"] = "A roupa atual possui alterações pendentes.\n\nDeseja mover essas alterações para a nova roupa ou descartá-las?"; +L["Outfit Popup Move Changes"] = "Mover"; +L["Outfit Popup Move Changes Tooltip"] = "Move as alterações pendentes para a roupa recém-selecionada."; +L["Outfit Popup Always Move Changes Over"] = "Sempre Mover as Alterações"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "Sempre move as alterações pendentes para a roupa recém-selecionada.\n\nVocê não verá mais esta janela."; +L["Outfit Popup Discard Changes"] = "Descartar"; +L["Outfit Popup Discard Changes Tooltip"] = "Descarta as alterações pendentes."; --QuestWatchCycle diff --git a/Locales/ruRU.lua b/Locales/ruRU.lua index 437b6cc..4f52611 100644 --- a/Locales/ruRU.lua +++ b/Locales/ruRU.lua @@ -805,6 +805,18 @@ L["Quick Access Outfit Button"] = "Быстрый доступ"; L["Quick Access Outfit Button Tooltip"] = "Нажмите и перетащите эту кнопку на панель действий, чтобы менять образы в любом месте."; +--TransmogRaestorePending +L["ModuleName TransmogRaestorePending"] = "Интерфейс трансмогрификации: восстановление несохранённых изменений"; +L["ModuleDescription TransmogRaestorePending"] = "Несохранённые изменения трансмогрификации автоматически восстанавливаются при повторном открытии окна.\n\nНесохранённые изменения можно перенести на другой образ."; +L["Outfit Popup Warning"] = "В текущем образе есть несохранённые изменения.\n\nХотите перенести эти изменения на новый образ или отклонить их?"; +L["Outfit Popup Move Changes"] = "Перенести"; +L["Outfit Popup Move Changes Tooltip"] = "Переносит несохранённые изменения на новый выбранный образ."; +L["Outfit Popup Always Move Changes Over"] = "Всегда переносить изменения"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "Всегда переносит несохранённые изменения на новый выбранный образ.\n\nЭто окно больше не будет отображаться."; +L["Outfit Popup Discard Changes"] = "Отклонить"; +L["Outfit Popup Discard Changes Tooltip"] = "Отклоняет несохранённые изменения."; + + --QuestWatchCycle L["ModuleName QuestWatchCycle"] = "Клавиши: Фокус на задание"; L["ModuleDescription QuestWatchCycle"] = "Позволяет использовать горячие клавиши для фокусировки на следующем/предыдущем задании в трекере целей.\n\n|cffd4641cНастройте горячие клавиши в Привязки клавиш > Аддона Plumber.|r"; diff --git a/Locales/zhCN.lua b/Locales/zhCN.lua index 1b78b39..d55c0bb 100755 --- a/Locales/zhCN.lua +++ b/Locales/zhCN.lua @@ -775,7 +775,14 @@ L["Quick Access Outfit Button Tooltip"] = "点击并拖动此按钮到技能栏 --TransmogRaestorePending L["ModuleName TransmogRaestorePending"] = "幻化界面: 恢复未保存的改动"; -L["ModuleDescription TransmogRaestorePending"] = "未保存的改动将在你重新打开幻化界面时自动恢复。"; +L["ModuleDescription TransmogRaestorePending"] = "未保存的改动将在你重新打开幻化界面时自动恢复。\n\n未保存的改动可以转移至另一个外观方案。"; +L["Outfit Popup Warning"] = "当前外观方案有未保存的改动。\n\n你想将这些改动转移至新的外观方案,还是要舍弃它们?"; +L["Outfit Popup Move Changes"] = "转移"; +L["Outfit Popup Move Changes Tooltip"] = "将未保存的改动转移至新选择的外观方案。"; +L["Outfit Popup Always Move Changes Over"] = "永远转移改动"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "永远将未保存的改动转移至新选择的外观方案。\n\n你将不会再看到这个弹出窗口。"; +L["Outfit Popup Discard Changes"] = "舍弃"; +L["Outfit Popup Discard Changes Tooltip"] = "舍弃未保存的改动。"; --QuestWatchCycle diff --git a/Locales/zhTW.lua b/Locales/zhTW.lua index aaf33bb..e5064b0 100755 --- a/Locales/zhTW.lua +++ b/Locales/zhTW.lua @@ -715,6 +715,18 @@ L["Quick Access Outfit Button"] = "快捷訪問"; L["Quick Access Outfit Button Tooltip"] = "點擊並拖動此按鈕到技能欄上,以便隨時隨地訪問外觀列表。"; +--TransmogRaestorePending +L["ModuleName TransmogRaestorePending"] = "塑形介面:恢復未保存的改動"; +L["ModuleDescription TransmogRaestorePending"] = "未保存的改動將在你重新開啟塑形介面時自動恢復。\n\n未保存的改動可以轉移至另一個外觀方案。"; +L["Outfit Popup Warning"] = "當前外觀方案有未保存的改動。\n\n你想將這些改動轉移至新的外觀方案,還是要捨棄它們?"; +L["Outfit Popup Move Changes"] = "轉移"; +L["Outfit Popup Move Changes Tooltip"] = "將未保存的改動轉移至新選擇的外觀方案。"; +L["Outfit Popup Always Move Changes Over"] = "永遠轉移改動"; +L["Outfit Popup Always Move Changes Over Tooltip"] = "永遠將未保存的改動轉移至新選擇的外觀方案。\n\n你將不會再看到這個彈出視窗。"; +L["Outfit Popup Discard Changes"] = "捨棄"; +L["Outfit Popup Discard Changes Tooltip"] = "捨棄未保存的改動。"; + + --QuestWatchCycle L["ModuleName QuestWatchCycle"] = "快捷鍵:任務焦點"; L["ModuleDescription QuestWatchCycle"] = "允許你設定快捷鍵來聚焦下一個或上一個任務。\n\n|cffd4641c請前往以下位置設定按鍵:遊戲設定> 快捷鍵> Plumber 插件.|r"; diff --git a/Modules/Shared/SharedEditMode.lua b/Modules/Shared/SharedEditMode.lua index 02109c2..5d50d82 100644 --- a/Modules/Shared/SharedEditMode.lua +++ b/Modules/Shared/SharedEditMode.lua @@ -299,9 +299,8 @@ do --EditModeSettingsDialog checkbox.useWhiteLabel = true; checkbox:SetData(widgetData); - checkbox:SetChecked(addon.GetDBValue(checkbox.dbKey)); - return checkbox + return checkbox; end function EditModeSettingsDialogMixin:CreateSlider(widgetData) diff --git a/Modules/Shared/SharedWidgets.lua b/Modules/Shared/SharedWidgets.lua index d1d29ee..72d459b 100644 --- a/Modules/Shared/SharedWidgets.lua +++ b/Modules/Shared/SharedWidgets.lua @@ -351,7 +351,7 @@ do -- Checkbox local newState; if self.dbKey then - newState = not addon.GetDBValue(self.dbKey) + newState = not addon.GetDBBool(self.dbKey) addon.SetDBValue(self.dbKey, newState, true); self:SetChecked(newState); else @@ -405,6 +405,12 @@ do -- Checkbox self.checked = state; end + function CheckboxMixin:UpdateChecked() + if self.dbKey then + self:SetChecked(addon.GetDBBool(self.dbKey)); + end + end + function CheckboxMixin:SetFixedWidth(width) self.fixedWidth = width; self:SetWidth(width); @@ -454,6 +460,8 @@ do -- Checkbox self.parentDBKey = data.parentDBKey; self.shouldEnableOption = data.shouldEnableOption; + self:UpdateChecked(); + if data.label then return self:SetLabel(data.label) else diff --git a/Modules/Shared/SharedWidgets_StaticPopup.lua b/Modules/Shared/SharedWidgets_StaticPopup.lua index d4c6779..a7031c8 100644 --- a/Modules/Shared/SharedWidgets_StaticPopup.lua +++ b/Modules/Shared/SharedWidgets_StaticPopup.lua @@ -74,6 +74,9 @@ do function StaticPopupMixin:OnHide() PlaySound(SOUNDKIT.IG_MAINMENU_CLOSE); StaticPopup_Hide(WHICH_DUMMY, self.data); + if self.onHideCallback then + self.onHideCallback(self); + end end function StaticPopupMixin:OnLoad() @@ -159,6 +162,9 @@ do end function StaticPopupMixin:Setup(popupInfo) + self.identifier = popupInfo.identifier; + self.onHideCallback = popupInfo.onHideFunc; + self:ReleaseAllWidgets(); if popupInfo.text then @@ -176,7 +182,7 @@ do local button = self.uiPanelButtonPool:Acquire(); button:SetWidth(120); button:SetText(v.label); - button.onEnterFunc = v.onClickFunc; + button.onEnterFunc = v.onEnterFunc; button.onLeaveFunc = v.onLeaveFunc; button.onEnterCallback = function(f) @@ -202,7 +208,16 @@ do button.onLeaveCallback = v.onLeaveFunc; if v.onClickFunc then - button:SetScript("OnClick", v.onClickFunc); + button:SetScript("OnClick", function(f, mouseButton) + v.onClickFunc(f, mouseButton); + if v.closePopup then + self:Hide(); + end + end); + elseif v.closePopup then + button:SetScript("OnClick", function() + self:Hide(); + end); else button:SetScript("OnClick", nil); end @@ -372,6 +387,8 @@ local function ShowClipboard(text, copySuccessMessage) MainFrame:ClearAllPoints(); MainFrame:ReleaseAllWidgets(); + MainFrame.identifier = "clipboard"; + MainFrame.onHideCallback = nil; MainFrame.EditBox:Show(); MainFrame.EditBox:SetDefaultText(text); @@ -415,3 +432,13 @@ local function ShowCustomPopup(popupInfo) StaticPopup_Show(WHICH_DUMMY, nil, nil, nil, MainFrame); end addon.ShowCustomPopup = ShowCustomPopup; + + +local function HideCustomPopup(identifier) + if MainFrame then + if (not identifier) or (MainFrame.identifier == identifier) then + StaticPopup_Hide(WHICH_DUMMY); + end + end +end +addon.HideCustomPopup = HideCustomPopup; diff --git a/Modules/TransmogRestorePending.lua b/Modules/TransmogRestorePending.lua index 6d5ac3f..9df4a10 100644 --- a/Modules/TransmogRestorePending.lua +++ b/Modules/TransmogRestorePending.lua @@ -3,6 +3,8 @@ local L = addon.L; local API = addon.API; local EL = CreateFrame("Frame"); +local DBKEY_ALWAYS_MOVE_CHANGED = "TransmogRaestorePending_AlwaysMoveChanges"; +local POPUP_IDENTIFIER = "transmogPendingChanges"; local SHOULDER_RIGHT = Enum.TransmogOutfitSlot.ShoulderRight; local WEAPON_SLOTS = { [16] = Enum.TransmogOutfitSlot.WeaponMainHand, @@ -220,14 +222,6 @@ do end end - function EL.ForceWeaponSlotWidgetRebuild() - --Toggling shoulder secondary state forces a weapon slot widget rebuild, working around a Blizzard display - --bug where the widget caches the wrong option (e.g. 1H for an equipped 2H) on first build. Must run first. - local liveSecondary = C_TransmogOutfitInfo.GetSecondarySlotState(SHOULDER_RIGHT); - C_TransmogOutfitInfo.SetSecondarySlotState(SHOULDER_RIGHT, not liveSecondary); - C_TransmogOutfitInfo.SetSecondarySlotState(SHOULDER_RIGHT, liveSecondary); - end - --Save all situations-related data (4 id fields) in one string, making it a simple per line row for SavedVariables. local function SituationOptionKey(option) return string.format("%d,%d,%d,%d", option.situationID, option.specID, option.loadoutID, option.equipmentSetID); @@ -339,6 +333,20 @@ do end EL.SavePendingToDB = SavePendingToDB; + function EL.WipePendingAppearanceFromDB(includeSituations, includeLastViewedOutfitID) + EL.PendingSnapshot = nil; + EL.PendingSlots = nil; + EL.PendingShoulderSecondary = nil; + EL.PendingWeaponOptions = nil; + if includeSituations then + EL.PendingSituations = nil; + end + if includeLastViewedOutfitID then + EL.LastViewedOutfitID = nil; + end + EL.SavePendingToDB(); + end + function EL.LoadPendingFromDB() EL.LastViewedOutfitID = PlumberDB_PC and PlumberDB_PC.TransmogRestoreLastOutfit; @@ -361,7 +369,7 @@ do local isRestoringPending = false; local function CapturePending() - if not EL.enabled or isRestoringPending then return end; + if not EL.enabled or isRestoringPending then return; end local liveList = TransmogFrame.CharacterPreview:GetItemTransmogInfoList(); --Kept even when nothing's pending, so the separate-shoulders fix has a value to fall back to. @@ -392,6 +400,19 @@ do SavePendingToDB(); end + -- Due to unknown reasons our frame could receive "VIEWED_TRANSMOG_OUTFIT_SLOT_REFRESH" before TransmogFrame does + -- And we will end up capturing the old items + -- Use this instead of always capture the current slots + function EL.TryCapturePending() + if not EL.capturePendingQueued then + EL.capturePendingQueued = true; + C_Timer.After(0, function() + EL.capturePendingQueued = nil; + CapturePending(); + end); + end + end + local function RestoreViewedOutfit(outfitID) if outfitID == nil then return; end if outfitID == C_TransmogOutfitInfo.GetCurrentlyViewedOutfitID() then return; end @@ -425,8 +446,6 @@ do local function ApplyPendingSnapshot(snapshot, pendingSlots, shoulderSecondary, weaponOptions) if not snapshot then return; end - EL.ForceWeaponSlotWidgetRebuild(); - --Must run before ApplySnapshotToPending, toggling this after would wipe the left shoulder's pending value EL.RestoreShoulderSecondaryState(shoulderSecondary); EL.ApplySnapshotToPending(snapshot, pendingSlots or {}); @@ -506,7 +525,7 @@ do local wipedSituations = isOutfitSwitch and EL.PendingSituations and not C_TransmogOutfitInfo.HasPendingOutfitSituations(); if not (wipedTransmogs or wipedSituations) then - CapturePending(); + EL.TryCapturePending(); else isRestoringPending = true; if wipedTransmogs then @@ -551,30 +570,71 @@ do elseif event == "VIEWED_TRANSMOG_OUTFIT_SECONDARY_SLOTS_CHANGED" then FixShoulderSecondaryToggle(); else - CapturePending(); + EL.TryCapturePending(); end end local function TransmogFrame_OnShow() if not EL.enabled then return end; - API.RegisterFrameForEvents(EL, TRACKED_EVENTS); - RestoreAllPending(); + -- You can open TransmogFrame anywhere, like Plumber's OutfitSelect + -- But we only restore and save changes when interacting with transmog NPC + if C_Transmog.IsAtTransmogNPC() then + API.RegisterFrameForEvents(EL, TRACKED_EVENTS); + RestoreAllPending(); + end end local function TransmogFrame_OnHide() API.UnregisterFrameForEvents(EL, TRACKED_EVENTS); + addon.HideCustomPopup(POPUP_IDENTIFIER); end - local function OnStaticPopupShown(which, _, _, data) - if which ~= "TRANSMOG_PENDING_CHANGES" or not EL.enabled then return; end + local function OnStaticPopupShown(_, _, _, data) + if not EL.enabled then return; end local hasPending = C_TransmogOutfitInfo.HasPendingOutfitTransmogs() or C_TransmogOutfitInfo.HasPendingOutfitSituations(); if not hasPending then return; end - --Both appearance and situation pending changes now survive an outfit switch, so this warning is stale. - StaticPopup_Hide(which, data); - if data and data.confirmCallback then - data.confirmCallback(); + local confirmCallback = data and data.confirmCallback; + if confirmCallback then + if addon.GetDBBool(DBKEY_ALWAYS_MOVE_CHANGED) or (not C_Transmog.IsAtTransmogNPC()) then + confirmCallback(); + else + local checkboxTempDBKey = POPUP_IDENTIFIER.."_TEMP"; + addon.SetDBValue(checkboxTempDBKey, nil) + + addon.ShowCustomPopup({ + identifier = POPUP_IDENTIFIER, + text = L["Outfit Popup Warning"], + + buttons = { + {label = L["Outfit Popup Move Changes"], tooltip = L["Outfit Popup Move Changes Tooltip"], closePopup = true, onClickFunc = function() + addon.SetDBValue(DBKEY_ALWAYS_MOVE_CHANGED, addon.GetDBBool(checkboxTempDBKey)); + confirmCallback(); + end + }, + {label = L["Outfit Popup Discard Changes"], tooltip = L["Outfit Popup Discard Changes Tooltip"], closePopup = true, + onClickFunc = function() + EL.WipePendingAppearanceFromDB(true); + confirmCallback(); + end + }, + {label = CANCEL, closePopup = true, onClickFunc = function() addon.SetDBValue(DBKEY_ALWAYS_MOVE_CHANGED, false); end}, + }, + + widgets = { + {type = "checkbox", label = L["Outfit Popup Always Move Changes Over"], tooltip = L["Outfit Popup Always Move Changes Over Tooltip"], dbKey = checkboxTempDBKey}, + }, + + onHideFunc = function() + addon.SetDBValue(checkboxTempDBKey, nil); + end, + }); + end + + return true; -- This hides the original popup + else + return; end end @@ -584,11 +644,7 @@ do local originalClearTransmogs = C_TransmogOutfitInfo.ClearAllPendingTransmogs; C_TransmogOutfitInfo.ClearAllPendingTransmogs = function(...) if TransmogFrame:IsShown() then - EL.PendingSnapshot = nil; - EL.PendingSlots = nil; - EL.PendingShoulderSecondary = nil; - EL.PendingWeaponOptions = nil; - EL.SavePendingToDB(); + EL.WipePendingAppearanceFromDB(); end return originalClearTransmogs(...); end; @@ -606,17 +662,71 @@ do local originalCommitAllPending = C_TransmogOutfitInfo.CommitAndApplyAllPending; C_TransmogOutfitInfo.CommitAndApplyAllPending = function(...) if TransmogFrame:IsShown() then - EL.PendingSnapshot = nil; - EL.PendingSlots = nil; - EL.PendingShoulderSecondary = nil; - EL.PendingWeaponOptions = nil; - EL.PendingSituations = nil; - EL.SavePendingToDB(); + EL.WipePendingAppearanceFromDB(true); end return originalCommitAllPending(...); end; end + local function OnRefreshSlots() + local f = TransmogFrame.CharacterPreview; + + local mainOrOHSlotSelected = f.selectedSlotData and f.selectedSlotData.transmogLocation:IsEitherHand(); + local rangedSlotSelected = f.selectedSlotData and f.selectedSlotData.transmogLocation:IsRangedSlot(); + local previewRangedWeapon = C_PaperDollInfo.IsRangedSlotShown() and ((C_CVar.GetCVarBool("transmogPreviewedWeaponToggle") and not mainOrOHSlotSelected) or rangedSlotSelected); + + if previewRangedWeapon then return; end + + local actor = f.ModelScene:GetPlayerActor(); + if not actor then return; end + + local weaponSlotItemTransmogInfo = {}; + + for slotFrame in f.CharacterAppearanceSlotFramePool:EnumerateActive() do + local transmogLocation = slotFrame:GetTransmogLocation(); + if transmogLocation then + local slotID = transmogLocation:GetSlotID(); + if slotID == 16 or slotID == 17 then + local illusionSlotFrame = slotFrame:GetIllusionSlotFrame(); + local illusionID = Constants.Transmog.NoTransmogID; + if illusionSlotFrame then + local illusionSlotInfo = illusionSlotFrame:GetSlotInfo(); + if illusionSlotInfo and illusionSlotInfo.warning ~= Enum.TransmogOutfitSlotWarning.WeaponDoesNotSupportIllusions then + illusionID = illusionSlotInfo.transmogID; + end + end + + local secondaryAppearanceID = Constants.Transmog.NoTransmogID; + local appearanceID = slotFrame:GetEffectiveTransmogID(); + local itemTransmogInfo = ItemUtil.CreateItemTransmogInfo(appearanceID, secondaryAppearanceID, illusionID); + + local mainHandCategoryID; + local isLegionArtifact = false; + if transmogLocation:IsMainHand() then + mainHandCategoryID = C_TransmogOutfitInfo.GetItemModifiedAppearanceEffectiveCategory(appearanceID); + isLegionArtifact = TransmogUtil.IsCategoryLegionArtifact(mainHandCategoryID); + itemTransmogInfo:ConfigureSecondaryForMainHand(isLegionArtifact); + end + + if appearanceID == Constants.Transmog.NoTransmogID then + actor:UndressSlot(slotID); + else + local slotToSetID = slotID; + weaponSlotItemTransmogInfo[slotToSetID] = itemTransmogInfo; + end + end + end + end + + -- Weapons must be equipped in specific order + -- So main-hand can correctly override off-hand + for slotToSetID = 17, 16, -1 do + if weaponSlotItemTransmogInfo[slotToSetID] then + actor:SetItemTransmogInfo(weaponSlotItemTransmogInfo[slotToSetID], slotToSetID); + end + end + end + function EL.SnapshotFrame_OnLoad() if EL.snapshotHooked then return end; EL.snapshotHooked = true; @@ -624,14 +734,16 @@ do EL:SetScript("OnEvent", OnTrackedEvent); TransmogFrame:HookScript("OnShow", TransmogFrame_OnShow); TransmogFrame:HookScript("OnHide", TransmogFrame_OnHide); - -- If we decide not to disable/skip the popup, comment/remove this hooksecurefunc below. - hooksecurefunc("StaticPopup_Show", OnStaticPopupShown); + hooksecurefunc(TransmogFrame, "SelectSlot", OnSlotSelected); + hooksecurefunc(TransmogFrame.CharacterPreview, "RefreshSlots", OnRefreshSlots); HookExplicitClears(); if TransmogFrame:IsShown() then TransmogFrame_OnShow(); end + + addon.StaticPopupUtil:SetStaticPopupHandler("TRANSMOG_PENDING_CHANGES", OnStaticPopupShown); end end @@ -645,13 +757,8 @@ do elseif (not state) and EL.enabled then EL.enabled = nil; addon.CallbackRegistry:UnregisterAddOnLoadedCallback("Blizzard_Transmog", EL.SnapshotFrame_OnLoad); - EL.PendingSnapshot = nil; - EL.PendingSlots = nil; - EL.PendingShoulderSecondary = nil; - EL.PendingWeaponOptions = nil; - EL.PendingSituations = nil; - EL.LastViewedOutfitID = nil; - EL.SavePendingToDB(); + EL.WipePendingAppearanceFromDB(true, true); + addon.SetDBValue(DBKEY_ALWAYS_MOVE_CHANGED, false); end end