From ab8e471a360b9547fb21c36e8dd225849b916a69 Mon Sep 17 00:00:00 2001 From: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 2 Apr 2026 22:51:48 +0100 Subject: [PATCH 1/3] Minor adjustments --- Core/MultiBotHandler.lua | 29 ++++- Locales/MultiBotAceLocale-deDE.lua | 2 + Locales/MultiBotAceLocale-enGB.lua | 2 + Locales/MultiBotAceLocale-enUS.lua | 2 + Locales/MultiBotAceLocale-esES.lua | 12 ++- Locales/MultiBotAceLocale-frFR.lua | 2 + Locales/MultiBotAceLocale-koKR.lua | 2 + Locales/MultiBotAceLocale-ruRU.lua | 2 + Locales/MultiBotAceLocale-zhCN.lua | 2 + TODO.md | 32 +----- UI/MultiBotCreatorUI.lua | 2 +- UI/MultiBotIconosFrame.lua | 51 ++++++--- UI/MultiBotInventoryFrame.lua | 160 ++++++++++++++++++++++++++++ UI/MultiBotQuestAllFrame.lua | 5 - UI/MultiBotQuestCompletedFrame.lua | 5 - UI/MultiBotQuestIncompleteFrame.lua | 5 - UI/MultiBotQuestLogFrame.lua | 5 - 17 files changed, 245 insertions(+), 75 deletions(-) diff --git a/Core/MultiBotHandler.lua b/Core/MultiBotHandler.lua index 1783d27..293f94f 100644 --- a/Core/MultiBotHandler.lua +++ b/Core/MultiBotHandler.lua @@ -542,7 +542,7 @@ local POINT_FRAME_BINDINGS = { { saveKey = "InventoryPoint", getFrame = function() return MultiBot.inventory end }, { saveKey = "SpellbookPoint", getFrame = function() return MultiBot.spellbook end }, { saveKey = "ItemusPoint", getFrame = function() return MultiBot.itemus end }, - { saveKey = "IconosPoint", getFrame = function() return MultiBot.iconos and (MultiBot.iconos.frame or MultiBot.iconos) end }, + { saveKey = "IconosPoint", getFrame = function() return MultiBot.iconos or (MultiBot.iconos and MultiBot.iconos.frame) end }, { saveKey = "StatsPoint", getFrame = function() return MultiBot.stats end }, { saveKey = "RewardPoint", getFrame = function() return MultiBot.reward end }, { saveKey = "TalentPoint", getFrame = function() return MultiBot.talent end }, @@ -562,9 +562,23 @@ local function getPortalButton(color) end local function saveBoundFramePoints() + local function canReadPoint(frame) + if not frame then + return false + end + + local getRight = frame.GetRight or frame.getRight + local getBottom = frame.GetBottom or frame.getBottom + if type(getRight) ~= "function" or type(getBottom) ~= "function" then + return false + end + + return getRight(frame) ~= nil and getBottom(frame) ~= nil + end + for _, binding in ipairs(POINT_FRAME_BINDINGS) do local frame = binding.getFrame and binding.getFrame() - if frame then + if frame and canReadPoint(frame) then local tX, tY = MultiBot.toPoint(frame) setSavedLayoutValue(binding.saveKey, tX .. ", " .. tY) end @@ -576,8 +590,12 @@ local function restoreBoundFramePoints() local pointValue = getSavedLayoutValue(binding.saveKey) local frame = binding.getFrame and binding.getFrame() if pointValue ~= nil and frame and frame.setPoint then - local tPoint = MultiBot.doSplit(pointValue, ", ") - frame.setPoint(tonumber(tPoint[1]), tonumber(tPoint[2])) + local pointX, pointY = string.match(tostring(pointValue), "^%s*(-?%d+)%s*,%s*(-?%d+)%s*$") + pointX = tonumber(pointX) + pointY = tonumber(pointY) + if pointX and pointY then + frame.setPoint(pointX, pointY) + end end end end @@ -1797,6 +1815,9 @@ function MultiBot.HandleMultiBotEvent(event, ...) end if(tButton.waitFor == "ITEM" and (MultiBot.beInside(arg1, "Bag,", "Dur") or MultiBot.beInside(arg1, "背包", "耐久度"))) then + if MultiBot.inventory and MultiBot.inventory.applySummaryLine then + MultiBot.inventory:applySummaryLine(arg1) + end MultiBot.inventory:Show() tButton.waitFor = "" InspectUnit(arg2) diff --git a/Locales/MultiBotAceLocale-deDE.lua b/Locales/MultiBotAceLocale-deDE.lua index 71e4de3..6eae9e8 100644 --- a/Locales/MultiBotAceLocale-deDE.lua +++ b/Locales/MultiBotAceLocale-deDE.lua @@ -41,6 +41,8 @@ local deDEValues = { ["info.teleport"] = "wird dich zu 'MAP - ZONE' teleportieren", ["info.normal"] = "Frage NAME nach Nicht-Kampf-Strategien.", ["info.inventory"] = "Inventar von NAME", + ["info.inventory.money_label"] = "Geld", + ["info.inventory.bag_slots_label"] = "Taschenplätze", ["info.spellbook"] = "Zauberbuch von NAME", ["info.player"] = "Ich werde 'NAME' vom Playerbot-Roster nicht Auto-Initialisieren.", ["info.member"] = "Ich werde 'NAME' vom Gilden-Roster nicht Auto-Initialisieren.", diff --git a/Locales/MultiBotAceLocale-enGB.lua b/Locales/MultiBotAceLocale-enGB.lua index 596bf43..890e77c 100644 --- a/Locales/MultiBotAceLocale-enGB.lua +++ b/Locales/MultiBotAceLocale-enGB.lua @@ -41,6 +41,8 @@ local enGBValues = { ["info.teleport"] = "will teleport you to 'MAP - ZONE'", ["info.normal"] = "I'm querying NAME for their non-combat directives...", ["info.inventory"] = "NAME's Inventory", + ["info.inventory.money_label"] = "Money", + ["info.inventory.bag_slots_label"] = "Bag Slots", ["info.spellbook"] = "NAME's Spellbook", ["info.player"] = "I couldn't auto-initialise NAME from the Playerbot Roster.", ["info.member"] = "I couldn't auto-initialise NAME from the Guild Roster.", diff --git a/Locales/MultiBotAceLocale-enUS.lua b/Locales/MultiBotAceLocale-enUS.lua index 93d5525..a2f6619 100644 --- a/Locales/MultiBotAceLocale-enUS.lua +++ b/Locales/MultiBotAceLocale-enUS.lua @@ -41,6 +41,8 @@ local enUSValues = { ["info.teleport"] = "will teleport you to 'MAP - ZONE'", ["info.normal"] = "I'm querying NAME for their non-combat directives...", ["info.inventory"] = "NAME's Inventory", + ["info.inventory.money_label"] = "Money", + ["info.inventory.bag_slots_label"] = "Bag Slots", ["info.spellbook"] = "NAME's Spellbook", ["info.player"] = "I couldn't auto-initialize NAME from the Playerbot Roster.", ["info.member"] = "I couldn't auto-initialize NAME from the Guild Roster.", diff --git a/Locales/MultiBotAceLocale-esES.lua b/Locales/MultiBotAceLocale-esES.lua index c978d71..892ca76 100644 --- a/Locales/MultiBotAceLocale-esES.lua +++ b/Locales/MultiBotAceLocale-esES.lua @@ -36,12 +36,14 @@ local esESValues = { ["info.macro"] = "Ya tengo el número máximo de macros privadas.", ["info.neither"] = "No tengo un objetivo, tampoco estoy en un grupo.", ["info.group"] = "Tenemos que estar en Grupo, invitemos..", - ["info.inviting"] = "Nombre de invitación al Grupo.", - ["info.combat"] = "Nombre preguntado para Estrategias de Combate.", + ["info.inviting"] = "NAME de invitación al Grupo.", + ["info.combat"] = "NAME preguntado para Estrategias de Combate.", ["info.teleport"] = "te teletransportará a 'MAP-ZONE'", - ["info.normal"] = "Nombre preguntado para estrategias que no son de combate.", - ["info.inventory"] = "Inventario del Nombre", - ["info.spellbook"] = "Libro de hechizos de Nombre", + ["info.normal"] = "NAME preguntado para estrategias que no son de combate.", + ["info.inventory"] = "Inventario del NAME", + ["info.inventory.money_label"] = "Dinero", + ["info.inventory.bag_slots_label"] = "Huecos de bolsa", + ["info.spellbook"] = "Libro de hechizos de NAME", ["info.player"] = "No inicializaré automáticamente 'NAME' del Playerbot-Roster.", ["info.member"] = "No inicializaré automáticamente 'NAME' del Guild-Roster.", ["info.players"] = "No inicializaré automáticamente a nadie del Playerbot-Roster.", diff --git a/Locales/MultiBotAceLocale-frFR.lua b/Locales/MultiBotAceLocale-frFR.lua index 7f58e86..3a51071 100644 --- a/Locales/MultiBotAceLocale-frFR.lua +++ b/Locales/MultiBotAceLocale-frFR.lua @@ -41,6 +41,8 @@ local frFRValues = { ["info.teleport"] = "vous téléportera vers 'MAP - ZONE'", ["info.normal"] = "Demande à NAME des stratégies non-combattantes.", ["info.inventory"] = "Inventaire de NAME", + ["info.inventory.money_label"] = "Argent", + ["info.inventory.bag_slots_label"] = "Sacs", ["info.spellbook"] = "Livre de sorts de NAME", ["info.player"] = "Je ne vais pas auto-initialiser 'NAME' depuis la liste des bots.", ["info.member"] = "Je ne vais pas auto-initialiser 'NAME' depuis la liste des membres de la guilde.", diff --git a/Locales/MultiBotAceLocale-koKR.lua b/Locales/MultiBotAceLocale-koKR.lua index 149ae47..bf1de3e 100644 --- a/Locales/MultiBotAceLocale-koKR.lua +++ b/Locales/MultiBotAceLocale-koKR.lua @@ -41,6 +41,8 @@ local koKRValues = { ["info.teleport"] = "will teleport you to 'MAP - ZONE'", ["info.normal"] = "NAME에게 비전투 전략에 대해 물어보세요.", ["info.inventory"] = "NAME의 인벤토리입니다.", + ["info.inventory.money_label"] = "소지금", + ["info.inventory.bag_slots_label"] = "가방 칸", ["info.spellbook"] = "NAME의 마법의 책.", ["info.player"] = "플레이어 봇 목록에서 'NAME'을 자동으로 초기화하지 않습니다.", ["info.member"] = "길드 목록에서 'NAME'을 자동으로 초기화하지 않습니다.", diff --git a/Locales/MultiBotAceLocale-ruRU.lua b/Locales/MultiBotAceLocale-ruRU.lua index b635266..0ee35ed 100644 --- a/Locales/MultiBotAceLocale-ruRU.lua +++ b/Locales/MultiBotAceLocale-ruRU.lua @@ -41,6 +41,8 @@ local ruRUValues = { ["info.teleport"] = "телепортирует вас в 'MAP - ZONE'", ["info.normal"] = "Запросил небоевые тактики у NAME.", ["info.inventory"] = "Инвентарь NAME", + ["info.inventory.money_label"] = "Деньги", + ["info.inventory.bag_slots_label"] = "Слоты сумок", ["info.spellbook"] = "Книга заклинаний NAME", ["info.player"] = "Я не буду авто-инициализировать 'NAME' из состава игровых ботов.", ["info.member"] = "Я не буду авто-инициализировать 'NAME' из состава гильдии.", diff --git a/Locales/MultiBotAceLocale-zhCN.lua b/Locales/MultiBotAceLocale-zhCN.lua index 9100c27..10b8d8d 100644 --- a/Locales/MultiBotAceLocale-zhCN.lua +++ b/Locales/MultiBotAceLocale-zhCN.lua @@ -41,6 +41,8 @@ local zhCNValues = { ["info.teleport"] = "将把你传送到'MAP - ZONE'。", ["info.normal"] = "向 NAME 询问非战斗策略。", ["info.inventory"] = "NAME 的物品栏。", + ["info.inventory.money_label"] = "金钱", + ["info.inventory.bag_slots_label"] = "背包栏位", ["info.spellbook"] = "NAME 的魔法书。", ["info.player"] = "我不会自动初始化玩家机器人名单中的'NAME'。", ["info.member"] = "我不会自动初始化公会名单中的'NAME'。", diff --git a/TODO.md b/TODO.md index 8dc4228..06ae089 100644 --- a/TODO.md +++ b/TODO.md @@ -1,43 +1,17 @@ TODO -* Voi si y'a pas d'autres appels à pageLabel:SetText(MB_PAGE_DEFAULT) dans les fichiers et remplacer par : + pageLabel:SetText(MultiBot.MB_PAGE_DEFAULT or "0/0") -* Ressortir les UI quetes dans leurs propre fichiers et uniformiser le tempklate de la frame comme celle de Itemus -* Uniformiser le templste de la frame reward comme celle de itemus +* Voir si y'a pas d'autres appels à pageLabel:SetText(MB_PAGE_DEFAULT) dans les fichiers et remplacer par : + pageLabel:SetText(MultiBot.MB_PAGE_DEFAULT or "0/0") +* Uniformiser le template des frame quetes comme celle de Itemus +* Uniformiser le template de la frame reward comme celle de itemus * Essayer de faire disparaitre la barre multibots au bout d'un temps et la faire apparaitre quand on passe la souris dessus. * Quand on deplace ou fait quelque chose dans l'ui il faudrait que ça se sauvegarde tout de suite dans les variables dans deco reco * Raidus doit se rafraichir à l'ouverture et fermeture * dans la liste des quêtes des fois c'est l'ID de la queête qui apparait et pas le tritre -* Afficher le pognon et les places de sacs dans la frame inventaire. -* Iconos ne mémorise pas sa position et n'a pas de strata -* Revoir le positionnement des fleches et pages de Iconos * Mettre une option pour choisir la tailles des icones de la main barre et des quickhunter/shaman * Voir si il y'a pas d'autres option que l'on peut ajouter à la frame options de multibot * creer le multilangue pour le tooltip: setTooltip(self, "Show / Hide / Move Quick Shaman") des fichiers quickshaman et quickhunter -* Ajouter des emplacements de sacs à la fenêtre inventaire -* Creator a l'air de planter et apparait même quand il est desactivé. -* Faire les tootips multi dans la fonction: - local originalDoRight = button.doRight - button.doRight = function(btn) - if(IsShiftKeyDown()) then - if(state.selected == nil) then - state.selected = entryRec - if(UIErrorsFrame) then - UIErrorsFrame:AddMessage("Swap source: " .. (entryRec.id or entryRec.name), 1, 0.82, 0, 1) - end - return - end - - if(state.selected == entryRec) then - state.selected = nil - if(UIErrorsFrame) then - UIErrorsFrame:AddMessage("Swap annulé.", 1, 0.25, 0.25, 1) - end - return - end -De MultiboEngine * Finir les options de déplacement des boutons * Debuguer le blocage de la barre principale en déplacement ça a l'air de ne pas persister apres une deco reco -* Améliorer le panneau options avec des onglets Ajouter la fonction unequipe à Multibit: diff --git a/UI/MultiBotCreatorUI.lua b/UI/MultiBotCreatorUI.lua index 66c7419..dc9e769 100644 --- a/UI/MultiBotCreatorUI.lua +++ b/UI/MultiBotCreatorUI.lua @@ -138,7 +138,7 @@ function MultiBot.InitializeCreatorUI(tLeft) return nil end - local rootButton = tLeft.addButton("Creator", 0, 0, CREATOR_ROOT_ICON, MultiBot.L("tips.creator.master")) + local rootButton = tLeft.addButton("Creator", 0, 0, CREATOR_ROOT_ICON, MultiBot.L("tips.creator.master")).doHide() local creatorFrame = tLeft.addFrame(CREATOR_FRAME_NAME, CREATOR_FRAME_X, CREATOR_FRAME_Y) creatorFrame:Hide() diff --git a/UI/MultiBotIconosFrame.lua b/UI/MultiBotIconosFrame.lua index 88c8cb8..da06abb 100644 --- a/UI/MultiBotIconosFrame.lua +++ b/UI/MultiBotIconosFrame.lua @@ -168,9 +168,9 @@ local function bindIconosWindowPosition(window) local savedPoint = MultiBot.GetSavedLayoutValue and MultiBot.GetSavedLayoutValue(ICONOS_LAYOUT_KEY) or nil if type(savedPoint) == "string" and savedPoint ~= "" then - local splitPoint = MultiBot.doSplit(savedPoint, ", ") - local offsetX = tonumber(splitPoint[1]) - local offsetY = tonumber(splitPoint[2]) + local offsetX, offsetY = string.match(savedPoint, "^%s*(-?%d+)%s*,%s*(-?%d+)%s*$") + offsetX = tonumber(offsetX) + offsetY = tonumber(offsetY) if offsetX and offsetY then window.frame:ClearAllPoints() window.frame:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", offsetX, offsetY) @@ -206,12 +206,11 @@ local function bindIconosMoveInteractions(window) end) window.title:HookScript("OnMouseUp", function() - if not window.frame.__mbRightDragging then - return + if window.frame.__mbRightDragging then + window.frame.__mbRightDragging = nil + window.frame:StopMovingOrSizing() end - window.frame.__mbRightDragging = nil - window.frame:StopMovingOrSizing() persistIconosWindowPosition(window.frame) end) @@ -220,15 +219,16 @@ local function bindIconosMoveInteractions(window) frame.__mbRightDragging = nil frame:StopMovingOrSizing() end + + persistIconosWindowPosition(frame) end) window.frame:HookScript("OnMouseUp", function(frame) - if not frame.__mbRightDragging then - return + if frame.__mbRightDragging then + frame.__mbRightDragging = nil + frame:StopMovingOrSizing() end - frame.__mbRightDragging = nil - frame:StopMovingOrSizing() persistIconosWindowPosition(frame) end) @@ -756,17 +756,20 @@ local function createIconosContent(window, iconos) resultsLabel:SetText("0/0") local prevButton = createPaginationButton(headerPanel, "<") - prevButton:SetPoint("BOTTOMRIGHT", headerPanel, "BOTTOMRIGHT", -50, 14) + prevButton:SetPoint("BOTTOMRIGHT", headerPanel, "BOTTOMRIGHT", -82, 14) local nextButton = createPaginationButton(headerPanel, ">") nextButton:SetPoint("BOTTOMRIGHT", headerPanel, "BOTTOMRIGHT", -10, 14) - resultsLabel:SetPoint("RIGHT", prevButton, "LEFT", -8, 0) + resultsLabel:ClearAllPoints() + resultsLabel:SetPoint("LEFT", prevButton, "RIGHT", 6, 0) + resultsLabel:SetPoint("RIGHT", nextButton, "LEFT", -6, 0) + resultsLabel:SetJustifyH("CENTER") local pageLabel = headerPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlight") - pageLabel:SetPoint("LEFT", prevButton, "RIGHT", 4, 0) - pageLabel:SetPoint("RIGHT", nextButton, "LEFT", -4, 0) - pageLabel:SetJustifyH("CENTER") + pageLabel:SetPoint("RIGHT", prevButton, "LEFT", -8, 0) + pageLabel:SetWidth(52) + pageLabel:SetJustifyH("RIGHT") pageLabel:SetText(getIconosPageLabel(0, 0)) local pathPanel = CreateFrame("Frame", nil, content) @@ -1036,6 +1039,22 @@ function MultiBot.InitializeIconosFrame() self:Refresh() end + function iconos.setPoint(pointX, pointY) + if not iconos.window or not iconos.window.frame then + return + end + + local offsetX = tonumber(pointX) + local offsetY = tonumber(pointY) + if not offsetX or not offsetY then + return + end + + iconos.window.frame:ClearAllPoints() + iconos.window.frame:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", offsetX, offsetY) + persistIconosWindowPosition(iconos.window.frame) + end + function iconos:HideWindow() hideIconosTooltip(self.window) self.window.frame:Hide() diff --git a/UI/MultiBotInventoryFrame.lua b/UI/MultiBotInventoryFrame.lua index f5bb8ec..2e9dd7c 100644 --- a/UI/MultiBotInventoryFrame.lua +++ b/UI/MultiBotInventoryFrame.lua @@ -20,6 +20,8 @@ local INVENTORY_WINDOW_DEFAULTS = { instantActionColumns = 3, instantActionSpacingX = 29, instantActionSpacingY = 34, + summaryTopPadding = 10, + summaryLineSpacing = 16, itemSize = 32, itemSpacingX = 38, itemSpacingY = 37, @@ -422,6 +424,112 @@ local function updateModeLabel() end end +local function formatMoneyLabel(gold, silver, copper) + local g = tonumber(gold) or 0 + local s = tonumber(silver) or 0 + local c = tonumber(copper) or 0 + local moneyLabel = MultiBot.L("info.inventory.money_label", "Money") + return string.format("|cffffff00%s:|r %d|cffffd700g|r %d|cffc7c7cfs|r %d|cffb87333c|r", moneyLabel, g, s, c) +end + +local function formatBagSlotsLabel(used, total) + local usedSlots = tonumber(used) + local totalSlots = tonumber(total) + local bagSlotsLabel = MultiBot.L("info.inventory.bag_slots_label", "Bag Slots") + if not usedSlots or not totalSlots then + return string.format("|cffffff00%s:|r -/-", bagSlotsLabel) + end + + return string.format("|cffffff00%s:|r %d/%d", bagSlotsLabel, usedSlots, totalSlots) +end + +local function parseInventorySummaryLine(rawLine) + local line = tostring(rawLine or "") + if line == "" then + return nil + end + + local function escapeLuaPattern(value) + return tostring(value or ""):gsub("([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1") + end + + local function resolveBagPair() + local markerCandidates = { + "Bag", + MultiBot.L("info.shorts.bag", "Bag"), + "背包", + } + local seen = {} + + for _, marker in ipairs(markerCandidates) do + local token = tostring(marker or "") + local lowered = string.lower(token) + if token ~= "" and not seen[lowered] then + seen[lowered] = true + local usedToken, totalToken = string.match(line, escapeLuaPattern(token) .. "[^%d]*(%d+)%s*/%s*(%d+)") + local usedValue = tonumber(usedToken) + local totalValue = tonumber(totalToken) + if usedValue and totalValue and usedValue <= totalValue then + return usedValue, totalValue + end + end + end + + local bestUsed, bestTotal + for usedToken, totalToken in string.gmatch(line, "(%d+)%s*/%s*(%d+)") do + local usedValue = tonumber(usedToken) + local totalValue = tonumber(totalToken) + if usedValue and totalValue and usedValue <= totalValue then + if not bestUsed or usedValue > bestUsed then + bestUsed, bestTotal = usedValue, totalValue + end + end + end + + return bestUsed, bestTotal + end + + local used, total = resolveBagPair() + + local gold = string.match(line, "(%d+)%s*[gG]%f[%A]") + or string.match(string.lower(line), "(%d+)%s*gold%f[%A]") + or string.match(line, "(%d+)%s*金") + local silver = string.match(line, "(%d+)%s*[sS]%f[%A]") + or string.match(string.lower(line), "(%d+)%s*silver%f[%A]") + or string.match(line, "(%d+)%s*银") + local copper = string.match(line, "(%d+)%s*[cC]%f[%A]") + or string.match(string.lower(line), "(%d+)%s*copper%f[%A]") + or string.match(line, "(%d+)%s*铜") + + if not used and not total and not gold and not silver and not copper then + return nil + end + + return { + bagUsed = tonumber(used), + bagTotal = tonumber(total), + gold = tonumber(gold) or 0, + silver = tonumber(silver) or 0, + copper = tonumber(copper) or 0, + } +end + +local function updateInventorySummaryLabels(inventory) + if not inventory then + return + end + + local summary = inventory.summary or {} + + if inventory.moneyLabel then + inventory.moneyLabel:SetText(formatMoneyLabel(summary.gold, summary.silver, summary.copper)) + end + + if inventory.bagSlotsLabel then + inventory.bagSlotsLabel:SetText(formatBagSlotsLabel(summary.bagUsed, summary.bagTotal)) + end +end + local function getInventoryWindowTitle(botName) local defaultTitle = MB_INVENTORY_LABEL or INVENTORY_TOOLTIP or BAGSLOT or "Inventory" if not botName or botName == "" then @@ -802,6 +910,22 @@ local function createInventoryContent(window) buttons[definition.key] = makeActionButton(leftPanel, definition.key, definition.texture, definition.tip, yOffset, xOffset) end + local summaryAnchorY = instantStartY + - (math.ceil(#instantButtonDefs / instantColumns) * instantSpacingY) + - INVENTORY_WINDOW_DEFAULTS.summaryTopPadding + + local moneyLabel = leftPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall") + moneyLabel:SetPoint("TOPLEFT", leftPanel, "TOPLEFT", 8, summaryAnchorY) + moneyLabel:SetPoint("TOPRIGHT", leftPanel, "TOPRIGHT", -6, summaryAnchorY) + moneyLabel:SetJustifyH("LEFT") + moneyLabel:SetText(formatMoneyLabel(0, 0, 0)) + + local bagSlotsLabel = leftPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall") + bagSlotsLabel:SetPoint("TOPLEFT", moneyLabel, "BOTTOMLEFT", 0, -INVENTORY_WINDOW_DEFAULTS.summaryLineSpacing) + bagSlotsLabel:SetPoint("TOPRIGHT", moneyLabel, "BOTTOMRIGHT", 0, -INVENTORY_WINDOW_DEFAULTS.summaryLineSpacing) + bagSlotsLabel:SetJustifyH("LEFT") + bagSlotsLabel:SetText(formatBagSlotsLabel(nil, nil)) + local items = makeItemsContainer(itemsPanel, scrollChild) items:updateLayout() @@ -817,6 +941,8 @@ local function createInventoryContent(window) modeLabel = modeLabel, modeValueLabel = modeValueLabel, helperText = helperText, + moneyLabel = moneyLabel, + bagSlotsLabel = bagSlotsLabel, actionHost = actionHost, buttons = buttons, } @@ -869,9 +995,18 @@ function MultiBot.InitializeInventoryFrame() modeLabel = content.modeLabel, modeValueLabel = content.modeValueLabel, helperText = content.helperText, + moneyLabel = content.moneyLabel, + bagSlotsLabel = content.bagSlotsLabel, name = "", action = "s", pendingLootBot = nil, + summary = { + bagUsed = nil, + bagTotal = nil, + gold = 0, + silver = 0, + copper = 0, + }, } MultiBot.inventory = inventory @@ -999,9 +1134,33 @@ function MultiBot.InitializeInventoryFrame() setInventoryBotName(botName or "") self.pendingLootBot = nil self:resetItems() + self.summary = { + bagUsed = nil, + bagTotal = nil, + gold = 0, + silver = 0, + copper = 0, + } + updateInventorySummaryLabels(self) return self end + function inventory:applySummaryLine(line) + local parsed = parseInventorySummaryLine(line) + if not parsed then + return false + end + + self.summary = self.summary or {} + self.summary.bagUsed = parsed.bagUsed or self.summary.bagUsed + self.summary.bagTotal = parsed.bagTotal or self.summary.bagTotal + self.summary.gold = parsed.gold or 0 + self.summary.silver = parsed.silver or 0 + self.summary.copper = parsed.copper or 0 + updateInventorySummaryLabels(self) + return true + end + function inventory:appendItem(itemInfo) local items = self.frames and self.frames.Items if items and items.addChatItem then @@ -1043,6 +1202,7 @@ function MultiBot.InitializeInventoryFrame() setInventoryActionState("Sell", { cancelTrade = false }) resetInventoryViewState() + updateInventorySummaryLabels(inventory) return inventory end \ No newline at end of file diff --git a/UI/MultiBotQuestAllFrame.lua b/UI/MultiBotQuestAllFrame.lua index da7631d..16652af 100644 --- a/UI/MultiBotQuestAllFrame.lua +++ b/UI/MultiBotQuestAllFrame.lua @@ -181,11 +181,6 @@ function MultiBot.InitializeQuestAllFrame() content:SetLayout("List") window:AddChild(content) - local heading = aceGUI:Create("Heading") - heading:SetFullWidth(true) - heading:SetText(MultiBot.L("tips.quests.alllist")) - content:AddChild(heading) - local summary = aceGUI:Create("Label") summary:SetFullWidth(true) summary:SetText("") diff --git a/UI/MultiBotQuestCompletedFrame.lua b/UI/MultiBotQuestCompletedFrame.lua index f2eab13..419bbe3 100644 --- a/UI/MultiBotQuestCompletedFrame.lua +++ b/UI/MultiBotQuestCompletedFrame.lua @@ -69,11 +69,6 @@ function MultiBot.InitializeQuestCompletedFrame() content:SetLayout("List") window:AddChild(content) - local heading = aceGUI:Create("Heading") - heading:SetFullWidth(true) - heading:SetText(MultiBot.L("tips.quests.complist")) - content:AddChild(heading) - local summary = aceGUI:Create("Label") summary:SetFullWidth(true) summary:SetText("") diff --git a/UI/MultiBotQuestIncompleteFrame.lua b/UI/MultiBotQuestIncompleteFrame.lua index 53494a4..e91fa89 100644 --- a/UI/MultiBotQuestIncompleteFrame.lua +++ b/UI/MultiBotQuestIncompleteFrame.lua @@ -69,11 +69,6 @@ function MultiBot.InitializeQuestIncompleteFrame() content:SetLayout("List") window:AddChild(content) - local heading = aceGUI:Create("Heading") - heading:SetFullWidth(true) - heading:SetText(MultiBot.L("tips.quests.incomplist")) - content:AddChild(heading) - local summary = aceGUI:Create("Label") summary:SetFullWidth(true) summary:SetText("") diff --git a/UI/MultiBotQuestLogFrame.lua b/UI/MultiBotQuestLogFrame.lua index 2856c34..ce06212 100644 --- a/UI/MultiBotQuestLogFrame.lua +++ b/UI/MultiBotQuestLogFrame.lua @@ -198,11 +198,6 @@ function MultiBot.InitializeQuestLogFrame() content:SetLayout("List") window:AddChild(content) - local header = aceGUI:Create("Heading") - header:SetFullWidth(true) - header:SetText(QUEST_LOG) - content:AddChild(header) - local scroll = aceGUI:Create("ScrollFrame") scroll:SetFullWidth(true) scroll:SetFullHeight(true) From ee66907504b8d34481f0ca229e3f0506bde86318 Mon Sep 17 00:00:00 2001 From: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 2 Apr 2026 23:24:32 +0100 Subject: [PATCH 2/3] Add unequip right click to inspect windows --- Core/MultiBotHandler.lua | 4 +- MultiBot.toc | 1 + UI/MultiBotInspectUI.lua | 157 +++++++++++++++++++++++++++++++++++++++ UI/MultiBotOptions.lua | 2 +- 4 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 UI/MultiBotInspectUI.lua diff --git a/Core/MultiBotHandler.lua b/Core/MultiBotHandler.lua index 293f94f..82cc001 100644 --- a/Core/MultiBotHandler.lua +++ b/Core/MultiBotHandler.lua @@ -1843,13 +1843,13 @@ function MultiBot.HandleMultiBotEvent(event, ...) -- EQUIPPING -- if(MultiBot.inventory:IsVisible()) then - if(MultiBot.isInside(arg1, "装备", "使用", "吃", "喝", "盛宴", "摧毁")) then + if(MultiBot.isInside(arg1, "装备", "卸下", "使用", "吃", "喝", "盛宴", "摧毁")) then tButton.waitFor = "INVENTORY" SendChatMessage("items", "WHISPER", nil, tButton.name) return end - if(MultiBot.isInside(string.lower(arg1), "equipping", "using", "eating", "drinking", "feasting", "destroyed")) then + if(MultiBot.isInside(string.lower(arg1), "equipping", "unequipping", "using", "eating", "drinking", "feasting", "destroyed", "removed", "taking off")) then tButton.waitFor = "INVENTORY" SendChatMessage("items", "WHISPER", nil, tButton.name) return diff --git a/MultiBot.toc b/MultiBot.toc index fda5733..542f4c2 100644 --- a/MultiBot.toc +++ b/MultiBot.toc @@ -65,6 +65,7 @@ UI\MultiBotSpellBookFrame.lua UI\MultiBotRewardFrame.lua UI\MultiBotInventoryFrame.lua UI\MultiBotInventoryItem.lua +UI\MultiBotInspectUI.lua UI\MultiBotItemusFrame.lua UI\MultiBotIconosFrame.lua UI\MultiBotItem.lua diff --git a/UI/MultiBotInspectUI.lua b/UI/MultiBotInspectUI.lua new file mode 100644 index 0000000..e84b65c --- /dev/null +++ b/UI/MultiBotInspectUI.lua @@ -0,0 +1,157 @@ +if not MultiBot then + return +end + +local EQUIPMENT_SLOT_BY_NAME = { + HeadSlot = 1, + NeckSlot = 2, + ShoulderSlot = 3, + ShirtSlot = 4, + ChestSlot = 5, + WaistSlot = 6, + LegsSlot = 7, + FeetSlot = 8, + WristSlot = 9, + HandsSlot = 10, + Finger0Slot = 11, + Finger1Slot = 12, + Trinket0Slot = 13, + Trinket1Slot = 14, + BackSlot = 15, + MainHandSlot = 16, + SecondaryHandSlot = 17, + RangedSlot = 18, + TabardSlot = 19, +} + +local INSPECT_SLOT_SUFFIXES = { + "HeadSlot", + "NeckSlot", + "ShoulderSlot", + "ShirtSlot", + "ChestSlot", + "WaistSlot", + "LegsSlot", + "FeetSlot", + "WristSlot", + "HandsSlot", + "Finger0Slot", + "Finger1Slot", + "Trinket0Slot", + "Trinket1Slot", + "BackSlot", + "MainHandSlot", + "SecondaryHandSlot", + "RangedSlot", + "TabardSlot", +} + +local function getInspectedBotName() + local inspectUnit = InspectFrame and InspectFrame.unit + if inspectUnit and UnitExists(inspectUnit) then + return UnitName(inspectUnit) + end + + return UnitName("target") +end + +local function canUnequipInspectedBot(botName) + if not botName or botName == "" then + return false + end + + if MultiBot.isActive then + return MultiBot.isActive(botName) + end + + return UnitIsPlayer("target") and not UnitIsUnit("target", "player") +end + +local function requestInventorySync(botName) + if MultiBot.RequestBotInventory then + MultiBot.RequestBotInventory(botName) + return + end + + if MultiBot.RefreshInventory then + MultiBot.RefreshInventory(0.15) + end +end + +local function getSlotItemLink(inspectButton) + if not inspectButton then + return nil + end + + local slotId = inspectButton.GetID and inspectButton:GetID() or nil + if not slotId or slotId <= 0 then + slotId = EQUIPMENT_SLOT_BY_NAME[inspectButton.mbSlotName or ""] + end + + local inspectUnit = InspectFrame and InspectFrame.unit + if inspectUnit and UnitExists(inspectUnit) and slotId then + return GetInventoryItemLink(inspectUnit, slotId) + end + + return nil +end + +local function showRightClickHint(self) + if not GameTooltip or not GameTooltip:IsShown() then + return + end + + local botName = getInspectedBotName() + if canUnequipInspectedBot(botName) then + GameTooltip:AddLine(" ") + GameTooltip:AddLine("Clic droit : déséquiper (ue)", 1, 0.82, 0) + GameTooltip:Show() + end +end + +local function onInspectSlotClick(self, mouseButton) + if mouseButton ~= "RightButton" then + return + end + + local botName = getInspectedBotName() + if not canUnequipInspectedBot(botName) then + return + end + + local itemLink = getSlotItemLink(self) + if not itemLink or itemLink == "" then + return + end + + SendChatMessage("ue " .. itemLink, "WHISPER", nil, botName) + requestInventorySync(botName) +end + +local function hookInspectSlot(slotSuffix) + local buttonName = "Inspect" .. slotSuffix + local button = _G[buttonName] + if not button or button.__mbUnequipHooked then + return + end + + button.__mbUnequipHooked = true + button.mbSlotName = slotSuffix + button:RegisterForClicks("LeftButtonUp", "RightButtonUp") + button:HookScript("OnClick", onInspectSlotClick) + button:HookScript("OnEnter", showRightClickHint) +end + +local function hookInspectSlots() + for _, suffix in ipairs(INSPECT_SLOT_SUFFIXES) do + hookInspectSlot(suffix) + end +end + +local loader = CreateFrame("Frame") +loader:RegisterEvent("ADDON_LOADED") +loader:RegisterEvent("PLAYER_ENTERING_WORLD") +loader:RegisterEvent("INSPECT_READY") +loader:SetScript("OnEvent", function() + hookInspectSlots() +end) \ No newline at end of file diff --git a/UI/MultiBotOptions.lua b/UI/MultiBotOptions.lua index ac191a9..ee671a1 100644 --- a/UI/MultiBotOptions.lua +++ b/UI/MultiBotOptions.lua @@ -626,7 +626,7 @@ function MultiBot.BuildOptionsPanel() if UIErrorsFrame then UIErrorsFrame:AddMessage(optL("options.layout.error_no_layout_to_delete"), 1, 0.25, 0.25, 1) end - return + return end if not MultiBot.DeleteSavedMainBarLayout then if UIErrorsFrame then From 831316f34c79385638fcdd11d41821f7d37f9eba Mon Sep 17 00:00:00 2001 From: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 2 Apr 2026 23:26:04 +0100 Subject: [PATCH 3/3] Update .luacheckrc --- .luacheckrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.luacheckrc b/.luacheckrc index c3ff305..160778e 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -36,7 +36,7 @@ globals = { "TooltipBackdropTemplateMixin", "NORMAL_FONT_COLOR", "HIGHLIGHT_FONT_COLOR", "GameTooltip_SetDefaultAnchor", "ChatFrame1", "UISpecialFrames", "GetMouseFocus", "ShowUIPanel", "tremove", "min", "max", "GetMinimapShape", "GetMinimapShape", "PanelTemplates_TabResize", "GetGuildRosterShowOffline", "SetGuildRosterShowOffline", "IsInGuild", "GetGuildInfo", "SetGuildRosterShowOffline", "PLAYER", "INVENTORY_TOOLTIP", "BAGSLOT", "UNKNOWN", "UnitIsDead", "ShowPrompt", "_MB_GetOrCreateShamanPos", "ensureHiddenTooltip", "MB_TAB_TITLE_DEFAULT", "SPELLBOOK", "MB_PAGE_DEFAULT", "SPELLBOOK_END_NON_SPELL_STREAK", "sendInventoryItemCommand", - "RAID_CLASS_COLORS", "INSPECT", "MB_INVENTORY_LABEL", "LOADING", "ITEM", "ITEMS", "SEARCH", "NO_QUESTS_LABEL", "QUESTS_LABEL", "QUEST_LOG" + "RAID_CLASS_COLORS", "INSPECT", "MB_INVENTORY_LABEL", "LOADING", "ITEM", "ITEMS", "SEARCH", "NO_QUESTS_LABEL", "QUESTS_LABEL", "QUEST_LOG", "UnitIsUnit" } read_globals = {