From 9e5d28ba0d20c68924e1adaec22fd20dd8f9c895 Mon Sep 17 00:00:00 2001 From: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 27 Aug 2026 15:46:50 +0100 Subject: [PATCH 1/2] Replace Quest/Skill loot profiles with Disenchant and sync loot mainbar --- Core/MultiBotComm.lua | 3 +-- Locales/MultiBotAceLocale-deDE.lua | 6 ++--- Locales/MultiBotAceLocale-enGB.lua | 6 ++--- Locales/MultiBotAceLocale-enUS.lua | 6 ++--- Locales/MultiBotAceLocale-esES.lua | 6 ++--- Locales/MultiBotAceLocale-frFR.lua | 6 ++--- Locales/MultiBotAceLocale-koKR.lua | 6 ++--- Locales/MultiBotAceLocale-ruRU.lua | 6 ++--- Locales/MultiBotAceLocale-zhCN.lua | 6 ++--- UI/MultiBotLootUI.lua | 39 +++++++++++++++++------------- 10 files changed, 39 insertions(+), 51 deletions(-) diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index 5a4481e..e026697 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -9078,8 +9078,7 @@ function Comm.HandleAddonMessage(prefix, message, distribution, sender) all = L("loot.profile.all", "All"), normal = L("loot.profile.normal", "Normal"), gray = L("loot.profile.gray", "Gray"), - quest = L("loot.profile.quest", "Quest"), - skill = L("loot.profile.skill", "Skill"), + disenchant = L("loot.profile.disenchant", "Disenchant"), })[profile] or profile systemMessage(string.format(L("loot.confirm.profile", "Loot profile set to %s for %d bot(s)."), profileName, executed)) diff --git a/Locales/MultiBotAceLocale-deDE.lua b/Locales/MultiBotAceLocale-deDE.lua index fe63060..f4c04a5 100644 --- a/Locales/MultiBotAceLocale-deDE.lua +++ b/Locales/MultiBotAceLocale-deDE.lua @@ -330,8 +330,7 @@ local deDEValues = { ["tips.loot.all"] = "Beuteprofil: Alles", ["tips.loot.normal"] = "Beuteprofil: Normal", ["tips.loot.gray"] = "Beuteprofil: Grau", - ["tips.loot.quest"] = "Beuteprofil: Quest", - ["tips.loot.skill"] = "Beuteprofil: Beruf", + ["tips.loot.disenchant"] = "Beuteprofil: Entzaubern|cffffffff\nNormale Beute + ungewöhnliche oder bessere Waffen und Rüstungen, die nicht beim Aufheben gebunden werden. Dieses Profil entzaubert Gegenstände nicht automatisch.|r", ["loot.bridge.required"] = "Die Beute-Bridge ist nicht verbunden.", ["loot.confirm.none"] = "Der Beutebefehl wurde auf keinen Bot angewendet.", ["loot.confirm.enable"] = "Beute für %d Bot(s) aktiviert.", @@ -340,8 +339,7 @@ local deDEValues = { ["loot.profile.all"] = "Alles", ["loot.profile.normal"] = "Normal", ["loot.profile.gray"] = "Grau", - ["loot.profile.quest"] = "Quest", - ["loot.profile.skill"] = "Beruf", + ["loot.profile.disenchant"] = "Entzaubern", ["disperse.bridge.required"] = "Position-Bridge ist nicht verbunden.", ["disperse.invalid_distance"] = "Gib eine Distanz zwischen 1 und 100 Yards ein.", ["disperse.confirm.set"] = "Disperse auf %s Yards gesetzt.", diff --git a/Locales/MultiBotAceLocale-enGB.lua b/Locales/MultiBotAceLocale-enGB.lua index fdd59f4..341fb54 100644 --- a/Locales/MultiBotAceLocale-enGB.lua +++ b/Locales/MultiBotAceLocale-enGB.lua @@ -330,8 +330,7 @@ local enGBValues = { ["tips.loot.all"] = "Loot profile: All", ["tips.loot.normal"] = "Loot profile: Normal", ["tips.loot.gray"] = "Loot profile: Gray", - ["tips.loot.quest"] = "Loot profile: Quest", - ["tips.loot.skill"] = "Loot profile: Skill", + ["tips.loot.disenchant"] = "Loot profile: Disenchant|cffffffff\nNormal loot + uncommon or better weapons and armour that are not Bind on Pickup. This profile does not automatically disenchant items.|r", ["loot.bridge.required"] = "Loot bridge is not connected.", ["loot.confirm.none"] = "Loot command was not applied to any bot.", ["loot.confirm.enable"] = "Loot enabled for %d bot(s).", @@ -340,8 +339,7 @@ local enGBValues = { ["loot.profile.all"] = "All", ["loot.profile.normal"] = "Normal", ["loot.profile.gray"] = "Gray", - ["loot.profile.quest"] = "Quest", - ["loot.profile.skill"] = "Skill", + ["loot.profile.disenchant"] = "Disenchant", ["disperse.bridge.required"] = "Position bridge is not connected.", ["disperse.invalid_distance"] = "Enter a distance between 1 and 100 yards.", ["disperse.confirm.set"] = "Disperse set to %s yards.", diff --git a/Locales/MultiBotAceLocale-enUS.lua b/Locales/MultiBotAceLocale-enUS.lua index 4aa5afd..36bbd4e 100644 --- a/Locales/MultiBotAceLocale-enUS.lua +++ b/Locales/MultiBotAceLocale-enUS.lua @@ -330,8 +330,7 @@ local enUSValues = { ["tips.loot.all"] = "Loot profile: All", ["tips.loot.normal"] = "Loot profile: Normal", ["tips.loot.gray"] = "Loot profile: Gray", - ["tips.loot.quest"] = "Loot profile: Quest", - ["tips.loot.skill"] = "Loot profile: Skill", + ["tips.loot.disenchant"] = "Loot profile: Disenchant|cffffffff\nNormal loot + uncommon or better weapons and armor that are not Bind on Pickup. This profile does not automatically disenchant items.|r", ["loot.bridge.required"] = "Loot bridge is not connected.", ["loot.confirm.none"] = "Loot command was not applied to any bot.", ["loot.confirm.enable"] = "Loot enabled for %d bot(s).", @@ -340,8 +339,7 @@ local enUSValues = { ["loot.profile.all"] = "All", ["loot.profile.normal"] = "Normal", ["loot.profile.gray"] = "Gray", - ["loot.profile.quest"] = "Quest", - ["loot.profile.skill"] = "Skill", + ["loot.profile.disenchant"] = "Disenchant", ["disperse.bridge.required"] = "Position bridge is not connected.", ["disperse.invalid_distance"] = "Enter a distance between 1 and 100 yards.", ["disperse.confirm.set"] = "Disperse set to %s yards.", diff --git a/Locales/MultiBotAceLocale-esES.lua b/Locales/MultiBotAceLocale-esES.lua index c7aa10d..b9af32e 100644 --- a/Locales/MultiBotAceLocale-esES.lua +++ b/Locales/MultiBotAceLocale-esES.lua @@ -330,8 +330,7 @@ local esESValues = { ["tips.loot.all"] = "Perfil de botín: Todo", ["tips.loot.normal"] = "Perfil de botín: Normal", ["tips.loot.gray"] = "Perfil de botín: Gris", - ["tips.loot.quest"] = "Perfil de botín: Misión", - ["tips.loot.skill"] = "Perfil de botín: Profesión", + ["tips.loot.disenchant"] = "Perfil de botín: Desencantar|cffffffff\nBotín normal + armas y armaduras poco comunes o superiores que no se ligan al recogerlas. Este perfil no desencanta los objetos automáticamente.|r", ["loot.bridge.required"] = "El bridge de botín no está conectado.", ["loot.confirm.none"] = "El comando de botín no se aplicó a ningún bot.", ["loot.confirm.enable"] = "Botín activado para %d bot(s).", @@ -340,8 +339,7 @@ local esESValues = { ["loot.profile.all"] = "Todo", ["loot.profile.normal"] = "Normal", ["loot.profile.gray"] = "Gris", - ["loot.profile.quest"] = "Misión", - ["loot.profile.skill"] = "Profesión", + ["loot.profile.disenchant"] = "Desencantar", ["disperse.bridge.required"] = "El puente de posición no está conectado.", ["disperse.invalid_distance"] = "Introduce una distancia entre 1 y 100 yardas.", ["disperse.confirm.set"] = "Dispersión establecida a %s yardas.", diff --git a/Locales/MultiBotAceLocale-frFR.lua b/Locales/MultiBotAceLocale-frFR.lua index 334b305..89f123b 100644 --- a/Locales/MultiBotAceLocale-frFR.lua +++ b/Locales/MultiBotAceLocale-frFR.lua @@ -330,8 +330,7 @@ local frFRValues = { ["tips.loot.all"] = "Profil de butin : Tout", ["tips.loot.normal"] = "Profil de butin : Normal", ["tips.loot.gray"] = "Profil de butin : Gris", - ["tips.loot.quest"] = "Profil de butin : Quête", - ["tips.loot.skill"] = "Profil de butin : Métier", + ["tips.loot.disenchant"] = "Profil de butin : Désenchantement|cffffffff\nButin normal + armes et armures inhabituelles ou supérieures qui ne sont pas liées quand ramassées. Ce profil ne désenchante pas automatiquement les objets.|r", ["loot.bridge.required"] = "Le bridge du butin n’est pas connecté.", ["loot.confirm.none"] = "La commande de butin n’a été appliquée à aucun bot.", ["loot.confirm.enable"] = "Butin activé pour %d bot(s).", @@ -340,8 +339,7 @@ local frFRValues = { ["loot.profile.all"] = "Tout", ["loot.profile.normal"] = "Normal", ["loot.profile.gray"] = "Gris", - ["loot.profile.quest"] = "Quête", - ["loot.profile.skill"] = "Métier", + ["loot.profile.disenchant"] = "Désenchantement", ["disperse.bridge.required"] = "Le bridge de position n’est pas connecté.", ["disperse.invalid_distance"] = "Entre une distance entre 1 et 100 yards.", ["disperse.confirm.set"] = "Disperse défini à %s yards.", diff --git a/Locales/MultiBotAceLocale-koKR.lua b/Locales/MultiBotAceLocale-koKR.lua index c4ef7e8..2288f16 100644 --- a/Locales/MultiBotAceLocale-koKR.lua +++ b/Locales/MultiBotAceLocale-koKR.lua @@ -330,8 +330,7 @@ local koKRValues = { ["tips.loot.all"] = "전리품 프로필: 전체", ["tips.loot.normal"] = "전리품 프로필: 일반", ["tips.loot.gray"] = "전리품 프로필: 회색", - ["tips.loot.quest"] = "전리품 프로필: 퀘스트", - ["tips.loot.skill"] = "전리품 프로필: 전문기술", + ["tips.loot.disenchant"] = "전리품 프로필: 마력 추출|cffffffff\n일반 전리품 + 획득 시 귀속이 아닌 고급 등급 이상의 무기와 방어구를 획득합니다. 이 프로필은 아이템을 자동으로 마력 추출하지 않습니다.|r", ["loot.bridge.required"] = "전리품 브리지가 연결되어 있지 않습니다.", ["loot.confirm.none"] = "전리품 명령이 어떤 봇에도 적용되지 않았습니다.", ["loot.confirm.enable"] = "%d 봇에게 전리품을 켰습니다.", @@ -340,8 +339,7 @@ local koKRValues = { ["loot.profile.all"] = "전체", ["loot.profile.normal"] = "일반", ["loot.profile.gray"] = "회색", - ["loot.profile.quest"] = "퀘스트", - ["loot.profile.skill"] = "전문기술", + ["loot.profile.disenchant"] = "마력 추출", ["disperse.bridge.required"] = "위치 브리지가 연결되어 있지 않습니다.", ["disperse.invalid_distance"] = "1에서 100 야드 사이의 거리를 입력하세요.", ["disperse.confirm.set"] = "분산 거리가 %s 야드로 설정되었습니다.", diff --git a/Locales/MultiBotAceLocale-ruRU.lua b/Locales/MultiBotAceLocale-ruRU.lua index 0dda507..af8e817 100644 --- a/Locales/MultiBotAceLocale-ruRU.lua +++ b/Locales/MultiBotAceLocale-ruRU.lua @@ -330,8 +330,7 @@ local ruRUValues = { ["tips.loot.all"] = "Профиль добычи: Всё", ["tips.loot.normal"] = "Профиль добычи: Обычное", ["tips.loot.gray"] = "Профиль добычи: Серое", - ["tips.loot.quest"] = "Профиль добычи: Задания", - ["tips.loot.skill"] = "Профиль добычи: Профессии", + ["tips.loot.disenchant"] = "Профиль добычи: Распыление|cffffffff\nОбычная добыча + оружие и броня необычного качества или выше, не становящиеся персональными при получении. Этот профиль не распыляет предметы автоматически.|r", ["loot.bridge.required"] = "Мост добычи не подключён.", ["loot.confirm.none"] = "Команда добычи не применена ни к одному боту.", ["loot.confirm.enable"] = "Добыча включена для %d бот(ов).", @@ -340,8 +339,7 @@ local ruRUValues = { ["loot.profile.all"] = "Всё", ["loot.profile.normal"] = "Обычное", ["loot.profile.gray"] = "Серое", - ["loot.profile.quest"] = "Задания", - ["loot.profile.skill"] = "Профессии", + ["loot.profile.disenchant"] = "Распыление", ["disperse.bridge.required"] = "Мост позиционирования не подключен.", ["disperse.invalid_distance"] = "Введите дистанцию от 1 до 100 ярдов.", ["disperse.confirm.set"] = "Рассредоточение установлено на %s ярдов.", diff --git a/Locales/MultiBotAceLocale-zhCN.lua b/Locales/MultiBotAceLocale-zhCN.lua index 26de0d8..69941b2 100644 --- a/Locales/MultiBotAceLocale-zhCN.lua +++ b/Locales/MultiBotAceLocale-zhCN.lua @@ -330,8 +330,7 @@ local zhCNValues = { ["tips.loot.all"] = "拾取配置:全部", ["tips.loot.normal"] = "拾取配置:普通", ["tips.loot.gray"] = "拾取配置:灰色", - ["tips.loot.quest"] = "拾取配置:任务", - ["tips.loot.skill"] = "拾取配置:专业", + ["tips.loot.disenchant"] = "拾取配置:分解|cffffffff\n普通拾取 + 非拾取绑定的优秀或更高品质武器和护甲。此配置不会自动分解物品。|r", ["loot.bridge.required"] = "拾取桥接未连接。", ["loot.confirm.none"] = "拾取命令未应用到任何机器人。", ["loot.confirm.enable"] = "已为 %d 个机器人启用拾取。", @@ -340,8 +339,7 @@ local zhCNValues = { ["loot.profile.all"] = "全部", ["loot.profile.normal"] = "普通", ["loot.profile.gray"] = "灰色", - ["loot.profile.quest"] = "任务", - ["loot.profile.skill"] = "专业", + ["loot.profile.disenchant"] = "分解", ["disperse.bridge.required"] = "位置桥接未连接。", ["disperse.invalid_distance"] = "请输入 1 到 100 码之间的距离。", ["disperse.confirm.set"] = "分散距离已设置为 %s 码。", diff --git a/UI/MultiBotLootUI.lua b/UI/MultiBotLootUI.lua index d1c107a..f818a59 100644 --- a/UI/MultiBotLootUI.lua +++ b/UI/MultiBotLootUI.lua @@ -12,18 +12,16 @@ local LOOT_COMMANDS = { { key = "all", command = "ll all", icon = "inv_misc_bag_10", tip = "tips.loot.all", fallback = "Loot profile: All" }, { key = "normal", command = "ll normal", icon = "inv_misc_bag_11", tip = "tips.loot.normal", fallback = "Loot profile: Normal" }, { key = "gray", command = "ll gray", icon = "inv_misc_coin_01", tip = "tips.loot.gray", fallback = "Loot profile: Gray" }, - { key = "quest", command = "ll quest", icon = "inv_misc_note_05", tip = "tips.loot.quest", fallback = "Loot profile: Quest" }, - { key = "skill", command = "ll skill", icon = "inv_misc_book_07", tip = "tips.loot.skill", fallback = "Loot profile: Skill" }, + { key = "disenchant", command = "ll disenchant", icon = "inv_misc_book_07", tip = "tips.loot.disenchant", fallback = "Loot profile: Disenchant" }, { key = "additem", action = "ADD", icon = "inv_misc_bag_10", tip = "loot.item.add", fallback = "Always loot: add item" }, { key = "removeitem", action = "REMOVE", icon = "inv_misc_bag_07", tip = "loot.item.remove", fallback = "Always loot: remove item" }, } -local LOOT_PROFILE_KEYS = { - all = true, - normal = true, - gray = true, - quest = true, - skill = true, +local LOOT_PROFILE_ENTRIES = { + all = LOOT_COMMANDS[3], + normal = LOOT_COMMANDS[4], + gray = LOOT_COMMANDS[5], + disenchant = LOOT_COMMANDS[6], } local lootVisualState = { @@ -196,6 +194,21 @@ function MultiBot.BuildLootUI(tLeft) if lootVisualState.profile and menuButtonsByKey[lootVisualState.profile] then menuButtonsByKey[lootVisualState.profile].setEnable() end + + if button then + local profileEntry = lootVisualState.profile and LOOT_PROFILE_ENTRIES[lootVisualState.profile] or nil + if profileEntry then + button.setButton(profileEntry.icon, L(profileEntry.tip, profileEntry.fallback)) + else + button.setButton("inv_misc_bag_10", L("tips.loot.main", "Loot rules")) + end + + if lootVisualState.enabled == true then + button.setEnable(false) + else + button.setDisable(false) + end + end end MultiBot.OnLootCommandApplied = function(command, executed) @@ -210,10 +223,9 @@ function MultiBot.BuildLootUI(tLeft) lootVisualState.enabled = true elseif command == "nc -loot" then lootVisualState.enabled = false - lootVisualState.profile = nil else local profile = command:match("^ll%s+([%w_%-]+)$") - if profile and LOOT_PROFILE_KEYS[profile] then + if profile and LOOT_PROFILE_ENTRIES[profile] then lootVisualState.profile = profile end end @@ -230,13 +242,6 @@ function MultiBot.BuildLootUI(tLeft) end end - if button then - if shown then - button.setEnable() - else - button.setDisable() - end - end updateClickBlocker() end From d9ce72a3cdb29dc24054045bb77020b8c53c2c3d Mon Sep 17 00:00:00 2001 From: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 27 Aug 2026 20:34:12 +0100 Subject: [PATCH 2/2] Sync loot Disenchant docs and tooltip wrapping --- Locales/MultiBotAceLocale-deDE.lua | 2 +- Locales/MultiBotAceLocale-enGB.lua | 2 +- Locales/MultiBotAceLocale-enUS.lua | 2 +- Locales/MultiBotAceLocale-esES.lua | 2 +- Locales/MultiBotAceLocale-frFR.lua | 2 +- Locales/MultiBotAceLocale-koKR.lua | 2 +- Locales/MultiBotAceLocale-ruRU.lua | 2 +- Locales/MultiBotAceLocale-zhCN.lua | 2 +- README.md | 15 +++++++-------- docs/ROADMAP.md | 16 ++++++++-------- 10 files changed, 23 insertions(+), 24 deletions(-) diff --git a/Locales/MultiBotAceLocale-deDE.lua b/Locales/MultiBotAceLocale-deDE.lua index f4c04a5..bb231f2 100644 --- a/Locales/MultiBotAceLocale-deDE.lua +++ b/Locales/MultiBotAceLocale-deDE.lua @@ -330,7 +330,7 @@ local deDEValues = { ["tips.loot.all"] = "Beuteprofil: Alles", ["tips.loot.normal"] = "Beuteprofil: Normal", ["tips.loot.gray"] = "Beuteprofil: Grau", - ["tips.loot.disenchant"] = "Beuteprofil: Entzaubern|cffffffff\nNormale Beute + ungewöhnliche oder bessere Waffen und Rüstungen, die nicht beim Aufheben gebunden werden. Dieses Profil entzaubert Gegenstände nicht automatisch.|r", + ["tips.loot.disenchant"] = "Beuteprofil: Entzaubern|cffffffff\nNormale Beute + ungewöhnliche oder bessere Waffen und Rüstungen, die nicht beim Aufheben gebunden werden.\nDieses Profil entzaubert Gegenstände nicht automatisch.|r", ["loot.bridge.required"] = "Die Beute-Bridge ist nicht verbunden.", ["loot.confirm.none"] = "Der Beutebefehl wurde auf keinen Bot angewendet.", ["loot.confirm.enable"] = "Beute für %d Bot(s) aktiviert.", diff --git a/Locales/MultiBotAceLocale-enGB.lua b/Locales/MultiBotAceLocale-enGB.lua index 341fb54..4cfa616 100644 --- a/Locales/MultiBotAceLocale-enGB.lua +++ b/Locales/MultiBotAceLocale-enGB.lua @@ -330,7 +330,7 @@ local enGBValues = { ["tips.loot.all"] = "Loot profile: All", ["tips.loot.normal"] = "Loot profile: Normal", ["tips.loot.gray"] = "Loot profile: Gray", - ["tips.loot.disenchant"] = "Loot profile: Disenchant|cffffffff\nNormal loot + uncommon or better weapons and armour that are not Bind on Pickup. This profile does not automatically disenchant items.|r", + ["tips.loot.disenchant"] = "Loot profile: Disenchant|cffffffff\nNormal loot + uncommon or better weapons and armour that are not Bind on Pickup.\nThis profile does not automatically disenchant items.|r", ["loot.bridge.required"] = "Loot bridge is not connected.", ["loot.confirm.none"] = "Loot command was not applied to any bot.", ["loot.confirm.enable"] = "Loot enabled for %d bot(s).", diff --git a/Locales/MultiBotAceLocale-enUS.lua b/Locales/MultiBotAceLocale-enUS.lua index 36bbd4e..4a0c40a 100644 --- a/Locales/MultiBotAceLocale-enUS.lua +++ b/Locales/MultiBotAceLocale-enUS.lua @@ -330,7 +330,7 @@ local enUSValues = { ["tips.loot.all"] = "Loot profile: All", ["tips.loot.normal"] = "Loot profile: Normal", ["tips.loot.gray"] = "Loot profile: Gray", - ["tips.loot.disenchant"] = "Loot profile: Disenchant|cffffffff\nNormal loot + uncommon or better weapons and armor that are not Bind on Pickup. This profile does not automatically disenchant items.|r", + ["tips.loot.disenchant"] = "Loot profile: Disenchant|cffffffff\nNormal loot + uncommon or better weapons and armor that are not Bind on Pickup.\nThis profile does not automatically disenchant items.|r", ["loot.bridge.required"] = "Loot bridge is not connected.", ["loot.confirm.none"] = "Loot command was not applied to any bot.", ["loot.confirm.enable"] = "Loot enabled for %d bot(s).", diff --git a/Locales/MultiBotAceLocale-esES.lua b/Locales/MultiBotAceLocale-esES.lua index b9af32e..28f1b83 100644 --- a/Locales/MultiBotAceLocale-esES.lua +++ b/Locales/MultiBotAceLocale-esES.lua @@ -330,7 +330,7 @@ local esESValues = { ["tips.loot.all"] = "Perfil de botín: Todo", ["tips.loot.normal"] = "Perfil de botín: Normal", ["tips.loot.gray"] = "Perfil de botín: Gris", - ["tips.loot.disenchant"] = "Perfil de botín: Desencantar|cffffffff\nBotín normal + armas y armaduras poco comunes o superiores que no se ligan al recogerlas. Este perfil no desencanta los objetos automáticamente.|r", + ["tips.loot.disenchant"] = "Perfil de botín: Desencantar|cffffffff\nBotín normal + armas y armaduras poco comunes o superiores que no se ligan al recogerlas.\nEste perfil no desencanta los objetos automáticamente.|r", ["loot.bridge.required"] = "El bridge de botín no está conectado.", ["loot.confirm.none"] = "El comando de botín no se aplicó a ningún bot.", ["loot.confirm.enable"] = "Botín activado para %d bot(s).", diff --git a/Locales/MultiBotAceLocale-frFR.lua b/Locales/MultiBotAceLocale-frFR.lua index 89f123b..8203047 100644 --- a/Locales/MultiBotAceLocale-frFR.lua +++ b/Locales/MultiBotAceLocale-frFR.lua @@ -330,7 +330,7 @@ local frFRValues = { ["tips.loot.all"] = "Profil de butin : Tout", ["tips.loot.normal"] = "Profil de butin : Normal", ["tips.loot.gray"] = "Profil de butin : Gris", - ["tips.loot.disenchant"] = "Profil de butin : Désenchantement|cffffffff\nButin normal + armes et armures inhabituelles ou supérieures qui ne sont pas liées quand ramassées. Ce profil ne désenchante pas automatiquement les objets.|r", + ["tips.loot.disenchant"] = "Profil de butin : Désenchantement|cffffffff\nButin normal + armes et armures inhabituelles ou supérieures qui ne sont pas liées quand ramassées.\nCe profil ne désenchante pas automatiquement les objets.|r", ["loot.bridge.required"] = "Le bridge du butin n’est pas connecté.", ["loot.confirm.none"] = "La commande de butin n’a été appliquée à aucun bot.", ["loot.confirm.enable"] = "Butin activé pour %d bot(s).", diff --git a/Locales/MultiBotAceLocale-koKR.lua b/Locales/MultiBotAceLocale-koKR.lua index 2288f16..7d4ac0f 100644 --- a/Locales/MultiBotAceLocale-koKR.lua +++ b/Locales/MultiBotAceLocale-koKR.lua @@ -330,7 +330,7 @@ local koKRValues = { ["tips.loot.all"] = "전리품 프로필: 전체", ["tips.loot.normal"] = "전리품 프로필: 일반", ["tips.loot.gray"] = "전리품 프로필: 회색", - ["tips.loot.disenchant"] = "전리품 프로필: 마력 추출|cffffffff\n일반 전리품 + 획득 시 귀속이 아닌 고급 등급 이상의 무기와 방어구를 획득합니다. 이 프로필은 아이템을 자동으로 마력 추출하지 않습니다.|r", + ["tips.loot.disenchant"] = "전리품 프로필: 마력 추출|cffffffff\n일반 전리품 + 획득 시 귀속이 아닌 고급 등급 이상의 무기와 방어구를 획득합니다.\n이 프로필은 아이템을 자동으로 마력 추출하지 않습니다.|r", ["loot.bridge.required"] = "전리품 브리지가 연결되어 있지 않습니다.", ["loot.confirm.none"] = "전리품 명령이 어떤 봇에도 적용되지 않았습니다.", ["loot.confirm.enable"] = "%d 봇에게 전리품을 켰습니다.", diff --git a/Locales/MultiBotAceLocale-ruRU.lua b/Locales/MultiBotAceLocale-ruRU.lua index af8e817..844e0b8 100644 --- a/Locales/MultiBotAceLocale-ruRU.lua +++ b/Locales/MultiBotAceLocale-ruRU.lua @@ -330,7 +330,7 @@ local ruRUValues = { ["tips.loot.all"] = "Профиль добычи: Всё", ["tips.loot.normal"] = "Профиль добычи: Обычное", ["tips.loot.gray"] = "Профиль добычи: Серое", - ["tips.loot.disenchant"] = "Профиль добычи: Распыление|cffffffff\nОбычная добыча + оружие и броня необычного качества или выше, не становящиеся персональными при получении. Этот профиль не распыляет предметы автоматически.|r", + ["tips.loot.disenchant"] = "Профиль добычи: Распыление|cffffffff\nОбычная добыча + оружие и броня необычного качества или выше, не становящиеся персональными при получении.\nЭтот профиль не распыляет предметы автоматически.|r", ["loot.bridge.required"] = "Мост добычи не подключён.", ["loot.confirm.none"] = "Команда добычи не применена ни к одному боту.", ["loot.confirm.enable"] = "Добыча включена для %d бот(ов).", diff --git a/Locales/MultiBotAceLocale-zhCN.lua b/Locales/MultiBotAceLocale-zhCN.lua index 69941b2..ed76b92 100644 --- a/Locales/MultiBotAceLocale-zhCN.lua +++ b/Locales/MultiBotAceLocale-zhCN.lua @@ -330,7 +330,7 @@ local zhCNValues = { ["tips.loot.all"] = "拾取配置:全部", ["tips.loot.normal"] = "拾取配置:普通", ["tips.loot.gray"] = "拾取配置:灰色", - ["tips.loot.disenchant"] = "拾取配置:分解|cffffffff\n普通拾取 + 非拾取绑定的优秀或更高品质武器和护甲。此配置不会自动分解物品。|r", + ["tips.loot.disenchant"] = "拾取配置:分解|cffffffff\n普通拾取 + 非拾取绑定的优秀或更高品质武器和护甲。\n此配置不会自动分解物品。|r", ["loot.bridge.required"] = "拾取桥接未连接。", ["loot.confirm.none"] = "拾取命令未应用到任何机器人。", ["loot.confirm.enable"] = "已为 %d 个机器人启用拾取。", diff --git a/README.md b/README.md index 758d802..f2b2dfc 100644 --- a/README.md +++ b/README.md @@ -643,7 +643,7 @@ Implemented bridge-first / chatless areas: - Disperse controls through the bridge with `disperse set ` and `disperse disable`. - Party/raid-wide formation application through `RUN~FORMATION`, with per-bot effective formation inspection through `GET~FORMATIONS` and no PARTY/RAID chat output. - Localized formation status tooltip for all eight addon locale files. -- Loot rules through the bridge with `nc +loot` and `nc -loot`. For the audited Playerbots build, the verified loot-list modes are `all`, `normal`, `gray` and `disenchant`; the older Quest/Skill wording is not treated as a validated capability and remains a separate roadmap decision. Exact always-loot item add/remove is handled by `LOOT_RULE_ITEM_V1`. +- Loot rules through the bridge with `nc +loot` and `nc -loot`. For the audited Playerbots build, the verified loot-list modes are `all`, `normal`, `gray` and `disenchant`; the older Quest/Skill wording is not treated as a validated capability. The audited Playerbots profile set is `all`, `normal`, `gray` and `disenchant`; the Quest/Skill versus Disenchant decision is closed in favor of `disenchant`. Exact always-loot item add/remove is handled by `LOOT_RULE_ITEM_V1`. - Loot Master UI for master-loot distribution with item tooltips, candidate scoring, profession/spec hints, saved preferences and recent loot history. - Bridge-visible bot discovery for AddClass bots, altbots and grouped randombots. - Custom glyph socket mapping and apply order. @@ -683,7 +683,7 @@ Validated development milestones on the current line: `SELL_VENDOR` safety hardening was completed and runtime revalidated on 2026-08-23. The Addon remains bridge-first and exposes the historical `s vendor` whisper only when `MultiBot.allowLegacyChatFallback == true`; the Bridge accepts `ITEM_USAGE_VENDOR` only for this action and excludes `ITEM_USAGE_AH`. Symbol of Kings and Gold Ore were both preserved in the runtime regression test while `SELL_VENDOR` remained functional. Validated commits: Addon `fe2c807785219b82ca885f1a95d7c1dc27f0eed0`, Bridge `3ccf5047f7994218b742312fe1437f4b303f7159`. -The bank / guild-bank comparison produced the completed `ITEM_DEPOSIT_EXACT_V1` P3A path. Exact BANK withdrawal (P3B) and exact GBANK withdrawal (P3C) remain intentionally deferred because their current read models do not expose a physical source stack end to end. `LOOT_RULE_ITEM_V1` is now also complete, runtime validated, persistent and localized. The next normal-roadmap decision is Quest/Skill versus Disenchant based on the Playerbots capabilities actually present in the audited build. +The bank / guild-bank comparison produced the completed `ITEM_DEPOSIT_EXACT_V1` P3A path. Exact BANK withdrawal (P3B) and exact GBANK withdrawal (P3C) remain intentionally deferred because their current read models do not expose a physical source stack end to end. `LOOT_RULE_ITEM_V1` is now also complete, runtime validated, persistent and localized. The Quest/Skill versus Disenchant decision is now closed from the audited Playerbots implementation: `disenchant` is retained, while `Quest` and `Skill` are not exposed as validated loot profiles. The next normal-roadmap work is the selector audit for collective `follow` / `attack` / `stay` orders. `LOOT_RULE_ITEM_V1` adds or removes one exact `itemId` from the audited Playerbots `always loot list` value. The protocol supports `ALL`, `RAID`, `GROUP`, `PARTY` and `BOT` scopes; the current Loot menu intentionally sends `ALL`. The Bridge revalidates requester/session/world state, strict scope/target syntax, visible controllable bots, Playerbots security, bot session/world/alive/context and the item template before mutation, with a maximum of 128 matched bots. Requests are bounded to 8 per requester per 2 seconds with 10-second replay protection, 32 recent tokens and 512 requester states. Only bots whose list actually changes are persisted, and a global budget of 128 bot saves per 10 seconds rejects the whole operation with `PERSISTENCE_BUSY` before mutation when insufficient capacity remains. Runtime validation covered ADD, idempotent ADD, REMOVE, idempotent REMOVE, invalid input/item rejection, item-link input, disconnect/reconnect persistence, full worldserver-restart persistence, localized results in the eight existing locale files and the corrected clickable/editable prompt, with no chat/whisper spam observed. Known migration remaining: @@ -694,7 +694,7 @@ Known migration remaining: - `ITEM_MOVE_V1` already covers whole-stack movement between allowed Backpack / Bag 1..4 / Keyring physical slots, including inter-container moves. A future `BAG_MOVE` item must therefore mean moving/re-equipping the **bag objects themselves** in equipped bag slots, not moving ordinary inventory items. - Generic exact-item Trade is now implemented and runtime validated through `ITEM_TRADE_V1`; it remains distinct from the specialized `ENCHANT_TRADE_V1` service and does not expose a generic command executor. - Quest abandon is now implemented through `QUEST_ABANDON_V1` and runtime validated with one bot. Quest sharing remains native through `QuestLogPushQuest()`. The mixed multi-bot Quest Abandon runtime scenario is deferred until suitable bots are available. -- `TALENT_APPLY_V1`, `TALENT_SPEC_APPLY_V1`, `CRAFT_RECIPE_TARGET_V1`, P3A `ITEM_DEPOSIT_EXACT_V1` and `LOOT_RULE_ITEM_V1` are complete and runtime validated. `ITEM_DEPOSIT_EXACT_V1` moves only the selected physical inventory stack for BANK/GBANK deposits and rejects stale `bag/slot/itemId/count` identity before mutation. `LOOT_RULE_ITEM_V1` performs exact persistent always-loot add/remove with structured results and bounded persistence. P3B/P3C exact withdrawals are deferred. The next normal-roadmap item is the Quest/Skill versus Disenchant decision, followed by collective `follow` / `attack` / `stay` orders. +- `TALENT_APPLY_V1`, `TALENT_SPEC_APPLY_V1`, `CRAFT_RECIPE_TARGET_V1`, P3A `ITEM_DEPOSIT_EXACT_V1` and `LOOT_RULE_ITEM_V1` are complete and runtime validated. `ITEM_DEPOSIT_EXACT_V1` moves only the selected physical inventory stack for BANK/GBANK deposits and rejects stale `bag/slot/itemId/count` identity before mutation. `LOOT_RULE_ITEM_V1` performs exact persistent always-loot add/remove with structured results and bounded persistence. P3B/P3C exact withdrawals are deferred. The Quest/Skill versus Disenchant decision is complete: `disenchant` is the verified Playerbots loot profile retained by the UI, while `Quest` and `Skill` are not exposed as validated loot profiles. The next normal-roadmap item is the collective `follow` / `attack` / `stay` selector audit. - The project should be described as **bridge-first / mostly chatless**, not fully chatless, until these remaining paths are classified/migrated and the final runtime matrix is closed. Kept intentionally: @@ -708,14 +708,13 @@ Kept intentionally: # Remaining Work -The current `jellypowered-chatless-integration-v2` line starts from the merged Jellypowered inventory baseline plus the separately completed SelfBot work. Its validated v2 feature batch is complete through `LOOT_RULE_ITEM_V1`. Addon PR #73 and Bridge PR #32 are already open from `jellypowered-chatless-integration-v2` toward `main`. No new functional work should be stacked onto these branches before their closure/merge; after merge, normal-roadmap development should restart on new branches created from the updated `main` baselines. +The previous `jellypowered-chatless-integration-v2` line is now historical baseline context. Current audited development is on `feature/loot-disenchant-mainbar` in both the Addon and Bridge. That branch carries the completed Quest/Skill-to-Disenchant profile change and MainBar loot-profile synchronization. Normal-roadmap development now continues from the updated `main` baselines; no new functional work should be stacked onto the historical v2 branches. -Immediate roadmap work after those merges: +Immediate normal-roadmap work: -1. Decide the Quest/Skill versus Disenchant path from verified Playerbots capabilities; do not infer unsupported loot modes from historical documentation. -2. Audit collective `follow`, `attack` and `stay` selectors before any structured group-order migration. +1. Audit the exact Playerbots selectors and semantics for collective `follow`, `attack` and `stay` before any structured group-order migration. -Completed on the current v2 line: `TALENT_APPLY_V1`, `TALENT_SPEC_APPLY_V1`, `CRAFT_RECIPE_TARGET_V1`, the 2026-08-23 `SELL_VENDOR` safety hardening, P3A `ITEM_DEPOSIT_EXACT_V1` and `LOOT_RULE_ITEM_V1`. P3A was runtime validated for BANK and GBANK with two identical physical stacks: only the selected stack moved, while a deliberately stale `count` returned `SOURCE_STALE` and left the real stack unchanged. `LOOT_RULE_ITEM_V1` was validated for exact ADD/REMOVE, idempotence, persistence across reconnect and worldserver restart, localized UI/results and no chat/whisper spam. +Completed on the historical `jellypowered-chatless-integration-v2` line: `TALENT_APPLY_V1`, `TALENT_SPEC_APPLY_V1`, `CRAFT_RECIPE_TARGET_V1`, the 2026-08-23 `SELL_VENDOR` safety hardening, P3A `ITEM_DEPOSIT_EXACT_V1` and `LOOT_RULE_ITEM_V1`. P3A was runtime validated for BANK and GBANK with two identical physical stacks: only the selected stack moved, while a deliberately stale `count` returned `SOURCE_STALE` and left the real stack unchanged. `LOOT_RULE_ITEM_V1` was validated for exact ADD/REMOVE, idempotence, persistence across reconnect and worldserver restart, localized UI/results and no chat/whisper spam. Low-priority residual: moving/re-equipping the **equipped bag objects themselves** (`BAG_MOVE`) only if the need remains; ordinary item moves between Backpack / Bag 1..4 / Keyring are already covered by `ITEM_MOVE_V1`. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 1faf599..a90984e 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,7 +1,7 @@ # Multibot Chatless + Bridge — Roadmap de reprise -Statut : roadmap active issue de l'audit initial v1c du 1er août 2026, resynchronisée le 26 août 2026 après clôture de P3A `ITEM_DEPOSIT_EXACT_V1` puis de `LOOT_RULE_ITEM_V1`. Le lot fonctionnel courant des branches `jellypowered-chatless-integration-v2` est terminé. Les PR Addon #73 et Bridge #32 sont ouvertes vers `main` ; aucun nouveau développement fonctionnel ne doit être ajouté à ces branches avant leur clôture/merge. Après merge, la roadmap reprendra sur de nouvelles branches créées depuis les `main` mis à jour. -Dernière mise à jour : 27/08/2026 — `LOOT_RULE_ITEM_V1` est terminé, validé en jeu, audité, archivé, commité et poussé après P3A `ITEM_DEPOSIT_EXACT_V1`. ADD/REMOVE modifie l'`always loot list` vérifiée dans Playerbots pour un `itemId` exact, avec résultats structurés, idempotence, persistance des seuls bots modifiés, budget global de 128 sauvegardes/10 s et rejet pré-mutation `PERSISTENCE_BUSY` lorsque le budget est insuffisant. La persistance a été validée après reconnexion et restart worldserver, le prompt et les résultats sont localisés dans les huit locales présentes, et aucun spam chat/whisper n'a été observé. P3B/P3C, `SOURCE_STALE` UI, SELL_GREY, Firestone/Spellstone et LuaLint restent différés. `TODO.md` reste séparé et inchangé. Le prochain chantier normal est la décision Quest/Skill versus Disenchant à partir des capacités Playerbots réellement présentes. +Statut : roadmap active issue de l'audit initial v1c du 1er août 2026, resynchronisée le 27 août 2026 après clôture de P3A `ITEM_DEPOSIT_EXACT_V1`, de `LOOT_RULE_ITEM_V1` et de la décision Quest/Skill versus Disenchant. Le lot `jellypowered-chatless-integration-v2` est désormais une baseline historique. Le chantier courant est `feature/loot-disenchant-mainbar` dans l'Addon et le Bridge. `disenchant` est le profil Playerbots retenu ; `Quest` et `Skill` ne sont pas traités comme profils de loot validés. Le prochain chantier normal est l'audit des ordres collectifs `follow`, `attack`, `stay`. +Dernière mise à jour : 27/08/2026 — le commit Addon `9e5d28ba0d20c68924e1adaec22fd20dd8f9c895` remplace les profils UI `Quest`/`Skill` par `Disenchant` et synchronise l'état visuel MainBar ; le commit Bridge `c2c48b604a10b619d08f27c39cc5ecf6e3f174a6` remplace la whitelist `Quest`/`Skill` par `Disenchant`. L'audit Playerbots en lecture seule confirme `DisenchantLootStrategy`, `GetName() == "disenchant"` et les alias `d`, `e`, `disenchant`, `enchant`. Le prochain chantier normal est l'audit ciblé des sélecteurs Playerbots pour `follow`, `attack`, `stay`. P3B/P3C, `SOURCE_STALE` UI, `BAG_MOVE`, SELL_GREY, Firestone/Spellstone et LuaLint restent différés ; `TODO.md` reste séparé et inchangé. Cette roadmap est la source de vérité active du projet. `TODO.md` reste un fichier de notes local séparé et est volontairement exclu de cette synchronisation documentaire. ## Baseline auditée @@ -224,7 +224,7 @@ Aucune fonction Extended ne doit être marquée comme intégrée avant validatio `Design inspired by the Jellypowered bridge contribution.` ; - les crédits sont ajoutés uniquement pour les parties réellement intégrées et validées. -Statut : **audit Extended validé ; reprise sélective prioritaire avant la roadmap normale ; merge direct du fork interdit.** L'ancienne branche `feature/jellypowered-chatless-integration` est conservée ici comme référence historique. Le travail courant de clôture est porté par `jellypowered-chatless-integration-v2` dans l'Addon et le Bridge. Les PR Addon #73 et Bridge #32 sont ouvertes vers `main` ; aucun nouveau développement fonctionnel ne doit être ajouté à ces branches avant leur clôture/merge. Après merge, la reprise se fera sur de nouvelles branches créées depuis les `main` mis à jour. +Statut : **audit Extended validé ; reprise sélective réalisée et historique conservé ; merge direct du fork toujours interdit.** L'ancienne branche `feature/jellypowered-chatless-integration` et la ligne `jellypowered-chatless-integration-v2` restent des références historiques. Le développement courant audité est `feature/loot-disenchant-mainbar`, créé depuis les `main` mis à jour et à un commit devant `origin/main` dans l'Addon et le Bridge au pré-patch V1c du 27/08/2026. ## Phase 0 — Assainissement documentaire — TERMINÉE @@ -540,7 +540,7 @@ Ces fonctions doivent rester séparées des patches de correction et de sécurit Critère de sortie : version stabilisée, documentée et reproductible du projet Multibot Chatless + Bridge. - + ## État consolidé Jellypowered / inventaire — 20/08/2026 @@ -604,7 +604,7 @@ Toutes ces intégrations conservent `mod-playerbots` en **lecture seule stricte* - **Résiduel UI basse priorité, non bloquant :** `SOURCE_STALE` utilise encore le libellé générique d'erreur d'action d'objet. - **Résiduel basse priorité, non bloquant :** `BAG_MOVE` concerne uniquement le déplacement/rééquipement des **sacs équipés eux-mêmes**. Les déplacements d'items entre Backpack / sacs 1..4 / Keyring sont déjà terminés via `ITEM_MOVE_V1`. -Le lot banque/GBANK prioritaire est clos pour la roadmap courante. Le chantier suivant, `LOOT_RULE_ITEM_V1`, est lui aussi désormais clos et validé ; la roadmap normale passe à la décision Quest/Skill versus Disenchant. +Le lot banque/GBANK prioritaire est clos pour la roadmap courante. `LOOT_RULE_ITEM_V1` est lui aussi clos et validé. La décision Quest/Skill versus Disenchant est désormais résolue à partir du code Playerbots audité : `disenchant` est retenu ; `Quest` et `Skill` ne sont pas exposés comme profils de loot validés. La roadmap normale passe à l'audit des ordres collectifs `follow`, `attack`, `stay`. ### Clôture règles de loot exactes — `LOOT_RULE_ITEM_V1` validé le 24/08/2026 @@ -616,7 +616,7 @@ Le lot banque/GBANK prioritaire est clos pour la roadmap courante. Le chantier s - Sémantique idempotente validée : `ADDED`, `REMOVED`, `ALREADY_PRESENT`, `ALREADY_ABSENT`, avec `PARTIAL` prévu pour les résultats mixtes et erreurs structurées côté Bridge. - Runtime validé : ADD/REMOVE et répétitions, itemId numérique, Shift+clic lien d'objet, entrée locale invalide sans envoi Bridge, item serveur invalide, persistance déconnexion/reconnexion, persistance après restart worldserver, nettoyage final de l'item de test 6948. - UI/i18n validée : prompt cliquable/éditable corrigé localement sans modifier AceGUI global, `/reload` sans erreur Lua, boutons/résultats localisés dans les huit locales présentes (`deDE`, `enGB`, `enUS`, `esES`, `frFR`, `koKR`, `ruRU`, `zhCN`), aucun spam chat/whisper observé. -- Divergence documentaire conservée comme décision séparée : l'audit du build Playerbots courant ne permet pas de traiter `Quest`/`Skill` comme capacités validées sur la seule foi du wiki ; la prochaine étape doit trancher Quest/Skill versus Disenchant à partir du code réellement présent. +- **Décision Quest/Skill versus Disenchant — TERMINÉE / VALIDÉE** : l'audit du build Playerbots courant confirme une vraie `DisenchantLootStrategy` nommée `disenchant` avec alias `d`, `e`, `disenchant`, `enchant`. L'Addon expose donc `Disenchant` à la place des anciens profils UI `Quest`/`Skill`, et le Bridge n'autorise plus ces anciens libellés dans sa whitelist loot. `mod-playerbots` reste strictement en lecture seule. ### Stabilisation de clôture PR Addon #73 — 27/08/2026 @@ -649,6 +649,6 @@ Ces points sont **préexistants ou hors objectif fonctionnel de la PR #73**. Ils ### Reprise de la roadmap normale -Le **prochain chantier fonctionnel** est : **décision Quest/Skill versus Disenchant à partir des capacités Playerbots réellement présentes**. Aucun endpoint, mode ou stratégie ne doit être conçu avant l'audit ciblé de ce point. +Le **prochain chantier fonctionnel** est : **audit ciblé des ordres collectifs `follow`, `attack`, `stay` et de leurs sélecteurs Playerbots exacts**. Aucun endpoint générique `RUN~ORDER` ne doit être conçu ; les API/actions/sélecteurs réellement présents doivent être vérifiés en lecture seule avant toute proposition. -Le lot fonctionnel courant de `jellypowered-chatless-integration-v2` est terminé avec `LOOT_RULE_ITEM_V1` et la stabilisation de clôture de la PR Addon #73. Les PR Addon #73 et Bridge #32 sont ouvertes vers `main`; aucun nouveau développement fonctionnel ne doit être empilé sur ces branches avant leur clôture/merge. Après merge et mise à jour des `main`, la roadmap normale reprendra sur de nouvelles branches créées depuis ces baselines. P3B/P3C, le libellé `SOURCE_STALE`, `BAG_MOVE`, `SELL_GREY`, Firestone/Spellstone TEMP_ENCHANT, LuaLint et les reliquats techniques explicitement différés ci-dessus restent hors du prochain chantier. +Le lot fonctionnel `jellypowered-chatless-integration-v2` reste une baseline historique terminée. Le développement courant est `feature/loot-disenchant-mainbar` dans l'Addon et le Bridge ; il clôt la décision Quest/Skill versus Disenchant et la synchronisation MainBar associée. La roadmap normale reprend maintenant avec l'audit de `follow`, `attack`, `stay`. P3B/P3C, le libellé `SOURCE_STALE`, `BAG_MOVE`, `SELL_GREY`, Firestone/Spellstone TEMP_ENCHANT, LuaLint et les reliquats techniques explicitement différés ci-dessus restent hors du prochain chantier.