mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-04-29 18:59:20 +02:00
741 lines
24 KiB
Lua
741 lines
24 KiB
Lua
local context = G.botContext
|
|
local Panels = context.Panels
|
|
|
|
Panels.Waypoints = function(parent)
|
|
local ui = context.setupUI([[
|
|
Panel
|
|
id: waypoints
|
|
height: 223
|
|
|
|
BotLabel
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
text: Waypoints
|
|
|
|
ComboBox
|
|
id: config
|
|
anchors.top: prev.bottom
|
|
anchors.left: parent.left
|
|
margin-top: 5
|
|
text-offset: 3 0
|
|
width: 130
|
|
|
|
Button
|
|
id: enableButton
|
|
anchors.top: prev.top
|
|
anchors.left: prev.right
|
|
anchors.right: parent.right
|
|
margin-left: 5
|
|
|
|
Button
|
|
margin-top: 1
|
|
id: add
|
|
anchors.top: prev.bottom
|
|
anchors.left: parent.left
|
|
text: Add
|
|
width: 60
|
|
height: 20
|
|
|
|
Button
|
|
id: edit
|
|
anchors.top: prev.top
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: Edit
|
|
width: 60
|
|
height: 20
|
|
|
|
Button
|
|
id: remove
|
|
anchors.top: prev.top
|
|
anchors.right: parent.right
|
|
text: Remove
|
|
width: 60
|
|
height: 20
|
|
|
|
TextList
|
|
id: list
|
|
anchors.top: prev.bottom
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
vertical-scrollbar: listScrollbar
|
|
margin-right: 15
|
|
margin-top: 2
|
|
height: 60
|
|
focusable: false
|
|
auto-focus: first
|
|
|
|
VerticalScrollBar
|
|
id: listScrollbar
|
|
anchors.top: prev.top
|
|
anchors.bottom: prev.bottom
|
|
anchors.right: parent.right
|
|
pixels-scroll: true
|
|
step: 5
|
|
|
|
Label
|
|
id: pos
|
|
anchors.top: prev.bottom
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
text-align: center
|
|
margin-top: 2
|
|
|
|
Button
|
|
id: wGoto
|
|
anchors.top: prev.bottom
|
|
anchors.left: parent.left
|
|
text: Goto
|
|
width: 61
|
|
margin-top: 1
|
|
height: 20
|
|
|
|
Button
|
|
id: wUse
|
|
anchors.top: prev.top
|
|
anchors.left: prev.right
|
|
text: Use
|
|
width: 61
|
|
height: 20
|
|
|
|
Button
|
|
id: wUseWith
|
|
anchors.top: prev.top
|
|
anchors.left: prev.right
|
|
text: UseWith
|
|
width: 61
|
|
height: 20
|
|
|
|
Button
|
|
id: wWait
|
|
anchors.top: prev.bottom
|
|
anchors.left: parent.left
|
|
text: Wait
|
|
width: 61
|
|
margin-top: 1
|
|
height: 20
|
|
|
|
Button
|
|
id: wSay
|
|
anchors.top: prev.top
|
|
anchors.left: prev.right
|
|
text: Say
|
|
width: 61
|
|
height: 20
|
|
|
|
Button
|
|
id: wNpc
|
|
anchors.top: prev.top
|
|
anchors.left: prev.right
|
|
text: Say NPC
|
|
width: 61
|
|
height: 20
|
|
|
|
Button
|
|
id: wLabel
|
|
anchors.top: prev.bottom
|
|
anchors.left: parent.left
|
|
text: Label
|
|
width: 61
|
|
margin-top: 1
|
|
height: 20
|
|
|
|
Button
|
|
id: wFollow
|
|
anchors.top: prev.top
|
|
anchors.left: prev.right
|
|
text: Follow
|
|
width: 61
|
|
height: 20
|
|
|
|
Button
|
|
id: wFunction
|
|
anchors.top: prev.top
|
|
anchors.left: prev.right
|
|
text: Function
|
|
width: 61
|
|
height: 20
|
|
|
|
BotSwitch
|
|
id: recording
|
|
anchors.top: prev.bottom
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
text: Auto Recording
|
|
height: 20
|
|
|
|
]], parent)
|
|
|
|
if type(context.storage.cavebot) ~= "table" then
|
|
context.storage.cavebot = {}
|
|
end
|
|
if type(context.storage.cavebot.configs) ~= "table" then
|
|
context.storage.cavebot.configs = {}
|
|
end
|
|
|
|
local getConfigName = function(config)
|
|
local matches = regexMatch(config, [[name:\s*([^\n]*)$]])
|
|
if matches[1] and matches[1][2] then
|
|
return matches[1][2]:trim()
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local isValidCommand = function(command)
|
|
if command == "goto" then
|
|
return true
|
|
elseif command == "use" then
|
|
return true
|
|
elseif command == "usewith" then
|
|
return true
|
|
elseif command == "wait" then
|
|
return true
|
|
elseif command == "say" then
|
|
return true
|
|
elseif command == "npc" then
|
|
return true
|
|
elseif command == "follow" then
|
|
return true
|
|
elseif command == "label" then
|
|
return true
|
|
elseif command == "gotolabel" then
|
|
return true
|
|
elseif command == "comment" then
|
|
return true
|
|
elseif command == "function" then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local commands = {}
|
|
local waitTo = 0
|
|
local autoRecording = false
|
|
|
|
local parseConfig = function(config)
|
|
commands = {}
|
|
local matches = regexMatch(config, [[([^:^\n^\s]+)(:?)([^\n]*)]])
|
|
for i=1,#matches do
|
|
local command = matches[i][2]
|
|
local validation = (matches[i][3] == ":")
|
|
if not validation or isValidCommand(command) then
|
|
local text = matches[i][4]
|
|
if validation then
|
|
table.insert(commands, {command=command:lower(), text=text})
|
|
elseif #commands > 0 then
|
|
commands[#commands].text = commands[#commands].text .. "\n" .. matches[i][1]
|
|
end
|
|
end
|
|
end
|
|
|
|
for i=1,#commands do
|
|
local label = g_ui.createWidget("CaveBotLabel", ui.list)
|
|
label:setText(commands[i].command .. ":" .. commands[i].text)
|
|
if commands[i].command == "goto" then
|
|
label:setColor("green")
|
|
elseif commands[i].command == "label" then
|
|
label:setColor("yellow")
|
|
elseif commands[i].command == "comment" then
|
|
label:setText(commands[i].text)
|
|
label:setColor("white")
|
|
elseif commands[i].command == "use" or commands[i].command == "usewith" then
|
|
label:setColor("orange")
|
|
elseif commands[i].command == "gotolabel" then
|
|
label:setColor("red")
|
|
end
|
|
end
|
|
end
|
|
|
|
local ignoreOnOptionChange = true
|
|
local refreshConfig = function(scrollDown)
|
|
ignoreOnOptionChange = true
|
|
if context.storage.cavebot.enabled then
|
|
autoRecording = false
|
|
ui.recording:setOn(false)
|
|
ui.enableButton:setText("On")
|
|
ui.enableButton:setColor('#00AA00FF')
|
|
else
|
|
ui.enableButton:setText("Off")
|
|
ui.enableButton:setColor('#FF0000FF')
|
|
ui.recording:setOn(autoRecording)
|
|
end
|
|
|
|
ui.config:clear()
|
|
for i, config in ipairs(context.storage.cavebot.configs) do
|
|
local name = getConfigName(config)
|
|
if not name then
|
|
name = "Unnamed config"
|
|
end
|
|
ui.config:addOption(name)
|
|
end
|
|
|
|
if not context.storage.cavebot.activeConfig and #context.storage.cavebot.configs > 0 then
|
|
context.storage.cavebot.activeConfig = 1
|
|
end
|
|
|
|
ui.list:destroyChildren()
|
|
|
|
if context.storage.cavebot.activeConfig and context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
ui.config:setCurrentIndex(context.storage.cavebot.activeConfig)
|
|
parseConfig(context.storage.cavebot.configs[context.storage.cavebot.activeConfig])
|
|
end
|
|
|
|
context.saveConfig()
|
|
if scrollDown and ui.list:getLastChild() then
|
|
ui.list:focusChild(ui.list:getLastChild())
|
|
end
|
|
|
|
waitTo = 0
|
|
ignoreOnOptionChange = false
|
|
end
|
|
|
|
|
|
ui.config.onOptionChange = function(widget)
|
|
if not ignoreOnOptionChange then
|
|
context.storage.cavebot.activeConfig = widget.currentIndex
|
|
refreshConfig()
|
|
end
|
|
end
|
|
ui.enableButton.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
context.storage.cavebot.enabled = not context.storage.cavebot.enabled
|
|
if autoRecording then
|
|
refreshConfig()
|
|
elseif context.storage.cavebot.enabled then
|
|
ui.enableButton:setText("On")
|
|
ui.enableButton:setColor('#00AA00FF')
|
|
else
|
|
ui.enableButton:setText("Off")
|
|
ui.enableButton:setColor('#FF0000FF')
|
|
end
|
|
end
|
|
ui.add.onClick = function()
|
|
modules.game_textedit.multilineEditor("Waypoints editor", "name:Config name\nlabel:start\n", function(newText)
|
|
table.insert(context.storage.cavebot.configs, newText)
|
|
context.storage.cavebot.activeConfig = #context.storage.cavebot.configs
|
|
refreshConfig()
|
|
end)
|
|
end
|
|
ui.edit.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
modules.game_textedit.multilineEditor("Waypoints editor", context.storage.cavebot.configs[context.storage.cavebot.activeConfig], function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = newText
|
|
refreshConfig()
|
|
end)
|
|
end
|
|
ui.remove.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
context.storage.cavebot.enabled = false
|
|
table.remove(context.storage.cavebot.configs, context.storage.cavebot.activeConfig)
|
|
context.storage.cavebot.activeConfig = 0
|
|
refreshConfig()
|
|
end
|
|
|
|
-- waypoint editor
|
|
-- auto recording
|
|
local stepsSincleLastPos = 0
|
|
|
|
context.onPlayerPositionChange(function(newPos, oldPos)
|
|
ui.pos:setText("Position: " .. newPos.x .. ", " .. newPos.y .. ", " .. newPos.z)
|
|
if not autoRecording then
|
|
return
|
|
end
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
local newText = ""
|
|
if newPos.z ~= oldPos.z then
|
|
newText = "goto:" .. oldPos.x .. "," .. oldPos.y .. "," .. oldPos.z
|
|
newText = newText .. "\ngoto:" .. newPos.x .. "," .. newPos.y .. "," .. newPos.z
|
|
stepsSincleLastPos = 0
|
|
else
|
|
stepsSincleLastPos = stepsSincleLastPos + 1
|
|
if stepsSincleLastPos > 10 then
|
|
newText = "goto:" .. oldPos.x .. "," .. oldPos.y .. "," .. oldPos.z
|
|
stepsSincleLastPos = 0
|
|
end
|
|
end
|
|
|
|
if newText:len() > 0 then
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\n" .. newText
|
|
refreshConfig(true)
|
|
end
|
|
end)
|
|
|
|
context.onUse(function(pos, itemId, stackPos, subType)
|
|
if not autoRecording then
|
|
return
|
|
end
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
if pos.x == 0xFFFF then
|
|
return
|
|
end
|
|
stepsSincleLastPos = 0
|
|
local playerPos = context.player:getPosition()
|
|
newText = "goto:" .. playerPos.x .. "," .. playerPos.y .. "," .. playerPos.z .. "\nuse:" .. pos.x .. "," .. pos.y .. "," .. pos.z
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\n" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
context.onUseWith(function(pos, itemId, target, subType)
|
|
if not autoRecording then
|
|
return
|
|
end
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
if not target:isItem() then
|
|
return
|
|
end
|
|
local targetPos = target:getPosition()
|
|
if targetPos.x == 0xFFFF then
|
|
return
|
|
end
|
|
stepsSincleLastPos = 0
|
|
local playerPos = context.player:getPosition()
|
|
newText = "goto:" .. playerPos.x .. "," .. playerPos.y .. "," .. playerPos.z .. "\nusewith:" .. itemId .. "," .. targetPos.x .. "," .. targetPos.y .. "," .. targetPos.z
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\n" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
|
|
-- ui
|
|
local pos = context.player:getPosition()
|
|
ui.pos:setText("Position: " .. pos.x .. ", " .. pos.y .. ", " .. pos.z)
|
|
|
|
ui.wGoto.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
local pos = context.player:getPosition()
|
|
modules.game_textedit.singlelineEditor("" .. pos.x .. "," .. pos.y .. "," .. pos.z, function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\ngoto:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.wUse.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
local pos = context.player:getPosition()
|
|
modules.game_textedit.singlelineEditor("" .. pos.x .. "," .. pos.y .. "," .. pos.z, function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\nuse:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.wUseWith.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
local pos = context.player:getPosition()
|
|
modules.game_textedit.singlelineEditor("ITEMID," .. pos.x .. "," .. pos.y .. "," .. pos.z, function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\nusewith:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.wWait.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
modules.game_textedit.singlelineEditor("1000", function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\nwait:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.wSay.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
modules.game_textedit.singlelineEditor("text", function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\nsay:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.wNpc.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
modules.game_textedit.singlelineEditor("text", function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\nnpc:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.wLabel.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
modules.game_textedit.singlelineEditor("label name", function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\nlabel:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.wFollow.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
modules.game_textedit.singlelineEditor("creature name", function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\nfollow:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.wFunction.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
modules.game_textedit.multilineEditor("Add function", "function(waypoints)\n -- your lua code, function is executed if previous goto was successful or is just after label\n\n -- must return true to execute next command, otherwise will run in loop till correct return\n return true\nend", function(newText)
|
|
context.storage.cavebot.configs[context.storage.cavebot.activeConfig] = context.storage.cavebot.configs[context.storage.cavebot.activeConfig] .. "\nfunction:" .. newText
|
|
refreshConfig(true)
|
|
end)
|
|
end
|
|
|
|
ui.recording.onClick = function()
|
|
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
|
|
return
|
|
end
|
|
autoRecording = not autoRecording
|
|
if autoRecording then
|
|
context.storage.cavebot.enabled = false
|
|
stepsSincleLastPos = 10
|
|
end
|
|
refreshConfig(true)
|
|
end
|
|
|
|
refreshConfig()
|
|
|
|
local usedGotoLabel = false
|
|
local executeNextMacroCall = false
|
|
local commandExecutionNo = 0
|
|
local lastGotoSuccesful = true
|
|
local lastOpenedContainer = 0
|
|
|
|
local functions = {
|
|
enable = function()
|
|
context.storage.cavebot.enabled = true
|
|
refreshConfig()
|
|
end,
|
|
disable = function()
|
|
context.storage.cavebot.enabled = false
|
|
refreshConfig()
|
|
end,
|
|
refresh = function()
|
|
refreshConfig()
|
|
end,
|
|
wait = function(peroid)
|
|
waitTo = context.now + peroid
|
|
end,
|
|
waitTo = function(timepoint)
|
|
waitTo = timepoint
|
|
end,
|
|
gotoLabel = function(name)
|
|
for i=1,ui.list:getChildCount() do
|
|
local command = commands[i]
|
|
if command and command.command == "label" and command.text == name then
|
|
ui.list:focusChild(ui.list:getChildByIndex(i))
|
|
usedGotoLabel = true
|
|
lastGotoSuccesful = true
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
}
|
|
|
|
context.onContainerOpen(function(container)
|
|
if container:getItemsCount() > 0 then
|
|
lastOpenedContainer = context.now + container:getItemsCount() * 100
|
|
end
|
|
end)
|
|
|
|
|
|
context.macro(250, function()
|
|
if not context.storage.cavebot.enabled then
|
|
return
|
|
end
|
|
|
|
if modules.game_walking.lastManualWalk + 500 > context.now then
|
|
return
|
|
end
|
|
|
|
-- wait if walked or opened container recently
|
|
if context.player:isWalking() or lastOpenedContainer + 1000 > context.now then
|
|
executeNextMacroCall = false
|
|
return
|
|
end
|
|
|
|
-- wait if attacking/following creature
|
|
local attacking = g_game.getAttackingCreature()
|
|
local following = g_game.getFollowingCreature()
|
|
if (attacking and context.getCreatureById(attacking:getId()) and not attacking.ignoreByWaypoints) or (following and context.getCreatureById(following:getId())) then
|
|
executeNextMacroCall = false
|
|
return
|
|
end
|
|
|
|
if not executeNextMacroCall then
|
|
executeNextMacroCall = true
|
|
return
|
|
end
|
|
executeNextMacroCall = false
|
|
|
|
local commandWidget = ui.list:getFocusedChild()
|
|
if not commandWidget then
|
|
if ui.list:getFirstChild() then
|
|
ui.list:focusChild(ui.list:getFirstChild())
|
|
end
|
|
return
|
|
end
|
|
|
|
local commandIndex = ui.list:getChildIndex(commandWidget)
|
|
local command = commands[commandIndex]
|
|
if not command then
|
|
if ui.list:getFirstChild() then
|
|
ui.list:focusChild(ui.list:getFirstChild())
|
|
end
|
|
return
|
|
end
|
|
|
|
if commandIndex == 1 then
|
|
lastGotoSuccesful = true
|
|
end
|
|
|
|
if command.command == "goto" or command.command == "follow" then
|
|
local matches = regexMatch(command.text, [[([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)]])
|
|
if (#matches == 1 and #matches[1] == 4) or command.command == "follow" then
|
|
local position = nil
|
|
if command.command == "follow" then
|
|
local creature = context.getCreatureByName(command.text)
|
|
if creature then
|
|
position = creature:getPosition()
|
|
end
|
|
else
|
|
position = {x=tonumber(matches[1][2]), y=tonumber(matches[1][3]), z=tonumber(matches[1][4])}
|
|
end
|
|
local distance = 0
|
|
if position then
|
|
distance = context.getDistanceBetween(position, context.player:getPosition())
|
|
end
|
|
if distance > 100 or not position or position.z ~= context.player:getPosition().z then
|
|
lastGotoSuccesful = false
|
|
elseif distance > 0 then
|
|
if not context.findPath(context.player:getPosition(), position, 100, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true }) then
|
|
lastGotoSuccesful = false
|
|
executeNextMacroCall = true
|
|
else
|
|
commandExecutionNo = commandExecutionNo + 1
|
|
lastGotoSuccesful = false
|
|
if commandExecutionNo <= 3 then -- try max 3 times
|
|
if not context.autoWalk(position, distance * 2, { ignoreNonPathable = false }) then
|
|
if commandExecutionNo > 1 then
|
|
if context.autoWalk(position, distance * 2, { ignoreNonPathable = true, precision = 1 }) then
|
|
context.delay(500)
|
|
end
|
|
end
|
|
return
|
|
end
|
|
return
|
|
elseif commandExecutionNo == 4 then -- try last time, location close to destination
|
|
if context.autoWalk(position, distance * 2, { ignoreNonPathable = true, ignoreLastCreature = true, precision = 2, allowUnseen = true }) then
|
|
context.delay(500)
|
|
return
|
|
end
|
|
elseif distance <= 2 then
|
|
lastGotoSuccesful = true
|
|
executeNextMacroCall = true
|
|
end
|
|
end
|
|
else
|
|
lastGotoSuccesful = true
|
|
executeNextMacroCall = true
|
|
end
|
|
else
|
|
context.error("Waypoints: invalid use of goto function")
|
|
end
|
|
elseif command.command == "use" then
|
|
local matches = regexMatch(command.text, [[([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)]])
|
|
if #matches == 1 and #matches[1] == 4 then
|
|
local position = {x=tonumber(matches[1][2]), y=tonumber(matches[1][3]), z=tonumber(matches[1][4])}
|
|
if context.player:getPosition().z == position.z then
|
|
local tile = g_map.getTile(position)
|
|
if tile then
|
|
local topThing = tile:getTopUseThing()
|
|
if topThing then
|
|
g_game.use(topThing)
|
|
context.delay(500)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
context.error("Waypoints: invalid use of use function")
|
|
end
|
|
elseif command.command == "usewith" then
|
|
local matches = regexMatch(command.text, [[([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)]])
|
|
if #matches == 1 and #matches[1] == 5 then
|
|
local itemId = tonumber(matches[1][2])
|
|
local position = {x=tonumber(matches[1][3]), y=tonumber(matches[1][4]), z=tonumber(matches[1][5])}
|
|
if context.player:getPosition().z == position.z then
|
|
local tile = g_map.getTile(position)
|
|
if tile then
|
|
local topThing = tile:getTopUseThing()
|
|
if topThing then
|
|
context.useWith(itemId, topThing)
|
|
context.delay(500)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
context.error("Waypoints: invalid use of usewith function")
|
|
end
|
|
elseif command.command == "wait" and lastGotoSuccesful then
|
|
if not waitTo or waitTo == 0 then
|
|
waitTo = context.now + tonumber(command.text)
|
|
end
|
|
if context.now < waitTo then
|
|
return
|
|
end
|
|
waitTo = 0
|
|
elseif command.command == "say" and lastGotoSuccesful then
|
|
context.say(command.text)
|
|
elseif command.command == "npc" and lastGotoSuccesful then
|
|
context.sayNpc(command.text)
|
|
elseif command.command == "function" and lastGotoSuccesful then
|
|
usedGotoLabel = false
|
|
local status, result = pcall(function()
|
|
return assert(load("return " .. command.text, nil, nil, context))()(functions)
|
|
end)
|
|
if not status then
|
|
context.error("Waypoints function execution error:\n" .. result)
|
|
context.delay(2500)
|
|
end
|
|
if not result or usedGotoLabel then
|
|
return
|
|
end
|
|
elseif command.command == "gotolabel" then
|
|
if functions.gotoLabel(command.text) then
|
|
return
|
|
end
|
|
end
|
|
|
|
local nextIndex = 1 + commandIndex % #commands
|
|
local nextChild = ui.list:getChildByIndex(nextIndex)
|
|
if nextChild then
|
|
ui.list:focusChild(nextChild)
|
|
commandExecutionNo = 0
|
|
end
|
|
end)
|
|
|
|
|
|
return functions
|
|
end
|
|
|