From d4ffc3624cf8b69d3807f301c8bcee5e245b881d Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Tue, 18 Aug 2026 20:14:45 +0200 Subject: [PATCH 01/11] Clean up SelfBot EveryBar controls --- Core/MultiBotEvery.lua | 44 ++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/Core/MultiBotEvery.lua b/Core/MultiBotEvery.lua index 335e59f..97c26ec 100644 --- a/Core/MultiBotEvery.lua +++ b/Core/MultiBotEvery.lua @@ -162,42 +162,48 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal) end -- MENU MISC END----------------------------------------- - pFrame.addButton("Summon", 94, 0, "ability_hunter_beastcall", MultiBot.L("tips.every.summon")) - .doLeft = function(pButton) - MultiBot.ActionToTarget("summon", pButton.getName()) - end + local isSelfBot = pFrame.getName() == UnitName("player") - pFrame.addButton("Uninvite", 124, 0, "inv_misc_grouplooking", MultiBot.L("tips.every.uninvite")).doShow() - .doLeft = function(pButton) - MultiBot.doSlash("/uninvite", pButton.getName()) - pButton.getButton("Invite").doShow() - pButton.doHide() - end + if not isSelfBot then + pFrame.addButton("Summon", 94, 0, "ability_hunter_beastcall", MultiBot.L("tips.every.summon")) + .doLeft = function(pButton) + MultiBot.ActionToTarget("summon", pButton.getName()) + end - pFrame.addButton("Invite", 124, 0, "inv_misc_groupneedmore", MultiBot.L("tips.every.invite")).doHide() - .doLeft = function(pButton) - MultiBot.doSlash("/invite", pButton.getName()) - pButton.getButton("Uninvite").doShow() - pButton.doHide() + pFrame.addButton("Uninvite", 124, 0, "inv_misc_grouplooking", MultiBot.L("tips.every.uninvite")).doShow() + .doLeft = function(pButton) + MultiBot.doSlash("/uninvite", pButton.getName()) + pButton.getButton("Invite").doShow() + pButton.doHide() + end + + pFrame.addButton("Invite", 124, 0, "inv_misc_groupneedmore", MultiBot.L("tips.every.invite")).doHide() + .doLeft = function(pButton) + MultiBot.doSlash("/invite", pButton.getName()) + pButton.getButton("Uninvite").doShow() + pButton.doHide() + end end - pFrame.addButton("Food", 154, 0, "inv_drink_24_sealwhey", MultiBot.L("tips.every.food")).setDisable() + local everyActionStartX = isSelfBot and 94 or 154 + + pFrame.addButton("Food", everyActionStartX, 0, "inv_drink_24_sealwhey", MultiBot.L("tips.every.food")).setDisable() .doLeft = function(pButton) MultiBot.OnOffActionToTarget(pButton, "nc +food,?", "nc -food,?", pButton.getName()) end - pFrame.addButton("Loot", 184, 0, "inv_misc_coin_16", MultiBot.L("tips.every.loot")).setDisable() + pFrame.addButton("Loot", everyActionStartX + 30, 0, "inv_misc_coin_16", MultiBot.L("tips.every.loot")).setDisable() .doLeft = function(pButton) MultiBot.OnOffActionToTarget(pButton, "nc +loot,?", "nc -loot,?", pButton.getName()) end - pFrame.addButton("Gather", 214, 0, "trade_mining", MultiBot.L("tips.every.gather")).setDisable() + pFrame.addButton("Gather", everyActionStartX + 60, 0, "trade_mining", MultiBot.L("tips.every.gather")).setDisable() .doLeft = function(pButton) MultiBot.OnOffActionToTarget(pButton, "nc +gather,?", "nc -gather,?", pButton.getName()) end -- Selfbot is not allowed to use these Tools -- - if(pFrame.getName() == UnitName("player")) then return end + if(isSelfBot) then return end pFrame.addButton("Inventory", 244, 0, "inv_misc_bag_08", MultiBot.L("tips.every.inventory")).setDisable() .doLeft = function(pButton) From 6075850ccf0ad87175ffc529a674ffa90c208bc6 Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Tue, 18 Aug 2026 21:47:22 +0200 Subject: [PATCH 02/11] Add isolated SelfBot strategy support --- Core/MultiBotComm.lua | 229 ++++++++++++++++++++++++++++++++++++++++ Core/MultiBotEngine.lua | 85 +++++++++++++++ Core/MultiBotEvery.lua | 27 +++-- 3 files changed, 334 insertions(+), 7 deletions(-) diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index 3c7f2a2..b2fb2b2 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -270,6 +270,7 @@ local function ensureBridgeState() state.pendingStateRefreshAll = state.pendingStateRefreshAll or false state.pendingStateRefreshByBot = state.pendingStateRefreshByBot or {} state.strategyMutationCapable = state.strategyMutationCapable or false + state.selfStrategyCapable = state.selfStrategyCapable or false state.outfitCapable = state.outfitCapable or false state.inventoryCapable = state.inventoryCapable or false state.inventoryExactCapable = state.inventoryExactCapable or false @@ -297,6 +298,8 @@ local function ensureBridgeState() state.groupRollCommands = state.groupRollCommands or {} state.strategyMutationSeq = state.strategyMutationSeq or 0 state.strategyMutationCommands = state.strategyMutationCommands or {} + state.selfStrategySeq = state.selfStrategySeq or 0 + state.selfStrategyCommands = state.selfStrategyCommands or {} state.weaponEnchantDebugSeq = state.weaponEnchantDebugSeq or 0 state.details = state.details or {} state.professions = state.professions or {} @@ -669,6 +672,43 @@ function Comm.RequestState(name) return token end +function Comm.RequestSelfStrategyState() + local state = ensureBridgeState() + local name = getPlayerName() + + if not name + or not state.connected + or state.selfStrategyCapable ~= true + or state.selfBotLastActive ~= true + or state.stateFramingCapable ~= true then + state.lastError = "SELF_STRATEGY_STATE_UNAVAILABLE" + return false + end + + local token = beginStateRequest(state, name, false) + if not token then + state.lastError = "SELF_STRATEGY_STATE_TOO_MANY_REQUESTS" + return false + end + + if not Comm.Send("GET", "SELF_STRATEGY_STATE~" .. token) then + clearStateRequest(state, token) + state.lastError = "SELF_STRATEGY_STATE_SEND_FAILED" + return false + end + + local request = state.stateRequests[token] + if type(request) == "table" then + local botKey = string.lower(name) + local requestOrder = tonumber(request.order) or 0 + local latestOrder = tonumber(state.stateLatestOrderByBot[botKey]) or 0 + if requestOrder > latestOrder then + state.stateLatestOrderByBot[botKey] = requestOrder + end + end + + return token +end function Comm.RequestStates() local state = ensureBridgeState() if not state.capabilitiesResolved then @@ -803,6 +843,7 @@ maybeResolveCapabilityFallback = function(generation) state.capabilityBatchActive = false state.stateFramingCapable = false state.strategyMutationCapable = false +state.selfStrategyCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false @@ -1114,6 +1155,103 @@ function Comm.RunStrategyCommand(scope, target, stateScope, changes, callback) return token end +local function finishSelfStrategyCommand(token, result) + local state = ensureBridgeState() + local pending = state.selfStrategyCommands[token] + if type(pending) ~= "table" then + return false + end + + state.selfStrategyCommands[token] = nil + result = type(result) == "table" and result or {} + result.token = token + result.stateScope = result.stateScope or pending.stateScope + result.changes = result.changes or pending.changes + + if type(pending.callback) == "function" then + pending.callback(result) + end + + if MultiBot.OnSelfStrategyMutationApplied then + MultiBot.OnSelfStrategyMutationApplied(result) + end + + return true +end + +function Comm.RunSelfStrategyCommand(stateScope, changes, callback) + local state = ensureBridgeState() + + if not state.connected then + state.lastError = "SELF_STRATEGY_NOT_CONNECTED" + return false + end + if state.selfBotCapable ~= true then + state.lastError = "SELF_BOT_CAPABILITY_UNAVAILABLE" + return false + end + if state.selfStrategyCapable ~= true then + state.lastError = "SELF_STRATEGY_CAPABILITY_UNAVAILABLE" + return false + end + if state.selfBotLastActive ~= true then + state.lastError = "SELF_STRATEGY_NOT_ACTIVE" + return false + end + + stateScope = string.upper(trim(stateScope or "")) + changes = validateStrategyMutationChanges(changes) + + if stateScope ~= "C" and stateScope ~= "N" then + state.lastError = "SELF_STRATEGY_INVALID_STATE_SCOPE" + return false + end + if not changes then + state.lastError = "SELF_STRATEGY_INVALID_CHANGES" + return false + end + if countTableEntries(state.selfStrategyCommands) >= STRATEGY_MUTATION_MAX_ACTIVE then + state.lastError = "SELF_STRATEGY_TOO_MANY_REQUESTS" + return false + end + + state.selfStrategySeq = (tonumber(state.selfStrategySeq) or 0) + 1 + local token = tostring(math.floor(safeNow() * 1000)) .. "-self-strategy-" .. tostring(state.selfStrategySeq) + state.selfStrategyCommands[token] = { + stateScope = stateScope, + changes = changes, + callback = type(callback) == "function" and callback or nil, + startedAt = safeNow(), + } + + local payload = "SELF_STRATEGY~" + .. token .. "~" + .. stateScope .. "~" + .. urlEncodeField(changes) + + if not Comm.Send("RUN", payload) then + state.selfStrategyCommands[token] = nil + state.lastError = "SELF_STRATEGY_SEND_FAILED" + return false + end + + if MultiBot and type(MultiBot.TimerAfter) == "function" then + MultiBot.TimerAfter(STRATEGY_MUTATION_TIMEOUT_SECONDS, function() + local bridge = ensureBridgeState() + if not bridge.selfStrategyCommands[token] then + return + end + + bridge.lastError = "SELF_STRATEGY_TIMEOUT~" .. token + finishSelfStrategyCommand(token, { + status = "timeout", + reason = "TIMEOUT", + }) + end) + end + + return token +end function Comm.RunLootCommand(scope, target, command) local state = ensureBridgeState() @@ -1698,6 +1836,11 @@ function Comm.HandleSelfBotAddonMessage(opcode, payload, state) reason = reason, desiredState = type(pending) == "table" and pending.desiredState or nil, }) + if status == "OK" and activeText == "1" and state.selfStrategyCapable == true + and type(Comm.RequestSelfStrategyState) == "function" then + Comm.RequestSelfStrategyState() + end + debugPrint("ADDON:RX", opcode, token, status, activeText, reason) return true end @@ -3114,6 +3257,7 @@ function Comm.MarkDisconnected(reason) state.formationCommands = {} state.formationQueryActive = nil state.strategyMutationCapable = false +state.selfStrategyCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false @@ -3144,6 +3288,18 @@ function Comm.MarkDisconnected(reason) MultiBot.RefreshEnchantingEveryButtons() end + local pendingSelfStrategyTokens = {} + for token in pairs(state.selfStrategyCommands or {}) do + pendingSelfStrategyTokens[#pendingSelfStrategyTokens + 1] = token + end + for _, token in ipairs(pendingSelfStrategyTokens) do + finishSelfStrategyCommand(token, { + status = "error", + reason = "DISCONNECTED", + }) + end + state.selfStrategyCommands = {} + local pendingTokens = {} for token in pairs(state.strategyMutationCommands or {}) do pendingTokens[#pendingTokens + 1] = token @@ -5037,6 +5193,66 @@ function Comm.HandleInventoryBuybackAddonMessage(opcode, payload, state) end -- MB_VENDOR_BUYBACK_V1_RX_HELPER_END +-- MB_SELFBOT_STRATEGY_V1_RX_HELPER_BEGIN +function Comm.HandleSelfStrategyAddonMessage(opcode, payload, state) + if opcode ~= "SELF_STRATEGY_ACK" then + return false + end + + state = type(state) == "table" and state or ensureBridgeState() + local fields = splitFields(payload or "") + if #fields ~= 4 then + state.lastError = "SELF_STRATEGY_ACK_BAD_FIELD_COUNT" + return true + end + + local token = trim(fields[1]) + local stateScope = string.upper(trim(fields[2])) + local status = string.upper(trim(fields[3])) + local reason = urlDecodeFieldStrict(fields[4], 64, false) + local pending = state.selfStrategyCommands[token] + + if not isValidStateToken(token) + or (stateScope ~= "C" and stateScope ~= "N") + or (status ~= "OK" and status ~= "ERR") + or reason == nil + or type(pending) ~= "table" + or pending.stateScope ~= stateScope then + state.lastError = "SELF_STRATEGY_ACK_INVALID" + return true + end + + state.connected = true + state.lastError = status == "OK" and nil or ("SELF_STRATEGY_" .. reason) + debugPrint("ADDON:RX", "SELF_STRATEGY_ACK", token, stateScope, status, reason) + finishSelfStrategyCommand(token, { + status = status == "OK" and "ok" or "failed", + stateScope = stateScope, + reason = reason, + }) + return true +end + +function Comm.HandleSelfStrategyProtocolError(requestType, token, reason, state) + if requestType ~= "SELF_STRATEGY" then + return false + end + + state = type(state) == "table" and state or ensureBridgeState() + token = trim(token) + local pending = state.selfStrategyCommands[token] + if type(pending) ~= "table" then + return true + end + + finishSelfStrategyCommand(token, { + status = "error", + stateScope = pending.stateScope, + reason = reason or "PROTOCOL_ERROR", + }) + return true +end +-- MB_SELFBOT_STRATEGY_V1_RX_HELPER_END function Comm.HandleAddonMessage(prefix, message, distribution, sender) if prefix ~= Comm.prefix then return false @@ -5098,6 +5314,7 @@ function Comm.HandleAddonMessage(prefix, message, distribution, sender) if opcode == "CAPS_BEGIN" then state.stateFramingCapable = false state.strategyMutationCapable = false +state.selfStrategyCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false @@ -5123,6 +5340,7 @@ function Comm.HandleAddonMessage(prefix, message, distribution, sender) if not state.capabilityBatchActive then state.stateFramingCapable = false state.strategyMutationCapable = false +state.selfStrategyCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false @@ -5146,6 +5364,8 @@ function Comm.HandleAddonMessage(prefix, message, distribution, sender) state.stateFramingCapable = true elseif capability == STRATEGY_MUTATION_CAPABILITY then state.strategyMutationCapable = true + elseif capability == "SELF_STRATEGY_V1" then + state.selfStrategyCapable = true elseif capability == OUTFIT_CAPABILITY then state.outfitCapable = true elseif capability == INVENTORY_CAPABILITY then @@ -5275,6 +5495,12 @@ function Comm.HandleAddonMessage(prefix, message, distribution, sender) end -- MB_ISSUE33_SELF_BOT_V1_RX_END + -- MB_SELFBOT_STRATEGY_V1_RX_BEGIN + if Comm.HandleSelfStrategyAddonMessage(opcode, payload, state) then + return true + end + -- MB_SELFBOT_STRATEGY_V1_RX_END + if opcode == "ROSTER" then state.connected = true state.lastError = nil @@ -7260,6 +7486,8 @@ function Comm.HandleAddonMessage(prefix, message, distribution, sender) if requestType and isValidStateToken(token) and reason then if Comm.HandleSelfBotProtocolError(requestType, token, reason, state) then return true + elseif Comm.HandleSelfStrategyProtocolError(requestType, token, reason, state) then + return true elseif requestType == "GROUP_ROLL" and state.groupRollCommands[token] then finishGroupRollCommand(token, { status = "error", @@ -7322,6 +7550,7 @@ function Comm.OnPlayerEnteringWorld() state.pendingStateRefreshAll = false state.pendingStateRefreshByBot = {} state.strategyMutationCapable = false +state.selfStrategyCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false diff --git a/Core/MultiBotEngine.lua b/Core/MultiBotEngine.lua index 51174bb..c7ad43f 100644 --- a/Core/MultiBotEngine.lua +++ b/Core/MultiBotEngine.lua @@ -616,6 +616,91 @@ local function _mbRouteStrategyMutation(action, commandScope, target) return MB_STRATEGY_ROUTE_BLOCKED end +local function _mbCanUseBridgeSelfStrategyMutation() + return MultiBot.bridge + and MultiBot.bridge.connected == true + and MultiBot.bridge.selfBotCapable == true + and MultiBot.bridge.selfStrategyCapable == true + and MultiBot.bridge.selfBotLastActive == true + and MultiBot.Comm + and type(MultiBot.Comm.RunSelfStrategyCommand) == "function" +end + +local function _mbSelfStrategyUnavailableReason() + if(not MultiBot.bridge) then return "SELF_STRATEGY_BRIDGE_UNAVAILABLE" end + if(MultiBot.bridge.connected ~= true) then return "SELF_STRATEGY_NOT_CONNECTED" end + if(MultiBot.bridge.selfBotCapable ~= true) then return "SELF_BOT_CAPABILITY_UNAVAILABLE" end + if(MultiBot.bridge.selfStrategyCapable ~= true) then return "SELF_STRATEGY_CAPABILITY_UNAVAILABLE" end + if(MultiBot.bridge.selfBotLastActive ~= true) then return "SELF_STRATEGY_NOT_ACTIVE" end + if(not MultiBot.Comm or type(MultiBot.Comm.RunSelfStrategyCommand) ~= "function") then + return "SELF_STRATEGY_CLIENT_UNAVAILABLE" + end + return "SELF_STRATEGY_UNAVAILABLE" +end + +local function _mbRefreshSelfStrategyState() + if(not MultiBot.bridge or MultiBot.bridge.connected ~= true or not MultiBot.Comm) then return end + if(type(MultiBot.Comm.RequestSelfStrategyState) == "function") then + MultiBot.Comm.RequestSelfStrategyState() + end +end + +local function _mbRouteSelfStrategyMutation(action) + local mutationScope, changes = _mbParseStrategyMutation(action) + if(not mutationScope) then return MB_STRATEGY_ROUTE_NOT_STRATEGY end + + local subject = UnitName("player") or "self" + if(not _mbCanUseBridgeSelfStrategyMutation()) then + _mbWarnStrategyMutationBlocked("SELF", subject, _mbSelfStrategyUnavailableReason()) + _mbRefreshSelfStrategyState() + return MB_STRATEGY_ROUTE_BLOCKED + end + + local stateScope = mutationScope == "nc" and "N" or "C" + local token = MultiBot.Comm.RunSelfStrategyCommand(stateScope, changes, function(result) + if(type(result) ~= "table") then + _mbWarnStrategyMutationBlocked("SELF", subject, "SELF_STRATEGY_INVALID_RESULT") + _mbRefreshSelfStrategyState() + return + end + + if(result.status ~= "ok") then + local reason = result.reason + if(type(reason) ~= "string" or reason == "") then + reason = result.status or "SELF_STRATEGY_REJECTED" + end + _mbWarnStrategyMutationBlocked("SELF", subject, reason) + end + + _mbRefreshSelfStrategyState() + end) + + if(token ~= false and token ~= nil) then + return MB_STRATEGY_ROUTE_BRIDGE + end + + _mbWarnStrategyMutationBlocked("SELF", subject, _mbStrategyLastError("SELF_STRATEGY_SEND_FAILED")) + _mbRefreshSelfStrategyState() + return MB_STRATEGY_ROUTE_BLOCKED +end + +MultiBot.OnOffSelfBotStrategy = function(pButton, pOn, pOff) + local wasEnabled = pButton.state == true + local action = wasEnabled and pOff or pOn + local mutationScope = _mbParseStrategyMutation(action) + if(not mutationScope) then + return wasEnabled + end + + local route = _mbRouteSelfStrategyMutation(action) + if(route == MB_STRATEGY_ROUTE_BRIDGE) then + -- The authoritative STATE response rebuilds the final visual state. + return not wasEnabled + end + + -- SelfBot never falls through to the legacy bot whisper route. + return wasEnabled +end MultiBot.ActionToTarget = function(pAction, oTarget) local tName = MultiBot.IF(oTarget == nil, UnitName("target"), oTarget) diff --git a/Core/MultiBotEvery.lua b/Core/MultiBotEvery.lua index 97c26ec..55eeec6 100644 --- a/Core/MultiBotEvery.lua +++ b/Core/MultiBotEvery.lua @@ -189,19 +189,36 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal) pFrame.addButton("Food", everyActionStartX, 0, "inv_drink_24_sealwhey", MultiBot.L("tips.every.food")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +food,?", "nc -food,?", pButton.getName()) + if(isSelfBot) then + MultiBot.OnOffSelfBotStrategy(pButton, "nc +food,?", "nc -food,?") + else + MultiBot.OnOffActionToTarget(pButton, "nc +food,?", "nc -food,?", pButton.getName()) + end end pFrame.addButton("Loot", everyActionStartX + 30, 0, "inv_misc_coin_16", MultiBot.L("tips.every.loot")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +loot,?", "nc -loot,?", pButton.getName()) + if(isSelfBot) then + MultiBot.OnOffSelfBotStrategy(pButton, "nc +loot,?", "nc -loot,?") + else + MultiBot.OnOffActionToTarget(pButton, "nc +loot,?", "nc -loot,?", pButton.getName()) + end end pFrame.addButton("Gather", everyActionStartX + 60, 0, "trade_mining", MultiBot.L("tips.every.gather")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +gather,?", "nc -gather,?", pButton.getName()) + if(isSelfBot) then + MultiBot.OnOffSelfBotStrategy(pButton, "nc +gather,?", "nc -gather,?") + else + MultiBot.OnOffActionToTarget(pButton, "nc +gather,?", "nc -gather,?", pButton.getName()) + end end + -- Common EveryBar strategy state must be initialized before the SelfBot-only early return. + if(MultiBot.hasStrategy(pNormal, "food")) then pFrame.getButton("Food").setEnable() end + if(MultiBot.hasStrategy(pNormal, "loot")) then pFrame.getButton("Loot").setEnable() end + if(MultiBot.hasStrategy(pNormal, "gather")) then pFrame.getButton("Gather").setEnable() end + -- Selfbot is not allowed to use these Tools -- if(isSelfBot) then return end @@ -359,10 +376,6 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal) end -- STRATEGIES -- - - if(MultiBot.hasStrategy(pNormal, "food")) then pFrame.getButton("Food").setEnable() end - if(MultiBot.hasStrategy(pNormal, "loot")) then pFrame.getButton("Loot").setEnable() end - if(MultiBot.hasStrategy(pNormal, "gather")) then pFrame.getButton("Gather").setEnable() end end local function sendCommonCombatStrategy(pButton, command) From f2851c5514fc1abb1f1ec0ebb61bc939649372bc Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Wed, 19 Aug 2026 11:30:06 +0200 Subject: [PATCH 03/11] Add SelfBot common combat strategies --- Core/MultiBotEngine.lua | 14 ++++++++++++++ Strategies/MultiBotDeathKnight.lua | 6 +++--- Strategies/MultiBotDruid.lua | 6 +++--- Strategies/MultiBotHunter.lua | 6 +++--- Strategies/MultiBotMage.lua | 6 +++--- Strategies/MultiBotPaladin.lua | 6 +++--- Strategies/MultiBotPriest.lua | 6 +++--- Strategies/MultiBotRogue.lua | 6 +++--- Strategies/MultiBotShaman.lua | 6 +++--- Strategies/MultiBotWarlock.lua | 6 +++--- Strategies/MultiBotWarrior.lua | 6 +++--- 11 files changed, 44 insertions(+), 30 deletions(-) diff --git a/Core/MultiBotEngine.lua b/Core/MultiBotEngine.lua index c7ad43f..8079041 100644 --- a/Core/MultiBotEngine.lua +++ b/Core/MultiBotEngine.lua @@ -1160,6 +1160,20 @@ MultiBot.OnOffActionToTarget = function(pButton, pOn, pOff, pTarget) end end +MultiBot.OnOffUnitStrategy = function(pButton, pOn, pOff, pTarget) + local targetName = MultiBot.IF(pTarget == nil, UnitName("target"), pTarget) + local playerName = UnitName("player") + + if(MultiBot.bridge + and MultiBot.bridge.selfBotLastActive == true + and targetName ~= nil + and playerName ~= nil + and targetName == playerName) then + return MultiBot.OnOffSelfBotStrategy(pButton, pOn, pOff) + end + + return MultiBot.OnOffActionToTarget(pButton, pOn, pOff, targetName) +end MultiBot.OnOffSwitch = function(pButton) if(pButton.state) then pButton.setDisable() diff --git a/Strategies/MultiBotDeathKnight.lua b/Strategies/MultiBotDeathKnight.lua index 4fdf9fc..6ae26e5 100644 --- a/Strategies/MultiBotDeathKnight.lua +++ b/Strategies/MultiBotDeathKnight.lua @@ -59,7 +59,7 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) tDpsFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.deathknight.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -67,7 +67,7 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) tDpsFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.deathknight.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -99,7 +99,7 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -60, 0, "ability_warrior_innerrage", MultiBot.L("tips.deathknight.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotDruid.lua b/Strategies/MultiBotDruid.lua index e0fe997..dec7693 100644 --- a/Strategies/MultiBotDruid.lua +++ b/Strategies/MultiBotDruid.lua @@ -82,7 +82,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) tDpsFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.druid.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -90,7 +90,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) tDpsFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.druid.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -139,7 +139,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -120, 0, "ability_warrior_innerrage", MultiBot.L("tips.druid.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotHunter.lua b/Strategies/MultiBotHunter.lua index 7c5dbfb..d0aa027 100644 --- a/Strategies/MultiBotHunter.lua +++ b/Strategies/MultiBotHunter.lua @@ -164,7 +164,7 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) dpsFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.hunter.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -172,7 +172,7 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) dpsFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.hunter.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -191,7 +191,7 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -120, 0, "ability_warrior_innerrage", MultiBot.L("tips.hunter.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotMage.lua b/Strategies/MultiBotMage.lua index 9fdc9b6..caed427 100644 --- a/Strategies/MultiBotMage.lua +++ b/Strategies/MultiBotMage.lua @@ -109,7 +109,7 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.mage.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -117,7 +117,7 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.mage.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -131,7 +131,7 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -90, 0, "ability_warrior_innerrage", MultiBot.L("tips.mage.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotPaladin.lua b/Strategies/MultiBotPaladin.lua index b9cafd0..9392326 100644 --- a/Strategies/MultiBotPaladin.lua +++ b/Strategies/MultiBotPaladin.lua @@ -277,7 +277,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) dpsFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.paladin.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -285,7 +285,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) dpsFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.paladin.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -330,7 +330,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -150, 0, "ability_warrior_innerrage", MultiBot.L("tips.paladin.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotPriest.lua b/Strategies/MultiBotPriest.lua index 14bc0cb..9e37b3d 100644 --- a/Strategies/MultiBotPriest.lua +++ b/Strategies/MultiBotPriest.lua @@ -85,7 +85,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.priest.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +healer dps,?", "co -healer dps,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +healer dps,?", "co -healer dps,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -102,7 +102,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("DpsAoe", 0, 52, "spell_holy_surgeoflight", MultiBot.L("tips.priest.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -126,7 +126,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -120, 0, "ability_warrior_innerrage", MultiBot.L("tips.priest.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotRogue.lua b/Strategies/MultiBotRogue.lua index 7d92fe2..02aac7c 100644 --- a/Strategies/MultiBotRogue.lua +++ b/Strategies/MultiBotRogue.lua @@ -9,7 +9,7 @@ MultiBot.addRogue = function(pFrame, pCombat, pNormal) tFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.rogue.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -17,7 +17,7 @@ MultiBot.addRogue = function(pFrame, pCombat, pNormal) tFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.rogue.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -60,7 +60,7 @@ MultiBot.addRogue = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -30, 0, "ability_warrior_innerrage", MultiBot.L("tips.rogue.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotShaman.lua b/Strategies/MultiBotShaman.lua index f59d32d..ae2fdc2 100644 --- a/Strategies/MultiBotShaman.lua +++ b/Strategies/MultiBotShaman.lua @@ -292,7 +292,7 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.shaman.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -300,7 +300,7 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.shaman.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -325,7 +325,7 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -60, 0, "ability_warrior_innerrage", MultiBot.L("tips.shaman.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotWarlock.lua b/Strategies/MultiBotWarlock.lua index 0852d20..fa22733 100644 --- a/Strategies/MultiBotWarlock.lua +++ b/Strategies/MultiBotWarlock.lua @@ -403,7 +403,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) tFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.warlock.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -412,7 +412,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) tFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.warlock.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -438,7 +438,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -30, 0, "ability_warrior_innerrage", MultiBot.L("tips.warlock.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end diff --git a/Strategies/MultiBotWarrior.lua b/Strategies/MultiBotWarrior.lua index 1ee4c51..52d155e 100644 --- a/Strategies/MultiBotWarrior.lua +++ b/Strategies/MultiBotWarrior.lua @@ -9,7 +9,7 @@ MultiBot.addWarrior = function(pFrame, pCombat, pNormal) tFrame.addButton("DpsAssist", 0, 0, "spell_holy_heroism", MultiBot.L("tips.warrior.dps.dpsAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps assist,?", "co -dps assist,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end @@ -17,7 +17,7 @@ MultiBot.addWarrior = function(pFrame, pCombat, pNormal) tFrame.addButton("DpsAoe", 0, 26, "spell_holy_surgeoflight", MultiBot.L("tips.warrior.dps.dpsAoe")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps aoe,?", "co -dps aoe,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAssist").setDisable() end @@ -31,7 +31,7 @@ MultiBot.addWarrior = function(pFrame, pCombat, pNormal) pFrame.addButton("TankAssist", -30, 0, "ability_warrior_innerrage", MultiBot.L("tips.warrior.tankAssist")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank assist,?", "co -tank assist,?", pButton.getName())) then pButton.getButton("DpsAssist").setDisable() pButton.getButton("DpsAoe").setDisable() end From 8cfaedfd54f8790916c0e06b0f9e81b8209d7b47 Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:36:29 +0200 Subject: [PATCH 04/11] Add SelfBot healer DPS class support --- Strategies/MultiBotDruid.lua | 2 +- Strategies/MultiBotPaladin.lua | 2 +- Strategies/MultiBotShaman.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Strategies/MultiBotDruid.lua b/Strategies/MultiBotDruid.lua index dec7693..7076095 100644 --- a/Strategies/MultiBotDruid.lua +++ b/Strategies/MultiBotDruid.lua @@ -99,7 +99,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) -- Missing HEALER DPS -- tDpsFrame.addButton("HealerDps", 0, 104, "INV_Alchemy_Elixir_02", MultiBot.L("tips.druid.dps.healerdps")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +healer dps,?", "co -healer dps,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +healer dps,?", "co -healer dps,?", pButton.getName())) then pButton.getButton("Dps").setDisable() pButton.getButton("OffHeal").setDisable() pButton.getButton("Heal").setDisable() diff --git a/Strategies/MultiBotPaladin.lua b/Strategies/MultiBotPaladin.lua index 9392326..61ebd08 100644 --- a/Strategies/MultiBotPaladin.lua +++ b/Strategies/MultiBotPaladin.lua @@ -315,7 +315,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) -- Added missing Healer DPS dpsFrame.addButton("HealerDps", 0, 104, "INV_Alchemy_Elixir_02", MultiBot.L("tips.paladin.dps.healerdps")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +healer dps,?", "co -healer dps,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +healer dps,?", "co -healer dps,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() pButton.getButton("DpsAssist").setDisable() diff --git a/Strategies/MultiBotShaman.lua b/Strategies/MultiBotShaman.lua index ae2fdc2..db58311 100644 --- a/Strategies/MultiBotShaman.lua +++ b/Strategies/MultiBotShaman.lua @@ -310,7 +310,7 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("HealerDps", 0, 52, "INV_Alchemy_Elixir_02", MultiBot.L("tips.shaman.dps.healerdps")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +healer dps,?", "co -healer dps,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +healer dps,?", "co -healer dps,?", pButton.getName())) then pButton.getButton("TankAssist").setDisable() pButton.getButton("DpsAoe").setDisable() pButton.getButton("DpsAssist").setDisable() From 191f320a8486a8256b16c692ba23d62fc057a107 Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Wed, 19 Aug 2026 19:25:03 +0200 Subject: [PATCH 05/11] Complete SelfBot strategy routing and EveryBar controls --- Core/MultiBotComm.lua | 64 ++++++++++++++++++++++- Core/MultiBotEngine.lua | 81 +++++++++++++++++++++++++++--- Core/MultiBotEvery.lua | 7 +++ Strategies/MultiBotDeathKnight.lua | 24 ++++----- Strategies/MultiBotDruid.lua | 18 +++---- Strategies/MultiBotHunter.lua | 24 ++++----- Strategies/MultiBotMage.lua | 12 ++--- Strategies/MultiBotPaladin.lua | 52 +++++++++---------- Strategies/MultiBotPriest.lua | 16 +++--- Strategies/MultiBotRogue.lua | 6 +-- Strategies/MultiBotShaman.lua | 31 ++++++++++-- Strategies/MultiBotWarlock.lua | 12 ++--- Strategies/MultiBotWarrior.lua | 4 +- UI/MultiBotShamanQuickFrame.lua | 4 +- 14 files changed, 257 insertions(+), 98 deletions(-) diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index b2fb2b2..f578524 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -47,6 +47,7 @@ local GROUP_ROLL_MAX_ITEM_LINK_LENGTH = 160 local STATE_TIMEOUT_SECONDS = 5.0 local STATES_TIMEOUT_SECONDS = 15.0 local STRATEGY_MUTATION_TIMEOUT_SECONDS = 5.0 +local SELF_STRATEGY_MUTATION_TIMEOUT_SECONDS = 10.0 local STRATEGY_MUTATION_MAX_ACTIVE = 32 local STRATEGY_MUTATION_MAX_CHANGES_LENGTH = 160 local STRATEGY_MUTATION_MAX_OPERATIONS = 32 @@ -290,6 +291,9 @@ local function ensureBridgeState() state.selfBotStateActive = state.selfBotStateActive or nil state.selfBotCommandSeq = state.selfBotCommandSeq or 0 state.selfBotCommandActive = state.selfBotCommandActive or nil + state.selfBotMountNormalized = state.selfBotMountNormalized == true + state.selfBotMountNormalizePending = state.selfBotMountNormalizePending == true + state.selfBotMountNormalizeEpoch = tonumber(state.selfBotMountNormalizeEpoch) or 0 state.enchantTradeSeq = state.enchantTradeSeq or 0 state.enchantTradeActive = state.enchantTradeActive or nil state.enchantTradeCommands = state.enchantTradeCommands or {} @@ -1236,7 +1240,7 @@ function Comm.RunSelfStrategyCommand(stateScope, changes, callback) end if MultiBot and type(MultiBot.TimerAfter) == "function" then - MultiBot.TimerAfter(STRATEGY_MUTATION_TIMEOUT_SECONDS, function() + MultiBot.TimerAfter(SELF_STRATEGY_MUTATION_TIMEOUT_SECONDS, function() local bridge = ensureBridgeState() if not bridge.selfStrategyCommands[token] then return @@ -1780,6 +1784,53 @@ local function finishSelfBotRequest(kind, token, result) return true end +local function normalizeSelfBotMountStrategy(state) + state = type(state) == "table" and state or ensureBridgeState() + + if state.connected ~= true + or state.selfBotLastActive ~= true + or state.selfStrategyCapable ~= true + or type(Comm.RunSelfStrategyCommand) ~= "function" then + return false + end + + if state.selfBotMountNormalized == true or state.selfBotMountNormalizePending == true then + return true + end + + local generation = tonumber(state.connectionGeneration) or 0 + local epoch = tonumber(state.selfBotMountNormalizeEpoch) or 0 + state.selfBotMountNormalizePending = true + + local token = Comm.RunSelfStrategyCommand("N", "-mount", function(result) + local bridge = ensureBridgeState() + if (tonumber(bridge.connectionGeneration) or 0) ~= generation + or (tonumber(bridge.selfBotMountNormalizeEpoch) or 0) ~= epoch then + return + end + + bridge.selfBotMountNormalizePending = false + if bridge.selfBotLastActive == true + and type(result) == "table" + and result.status == "ok" then + bridge.selfBotMountNormalized = true + debugPrint("SELFBOT:MOUNT_NORMALIZE", "OK") + else + bridge.selfBotMountNormalized = false + debugPrint("SELFBOT:MOUNT_NORMALIZE", "FAILED", + type(result) == "table" and tostring(result.reason or result.status or "UNKNOWN") or "INVALID_RESULT") + end + end) + + if token == false or token == nil then + state.selfBotMountNormalizePending = false + return false + end + + debugPrint("SELFBOT:MOUNT_NORMALIZE", "SENT", tostring(token)) + return true +end + -- Keep SELF_BOT response parsing outside Comm.HandleAddonMessage. WoW 3.3.5a -- uses Lua 5.1, whose function upvalue limit is 60; the main dispatcher is -- already close to that limit. @@ -1836,6 +1887,14 @@ function Comm.HandleSelfBotAddonMessage(opcode, payload, state) reason = reason, desiredState = type(pending) == "table" and pending.desiredState or nil, }) + if activeText == "0" then + state.selfBotMountNormalizeEpoch = (tonumber(state.selfBotMountNormalizeEpoch) or 0) + 1 + state.selfBotMountNormalizePending = false + state.selfBotMountNormalized = false + elseif state.selfStrategyCapable == true then + normalizeSelfBotMountStrategy(state) + end + if status == "OK" and activeText == "1" and state.selfStrategyCapable == true and type(Comm.RequestSelfStrategyState) == "function" then Comm.RequestSelfStrategyState() @@ -3122,6 +3181,9 @@ function Comm.MarkDisconnected(reason) state.selfBotStateActive = nil state.selfBotCommandActive = nil state.selfBotLastActive = nil + state.selfBotMountNormalizeEpoch = (tonumber(state.selfBotMountNormalizeEpoch) or 0) + 1 + state.selfBotMountNormalizePending = false + state.selfBotMountNormalized = false if type(selfBotStatePending) == "table" and type(selfBotStatePending.callback) == "function" then selfBotStatePending.callback({ diff --git a/Core/MultiBotEngine.lua b/Core/MultiBotEngine.lua index 8079041..ebd9a5b 100644 --- a/Core/MultiBotEngine.lua +++ b/Core/MultiBotEngine.lua @@ -701,6 +701,67 @@ MultiBot.OnOffSelfBotStrategy = function(pButton, pOn, pOff) -- SelfBot never falls through to the legacy bot whisper route. return wasEnabled end + +MultiBot.IsSelfBotStrategyTarget = function(pTarget) + local targetName = MultiBot.IF(pTarget == nil, UnitName("target"), pTarget) + local playerName = UnitName("player") + + return MultiBot.bridge + and MultiBot.bridge.selfBotLastActive == true + and type(targetName) == "string" + and targetName ~= "" + and type(playerName) == "string" + and playerName ~= "" + and targetName == playerName +end + +MultiBot.RequestUnitStrategyState = function(pTarget) + local targetName = MultiBot.IF(pTarget == nil, UnitName("target"), pTarget) + + if(MultiBot.IsSelfBotStrategyTarget(targetName)) then + if(MultiBot.bridge + and MultiBot.bridge.connected == true + and MultiBot.Comm + and type(MultiBot.Comm.RequestSelfStrategyState) == "function") then + MultiBot.Comm.RequestSelfStrategyState() + return true + end + return false + end + + if(type(targetName) == "string" + and targetName ~= "" + and MultiBot.bridge + and MultiBot.bridge.connected == true + and MultiBot.Comm + and type(MultiBot.Comm.RequestState) == "function") then + MultiBot.Comm.RequestState(targetName) + return true + end + + return false +end + +MultiBot.ActionToUnitStrategy = function(pAction, oTarget) + local targetName = MultiBot.IF(oTarget == nil, UnitName("target"), oTarget) + + if(MultiBot.IsSelfBotStrategyTarget(targetName)) then + if(not _mbParseStrategyMutation(pAction)) then + _mbWarnStrategyMutationBlocked("SELF", targetName, "BAD_OPERATION") + _mbRefreshSelfStrategyState() + return false, "blocked" + end + + local route = _mbRouteSelfStrategyMutation(pAction) + if(route == MB_STRATEGY_ROUTE_BRIDGE) then + return true, "bridge" + end + + return false, "blocked" + end + + return MultiBot.ActionToTarget(pAction, targetName) +end MultiBot.ActionToTarget = function(pAction, oTarget) local tName = MultiBot.IF(oTarget == nil, UnitName("target"), oTarget) @@ -799,6 +860,19 @@ MultiBot.SelectToTarget = function(pParent, pIndex, pTexture, pAction, oTarget) return false end +MultiBot.SelectToUnitStrategy = function(pParent, pIndex, pTexture, pAction, oTarget) + if(MultiBot.ActionToUnitStrategy(pAction, oTarget)) then + local tFrame = pParent.frames[pIndex] + local tButton = pParent.buttons[pIndex] + tButton.setTexture(pTexture) + tFrame:Hide() + if(MultiBot.RequestClickBlockerUpdate) then MultiBot.RequestClickBlockerUpdate(tFrame) end + return true + end + + return false +end + MultiBot.SelectToTargetButton = function(pParent, pIndex, pTexture, pAction, oTarget) local tFrame = pParent.frames[pIndex] local tButton = pParent.buttons[pIndex] @@ -1162,13 +1236,8 @@ end MultiBot.OnOffUnitStrategy = function(pButton, pOn, pOff, pTarget) local targetName = MultiBot.IF(pTarget == nil, UnitName("target"), pTarget) - local playerName = UnitName("player") - if(MultiBot.bridge - and MultiBot.bridge.selfBotLastActive == true - and targetName ~= nil - and playerName ~= nil - and targetName == playerName) then + if(MultiBot.IsSelfBotStrategyTarget(targetName)) then return MultiBot.OnOffSelfBotStrategy(pButton, pOn, pOff) end diff --git a/Core/MultiBotEvery.lua b/Core/MultiBotEvery.lua index 55eeec6..313ef73 100644 --- a/Core/MultiBotEvery.lua +++ b/Core/MultiBotEvery.lua @@ -409,6 +409,13 @@ local function addCommonCombatStrategyButton(pFrame, pCombat, tFrame, buttonName ):setDisable() button.doLeft = function(self) + local botName = self.getName and self.getName() or "" + if MultiBot.IsSelfBotStrategyTarget + and MultiBot.IsSelfBotStrategyTarget(botName) then + MultiBot.OnOffUnitStrategy(self, plusCommand, minusCommand, botName) + return + end + if MultiBot.OnOffSwitch(self) then sendCommonCombatStrategy(self, plusCommand) else diff --git a/Strategies/MultiBotDeathKnight.lua b/Strategies/MultiBotDeathKnight.lua index 6ae26e5..58e0eb3 100644 --- a/Strategies/MultiBotDeathKnight.lua +++ b/Strategies/MultiBotDeathKnight.lua @@ -9,25 +9,25 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) tFrame.addButton("Unholy", 0, 0, "spell_deathknight_unholypresence", MultiBot.L("tips.deathknight.presence.unholy")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Presence", pButton.texture, "co +unholy,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +unholy,?", pButton.getName()) pButton.getButton("Presence").doRight = function() - MultiBot.OnOffActionToTarget(pButton, "co +unholy,?", "co -unholy,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +unholy,?", "co -unholy,?", pButton.getName()) end end tFrame.addButton("Frost", 0, 26, "spell_deathknight_frostpresence", MultiBot.L("tips.deathknight.presence.frost")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Presence", pButton.texture, "co +frost,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +frost,?", pButton.getName()) pButton.getButton("Presence").doRight = function() - MultiBot.OnOffActionToTarget(pButton, "co +frost,?", "co -frost,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +frost,?", "co -frost,?", pButton.getName()) end end tFrame.addButton("Blood", 0, 52, "spell_deathknight_bloodpresence", MultiBot.L("tips.deathknight.presence.blood")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Presence", pButton.texture, "co +blood,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +blood,?", pButton.getName()) pButton.getButton("Presence").doRight = function() - MultiBot.OnOffActionToTarget(pButton, "co +blood,?", "co -blood,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +blood,?", "co -blood,?", pButton.getName()) end end @@ -35,15 +35,15 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) if(MultiBot.hasStrategy(pCombat, "unholy")) then tButton.setTexture("spell_deathknight_unholypresence").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +unholy,?", "co -unholy,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +unholy,?", "co -unholy,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "frost")) then tButton.setTexture("spell_deathknight_frostpresence").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +frost,?", "co -frost,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +frost,?", "co -frost,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "blood")) then tButton.setTexture("spell_deathknight_bloodpresence").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +blood,?", "co -blood,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +blood,?", "co -blood,?", pButton.getName()) end end @@ -77,7 +77,7 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) tDpsFrame.addButton("FrostAoe", 0, 52, "spell_frost_frostbolt02", MultiBot.L("tips.deathknight.dps.frostAoe")).setDisable() -- Variable a créér .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +frost aoe,?", "co -frost aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +frost aoe,?", "co -frost aoe,?", pButton.getName())) then pButton.getButton("DpsAoe").setDisable() pButton.getButton("UnholyAoe").setDisable() end @@ -85,7 +85,7 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) tDpsFrame.addButton("UnholyAoe", 0, 78, "spell_fire_felflamering", MultiBot.L("tips.deathknight.dps.unholyAoe")).setDisable() -- Variable à créer .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +unholy aoe,?", "co -unholy aoe,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +unholy aoe,?", "co -unholy aoe,?", pButton.getName())) then pButton.getButton("DpsAoe").setDisable() pButton.getButton("FrostAoe").setDisable() end @@ -109,7 +109,7 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) pFrame.addButton("TankFace", -90, 0, "ability_warrior_defensivestance", MultiBot.L("tips.tankFace")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +tank face,?", "co -tank face,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +tank face,?", "co -tank face,?", pButton.getName()) end -- STRATEGIES -- diff --git a/Strategies/MultiBotDruid.lua b/Strategies/MultiBotDruid.lua index 7076095..2e73343 100644 --- a/Strategies/MultiBotDruid.lua +++ b/Strategies/MultiBotDruid.lua @@ -1,7 +1,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) pFrame.addButton("Heal", 0, 0, "spell_holy_aspiration", MultiBot.L("tips.druid.heal")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +resto,?", "co -resto,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +resto,?", "co -resto,?", pButton.getName())) then pButton.getButton("Caster").setDisable() pButton.getButton("Tank").setDisable() pButton.getButton("Bear").setDisable() @@ -30,12 +30,12 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) tFrame.addButton("CasterAoe", 0, 0, "spell_arcane_starfire", MultiBot.L("tips.druid.playbook.casterAoe")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +aoe,?", "co -aoe,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +aoe,?", "co -aoe,?", pButton.getName()) end tFrame.addButton("Caster", 0, 26, "spell_nature_starfall", MultiBot.L("tips.druid.playbook.caster")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +balance,?", "co -balance,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +balance,?", "co -balance,?", pButton.getName())) then pButton.getButton("Heal").setDisable() pButton.getButton("Tank").setDisable() pButton.getButton("Bear").setDisable() @@ -46,7 +46,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) tFrame.addButton("Cat", 0, 52, "ability_druid_catform", MultiBot.L("tips.druid.playbook.cat")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +cat,?", "co -cat,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +cat,?", "co -cat,?", pButton.getName())) then pButton.getButton("Caster").setDisable() pButton.getButton("Heal").setDisable() pButton.getButton("Tank").setDisable() @@ -59,7 +59,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) tFrame.addButton("Bear", 0, 78, "ability_racial_bearform", MultiBot.L("tips.druid.playbook.bear")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +bear,?", "co -bear,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +bear,?", "co -bear,?", pButton.getName())) then pButton.getButton("Caster").setDisable() pButton.getButton("Heal").setDisable() pButton.getButton("Cat").setDisable() @@ -108,7 +108,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) tDpsFrame.addButton("Dps", 0, 52, "spell_holy_divinepurpose", MultiBot.L("tips.druid.dps.dps")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +cat,?", "co -cat,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +cat,?", "co -cat,?", pButton.getName())) then pButton.getButton("Caster").setDisable() pButton.getButton("Tank").setDisable() pButton.getButton("Bear").setDisable() @@ -121,7 +121,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) -- OFF-HEAL -- tDpsFrame.addButton("OffHeal", 0, 78, "spell_nature_healingtouch", MultiBot.L("tips.druid.dps.offheal")).setDisable() .doLeft = function(pButton) - if (MultiBot.OnOffActionToTarget( + if (MultiBot.OnOffUnitStrategy( pButton, "co +offheal,?", "co -offheal,?", pButton.getName())) then @@ -149,7 +149,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) pFrame.addButton("Tank", -150, 0, "ability_warrior_shieldmastery", MultiBot.L("tips.druid.tank")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +bear,?", "co -bear,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +bear,?", "co -bear,?", pButton.getName())) then pButton.getButton("Caster").setDisable() pButton.getButton("Heal").setDisable() pButton.getButton("Dps").setDisable() @@ -164,7 +164,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) pFrame.addButton("TankFace", -180, 0, "ability_warrior_defensivestance", MultiBot.L("tips.tankFace")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +tank face,?", "co -tank face,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +tank face,?", "co -tank face,?", pButton.getName()) end -- STRATEGIES -- diff --git a/Strategies/MultiBotHunter.lua b/Strategies/MultiBotHunter.lua index d0aa027..3c7a175 100644 --- a/Strategies/MultiBotHunter.lua +++ b/Strategies/MultiBotHunter.lua @@ -59,25 +59,25 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) combatAspectFrame.addButton("CombatNature", 0, 0, "spell_nature_protectionformnature", MultiBot.L("tips.hunter.caspect.rnature")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAspect", pButton.texture, "co +rnature,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +rnature,?", pButton.getName()) pButton.getButton("CombatAspect").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +rnature,?", "co -rnature,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +rnature,?", "co -rnature,?", btn.getName()) end end combatAspectFrame.addButton("CombatSpeed", 0, 26, "ability_mount_whitetiger", MultiBot.L("tips.hunter.caspect.bspeed")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAspect", pButton.texture, "co +bspeed,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +bspeed,?", pButton.getName()) pButton.getButton("CombatAspect").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +bspeed,?", "co -bspeed,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +bspeed,?", "co -bspeed,?", btn.getName()) end end combatAspectFrame.addButton("CombatDps", 0, 52, "ability_hunter_pet_dragonhawk", MultiBot.L("tips.hunter.caspect.bdps")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAspect", pButton.texture, "co +bdps,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +bdps,?", pButton.getName()) pButton.getButton("CombatAspect").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +bdps,?", "co -bdps,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +bdps,?", "co -bdps,?", btn.getName()) end end @@ -85,15 +85,15 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) if(MultiBot.hasStrategy(pCombat, "rnature")) then combatAspectButton.setTexture("spell_nature_protectionformnature").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +rnature,?", "co -rnature,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +rnature,?", "co -rnature,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "bspeed")) then combatAspectButton.setTexture("ability_mount_whitetiger").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +bspeed,?", "co -bspeed,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +bspeed,?", "co -bspeed,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "bdps")) then combatAspectButton.setTexture("ability_hunter_pet_dragonhawk").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +bdps,?", "co -bdps,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +bdps,?", "co -bdps,?", pButton.getName()) end end @@ -119,7 +119,7 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) pButton.setDisable() end - if(MultiBot.OnOffActionToTarget(pButton, pCommand, pCommand, pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, pCommand, pCommand, pButton.getName())) then pButton.getButton(pOtherOne).setDisable() pButton.getButton(pOtherTwo).setDisable() end @@ -127,7 +127,7 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) playbookFrame.addButton("Aoe", 0, 0, "spell_holy_surgeoflight", MultiBot.L("tips.hunter.playbook.aoe")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +aoe,?", "co -aoe,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +aoe,?", "co -aoe,?", pButton.getName()) end playbookFrame.addButton("BeastMastery", 0, 26, "ability_hunter_pet_dragonhawk", MultiBot.L("tips.hunter.playbook.bm")).setDisable() @@ -180,7 +180,7 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) dpsFrame.addButton("TrapWeave", 0, 52, "ability_ensnare", MultiBot.L("tips.hunter.trapweave")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +trap weave,?", "co -trap weave,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +trap weave,?", "co -trap weave,?", pButton.getName()) end if MultiBot.AddCommonCombatStrategyButtons then diff --git a/Strategies/MultiBotMage.lua b/Strategies/MultiBotMage.lua index caed427..4fb8b7a 100644 --- a/Strategies/MultiBotMage.lua +++ b/Strategies/MultiBotMage.lua @@ -47,12 +47,12 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) playbookFrame.addButton("Aoe", 0, 0, "spell_arcane_starfire", MultiBot.L("tips.mage.playbook.aoe")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +aoe,?", "co -aoe,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +aoe,?", "co -aoe,?", pButton.getName()) end playbookFrame.addButton("Arcane", 0, 26, "ability_mage_arcanebarrage", MultiBot.L("tips.mage.playbook.arcane")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +arcane,?", "co -arcane,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +arcane,?", "co -arcane,?", pButton.getName())) then pButton.getButton("Frost").setDisable() pButton.getButton("Fire").setDisable() end @@ -60,7 +60,7 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) playbookFrame.addButton("Frost", 0, 52, "spell_frost_frostbolt02", MultiBot.L("tips.mage.playbook.frost")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +frost,?", "co -frost,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +frost,?", "co -frost,?", pButton.getName())) then pButton.getButton("Arcane").setDisable() pButton.getButton("Fire").setDisable() end @@ -68,7 +68,7 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) playbookFrame.addButton("Fire", 0, 78, "spell_fire_fireball02", MultiBot.L("tips.mage.playbook.fire")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +fire,?", "co -fire,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +fire,?", "co -fire,?", pButton.getName())) then pButton.getButton("Arcane").setDisable() pButton.getButton("Frost").setDisable() end @@ -76,7 +76,7 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) -- missing Frostfire & Firestarter -- playbookFrame.addButton("FrostFire", 0, 104, "ability_mage_frostfirebolt", MultiBot.L("tips.mage.playbook.frostfire")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +frostfire,?", "co -frostfire,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +frostfire,?", "co -frostfire,?", pButton.getName())) then pButton.getButton("Arcane").setDisable() pButton.getButton("Frost").setDisable() pButton.getButton("Fire").setDisable() @@ -85,7 +85,7 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) playbookFrame.addButton("Firestarter", 0, 130, "ability_mage_firestarter", MultiBot.L("tips.mage.playbook.firestarter")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +firestarter,?", "co -firestarter,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +firestarter,?", "co -firestarter,?", pButton.getName()) end -- STRATEGIES:PLAYBOOK -- diff --git a/Strategies/MultiBotPaladin.lua b/Strategies/MultiBotPaladin.lua index 61ebd08..37e317b 100644 --- a/Strategies/MultiBotPaladin.lua +++ b/Strategies/MultiBotPaladin.lua @@ -1,7 +1,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) pFrame.addButton("Heal", 0, 0, "spell_holy_aspiration", MultiBot.L("tips.paladin.heal")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +heal,?", "co -heal,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +heal,?", "co -heal,?", pButton.getName())) then pButton.getButton("Tank").setDisable() pButton.getButton("Dps").setDisable() end @@ -179,57 +179,57 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) combatAuraFrame.addButton("CombatSpeed", 0, 0, "spell_holy_crusaderaura", MultiBot.L("tips.paladin.caura.bspeed")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAura", pButton.texture, "co +bspeed,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +bspeed,?", pButton.getName()) pButton.getButton("CombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +bspeed,?", "co -bspeed,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +bspeed,?", "co -bspeed,?", btn.getName()) end end combatAuraFrame.addButton("CombatFire", 0, 26, "spell_fire_sealoffire", MultiBot.L("tips.paladin.caura.rfire")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAura", pButton.texture, "co +rfire,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rfire,?", pButton.getName()) pButton.getButton("CombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +rfire,?", "co -rfire,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +rfire,?", "co -rfire,?", btn.getName()) end end combatAuraFrame.addButton("CombatFrost", 0, 52, "spell_frost_wizardmark", MultiBot.L("tips.paladin.caura.rfrost")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAura", pButton.texture, "co +rfrost,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rfrost,?", pButton.getName()) pButton.getButton("CombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +rfrost,?", "co -rfrost,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +rfrost,?", "co -rfrost,?", btn.getName()) end end combatAuraFrame.addButton("CombatShadow", 0, 78, "spell_shadow_sealofkings", MultiBot.L("tips.paladin.caura.rshadow")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAura", pButton.texture, "co +rshadow,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rshadow,?", pButton.getName()) pButton.getButton("CombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +rshadow,?", "co -rshadow,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +rshadow,?", "co -rshadow,?", btn.getName()) end end combatAuraFrame.addButton("CombatDamage", 0, 104, "spell_holy_auraoflight", MultiBot.L("tips.paladin.caura.baoe")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAura", pButton.texture, "co +baoe,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +baoe,?", pButton.getName()) pButton.getButton("CombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +baoe,?", "co -baoe,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +baoe,?", "co -baoe,?", btn.getName()) end end combatAuraFrame.addButton("CombatArmor", 0, 130, "spell_holy_devotionaura", MultiBot.L("tips.paladin.caura.barmor")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAura", pButton.texture, "co +barmor,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +barmor,?", pButton.getName()) pButton.getButton("CombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +barmor,?", "co -barmor,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +barmor,?", "co -barmor,?", btn.getName()) end end combatAuraFrame.addButton("CombatCast", 0, 156, "spell_holy_mindsooth", MultiBot.L("tips.paladin.caura.bcast")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "CombatAura", pButton.texture, "co +bcast,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +bcast,?", pButton.getName()) pButton.getButton("CombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "co +bcast,?", "co -bcast,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "co +bcast,?", "co -bcast,?", btn.getName()) end end @@ -237,31 +237,31 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) if(MultiBot.hasStrategy(pCombat, "bspeed")) then combatAuraButton.setTexture("spell_holy_crusaderaura").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +bspeed,?", "co -bspeed,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +bspeed,?", "co -bspeed,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "rfire")) then combatAuraButton.setTexture("spell_fire_sealoffire").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +rfire,?", "co -rfire,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +rfire,?", "co -rfire,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "rfrost")) then combatAuraButton.setTexture("spell_frost_wizardmark").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +rfrost,?", "co -rfrost,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +rfrost,?", "co -rfrost,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "rshadow")) then combatAuraButton.setTexture("spell_shadow_sealofkings").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +rshadow,?", "co -rshadow,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +rshadow,?", "co -rshadow,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "baoe")) then combatAuraButton.setTexture("spell_holy_auraoflight").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +baoe,?", "co -baoe,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +baoe,?", "co -baoe,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "barmor")) then combatAuraButton.setTexture("spell_holy_devotionaura").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +barmor,?", "co -barmor,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +barmor,?", "co -barmor,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pCombat, "bcast")) then combatAuraButton.setTexture("spell_holy_mindsooth").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +bcast,?", "co -bcast,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +bcast,?", "co -bcast,?", pButton.getName()) end end @@ -293,7 +293,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) dpsFrame.addButton("Dps", 0, 52, "spell_holy_divinepurpose", MultiBot.L("tips.paladin.dps.dps")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +dps,?", "co -dps,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +dps,?", "co -dps,?", pButton.getName())) then pButton.getButton("Heal").setDisable() pButton.getButton("Tank").setDisable() end @@ -302,7 +302,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) -- OFF-HEAL -- dpsFrame.addButton("OffHeal", 0, 78, "Spell_Holy_FlashHeal", MultiBot.L("tips.paladin.dps.offheal")).setDisable() .doLeft = function(pButton) - if (MultiBot.OnOffActionToTarget( + if (MultiBot.OnOffUnitStrategy( pButton, "co +offheal,?", "co -offheal,?", pButton.getName())) then @@ -340,7 +340,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) pFrame.addButton("Tank", -180, 0, "ability_warrior_shieldmastery", MultiBot.L("tips.paladin.tank")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +tank,?", "co -tank,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +tank,?", "co -tank,?", pButton.getName())) then pButton.getButton("Heal").setDisable() pButton.getButton("Dps").setDisable() end @@ -350,7 +350,7 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) pFrame.addButton("TankFace", -210, 0, "ability_warrior_defensivestance", MultiBot.L("tips.tankFace")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +tank face,?", "co -tank face,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +tank face,?", "co -tank face,?", pButton.getName()) end -- STRATEGIES -- diff --git a/Strategies/MultiBotPriest.lua b/Strategies/MultiBotPriest.lua index 9e37b3d..9823e4c 100644 --- a/Strategies/MultiBotPriest.lua +++ b/Strategies/MultiBotPriest.lua @@ -1,7 +1,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) pFrame.addButton("Heal", 0, 0, "spell_holy_aspiration", MultiBot.L("tips.priest.heal")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +heal,?", "co -heal,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +heal,?", "co -heal,?", pButton.getName())) then pButton.getButton("Shadow").setDisable() pButton.getButton("Dps").setDisable() end @@ -26,7 +26,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) playbookFrame.addButton("ShadowDebuff", 0, 0, "spell_shadow_demonicempathy", MultiBot.L("tips.priest.playbook.shadowDebuff")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +shadow debuff,?", "co -shadow debuff,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +shadow debuff,?", "co -shadow debuff,?", pButton.getName())) then pButton.getButton("DpsDebuff").setEnable() else pButton.getButton("DpsDebuff").setDisable() @@ -35,12 +35,12 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) playbookFrame.addButton("ShadowAoe", 0, 26, "spell_arcane_arcanetorrent", MultiBot.L("tips.priest.playbook.shadowAoe")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +shadow aoe,?", "co -shadow aoe,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +shadow aoe,?", "co -shadow aoe,?", pButton.getName()) end playbookFrame.addButton("Shadow", 0, 52, "spell_holy_devotion", MultiBot.L("tips.priest.playbook.shadow")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +shadow,?", "co -shadow,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +shadow,?", "co -shadow,?", pButton.getName())) then pButton.getButton("Heal").setDisable() pButton.getButton("Dps").setEnable() else @@ -51,7 +51,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) -- HOLY (PLAYBOOK) -- playbookFrame.addButton("HolyHeal", 0, 78, "spell_holy_guardianspirit", MultiBot.L("tips.priest.playbook.holyheal")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +holy heal,?", "co -holy heal,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +holy heal,?", "co -holy heal,?", pButton.getName())) then pButton.getButton("Shadow").setDisable() pButton.getButton("Dps").setDisable() end @@ -59,7 +59,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) playbookFrame.addButton("HolyDps", 0, 102, "spell_holy_holybolt", MultiBot.L("tips.priest.playbook.holydps")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +holy dps,?", "co -holy dps,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +holy dps,?", "co -holy dps,?", pButton.getName())) then pButton.getButton("Heal").setDisable() pButton.getButton("Shadow").setDisable() pButton.getButton("Dps").setEnable() @@ -93,7 +93,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("DpsDebuff", 0, 26, "spell_holy_restoration", MultiBot.L("tips.priest.dps.dpsDebuff")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +shadow debuff,?", "co -shadow debuff,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +shadow debuff,?", "co -shadow debuff,?", pButton.getName())) then pButton.getButton("ShadowDebuff").setEnable() else pButton.getButton("ShadowDebuff").setDisable() @@ -110,7 +110,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) dpsControlFrame.addButton("Dps", 0, 78, "spell_holy_divinepurpose", MultiBot.L("tips.priest.dps.dps")).setDisable() .doLeft = function(pButton) - if(MultiBot.OnOffActionToTarget(pButton, "co +shadow,?", "co -shadow,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +shadow,?", "co -shadow,?", pButton.getName())) then pButton.getButton("Shadow").setEnable() pButton.getButton("Heal").setDisable() else diff --git a/Strategies/MultiBotRogue.lua b/Strategies/MultiBotRogue.lua index 02aac7c..b38bba4 100644 --- a/Strategies/MultiBotRogue.lua +++ b/Strategies/MultiBotRogue.lua @@ -25,7 +25,7 @@ MultiBot.addRogue = function(pFrame, pCombat, pNormal) tFrame.addButton("Dps", 0, 52, "spell_holy_divinepurpose", MultiBot.L("tips.rogue.dps.dps")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +dps,?", "co -dps,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +dps,?", "co -dps,?", pButton.getName()) end -- STEALTH (maintenir le camouflage HORS COMBAT) @@ -39,7 +39,7 @@ MultiBot.addRogue = function(pFrame, pCombat, pNormal) tFrame.addButton("Stealthed", 0, 104, "ability_sap", MultiBot.L("tips.rogue.dps.stealthed")).setDisable() .doLeft = function(pButton) -- Pour entrer en mode "stealthed", on coupe dps et on force stealthed ; l'inverse pour repasser en dps. - if(MultiBot.OnOffActionToTarget(pButton, "co +stealthed,?", "co -stealthed,?", pButton.getName())) then + if(MultiBot.OnOffUnitStrategy(pButton, "co +stealthed,?", "co -stealthed,?", pButton.getName())) then pButton.getButton("Dps") .setDisable() pButton.getButton("DpsAoe") .setDisable() pButton.getButton("DpsAssist") .setDisable() @@ -49,7 +49,7 @@ MultiBot.addRogue = function(pFrame, pCombat, pNormal) -- BOOST (active les CD offensifs : Adrenaline Rush, Blade Flurry, etc.) tFrame.addButton("Boost", 0, 130, "ability_mage_potentspirit", MultiBot.L("tips.rogue.dps.boost")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +boost,?", "co -boost,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +boost,?", "co -boost,?", pButton.getName()) end if MultiBot.AddCommonCombatStrategyButtons then diff --git a/Strategies/MultiBotShaman.lua b/Strategies/MultiBotShaman.lua index db58311..37e9c43 100644 --- a/Strategies/MultiBotShaman.lua +++ b/Strategies/MultiBotShaman.lua @@ -159,12 +159,30 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) end local function requestShamanCombatState(target, bridgeSync, sequenceKey, sequence) - local previousUpdateAt = getShamanBridgeStateTimestamp(target) + local selfStrategyTarget = MultiBot.IsSelfBotStrategyTarget + and MultiBot.IsSelfBotStrategyTarget(target) local function isCurrent() return isShamanPlaybookSequenceCurrent(sequenceKey, sequence) end + if(selfStrategyTarget) then + local function requestSelfState() + if(not isCurrent()) then return end + if(MultiBot.Comm and type(MultiBot.Comm.RequestSelfStrategyState) == "function") then + MultiBot.Comm.RequestSelfStrategyState() + end + end + + if(bridgeSync) then + scheduleShamanTask(shamanStateRefreshDelay, requestSelfState) + scheduleShamanTask(shamanStateRefreshDelay + 0.65, requestSelfState) + end + return + end + + local previousUpdateAt = getShamanBridgeStateTimestamp(target) + local function requestBridgeState() if(not isCurrent()) then return end if(MultiBot.Comm and MultiBot.Comm.RequestState) then @@ -199,7 +217,7 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) local command = commands[index] if(not command) then return end - if(not MultiBot.ActionToTarget(command, target)) then return end + if(not MultiBot.ActionToUnitStrategy(command, target)) then return end if(index < #commands) then scheduleShamanTask(shamanCommandInterval, function() @@ -221,10 +239,13 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) local target = pButton.getName() if(not defaults or type(target) ~= "string" or target == "") then return end + local selfStrategyTarget = MultiBot.IsSelfBotStrategyTarget + and MultiBot.IsSelfBotStrategyTarget(target) local bridgeSync = MultiBot.bridge and MultiBot.bridge.connected == true and MultiBot.Comm - and MultiBot.Comm.RequestState + and ((selfStrategyTarget and type(MultiBot.Comm.RequestSelfStrategyState) == "function") + or (not selfStrategyTarget and type(MultiBot.Comm.RequestState) == "function")) local commands = { "co -resto,-ele,-enh,+" .. specKey } for _, elementKey in ipairs(shamanElementOrder) do @@ -249,7 +270,7 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) "Aoe", 0, 0, "spell_nature_lightningoverload", MultiBot.L("tips.shaman.playbook.aoe")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +aoe,?", "co -aoe,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +aoe,?", "co -aoe,?", pButton.getName()) end playbookFrame.addButton( @@ -335,7 +356,7 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) pFrame.addButton("Cure", -90, 0, "Ability_Creature_Poison_02", MultiBot.L("tips.shaman.playbook.cure")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +cure,?", "co -cure,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +cure,?", "co -cure,?", pButton.getName()) end -- STRATEGIES -- diff --git a/Strategies/MultiBotWarlock.lua b/Strategies/MultiBotWarlock.lua index fa22733..fd4bd21 100644 --- a/Strategies/MultiBotWarlock.lua +++ b/Strategies/MultiBotWarlock.lua @@ -163,7 +163,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) end end - local sent, transport = MultiBot.ActionToTarget(action, target) + local sent, transport = MultiBot.ActionToUnitStrategy(action, target) if not sent then return end if transport ~= "bridge" then fStones.activeStone = desired @@ -258,7 +258,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) end end - local sent, transport = MultiBot.ActionToTarget(action, target) + local sent, transport = MultiBot.ActionToUnitStrategy(action, target) if not sent then return end if transport ~= "bridge" then fSoul.activeSS = desired @@ -357,7 +357,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) end end - local sent, transport = MultiBot.ActionToTarget(action, target) + local sent, transport = MultiBot.ActionToUnitStrategy(action, target) if not sent then return end if transport ~= "bridge" then fPets.activePet = desired @@ -427,7 +427,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) btnMeta.setDisable() btnMeta.doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +meta melee,?", "co -meta melee,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +meta melee,?", "co -meta melee,?", pButton.getName()) end if MultiBot.AddCommonCombatStrategyButtons then @@ -448,7 +448,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) pFrame.addButton("Tank", -60, 0, "ability_warrior_shieldmastery", MultiBot.L("tips.warlock.tank")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +tank,?", "co -tank,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +tank,?", "co -tank,?", pButton.getName()) end -- CURSES -- @@ -537,7 +537,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) end end - local sent, transport = MultiBot.ActionToTarget(action, target) + local sent, transport = MultiBot.ActionToUnitStrategy(action, target) if not sent then return end if transport ~= "bridge" then fCurses.activeCurse = desired diff --git a/Strategies/MultiBotWarrior.lua b/Strategies/MultiBotWarrior.lua index 52d155e..ee7f2f4 100644 --- a/Strategies/MultiBotWarrior.lua +++ b/Strategies/MultiBotWarrior.lua @@ -41,14 +41,14 @@ MultiBot.addWarrior = function(pFrame, pCombat, pNormal) pFrame.addButton("Tank", -60, 0, "ability_warrior_shieldmastery", MultiBot.L("tips.warrior.tank")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +tank,?", "co -tank,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +tank,?", "co -tank,?", pButton.getName()) end -- TANK FACE -- pFrame.addButton("TankFace", -90, 0, "ability_warrior_defensivestance", MultiBot.L("tips.tankFace")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "co +tank face,?", "co -tank face,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "co +tank face,?", "co -tank face,?", pButton.getName()) end -- STRATEGIES -- diff --git a/UI/MultiBotShamanQuickFrame.lua b/UI/MultiBotShamanQuickFrame.lua index 961c37d..e352630 100644 --- a/UI/MultiBotShamanQuickFrame.lua +++ b/UI/MultiBotShamanQuickFrame.lua @@ -720,7 +720,7 @@ function ShamanQuick:SelectTotem(row, elementKey, button, definition) local isSameSelection = currentButton == button or currentIcon == button.__mbIcon if isSameSelection then - if not MultiBot.ActionToTarget("co -" .. definition.spell .. ",?", row.owner) then + if not MultiBot.ActionToUnitStrategy("co -" .. definition.spell .. ",?", row.owner) then return end self:ClearTotemSelection(row, elementKey) @@ -732,7 +732,7 @@ function ShamanQuick:SelectTotem(row, elementKey, button, definition) command = "co -" .. currentButton.__mbSpell .. ",+" .. definition.spell .. ",?" end - if not MultiBot.ActionToTarget(command, row.owner) then + if not MultiBot.ActionToUnitStrategy(command, row.owner) then return end From ce871adaff41e6e4ed10af2a935060685b5a87d2 Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Wed, 19 Aug 2026 22:26:07 +0200 Subject: [PATCH 06/11] Complete SelfBot EveryBar chatless support --- Core/MultiBotComm.lua | 163 +++++++++++++++++++++++++++++++++ Core/MultiBotEngine.lua | 5 +- Core/MultiBotEvery.lua | 84 +++++++++++++++-- Strategies/MultiBotDruid.lua | 2 +- Strategies/MultiBotHunter.lua | 18 ++-- Strategies/MultiBotMage.lua | 12 +-- Strategies/MultiBotPaladin.lua | 66 ++++++------- Strategies/MultiBotPriest.lua | 4 +- Strategies/MultiBotRogue.lua | 2 +- 9 files changed, 290 insertions(+), 66 deletions(-) diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index f578524..443c9c1 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -13,6 +13,7 @@ Comm.version = "1" local STATE_FRAMING_CAPABILITY = "STATE_FRAMING_V1" local STRATEGY_MUTATION_CAPABILITY = "STRATEGY_MUTATION_V1" +local SELF_ACTION_CAPABILITY = "SELF_ACTION_V1" local OUTFIT_CAPABILITY = "OUTFIT_V1" local INVENTORY_CAPABILITY = "INVENTORY_V1" local INVENTORY_EXACT_CAPABILITY = "INVENTORY_EXACT_V1" @@ -48,6 +49,7 @@ local STATE_TIMEOUT_SECONDS = 5.0 local STATES_TIMEOUT_SECONDS = 15.0 local STRATEGY_MUTATION_TIMEOUT_SECONDS = 5.0 local SELF_STRATEGY_MUTATION_TIMEOUT_SECONDS = 10.0 +local SELF_ACTION_TIMEOUT_SECONDS = 10.0 local STRATEGY_MUTATION_MAX_ACTIVE = 32 local STRATEGY_MUTATION_MAX_CHANGES_LENGTH = 160 local STRATEGY_MUTATION_MAX_OPERATIONS = 32 @@ -272,6 +274,7 @@ local function ensureBridgeState() state.pendingStateRefreshByBot = state.pendingStateRefreshByBot or {} state.strategyMutationCapable = state.strategyMutationCapable or false state.selfStrategyCapable = state.selfStrategyCapable or false + state.selfActionCapable = state.selfActionCapable or false state.outfitCapable = state.outfitCapable or false state.inventoryCapable = state.inventoryCapable or false state.inventoryExactCapable = state.inventoryExactCapable or false @@ -304,6 +307,8 @@ local function ensureBridgeState() state.strategyMutationCommands = state.strategyMutationCommands or {} state.selfStrategySeq = state.selfStrategySeq or 0 state.selfStrategyCommands = state.selfStrategyCommands or {} + state.selfActionSeq = state.selfActionSeq or 0 + state.selfActionCommands = state.selfActionCommands or {} state.weaponEnchantDebugSeq = state.weaponEnchantDebugSeq or 0 state.details = state.details or {} state.professions = state.professions or {} @@ -848,6 +853,7 @@ maybeResolveCapabilityFallback = function(generation) state.stateFramingCapable = false state.strategyMutationCapable = false state.selfStrategyCapable = false +state.selfActionCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false @@ -3181,6 +3187,9 @@ function Comm.MarkDisconnected(reason) state.selfBotStateActive = nil state.selfBotCommandActive = nil state.selfBotLastActive = nil + if MultiBot and type(MultiBot.OnBridgeSelfBotState) == "function" then + MultiBot.OnBridgeSelfBotState(false, reason or "DISCONNECTED") + end state.selfBotMountNormalizeEpoch = (tonumber(state.selfBotMountNormalizeEpoch) or 0) + 1 state.selfBotMountNormalizePending = false state.selfBotMountNormalized = false @@ -3320,6 +3329,7 @@ function Comm.MarkDisconnected(reason) state.formationQueryActive = nil state.strategyMutationCapable = false state.selfStrategyCapable = false +state.selfActionCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false @@ -3362,6 +3372,17 @@ state.selfStrategyCapable = false end state.selfStrategyCommands = {} + for token, pending in pairs(state.selfActionCommands or {}) do + if type(pending) == "table" and type(pending.callback) == "function" then + pending.callback({ + status = "error", + action = pending.action, + reason = "DISCONNECTED", + }) + end + end + state.selfActionCommands = {} + local pendingTokens = {} for token in pairs(state.strategyMutationCommands or {}) do pendingTokens[#pendingTokens + 1] = token @@ -5255,6 +5276,137 @@ function Comm.HandleInventoryBuybackAddonMessage(opcode, payload, state) end -- MB_VENDOR_BUYBACK_V1_RX_HELPER_END +-- MB_SELFBOT_ACTION_V1_BEGIN +function Comm.RunSelfAction(action, argument, callback) + local state = ensureBridgeState() + action = string.upper(trim(action or "")) + argument = trim(argument or "") + + if not state.connected then + state.lastError = "SELF_ACTION_NOT_CONNECTED" + return false + end + if state.selfBotCapable ~= true then + state.lastError = "SELF_ACTION_SELF_BOT_CAPABILITY_UNAVAILABLE" + return false + end + if state.selfActionCapable ~= true then + state.lastError = "SELF_ACTION_CAPABILITY_UNAVAILABLE" + return false + end + if state.selfBotLastActive ~= true then + state.lastError = "SELF_ACTION_NOT_ACTIVE" + return false + end + + local allowed = action == "AUTOGEAR" + or action == "MAINTENANCE" + or action == "WAIT_ATTACK_TIME" + if not allowed then + state.lastError = "SELF_ACTION_UNSUPPORTED" + return false + end + + if (action == "AUTOGEAR" or action == "MAINTENANCE") and argument ~= "" then + state.lastError = "SELF_ACTION_BAD_ARGUMENT" + return false + end + if action == "WAIT_ATTACK_TIME" + and argument ~= "0" + and argument ~= "3" + and argument ~= "5" + and argument ~= "10" then + state.lastError = "SELF_ACTION_BAD_ARGUMENT" + return false + end + + if countTableEntries(state.selfActionCommands) >= STRATEGY_MUTATION_MAX_ACTIVE then + state.lastError = "SELF_ACTION_TOO_MANY_REQUESTS" + return false + end + + state.selfActionSeq = (tonumber(state.selfActionSeq) or 0) + 1 + local token = tostring(math.floor(safeNow() * 1000)) .. "-self-action-" .. tostring(state.selfActionSeq) + state.selfActionCommands[token] = { + action = action, + argument = argument, + callback = type(callback) == "function" and callback or nil, + startedAt = safeNow(), + } + + local payload = "SELF_ACTION~" .. token .. "~" .. action .. "~" .. argument + if not Comm.Send("RUN", payload) then + state.selfActionCommands[token] = nil + state.lastError = "SELF_ACTION_SEND_FAILED" + return false + end + + if MultiBot and type(MultiBot.TimerAfter) == "function" then + MultiBot.TimerAfter(SELF_ACTION_TIMEOUT_SECONDS, function() + local bridge = ensureBridgeState() + local pending = bridge.selfActionCommands[token] + if type(pending) ~= "table" then + return + end + + bridge.selfActionCommands[token] = nil + bridge.lastError = "SELF_ACTION_TIMEOUT" + if type(pending.callback) == "function" then + pending.callback({ + status = "timeout", + action = pending.action, + reason = "TIMEOUT", + }) + end + end) + end + + return token +end + +function Comm.HandleSelfActionAddonMessage(opcode, payload, state) + if opcode ~= "SELF_ACTION_ACK" then + return false + end + + state = type(state) == "table" and state or ensureBridgeState() + local fields = splitFields(payload or "") + if #fields ~= 4 then + state.lastError = "SELF_ACTION_ACK_BAD_FIELD_COUNT" + return true + end + + local token = trim(fields[1]) + local action = string.upper(trim(fields[2])) + local status = string.upper(trim(fields[3])) + local reason = urlDecodeFieldStrict(fields[4], 96, true) + local pending = state.selfActionCommands[token] + + if not isValidStateToken(token) + or (status ~= "OK" and status ~= "ERR") + or reason == nil + or type(pending) ~= "table" + or pending.action ~= action then + state.lastError = "SELF_ACTION_ACK_INVALID" + return true + end + + state.selfActionCommands[token] = nil + state.connected = true + state.lastError = status == "OK" and nil or ("SELF_ACTION_" .. reason) + debugPrint("ADDON:RX", "SELF_ACTION_ACK", token, action, status, reason) + + if type(pending.callback) == "function" then + pending.callback({ + status = status == "OK" and "ok" or "failed", + action = action, + reason = reason, + }) + end + + return true +end +-- MB_SELFBOT_ACTION_V1_END -- MB_SELFBOT_STRATEGY_V1_RX_HELPER_BEGIN function Comm.HandleSelfStrategyAddonMessage(opcode, payload, state) if opcode ~= "SELF_STRATEGY_ACK" then @@ -5377,6 +5529,7 @@ function Comm.HandleAddonMessage(prefix, message, distribution, sender) state.stateFramingCapable = false state.strategyMutationCapable = false state.selfStrategyCapable = false +state.selfActionCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false @@ -5403,6 +5556,7 @@ state.selfStrategyCapable = false state.stateFramingCapable = false state.strategyMutationCapable = false state.selfStrategyCapable = false +state.selfActionCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false @@ -5428,6 +5582,8 @@ state.selfStrategyCapable = false state.strategyMutationCapable = true elseif capability == "SELF_STRATEGY_V1" then state.selfStrategyCapable = true + elseif capability == SELF_ACTION_CAPABILITY then + state.selfActionCapable = true elseif capability == OUTFIT_CAPABILITY then state.outfitCapable = true elseif capability == INVENTORY_CAPABILITY then @@ -5557,6 +5713,12 @@ state.selfStrategyCapable = false end -- MB_ISSUE33_SELF_BOT_V1_RX_END + -- MB_SELFBOT_ACTION_V1_RX_BEGIN + if Comm.HandleSelfActionAddonMessage(opcode, payload, state) then + return true + end + -- MB_SELFBOT_ACTION_V1_RX_END + -- MB_SELFBOT_STRATEGY_V1_RX_BEGIN if Comm.HandleSelfStrategyAddonMessage(opcode, payload, state) then return true @@ -7613,6 +7775,7 @@ function Comm.OnPlayerEnteringWorld() state.pendingStateRefreshByBot = {} state.strategyMutationCapable = false state.selfStrategyCapable = false +state.selfActionCapable = false state.outfitCapable = false state.inventoryCapable = false state.inventoryExactCapable = false diff --git a/Core/MultiBotEngine.lua b/Core/MultiBotEngine.lua index ebd9a5b..1e80901 100644 --- a/Core/MultiBotEngine.lua +++ b/Core/MultiBotEngine.lua @@ -706,15 +706,12 @@ MultiBot.IsSelfBotStrategyTarget = function(pTarget) local targetName = MultiBot.IF(pTarget == nil, UnitName("target"), pTarget) local playerName = UnitName("player") - return MultiBot.bridge - and MultiBot.bridge.selfBotLastActive == true - and type(targetName) == "string" + return type(targetName) == "string" and targetName ~= "" and type(playerName) == "string" and playerName ~= "" and targetName == playerName end - MultiBot.RequestUnitStrategyState = function(pTarget) local targetName = MultiBot.IF(pTarget == nil, UnitName("target"), pTarget) diff --git a/Core/MultiBotEvery.lua b/Core/MultiBotEvery.lua index 313ef73..e1b14c5 100644 --- a/Core/MultiBotEvery.lua +++ b/Core/MultiBotEvery.lua @@ -1,3 +1,25 @@ +local showEveryMessage + +local function runEverySelfAction(action, argument) + local comm = MultiBot and MultiBot.Comm or nil + if not (comm and type(comm.RunSelfAction) == "function") then + if showEveryMessage then + showEveryMessage("Bridge unavailable: SelfBot action was not sent.") + end + return false + end + + local token = comm.RunSelfAction(action, argument or "", function(result) + if type(result) == "table" and result.status ~= "ok" and showEveryMessage then + showEveryMessage("SelfBot action failed: " .. tostring(result.reason or "UNKNOWN")) + end + end) + if not token and showEveryMessage then + local reason = MultiBot and MultiBot.bridge and MultiBot.bridge.lastError or "UNAVAILABLE" + showEveryMessage("SelfBot action was not sent: " .. tostring(reason)) + end + return token and true or false +end -- Confirmation popup for Autogear if not StaticPopupDialogs["MULTIBOT_AUTOGEAR_CONFIRM"] then StaticPopupDialogs["MULTIBOT_AUTOGEAR_CONFIRM"] = { @@ -6,7 +28,11 @@ if not StaticPopupDialogs["MULTIBOT_AUTOGEAR_CONFIRM"] then button2 = CANCEL, OnAccept = function(self, data) if data and data.target then - SendChatMessage("autogear", "WHISPER", nil, data.target) + if data.selfAction == true then + runEverySelfAction("AUTOGEAR", "") + else + SendChatMessage("autogear", "WHISPER", nil, data.target) + end end end, timeout = 0, @@ -16,7 +42,7 @@ if not StaticPopupDialogs["MULTIBOT_AUTOGEAR_CONFIRM"] then } end -local function showEveryMessage(message) +showEveryMessage = function(message) if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99MultiBot|r " .. tostring(message or "")) elseif print then @@ -76,6 +102,8 @@ end MultiBot.addEvery = function(pFrame, pCombat, pNormal) + local isSelfBot = (pFrame.getName() == UnitName("player")) + -- MENU MISC -------------------------------------------- -- Crée un sous-frame « Misc » au-dessus du bouton local tMisc = pFrame.addFrame("Misc", 64, 29) @@ -97,7 +125,7 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal) end }, { "Autogear", "inv_misc_enggizmos_30", MultiBot.L("tips.every.autogear"), function(b) - StaticPopup_Show("MULTIBOT_AUTOGEAR_CONFIRM", b.getName(), nil, { target = b.getName() }) + StaticPopup_Show("MULTIBOT_AUTOGEAR_CONFIRM", b.getName(), nil, { target = b.getName(), selfAction = isSelfBot }) end }, -- NEW: Favorite toggle (per-character) @@ -133,13 +161,19 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal) end }, { "Maintenance", "Achievement_Halloween_Smiley_01", MultiBot.L("tips.every.maintenance"), function(b) - SendChatMessage("maintenance", "WHISPER", nil, b.getName()) + if isSelfBot then + runEverySelfAction("MAINTENANCE", "") + else + SendChatMessage("maintenance", "WHISPER", nil, b.getName()) + end end }, } do - local btn = tMisc.addButton(data[1], 0, y, data[2], data[3]) - btn.doLeft = data[4] - y = y + dy + if not (isSelfBot and (data[1] == "Wipe" or data[1] == "CharacterInfo")) then + local btn = tMisc.addButton(data[1], 0, y, data[2], data[3]) + btn.doLeft = data[4] + y = y + dy + end end @@ -162,7 +196,6 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal) end -- MENU MISC END----------------------------------------- - local isSelfBot = pFrame.getName() == UnitName("player") if not isSelfBot then pFrame.addButton("Summon", 94, 0, "ability_hunter_beastcall", MultiBot.L("tips.every.summon")) @@ -219,8 +252,39 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal) if(MultiBot.hasStrategy(pNormal, "loot")) then pFrame.getButton("Loot").setEnable() end if(MultiBot.hasStrategy(pNormal, "gather")) then pFrame.getButton("Gather").setEnable() end - -- Selfbot is not allowed to use these Tools -- - if(isSelfBot) then return end + -- Selfbot is not allowed to use the ordinary bot-only Tools -- + -- SelfBot keeps a compact chatless Combat menu and never falls through to BOT commands. + if(isSelfBot) then + local selfCombatFrame = pFrame.addFrame("CombatCommands", everyActionStartX + 90, 29, nil, 58, 114) + selfCombatFrame:Hide() + selfCombatFrame._mbDropdownManaged = true + + pFrame.addButton("Combat", everyActionStartX + 90, 0, "Ability_Warrior_BattleShout", MultiBot.L("tips.every.combat")) + .doLeft = function() + MultiBot.ShowHideSwitch(selfCombatFrame) + end + + local focusButton = selfCombatFrame.addButton("CombatFocus", -28, 84, "Ability_Hunter_MasterMarksman", MultiBot.L("tips.every.combatfocus")) + focusButton.setDisable() + focusButton.doLeft = function(pButton) + MultiBot.OnOffSelfBotStrategy(pButton, "co +focus,?", "co -focus,?") + end + + local function addSelfWaitButton(name, x, y, tip, value) + local button = selfCombatFrame.addButton(name, x, y, "Spell_Holy_BorrowedTime", tip) + button.doLeft = function() + runEverySelfAction("WAIT_ATTACK_TIME", tostring(value)) + end + end + + addSelfWaitButton("CombatWait0", -28, 56, MultiBot.L("tips.every.combatwait0"), 0) + addSelfWaitButton("CombatWait3", 0, 56, MultiBot.L("tips.every.combatwait3"), 3) + addSelfWaitButton("CombatWait5", -28, 28, MultiBot.L("tips.every.combatwait5"), 5) + addSelfWaitButton("CombatWait10", 0, 28, MultiBot.L("tips.every.combatwait10"), 10) + + if(MultiBot.hasStrategy(pCombat, "focus")) then focusButton.setEnable() end + return + end pFrame.addButton("Inventory", 244, 0, "inv_misc_bag_08", MultiBot.L("tips.every.inventory")).setDisable() .doLeft = function(pButton) diff --git a/Strategies/MultiBotDruid.lua b/Strategies/MultiBotDruid.lua index 2e73343..1100a0b 100644 --- a/Strategies/MultiBotDruid.lua +++ b/Strategies/MultiBotDruid.lua @@ -15,7 +15,7 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal) pFrame.addButton("Buff", -30, 0, "spell_holy_power", MultiBot.L("tips.druid.buff")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +buff,?", "nc -buff,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +buff,?", "nc -buff,?", pButton.getName()) end -- PLAYBOOK -- diff --git a/Strategies/MultiBotHunter.lua b/Strategies/MultiBotHunter.lua index 3c7a175..6017d0b 100644 --- a/Strategies/MultiBotHunter.lua +++ b/Strategies/MultiBotHunter.lua @@ -9,25 +9,25 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) nonCombatAspectFrame.addButton("NonCombatNature", 0, 0, "spell_nature_protectionformnature", MultiBot.L("tips.hunter.naspect.rnature")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAspect", pButton.texture, "nc +rnature,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +rnature,?", pButton.getName()) pButton.getButton("NonCombatAspect").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +rnature,?", "nc -rnature,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +rnature,?", "nc -rnature,?", btn.getName()) end end nonCombatAspectFrame.addButton("NonCombatSpeed", 0, 26, "ability_mount_whitetiger", MultiBot.L("tips.hunter.naspect.bspeed")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAspect", pButton.texture, "nc +bspeed,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +bspeed,?", pButton.getName()) pButton.getButton("NonCombatAspect").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bspeed,?", "nc -bspeed,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bspeed,?", "nc -bspeed,?", btn.getName()) end end nonCombatAspectFrame.addButton("NonCombatDps", 0, 52, "ability_hunter_pet_dragonhawk", MultiBot.L("tips.hunter.naspect.bdps")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAspect", pButton.texture, "nc +bdps,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +bdps,?", pButton.getName()) pButton.getButton("NonCombatAspect").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bdps,?", "nc -bdps,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bdps,?", "nc -bdps,?", btn.getName()) end end @@ -35,15 +35,15 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) if(MultiBot.hasStrategy(pNormal, "rnature")) then nonCombatAspectButton.setTexture("spell_nature_protectionformnature").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +rnature,?", "nc -rnature,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +rnature,?", "nc -rnature,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "bspeed")) then nonCombatAspectButton.setTexture("ability_mount_whitetiger").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bspeed,?", "nc -bspeed,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bspeed,?", "nc -bspeed,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "bdps")) then nonCombatAspectButton.setTexture("ability_hunter_pet_dragonhawk").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bdps,?", "nc -bdps,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bdps,?", "nc -bdps,?", pButton.getName()) end end diff --git a/Strategies/MultiBotMage.lua b/Strategies/MultiBotMage.lua index 4fb8b7a..f36576b 100644 --- a/Strategies/MultiBotMage.lua +++ b/Strategies/MultiBotMage.lua @@ -9,17 +9,17 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) buffFrame.addButton("NonCombatMana", 0, 0, "inv_elemental_primal_mana", MultiBot.L("tips.mage.buff.bmana")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Buff", pButton.texture, "nc +bmana,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Buff", pButton.texture, "nc +bmana,?", pButton.getName()) pButton.getButton("Buff").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bmana,?", "nc -bmana,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bmana,?", "nc -bmana,?", btn.getName()) end end buffFrame.addButton("NonCombatDps", 0, 26, "inv_elemental_primal_nether", MultiBot.L("tips.mage.buff.bdps")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Buff", pButton.texture, "nc +bdps,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Buff", pButton.texture, "nc +bdps,?", pButton.getName()) pButton.getButton("Buff").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bdps,?", "nc -bdps,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bdps,?", "nc -bdps,?", btn.getName()) end end @@ -27,11 +27,11 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) if(MultiBot.hasStrategy(pNormal, "bmana")) then tButton.setTexture("inv_elemental_primal_mana").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bmana,?", "nc -bmana,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bmana,?", "nc -bmana,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "bdps")) then tButton.setTexture("inv_elemental_primal_nether").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bdps,?", "nc -bdps,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bdps,?", "nc -bdps,?", pButton.getName()) end end diff --git a/Strategies/MultiBotPaladin.lua b/Strategies/MultiBotPaladin.lua index 37e317b..120eaf3 100644 --- a/Strategies/MultiBotPaladin.lua +++ b/Strategies/MultiBotPaladin.lua @@ -19,33 +19,33 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) sealFrame.addButton("SealHealth", 0, 0, "spell_holy_healingaura", MultiBot.L("tips.paladin.seal.bhealth")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Seal", pButton.texture, "nc +bsanc,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bsanc,?", pButton.getName()) pButton.getButton("Seal").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bsanc,?", "nc -bsanc,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bsanc,?", "nc -bsanc,?", btn.getName()) end end sealFrame.addButton("SealMana", 0, 26, "spell_holy_sealofwisdom", MultiBot.L("tips.paladin.seal.bmana")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Seal", pButton.texture, "nc +bwisdom,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bwisdom,?", pButton.getName()) pButton.getButton("Seal").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bwisdom,?", "nc -bwisdom,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bwisdom,?", "nc -bwisdom,?", btn.getName()) end end sealFrame.addButton("SealStats", 0, 52, "spell_magic_magearmor", MultiBot.L("tips.paladin.seal.bstats")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Seal", pButton.texture, "nc +bkings,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bkings,?", pButton.getName()) pButton.getButton("Seal").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bkings,?", "nc -bkings,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bkings,?", "nc -bkings,?", btn.getName()) end end sealFrame.addButton("SealDps", 0, 78, "inv_hammer_01", MultiBot.L("tips.paladin.seal.bdps")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "Seal", pButton.texture, "nc +bmight,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bmight,?", pButton.getName()) pButton.getButton("Seal").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bmight,?", "nc -bmight,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bmight,?", "nc -bmight,?", btn.getName()) end end @@ -53,19 +53,19 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) if(MultiBot.hasStrategy(pNormal, "bsanc")) then sealButton.setTexture("spell_holy_healingaura").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bsanc,?", "nc -bsanc,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bsanc,?", "nc -bsanc,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "bwisdom")) then sealButton.setTexture("spell_holy_sealofwisdom").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bwisdom,?", "nc -bwisdom,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bwisdom,?", "nc -bwisdom,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "bkings")) then sealButton.setTexture("spell_magic_magearmor").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bkings,?", "nc -bkings,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bkings,?", "nc -bkings,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "bmight")) then sealButton.setTexture("inv_hammer_01").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bmight,?", "nc -bmight,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bmight,?", "nc -bmight,?", pButton.getName()) end end @@ -81,57 +81,57 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) nonCombatAuraFrame.addButton("NonCombatSpeed", 0, 0, "spell_holy_crusaderaura", MultiBot.L("tips.paladin.naura.bspeed")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAura", pButton.texture, "nc +bspeed,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +bspeed,?", pButton.getName()) pButton.getButton("NonCombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bspeed,?", "nc -bspeed,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bspeed,?", "nc -bspeed,?", btn.getName()) end end nonCombatAuraFrame.addButton("NonCombatFire", 0, 26, "spell_fire_sealoffire", MultiBot.L("tips.paladin.naura.rfire")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAura", pButton.texture, "nc +rfire,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rfire,?", pButton.getName()) pButton.getButton("NonCombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +rfire,?", "nc -rfire,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +rfire,?", "nc -rfire,?", btn.getName()) end end nonCombatAuraFrame.addButton("NonCombatFrost", 0, 52, "spell_frost_wizardmark", MultiBot.L("tips.paladin.naura.rfrost")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAura", pButton.texture, "nc +rfrost,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rfrost,?", pButton.getName()) pButton.getButton("NonCombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +rfrost,?", "nc -rfrost,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +rfrost,?", "nc -rfrost,?", btn.getName()) end end nonCombatAuraFrame.addButton("NonCombatShadow", 0, 78, "spell_shadow_sealofkings", MultiBot.L("tips.paladin.naura.rshadow")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAura", pButton.texture, "nc +rshadow,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rshadow,?", pButton.getName()) pButton.getButton("NonCombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +rshadow,?", "nc -rshadow,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +rshadow,?", "nc -rshadow,?", btn.getName()) end end nonCombatAuraFrame.addButton("NonCombatDamage", 0, 104, "spell_holy_auraoflight", MultiBot.L("tips.paladin.naura.baoe")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAura", pButton.texture, "nc +baoe,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +baoe,?", pButton.getName()) pButton.getButton("NonCombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +baoe,?", "nc -baoe,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +baoe,?", "nc -baoe,?", btn.getName()) end end nonCombatAuraFrame.addButton("NonCombatArmor", 0, 130, "spell_holy_devotionaura", MultiBot.L("tips.paladin.naura.barmor")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAura", pButton.texture, "nc +barmor,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +barmor,?", pButton.getName()) pButton.getButton("NonCombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +barmor,?", "nc -barmor,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +barmor,?", "nc -barmor,?", btn.getName()) end end nonCombatAuraFrame.addButton("NonCombatCast", 0, 156, "spell_holy_mindsooth", MultiBot.L("tips.paladin.naura.bcast")) .doLeft = function(pButton) - MultiBot.SelectToTarget(pButton.get(), "NonCombatAura", pButton.texture, "nc +bcast,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +bcast,?", pButton.getName()) pButton.getButton("NonCombatAura").doRight = function(btn) - MultiBot.OnOffActionToTarget(btn, "nc +bcast,?", "nc -bcast,?", btn.getName()) + MultiBot.OnOffUnitStrategy(btn, "nc +bcast,?", "nc -bcast,?", btn.getName()) end end @@ -139,31 +139,31 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) if(MultiBot.hasStrategy(pNormal, "bspeed")) then nonCombatAuraButton.setTexture("spell_holy_crusaderaura").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bspeed,?", "nc -bspeed,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bspeed,?", "nc -bspeed,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "rfire")) then nonCombatAuraButton.setTexture("spell_fire_sealoffire").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +rfire,?", "nc -rfire,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +rfire,?", "nc -rfire,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "rfrost")) then nonCombatAuraButton.setTexture("spell_frost_wizardmark").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +rfrost,?", "nc -rfrost,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +rfrost,?", "nc -rfrost,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "rshadow")) then nonCombatAuraButton.setTexture("spell_shadow_sealofkings").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +rshadow,?", "nc -rshadow,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +rshadow,?", "nc -rshadow,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "baoe")) then nonCombatAuraButton.setTexture("spell_holy_auraoflight").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +baoe,?", "nc -baoe,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +baoe,?", "nc -baoe,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "barmor")) then nonCombatAuraButton.setTexture("spell_holy_devotionaura").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +barmor,?", "nc -barmor,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +barmor,?", "nc -barmor,?", pButton.getName()) end elseif(MultiBot.hasStrategy(pNormal, "bcast")) then nonCombatAuraButton.setTexture("spell_holy_mindsooth").setEnable().doRight = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +bcast,?", "nc -bcast,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +bcast,?", "nc -bcast,?", pButton.getName()) end end diff --git a/Strategies/MultiBotPriest.lua b/Strategies/MultiBotPriest.lua index 9823e4c..f54ba50 100644 --- a/Strategies/MultiBotPriest.lua +++ b/Strategies/MultiBotPriest.lua @@ -11,7 +11,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) pFrame.addButton("Buff", -30, 0, "spell_holy_power", MultiBot.L("tips.priest.buff")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +buff,?", "nc -buff,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +buff,?", "nc -buff,?", pButton.getName()) end -- PLAYBOOK -- @@ -70,7 +70,7 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal) -- (Expose 'rshadow' pour Shadow Protection) playbookFrame.addButton("ShadowRes", 0, 128, "spell_shadow_antishadow", MultiBot.L("tips.priest.playbook.rshadow")).setDisable() .doLeft = function(pButton) - MultiBot.OnOffActionToTarget(pButton, "nc +rshadow,?", "nc -rshadow,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +rshadow,?", "nc -rshadow,?", pButton.getName()) end -- DPS -- diff --git a/Strategies/MultiBotRogue.lua b/Strategies/MultiBotRogue.lua index b38bba4..a9cf0fc 100644 --- a/Strategies/MultiBotRogue.lua +++ b/Strategies/MultiBotRogue.lua @@ -32,7 +32,7 @@ MultiBot.addRogue = function(pFrame, pCombat, pNormal) tFrame.addButton("Stealth", 0, 78, "ability_stealth", MultiBot.L("tips.rogue.dps.stealth")).setDisable() .doLeft = function(pButton) -- "stealth" est une stratégie non-combat : on la pousse côté pNormal - MultiBot.OnOffActionToTarget(pButton, "nc +stealth,?", "nc -stealth,?", pButton.getName()) + MultiBot.OnOffUnitStrategy(pButton, "nc +stealth,?", "nc -stealth,?", pButton.getName()) end -- STEALTHED (comportement EN CAMOUFLAGE en combat) From 9342fbbccfd66b7d39c0c625f14997b30087edbf Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Wed, 19 Aug 2026 22:40:26 +0200 Subject: [PATCH 07/11] Fix LuaLint shadowing in SelfBot wait buttons --- Core/MultiBotEvery.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/MultiBotEvery.lua b/Core/MultiBotEvery.lua index e1b14c5..ff1390e 100644 --- a/Core/MultiBotEvery.lua +++ b/Core/MultiBotEvery.lua @@ -270,8 +270,8 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal) MultiBot.OnOffSelfBotStrategy(pButton, "co +focus,?", "co -focus,?") end - local function addSelfWaitButton(name, x, y, tip, value) - local button = selfCombatFrame.addButton(name, x, y, "Spell_Holy_BorrowedTime", tip) + local function addSelfWaitButton(name, posX, posY, tip, value) + local button = selfCombatFrame.addButton(name, posX, posY, "Spell_Holy_BorrowedTime", tip) button.doLeft = function() runEverySelfAction("WAIT_ATTACK_TIME", tostring(value)) end From b2e4e11d75d248ef3868fd45de63013af0f45e81 Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 20 Aug 2026 12:06:31 +0200 Subject: [PATCH 08/11] Fix SelfBot PR review issues and localized action errors --- Core/MultiBotComm.lua | 43 ++++++++++++++++++++++++++++++ Core/MultiBotEngine.lua | 4 +-- Core/MultiBotEvery.lua | 15 ++++++++--- Locales/MultiBotAceLocale-deDE.lua | 16 +++++++++++ Locales/MultiBotAceLocale-enGB.lua | 16 +++++++++++ Locales/MultiBotAceLocale-enUS.lua | 16 +++++++++++ Locales/MultiBotAceLocale-esES.lua | 16 +++++++++++ Locales/MultiBotAceLocale-frFR.lua | 16 +++++++++++ Locales/MultiBotAceLocale-koKR.lua | 16 +++++++++++ Locales/MultiBotAceLocale-ruRU.lua | 16 +++++++++++ Locales/MultiBotAceLocale-zhCN.lua | 16 +++++++++++ 11 files changed, 185 insertions(+), 5 deletions(-) diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index 443c9c1..3d5435f 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -5406,6 +5406,31 @@ function Comm.HandleSelfActionAddonMessage(opcode, payload, state) return true end + +function Comm.HandleSelfActionProtocolError(requestType, token, reason, state) + if requestType ~= "SELF_ACTION" then + return false + end + + state = type(state) == "table" and state or ensureBridgeState() + token = trim(token) + local pending = state.selfActionCommands[token] + if type(pending) ~= "table" then + return true + end + + state.selfActionCommands[token] = nil + local failureReason = reason or "PROTOCOL_ERROR" + state.lastError = "SELF_ACTION_" .. failureReason + if type(pending.callback) == "function" then + pending.callback({ + status = "error", + action = pending.action, + reason = failureReason, + }) + end + return true +end -- MB_SELFBOT_ACTION_V1_END -- MB_SELFBOT_STRATEGY_V1_RX_HELPER_BEGIN function Comm.HandleSelfStrategyAddonMessage(opcode, payload, state) @@ -5467,11 +5492,27 @@ function Comm.HandleSelfStrategyProtocolError(requestType, token, reason, state) return true end -- MB_SELFBOT_STRATEGY_V1_RX_HELPER_END +function Comm.IsExpectedBridgeSender(sender) + local expectedSender = getPlayerName() + local senderName = trim(sender or "") + senderName = string.gsub(senderName, "%-.*$", "") + if not expectedSender or string.lower(senderName) ~= string.lower(expectedSender) then + debugPrint("ADDON:RX:DROP", "SENDER", sender or "") + return false + end + + return true +end + function Comm.HandleAddonMessage(prefix, message, distribution, sender) if prefix ~= Comm.prefix then return false end + if not Comm.IsExpectedBridgeSender(sender) then + return true + end + local state = ensureBridgeState() local opcode, payload = splitOnce(message or "", "~") opcode = string.upper(trim(opcode)) @@ -7710,6 +7751,8 @@ state.selfActionCapable = false if requestType and isValidStateToken(token) and reason then if Comm.HandleSelfBotProtocolError(requestType, token, reason, state) then return true + elseif Comm.HandleSelfActionProtocolError(requestType, token, reason, state) then + return true elseif Comm.HandleSelfStrategyProtocolError(requestType, token, reason, state) then return true elseif requestType == "GROUP_ROLL" and state.groupRollCommands[token] then diff --git a/Core/MultiBotEngine.lua b/Core/MultiBotEngine.lua index 1e80901..e0f6664 100644 --- a/Core/MultiBotEngine.lua +++ b/Core/MultiBotEngine.lua @@ -720,8 +720,8 @@ MultiBot.RequestUnitStrategyState = function(pTarget) and MultiBot.bridge.connected == true and MultiBot.Comm and type(MultiBot.Comm.RequestSelfStrategyState) == "function") then - MultiBot.Comm.RequestSelfStrategyState() - return true + local request = MultiBot.Comm.RequestSelfStrategyState() + return request ~= false and request ~= nil end return false end diff --git a/Core/MultiBotEvery.lua b/Core/MultiBotEvery.lua index ff1390e..51e8e0f 100644 --- a/Core/MultiBotEvery.lua +++ b/Core/MultiBotEvery.lua @@ -1,22 +1,31 @@ local showEveryMessage +local function selfActionReasonText(reason) + local reasonCode = tostring(reason or "UNKNOWN") + if reasonCode == "RATE_LIMIT" then + return MultiBot.L("selfaction.reason.RATE_LIMIT") + end + return reasonCode +end + local function runEverySelfAction(action, argument) local comm = MultiBot and MultiBot.Comm or nil if not (comm and type(comm.RunSelfAction) == "function") then if showEveryMessage then - showEveryMessage("Bridge unavailable: SelfBot action was not sent.") + showEveryMessage(MultiBot.L("selfaction.bridge_unavailable")) end return false end local token = comm.RunSelfAction(action, argument or "", function(result) if type(result) == "table" and result.status ~= "ok" and showEveryMessage then - showEveryMessage("SelfBot action failed: " .. tostring(result.reason or "UNKNOWN")) + local reasonText = selfActionReasonText(result.reason) + showEveryMessage(string.format(MultiBot.L("selfaction.failed"), reasonText)) end end) if not token and showEveryMessage then local reason = MultiBot and MultiBot.bridge and MultiBot.bridge.lastError or "UNAVAILABLE" - showEveryMessage("SelfBot action was not sent: " .. tostring(reason)) + showEveryMessage(string.format(MultiBot.L("selfaction.send_failed"), selfActionReasonText(reason))) end return token and true or false end diff --git a/Locales/MultiBotAceLocale-deDE.lua b/Locales/MultiBotAceLocale-deDE.lua index ce7d38d..c337426 100644 --- a/Locales/MultiBotAceLocale-deDE.lua +++ b/Locales/MultiBotAceLocale-deDE.lua @@ -4,6 +4,12 @@ if type(register) ~= "function" then end local deDEValues = { + -- MB_SELFACTION_I18N_V1_BEGIN + ["selfaction.bridge_unavailable"] = "Die Bridge ist nicht verfügbar: Die SelfBot-Aktion wurde nicht gesendet.", + ["selfaction.failed"] = "SelfBot-Aktion fehlgeschlagen: %s", + ["selfaction.send_failed"] = "Die SelfBot-Aktion konnte nicht gesendet werden: %s", + ["selfaction.reason.RATE_LIMIT"] = "Zu viele SelfBot-Anfragen. Bitte in einigen Sekunden erneut versuchen.", + -- MB_SELFACTION_I18N_V1_END ["lootmaster.title"] = "MultiBot Plündermeister", ["lootmaster.refresh"] = "Aktualisieren", ["lootmaster.assign_to"] = "Zuweisen an:", @@ -1185,6 +1191,16 @@ local deDEValues = { ["strategy.reason.PARTIAL"] = "Der Strategiebefehl wurde nur teilweise angewendet.", ["strategy.reason.FAILED"] = "Der Strategiebefehl ist fehlgeschlagen.", ["strategy.reason.ACK_TOO_LONG"] = "Die Strategiebestätigung ist zu groß.", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "Die Bridge-Unterstützung für SelfBot-Strategien ist nicht verfügbar.", + ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "Die Bridge ist nicht verbunden.", + ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "SelfBot-Unterstützung ist auf der Bridge nicht verfügbar.", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "SelfBot-Strategieunterstützung ist auf der Bridge nicht verfügbar.", + ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot ist nicht aktiv.", + ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "Das Addon kann keine SelfBot-Strategiebefehle senden.", + ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "Die SelfBot-Strategiesteuerung ist nicht verfügbar.", + ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "Die Bridge hat ein ungültiges SelfBot-Strategieergebnis zurückgegeben.", + ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "Der SelfBot-Strategiebefehl konnte nicht gesendet werden.", + ["strategy.reason.SELF_STRATEGY_REJECTED"] = "Der SelfBot-Strategiebefehl wurde abgelehnt.", ["strategy.reason.UNKNOWN"] = "Der Strategiebefehl ist aus unbekanntem Grund fehlgeschlagen.", ["info.outfits.feedback_equip"] = "Outfit „%s“ ausgerüstet.", ["info.outfits.feedback_replace"] = "Outfit „%s“ ersetzt.", diff --git a/Locales/MultiBotAceLocale-enGB.lua b/Locales/MultiBotAceLocale-enGB.lua index 309afda..5ecc9f3 100644 --- a/Locales/MultiBotAceLocale-enGB.lua +++ b/Locales/MultiBotAceLocale-enGB.lua @@ -4,6 +4,12 @@ if type(register) ~= "function" then end local enGBValues = { + -- MB_SELFACTION_I18N_V1_BEGIN + ["selfaction.bridge_unavailable"] = "The bridge is unavailable: the SelfBot action was not sent.", + ["selfaction.failed"] = "SelfBot action failed: %s", + ["selfaction.send_failed"] = "The SelfBot action could not be sent: %s", + ["selfaction.reason.RATE_LIMIT"] = "Too many SelfBot requests. Try again in a few seconds.", + -- MB_SELFACTION_I18N_V1_END ["lootmaster.title"] = "MultiBot Loot Master", ["lootmaster.refresh"] = "Refresh", ["lootmaster.assign_to"] = "Assign to:", @@ -1188,6 +1194,16 @@ local enGBValues = { ["strategy.reason.PARTIAL"] = "The strategy command was only partially applied.", ["strategy.reason.FAILED"] = "The strategy command failed.", ["strategy.reason.ACK_TOO_LONG"] = "The strategy acknowledgement was too large.", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "Bridge support for SelfBot strategies is unavailable.", + ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "The bridge is not connected.", + ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "SelfBot support is unavailable on the bridge.", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "SelfBot strategy support is unavailable on the bridge.", + ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot is not active.", + ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "The addon cannot send SelfBot strategy commands.", + ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "SelfBot strategy control is unavailable.", + ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "The bridge returned an invalid SelfBot strategy result.", + ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "The SelfBot strategy command could not be sent.", + ["strategy.reason.SELF_STRATEGY_REJECTED"] = "The SelfBot strategy command was rejected.", ["strategy.reason.UNKNOWN"] = "The strategy command failed for an unknown reason.", ["info.outfits.feedback_equip"] = "Outfit \"%s\" equipped.", ["info.outfits.feedback_replace"] = "Outfit \"%s\" replaced.", diff --git a/Locales/MultiBotAceLocale-enUS.lua b/Locales/MultiBotAceLocale-enUS.lua index a0bb2f8..a8ea5d3 100644 --- a/Locales/MultiBotAceLocale-enUS.lua +++ b/Locales/MultiBotAceLocale-enUS.lua @@ -4,6 +4,12 @@ if type(register) ~= "function" then end local enUSValues = { + -- MB_SELFACTION_I18N_V1_BEGIN + ["selfaction.bridge_unavailable"] = "The bridge is unavailable: the SelfBot action was not sent.", + ["selfaction.failed"] = "SelfBot action failed: %s", + ["selfaction.send_failed"] = "The SelfBot action could not be sent: %s", + ["selfaction.reason.RATE_LIMIT"] = "Too many SelfBot requests. Try again in a few seconds.", + -- MB_SELFACTION_I18N_V1_END ["lootmaster.title"] = "MultiBot Loot Master", ["lootmaster.refresh"] = "Refresh", ["lootmaster.assign_to"] = "Assign to:", @@ -1188,6 +1194,16 @@ local enUSValues = { ["strategy.reason.PARTIAL"] = "The strategy command was only partially applied.", ["strategy.reason.FAILED"] = "The strategy command failed.", ["strategy.reason.ACK_TOO_LONG"] = "The strategy acknowledgement was too large.", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "Bridge support for SelfBot strategies is unavailable.", + ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "The bridge is not connected.", + ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "SelfBot support is unavailable on the bridge.", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "SelfBot strategy support is unavailable on the bridge.", + ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot is not active.", + ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "The addon cannot send SelfBot strategy commands.", + ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "SelfBot strategy control is unavailable.", + ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "The bridge returned an invalid SelfBot strategy result.", + ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "The SelfBot strategy command could not be sent.", + ["strategy.reason.SELF_STRATEGY_REJECTED"] = "The SelfBot strategy command was rejected.", ["strategy.reason.UNKNOWN"] = "The strategy command failed for an unknown reason.", ["info.outfits.feedback_equip"] = "Outfit \"%s\" equipped.", ["info.outfits.feedback_replace"] = "Outfit \"%s\" replaced.", diff --git a/Locales/MultiBotAceLocale-esES.lua b/Locales/MultiBotAceLocale-esES.lua index 42ccdfd..f367b18 100644 --- a/Locales/MultiBotAceLocale-esES.lua +++ b/Locales/MultiBotAceLocale-esES.lua @@ -4,6 +4,12 @@ if type(register) ~= "function" then end local esESValues = { + -- MB_SELFACTION_I18N_V1_BEGIN + ["selfaction.bridge_unavailable"] = "El bridge no está disponible: la acción de SelfBot no se ha enviado.", + ["selfaction.failed"] = "La acción de SelfBot ha fallado: %s", + ["selfaction.send_failed"] = "No se ha podido enviar la acción de SelfBot: %s", + ["selfaction.reason.RATE_LIMIT"] = "Demasiadas solicitudes de SelfBot. Vuelve a intentarlo en unos segundos.", + -- MB_SELFACTION_I18N_V1_END ["lootmaster.title"] = "MultiBot Maestro despojador", ["lootmaster.refresh"] = "Actualizar", ["lootmaster.assign_to"] = "Asignar a:", @@ -1186,6 +1192,16 @@ local esESValues = { ["strategy.reason.PARTIAL"] = "La orden de estrategia solo se aplicó parcialmente.", ["strategy.reason.FAILED"] = "La orden de estrategia falló.", ["strategy.reason.ACK_TOO_LONG"] = "La confirmación de estrategia es demasiado grande.", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "La compatibilidad del puente con las estrategias de SelfBot no está disponible.", + ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "El puente no está conectado.", + ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "La compatibilidad con SelfBot no está disponible en el puente.", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "La compatibilidad con estrategias de SelfBot no está disponible en el puente.", + ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot no está activo.", + ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "El addon no puede enviar comandos de estrategia de SelfBot.", + ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "El control de estrategias de SelfBot no está disponible.", + ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "El puente devolvió un resultado de estrategia de SelfBot no válido.", + ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "No se pudo enviar el comando de estrategia de SelfBot.", + ["strategy.reason.SELF_STRATEGY_REJECTED"] = "El comando de estrategia de SelfBot fue rechazado.", ["strategy.reason.UNKNOWN"] = "La orden de estrategia falló por un motivo desconocido.", ["info.outfits.feedback_equip"] = "Conjunto «%s» equipado.", ["info.outfits.feedback_replace"] = "Conjunto «%s» reemplazado.", diff --git a/Locales/MultiBotAceLocale-frFR.lua b/Locales/MultiBotAceLocale-frFR.lua index 6fdf5a7..6e79e0d 100644 --- a/Locales/MultiBotAceLocale-frFR.lua +++ b/Locales/MultiBotAceLocale-frFR.lua @@ -4,6 +4,12 @@ if type(register) ~= "function" then end local frFRValues = { + -- MB_SELFACTION_I18N_V1_BEGIN + ["selfaction.bridge_unavailable"] = "Le bridge est indisponible : l'action SelfBot n'a pas été envoyée.", + ["selfaction.failed"] = "Échec de l'action SelfBot : %s", + ["selfaction.send_failed"] = "L'action SelfBot n'a pas pu être envoyée : %s", + ["selfaction.reason.RATE_LIMIT"] = "Trop de demandes SelfBot. Réessayez dans quelques secondes.", + -- MB_SELFACTION_I18N_V1_END ["lootmaster.title"] = "MultiBot Responsable du butin", ["lootmaster.refresh"] = "Rafraîchir", ["lootmaster.assign_to"] = "Attribuer à :", @@ -1185,6 +1191,16 @@ local frFRValues = { ["strategy.reason.PARTIAL"] = "La commande de stratégie n'a été appliquée que partiellement.", ["strategy.reason.FAILED"] = "La commande de stratégie a échoué.", ["strategy.reason.ACK_TOO_LONG"] = "L'accusé de réception de stratégie est trop volumineux.", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "Le bridge SelfBot pour les stratégies est indisponible.", + ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "Le bridge n'est pas connecté.", + ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "La prise en charge SelfBot est indisponible sur le bridge.", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "La prise en charge des stratégies SelfBot est indisponible sur le bridge.", + ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot n'est pas actif.", + ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "L'addon ne peut pas envoyer de commandes de stratégie SelfBot.", + ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "Le contrôle des stratégies SelfBot est indisponible.", + ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "Le bridge a renvoyé un résultat de stratégie SelfBot invalide.", + ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "La commande de stratégie SelfBot n'a pas pu être envoyée.", + ["strategy.reason.SELF_STRATEGY_REJECTED"] = "La commande de stratégie SelfBot a été refusée.", ["strategy.reason.UNKNOWN"] = "La commande de stratégie a échoué pour une raison inconnue.", ["info.outfits.feedback_equip"] = "Tenue « %s » équipée.", ["info.outfits.feedback_replace"] = "Tenue « %s » remplacée.", diff --git a/Locales/MultiBotAceLocale-koKR.lua b/Locales/MultiBotAceLocale-koKR.lua index 57afb7a..5cb630f 100644 --- a/Locales/MultiBotAceLocale-koKR.lua +++ b/Locales/MultiBotAceLocale-koKR.lua @@ -4,6 +4,12 @@ if type(register) ~= "function" then end local koKRValues = { + -- MB_SELFACTION_I18N_V1_BEGIN + ["selfaction.bridge_unavailable"] = "브리지를 사용할 수 없어 SelfBot 동작을 보내지 못했습니다.", + ["selfaction.failed"] = "SelfBot 동작 실패: %s", + ["selfaction.send_failed"] = "SelfBot 동작을 보내지 못했습니다: %s", + ["selfaction.reason.RATE_LIMIT"] = "SelfBot 요청이 너무 많습니다. 몇 초 후 다시 시도하세요.", + -- MB_SELFACTION_I18N_V1_END ["lootmaster.title"] = "MultiBot 전리품 담당자", ["lootmaster.refresh"] = "새로 고침", ["lootmaster.assign_to"] = "할당 대상:", @@ -1177,6 +1183,16 @@ local koKRValues = { ["strategy.reason.PARTIAL"] = "전략 명령이 일부만 적용되었습니다.", ["strategy.reason.FAILED"] = "전략 명령이 실패했습니다.", ["strategy.reason.ACK_TOO_LONG"] = "전략 응답이 너무 큽니다.", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "브리지의 SelfBot 전략 지원을 사용할 수 없습니다.", + ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "브리지가 연결되어 있지 않습니다.", + ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "브리지에서 SelfBot 지원을 사용할 수 없습니다.", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "브리지에서 SelfBot 전략 지원을 사용할 수 없습니다.", + ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot이 활성화되어 있지 않습니다.", + ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "애드온이 SelfBot 전략 명령을 보낼 수 없습니다.", + ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "SelfBot 전략 제어를 사용할 수 없습니다.", + ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "브리지가 잘못된 SelfBot 전략 결과를 반환했습니다.", + ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "SelfBot 전략 명령을 보낼 수 없습니다.", + ["strategy.reason.SELF_STRATEGY_REJECTED"] = "SelfBot 전략 명령이 거부되었습니다.", ["strategy.reason.UNKNOWN"] = "알 수 없는 이유로 전략 명령이 실패했습니다.", ["info.outfits.feedback_equip"] = "장비 세트 \"%s\": 장착 완료.", ["info.outfits.feedback_replace"] = "장비 세트 \"%s\": 교체 완료.", diff --git a/Locales/MultiBotAceLocale-ruRU.lua b/Locales/MultiBotAceLocale-ruRU.lua index 8a92f1d..d57e1d3 100644 --- a/Locales/MultiBotAceLocale-ruRU.lua +++ b/Locales/MultiBotAceLocale-ruRU.lua @@ -4,6 +4,12 @@ if type(register) ~= "function" then end local ruRUValues = { + -- MB_SELFACTION_I18N_V1_BEGIN + ["selfaction.bridge_unavailable"] = "Мост недоступен: действие SelfBot не было отправлено.", + ["selfaction.failed"] = "Ошибка действия SelfBot: %s", + ["selfaction.send_failed"] = "Не удалось отправить действие SelfBot: %s", + ["selfaction.reason.RATE_LIMIT"] = "Слишком много запросов SelfBot. Повторите попытку через несколько секунд.", + -- MB_SELFACTION_I18N_V1_END ["lootmaster.title"] = "MultiBot ответственный за добычу", ["lootmaster.refresh"] = "Обновить", ["lootmaster.assign_to"] = "Назначить:", @@ -1186,6 +1192,16 @@ local ruRUValues = { ["strategy.reason.PARTIAL"] = "Команда стратегии применена только частично.", ["strategy.reason.FAILED"] = "Команда стратегии завершилась ошибкой.", ["strategy.reason.ACK_TOO_LONG"] = "Подтверждение стратегии слишком велико.", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "Поддержка стратегий SelfBot через мост недоступна.", + ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "Мост не подключен.", + ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "Поддержка SelfBot на мосту недоступна.", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "Поддержка стратегий SelfBot на мосту недоступна.", + ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot не активен.", + ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "Аддон не может отправлять команды стратегий SelfBot.", + ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "Управление стратегиями SelfBot недоступно.", + ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "Мост вернул некорректный результат стратегии SelfBot.", + ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "Не удалось отправить команду стратегии SelfBot.", + ["strategy.reason.SELF_STRATEGY_REJECTED"] = "Команда стратегии SelfBot была отклонена.", ["strategy.reason.UNKNOWN"] = "Команда стратегии завершилась ошибкой по неизвестной причине.", ["info.outfits.feedback_equip"] = "Комплект «%s» экипирован.", ["info.outfits.feedback_replace"] = "Комплект «%s» заменён.", diff --git a/Locales/MultiBotAceLocale-zhCN.lua b/Locales/MultiBotAceLocale-zhCN.lua index 0e4d0db..8291221 100644 --- a/Locales/MultiBotAceLocale-zhCN.lua +++ b/Locales/MultiBotAceLocale-zhCN.lua @@ -4,6 +4,12 @@ if type(register) ~= "function" then end local zhCNValues = { + -- MB_SELFACTION_I18N_V1_BEGIN + ["selfaction.bridge_unavailable"] = "Bridge 不可用:SelfBot 操作未发送。", + ["selfaction.failed"] = "SelfBot 操作失败:%s", + ["selfaction.send_failed"] = "无法发送 SelfBot 操作:%s", + ["selfaction.reason.RATE_LIMIT"] = "SelfBot 请求过于频繁。请几秒后重试。", + -- MB_SELFACTION_I18N_V1_END ["lootmaster.title"] = "MultiBot 战利品分配者", ["lootmaster.refresh"] = "刷新", ["lootmaster.assign_to"] = "分配给:", @@ -1186,6 +1192,16 @@ local zhCNValues = { ["strategy.reason.PARTIAL"] = "策略命令只应用了一部分。", ["strategy.reason.FAILED"] = "策略命令失败。", ["strategy.reason.ACK_TOO_LONG"] = "策略确认消息过大。", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "桥接端的 SelfBot 策略支持不可用。", + ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "桥接端未连接。", + ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "桥接端不支持 SelfBot。", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "桥接端不支持 SelfBot 策略。", + ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot 未启用。", + ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "插件无法发送 SelfBot 策略命令。", + ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "SelfBot 策略控制不可用。", + ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "桥接端返回了无效的 SelfBot 策略结果。", + ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "无法发送 SelfBot 策略命令。", + ["strategy.reason.SELF_STRATEGY_REJECTED"] = "SelfBot 策略命令被拒绝。", ["strategy.reason.UNKNOWN"] = "策略命令因未知原因失败。", ["info.outfits.feedback_equip"] = "配装“%s”已装备。", ["info.outfits.feedback_replace"] = "配装“%s”已替换。", From 2cc392c9e2787461f2c73b02664a65bbc572dc3a Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 20 Aug 2026 12:57:56 +0200 Subject: [PATCH 09/11] Fix remaining SelfBot strategy review issues --- Core/MultiBotComm.lua | 2 +- Locales/MultiBotAceLocale-deDE.lua | 3 +++ Locales/MultiBotAceLocale-enGB.lua | 3 +++ Locales/MultiBotAceLocale-enUS.lua | 3 +++ Locales/MultiBotAceLocale-esES.lua | 7 +++++-- Locales/MultiBotAceLocale-frFR.lua | 3 +++ Locales/MultiBotAceLocale-koKR.lua | 3 +++ Locales/MultiBotAceLocale-ruRU.lua | 3 +++ Locales/MultiBotAceLocale-zhCN.lua | 3 +++ 9 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index 3d5435f..6a5345f 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -7770,7 +7770,7 @@ state.selfActionCapable = false failed = 0, reason = reason, }) - elseif (requestType == "STATE" or requestType == "STATES") and state.stateRequests[token] then + elseif (requestType == "STATE" or requestType == "STATES" or requestType == "SELF_STRATEGY_STATE") and state.stateRequests[token] then failBootstrapStateRequest(state, token) clearStateRequest(state, token) end diff --git a/Locales/MultiBotAceLocale-deDE.lua b/Locales/MultiBotAceLocale-deDE.lua index c337426..28bf5b0 100644 --- a/Locales/MultiBotAceLocale-deDE.lua +++ b/Locales/MultiBotAceLocale-deDE.lua @@ -1201,6 +1201,9 @@ local deDEValues = { ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "Die Bridge hat ein ungültiges SelfBot-Strategieergebnis zurückgegeben.", ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "Der SelfBot-Strategiebefehl konnte nicht gesendet werden.", ["strategy.reason.SELF_STRATEGY_REJECTED"] = "Der SelfBot-Strategiebefehl wurde abgelehnt.", + ["strategy.reason.SELF_STRATEGY_INVALID_STATE_SCOPE"] = "Ungültiger SelfBot-Strategiezustandsbereich.", + ["strategy.reason.SELF_STRATEGY_INVALID_CHANGES"] = "Ungültige SelfBot-Strategieänderungen.", + ["strategy.reason.SELF_STRATEGY_TOO_MANY_REQUESTS"] = "Zu viele SelfBot-Strategieanfragen. Versuche es gleich erneut.", ["strategy.reason.UNKNOWN"] = "Der Strategiebefehl ist aus unbekanntem Grund fehlgeschlagen.", ["info.outfits.feedback_equip"] = "Outfit „%s“ ausgerüstet.", ["info.outfits.feedback_replace"] = "Outfit „%s“ ersetzt.", diff --git a/Locales/MultiBotAceLocale-enGB.lua b/Locales/MultiBotAceLocale-enGB.lua index 5ecc9f3..0df4e4d 100644 --- a/Locales/MultiBotAceLocale-enGB.lua +++ b/Locales/MultiBotAceLocale-enGB.lua @@ -1204,6 +1204,9 @@ local enGBValues = { ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "The bridge returned an invalid SelfBot strategy result.", ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "The SelfBot strategy command could not be sent.", ["strategy.reason.SELF_STRATEGY_REJECTED"] = "The SelfBot strategy command was rejected.", + ["strategy.reason.SELF_STRATEGY_INVALID_STATE_SCOPE"] = "Invalid SelfBot strategy state scope.", + ["strategy.reason.SELF_STRATEGY_INVALID_CHANGES"] = "Invalid SelfBot strategy changes.", + ["strategy.reason.SELF_STRATEGY_TOO_MANY_REQUESTS"] = "Too many SelfBot strategy requests. Try again in a moment.", ["strategy.reason.UNKNOWN"] = "The strategy command failed for an unknown reason.", ["info.outfits.feedback_equip"] = "Outfit \"%s\" equipped.", ["info.outfits.feedback_replace"] = "Outfit \"%s\" replaced.", diff --git a/Locales/MultiBotAceLocale-enUS.lua b/Locales/MultiBotAceLocale-enUS.lua index a8ea5d3..d855cef 100644 --- a/Locales/MultiBotAceLocale-enUS.lua +++ b/Locales/MultiBotAceLocale-enUS.lua @@ -1204,6 +1204,9 @@ local enUSValues = { ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "The bridge returned an invalid SelfBot strategy result.", ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "The SelfBot strategy command could not be sent.", ["strategy.reason.SELF_STRATEGY_REJECTED"] = "The SelfBot strategy command was rejected.", + ["strategy.reason.SELF_STRATEGY_INVALID_STATE_SCOPE"] = "Invalid SelfBot strategy state scope.", + ["strategy.reason.SELF_STRATEGY_INVALID_CHANGES"] = "Invalid SelfBot strategy changes.", + ["strategy.reason.SELF_STRATEGY_TOO_MANY_REQUESTS"] = "Too many SelfBot strategy requests. Try again in a moment.", ["strategy.reason.UNKNOWN"] = "The strategy command failed for an unknown reason.", ["info.outfits.feedback_equip"] = "Outfit \"%s\" equipped.", ["info.outfits.feedback_replace"] = "Outfit \"%s\" replaced.", diff --git a/Locales/MultiBotAceLocale-esES.lua b/Locales/MultiBotAceLocale-esES.lua index f367b18..8b1a937 100644 --- a/Locales/MultiBotAceLocale-esES.lua +++ b/Locales/MultiBotAceLocale-esES.lua @@ -1192,16 +1192,19 @@ local esESValues = { ["strategy.reason.PARTIAL"] = "La orden de estrategia solo se aplicó parcialmente.", ["strategy.reason.FAILED"] = "La orden de estrategia falló.", ["strategy.reason.ACK_TOO_LONG"] = "La confirmación de estrategia es demasiado grande.", - ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "La compatibilidad del puente con las estrategias de SelfBot no está disponible.", + ["strategy.reason.SELF_STRATEGY_BRIDGE_UNAVAILABLE"] = "El bridge de estrategias de SelfBot no está disponible.", ["strategy.reason.SELF_STRATEGY_NOT_CONNECTED"] = "El puente no está conectado.", ["strategy.reason.SELF_BOT_CAPABILITY_UNAVAILABLE"] = "La compatibilidad con SelfBot no está disponible en el puente.", - ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "La compatibilidad con estrategias de SelfBot no está disponible en el puente.", + ["strategy.reason.SELF_STRATEGY_CAPABILITY_UNAVAILABLE"] = "El bridge conectado no admite la modificación de estrategias de SelfBot.", ["strategy.reason.SELF_STRATEGY_NOT_ACTIVE"] = "SelfBot no está activo.", ["strategy.reason.SELF_STRATEGY_CLIENT_UNAVAILABLE"] = "El addon no puede enviar comandos de estrategia de SelfBot.", ["strategy.reason.SELF_STRATEGY_UNAVAILABLE"] = "El control de estrategias de SelfBot no está disponible.", ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "El puente devolvió un resultado de estrategia de SelfBot no válido.", ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "No se pudo enviar el comando de estrategia de SelfBot.", ["strategy.reason.SELF_STRATEGY_REJECTED"] = "El comando de estrategia de SelfBot fue rechazado.", + ["strategy.reason.SELF_STRATEGY_INVALID_STATE_SCOPE"] = "Ámbito de estado de estrategia de SelfBot no válido.", + ["strategy.reason.SELF_STRATEGY_INVALID_CHANGES"] = "Cambios de estrategia de SelfBot no válidos.", + ["strategy.reason.SELF_STRATEGY_TOO_MANY_REQUESTS"] = "Demasiadas solicitudes de estrategia de SelfBot. Inténtalo de nuevo en un momento.", ["strategy.reason.UNKNOWN"] = "La orden de estrategia falló por un motivo desconocido.", ["info.outfits.feedback_equip"] = "Conjunto «%s» equipado.", ["info.outfits.feedback_replace"] = "Conjunto «%s» reemplazado.", diff --git a/Locales/MultiBotAceLocale-frFR.lua b/Locales/MultiBotAceLocale-frFR.lua index 6e79e0d..ec5b49a 100644 --- a/Locales/MultiBotAceLocale-frFR.lua +++ b/Locales/MultiBotAceLocale-frFR.lua @@ -1201,6 +1201,9 @@ local frFRValues = { ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "Le bridge a renvoyé un résultat de stratégie SelfBot invalide.", ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "La commande de stratégie SelfBot n'a pas pu être envoyée.", ["strategy.reason.SELF_STRATEGY_REJECTED"] = "La commande de stratégie SelfBot a été refusée.", + ["strategy.reason.SELF_STRATEGY_INVALID_STATE_SCOPE"] = "Portée d'état de stratégie SelfBot non valide.", + ["strategy.reason.SELF_STRATEGY_INVALID_CHANGES"] = "Modifications de stratégie SelfBot non valides.", + ["strategy.reason.SELF_STRATEGY_TOO_MANY_REQUESTS"] = "Trop de requêtes de stratégie SelfBot. Réessayez dans un instant.", ["strategy.reason.UNKNOWN"] = "La commande de stratégie a échoué pour une raison inconnue.", ["info.outfits.feedback_equip"] = "Tenue « %s » équipée.", ["info.outfits.feedback_replace"] = "Tenue « %s » remplacée.", diff --git a/Locales/MultiBotAceLocale-koKR.lua b/Locales/MultiBotAceLocale-koKR.lua index 5cb630f..d48dfcc 100644 --- a/Locales/MultiBotAceLocale-koKR.lua +++ b/Locales/MultiBotAceLocale-koKR.lua @@ -1193,6 +1193,9 @@ local koKRValues = { ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "브리지가 잘못된 SelfBot 전략 결과를 반환했습니다.", ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "SelfBot 전략 명령을 보낼 수 없습니다.", ["strategy.reason.SELF_STRATEGY_REJECTED"] = "SelfBot 전략 명령이 거부되었습니다.", + ["strategy.reason.SELF_STRATEGY_INVALID_STATE_SCOPE"] = "SelfBot 전략 상태 범위가 올바르지 않습니다.", + ["strategy.reason.SELF_STRATEGY_INVALID_CHANGES"] = "SelfBot 전략 변경 내용이 올바르지 않습니다.", + ["strategy.reason.SELF_STRATEGY_TOO_MANY_REQUESTS"] = "SelfBot 전략 요청이 너무 많습니다. 잠시 후 다시 시도하세요.", ["strategy.reason.UNKNOWN"] = "알 수 없는 이유로 전략 명령이 실패했습니다.", ["info.outfits.feedback_equip"] = "장비 세트 \"%s\": 장착 완료.", ["info.outfits.feedback_replace"] = "장비 세트 \"%s\": 교체 완료.", diff --git a/Locales/MultiBotAceLocale-ruRU.lua b/Locales/MultiBotAceLocale-ruRU.lua index d57e1d3..edebc4b 100644 --- a/Locales/MultiBotAceLocale-ruRU.lua +++ b/Locales/MultiBotAceLocale-ruRU.lua @@ -1202,6 +1202,9 @@ local ruRUValues = { ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "Мост вернул некорректный результат стратегии SelfBot.", ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "Не удалось отправить команду стратегии SelfBot.", ["strategy.reason.SELF_STRATEGY_REJECTED"] = "Команда стратегии SelfBot была отклонена.", + ["strategy.reason.SELF_STRATEGY_INVALID_STATE_SCOPE"] = "Недопустимая область состояния стратегии SelfBot.", + ["strategy.reason.SELF_STRATEGY_INVALID_CHANGES"] = "Недопустимые изменения стратегии SelfBot.", + ["strategy.reason.SELF_STRATEGY_TOO_MANY_REQUESTS"] = "Слишком много запросов стратегии SelfBot. Повторите попытку чуть позже.", ["strategy.reason.UNKNOWN"] = "Команда стратегии завершилась ошибкой по неизвестной причине.", ["info.outfits.feedback_equip"] = "Комплект «%s» экипирован.", ["info.outfits.feedback_replace"] = "Комплект «%s» заменён.", diff --git a/Locales/MultiBotAceLocale-zhCN.lua b/Locales/MultiBotAceLocale-zhCN.lua index 8291221..d64c50c 100644 --- a/Locales/MultiBotAceLocale-zhCN.lua +++ b/Locales/MultiBotAceLocale-zhCN.lua @@ -1202,6 +1202,9 @@ local zhCNValues = { ["strategy.reason.SELF_STRATEGY_INVALID_RESULT"] = "桥接端返回了无效的 SelfBot 策略结果。", ["strategy.reason.SELF_STRATEGY_SEND_FAILED"] = "无法发送 SelfBot 策略命令。", ["strategy.reason.SELF_STRATEGY_REJECTED"] = "SelfBot 策略命令被拒绝。", + ["strategy.reason.SELF_STRATEGY_INVALID_STATE_SCOPE"] = "SelfBot 策略状态范围无效。", + ["strategy.reason.SELF_STRATEGY_INVALID_CHANGES"] = "SelfBot 策略更改无效。", + ["strategy.reason.SELF_STRATEGY_TOO_MANY_REQUESTS"] = "SelfBot 策略请求过多,请稍后重试。", ["strategy.reason.UNKNOWN"] = "策略命令因未知原因失败。", ["info.outfits.feedback_equip"] = "配装“%s”已装备。", ["info.outfits.feedback_replace"] = "配装“%s”已替换。", From ae59463cde667f590c5e8437b8b719531bed6afc Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 20 Aug 2026 14:07:37 +0200 Subject: [PATCH 10/11] Make SelfBot strategy UI ACK-authoritative --- Core/MultiBotComm.lua | 3 +- Core/MultiBotEngine.lua | 79 +++++++++++++++++++++++---------- Strategies/MultiBotShaman.lua | 44 +++++++++++++++--- Strategies/MultiBotWarlock.lua | 28 ++++++++++-- UI/MultiBotShamanQuickFrame.lua | 53 ++++++++++++++++------ 5 files changed, 159 insertions(+), 48 deletions(-) diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index 6a5345f..117c0c9 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -51,6 +51,7 @@ local STRATEGY_MUTATION_TIMEOUT_SECONDS = 5.0 local SELF_STRATEGY_MUTATION_TIMEOUT_SECONDS = 10.0 local SELF_ACTION_TIMEOUT_SECONDS = 10.0 local STRATEGY_MUTATION_MAX_ACTIVE = 32 +local SELF_STRATEGY_MUTATION_MAX_ACTIVE = 1 local STRATEGY_MUTATION_MAX_CHANGES_LENGTH = 160 local STRATEGY_MUTATION_MAX_OPERATIONS = 32 local STRATEGY_MUTATION_MAX_STRATEGY_LENGTH = 96 @@ -1220,7 +1221,7 @@ function Comm.RunSelfStrategyCommand(stateScope, changes, callback) state.lastError = "SELF_STRATEGY_INVALID_CHANGES" return false end - if countTableEntries(state.selfStrategyCommands) >= STRATEGY_MUTATION_MAX_ACTIVE then + if countTableEntries(state.selfStrategyCommands) >= SELF_STRATEGY_MUTATION_MAX_ACTIVE then state.lastError = "SELF_STRATEGY_TOO_MANY_REQUESTS" return false end diff --git a/Core/MultiBotEngine.lua b/Core/MultiBotEngine.lua index e0f6664..224b132 100644 --- a/Core/MultiBotEngine.lua +++ b/Core/MultiBotEngine.lua @@ -645,43 +645,48 @@ local function _mbRefreshSelfStrategyState() end end -local function _mbRouteSelfStrategyMutation(action) +local function _mbRouteSelfStrategyMutation(action, onComplete) local mutationScope, changes = _mbParseStrategyMutation(action) - if(not mutationScope) then return MB_STRATEGY_ROUTE_NOT_STRATEGY end + if(not mutationScope) then return MB_STRATEGY_ROUTE_NOT_STRATEGY, nil end local subject = UnitName("player") or "self" if(not _mbCanUseBridgeSelfStrategyMutation()) then _mbWarnStrategyMutationBlocked("SELF", subject, _mbSelfStrategyUnavailableReason()) _mbRefreshSelfStrategyState() - return MB_STRATEGY_ROUTE_BLOCKED + return MB_STRATEGY_ROUTE_BLOCKED, nil end local stateScope = mutationScope == "nc" and "N" or "C" local token = MultiBot.Comm.RunSelfStrategyCommand(stateScope, changes, function(result) + local ok = false if(type(result) ~= "table") then _mbWarnStrategyMutationBlocked("SELF", subject, "SELF_STRATEGY_INVALID_RESULT") - _mbRefreshSelfStrategyState() - return - end - - if(result.status ~= "ok") then - local reason = result.reason - if(type(reason) ~= "string" or reason == "") then - reason = result.status or "SELF_STRATEGY_REJECTED" + else + ok = result.status == "ok" + if(not ok) then + local reason = result.reason + if(type(reason) ~= "string" or reason == "") then + reason = result.status or "SELF_STRATEGY_REJECTED" + end + _mbWarnStrategyMutationBlocked("SELF", subject, reason) end - _mbWarnStrategyMutationBlocked("SELF", subject, reason) end + -- Refresh authoritative state before any specialized ACK-side UI commit. _mbRefreshSelfStrategyState() + + if(type(onComplete) == "function") then + onComplete(ok, result) + end end) if(token ~= false and token ~= nil) then - return MB_STRATEGY_ROUTE_BRIDGE + return MB_STRATEGY_ROUTE_BRIDGE, token end _mbWarnStrategyMutationBlocked("SELF", subject, _mbStrategyLastError("SELF_STRATEGY_SEND_FAILED")) _mbRefreshSelfStrategyState() - return MB_STRATEGY_ROUTE_BLOCKED + return MB_STRATEGY_ROUTE_BLOCKED, nil end MultiBot.OnOffSelfBotStrategy = function(pButton, pOn, pOff) @@ -689,17 +694,19 @@ MultiBot.OnOffSelfBotStrategy = function(pButton, pOn, pOff) local action = wasEnabled and pOff or pOn local mutationScope = _mbParseStrategyMutation(action) if(not mutationScope) then - return wasEnabled + return false, "blocked" end - local route = _mbRouteSelfStrategyMutation(action) + local route, token = _mbRouteSelfStrategyMutation(action) if(route == MB_STRATEGY_ROUTE_BRIDGE) then - -- The authoritative STATE response rebuilds the final visual state. - return not wasEnabled + -- A queued request is not an applied mutation. The authoritative + -- SELF_STRATEGY_STATE refresh owns the final toggle and sibling state. + return false, "pending", token end - -- SelfBot never falls through to the legacy bot whisper route. - return wasEnabled + -- SelfBot never falls through to the legacy bot whisper route and blocked + -- requests must never be mistaken for a successful/active toggle. + return false, "blocked" end MultiBot.IsSelfBotStrategyTarget = function(pTarget) @@ -739,7 +746,7 @@ MultiBot.RequestUnitStrategyState = function(pTarget) return false end -MultiBot.ActionToUnitStrategy = function(pAction, oTarget) +MultiBot.ActionToUnitStrategy = function(pAction, oTarget, onComplete) local targetName = MultiBot.IF(oTarget == nil, UnitName("target"), oTarget) if(MultiBot.IsSelfBotStrategyTarget(targetName)) then @@ -749,14 +756,17 @@ MultiBot.ActionToUnitStrategy = function(pAction, oTarget) return false, "blocked" end - local route = _mbRouteSelfStrategyMutation(pAction) + local route, token = _mbRouteSelfStrategyMutation(pAction, onComplete) if(route == MB_STRATEGY_ROUTE_BRIDGE) then - return true, "bridge" + -- false means "not synchronously applied"; pending is explicit so + -- callers cannot accidentally commit optimistic SelfBot UI. + return false, "pending", token end return false, "blocked" end + -- Ordinary bot semantics remain unchanged. return MultiBot.ActionToTarget(pAction, targetName) end MultiBot.ActionToTarget = function(pAction, oTarget) @@ -858,7 +868,28 @@ MultiBot.SelectToTarget = function(pParent, pIndex, pTexture, pAction, oTarget) end MultiBot.SelectToUnitStrategy = function(pParent, pIndex, pTexture, pAction, oTarget) - if(MultiBot.ActionToUnitStrategy(pAction, oTarget)) then + local targetName = MultiBot.IF(oTarget == nil, UnitName("target"), oTarget) + + if(MultiBot.IsSelfBotStrategyTarget(targetName)) then + local _, transport, token = MultiBot.ActionToUnitStrategy(pAction, targetName, function(ok) + if(ok ~= true) then return end + + local tFrame = pParent.frames[pIndex] + local tButton = pParent.buttons[pIndex] + if(not tFrame or not tButton) then return end + + tButton.setTexture(pTexture) + tFrame:Hide() + if(MultiBot.RequestClickBlockerUpdate) then MultiBot.RequestClickBlockerUpdate(tFrame) end + end) + + if(transport == "pending") then + return false, "pending", token + end + return false, transport or "blocked" + end + + if(MultiBot.ActionToUnitStrategy(pAction, targetName)) then local tFrame = pParent.frames[pIndex] local tButton = pParent.buttons[pIndex] tButton.setTexture(pTexture) diff --git a/Strategies/MultiBotShaman.lua b/Strategies/MultiBotShaman.lua index 37e9c43..1fb5a2c 100644 --- a/Strategies/MultiBotShaman.lua +++ b/Strategies/MultiBotShaman.lua @@ -212,22 +212,56 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal) -- MB_P1A_SHAMAN_PLAYBOOK_BLOCKED_STATE_V1_START local function dispatchShamanPlaybookCommands(target, commands, bridgeSync, sequenceKey, sequence, onAccepted) + local selfStrategyTarget = MultiBot.IsSelfBotStrategyTarget + and MultiBot.IsSelfBotStrategyTarget(target) + + local function finishAcceptedSequence() + if(type(onAccepted) == "function" and isShamanPlaybookSequenceCurrent(sequenceKey, sequence)) then + onAccepted() + end + requestShamanCombatState(target, bridgeSync, sequenceKey, sequence) + end + local function sendCommand(index) if(not isShamanPlaybookSequenceCurrent(sequenceKey, sequence)) then return end local command = commands[index] if(not command) then return end - if(not MultiBot.ActionToUnitStrategy(command, target)) then return end + + local completion = nil + if(selfStrategyTarget) then + completion = function(ok) + if(not isShamanPlaybookSequenceCurrent(sequenceKey, sequence)) then return end + if(ok ~= true) then return end + + if(index < #commands) then + scheduleShamanTask(shamanCommandInterval, function() + sendCommand(index + 1) + end) + else + finishAcceptedSequence() + end + end + end + + local sent, transport = MultiBot.ActionToUnitStrategy(command, target, completion) + + if(selfStrategyTarget) then + -- "pending" means queued only. The completion callback alone + -- advances the SelfBot sequence after an ACK OK. + if(transport ~= "pending") then return end + return + end + + -- Preserve the existing ordinary-bot behavior. + if(not sent) then return end if(index < #commands) then scheduleShamanTask(shamanCommandInterval, function() sendCommand(index + 1) end) else - if(type(onAccepted) == "function" and isShamanPlaybookSequenceCurrent(sequenceKey, sequence)) then - onAccepted() - end - requestShamanCombatState(target, bridgeSync, sequenceKey, sequence) + finishAcceptedSequence() end end diff --git a/Strategies/MultiBotWarlock.lua b/Strategies/MultiBotWarlock.lua index fd4bd21..2b4f6d9 100644 --- a/Strategies/MultiBotWarlock.lua +++ b/Strategies/MultiBotWarlock.lua @@ -163,7 +163,12 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) end end - local sent, transport = MultiBot.ActionToUnitStrategy(action, target) + local sent, transport = MultiBot.ActionToUnitStrategy(action, target, function(ok) + if ok == true then + fStones:Hide() + end + end) + if transport == "pending" then return end if not sent then return end if transport ~= "bridge" then fStones.activeStone = desired @@ -258,7 +263,12 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) end end - local sent, transport = MultiBot.ActionToUnitStrategy(action, target) + local sent, transport = MultiBot.ActionToUnitStrategy(action, target, function(ok) + if ok == true then + fSoul:Hide() + end + end) + if transport == "pending" then return end if not sent then return end if transport ~= "bridge" then fSoul.activeSS = desired @@ -357,7 +367,12 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) end end - local sent, transport = MultiBot.ActionToUnitStrategy(action, target) + local sent, transport = MultiBot.ActionToUnitStrategy(action, target, function(ok) + if ok == true then + fPets:Hide() + end + end) + if transport == "pending" then return end if not sent then return end if transport ~= "bridge" then fPets.activePet = desired @@ -537,7 +552,12 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal) end end - local sent, transport = MultiBot.ActionToUnitStrategy(action, target) + local sent, transport = MultiBot.ActionToUnitStrategy(action, target, function(ok) + if ok == true then + fCurses:Hide() + end + end) + if transport == "pending" then return end if not sent then return end if transport ~= "bridge" then fCurses.activeCurse = desired diff --git a/UI/MultiBotShamanQuickFrame.lua b/UI/MultiBotShamanQuickFrame.lua index e352630..4c38771 100644 --- a/UI/MultiBotShamanQuickFrame.lua +++ b/UI/MultiBotShamanQuickFrame.lua @@ -718,12 +718,39 @@ function ShamanQuick:SelectTotem(row, elementKey, button, definition) local currentButton = row.selectedButtons[elementKey] local currentIcon = row.selectedIcons[elementKey] local isSameSelection = currentButton == button or currentIcon == button.__mbIcon + local selfStrategyTarget = MultiBot.IsSelfBotStrategyTarget + and MultiBot.IsSelfBotStrategyTarget(row.owner) + + local function runMutation(action, onAccepted) + local completion = nil + if selfStrategyTarget then + completion = function(ok) + if ok == true and type(onAccepted) == "function" then + onAccepted() + end + end + end - if isSameSelection then - if not MultiBot.ActionToUnitStrategy("co -" .. definition.spell .. ",?", row.owner) then - return + local sent, transport = MultiBot.ActionToUnitStrategy(action, row.owner, completion) + + if selfStrategyTarget then + return transport == "pending" + end + + if not sent then + return false + end + + if type(onAccepted) == "function" then + onAccepted() end - self:ClearTotemSelection(row, elementKey) + return true + end + + if isSameSelection then + runMutation("co -" .. definition.spell .. ",?", function() + self:ClearTotemSelection(row, elementKey) + end) return end @@ -732,17 +759,15 @@ function ShamanQuick:SelectTotem(row, elementKey, button, definition) command = "co -" .. currentButton.__mbSpell .. ",+" .. definition.spell .. ",?" end - if not MultiBot.ActionToUnitStrategy(command, row.owner) then - return - end - - row.selectedIcons[elementKey] = button.__mbIcon - self:SetSelectedTotemButton(row, elementKey, button) - self:SetElementIcon(row, elementKey, button.__mbIcon) + runMutation(command, function() + row.selectedIcons[elementKey] = button.__mbIcon + self:SetSelectedTotemButton(row, elementKey, button) + self:SetElementIcon(row, elementKey, button.__mbIcon) - if MultiBot.SetShamanTotemChoice then - MultiBot.SetShamanTotemChoice(row.owner, elementKey, button.__mbIcon) - end + if MultiBot.SetShamanTotemChoice then + MultiBot.SetShamanTotemChoice(row.owner, elementKey, button.__mbIcon) + end + end) end -- MB_P1A_SHAMAN_QUICK_BLOCKED_STATE_V1_END function ShamanQuick:CreateTotemButton(row, elementDefinition, groupFrame, spellDefinition, index) From 2e3d24ebf136d81955f0f14c365c072daee44983 Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Thu, 20 Aug 2026 16:32:58 +0200 Subject: [PATCH 11/11] Fix SelfBot async UI state handling --- Core/MultiBotComm.lua | 37 ++++++++++++++++++++ Core/MultiBotEngine.lua | 4 ++- Strategies/MultiBotDeathKnight.lua | 9 +++-- Strategies/MultiBotHunter.lua | 18 ++++++---- Strategies/MultiBotMage.lua | 6 ++-- Strategies/MultiBotPaladin.lua | 54 ++++++++++++++++++++---------- 6 files changed, 98 insertions(+), 30 deletions(-) diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index 117c0c9..76812c5 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -261,6 +261,7 @@ local function ensureBridgeState() state.stateLatestByBot = state.stateLatestByBot or {} state.stateLatestOrderByBot = state.stateLatestOrderByBot or {} state.stateGlobalLatestToken = state.stateGlobalLatestToken or nil + state.selfStrategyStateToken = state.selfStrategyStateToken or nil state.stateFramingCapable = state.stateFramingCapable or false state.connectionGeneration = tonumber(state.connectionGeneration) or 0 state.capabilityFallbackDeadline = tonumber(state.capabilityFallbackDeadline) or 0 @@ -431,6 +432,10 @@ local function clearStateRequest(state, token) clearStateTransactionsForToken(state, token) state.stateRequests[token] = nil + if state.selfStrategyStateToken == token then + state.selfStrategyStateToken = nil + end + if state.bootstrapStateToken == token then state.bootstrapStateToken = nil end @@ -707,6 +712,8 @@ function Comm.RequestSelfStrategyState() return false end + state.selfStrategyStateToken = token + local request = state.stateRequests[token] if type(request) == "table" then local botKey = string.lower(name) @@ -1190,6 +1197,34 @@ local function finishSelfStrategyCommand(token, result) return true end +local function invalidateInactiveSelfBotWork(state) + state = type(state) == "table" and state or ensureBridgeState() + + local strategyStateToken = state.selfStrategyStateToken + if type(strategyStateToken) == "string" and strategyStateToken ~= "" then + clearStateRequest(state, strategyStateToken) + end + state.selfStrategyStateToken = nil + + local pendingSelfStrategyTokens = {} + for token in pairs(state.selfStrategyCommands or {}) do + pendingSelfStrategyTokens[#pendingSelfStrategyTokens + 1] = token + end + for _, token in ipairs(pendingSelfStrategyTokens) do + finishSelfStrategyCommand(token, { + status = "error", + reason = "SELF_STRATEGY_NOT_ACTIVE", + }) + end + state.selfStrategyCommands = {} + + -- SELF_ACTION consumers currently use callbacks for result/error reporting + -- only; there is no local optimistic button state to repair. Dropping these + -- requests prevents late ACKs from completing work that belonged to the + -- previous active SelfBot lifecycle without adding disable-time UI spam. + state.selfActionCommands = {} +end + function Comm.RunSelfStrategyCommand(stateScope, changes, callback) local state = ensureBridgeState() @@ -1898,6 +1933,7 @@ function Comm.HandleSelfBotAddonMessage(opcode, payload, state) state.selfBotMountNormalizeEpoch = (tonumber(state.selfBotMountNormalizeEpoch) or 0) + 1 state.selfBotMountNormalizePending = false state.selfBotMountNormalized = false + invalidateInactiveSelfBotWork(state) elseif state.selfStrategyCapable == true then normalizeSelfBotMountStrategy(state) end @@ -3401,6 +3437,7 @@ state.selfActionCapable = false state.stateRequests = {} state.stateActive = {} + state.selfStrategyStateToken = nil state.stateLatestByBot = {} state.stateLatestOrderByBot = {} state.stateGlobalLatestToken = nil diff --git a/Core/MultiBotEngine.lua b/Core/MultiBotEngine.lua index 224b132..b6d8950 100644 --- a/Core/MultiBotEngine.lua +++ b/Core/MultiBotEngine.lua @@ -867,7 +867,7 @@ MultiBot.SelectToTarget = function(pParent, pIndex, pTexture, pAction, oTarget) return false end -MultiBot.SelectToUnitStrategy = function(pParent, pIndex, pTexture, pAction, oTarget) +MultiBot.SelectToUnitStrategy = function(pParent, pIndex, pTexture, pAction, oTarget, onAccepted) local targetName = MultiBot.IF(oTarget == nil, UnitName("target"), oTarget) if(MultiBot.IsSelfBotStrategyTarget(targetName)) then @@ -881,6 +881,7 @@ MultiBot.SelectToUnitStrategy = function(pParent, pIndex, pTexture, pAction, oTa tButton.setTexture(pTexture) tFrame:Hide() if(MultiBot.RequestClickBlockerUpdate) then MultiBot.RequestClickBlockerUpdate(tFrame) end + if(type(onAccepted) == "function") then onAccepted() end end) if(transport == "pending") then @@ -895,6 +896,7 @@ MultiBot.SelectToUnitStrategy = function(pParent, pIndex, pTexture, pAction, oTa tButton.setTexture(pTexture) tFrame:Hide() if(MultiBot.RequestClickBlockerUpdate) then MultiBot.RequestClickBlockerUpdate(tFrame) end + if(type(onAccepted) == "function") then onAccepted() end return true end diff --git a/Strategies/MultiBotDeathKnight.lua b/Strategies/MultiBotDeathKnight.lua index 58e0eb3..5121e71 100644 --- a/Strategies/MultiBotDeathKnight.lua +++ b/Strategies/MultiBotDeathKnight.lua @@ -9,26 +9,29 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal) tFrame.addButton("Unholy", 0, 0, "spell_deathknight_unholypresence", MultiBot.L("tips.deathknight.presence.unholy")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +unholy,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +unholy,?", pButton.getName(), function() pButton.getButton("Presence").doRight = function() MultiBot.OnOffUnitStrategy(pButton, "co +unholy,?", "co -unholy,?", pButton.getName()) end + end) end tFrame.addButton("Frost", 0, 26, "spell_deathknight_frostpresence", MultiBot.L("tips.deathknight.presence.frost")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +frost,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +frost,?", pButton.getName(), function() pButton.getButton("Presence").doRight = function() MultiBot.OnOffUnitStrategy(pButton, "co +frost,?", "co -frost,?", pButton.getName()) end + end) end tFrame.addButton("Blood", 0, 52, "spell_deathknight_bloodpresence", MultiBot.L("tips.deathknight.presence.blood")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +blood,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Presence", pButton.texture, "co +blood,?", pButton.getName(), function() pButton.getButton("Presence").doRight = function() MultiBot.OnOffUnitStrategy(pButton, "co +blood,?", "co -blood,?", pButton.getName()) end + end) end -- SRATEGIES:PRESENCE --- diff --git a/Strategies/MultiBotHunter.lua b/Strategies/MultiBotHunter.lua index 6017d0b..fd1b593 100644 --- a/Strategies/MultiBotHunter.lua +++ b/Strategies/MultiBotHunter.lua @@ -9,26 +9,29 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) nonCombatAspectFrame.addButton("NonCombatNature", 0, 0, "spell_nature_protectionformnature", MultiBot.L("tips.hunter.naspect.rnature")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +rnature,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +rnature,?", pButton.getName(), function() pButton.getButton("NonCombatAspect").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +rnature,?", "nc -rnature,?", btn.getName()) end + end) end nonCombatAspectFrame.addButton("NonCombatSpeed", 0, 26, "ability_mount_whitetiger", MultiBot.L("tips.hunter.naspect.bspeed")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +bspeed,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +bspeed,?", pButton.getName(), function() pButton.getButton("NonCombatAspect").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bspeed,?", "nc -bspeed,?", btn.getName()) end + end) end nonCombatAspectFrame.addButton("NonCombatDps", 0, 52, "ability_hunter_pet_dragonhawk", MultiBot.L("tips.hunter.naspect.bdps")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +bdps,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAspect", pButton.texture, "nc +bdps,?", pButton.getName(), function() pButton.getButton("NonCombatAspect").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bdps,?", "nc -bdps,?", btn.getName()) end + end) end -- STRATEGIES:NON-COMBAT-BUFF -- @@ -59,26 +62,29 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal) combatAspectFrame.addButton("CombatNature", 0, 0, "spell_nature_protectionformnature", MultiBot.L("tips.hunter.caspect.rnature")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +rnature,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +rnature,?", pButton.getName(), function() pButton.getButton("CombatAspect").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +rnature,?", "co -rnature,?", btn.getName()) end + end) end combatAspectFrame.addButton("CombatSpeed", 0, 26, "ability_mount_whitetiger", MultiBot.L("tips.hunter.caspect.bspeed")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +bspeed,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +bspeed,?", pButton.getName(), function() pButton.getButton("CombatAspect").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +bspeed,?", "co -bspeed,?", btn.getName()) end + end) end combatAspectFrame.addButton("CombatDps", 0, 52, "ability_hunter_pet_dragonhawk", MultiBot.L("tips.hunter.caspect.bdps")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +bdps,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAspect", pButton.texture, "co +bdps,?", pButton.getName(), function() pButton.getButton("CombatAspect").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +bdps,?", "co -bdps,?", btn.getName()) end + end) end -- STRATEGIES:COMABT-ASPECT -- diff --git a/Strategies/MultiBotMage.lua b/Strategies/MultiBotMage.lua index f36576b..856bdcf 100644 --- a/Strategies/MultiBotMage.lua +++ b/Strategies/MultiBotMage.lua @@ -9,18 +9,20 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal) buffFrame.addButton("NonCombatMana", 0, 0, "inv_elemental_primal_mana", MultiBot.L("tips.mage.buff.bmana")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Buff", pButton.texture, "nc +bmana,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Buff", pButton.texture, "nc +bmana,?", pButton.getName(), function() pButton.getButton("Buff").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bmana,?", "nc -bmana,?", btn.getName()) end + end) end buffFrame.addButton("NonCombatDps", 0, 26, "inv_elemental_primal_nether", MultiBot.L("tips.mage.buff.bdps")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Buff", pButton.texture, "nc +bdps,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Buff", pButton.texture, "nc +bdps,?", pButton.getName(), function() pButton.getButton("Buff").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bdps,?", "nc -bdps,?", btn.getName()) end + end) end -- STRATEGIES:BUFF -- diff --git a/Strategies/MultiBotPaladin.lua b/Strategies/MultiBotPaladin.lua index 120eaf3..7e398af 100644 --- a/Strategies/MultiBotPaladin.lua +++ b/Strategies/MultiBotPaladin.lua @@ -19,34 +19,38 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) sealFrame.addButton("SealHealth", 0, 0, "spell_holy_healingaura", MultiBot.L("tips.paladin.seal.bhealth")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bsanc,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bsanc,?", pButton.getName(), function() pButton.getButton("Seal").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bsanc,?", "nc -bsanc,?", btn.getName()) end + end) end sealFrame.addButton("SealMana", 0, 26, "spell_holy_sealofwisdom", MultiBot.L("tips.paladin.seal.bmana")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bwisdom,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bwisdom,?", pButton.getName(), function() pButton.getButton("Seal").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bwisdom,?", "nc -bwisdom,?", btn.getName()) end + end) end sealFrame.addButton("SealStats", 0, 52, "spell_magic_magearmor", MultiBot.L("tips.paladin.seal.bstats")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bkings,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bkings,?", pButton.getName(), function() pButton.getButton("Seal").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bkings,?", "nc -bkings,?", btn.getName()) end + end) end sealFrame.addButton("SealDps", 0, 78, "inv_hammer_01", MultiBot.L("tips.paladin.seal.bdps")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bmight,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "Seal", pButton.texture, "nc +bmight,?", pButton.getName(), function() pButton.getButton("Seal").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bmight,?", "nc -bmight,?", btn.getName()) end + end) end -- STRATEGIES:SEAL -- @@ -81,58 +85,65 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) nonCombatAuraFrame.addButton("NonCombatSpeed", 0, 0, "spell_holy_crusaderaura", MultiBot.L("tips.paladin.naura.bspeed")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +bspeed,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +bspeed,?", pButton.getName(), function() pButton.getButton("NonCombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bspeed,?", "nc -bspeed,?", btn.getName()) end + end) end nonCombatAuraFrame.addButton("NonCombatFire", 0, 26, "spell_fire_sealoffire", MultiBot.L("tips.paladin.naura.rfire")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rfire,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rfire,?", pButton.getName(), function() pButton.getButton("NonCombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +rfire,?", "nc -rfire,?", btn.getName()) end + end) end nonCombatAuraFrame.addButton("NonCombatFrost", 0, 52, "spell_frost_wizardmark", MultiBot.L("tips.paladin.naura.rfrost")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rfrost,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rfrost,?", pButton.getName(), function() pButton.getButton("NonCombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +rfrost,?", "nc -rfrost,?", btn.getName()) end + end) end nonCombatAuraFrame.addButton("NonCombatShadow", 0, 78, "spell_shadow_sealofkings", MultiBot.L("tips.paladin.naura.rshadow")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rshadow,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +rshadow,?", pButton.getName(), function() pButton.getButton("NonCombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +rshadow,?", "nc -rshadow,?", btn.getName()) end + end) end nonCombatAuraFrame.addButton("NonCombatDamage", 0, 104, "spell_holy_auraoflight", MultiBot.L("tips.paladin.naura.baoe")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +baoe,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +baoe,?", pButton.getName(), function() pButton.getButton("NonCombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +baoe,?", "nc -baoe,?", btn.getName()) end + end) end nonCombatAuraFrame.addButton("NonCombatArmor", 0, 130, "spell_holy_devotionaura", MultiBot.L("tips.paladin.naura.barmor")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +barmor,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +barmor,?", pButton.getName(), function() pButton.getButton("NonCombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +barmor,?", "nc -barmor,?", btn.getName()) end + end) end nonCombatAuraFrame.addButton("NonCombatCast", 0, 156, "spell_holy_mindsooth", MultiBot.L("tips.paladin.naura.bcast")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +bcast,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "NonCombatAura", pButton.texture, "nc +bcast,?", pButton.getName(), function() pButton.getButton("NonCombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "nc +bcast,?", "nc -bcast,?", btn.getName()) end + end) end -- STRATEGIES:NON-COMBAT-AURA -- @@ -179,58 +190,65 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal) combatAuraFrame.addButton("CombatSpeed", 0, 0, "spell_holy_crusaderaura", MultiBot.L("tips.paladin.caura.bspeed")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +bspeed,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +bspeed,?", pButton.getName(), function() pButton.getButton("CombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +bspeed,?", "co -bspeed,?", btn.getName()) end + end) end combatAuraFrame.addButton("CombatFire", 0, 26, "spell_fire_sealoffire", MultiBot.L("tips.paladin.caura.rfire")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rfire,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rfire,?", pButton.getName(), function() pButton.getButton("CombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +rfire,?", "co -rfire,?", btn.getName()) end + end) end combatAuraFrame.addButton("CombatFrost", 0, 52, "spell_frost_wizardmark", MultiBot.L("tips.paladin.caura.rfrost")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rfrost,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rfrost,?", pButton.getName(), function() pButton.getButton("CombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +rfrost,?", "co -rfrost,?", btn.getName()) end + end) end combatAuraFrame.addButton("CombatShadow", 0, 78, "spell_shadow_sealofkings", MultiBot.L("tips.paladin.caura.rshadow")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rshadow,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +rshadow,?", pButton.getName(), function() pButton.getButton("CombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +rshadow,?", "co -rshadow,?", btn.getName()) end + end) end combatAuraFrame.addButton("CombatDamage", 0, 104, "spell_holy_auraoflight", MultiBot.L("tips.paladin.caura.baoe")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +baoe,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +baoe,?", pButton.getName(), function() pButton.getButton("CombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +baoe,?", "co -baoe,?", btn.getName()) end + end) end combatAuraFrame.addButton("CombatArmor", 0, 130, "spell_holy_devotionaura", MultiBot.L("tips.paladin.caura.barmor")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +barmor,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +barmor,?", pButton.getName(), function() pButton.getButton("CombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +barmor,?", "co -barmor,?", btn.getName()) end + end) end combatAuraFrame.addButton("CombatCast", 0, 156, "spell_holy_mindsooth", MultiBot.L("tips.paladin.caura.bcast")) .doLeft = function(pButton) - MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +bcast,?", pButton.getName()) + MultiBot.SelectToUnitStrategy(pButton.get(), "CombatAura", pButton.texture, "co +bcast,?", pButton.getName(), function() pButton.getButton("CombatAura").doRight = function(btn) MultiBot.OnOffUnitStrategy(btn, "co +bcast,?", "co -bcast,?", btn.getName()) end + end) end -- STRATEGIES:COMBAT-AURA --