mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-10-20 06:33:26 +02:00
Version 0.999 BETA - a lot of bug fixes, improvments and more advanced bot
This commit is contained in:
@@ -6,6 +6,7 @@ contentsPanel = nil
|
||||
configWindow = nil
|
||||
configEditorText = nil
|
||||
configList = nil
|
||||
botTabs = nil
|
||||
botPanel = nil
|
||||
local botMessages = nil
|
||||
local configCopy = ""
|
||||
@@ -32,6 +33,17 @@ function init()
|
||||
onKeyPress = botKeyPress })
|
||||
|
||||
connect(Tile, { onAddThing = botAddThing, onRemoveThing = botRemoveThing })
|
||||
|
||||
connect(Creature, {
|
||||
onAppear = botCreatureAppear,
|
||||
onDisappear =botCreatureDisappear,
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
connect(LocalPlayer, {
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
|
||||
botConfigFile = g_configs.create("/bot.otml")
|
||||
local config = botConfigFile:get("config")
|
||||
@@ -53,18 +65,20 @@ function init()
|
||||
botWindow = g_ui.loadUI('bot', modules.game_interface.getRightPanel())
|
||||
botWindow:setup()
|
||||
|
||||
contentsPanel = botWindow:getChildById('contentsPanel')
|
||||
configList = contentsPanel:getChildById('config')
|
||||
enableButton = contentsPanel:getChildById('enableButton')
|
||||
statusLabel = contentsPanel:getChildById('statusLabel')
|
||||
botMessages = contentsPanel:getChildById('messages')
|
||||
botPanel = contentsPanel:getChildById('botPanel')
|
||||
|
||||
contentsPanel = botWindow.contentsPanel
|
||||
configList = contentsPanel.config
|
||||
enableButton = contentsPanel.enableButton
|
||||
statusLabel = contentsPanel.statusLabel
|
||||
botMessages = contentsPanel.messages
|
||||
botTabs = contentsPanel.botTabs
|
||||
botPanel = contentsPanel.botPanel
|
||||
botTabs:setContentWidget(botPanel)
|
||||
|
||||
configWindow = g_ui.displayUI('config')
|
||||
configWindow:hide()
|
||||
|
||||
configEditorText = configWindow:getChildById('text')
|
||||
configTab = configWindow:getChildById('configTab')
|
||||
configEditorText = configWindow.text
|
||||
configTab = configWindow.configTab
|
||||
|
||||
configTab.onTabChange = editorTabChanged
|
||||
|
||||
@@ -91,8 +105,27 @@ function init()
|
||||
end
|
||||
|
||||
function saveConfig()
|
||||
botConfigFile:set("config", json.encode(botConfig))
|
||||
botConfigFile:save()
|
||||
local status, result = pcall(function()
|
||||
botConfigFile:set("config", json.encode(botConfig))
|
||||
botConfigFile:save()
|
||||
end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
-- try to fix it
|
||||
local extraInfo = ""
|
||||
for i = 1, #botConfig.configs do
|
||||
if botConfig.configs[i].storage then
|
||||
local status, result = pcall(function() json.encode(botConfig.configs[i].storage) end)
|
||||
if not status then
|
||||
botConfig.configs[i].storage = nil
|
||||
extraInfo = extraInfo .. "\nLocal storage of config " .. i .. " has been erased due to invalid data"
|
||||
end
|
||||
end
|
||||
end
|
||||
statusLabel:setText("Error while saving config and user storage:\n" .. result .. extraInfo .. "\n\n" .. "Try to restart bot")
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function terminate()
|
||||
@@ -107,6 +140,17 @@ function terminate()
|
||||
|
||||
disconnect(Tile, { onAddThing = botAddThing, onRemoveThing = botRemoveThing })
|
||||
|
||||
disconnect(Creature, {
|
||||
onAppear = botCreatureAppear,
|
||||
onDisappear =botCreatureDisappear,
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
disconnect(LocalPlayer, {
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
|
||||
removeEvent(executeEvent)
|
||||
removeEvent(checkMsgsEvent)
|
||||
|
||||
@@ -259,13 +303,15 @@ end
|
||||
|
||||
function clearConfig()
|
||||
compiledConfig = nil
|
||||
botPanel:destroyChildren()
|
||||
|
||||
botTabs:clearTabs()
|
||||
botTabs:setOn(false)
|
||||
|
||||
botMessages:destroyChildren()
|
||||
botMessages:updateLayout()
|
||||
end
|
||||
|
||||
function refreshConfig()
|
||||
clearConfig()
|
||||
configWindow:hide()
|
||||
|
||||
botConfig.selectedConfig = configList.currentIndex
|
||||
@@ -273,8 +319,13 @@ function refreshConfig()
|
||||
return
|
||||
end
|
||||
|
||||
saveConfig()
|
||||
if not saveConfig() then
|
||||
clearConfig()
|
||||
return
|
||||
end
|
||||
|
||||
clearConfig()
|
||||
|
||||
local config = botConfig.configs[configList.currentIndex]
|
||||
if not config.storage then
|
||||
config.storage = {}
|
||||
@@ -286,7 +337,7 @@ function refreshConfig()
|
||||
end
|
||||
errorOccured = false
|
||||
g_game.enableTileThingLuaCallback(false)
|
||||
local status, result = pcall(function() return executeBot(config.script, config.storage, botPanel, botMsgCallback) end)
|
||||
local status, result = pcall(function() return executeBot(config.script, config.storage, botTabs, botMsgCallback) end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. tostring(result))
|
||||
@@ -342,9 +393,8 @@ function checkMsgs()
|
||||
end
|
||||
end
|
||||
|
||||
function botKeyDown(widget, keyCode, keyboardModifiers)
|
||||
if keyCode == KeyUnknown or compiledConfig == nil then return false end
|
||||
local status, result = pcall(function() compiledConfig.callbacks.onKeyDown(keyCode, keyboardModifiers) end)
|
||||
function safeBotCall(func)
|
||||
local status, result = pcall(func)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. result)
|
||||
@@ -352,52 +402,55 @@ function botKeyDown(widget, keyCode, keyboardModifiers)
|
||||
return false
|
||||
end
|
||||
|
||||
function botKeyDown(widget, keyCode, keyboardModifiers)
|
||||
if compiledConfig == nil then return false end
|
||||
if keyCode == KeyUnknown then return end
|
||||
safeBotCall(function() compiledConfig.callbacks.onKeyDown(keyCode, keyboardModifiers) end)
|
||||
end
|
||||
|
||||
function botKeyUp(widget, keyCode, keyboardModifiers)
|
||||
if keyCode == KeyUnknown or compiledConfig == nil then return false end
|
||||
local status, result = pcall(function() compiledConfig.callbacks.onKeyUp(keyCode, keyboardModifiers) end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. result)
|
||||
end
|
||||
return false
|
||||
if compiledConfig == nil then return false end
|
||||
if keyCode == KeyUnknown then return end
|
||||
safeBotCall(function() compiledConfig.callbacks.onKeyUp(keyCode, keyboardModifiers) end)
|
||||
end
|
||||
|
||||
function botKeyPress(widget, keyCode, keyboardModifiers, autoRepeatTicks)
|
||||
if keyCode == KeyUnknown or compiledConfig == nil then return false end
|
||||
local status, result = pcall(function() compiledConfig.callbacks.onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks) end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. result)
|
||||
end
|
||||
return false
|
||||
if compiledConfig == nil then return false end
|
||||
if keyCode == KeyUnknown then return end
|
||||
safeBotCall(function() compiledConfig.callbacks.onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks) end)
|
||||
end
|
||||
|
||||
function botOnTalk(name, level, mode, text, channelId, pos)
|
||||
if compiledConfig == nil then return false end
|
||||
local status, result = pcall(function() compiledConfig.callbacks.onTalk(name, level, mode, text, channelId, pos) end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. result)
|
||||
end
|
||||
return false
|
||||
safeBotCall(function() compiledConfig.callbacks.onTalk(name, level, mode, text, channelId, pos) end)
|
||||
end
|
||||
|
||||
function botAddThing(tile, thing, asd)
|
||||
function botAddThing(tile, thing)
|
||||
if compiledConfig == nil then return false end
|
||||
local status, result = pcall(function() compiledConfig.callbacks.onAddThing(tile, thing) end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. result)
|
||||
end
|
||||
return false
|
||||
safeBotCall(function() compiledConfig.callbacks.onAddThing(tile, thing) end)
|
||||
end
|
||||
|
||||
function botRemoveThing(tile, thing)
|
||||
if compiledConfig == nil then return false end
|
||||
local status, result = pcall(function() compiledConfig.callbacks.onRemoveThing(tile, thing) end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. result)
|
||||
end
|
||||
return false
|
||||
end
|
||||
safeBotCall(function() compiledConfig.callbacks.onRemoveThing(tile, thing) end)
|
||||
end
|
||||
|
||||
function botCreatureAppear(creature)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCreatureAppear(creature) end)
|
||||
end
|
||||
|
||||
function botCreatureDisappear(creature)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCreatureDisappear(creature) end)
|
||||
end
|
||||
|
||||
function botCreaturePositionChange(creature, newPos, oldPos)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCreaturePositionChange(creature, newPos, oldPos) end)
|
||||
end
|
||||
|
||||
function botCraetureHealthPercentChange(creature, healthPercent)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCreatureHealthPercentChange(creature, healthPercent) end)
|
||||
end
|
||||
|
@@ -3,12 +3,14 @@ BotButton < Button
|
||||
|
||||
BotSwitch < Button
|
||||
margin-top: 2
|
||||
height: 20
|
||||
image-color: green
|
||||
$!on:
|
||||
image-color: red
|
||||
|
||||
BotLabel < Label
|
||||
margin-top: 2
|
||||
height: 20
|
||||
text-auto-resize: true
|
||||
text-align: center
|
||||
text-wrap: true
|
||||
@@ -18,17 +20,20 @@ BotItem < UIItem
|
||||
size: 32 32
|
||||
border: 1 black
|
||||
&selectable: true
|
||||
|
||||
BotTextEdit < TextEdit
|
||||
@onClick: modules.game_textedit.show(self)
|
||||
text-align: center
|
||||
multiline: false
|
||||
|
||||
BotSeparator < HorizontalSeparator
|
||||
margin-top: 5
|
||||
margin-bottom: 3
|
||||
|
||||
|
||||
BotPanel < Panel
|
||||
margin-top: 2
|
||||
layout:
|
||||
type: verticalBox
|
||||
fit-children: true
|
||||
|
||||
|
||||
MiniWindow
|
||||
id: botWindow
|
||||
!text: tr('Bot')
|
||||
@@ -99,12 +104,28 @@ MiniWindow
|
||||
anchors.right: parent.right
|
||||
anchors.top: prev.bottom
|
||||
margin-top: 5
|
||||
|
||||
MoveableTabBar
|
||||
id: botTabs
|
||||
anchors.top: prev.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
tab-spacing: 2
|
||||
height: 20
|
||||
movable: false
|
||||
|
||||
$on:
|
||||
visible: true
|
||||
margin-top: 2
|
||||
|
||||
$!on:
|
||||
visible: false
|
||||
margin-top: -20
|
||||
|
||||
Panel
|
||||
id: botPanel
|
||||
margin-top: 2
|
||||
anchors.top: prev.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
id: botPanel
|
||||
layout:
|
||||
type: verticalBox
|
@@ -1,82 +1,52 @@
|
||||
botDefaultConfig = {
|
||||
configs = {
|
||||
{name = "Example", script = [=[
|
||||
--#Example
|
||||
info("Tested on 10.99")
|
||||
--Example
|
||||
|
||||
--#main
|
||||
local widget = setupUI([[
|
||||
Panel
|
||||
id: redPanel
|
||||
background: red
|
||||
margin-top: 10
|
||||
margin-bottom: 10
|
||||
height: 100
|
||||
|
||||
Label
|
||||
anchors.fill: parent
|
||||
text: custom ui, otml based
|
||||
text-align: center
|
||||
]])
|
||||
|
||||
Panels.Haste()
|
||||
Panels.ManaShield()
|
||||
Panels.Health()
|
||||
Panels.HealthItem()
|
||||
Panels.ManaItem()
|
||||
Panels.ManaItem()
|
||||
Panels.AntiParalyze()
|
||||
|
||||
local tab2 = addTab("Another Tab")
|
||||
addButton("button1", "test button on 2nd tab", nil, tab2)
|
||||
|
||||
local tab3 = addTab("3th tab")
|
||||
addLabel("label1", "Label on 3th tab", tab3)
|
||||
Panels.Turning(tab3)
|
||||
|
||||
--#macros
|
||||
macro(5000, "macro send link", "f5", function()
|
||||
g_game.talk("macro test - https://github.com/OTCv8/otclient_bot")
|
||||
g_game.talk("bot is hiding 50% of effects as example, say exevo gran mas vis")
|
||||
end)
|
||||
|
||||
macro(1000, "flag tiles", function()
|
||||
player:getTile():setText("Hello =)", "red")
|
||||
end)
|
||||
|
||||
macro(25, "auto healing", function()
|
||||
if hppercent() < 80 then
|
||||
say("exura")
|
||||
delay(1000) -- not calling this macro for next 1s
|
||||
end
|
||||
end)
|
||||
|
||||
addSeparator("spe0")
|
||||
local helloLabel = addLabel("helloLabel", "", tab2)
|
||||
|
||||
macro(1000, "example macro (time)", nil, function()
|
||||
helloLabel:setText("Time from start: " .. now)
|
||||
end, tab2)
|
||||
--#hotkeys
|
||||
hotkey('y', 'test hotkey', function() g_game.talk('hotkey elo') end)
|
||||
singlehotkey('x', 'single hotkey', function() g_game.talk('single hotkey') end)
|
||||
|
||||
singlehotkey('=', "Zoom in map", function () zoomIn() end)
|
||||
singlehotkey('-', "Zoom out map", function () zoomOut() end)
|
||||
|
||||
--#callbacks
|
||||
onAddThing(function(tile, thing)
|
||||
if thing:isItem() and thing:getId() == 2129 then
|
||||
local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z
|
||||
if not storage[pos] or storage[pos] < now then
|
||||
storage[pos] = now + 20000
|
||||
end
|
||||
tile:setTimer(storage[pos] - now)
|
||||
end
|
||||
hotkey("f5", "example hotkey", function()
|
||||
info("Wow, you clicked f5 hotkey")
|
||||
end)
|
||||
|
||||
-- hide 50% of effects
|
||||
onAddThing(function(tile, thing)
|
||||
if thing:isEffect() and math.random(1, 2) == 1 then
|
||||
thing:hide()
|
||||
end
|
||||
singlehotkey("f6", "example hotkey2", function()
|
||||
info("Wow, you clicked f6 singlehotkey")
|
||||
end)
|
||||
--#callbacks
|
||||
|
||||
local positionLabel = addLabel("positionLabel", "")
|
||||
onPlayerPositionChange(function()
|
||||
positionLabel:setText("Pos: " .. posx() .. "," .. posy() .. "," .. posz())
|
||||
end)
|
||||
|
||||
listen(player:getName(), function(text)
|
||||
info("you said: " .. text)
|
||||
end)
|
||||
|
||||
--#other
|
||||
addLabel("label1", "Test label 1")
|
||||
addSeparator("sep1")
|
||||
addLabel("label2", "Test label 2")
|
||||
|
||||
storage.clicks = 0
|
||||
addButton("button1", "Click me", function()
|
||||
storage.clicks = storage.clicks + 1
|
||||
ui.button1:setText("Clicks: " .. storage.clicks)
|
||||
end)
|
||||
|
||||
HTTP.getJSON("https://api.ipify.org/?format=json", function(data, err)
|
||||
if err then
|
||||
@@ -85,6 +55,7 @@ HTTP.getJSON("https://api.ipify.org/?format=json", function(data, err)
|
||||
end
|
||||
info("HTTP: My IP is: " .. tostring(data['ip']))
|
||||
end)
|
||||
|
||||
|
||||
|
||||
]=]},
|
||||
|
@@ -1,6 +1,8 @@
|
||||
function executeBot(config, storage, panel, msgCallback)
|
||||
function executeBot(config, storage, tabs, msgCallback)
|
||||
local context = {}
|
||||
context.panel = panel
|
||||
context.tabs = tabs
|
||||
context.panel = context.tabs:addTab("Main", g_ui.createWidget('BotPanel')).tabPanel
|
||||
|
||||
context.storage = storage
|
||||
if context.storage._macros == nil then
|
||||
context.storage._macros = {} -- active macros
|
||||
@@ -16,9 +18,12 @@ function executeBot(config, storage, panel, msgCallback)
|
||||
onKeyPress = {},
|
||||
onTalk = {},
|
||||
onAddThing = {},
|
||||
onRemoveThing = {}
|
||||
onRemoveThing = {},
|
||||
onCreatureAppear = {},
|
||||
onCreatureDisappear = {},
|
||||
onCreaturePositionChange = {},
|
||||
onCreatureHealthPercentChange = {}
|
||||
}
|
||||
context.ui = {}
|
||||
|
||||
-- basic functions & classes
|
||||
context.print = print
|
||||
@@ -44,265 +49,20 @@ function executeBot(config, storage, panel, msgCallback)
|
||||
context.info = function(text) return msgCallback("info", tostring(text)) end
|
||||
context.warn = function(text) return msgCallback("warn", tostring(text)) end
|
||||
context.error = function(text) return msgCallback("error", tostring(text)) end
|
||||
context.warning = context.warn
|
||||
|
||||
-- UI
|
||||
context.setupUI = function(otml, parent)
|
||||
if parent == nil then
|
||||
parent = context.panel
|
||||
end
|
||||
local widget = g_ui.loadUIFromString(otml, parent)
|
||||
if parent == context.panel and widget:getId() then
|
||||
context.ui[widget:getId()] = widget
|
||||
end
|
||||
return widget
|
||||
end
|
||||
|
||||
context.addSwitch = function(id, text, onClickCallback)
|
||||
local switch = g_ui.createWidget('BotSwitch', context.panel)
|
||||
switch:setId(id)
|
||||
switch:setText(text)
|
||||
switch.onClick = onClickCallback
|
||||
context.ui[id] = switch
|
||||
return switch
|
||||
end
|
||||
|
||||
context.addButton = function(id, text, onClickCallback)
|
||||
local button = g_ui.createWidget('BotButton', context.panel)
|
||||
button:setId(id)
|
||||
button:setText(text)
|
||||
button.onClick = onClickCallback
|
||||
context.ui[id] = button
|
||||
return button
|
||||
end
|
||||
|
||||
context.addLabel = function(id, text)
|
||||
local label = g_ui.createWidget('BotLabel', context.panel)
|
||||
label:setId(id)
|
||||
label:setText(text)
|
||||
context.ui[id] = label
|
||||
return label
|
||||
end
|
||||
|
||||
context.addSeparator = function(id)
|
||||
local separator = g_ui.createWidget('BotSeparator', context.panel)
|
||||
separator:setId(id)
|
||||
context.ui[id] = separator
|
||||
return separator
|
||||
end
|
||||
|
||||
context._addMacroSwitch = function(name, keys)
|
||||
local text = name
|
||||
if keys:len() > 0 then
|
||||
text = name .. " [" .. keys .. "]"
|
||||
end
|
||||
local switch = context.addSwitch("macro_" .. #context._macros, text, function(widget)
|
||||
context.storage._macros[name] = not context.storage._macros[name]
|
||||
widget:setOn(context.storage._macros[name])
|
||||
end)
|
||||
switch:setOn(context.storage._macros[name])
|
||||
return switch
|
||||
end
|
||||
|
||||
context._addHotkeySwitch = function(name, keys)
|
||||
local text = name
|
||||
if keys:len() > 0 then
|
||||
text = name .. " [" .. keys .. "]"
|
||||
end
|
||||
local switch = context.addSwitch("hotkey_" .. #context._hotkeys, text, nil)
|
||||
switch:setOn(false)
|
||||
return switch
|
||||
end
|
||||
|
||||
-- MAIN BOT FUNCTION
|
||||
-- macro(timeout, callback)
|
||||
-- macro(timeout, name, callback)
|
||||
-- macro(timeout, name, hotkey, callback)
|
||||
context.macro = function(timeout, name, hotkey, callback)
|
||||
if type(timeout) ~= 'number' or timeout < 1 then
|
||||
error("Invalid timeout for macro: " .. tostring(timeout))
|
||||
end
|
||||
if type(name) == 'function' then
|
||||
callback = name
|
||||
name = ""
|
||||
hotkey = ""
|
||||
elseif type(hotkey) == 'function' then
|
||||
callback = hotkey
|
||||
hotkey = ""
|
||||
elseif type(callback) ~= 'function' then
|
||||
error("Invalid callback for macro: " .. tostring(callback))
|
||||
end
|
||||
if type(name) ~= 'string' or type(hotkey) ~= 'string' then
|
||||
error("Invalid name or hotkey for macro")
|
||||
end
|
||||
if hotkey:len() > 0 then
|
||||
hotkey = retranslateKeyComboDesc(hotkey)
|
||||
end
|
||||
|
||||
local switch = nil
|
||||
if name:len() > 0 then
|
||||
if context.storage._macros[name] == nil then
|
||||
context.storage._macros[name] = true
|
||||
end
|
||||
switch = context._addMacroSwitch(name, hotkey)
|
||||
end
|
||||
|
||||
table.insert(context._macros, {
|
||||
timeout = timeout,
|
||||
name = name,
|
||||
callback = callback,
|
||||
lastExecution = context.now,
|
||||
hotkey = hotkey,
|
||||
switch = switch
|
||||
})
|
||||
return context._macros[#context._macros]
|
||||
end
|
||||
|
||||
-- hotkey(keys, callback)
|
||||
-- hotkey(keys, name, callback)
|
||||
context.hotkey = function(keys, name, callback)
|
||||
if type(name) == 'function' then
|
||||
callback = name
|
||||
name = ""
|
||||
end
|
||||
keys = retranslateKeyComboDesc(keys)
|
||||
if not keys or #keys == 0 then
|
||||
return context.error("Invalid hotkey keys " .. tostring(name))
|
||||
end
|
||||
if context._hotkeys[keys] then
|
||||
return context.error("Duplicated hotkey: " .. keys)
|
||||
end
|
||||
|
||||
local switch = nil
|
||||
if name:len() > 0 then
|
||||
switch = context._addHotkeySwitch(name, keys)
|
||||
end
|
||||
|
||||
context._hotkeys[keys] = {
|
||||
name = name,
|
||||
callback = callback,
|
||||
lastExecution = context.now,
|
||||
switch = switch,
|
||||
single = false
|
||||
}
|
||||
return context._hotkeys[keys]
|
||||
end
|
||||
|
||||
-- singlehotkey(keys, callback)
|
||||
-- singlehotkey(keys, name, callback)
|
||||
context.singlehotkey = function(keys, name, callback)
|
||||
if type(name) == 'function' then
|
||||
callback = name
|
||||
name = ""
|
||||
end
|
||||
keys = retranslateKeyComboDesc(keys)
|
||||
if not keys or #keys == 0 then
|
||||
return context.error("Invalid hotkey keys " .. tostring(name))
|
||||
end
|
||||
if context._hotkeys[keys] then
|
||||
return context.error("Duplicated hotkey: " .. keys)
|
||||
end
|
||||
|
||||
local switch = nil
|
||||
if name:len() > 0 then
|
||||
switch = context._addHotkeySwitch(name, keys)
|
||||
end
|
||||
|
||||
context._hotkeys[keys] = {
|
||||
name = name,
|
||||
callback = callback,
|
||||
lastExecution = context.now,
|
||||
switch = switch,
|
||||
single = true
|
||||
}
|
||||
return context._hotkeys[keys]
|
||||
end
|
||||
|
||||
-- schedule(timeout, callback)
|
||||
context.schedule = function(timeout, callback)
|
||||
local extecute_time = g_clock.millis() + timeout
|
||||
table.insert(context._scheduler, {
|
||||
execution = extecute_time,
|
||||
callback = callback
|
||||
})
|
||||
table.sort(context._scheduler, function(a, b) return a.execution < b.execution end)
|
||||
end
|
||||
|
||||
-- callback(callbackType, callback)
|
||||
context.callback = function(callbackType, callback)
|
||||
if not context._callbacks[callbackType] then
|
||||
return error("Wrong callback type: " .. callbackType)
|
||||
end
|
||||
if callbackType == "onAddThing" or callbackType == "onRemoveThing" then
|
||||
g_game.enableTileThingLuaCallback(true)
|
||||
end
|
||||
local callbackData = {}
|
||||
table.insert(context._callbacks[callbackType], function(...)
|
||||
if not callbackData.delay or callbackData.delay < context.now then
|
||||
context._currentExecution = callbackData
|
||||
callback(...)
|
||||
context._currentExecution = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- onKeyDown(callback) -- callback = function(keys)
|
||||
context.onKeyDown = function(callback)
|
||||
return context.callback("onKeyDown", callback)
|
||||
end
|
||||
|
||||
-- onKeyPress(callback) -- callback = function(keys)
|
||||
context.onKeyPress = function(callback)
|
||||
return context.callback("onKeyPress", callback)
|
||||
end
|
||||
|
||||
-- onKeyUp(callback) -- callback = function(keys)
|
||||
context.onKeyUp = function(callback)
|
||||
return context.callback("onKeyUp", callback)
|
||||
end
|
||||
|
||||
-- onTalk(callback) -- callback = function(name, level, mode, text, channelId, pos)
|
||||
context.onTalk = function(callback)
|
||||
return context.callback("onTalk", callback)
|
||||
end
|
||||
|
||||
-- onAddThing(callback) -- callback = function(tile, thing)
|
||||
context.onAddThing = function(callback)
|
||||
return context.callback("onAddThing", callback)
|
||||
end
|
||||
|
||||
-- onRemoveThing(callback) -- callback = function(tile, thing)
|
||||
context.onRemoveThing = function(callback)
|
||||
return context.callback("onRemoveThing", callback)
|
||||
end
|
||||
|
||||
-- listen(name, callback) -- callback = function(text, channelId, pos)
|
||||
context.listen = function(name, callback)
|
||||
if not name then return context.error("listen: invalid name") end
|
||||
name = name:lower()
|
||||
context.onTalk(function(name2, level, mode, text, channelId, pos)
|
||||
if name == name2:lower() then
|
||||
callback(text, channelId, pos)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- delay(duration) -- block execution of current macro/hotkey/callback for x milliseconds
|
||||
context.delay = function(duration)
|
||||
if not context._currentExecution then
|
||||
return context.error("Invalid usage of delay function, it should be used inside callbacks")
|
||||
end
|
||||
context._currentExecution.delay = context.now + duration
|
||||
end
|
||||
context.warning = context.warn
|
||||
|
||||
-- init context
|
||||
context.now = g_clock.millis()
|
||||
context.time = g_clock.millis()
|
||||
context.player = g_game.getLocalPlayer()
|
||||
|
||||
require("functions.lua")
|
||||
setupFunctions(context)
|
||||
|
||||
-- init functions
|
||||
G.botContext = context
|
||||
dofiles("functions")
|
||||
context.Panels = {}
|
||||
dofiles("panels")
|
||||
G.botContext = nil
|
||||
|
||||
-- run script
|
||||
assert(load(config, nil, nil, context))()
|
||||
|
||||
@@ -313,11 +73,8 @@ function executeBot(config, storage, panel, msgCallback)
|
||||
|
||||
for i, macro in ipairs(context._macros) do
|
||||
if macro.lastExecution + macro.timeout <= context.now and (macro.name == nil or macro.name:len() < 1 or context.storage._macros[macro.name]) then
|
||||
if not macro.delay or macro.delay < context.now then
|
||||
macro.lastExecution = context.now
|
||||
context._currentExecution = context._macros[i]
|
||||
macro.callback()
|
||||
context._currentExecution = nil
|
||||
if macro.callback() then
|
||||
macro.lastExecution = context.now
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -338,11 +95,8 @@ function executeBot(config, storage, panel, msgCallback)
|
||||
local hotkey = context._hotkeys[keyDesc]
|
||||
if hotkey then
|
||||
if hotkey.single then
|
||||
if not hotkey.delay or hotkey.delay < context.now then
|
||||
hotkey.lastExecution = context.now
|
||||
context._currentExecution = hotkey
|
||||
hotkey.callback()
|
||||
context._currentExecution = nil
|
||||
if hotkey.callback() then
|
||||
hotkey.lastExecution = context.now
|
||||
end
|
||||
end
|
||||
if hotkey.switch then
|
||||
@@ -369,11 +123,8 @@ function executeBot(config, storage, panel, msgCallback)
|
||||
local keyDesc = determineKeyComboDesc(keyCode, keyboardModifiers)
|
||||
local hotkey = context._hotkeys[keyDesc]
|
||||
if hotkey and not hotkey.single then
|
||||
if not hotkey.delay or hotkey.delay < context.now then
|
||||
hotkey.lastExecution = context.now
|
||||
context._currentExecution = hotkey
|
||||
hotkey.callback()
|
||||
context._currentExecution = nil
|
||||
if hotkey.callback() then
|
||||
hotkey.lastExecution = context.now
|
||||
end
|
||||
end
|
||||
for i, callback in ipairs(context._callbacks.onKeyPress) do
|
||||
@@ -394,6 +145,26 @@ function executeBot(config, storage, panel, msgCallback)
|
||||
for i, callback in ipairs(context._callbacks.onRemoveThing) do
|
||||
callback(tile, thing)
|
||||
end
|
||||
end,
|
||||
onCreatureAppear = function(creature)
|
||||
for i, callback in ipairs(context._callbacks.onCreatureAppear) do
|
||||
callback(creature)
|
||||
end
|
||||
end,
|
||||
onCreatureDisappear = function(creature)
|
||||
for i, callback in ipairs(context._callbacks.onCreatureDisappear) do
|
||||
callback(creature)
|
||||
end
|
||||
end,
|
||||
onCreaturePositionChange = function(creature, newPos, oldPos)
|
||||
for i, callback in ipairs(context._callbacks.onCreaturePositionChange) do
|
||||
callback(creature, newPos, oldPos)
|
||||
end
|
||||
end,
|
||||
onCreatureHealthPercentChange = function(creature, healthPercent)
|
||||
for i, callback in ipairs(context._callbacks.onCreatureHealthPercentChange) do
|
||||
callback(creature, healthPercent)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
|
101
modules/game_bot/functions/callbacks.lua
Normal file
101
modules/game_bot/functions/callbacks.lua
Normal file
@@ -0,0 +1,101 @@
|
||||
local context = G.botContext
|
||||
|
||||
-- callback(callbackType, callback)
|
||||
context.callback = function(callbackType, callback)
|
||||
if not context._callbacks[callbackType] then
|
||||
return error("Wrong callback type: " .. callbackType)
|
||||
end
|
||||
if callbackType == "onAddThing" or callbackType == "onRemoveThing" then
|
||||
g_game.enableTileThingLuaCallback(true)
|
||||
end
|
||||
local callbackData = {}
|
||||
table.insert(context._callbacks[callbackType], function(...)
|
||||
if not callbackData.delay or callbackData.delay < context.now then
|
||||
context._currentExecution = callbackData
|
||||
callback(...)
|
||||
context._currentExecution = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- onKeyDown(callback) -- callback = function(keys)
|
||||
context.onKeyDown = function(callback)
|
||||
return context.callback("onKeyDown", callback)
|
||||
end
|
||||
|
||||
-- onKeyPress(callback) -- callback = function(keys)
|
||||
context.onKeyPress = function(callback)
|
||||
return context.callback("onKeyPress", callback)
|
||||
end
|
||||
|
||||
-- onKeyUp(callback) -- callback = function(keys)
|
||||
context.onKeyUp = function(callback)
|
||||
return context.callback("onKeyUp", callback)
|
||||
end
|
||||
|
||||
-- onTalk(callback) -- callback = function(name, level, mode, text, channelId, pos)
|
||||
context.onTalk = function(callback)
|
||||
return context.callback("onTalk", callback)
|
||||
end
|
||||
|
||||
-- onAddThing(callback) -- callback = function(tile, thing)
|
||||
context.onAddThing = function(callback)
|
||||
return context.callback("onAddThing", callback)
|
||||
end
|
||||
|
||||
-- onRemoveThing(callback) -- callback = function(tile, thing)
|
||||
context.onRemoveThing = function(callback)
|
||||
return context.callback("onRemoveThing", callback)
|
||||
end
|
||||
|
||||
-- onCreatureAppear(callback) -- callback = function(creature)
|
||||
context.onCreatureAppear = function(callback)
|
||||
return context.callback("onCreatureAppear", callback)
|
||||
end
|
||||
|
||||
-- onCreatureDisappear(callback) -- callback = function(creature)
|
||||
context.onCreatureDisappear = function(callback)
|
||||
return context.callback("onCreatureDisappear", callback)
|
||||
end
|
||||
|
||||
-- onCreaturePositionChange(callback) -- callback = function(creature, newPos, oldPos)
|
||||
context.onCreaturePositionChange = function(callback)
|
||||
return context.callback("onCreaturePositionChange", callback)
|
||||
end
|
||||
|
||||
-- onCreatureHealthPercentChange(callback) -- callback = function(creature, healthPercent)
|
||||
context.onCreatureHealthPercentChange = function(callback)
|
||||
return context.callback("onCreatureHealthPercentChange", callback)
|
||||
end
|
||||
|
||||
|
||||
-- custom callbacks
|
||||
|
||||
-- listen(name, callback) -- callback = function(text, channelId, pos)
|
||||
context.listen = function(name, callback)
|
||||
if not name then return context.error("listen: invalid name") end
|
||||
name = name:lower()
|
||||
context.onTalk(function(name2, level, mode, text, channelId, pos)
|
||||
if name == name2:lower() then
|
||||
callback(text, channelId, pos)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- onPlayerPositionChange(callback) -- callback = function(newPos, oldPos)
|
||||
context.onPlayerPositionChange = function(callback)
|
||||
context.onCreaturePositionChange(function(creature, newPos, oldPos)
|
||||
if creature == context.player then
|
||||
callback(newPos, oldPos)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- onPlayerHealthChange(callback) -- callback = function(healthPercent)
|
||||
context.onPlayerHealthChange = function(callback)
|
||||
context.onCreatureHealthPercentChange(function(creature, healthPercent)
|
||||
if creature == context.player then
|
||||
callback(healthPercent)
|
||||
end
|
||||
end)
|
||||
end
|
136
modules/game_bot/functions/main.lua
Normal file
136
modules/game_bot/functions/main.lua
Normal file
@@ -0,0 +1,136 @@
|
||||
local context = G.botContext
|
||||
|
||||
-- MAIN BOT FUNCTION
|
||||
-- macro(timeout, callback)
|
||||
-- macro(timeout, name, callback)
|
||||
-- macro(timeout, name, hotkey, callback)
|
||||
-- macro(timeout, name, hotkey, callback, parent)
|
||||
context.macro = function(timeout, name, hotkey, callback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
|
||||
if type(timeout) ~= 'number' or timeout < 1 then
|
||||
error("Invalid timeout for macro: " .. tostring(timeout))
|
||||
end
|
||||
if type(name) == 'function' then
|
||||
callback = name
|
||||
name = ""
|
||||
hotkey = ""
|
||||
elseif type(hotkey) == 'function' then
|
||||
callback = hotkey
|
||||
hotkey = ""
|
||||
elseif type(callback) ~= 'function' then
|
||||
error("Invalid callback for macro: " .. tostring(callback))
|
||||
end
|
||||
if hotkey == nil then
|
||||
hotkey = ""
|
||||
end
|
||||
if type(name) ~= 'string' or type(hotkey) ~= 'string' then
|
||||
error("Invalid name or hotkey for macro")
|
||||
end
|
||||
if hotkey:len() > 0 then
|
||||
hotkey = retranslateKeyComboDesc(hotkey)
|
||||
end
|
||||
|
||||
local switch = nil
|
||||
if name:len() > 0 then
|
||||
if context.storage._macros[name] == nil then
|
||||
context.storage._macros[name] = true
|
||||
end
|
||||
switch = context._addMacroSwitch(name, hotkey, parent)
|
||||
end
|
||||
|
||||
table.insert(context._macros, {
|
||||
timeout = timeout,
|
||||
name = name,
|
||||
lastExecution = context.now,
|
||||
hotkey = hotkey,
|
||||
switch = switch
|
||||
})
|
||||
|
||||
local macroData = context._macros[#context._macros]
|
||||
macroData.callback = function()
|
||||
if not macroData.delay or macroData.delay < context.now then
|
||||
context._currentExecution = macroData
|
||||
callback()
|
||||
context._currentExecution = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return macroData
|
||||
end
|
||||
|
||||
-- hotkey(keys, callback)
|
||||
-- hotkey(keys, name, callback)
|
||||
-- hotkey(keys, name, callback, parent)
|
||||
context.hotkey = function(keys, name, callback, single, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
if type(name) == 'function' then
|
||||
callback = name
|
||||
name = ""
|
||||
end
|
||||
keys = retranslateKeyComboDesc(keys)
|
||||
if not keys or #keys == 0 then
|
||||
return context.error("Invalid hotkey keys " .. tostring(name))
|
||||
end
|
||||
if context._hotkeys[keys] then
|
||||
return context.error("Duplicated hotkey: " .. keys)
|
||||
end
|
||||
|
||||
local switch = nil
|
||||
if name:len() > 0 then
|
||||
switch = context._addHotkeySwitch(name, keys, parent)
|
||||
end
|
||||
|
||||
context._hotkeys[keys] = {
|
||||
name = name,
|
||||
lastExecution = context.now,
|
||||
switch = switch,
|
||||
single = single
|
||||
}
|
||||
|
||||
local hotkeyData = context._hotkeys[keys]
|
||||
hotkeyData.callback = function()
|
||||
if not hotkeyData.delay or hotkeyData.delay < context.now then
|
||||
context._currentExecution = hotkeyData
|
||||
callback()
|
||||
context._currentExecution = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return hotkeyData
|
||||
end
|
||||
|
||||
-- singlehotkey(keys, callback)
|
||||
-- singlehotkey(keys, name, callback)
|
||||
-- singlehotkey(keys, name, callback, parent)
|
||||
context.singlehotkey = function(keys, name, callback, parent)
|
||||
if type(name) == 'function' then
|
||||
callback = name
|
||||
name = ""
|
||||
end
|
||||
return context.hotkey(keys, name, callback, true, parent)
|
||||
end
|
||||
|
||||
-- schedule(timeout, callback)
|
||||
context.schedule = function(timeout, callback)
|
||||
local extecute_time = g_clock.millis() + timeout
|
||||
table.insert(context._scheduler, {
|
||||
execution = extecute_time,
|
||||
callback = callback
|
||||
})
|
||||
table.sort(context._scheduler, function(a, b) return a.execution < b.execution end)
|
||||
end
|
||||
|
||||
-- delay(duration) -- block execution of current macro/hotkey/callback for x milliseconds
|
||||
context.delay = function(duration)
|
||||
if not context._currentExecution then
|
||||
return context.error("Invalid usage of delay function, it should be used inside callbacks")
|
||||
end
|
||||
context._currentExecution.delay = context.now + duration
|
||||
end
|
39
modules/game_bot/functions/map.lua
Normal file
39
modules/game_bot/functions/map.lua
Normal file
@@ -0,0 +1,39 @@
|
||||
local context = G.botContext
|
||||
|
||||
context.zoomIn = function() modules.game_interface.getMapPanel():zoomIn() end
|
||||
context.zoomOut = function() modules.game_interface.getMapPanel():zoomOut() end
|
||||
|
||||
context.getSpectators = function(multifloor)
|
||||
if multifloor ~= true then
|
||||
multifloor = false
|
||||
end
|
||||
return g_map.getSpectators(context.player:getPosition(), multifloor)
|
||||
end
|
||||
|
||||
context.getCreatureByName = function(name, multifloor)
|
||||
if not name then return nil end
|
||||
name = name:lower()
|
||||
if multifloor ~= true then
|
||||
multifloor = false
|
||||
end
|
||||
for i, spec in ipairs(g_map.getSpectators(context.player:getPosition(), multifloor)) do
|
||||
if spec:getName():lower() == name then
|
||||
return spec
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
context.getPlayerByName = function(name, multifloor)
|
||||
if not name then return nil end
|
||||
name = name:lower()
|
||||
if multifloor ~= true then
|
||||
multifloor = false
|
||||
end
|
||||
for i, spec in ipairs(g_map.getSpectators(context.player:getPosition(), multifloor)) do
|
||||
if spec:isPlayer() and spec:getName():lower() == name then
|
||||
return spec
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
98
modules/game_bot/functions/player.lua
Normal file
98
modules/game_bot/functions/player.lua
Normal file
@@ -0,0 +1,98 @@
|
||||
local context = G.botContext
|
||||
|
||||
context.name = function() return context.player:getName() end
|
||||
|
||||
context.hp = function() return context.player:getHealth() end
|
||||
context.mana = function() return context.player:getMana() end
|
||||
context.hppercent = function() return context.player:getHealthPercent() end
|
||||
context.manapercent = function() if context.player:getMaxMana() <= 1 then return 100 else return math.floor(context.player:getMana() * 100 / context.player:getMaxMana()) end end
|
||||
context.maxhp = function() return context.player:getMaxHealth() end
|
||||
context.maxmana = function() return context.player:getMaxMana() end
|
||||
context.hpmax = function() return context.player:getMaxHealth() end
|
||||
context.manamax = function() return context.player:getMaxMana() end
|
||||
|
||||
context.cap = function() return context.player:getCapacity() end
|
||||
context.freecap = function() return context.player:getFreeCapacity() end
|
||||
context.maxcap = function() return context.player:getTotalCapacity() end
|
||||
context.capmax = function() return context.player:getTotalCapacity() end
|
||||
|
||||
context.exp = function() return context.player:getExperience() end
|
||||
context.lvl = function() return context.player:getLevel() end
|
||||
context.level = function() return context.player:getLevel() end
|
||||
|
||||
context.mlev = function() return context.player:getMagicLevel() end
|
||||
context.magic = function() return context.player:getMagicLevel() end
|
||||
context.mlevel = function() return context.player:getMagicLevel() end
|
||||
|
||||
context.soul = function() return context.player:getSoul() end
|
||||
context.stamina = function() return context.player:getStamina() end
|
||||
context.voc = function() return context.player:getVocation() end
|
||||
context.vocation = function() return context.player:getVocation() end
|
||||
|
||||
context.bless = function() return context.player:getBlessings() end
|
||||
context.blesses = function() return context.player:getBlessings() end
|
||||
context.blessings = function() return context.player:getBlessings() end
|
||||
|
||||
|
||||
context.pos = function() return context.player:getPosition() end
|
||||
context.posx = function() return context.player:getPosition().x end
|
||||
context.posy = function() return context.player:getPosition().y end
|
||||
context.posz = function() return context.player:getPosition().z end
|
||||
|
||||
context.direction = function() return context.player:getDirection() end
|
||||
context.speed = function() return context.player:getSpeed() end
|
||||
context.skull = function() return context.player:getSkull() end
|
||||
context.outfit = function() return context.player:getOutfit() end
|
||||
|
||||
context.setOutfit = function(outfit)
|
||||
modules.game_outfit.ignoreNextOutfitWindow = g_clock.millis()
|
||||
g_game.requestOutfit()
|
||||
context.schedule(100, function()
|
||||
g_game.changeOutfit(outfit)
|
||||
end)
|
||||
end
|
||||
context.changeOutfit = context.setOutfit
|
||||
context.setSpeed = function(value) context.player:setSpeed(value) end
|
||||
|
||||
context.autoWalk = function(destination) return context.player:autoWalk(destination) end
|
||||
context.walk = function(dir) return modules.game_walking.walk(dir) end
|
||||
context.turn = function(dir) return g_game.turn(dir) end
|
||||
|
||||
-- game releated
|
||||
context.say = g_game.talk
|
||||
context.talk = g_game.talk
|
||||
|
||||
context.saySpell = function(text, lastSpellTimeout)
|
||||
if context.lastSpell == nil then
|
||||
context.lastSpell = 0
|
||||
end
|
||||
if not lastSpellTimeout then
|
||||
lastSpellTimeout = 1000
|
||||
end
|
||||
if context.lastSpell + lastSpellTimeout > context.now then
|
||||
return false
|
||||
end
|
||||
context.say(text)
|
||||
context.lastSpell = context.now
|
||||
return true
|
||||
end
|
||||
|
||||
context.setSpellTimeout = function()
|
||||
context.lastSpell = context.now
|
||||
end
|
||||
|
||||
context.talkPrivate = g_game.talkPrivate
|
||||
context.sayPrivate = g_game.talkPrivate
|
||||
context.use = g_game.useInventoryItem
|
||||
context.usewith = g_game.useInventoryItemWith
|
||||
context.useWith = g_game.useInventoryItemWith
|
||||
context.findItem = g_game.findItemInContainers
|
||||
|
||||
context.attack = g_game.attack
|
||||
context.cancelAttack = g_game.cancelAttack
|
||||
context.follow = g_game.follow
|
||||
context.cancelFollow = g_game.cancelFollow
|
||||
context.cancelAttackAndFollow = g_game.cancelAttackAndFollow
|
||||
|
||||
context.logout = g_game.forceLogout
|
||||
context.ping = g_game.getPing
|
32
modules/game_bot/functions/player_conditions.lua
Normal file
32
modules/game_bot/functions/player_conditions.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
local context = G.botContext
|
||||
|
||||
for i, state in ipairs(PlayerStates) do
|
||||
context[state] = state
|
||||
end
|
||||
|
||||
context.hasCondition = function(condition) return bit.band(context.player:getStates(), condition) > 0 end
|
||||
|
||||
context.isPoisioned = function() return context.hasCondition(PlayerStates.Poison) end
|
||||
context.isBurnining = function() return context.hasCondition(PlayerStates.Burn) end
|
||||
context.isEnergized = function() return context.hasCondition(PlayerStates.Energy) end
|
||||
context.isDrunk = function() return context.hasCondition(PlayerStates.Drunk) end
|
||||
context.hasManaShield = function() return context.hasCondition(PlayerStates.ManaShield) end
|
||||
context.isParalyzed = function() return context.hasCondition(PlayerStates.Paralyze) end
|
||||
context.hasHaste = function() return context.hasCondition(PlayerStates.Haste) end
|
||||
context.hasSwords = function() return context.hasCondition(PlayerStates.Swords) end
|
||||
context.isInFight = function() return context.hasCondition(PlayerStates.Swords) end
|
||||
context.canLogout = function() return not context.hasCondition(PlayerStates.Swords) end
|
||||
context.isDrowning = function() return context.hasCondition(PlayerStates.Drowning) end
|
||||
context.isFreezing = function() return context.hasCondition(PlayerStates.Freezing) end
|
||||
context.isDazzled = function() return context.hasCondition(PlayerStates.Dazzled) end
|
||||
context.isCursed = function() return context.hasCondition(PlayerStates.Cursed) end
|
||||
context.hasPartyBuff = function() return context.hasCondition(PlayerStates.PartyBuff) end
|
||||
context.hasPzLock = function() return context.hasCondition(PlayerStates.PzBlock) end
|
||||
context.hasPzBlock = function() return context.hasCondition(PlayerStates.PzBlock) end
|
||||
context.isPzLocked = function() return context.hasCondition(PlayerStates.PzBlock) end
|
||||
context.isPzBlocked = function() return context.hasCondition(PlayerStates.PzBlock) end
|
||||
context.isInProtectionZone = function() return context.hasCondition(PlayerStates.Pz) end
|
||||
context.hasPz = function() return context.hasCondition(PlayerStates.Pz) end
|
||||
context.isInPz = function() return context.hasCondition(PlayerStates.Pz) end
|
||||
context.isBleeding = function() return context.hasCondition(PlayerStates.Bleeding) end
|
||||
context.isHungry = function() return context.hasCondition(PlayerStates.Hungry) end
|
33
modules/game_bot/functions/player_inventory.lua
Normal file
33
modules/game_bot/functions/player_inventory.lua
Normal file
@@ -0,0 +1,33 @@
|
||||
local context = G.botContext
|
||||
|
||||
context.SlotOther = InventorySlotOther
|
||||
context.SlotHead = InventorySlotHead
|
||||
context.SlotNeck = InventorySlotNeck
|
||||
context.SlotBack = InventorySlotBack
|
||||
context.SlotBody = InventorySlotBody
|
||||
context.SlotRight = InventorySlotRight
|
||||
context.SlotLeft = InventorySlotLeft
|
||||
context.SlotLeg = InventorySlotLeg
|
||||
context.SlotFeet = InventorySlotFeet
|
||||
context.SlotFinger = InventorySlotFinger
|
||||
context.SlotAmmo = InventorySlotAmmo
|
||||
context.SlotPurse = InventorySlotPurse
|
||||
|
||||
context.getInventoryItem = function(slot) return context.player:getInventoryItem(slot) end
|
||||
context.getSlot = context.getInventoryItem
|
||||
|
||||
context.getHead = function() return context.getInventoryItem(context.SlotHead) end
|
||||
context.getNeck = function() return context.getInventoryItem(context.SlotNeck) end
|
||||
context.getBack = function() return context.getInventoryItem(context.SlotBack) end
|
||||
context.getBody = function() return context.getInventoryItem(context.SlotBody) end
|
||||
context.getRight = function() return context.getInventoryItem(context.SlotRight) end
|
||||
context.getLeft = function() return context.getInventoryItem(context.SlotLeft) end
|
||||
context.getLeg = function() return context.getInventoryItem(context.SlotLeg) end
|
||||
context.getFeet = function() return context.getInventoryItem(context.SlotFeet) end
|
||||
context.getFinger = function() return context.getInventoryItem(context.SlotFinger) end
|
||||
context.getAmmo = function() return context.getInventoryItem(context.SlotAmmo) end
|
||||
context.getPurse = function() return context.getInventoryItem(context.SlotPurse) end
|
||||
|
||||
|
||||
context.getContainers = function() return g_game.getContainers() end
|
||||
context.getContainer = function(index) return g_game.getContainer(index) end
|
3
modules/game_bot/functions/test.lua
Normal file
3
modules/game_bot/functions/test.lua
Normal file
@@ -0,0 +1,3 @@
|
||||
local context = G.botContext
|
||||
|
||||
context.test = function() return context.info("test") end
|
4
modules/game_bot/functions/tools.lua
Normal file
4
modules/game_bot/functions/tools.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
local context = G.botContext
|
||||
|
||||
context.encode = function(data) return json.encode(data) end
|
||||
context.decode = function(text) local status, result = pcall(function() return json.decode(text) end) if status then return result end return {} end
|
95
modules/game_bot/functions/ui.lua
Normal file
95
modules/game_bot/functions/ui.lua
Normal file
@@ -0,0 +1,95 @@
|
||||
local context = G.botContext
|
||||
|
||||
context.setupUI = function(otml, parent)
|
||||
if parent == nil then
|
||||
parent = context.panel
|
||||
end
|
||||
local widget = g_ui.loadUIFromString(otml, parent)
|
||||
return widget
|
||||
end
|
||||
|
||||
context.addTab = function(name)
|
||||
context.tabs:setOn(true)
|
||||
return context.tabs:addTab(name, g_ui.createWidget('BotPanel')).tabPanel
|
||||
end
|
||||
|
||||
context.addSwitch = function(id, text, onClickCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local switch = g_ui.createWidget('BotSwitch', parent)
|
||||
switch:setId(id)
|
||||
switch:setText(text)
|
||||
switch.onClick = onClickCallback
|
||||
return switch
|
||||
end
|
||||
|
||||
context.addButton = function(id, text, onClickCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local button = g_ui.createWidget('BotButton', parent)
|
||||
button:setId(id)
|
||||
button:setText(text)
|
||||
button.onClick = onClickCallback
|
||||
return button
|
||||
end
|
||||
|
||||
context.addLabel = function(id, text, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local label = g_ui.createWidget('BotLabel', parent)
|
||||
label:setId(id)
|
||||
label:setText(text)
|
||||
return label
|
||||
end
|
||||
|
||||
context.addTextEdit = function(id, text, onTextChangeCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local widget = g_ui.createWidget('BotTextEdit', parent)
|
||||
widget:setId(id)
|
||||
widget.onTextChange = onTextChangeCallback
|
||||
widget:setText(text)
|
||||
return widget
|
||||
end
|
||||
|
||||
context.addSeparator = function(id, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local separator = g_ui.createWidget('BotSeparator', parent)
|
||||
separator:setId(id)
|
||||
return separator
|
||||
end
|
||||
|
||||
context._addMacroSwitch = function(name, keys, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local text = name
|
||||
if keys:len() > 0 then
|
||||
text = name .. " [" .. keys .. "]"
|
||||
end
|
||||
local switch = context.addSwitch("macro_" .. #context._macros, text, function(widget)
|
||||
context.storage._macros[name] = not context.storage._macros[name]
|
||||
widget:setOn(context.storage._macros[name])
|
||||
end, parent)
|
||||
switch:setOn(context.storage._macros[name])
|
||||
return switch
|
||||
end
|
||||
|
||||
context._addHotkeySwitch = function(name, keys, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local text = name
|
||||
if keys:len() > 0 then
|
||||
text = name .. " [" .. keys .. "]"
|
||||
end
|
||||
local switch = context.addSwitch("hotkey_" .. #context._hotkeys, text, nil, parent)
|
||||
switch:setOn(false)
|
||||
return switch
|
||||
end
|
326
modules/game_bot/panels/basic.lua
Normal file
326
modules/game_bot/panels/basic.lua
Normal file
@@ -0,0 +1,326 @@
|
||||
local context = G.botContext
|
||||
local Panels = context.Panels
|
||||
|
||||
Panels.Haste = function(parent)
|
||||
context.macro(500, "Auto Haste", nil, function()
|
||||
if not context.hasHaste() and context.storage.autoHasteText:len() > 0 then
|
||||
if context.saySpell(context.storage.autoHasteText, 2500) then
|
||||
context.delay(5000)
|
||||
end
|
||||
end
|
||||
end, parent)
|
||||
context.addTextEdit("autoHasteText", context.storage.autoHasteText or "utani hur", function(widget, text)
|
||||
context.storage.autoHasteText = text
|
||||
end, parent)
|
||||
end
|
||||
|
||||
Panels.ManaShield = function(parent)
|
||||
context.macro(500, "Auto ManaShield", nil, function()
|
||||
if not context.hasManaShield() then
|
||||
if context.saySpell("utamo vita", 1000) then
|
||||
context.delay(5000)
|
||||
end
|
||||
end
|
||||
end, parent)
|
||||
end
|
||||
|
||||
Panels.AntiParalyze = function(parent)
|
||||
context.macro(500, "Anti Paralyze", nil, function()
|
||||
if not context.isParalyzed() and context.storage.autoHasteText:len() > 0 then
|
||||
if context.saySpell(context.storage.autoAntiParalyzeText, 2500) then
|
||||
context.delay(5000)
|
||||
end
|
||||
end
|
||||
end, parent)
|
||||
context.addTextEdit("autoHasteText", context.storage.autoAntiParalyzeText or "utani hur", function(widget, text)
|
||||
context.storage.autoAntiParalyzeText = text
|
||||
end, parent)
|
||||
end
|
||||
|
||||
|
||||
Panels.Health = function(parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
|
||||
local panelName = "autoHealthPanel"
|
||||
local panelId = 1
|
||||
while parent:getChildById(panelName .. panelId) do
|
||||
panelId = panelId + 1
|
||||
end
|
||||
panelName = panelName .. panelId
|
||||
|
||||
local ui = context.setupUI([[
|
||||
Panel
|
||||
height: 70
|
||||
margin-top: 2
|
||||
|
||||
Label
|
||||
id: info
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
text: Auto Healing
|
||||
text-align: center
|
||||
|
||||
Label
|
||||
id: label
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: prev.bottom
|
||||
margin: 0 5 0 5
|
||||
text-align: center
|
||||
|
||||
HorizontalScrollBar
|
||||
id: scroll1
|
||||
anchors.left: label.left
|
||||
anchors.right: label.horizontalCenter
|
||||
anchors.top: label.bottom
|
||||
margin-top: 5
|
||||
margin-right: 2
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
step: 1
|
||||
|
||||
HorizontalScrollBar
|
||||
id: scroll2
|
||||
anchors.left: label.horizontalCenter
|
||||
anchors.right: label.right
|
||||
anchors.top: label.bottom
|
||||
margin-top: 5
|
||||
margin-left: 2
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
step: 1
|
||||
|
||||
BotTextEdit
|
||||
id: text
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: scroll1.bottom
|
||||
]], parent)
|
||||
ui:setId(panelName)
|
||||
|
||||
ui.text.onTextChange = function(widget, text)
|
||||
context.storage["healthText" .. panelId] = text
|
||||
end
|
||||
ui.text:setText(context.storage["healthText" .. panelId] or "exura")
|
||||
|
||||
local updateText = function()
|
||||
ui.label:setText("" .. (context.storage["healthPercentMin" .. panelId] or "") .. "% <= hp <= " .. (context.storage["healthPercentMax" .. panelId] or "") .. "%")
|
||||
end
|
||||
|
||||
ui.scroll1.onValueChange = function(scroll, value)
|
||||
context.storage["healthPercentMin" .. panelId] = value
|
||||
updateText()
|
||||
end
|
||||
ui.scroll2.onValueChange = function(scroll, value)
|
||||
context.storage["healthPercentMax" .. panelId] = value
|
||||
updateText()
|
||||
end
|
||||
|
||||
ui.scroll1:setValue(context.storage["healthPercentMin" .. panelId] or 20)
|
||||
ui.scroll2:setValue(context.storage["healthPercentMax" .. panelId] or 60)
|
||||
|
||||
context.macro(25, function()
|
||||
if context.storage["healthText" .. panelId]:len() > 0 and context.storage["healthPercentMin" .. panelId] <= context.hppercent() and context.hppercent() <= context.storage["healthPercentMax" .. panelId] then
|
||||
if context.saySpell(context.storage["healthText" .. panelId], 500) then
|
||||
context.delay(200)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
Panels.HealthItem = function(parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
|
||||
local panelName = "autoHealthItemPanel"
|
||||
local panelId = 1
|
||||
while parent:getChildById(panelName .. panelId) do
|
||||
panelId = panelId + 1
|
||||
end
|
||||
panelName = panelName .. panelId
|
||||
|
||||
local ui = context.setupUI([[
|
||||
Panel
|
||||
height: 55
|
||||
margin-top: 2
|
||||
|
||||
Label
|
||||
id: info
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
text: Auto Healing
|
||||
text-align: center
|
||||
|
||||
BotItem
|
||||
id: item
|
||||
anchors.left: parent.left
|
||||
anchors.top: prev.bottom
|
||||
margin-top: 3
|
||||
|
||||
Label
|
||||
id: label
|
||||
anchors.left: prev.right
|
||||
anchors.right: parent.right
|
||||
anchors.top: prev.top
|
||||
margin: 0 5 0 5
|
||||
text-align: center
|
||||
|
||||
HorizontalScrollBar
|
||||
id: scroll1
|
||||
anchors.left: label.left
|
||||
anchors.right: label.horizontalCenter
|
||||
anchors.top: label.bottom
|
||||
margin-top: 5
|
||||
margin-right: 2
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
step: 1
|
||||
|
||||
HorizontalScrollBar
|
||||
id: scroll2
|
||||
anchors.left: label.horizontalCenter
|
||||
anchors.right: label.right
|
||||
anchors.top: label.bottom
|
||||
margin-top: 5
|
||||
margin-left: 2
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
step: 1
|
||||
]], parent)
|
||||
ui:setId(panelName)
|
||||
|
||||
ui.item.onItemChange = function(widget)
|
||||
cp("item change")
|
||||
context.storage["healthItem" .. panelId] = widget:getItemId()
|
||||
end
|
||||
ui.item:setItemId(context.storage["healthItem" .. panelId] or 266)
|
||||
|
||||
local updateText = function()
|
||||
ui.label:setText("" .. (context.storage["healthItemPercentMin" .. panelId] or "") .. "% <= hp <= " .. (context.storage["healthItemPercentMax" .. panelId] or "") .. "%")
|
||||
end
|
||||
|
||||
ui.scroll1.onValueChange = function(scroll, value)
|
||||
context.storage["healthItemPercentMin" .. panelId] = value
|
||||
updateText()
|
||||
end
|
||||
ui.scroll2.onValueChange = function(scroll, value)
|
||||
context.storage["healthItemPercentMax" .. panelId] = value
|
||||
updateText()
|
||||
end
|
||||
|
||||
ui.scroll1:setValue(context.storage["healthItemPercentMin" .. panelId] or 20)
|
||||
ui.scroll2:setValue(context.storage["healthItemPercentMax" .. panelId] or 60)
|
||||
|
||||
context.macro(25, function()
|
||||
if context.storage["healthItem" .. panelId] > 0 and context.storage["healthItemPercentMin" .. panelId] <= context.hppercent() and context.hppercent() <= context.storage["healthItemPercentMax" .. panelId] then
|
||||
context.useWith(context.storage["healthItem" .. panelId], context.player)
|
||||
context.delay(300)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
Panels.Mana = function(parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
|
||||
local panelName = "autoManaItemPanel"
|
||||
local panelId = 1
|
||||
while parent:getChildById(panelName .. panelId) do
|
||||
panelId = panelId + 1
|
||||
end
|
||||
panelName = panelName .. panelId
|
||||
|
||||
local ui = context.setupUI([[
|
||||
Panel
|
||||
height: 55
|
||||
margin-top: 2
|
||||
|
||||
Label
|
||||
id: info
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
text: Auto Mana
|
||||
text-align: center
|
||||
|
||||
BotItem
|
||||
id: item
|
||||
anchors.left: parent.left
|
||||
anchors.top: prev.bottom
|
||||
margin-top: 3
|
||||
|
||||
Label
|
||||
id: label
|
||||
anchors.left: prev.right
|
||||
anchors.right: parent.right
|
||||
anchors.top: prev.top
|
||||
margin: 0 5 0 5
|
||||
text-align: center
|
||||
|
||||
HorizontalScrollBar
|
||||
id: scroll1
|
||||
anchors.left: label.left
|
||||
anchors.right: label.horizontalCenter
|
||||
anchors.top: label.bottom
|
||||
margin-top: 5
|
||||
margin-right: 2
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
step: 1
|
||||
|
||||
HorizontalScrollBar
|
||||
id: scroll2
|
||||
anchors.left: label.horizontalCenter
|
||||
anchors.right: label.right
|
||||
anchors.top: label.bottom
|
||||
margin-top: 5
|
||||
margin-left: 2
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
step: 1
|
||||
]], parent)
|
||||
ui:setId(panelName)
|
||||
|
||||
ui.item.onItemChange = function(widget)
|
||||
context.storage["manaItem" .. panelId] = widget:getItemId()
|
||||
end
|
||||
ui.item:setItemId(context.storage["manaItem" .. panelId] or 268)
|
||||
|
||||
local updateText = function()
|
||||
ui.label:setText("" .. (context.storage["manaItemPercentMin" .. panelId] or "") .. "% <= mana <= " .. (context.storage["manaItemPercentMax" .. panelId] or "") .. "%")
|
||||
end
|
||||
|
||||
ui.scroll1.onValueChange = function(scroll, value)
|
||||
context.storage["manaItemPercentMin" .. panelId] = value
|
||||
updateText()
|
||||
end
|
||||
ui.scroll2.onValueChange = function(scroll, value)
|
||||
context.storage["manaItemPercentMax" .. panelId] = value
|
||||
updateText()
|
||||
end
|
||||
|
||||
ui.scroll1:setValue(context.storage["manaItemPercentMin" .. panelId] or 20)
|
||||
ui.scroll2:setValue(context.storage["manaItemPercentMax" .. panelId] or 60)
|
||||
|
||||
context.macro(25, function()
|
||||
if context.storage["manaItem" .. panelId] > 0 and context.storage["manaItemPercentMin" .. panelId] <= context.manapercent() and context.manapercent() <= context.storage["manaItemPercentMax" .. panelId] then
|
||||
context.useWith(context.storage["manaItem" .. panelId], context.player)
|
||||
context.delay(300)
|
||||
end
|
||||
end)
|
||||
end
|
||||
Panels.ManaItem = Panels.Mana
|
||||
|
||||
Panels.Turning = function(parent)
|
||||
context.macro(1000, "Turning / AntiIdle", nil, function()
|
||||
context.turn(math.random(1, 4))
|
||||
end, parent)
|
||||
end
|
||||
Panels.AntiIdle = Panels.Turning
|
||||
|
Reference in New Issue
Block a user