mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-05-02 12:09:20 +02:00
441 lines
17 KiB
Lua
441 lines
17 KiB
Lua
setDefaultTab("Main")
|
|
ComboPanelName = "combobot"
|
|
local ui = setupUI([[
|
|
Panel
|
|
height: 19
|
|
|
|
BotSwitch
|
|
id: title
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
text-align: center
|
|
width: 130
|
|
!text: tr('ComboBot')
|
|
|
|
Button
|
|
id: combos
|
|
anchors.top: prev.top
|
|
anchors.left: prev.right
|
|
anchors.right: parent.right
|
|
margin-left: 3
|
|
height: 17
|
|
text: Setup
|
|
|
|
]])
|
|
ui:setId(ComboPanelName)
|
|
|
|
if not storage[ComboPanelName] then
|
|
storage[ComboPanelName] = {
|
|
enabled = false,
|
|
onSayEnabled = false,
|
|
onShootEnabled = false,
|
|
onCastEnabled = false,
|
|
followLeaderEnabled = false,
|
|
attackLeaderTargetEnabled = false,
|
|
attackSpellEnabled = false,
|
|
attackItemToggle = false,
|
|
sayLeader = "",
|
|
shootLeader = "",
|
|
castLeader = "",
|
|
sayPhrase = "",
|
|
spell = "",
|
|
serverLeader = "",
|
|
item = 3155,
|
|
attack = "",
|
|
follow = "",
|
|
commandsEnabled = true,
|
|
serverEnabled = false,
|
|
serverLeaderTarget = false,
|
|
serverTriggers = true
|
|
}
|
|
end
|
|
|
|
ui.title:setOn(storage[ComboPanelName].enabled)
|
|
ui.title.onClick = function(widget)
|
|
storage[ComboPanelName].enabled = not storage[ComboPanelName].enabled
|
|
widget:setOn(storage[ComboPanelName].enabled)
|
|
end
|
|
|
|
ui.combos.onClick = function(widget)
|
|
comboWindow:show()
|
|
comboWindow:raise()
|
|
comboWindow:focus()
|
|
end
|
|
|
|
rootWidget = g_ui.getRootWidget()
|
|
if rootWidget then
|
|
comboWindow = UI.createWindow('ComboWindow', rootWidget)
|
|
comboWindow:hide()
|
|
|
|
-- bot item
|
|
|
|
comboWindow.actions.attackItem:setItemId(storage[ComboPanelName].item)
|
|
comboWindow.actions.attackItem.onItemChange = function(widget)
|
|
storage[ComboPanelName].item = widget:getItemId()
|
|
end
|
|
|
|
-- switches
|
|
|
|
comboWindow.actions.commandsToggle:setOn(storage[ComboPanelName].commandsEnabled)
|
|
comboWindow.actions.commandsToggle.onClick = function(widget)
|
|
storage[ComboPanelName].commandsEnabled = not storage[ComboPanelName].commandsEnabled
|
|
widget:setOn(storage[ComboPanelName].commandsEnabled)
|
|
end
|
|
|
|
comboWindow.server.botServerToggle:setOn(storage[ComboPanelName].serverEnabled)
|
|
comboWindow.server.botServerToggle.onClick = function(widget)
|
|
storage[ComboPanelName].serverEnabled = not storage[ComboPanelName].serverEnabled
|
|
widget:setOn(storage[ComboPanelName].serverEnabled)
|
|
end
|
|
|
|
comboWindow.server.Triggers:setOn(storage[ComboPanelName].serverTriggers)
|
|
comboWindow.server.Triggers.onClick = function(widget)
|
|
storage[ComboPanelName].serverTriggers = not storage[ComboPanelName].serverTriggers
|
|
widget:setOn(storage[ComboPanelName].serverTriggers)
|
|
end
|
|
|
|
comboWindow.server.targetServerLeaderToggle:setOn(storage[ComboPanelName].serverLeaderTarget)
|
|
comboWindow.server.targetServerLeaderToggle.onClick = function(widget)
|
|
storage[ComboPanelName].serverLeaderTarget = not storage[ComboPanelName].serverLeaderTarget
|
|
widget:setOn(storage[ComboPanelName].serverLeaderTarget)
|
|
end
|
|
|
|
-- buttons
|
|
comboWindow.closeButton.onClick = function(widget)
|
|
comboWindow:hide()
|
|
end
|
|
|
|
-- combo boxes
|
|
|
|
comboWindow.actions.followLeader:setOption(storage[ComboPanelName].follow)
|
|
comboWindow.actions.followLeader.onOptionChange = function(widget)
|
|
storage[ComboPanelName].follow = widget:getCurrentOption().text
|
|
end
|
|
|
|
comboWindow.actions.attackLeaderTarget:setOption(storage[ComboPanelName].attack)
|
|
comboWindow.actions.attackLeaderTarget.onOptionChange = function(widget)
|
|
storage[ComboPanelName].attack = widget:getCurrentOption().text
|
|
end
|
|
|
|
-- checkboxes
|
|
comboWindow.trigger.onSayToggle:setChecked(storage[ComboPanelName].onSayEnabled)
|
|
comboWindow.trigger.onSayToggle.onClick = function(widget)
|
|
storage[ComboPanelName].onSayEnabled = not storage[ComboPanelName].onSayEnabled
|
|
widget:setChecked(storage[ComboPanelName].onSayEnabled)
|
|
end
|
|
|
|
comboWindow.trigger.onShootToggle:setChecked(storage[ComboPanelName].onShootEnabled)
|
|
comboWindow.trigger.onShootToggle.onClick = function(widget)
|
|
storage[ComboPanelName].onShootEnabled = not storage[ComboPanelName].onShootEnabled
|
|
widget:setChecked(storage[ComboPanelName].onShootEnabled)
|
|
end
|
|
|
|
comboWindow.trigger.onCastToggle:setChecked(storage[ComboPanelName].onCastEnabled)
|
|
comboWindow.trigger.onCastToggle.onClick = function(widget)
|
|
storage[ComboPanelName].onCastEnabled = not storage[ComboPanelName].onCastEnabled
|
|
widget:setChecked(storage[ComboPanelName].onCastEnabled)
|
|
end
|
|
|
|
comboWindow.actions.followLeaderToggle:setChecked(storage[ComboPanelName].followLeaderEnabled)
|
|
comboWindow.actions.followLeaderToggle.onClick = function(widget)
|
|
storage[ComboPanelName].followLeaderEnabled = not storage[ComboPanelName].followLeaderEnabled
|
|
widget:setChecked(storage[ComboPanelName].followLeaderEnabled)
|
|
end
|
|
|
|
comboWindow.actions.attackLeaderTargetToggle:setChecked(storage[ComboPanelName].attackLeaderTargetEnabled)
|
|
comboWindow.actions.attackLeaderTargetToggle.onClick = function(widget)
|
|
storage[ComboPanelName].attackLeaderTargetEnabled = not storage[ComboPanelName].attackLeaderTargetEnabled
|
|
widget:setChecked(storage[ComboPanelName].attackLeaderTargetEnabled)
|
|
end
|
|
|
|
comboWindow.actions.attackSpellToggle:setChecked(storage[ComboPanelName].attackSpellEnabled)
|
|
comboWindow.actions.attackSpellToggle.onClick = function(widget)
|
|
storage[ComboPanelName].attackSpellEnabled = not storage[ComboPanelName].attackSpellEnabled
|
|
widget:setChecked(storage[ComboPanelName].attackSpellEnabled)
|
|
end
|
|
|
|
comboWindow.actions.attackItemToggle:setChecked(storage[ComboPanelName].attackItemEnabled)
|
|
comboWindow.actions.attackItemToggle.onClick = function(widget)
|
|
storage[ComboPanelName].attackItemEnabled = not storage[ComboPanelName].attackItemEnabled
|
|
widget:setChecked(storage[ComboPanelName].attackItemEnabled)
|
|
end
|
|
|
|
-- text edits
|
|
comboWindow.trigger.onSayLeader:setText(storage[ComboPanelName].sayLeader)
|
|
comboWindow.trigger.onSayLeader.onTextChange = function(widget, text)
|
|
storage[ComboPanelName].sayLeader = text
|
|
end
|
|
|
|
comboWindow.trigger.onShootLeader:setText(storage[ComboPanelName].shootLeader)
|
|
comboWindow.trigger.onShootLeader.onTextChange = function(widget, text)
|
|
storage[ComboPanelName].shootLeader = text
|
|
end
|
|
|
|
comboWindow.trigger.onCastLeader:setText(storage[ComboPanelName].castLeader)
|
|
comboWindow.trigger.onCastLeader.onTextChange = function(widget, text)
|
|
storage[ComboPanelName].castLeader = text
|
|
end
|
|
|
|
comboWindow.trigger.onSayPhrase:setText(storage[ComboPanelName].sayPhrase)
|
|
comboWindow.trigger.onSayPhrase.onTextChange = function(widget, text)
|
|
storage[ComboPanelName].sayPhrase = text
|
|
end
|
|
|
|
comboWindow.actions.attackSpell:setText(storage[ComboPanelName].spell)
|
|
comboWindow.actions.attackSpell.onTextChange = function(widget, text)
|
|
storage[ComboPanelName].spell = text
|
|
end
|
|
|
|
comboWindow.server.botServerLeader:setText(storage[ComboPanelName].serverLeader)
|
|
comboWindow.server.botServerLeader.onTextChange = function(widget, text)
|
|
storage[ComboPanelName].serverLeader = text
|
|
end
|
|
end
|
|
|
|
-- bot server
|
|
-- [[ join party made by Frosty ]] --
|
|
|
|
local shouldCloseWindow = false
|
|
local firstInvitee = true
|
|
local isInComboTeam = false
|
|
macro(10, function()
|
|
if shouldCloseWindow and storage[ComboPanelName].serverEnabled and storage[ComboPanelName].enabled then
|
|
local channelsWindow = modules.game_console.channelsWindow
|
|
if channelsWindow then
|
|
local child = channelsWindow:getChildById("buttonCancel")
|
|
if child then
|
|
child:onClick()
|
|
shouldCloseWindow = false
|
|
isInComboTeam = true
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
comboWindow.server.partyButton.onClick = function(widget)
|
|
if storage[ComboPanelName].serverEnabled and storage[ComboPanelName].enabled then
|
|
if storage[ComboPanelName].serverLeader:len() > 0 and storage.BotServerChannel:len() > 0 then
|
|
talkPrivate(storage[ComboPanelName].serverLeader, "request invite " .. storage.BotServerChannel)
|
|
else
|
|
error("Request failed. Lack of data.")
|
|
end
|
|
end
|
|
end
|
|
|
|
onTextMessage(function(mode, text)
|
|
if storage[ComboPanelName].serverEnabled and storage[ComboPanelName].enabled then
|
|
if mode == 20 then
|
|
if string.find(text, "invited you to") then
|
|
local regex = "[a-zA-Z]*"
|
|
local regexData = regexMatch(text, regex)
|
|
if regexData[1][1]:lower() == storage[ComboPanelName].serverLeader:lower() then
|
|
local leader = getCreatureByName(regexData[1][1])
|
|
if leader then
|
|
g_game.partyJoin(leader:getId())
|
|
g_game.requestChannels()
|
|
g_game.joinChannel(1)
|
|
shouldCloseWindow = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
onTalk(function(name, level, mode, text, channelId, pos)
|
|
if storage[ComboPanelName].serverEnabled and storage[ComboPanelName].enabled then
|
|
if mode == 4 then
|
|
if string.find(text, "request invite") then
|
|
local access = string.match(text, "%d.*")
|
|
if access and access == storage.BotServerChannel then
|
|
local minion = getCreatureByName(name)
|
|
if minion then
|
|
g_game.partyInvite(minion:getId())
|
|
if firstInvitee then
|
|
g_game.requestChannels()
|
|
g_game.joinChannel(1)
|
|
shouldCloseWindow = true
|
|
firstInvitee = false
|
|
end
|
|
end
|
|
else
|
|
talkPrivate(name, "Incorrect access key!")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- [[ End of Frosty's Code ]] --
|
|
if storage[ComboPanelName].enabled and storage[ComboPanelName].enabled then
|
|
if name:lower() == storage[ComboPanelName].sayLeader:lower() and string.find(text, storage[ComboPanelName].sayPhrase) and storage[ComboPanelName].onSayEnabled then
|
|
startCombo = true
|
|
end
|
|
if (storage[ComboPanelName].castLeader and name:lower() == storage[ComboPanelName].castLeader:lower()) and isAttSpell(text) and storage[ComboPanelName].onCastEnabled then
|
|
startCombo = true
|
|
end
|
|
end
|
|
if storage[ComboPanelName].enabled and storage[ComboPanelName].commandsEnabled and (storage[ComboPanelName].shootLeader and name:lower() == storage[ComboPanelName].shootLeader:lower()) or (storage[ComboPanelName].sayLeader and name:lower() == storage[ComboPanelName].sayLeader:lower()) or (storage[ComboPanelName].castLeader and name:lower() == storage[ComboPanelName].castLeader:lower()) then
|
|
if string.find(text, "ue") then
|
|
say(storage[ComboPanelName].spell)
|
|
elseif string.find(text, "sd") then
|
|
local params = string.split(text, ",")
|
|
if #params == 2 then
|
|
local target = params[2]:trim()
|
|
if getCreatureByName(target) then
|
|
useWith(3155, getCreatureByName(target))
|
|
end
|
|
end
|
|
elseif string.find(text, "att") then
|
|
local attParams = string.split(text, ",")
|
|
if #attParams == 2 then
|
|
local atTarget = attParams[2]:trim()
|
|
if getCreatureByName(atTarget) and storage[ComboPanelName].attack == "COMMAND TARGET" then
|
|
g_game.attack(getCreatureByName(atTarget))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if isAttSpell(text) and storage[ComboPanelName].enabled and storage[ComboPanelName].serverEnabled then
|
|
BotServer.send("trigger", "start")
|
|
end
|
|
end)
|
|
|
|
onMissle(function(missle)
|
|
if storage[ComboPanelName].enabled and storage[ComboPanelName].onShootEnabled then
|
|
if not storage[ComboPanelName].shootLeader or storage[ComboPanelName].shootLeader:len() == 0 then
|
|
return
|
|
end
|
|
local src = missle:getSource()
|
|
if src.z ~= posz() then
|
|
return
|
|
end
|
|
local from = g_map.getTile(src)
|
|
local to = g_map.getTile(missle:getDestination())
|
|
if not from or not to then
|
|
return
|
|
end
|
|
local fromCreatures = from:getCreatures()
|
|
local toCreatures = to:getCreatures()
|
|
if #fromCreatures ~= 1 or #toCreatures ~= 1 then
|
|
return
|
|
end
|
|
local c1 = fromCreatures[1]
|
|
local t1 = toCreatures[1]
|
|
leaderTarget = t1
|
|
if c1:getName():lower() == storage[ComboPanelName].shootLeader:lower() then
|
|
if storage[ComboPanelName].attackItemEnabled and storage[ComboPanelName].item and storage[ComboPanelName].item > 100 and findItem(storage[ComboPanelName].item) then
|
|
useWith(storage[ComboPanelName].item, t1)
|
|
end
|
|
if storage[ComboPanelName].attackSpellEnabled and storage[ComboPanelName].spell:len() > 1 then
|
|
say(storage[ComboPanelName].spell)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
macro(10, function()
|
|
if not storage[ComboPanelName].enabled or not storage[ComboPanelName].attackLeaderTargetEnabled then return end
|
|
if leaderTarget and storage[ComboPanelName].attack == "LEADER TARGET" then
|
|
if not getTarget() or (getTarget() and getTarget():getName() ~= leaderTarget:getName()) then
|
|
g_game.attack(leaderTarget)
|
|
end
|
|
end
|
|
if storage[ComboPanelName].enabled and storage[ComboPanelName].serverEnabled and storage[ComboPanelName].attack == "SERVER LEADER TARGET" and serverTarget then
|
|
if serverTarget and not getTarget() or (getTarget() and getTarget():getname() ~= serverTarget)
|
|
then
|
|
g_game.attack(serverTarget)
|
|
end
|
|
end
|
|
end)
|
|
|
|
|
|
local toFollow
|
|
local toFollowPos = {}
|
|
|
|
macro(100, function()
|
|
toFollow = nil
|
|
if not storage[ComboPanelName].enabled or not storage[ComboPanelName].followLeaderEnabled then return end
|
|
if leaderTarget and storage[ComboPanelName].follow == "LEADER TARGET" and leaderTarget:isPlayer() then
|
|
toFollow = leaderTarget:getName()
|
|
elseif storage[ComboPanelName].follow == "SERVER LEADER TARGET" and storage[ComboPanelName].serverLeader:len() ~= 0 then
|
|
toFollow = serverTarget
|
|
elseif storage[ComboPanelName].follow == "SERVER LEADER" and storage[ComboPanelName].serverLeader:len() ~= 0 then
|
|
toFollow = storage[ComboPanelName].serverLeader
|
|
elseif storage[ComboPanelName].follow == "LEADER" then
|
|
if storage[ComboPanelName].onSayEnabled and storage[ComboPanelName].sayLeader:len() ~= 0 then
|
|
toFollow = storage[ComboPanelName].sayLeader
|
|
elseif storage[ComboPanelName].onCastEnabled and storage[ComboPanelName].castLeader:len() ~= 0 then
|
|
toFollow = storage[ComboPanelName].castLeader
|
|
elseif storage[ComboPanelName].onShootEnabled and storage[ComboPanelName].shootLeader:len() ~= 0 then
|
|
toFollow = storage[ComboPanelName].shootLeader
|
|
end
|
|
end
|
|
if not toFollow then return end
|
|
local target = getCreatureByName(toFollow)
|
|
if target then
|
|
local tpos = target:getPosition()
|
|
toFollowPos[tpos.z] = tpos
|
|
end
|
|
if player:isWalking() then return end
|
|
local p = toFollowPos[posz()]
|
|
if not p then return end
|
|
if CaveBot.walkTo(p, 20, {ignoreNonPathable=true, precision=1, ignoreStairs=false}) then
|
|
delay(100)
|
|
end
|
|
end)
|
|
|
|
onCreaturePositionChange(function(creature, oldPos, newPos)
|
|
if creature:getName() == toFollow and newPos then
|
|
toFollowPos[newPos.z] = newPos
|
|
end
|
|
end)
|
|
|
|
local timeout = now
|
|
macro(10, function()
|
|
if storage[ComboPanelName].enabled and startCombo then
|
|
if storage[ComboPanelName].attackItemEnabled and storage[ComboPanelName].item and storage[ComboPanelName].item > 100 and findItem(storage[ComboPanelName].item) then
|
|
useWith(storage[ComboPanelName].item, getTarget())
|
|
end
|
|
if storage[ComboPanelName].attackSpellEnabled and storage[ComboPanelName].spell:len() > 1 then
|
|
say(storage[ComboPanelName].spell)
|
|
end
|
|
startCombo = false
|
|
end
|
|
-- attack part / server
|
|
if BotServer._websocket and storage[ComboPanelName].enabled and storage[ComboPanelName].serverEnabled then
|
|
if target() and now - timeout > 500 then
|
|
targetPos = target():getName()
|
|
BotServer.send("target", targetPos)
|
|
timeout = now
|
|
end
|
|
end
|
|
end)
|
|
|
|
onUseWith(function(pos, itemId, target, subType)
|
|
if BotServer._websocket and itemId == 3155 then
|
|
BotServer.send("useWith", target:getPosition())
|
|
end
|
|
end)
|
|
|
|
if BotServer._websocket and storage[ComboPanelName].enabled and storage[ComboPanelName].serverEnabled then
|
|
BotServer.listen("trigger", function(name, message)
|
|
if message == "start" and name:lower() ~= player:getName():lower() and name:lower() == storage[ComboPanelName].serverLeader:lower() and storage[ComboPanelName].serverTriggers then
|
|
startCombo = true
|
|
end
|
|
end)
|
|
BotServer.listen("target", function(name, message)
|
|
if name:lower() ~= player:getName():lower() and name:lower() == storage[ComboPanelName].serverLeader:lower() then
|
|
if not target() or target():getName() == getCreatureByName(message) then
|
|
if storage[ComboPanelName].serverLeaderTarget then
|
|
serverTarget = getCreatureByName(message)
|
|
g_game.attack(getCreatureByName(message))
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
BotServer.listen("useWith", function(name, message)
|
|
local tile = g_map.getTile(message)
|
|
if storage[ComboPanelName].serverTriggers and name:lower() ~= player:getName():lower() and name:lower() == storage[ComboPanelName].serverLeader:lower() and storage[ComboPanelName].attackItemEnabled and storage[ComboPanelName].item and findItem(storage[ComboPanelName].item) then
|
|
useWith(storage[ComboPanelName].item, tile:getTopUseThing())
|
|
end
|
|
end)
|
|
end |