Version 1.2 - more advanced bot, new hotkeys, bug fixes

This commit is contained in:
OTCv8
2019-11-06 23:46:40 +01:00
parent ba2a1c8d5f
commit bb8e1a247b
31 changed files with 1368 additions and 608 deletions

View File

@@ -269,9 +269,16 @@ function checkCreatures()
end end
battleButton:creatureSetup(creature) battleButton:creatureSetup(creature)
battleButton:enable()
creature_i = creature_i + 1 creature_i = creature_i + 1
end end
end end
for i=#creatures + 1, 30 do
local battleButton = battleButtonsList[i]
if battleButton then
battleButton:disable()
end
end
local height = 0 local height = 0
if creature_i > 1 then if creature_i > 1 then

View File

@@ -17,7 +17,7 @@ local errorOccured = false
local statusLabel = nil local statusLabel = nil
local compiledConfig = nil local compiledConfig = nil
local configTab = nil local configTab = nil
local tabs = {"main", "macros", "hotkeys", "callbacks", "other"} local tabs = {"main", "panels", "macros", "hotkeys", "callbacks", "other"}
local mainTab = nil local mainTab = nil
local activeTab = nil local activeTab = nil
local editorText = {"", ""} local editorText = {"", ""}
@@ -26,6 +26,9 @@ function init()
dofile("defaultconfig") dofile("defaultconfig")
dofile("executor") dofile("executor")
g_ui.importStyle("ui/basic.otui")
g_ui.importStyle("ui/panels.otui")
connect(g_game, { connect(g_game, {
onGameStart = online, onGameStart = online,
onGameEnd = offline, onGameEnd = offline,
@@ -346,6 +349,10 @@ function clearConfig()
widget:destroy() widget:destroy()
end end
end end
local gameMapPanel = modules.game_interface.getMapPanel()
if gameMapPanel then
gameMapPanel:unlockVisibleFloor()
end
end end
function refreshConfig() function refreshConfig()

View File

@@ -3,6 +3,6 @@ Module
description: Advanced OTClientV8 Bot description: Advanced OTClientV8 Bot
author: otclient@otclient.ovh author: otclient@otclient.ovh
sandboxed: true sandboxed: true
scripts: [ ui/botitemcontainer, ui/botwaypoints, bot ] scripts: [ bot ]
@onLoad: init() @onLoad: init()
@onUnload: terminate() @onUnload: terminate()

View File

@@ -1,46 +1,3 @@
BotButton < Button
margin-top: 2
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
BotItem < Item
virtual: true
&selectable: true
BotTextEdit < TextEdit
@onClick: modules.game_textedit.show(self)
text-align: center
multiline: false
focusable: false
BotSeparator < HorizontalSeparator
margin-top: 5
margin-bottom: 3
BotPanel < Panel
layout:
type: verticalBox
CaveBotLabel < Label
background-color: alpha
text-offset: 2 0
focusable: true
$focus:
background-color: #00000055
MiniWindow MiniWindow
id: botWindow id: botWindow
!text: tr('Bot') !text: tr('Bot')

View File

@@ -7,20 +7,33 @@ botDefaultConfig = {
--#main --#main
Panels.Haste()
Panels.ManaShield()
Panels.AntiParalyze()
local battleTab = addTab("Battle") local healTab = addTab("HP")
local attackTab = addTab("Atck")
local warTab = addTab("War")
local caveTab = addTab("Cave") local caveTab = addTab("Cave")
local toolsTab = addTab("Tools")
Panels.Eating(battleTab) Panels.TradeMessage()
Panels.Health(battleTab)
Panels.HealthItem(battleTab) Panels.Haste(healTab)
Panels.ManaItem(battleTab) Panels.ManaShield(healTab)
Panels.AttackSpell(battleTab) Panels.AntiParalyze(healTab)
Panels.AttackItem(battleTab) Panels.Health(healTab)
Panels.Health(healTab)
Panels.HealthItem(healTab)
Panels.HealthItem(healTab)
Panels.ManaItem(healTab)
Panels.ManaItem(healTab)
Panels.Equip(healTab)
Panels.Equip(healTab)
Panels.Equip(healTab)
Panels.Eating(healTab)
Panels.AttackSpell(attackTab)
Panels.AttackItem(attackTab)
Panels.AttackLeaderTarget(warTab)
Panels.LimitFloor(warTab)
local waypoints = Panels.Waypoints(caveTab) local waypoints = Panels.Waypoints(caveTab)
local attacking = Panels.Attacking(caveTab) local attacking = Panels.Attacking(caveTab)
@@ -40,7 +53,7 @@ end)
macro(1000, "this macro does nothing", "f7", function() macro(1000, "this macro does nothing", "f7", function()
end, toolsTab) end)
macro(100, "debug pathfinding", nil, function() macro(100, "debug pathfinding", nil, function()
for i, tile in ipairs(g_map.getTiles(posz())) do for i, tile in ipairs(g_map.getTiles(posz())) do
@@ -59,11 +72,11 @@ macro(100, "debug pathfinding", nil, function()
end end
total = total + 1 total = total + 1
end end
end, toolsTab) end)
macro(1000, "speed hack", nil, function() macro(1000, "speed hack", nil, function()
player:setSpeed(1000) player:setSpeed(1000)
end, toolsTab) end)
--#hotkeys --#hotkeys
@@ -87,14 +100,14 @@ end)
--#other --#other
macro(100, "hide useless tiles", "", function() macro(100, "hide useless tiles", "", function()
for i, tile in ipairs(g_map.getTiles(-1)) do for i, tile in ipairs(g_map.getTiles(posz())) do
if not tile:isWalkable(true) then if not tile:isWalkable(true) then
tile:setFill('black') tile:setFill('black')
end end
end end
end, toolsTab) end)
addLabel("mapinfo", "You can use ctrl + plus and ctrl + minus to zoom in / zoom out map", toolsTab) addLabel("mapinfo", "You can use ctrl + plus and ctrl + minus to zoom in / zoom out map")
]=]}, ]=]},
{name = "UI & Healing", script = [=[ {name = "UI & Healing", script = [=[

View File

@@ -61,6 +61,7 @@ context.findAllPaths = function(start, maxDist, params)
ignoreStairs ignoreStairs
ignoreCost ignoreCost
allowUnseen allowUnseen
allowOnlyVisibleTiles
]]-- ]]--
if type(params) ~= 'table' then if type(params) ~= 'table' then
params = {} params = {}
@@ -114,6 +115,7 @@ context.findPath = function(startPos, destPos, maxDist, params)
ignoreStairs ignoreStairs
ignoreCost ignoreCost
allowUnseen allowUnseen
allowOnlyVisibleTiles
precision precision
marginMin marginMin
marginMax marginMax

View File

@@ -70,6 +70,7 @@ context.getChannelId = function(name)
end end
return nil return nil
end end
context.getChannel = context.getChannelId
context.say = g_game.talk context.say = g_game.talk
context.talk = g_game.talk context.talk = g_game.talk
@@ -79,6 +80,17 @@ context.sayChannel = context.talkChannel
context.talkPrivate = function(receiver, text) g_game.talkPrivate(5, receiver, text) end context.talkPrivate = function(receiver, text) g_game.talkPrivate(5, receiver, text) end
context.sayPrivate = g_game.talkPrivate context.sayPrivate = g_game.talkPrivate
context.talkNpc = function(text)
if g_game.getClientVersion() >= 810 then
g_game.talkChannel(11, 0, text)
else
return context.say(text)
end
end
context.sayNpc = context.talkNpc
context.sayNPC = context.talkNpc
context.talkNPC = context.talkNpc
context.saySpell = function(text, lastSpellTimeout) context.saySpell = function(text, lastSpellTimeout)
if context.lastSpell == nil then if context.lastSpell == nil then
context.lastSpell = 0 context.lastSpell = 0
@@ -101,6 +113,23 @@ end
context.use = g_game.useInventoryItem context.use = g_game.useInventoryItem
context.usewith = g_game.useInventoryItemWith context.usewith = g_game.useInventoryItemWith
context.useWith = g_game.useInventoryItemWith context.useWith = g_game.useInventoryItemWith
context.useRune = function(itemid, target, lastSpellTimeout)
if context.lastRuneUse == nil then
context.lastRuneUse = 0
end
if not lastRuneTimeout then
lastRuneTimeout = 1000
end
if context.lastRuneUse + lastRuneTimeout > context.now then
return false
end
context.usewith(itemid, target)
context.lastRuneUse = context.now
return true
end
context.userune = context.useRune
context.findItem = g_game.findItemInContainers context.findItem = g_game.findItemInContainers
context.attack = g_game.attack context.attack = g_game.attack

View File

@@ -10,7 +10,7 @@ Panels.MonsterEditor = function(monster, config, callback, parent)
local window = context.setupUI([[ local window = context.setupUI([[
MainWindow MainWindow
id: monsterEditor id: monsterEditor
size: 400 300 size: 450 430
!text: tr("Edit monster") !text: tr("Edit monster")
Label Label
@@ -21,6 +21,14 @@ MainWindow
text-align: center text-align: center
text: Use monster name * for any other monster not on the list text: Use monster name * for any other monster not on the list
Label
id: info2
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
text-align: center
text: Add number (1-5) at the end of the name to create multiple configs
TextEdit TextEdit
id: name id: name
anchors.top: prev.bottom anchors.top: prev.bottom
@@ -33,7 +41,7 @@ MainWindow
Label Label
anchors.verticalCenter: prev.verticalCenter anchors.verticalCenter: prev.verticalCenter
anchors.left: parent.left anchors.left: parent.left
text: Monster name: text: Target name:
Label Label
id: priorityText id: priorityText
@@ -75,6 +83,26 @@ MainWindow
maximum: 10 maximum: 10
step: 1 step: 1
Label
id: maxDistanceText
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: prev.bottom
margin-right: 10
margin-top: 10
text: Max distance to target
text-align: center
HorizontalScrollBar
id: maxDistance
anchors.left: prev.left
anchors.right: prev.right
anchors.top: prev.bottom
margin-top: 5
minimum: 1
maximum: 10
step: 1
Label Label
id: distanceText id: distanceText
anchors.left: parent.left anchors.left: parent.left
@@ -82,7 +110,7 @@ MainWindow
anchors.top: prev.bottom anchors.top: prev.bottom
margin-right: 10 margin-right: 10
margin-top: 10 margin-top: 10
text: Distance text: Keep distance
text-align: center text-align: center
HorizontalScrollBar HorizontalScrollBar
@@ -135,6 +163,18 @@ MainWindow
maximum: 100 maximum: 100
step: 1 step: 1
Label
id: attackSpellText
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: prev.bottom
margin-right: 10
margin-top: 10
text: Attack spell and attack rune are only used when you have more than 30% health
text-align: center
text-wrap: true
text-auto-resize: true
BotSwitch BotSwitch
id: attack id: attack
anchors.left: parent.horizontalCenter anchors.left: parent.horizontalCenter
@@ -148,7 +188,7 @@ MainWindow
id: ignore id: ignore
anchors.left: prev.right anchors.left: prev.right
anchors.top: name.bottom anchors.top: name.bottom
margin-left: 5 margin-left: 18
margin-top: 10 margin-top: 10
width: 55 width: 55
text: Ignore text: Ignore
@@ -157,7 +197,7 @@ MainWindow
id: avoid id: avoid
anchors.left: prev.right anchors.left: prev.right
anchors.top: name.bottom anchors.top: name.bottom
margin-left: 5 margin-left: 18
margin-top: 10 margin-top: 10
width: 55 width: 55
text: Avoid text: Avoid
@@ -187,7 +227,7 @@ MainWindow
anchors.top: prev.bottom anchors.top: prev.bottom
margin-left: 10 margin-left: 10
margin-top: 10 margin-top: 10
text: Chase when running away text: Chase when has low health
BotSwitch BotSwitch
id: loot id: loot
@@ -198,6 +238,56 @@ MainWindow
margin-top: 10 margin-top: 10
text: Loot corpse text: Loot corpse
BotSwitch
id: monstersOnly
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: prev.bottom
margin-left: 10
margin-top: 10
text: Only for monsters
BotSwitch
id: dontWalk
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: prev.bottom
margin-left: 10
margin-top: 10
text: Don't walk to target
Label
id: attackSpellText
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: prev.bottom
margin-left: 10
margin-top: 10
text: Attack Spell:
text-align: center
TextEdit
id: attackSpell
anchors.left: prev.left
anchors.right: prev.right
anchors.top: prev.bottom
margin-top: 2
Label
id: attackItemText
anchors.left: parent.horizontalCenter
anchors.top: prev.bottom
margin-top: 20
margin-left: 20
text: Attack rune:
text-align: left
BotItem
id: attackItem
anchors.right: parent.right
anchors.verticalCenter: prev.verticalCenter
margin-right: 30
Button Button
id: okButton id: okButton
!text: tr('Ok') !text: tr('Ok')
@@ -212,7 +302,7 @@ MainWindow
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
width: 60 width: 60
]], g_ui.getRootWidget()) ]], g_ui.getRootWidget())
local destroy = function() local destroy = function()
window:destroy() window:destroy()
@@ -222,6 +312,7 @@ MainWindow
local config = { local config = {
priority = window.priority:getValue(), priority = window.priority:getValue(),
danger = window.danger:getValue(), danger = window.danger:getValue(),
maxDistance = window.maxDistance:getValue(),
distance = window.distance:getValue(), distance = window.distance:getValue(),
minHealth = window.minHealth:getValue(), minHealth = window.minHealth:getValue(),
maxHealth = window.maxHealth:getValue(), maxHealth = window.maxHealth:getValue(),
@@ -231,7 +322,11 @@ MainWindow
keepDistance = window.keepDistance:isOn(), keepDistance = window.keepDistance:isOn(),
avoidAttacks = window.avoidAttacks:isOn(), avoidAttacks = window.avoidAttacks:isOn(),
chase = window.chase:isOn(), chase = window.chase:isOn(),
loot = window.loot:isOn() loot = window.loot:isOn(),
monstersOnly = window.monstersOnly:isOn(),
dontWalk = window.dontWalk:isOn(),
attackItem = window.attackItem:getItemId(),
attackSpell = window.attackSpell:getText()
} }
destroy() destroy()
callback(monster, config) callback(monster, config)
@@ -249,8 +344,11 @@ MainWindow
window.danger.onValueChange = function(scroll, value) window.danger.onValueChange = function(scroll, value)
window.dangerText:setText("Danger: " .. value) window.dangerText:setText("Danger: " .. value)
end end
window.maxDistance.onValueChange = function(scroll, value)
window.maxDistanceText:setText("Max distance to target: " .. value)
end
window.distance.onValueChange = function(scroll, value) window.distance.onValueChange = function(scroll, value)
window.distanceText:setText("Distance: " .. value) window.distanceText:setText("Keep distance: " .. value)
end end
window.minHealth.onValueChange = function(scroll, value) window.minHealth.onValueChange = function(scroll, value)
window.minHealthText:setText("Minimum health: " .. value .. "%") window.minHealthText:setText("Minimum health: " .. value .. "%")
@@ -261,12 +359,16 @@ MainWindow
window.priority:setValue(config.priority or 1) window.priority:setValue(config.priority or 1)
window.danger:setValue(config.danger or 1) window.danger:setValue(config.danger or 1)
window.maxDistance:setValue(config.maxDistance or 6)
window.distance:setValue(config.distance or 1) window.distance:setValue(config.distance or 1)
window.minHealth:setValue(1) -- to force onValueChange update window.minHealth:setValue(1) -- to force onValueChange update
window.maxHealth:setValue(1) -- to force onValueChange update window.maxHealth:setValue(1) -- to force onValueChange update
window.minHealth:setValue(config.minHealth or 0) window.minHealth:setValue(config.minHealth or 0)
window.maxHealth:setValue(config.maxHealth or 100) window.maxHealth:setValue(config.maxHealth or 100)
window.attackSpell:setText(config.attackSpell or "")
window.attackItem:setItemId(config.attackItem or 0)
window.attack.onClick = function(widget) window.attack.onClick = function(widget)
if widget:isOn() then if widget:isOn() then
return return
@@ -311,6 +413,12 @@ MainWindow
window.loot.onClick = function(widget) window.loot.onClick = function(widget)
widget:setOn(not widget:isOn()) widget:setOn(not widget:isOn())
end end
window.monstersOnly.onClick = function(widget)
widget:setOn(not widget:isOn())
end
window.dontWalk.onClick = function(widget)
widget:setOn(not widget:isOn())
end
window.keepDistance:setOn(config.keepDistance) window.keepDistance:setOn(config.keepDistance)
window.avoidAttacks:setOn(config.avoidAttacks) window.avoidAttacks:setOn(config.avoidAttacks)
@@ -319,6 +427,11 @@ MainWindow
if config.loot == nil then if config.loot == nil then
window.loot:setOn(true) window.loot:setOn(true)
end end
window.monstersOnly:setOn(config.monstersOnly)
if config.monstersOnly == nil then
window.monstersOnly:setOn(true)
end
window.dontWalk:setOn(config.dontWalk)
window.name:setText(monster) window.name:setText(monster)
@@ -623,22 +736,17 @@ Panel
refreshConfig() refreshConfig()
-- processing -- processing
local isConfigPassingConditions = function(monster, config)
local getMonsterConfig = function(monster) if not config or type(config.priority) ~= 'number' or type(config.danger) ~= 'number' then
if monsters[monster:getName():lower()] then return false
return monsters[monster:getName():lower()]
end
return monsters["*"]
end end
local calculatePriority = function(monster)
local priority = 0
local config = getMonsterConfig(monster)
if not config or type(config.priority) ~= 'number' then
return -1
end
if not config.attack then if not config.attack then
return -1 return false
end
if monster:isPlayer() and config.monstersOnly then
return false
end end
local pos = context.player:getPosition() local pos = context.player:getPosition()
@@ -646,27 +754,63 @@ Panel
local hp = monster:getHealthPercent() local hp = monster:getHealthPercent()
if config.minHealth > hp or config.maxHealth < hp then if config.minHealth > hp or config.maxHealth < hp then
return -1 return false
end end
local maxDistance = 5 local maxDistance = 5
if config.chase and hp < 20 then if type(config.maxDistance) == 'number' then
maxDistance = 7 maxDistance = config.maxDistance
end
if config.chase and hp < 25 then
maxDistance = maxDistance + 2
end end
local distance = math.max(math.abs(pos.x-mpos.x), math.abs(pos.y-mpos.y)) local distance = math.max(math.abs(pos.x-mpos.x), math.abs(pos.y-mpos.y))
if distance > maxDistance then if distance > maxDistance then
return false
end
local pathTo = context.findPath(context.player:getPosition(), {x=mpos.x, y=mpos.y, z=mpos.z}, maxDistance + 2, { ignoreNonPathable = true, precision=1, allowOnlyVisibleTiles = true })
if not pathTo or #pathTo > maxDistance + 1 then
return false
end
return true
end
local getMonsterConfig = function(monster)
local name = monster:getName():lower()
if isConfigPassingConditions(monster, monsters[name]) then
return monsters[name]
end
for i=1, 5 do
if isConfigPassingConditions(monster, monsters[name .. i]) then
return monsters[name .. i]
end
end
if isConfigPassingConditions(monster, monsters["*"]) then
return monsters["*"]
end
return nil
end
local calculatePriority = function(monster)
local priority = 0
local config = getMonsterConfig(monster)
if not config then
return -1 return -1
end end
local hasPath = false local pos = context.player:getPosition()
local pathTo = context.findPath(context.player:getPosition(), {x=mpos.x, y=mpos.y, z=mpos.z}, 10, { ignoreNonPathable = true, precision=1 }) local mpos = monster:getPosition()
if pathTo then local hp = monster:getHealthPercent()
hasPath = true local pathTo = context.findPath(context.player:getPosition(), {x=mpos.x, y=mpos.y, z=mpos.z}, 10, { ignoreNonPathable = true, ignoreLastCreature = true, precision=0, allowOnlyVisibleTiles = true })
end if not pathTo then
if distance > 2 and not hasPath then pathTo = context.findPath(context.player:getPosition(), {x=mpos.x, y=mpos.y, z=mpos.z}, 10, { ignoreNonPathable = true, precision=1, allowOnlyVisibleTiles = true })
if not pathTo then
return -1 return -1
end end
end
local distance = #pathTo
if monster == g_game.getAttackingCreature() then if monster == g_game.getAttackingCreature() then
priority = priority + 10 priority = priority + 10
@@ -682,7 +826,7 @@ Panel
priority = priority + 10 priority = priority + 10
end end
if hp <= 20 and config.chase then if hp <= 25 and config.chase then
priority = priority + 30 priority = priority + 30
end end
@@ -718,6 +862,8 @@ Panel
local lootTries = 0 local lootTries = 0
local openContainerRequest = 0 local openContainerRequest = 0
local waitForLooting = 0 local waitForLooting = 0
local lastAttackSpell = 0
local lastAttackRune = 0
local goForLoot = function() local goForLoot = function()
if #lootContainers == 0 or not context.storage.looting.enabled then if #lootContainers == 0 or not context.storage.looting.enabled then
@@ -864,7 +1010,7 @@ Panel
if followingCandidate and followingCandidate:getId() == spec:getId() then if followingCandidate and followingCandidate:getId() == spec:getId() then
following = spec following = spec
end end
if spec:isMonster() then if spec:isMonster() or (spec:isPlayer() and not spec:isLocalPlayer()) then
danger = danger + calculateMonsterDanger(spec) danger = danger + calculateMonsterDanger(spec)
spec.attackingPriority = calculatePriority(spec) spec.attackingPriority = calculatePriority(spec)
table.insert(monsters, spec) table.insert(monsters, spec)
@@ -879,7 +1025,7 @@ Panel
return return
end end
if #monsters == 0 then if #monsters == 0 or context.isInProtectionZone() then
goForLoot() goForLoot()
return return
end end
@@ -899,14 +1045,16 @@ Panel
local offsetX = pos.x - tpos.x local offsetX = pos.x - tpos.x
local offsetY = pos.y - tpos.y local offsetY = pos.y - tpos.y
local justStartedAttack = false
if target ~= attacking then if target ~= attacking then
g_game.attack(target) g_game.attack(target)
attacking = target attacking = target
lastAttack = context.now lastAttack = context.now
justStartedAttack = true
end end
-- proceed attack -- proceed attack
if lastAttack + 15000 < context.now then if not target:isPlayer() and lastAttack + 15000 < context.now then
-- stop and attack again, just in case -- stop and attack again, just in case
g_game.cancelAttack() g_game.cancelAttack()
g_game.attack(target) g_game.attack(target)
@@ -914,6 +1062,26 @@ Panel
return return
end end
if not justStartedAttack and config.attackSpell and config.attackSpell:len() > 0 then
if context.now > lastAttackSpell + 1000 and context.player:getHealthPercent() > 30 then
if context.saySpell(config.attackSpell, 1500) then
lastAttackRune = context.now
end
end
end
if not justStartedAttack and config.attackItem and config.attackItem >= 100 then
if context.now > lastAttackRune + 1000 and context.player:getHealthPercent() > 30 then
if context.useRune(config.attackItem, target, 1500) then
lastAttackRune = context.now
end
end
end
if modules.game_walking.lastManualWalk + 500 > context.now then
return
end
if danger < 8 then if danger < 8 then
-- low danger, go for loot first -- low danger, go for loot first
if goForLoot() then if goForLoot() then
@@ -921,10 +1089,14 @@ Panel
end end
end end
if config.dontWalk then
return
end
local distance = math.max(math.abs(offsetX), math.abs(offsetY)) local distance = math.max(math.abs(offsetX), math.abs(offsetY))
if config.keepDistance then if config.keepDistance then
local minDistance = config.distance local minDistance = config.distance
if target:getHealthPercent() < 20 and config.chase and danger < 10 then if target:getHealthPercent() <= 25 and config.chase and danger < 10 then
minDistance = 1 minDistance = 1
end end
if (distance == minDistance or distance == minDistance + 1) then if (distance == minDistance or distance == minDistance + 1) then
@@ -932,15 +1104,17 @@ Panel
else else
local bestDist = 10 local bestDist = 10
local bestPos = pos local bestPos = pos
if not context.autoWalk(tpos, 8, { minMargin=minDistance, maxMargin=minDistance + 1}) then if not context.autoWalk(tpos, 10, { minMargin=minDistance, maxMargin=minDistance + 1, allowOnlyVisibleTiles = true}) then
if not context.autoWalk(tpos, 8, { ignoreNonPathable = true, minMargin=minDistance, maxMargin=minDistance + 1}) then if not context.autoWalk(tpos, 10, { ignoreNonPathable = true, minMargin=minDistance, maxMargin=minDistance + 1, allowOnlyVisibleTiles = true}) then
if not context.autoWalk(tpos, 8, { ignoreNonPathable = true, ignoreCreatures = true, minMargin=minDistance, maxMargin=minDistance + 2}) then if not context.autoWalk(tpos, 10, { ignoreNonPathable = true, ignoreCreatures = true, minMargin=minDistance, maxMargin=minDistance + 2, allowOnlyVisibleTiles = true}) then
return return
end end
end end
end end
if not target:isPlayer() then
context.delay(300) context.delay(300)
end end
end
return return
end end
@@ -961,15 +1135,17 @@ Panel
end end
if distance > 1 then if distance > 1 then
if not context.autoWalk(tpos, 8, { precision = 1}) then if not context.autoWalk(tpos, 10, { precision = 1, allowOnlyVisibleTiles = true}) then
if not context.autoWalk(tpos, 8, { ignoreNonPathable = true, precision = 1}) then if not context.autoWalk(tpos, 10, { ignoreNonPathable = true, precision = 1, allowOnlyVisibleTiles = true}) then
if not context.autoWalk(tpos, 8, { ignoreNonPathable = true, precision = 2}) then if not context.autoWalk(tpos, 10, { ignoreNonPathable = true, precision = 2, allowOnlyVisibleTiles = true}) then
return return
end end
end end
end end
if not target:isPlayer() then
context.delay(300) context.delay(300)
end end
end
end) end)
end end

View File

@@ -1,402 +1,6 @@
local context = G.botContext local context = G.botContext
local Panels = context.Panels 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", 500) then
context.delay(5000)
end
end
end, parent)
end
Panels.AntiParalyze = function(parent)
context.macro(500, "Anti Paralyze", nil, function()
if context.isParalyzed() and context.storage.autoAntiParalyzeText:len() > 0 then
if context.saySpell(context.storage.autoAntiParalyzeText, 750) then
context.delay(1000)
end
end
end, parent)
context.addTextEdit("autoAntiParalyzeText", 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)
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.Eating = function(parent)
if not parent then
parent = context.panel
end
local panelName = "autoEatingPanel"
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 Eating
text-align: center
BotItem
id: item1
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 3
margin-left: 10
BotItem
id: item2
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: prev.top
BotItem
id: item3
anchors.right: parent.right
anchors.top: prev.top
margin-right: 10
]], parent)
ui:setId(panelName)
if not context.storage["autoEating" .. panelId] then
context.storage["autoEating" .. panelId] = {}
end
ui.item1.onItemChange = function(widget)
context.storage["autoEating" .. panelId][1] = widget:getItemId()
end
ui.item1:setItemId(context.storage["autoEating" .. panelId][1] or 3725)
ui.item2.onItemChange = function(widget)
context.storage["autoEating" .. panelId][2] = widget:getItemId()
end
ui.item2:setItemId(context.storage["autoEating" .. panelId][2] or 0)
ui.item3.onItemChange = function(widget)
context.storage["autoEating" .. panelId][3] = widget:getItemId()
end
ui.item3:setItemId(context.storage["autoEating" .. panelId][3] or 0)
context.macro(15000, function()
local candidates = {}
for i, item in pairs(context.storage["autoEating" .. panelId]) do
if item >= 100 then
table.insert(candidates, item)
end
end
if #candidates == 0 then
return
end
context.usewith(candidates[math.random(1, #candidates)], context.player)
end)
end
Panels.ManaItem = Panels.Mana
Panels.Turning = function(parent) Panels.Turning = function(parent)
context.macro(1000, "Turning / AntiIdle", nil, function() context.macro(1000, "Turning / AntiIdle", nil, function()
context.turn(math.random(1, 4)) context.turn(math.random(1, 4))
@@ -423,48 +27,31 @@ Panels.AttackItem = function(parent)
parent = context.panel parent = context.panel
end end
local panelName = "autoAttackItem" local panelName = "attackItem"
local panelId = 1 local ui = g_ui.createWidget("ItemAndButtonPanel", parent)
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 Attack Item
text-align: center
BotItem
id: item
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: prev.bottom
margin-top: 3
margin-left: 10
]], parent)
ui:setId(panelName) ui:setId(panelName)
if not context.storage["autoEating" .. panelId] then ui.title:setText("Auto attack item")
context.storage["autoEating" .. panelId] = {}
if not context.storage.attackItem then
context.storage.attackItem = {}
end
ui.title:setOn(context.storage.attackItem.enabled)
ui.title.onClick = function(widget)
context.storage.attackItem.enabled = not context.storage.attackItem.enabled
widget:setOn(context.storage.attackItem.enabled)
end end
ui.item.onItemChange = function(widget) ui.item.onItemChange = function(widget)
context.storage["autoAttackItem" .. panelId] = widget:getItemId() context.storage.attackItem.item = widget:getItemId()
end end
ui.item:setItemId(context.storage["autoAttackItem" .. panelId] or 3155) ui.item:setItemId(context.storage.attackItem.item or 3155)
context.macro(500, "Auto attack with item", nil, function() context.macro(500, function()
local target = g_game.getAttackingCreature() local target = g_game.getAttackingCreature()
if target and context.getCreatureById(target:getId()) and context.storage["autoAttackItem" .. panelId] >= 100 then if context.storage.attackItem.enabled and target and context.getCreatureById(target:getId()) and context.storage.attackItem.item and context.storage.attackItem.item >= 100 then
context.useWith(context.storage["autoAttackItem" .. panelId], target) context.useWith(context.storage.attackItem.item, target)
end end
end, parent) end)
end end

View File

@@ -0,0 +1,344 @@
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(100, "Auto Mana Shield", nil, function()
if not context.hasManaShield() then
context.saySpell("utamo vita", 200)
end
end, parent)
end
Panels.AntiParalyze = function(parent)
context.macro(100, "Anti Paralyze", nil, function()
if context.isParalyzed() and context.storage.autoAntiParalyzeText:len() > 0 then
context.saySpell(context.storage.autoAntiParalyzeText, 750)
end
end, parent)
context.addTextEdit("autoAntiParalyzeText", 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 = g_ui.createWidget("DualScrollPanel", parent)
ui:setId(panelName)
if not context.storage[panelName] then
context.storage[panelName] = {
item = 266,
min = 20,
max = 80,
text = "exura"
}
end
ui.title:setOn(context.storage[panelName].enabled)
ui.title.onClick = function(widget)
context.storage[panelName].enabled = not context.storage[panelName].enabled
widget:setOn(context.storage[panelName].enabled)
end
ui.text.onTextChange = function(widget, text)
context.storage[panelName].text = text
end
ui.text:setText(context.storage[panelName].text or "exura")
local updateText = function()
ui.title:setText("" .. context.storage[panelName].min .. "% <= hp <= " .. context.storage[panelName].max .. "%")
end
ui.scroll1.onValueChange = function(scroll, value)
context.storage[panelName].min = value
updateText()
end
ui.scroll2.onValueChange = function(scroll, value)
context.storage[panelName].max = value
updateText()
end
ui.scroll1:setValue(context.storage[panelName].min)
ui.scroll2:setValue(context.storage[panelName].max)
context.macro(25, function()
if context.storage[panelName].enabled and context.storage[panelName].text:len() > 0 and context.storage[panelName].min <= context.hppercent() and context.hppercent() <= context.storage[panelName].max then
if context.saySpell(context.storage[panelName].text, 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 = g_ui.createWidget("DualScrollItemPanel", parent)
ui:setId(panelName)
if not context.storage[panelName] then
context.storage[panelName] = {
item = 266,
min = 0,
max = 60
}
end
ui.title:setOn(context.storage[panelName].enabled)
ui.title.onClick = function(widget)
context.storage[panelName].enabled = not context.storage[panelName].enabled
widget:setOn(context.storage[panelName].enabled)
end
ui.item.onItemChange = function(widget)
context.storage[panelName].item = widget:getItemId()
end
ui.item:setItemId(context.storage[panelName].item)
local updateText = function()
ui.title:setText("" .. (context.storage[panelName].min or "") .. "% <= hp <= " .. (context.storage[panelName].max or "") .. "%")
end
ui.scroll1.onValueChange = function(scroll, value)
context.storage[panelName].min = value
updateText()
end
ui.scroll2.onValueChange = function(scroll, value)
context.storage[panelName].max = value
updateText()
end
ui.scroll1:setValue(context.storage[panelName].min)
ui.scroll2:setValue(context.storage[panelName].max)
context.macro(25, function()
if context.storage[panelName].enabled and context.storage[panelName].item >= 100 and context.storage[panelName].min <= context.hppercent() and context.hppercent() <= context.storage[panelName].max then
if context.useRune(context.storage[panelName].item, context.player, 500) then
context.delay(300)
end
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 = g_ui.createWidget("DualScrollItemPanel", parent)
ui:setId(panelName)
if not context.storage[panelName] then
context.storage[panelName] = {
item = 268,
min = 0,
max = 60
}
end
ui.title:setOn(context.storage[panelName].enabled)
ui.title.onClick = function(widget)
context.storage[panelName].enabled = not context.storage[panelName].enabled
widget:setOn(context.storage[panelName].enabled)
end
ui.item.onItemChange = function(widget)
context.storage[panelName].item = widget:getItemId()
end
ui.item:setItemId(context.storage[panelName].item)
local updateText = function()
ui.title:setText("" .. (context.storage[panelName].min or "") .. "% <= mana <= " .. (context.storage[panelName].max or "") .. "%")
end
ui.scroll1.onValueChange = function(scroll, value)
context.storage[panelName].min = value
updateText()
end
ui.scroll2.onValueChange = function(scroll, value)
context.storage[panelName].max = value
updateText()
end
ui.scroll1:setValue(context.storage[panelName].min)
ui.scroll2:setValue(context.storage[panelName].max)
context.macro(25, function()
if context.storage[panelName].enabled and context.storage[panelName].item >= 100 and context.storage[panelName].min <= context.manapercent() and context.manapercent() <= context.storage[panelName].max then
if context.useRune(context.storage[panelName].item, context.player, 500) then
context.delay(300)
end
end
end)
end
Panels.ManaItem = Panels.Mana
Panels.Equip = function(parent)
if not parent then
parent = context.panel
end
local panelName = "autoEquipItem"
local panelId = 1
while parent:getChildById(panelName .. panelId) do
panelId = panelId + 1
end
panelName = panelName .. panelId
local ui = g_ui.createWidget("TwoItemsAndSlotPanel", parent)
ui:setId(panelName)
if not context.storage[panelName] then
context.storage[panelName] = {}
if panelId == 1 then
context.storage[panelName].item1 = 3052
context.storage[panelName].item2 = 3089
context.storage[panelName].slot = 9
end
end
ui.title:setText("Auto equip")
ui.title:setOn(context.storage[panelName].enabled)
ui.title.onClick = function(widget)
context.storage[panelName].enabled = not context.storage[panelName].enabled
widget:setOn(context.storage[panelName].enabled)
end
ui.item1:setItemId(context.storage[panelName].item1 or 0)
ui.item1.onItemChange = function(widget)
context.storage[panelName].item1 = widget:getItemId()
end
ui.item2:setItemId(context.storage[panelName].item2 or 0)
ui.item2.onItemChange = function(widget)
context.storage[panelName].item2 = widget:getItemId()
end
if not context.storage[panelName].slot then
context.storage[panelName].slot = 1
end
ui.slot:setCurrentIndex(context.storage[panelName].slot)
ui.slot.onOptionChange = function(widget)
context.storage[panelName].slot = widget.currentIndex
end
context.macro(250, function()
if context.storage[panelName].enabled and context.storage[panelName].slot > 0 then
local item1 = context.storage[panelName].item1 or 0
local item2 = context.storage[panelName].item2 or 0
if item1 < 100 and item2 < 100 then
return
end
local slotItem = context.getSlot(context.storage[panelName].slot)
if slotItem and (slotItem:getId() == item1 or slotItem:getId() == item2) then
return
end
local newItem = context.findItem(context.storage[panelName].item1, 0)
if not newItem then
newItem = context.findItem(context.storage[panelName].item2, 0)
if not newItem then
return
end
end
g_game.move(newItem, {x=65535, y=context.storage[panelName].slot, z=0})
context.delay(1000)
end
end)
end
Panels.AutoEquip = Panels.Equip
Panels.Eating = function(parent)
if not parent then
parent = context.panel
end
local panelName = "autoEatingPanel"
local panelId = 1
while parent:getChildById(panelName .. panelId) do
panelId = panelId + 1
end
panelName = panelName .. panelId
local ui = g_ui.createWidget("ItemsPanel", parent)
ui:setId(panelName)
if not context.storage[panelName] then
context.storage[panelName] = {}
end
ui.title:setText("Auto eating")
ui.title:setOn(context.storage[panelName].enabled)
ui.title.onClick = function(widget)
context.storage[panelName].enabled = not context.storage[panelName].enabled
widget:setOn(context.storage[panelName].enabled)
end
if type(context.storage["autoEating" .. panelId]) ~= 'table' then
context.storage["autoEating" .. panelId] = {3725, 0, 0, 0, 0}
end
for i=1,5 do
ui.items:getChildByIndex(i).onItemChange = function(widget)
context.storage["autoEating" .. panelId][i] = widget:getItemId()
end
ui.items:getChildByIndex(i):setItemId(context.storage["autoEating" .. panelId][i])
end
context.macro(15000, function()
if not context.storage[panelName].enabled then
return
end
local candidates = {}
for i, item in pairs(context.storage["autoEating" .. panelId]) do
if item >= 100 then
table.insert(candidates, item)
end
end
if #candidates == 0 then
return
end
context.usewith(candidates[math.random(1, #candidates)], context.player)
end)
end
Panels.ManaItem = Panels.Mana

View File

@@ -82,7 +82,7 @@ Panel
margin-top: 4 margin-top: 4
text: Loot Containers text: Loot Containers
Panel ItemsRow
id: containers id: containers
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.left: parent.left anchors.left: parent.left
@@ -90,35 +90,6 @@ Panel
height: 33 height: 33
margin-top: 2 margin-top: 2
BotItem
id: item1
anchors.top: parent.top
anchors.left: parent.left
margin-left: 3
BotItem
id: item2
anchors.top: prev.top
anchors.left: prev.right
margin-left: 2
BotItem
id: item3
anchors.top: prev.top
anchors.left: prev.right
margin-left: 2
BotItem
id: item4
anchors.top: prev.top
anchors.left: prev.right
margin-left: 2
BotItem
id: item5
anchors.top: prev.top
anchors.left: prev.right
margin-left: 2
]], parent) ]], parent)

View File

@@ -0,0 +1,17 @@
local context = G.botContext
local Panels = context.Panels
Panels.TradeMessage = function(parent)
context.macro(60000, "Send message on trade", nil, function()
local trade = context.getChannelId("advertising")
if not trade then
trade = context.getChannelId("trade")
end
if context.storage.autoTradeMessage:len() > 0 and trade then
context.sayChannel(trade, context.storage.autoTradeMessage)
end
end, parent)
context.addTextEdit("autoTradeMessage", context.storage.autoTradeMessage or "I'm using OTClientV8 - https://github.com/OTCv8/otclientv8", function(widget, text)
context.storage.autoTradeMessage = text
end, parent)
end

View File

@@ -0,0 +1,65 @@
local context = G.botContext
local Panels = context.Panels
Panels.AttackLeaderTarget = function(parent)
local toAttack = nil
context.onMissle(function(missle)
if not context.storage.attackLeader or context.storage.attackLeader:len() == 0 then
return
end
local src = missle:getSource()
if src.z ~= context.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]
if c1:getName():lower() == context.storage.attackLeader:lower() then
toAttack = toCreatures[1]
end
end)
context.macro(50, "Attack leader's target", nil, function()
if toAttack and context.storage.attackLeader:len() > 0 then
g_game.attack(toAttack)
toAttack = nil
end
end, parent)
context.addTextEdit("attackLeader", context.storage.attackLeader or "player name", function(widget, text)
context.storage.attackLeader = text
end, parent)
end
Panels.LimitFloor = function(parent)
context.onPlayerPositionChange(function(pos)
if context.storage.limitFloor then
local gameMapPanel = modules.game_interface.getMapPanel()
if gameMapPanel then
gameMapPanel:lockVisibleFloor(pos.z)
end
end
end)
local switch = context.addSwitch("limitFloor", "Don't show higher floors", function(widget)
widget:setOn(not widget:isOn())
context.storage.limitFloor = widget:isOn()
local gameMapPanel = modules.game_interface.getMapPanel()
if gameMapPanel then
if context.storage.limitFloor then
gameMapPanel:lockVisibleFloor(context.posz())
else
gameMapPanel:unlockVisibleFloor()
end
end
end, parent)
switch:setOn(context.storage.limitFloor)
end

View File

@@ -5,7 +5,7 @@ Panels.Waypoints = function(parent)
local ui = context.setupUI([[ local ui = context.setupUI([[
Panel Panel
id: waypoints id: waypoints
height: 203 height: 223
BotLabel BotLabel
anchors.top: parent.top anchors.top: parent.top
@@ -123,6 +123,31 @@ Panel
width: 61 width: 61
height: 20 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 Button
id: wFunction id: wFunction
anchors.top: prev.top anchors.top: prev.top
@@ -167,6 +192,10 @@ Panel
return true return true
elseif command == "say" then elseif command == "say" then
return true return true
elseif command == "npc" then
return true
elseif command == "follow" then
return true
elseif command == "label" then elseif command == "label" then
return true return true
elseif command == "gotolabel" then elseif command == "gotolabel" then
@@ -272,7 +301,15 @@ Panel
return return
end end
context.storage.cavebot.enabled = not context.storage.cavebot.enabled context.storage.cavebot.enabled = not context.storage.cavebot.enabled
if autoRecording then
refreshConfig() 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 end
ui.add.onClick = function() ui.add.onClick = function()
modules.game_textedit.multilineEditor("Waypoints editor", "name:Config name\nlabel:start\n", function(newText) modules.game_textedit.multilineEditor("Waypoints editor", "name:Config name\nlabel:start\n", function(newText)
@@ -425,6 +462,36 @@ Panel
end) end)
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() ui.wFunction.onClick = function()
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
return return
@@ -498,6 +565,10 @@ Panel
return return
end end
if modules.game_walking.lastManualWalk + 500 > context.now then
return
end
-- wait if walked or opened container recently -- wait if walked or opened container recently
if context.player:isWalking() or lastOpenedContainer + 1000 > context.now then if context.player:isWalking() or lastOpenedContainer + 1000 > context.now then
executeNextMacroCall = false executeNextMacroCall = false
@@ -539,12 +610,23 @@ Panel
lastGotoSuccesful = true lastGotoSuccesful = true
end end
if command.command == "goto" then if command.command == "goto" or command.command == "follow" then
local matches = regexMatch(command.text, [[([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)]]) local matches = regexMatch(command.text, [[([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)]])
if #matches == 1 and #matches[1] == 4 then if (#matches == 1 and #matches[1] == 4) or command.command == "follow" then
local position = {x=tonumber(matches[1][2]), y=tonumber(matches[1][3]), z=tonumber(matches[1][4])} local position = nil
local distance = context.getDistanceBetween(position, context.player:getPosition()) if command.command == "follow" then
if distance > 100 or position.z ~= context.player:getPosition().z 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 lastGotoSuccesful = false
elseif distance > 0 then elseif distance > 0 then
if not context.findPath(context.player:getPosition(), position, 100, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true }) then if not context.findPath(context.player:getPosition(), position, 100, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true }) then
@@ -625,6 +707,8 @@ Panel
waitTo = 0 waitTo = 0
elseif command.command == "say" and lastGotoSuccesful then elseif command.command == "say" and lastGotoSuccesful then
context.say(command.text) context.say(command.text)
elseif command.command == "npc" and lastGotoSuccesful then
context.sayNpc(command.text)
elseif command.command == "function" and lastGotoSuccesful then elseif command.command == "function" and lastGotoSuccesful then
usedGotoLabel = false usedGotoLabel = false
local status, result = pcall(function() local status, result = pcall(function()

View File

@@ -0,0 +1,68 @@
BotButton < Button
margin-top: 2
BotSwitch < Button
margin-top: 2
height: 20
image-color: green
$!on:
image-color: red
SmallBotSwitch < Button
margin-top: 2
height: 15
image-color: green
$!on:
image-color: red
BotLabel < Label
margin-top: 2
height: 20
text-auto-resize: true
text-align: center
text-wrap: true
BotItem < Item
virtual: true
&selectable: true
BotTextEdit < TextEdit
@onClick: modules.game_textedit.show(self)
text-align: center
multiline: false
focusable: false
height: 20
BotSeparator < HorizontalSeparator
margin-top: 5
margin-bottom: 3
BotPanel < Panel
layout:
type: verticalBox
CaveBotLabel < Label
background-color: alpha
text-offset: 2 0
focusable: true
$focus:
background-color: #00000055
SlotComboBoxPopupMenu < ComboBoxPopupMenu
SlotComboBoxPopupMenuButton < ComboBoxPopupMenuButton
SlotComboBox < ComboBox
@onSetup: |
self:addOption("Head")
self:addOption("Neck")
self:addOption("Back")
self:addOption("Body")
self:addOption("Right")
self:addOption("Left")
self:addOption("Leg")
self:addOption("Feet")
self:addOption("Finger")
self:addOption("Ammo")
self:addOption("Purse")

View File

@@ -0,0 +1,229 @@
DualScrollPanel < Panel
height: 55
margin-top: 2
SmallBotSwitch
id: title
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
text-align: center
HorizontalScrollBar
id: scroll1
anchors.left: title.left
anchors.right: title.horizontalCenter
anchors.top: title.bottom
margin-right: 2
margin-top: 2
minimum: 0
maximum: 100
step: 1
HorizontalScrollBar
id: scroll2
anchors.left: title.horizontalCenter
anchors.right: title.right
anchors.top: prev.top
margin-left: 2
minimum: 0
maximum: 100
step: 1
BotTextEdit
id: text
anchors.left: parent.left
anchors.right: parent.right
anchors.top: scroll1.bottom
margin-top: 3
SingleScrollItemPanel < Panel
height: 45
margin-top: 2
BotItem
id: item
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 3
SmallBotSwitch
id: title
anchors.left: prev.right
anchors.right: parent.right
anchors.top: prev.top
margin-left: 2
text-align: center
HorizontalScrollBar
id: scroll
anchors.left: title.left
anchors.right: title.right
anchors.top: title.bottom
margin-top: 2
minimum: 0
maximum: 100
step: 1
DualScrollItemPanel < Panel
height: 40
margin-top: 2
BotItem
id: item
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 3
SmallBotSwitch
id: title
anchors.left: prev.right
anchors.right: parent.right
anchors.top: prev.top
margin-left: 2
text-align: center
HorizontalScrollBar
id: scroll1
anchors.left: title.left
anchors.right: title.horizontalCenter
anchors.top: title.bottom
margin-top: 2
margin-right: 2
minimum: 0
maximum: 100
step: 1
HorizontalScrollBar
id: scroll2
anchors.left: title.horizontalCenter
anchors.right: title.right
anchors.top: prev.top
margin-left: 2
minimum: 0
maximum: 100
step: 1
ItemsRow < Panel
height: 33
margin-top: 2
BotItem
id: item1
anchors.top: parent.top
anchors.left: parent.left
margin-left: 3
BotItem
id: item2
anchors.top: prev.top
anchors.left: prev.right
margin-left: 2
BotItem
id: item3
anchors.top: prev.top
anchors.left: prev.right
margin-left: 2
BotItem
id: item4
anchors.top: prev.top
anchors.left: prev.right
margin-left: 2
BotItem
id: item5
anchors.top: prev.top
anchors.left: prev.right
margin-left: 2
ItemsPanel < Panel
height: 55
SmallBotSwitch
id: title
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
text-align: center
ItemsRow
id: items
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
ItemAndButtonPanel < Panel
height: 40
BotItem
id: item
anchors.left: parent.left
anchors.top: parent.top
BotSwitch
id: title
anchors.left: prev.right
anchors.right: parent.right
anchors.verticalCenter: prev.verticalCenter
text-align: center
margin-left: 2
margin-top: 0
ItemAndSlotPanel < Panel
height: 40
BotItem
id: item
anchors.left: parent.left
anchors.top: parent.top
SmallBotSwitch
id: title
anchors.left: prev.right
anchors.right: parent.right
anchors.top: prev.top
text-align: center
margin-left: 2
margin-top: 0
SlotComboBox
id: slot
anchors.left: prev.left
anchors.right: prev.right
anchors.top: prev.bottom
margin-top: 2
height: 20
TwoItemsAndSlotPanel < Panel
height: 40
BotItem
id: item1
anchors.left: parent.left
anchors.top: parent.top
BotItem
id: item2
anchors.left: prev.right
anchors.top: prev.top
SmallBotSwitch
id: title
anchors.left: prev.right
anchors.right: parent.right
anchors.top: prev.top
text-align: center
margin-left: 2
margin-top: 0
SlotComboBox
id: slot
anchors.left: prev.left
anchors.right: prev.right
anchors.top: prev.bottom
margin-top: 2
height: 20

View File

@@ -206,7 +206,6 @@ function enableChat(temporarily)
consoleTextEdit:focus() consoleTextEdit:focus()
local gameRootPanel = modules.game_interface.getRootPanel() local gameRootPanel = modules.game_interface.getRootPanel()
g_keyboard.unbindKeyDown("Space", gameRootPanel)
g_keyboard.unbindKeyDown("Enter", gameRootPanel) g_keyboard.unbindKeyDown("Enter", gameRootPanel)
if temporarily then if temporarily then
@@ -225,7 +224,7 @@ function enableChat(temporarily)
consoleToggleChat:setTooltip(tr("Disable chat mode, allow to walk using ASDW")) consoleToggleChat:setTooltip(tr("Disable chat mode, allow to walk using ASDW"))
end end
function disableChat() function disableChat(temporarily)
if not consoleToggleChat:isChecked() then if not consoleToggleChat:isChecked() then
return consoleToggleChat:setChecked(true) return consoleToggleChat:setChecked(true)
end end
@@ -245,7 +244,6 @@ function disableChat()
end end
local gameRootPanel = modules.game_interface.getRootPanel() local gameRootPanel = modules.game_interface.getRootPanel()
g_keyboard.bindKeyDown("Space", quickFunc, gameRootPanel)
g_keyboard.bindKeyDown("Enter", quickFunc, gameRootPanel) g_keyboard.bindKeyDown("Enter", quickFunc, gameRootPanel)
modules.game_walking.enableWSAD() modules.game_walking.enableWSAD()
@@ -392,6 +390,13 @@ function switchMode(floating)
consolePanel:setWidth(600) consolePanel:setWidth(600)
consolePanel:setDraggable(true) consolePanel:setDraggable(true)
consoleTabBar:setDraggable(true) consoleTabBar:setDraggable(true)
local bottomSplitter = modules.game_interface.bottomSplitter
if bottomSplitter then
bottomSplitter:removeAnchor(AnchorRight)
bottomSplitter:setWidth(600)
end
if not floatingMode then if not floatingMode then
local savedMargin = g_settings.get("consoleLeftMargin") local savedMargin = g_settings.get("consoleLeftMargin")
local newMargin = 150 local newMargin = 150
@@ -401,7 +406,12 @@ function switchMode(floating)
newMargin = math.max(0, newMargin) newMargin = math.max(0, newMargin)
newMargin = math.min(consolePanel:getParent():getWidth() - consolePanel:getWidth(), newMargin) newMargin = math.min(consolePanel:getParent():getWidth() - consolePanel:getWidth(), newMargin)
consolePanel:setMarginLeft(newMargin) consolePanel:setMarginLeft(newMargin)
if bottomSplitter then
bottomSplitter:setMarginLeft(newMargin)
end end
end
else else
consolePanel:setImageColor('white') consolePanel:setImageColor('white')
consolePanel:addAnchor(AnchorLeft, 'parent', AnchorLeft) consolePanel:addAnchor(AnchorLeft, 'parent', AnchorLeft)
@@ -425,6 +435,10 @@ function onDragMove(widget, pos, moved)
newMargin = math.max(0, newMargin) newMargin = math.max(0, newMargin)
newMargin = math.min(consolePanel:getParent():getWidth() - consolePanel:getWidth(), newMargin) newMargin = math.min(consolePanel:getParent():getWidth() - consolePanel:getWidth(), newMargin)
consolePanel:setMarginLeft(newMargin) consolePanel:setMarginLeft(newMargin)
local bottomSplitter = modules.game_interface.bottomSplitter
if bottomSplitter then
bottomSplitter:setMarginLeft(newMargin)
end
g_settings.set("consoleLeftMargin", newMargin) g_settings.set("consoleLeftMargin", newMargin)
return true return true
end end

View File

@@ -7,6 +7,7 @@ function terminate()
end end
function updateFeatures(version) function updateFeatures(version)
print(version)
g_game.resetFeatures() g_game.resetFeatures()
-- you can add custom features here, list of them in modules\gamelib\const.lua -- you can add custom features here, list of them in modules\gamelib\const.lua

View File

@@ -144,6 +144,10 @@ function onMiniWindowClose()
end end
function onHealthChange(localPlayer, health, maxHealth) function onHealthChange(localPlayer, health, maxHealth)
if health > maxHealth then
maxHealth = health
end
healthBar:setText(health .. ' / ' .. maxHealth) healthBar:setText(health .. ' / ' .. maxHealth)
healthBar:setTooltip(tr(healthTooltip, health, maxHealth)) healthBar:setTooltip(tr(healthTooltip, health, maxHealth))
healthBar:setValue(health, 0, maxHealth) healthBar:setValue(health, 0, maxHealth)
@@ -175,6 +179,9 @@ function onHealthChange(localPlayer, health, maxHealth)
end end
function onManaChange(localPlayer, mana, maxMana) function onManaChange(localPlayer, mana, maxMana)
if mana > maxMana then
maxMana = mana
end
manaBar:setText(mana .. ' / ' .. maxMana) manaBar:setText(mana .. ' / ' .. maxMana)
manaBar:setTooltip(tr(manaTooltip, mana, maxMana)) manaBar:setTooltip(tr(manaTooltip, mana, maxMana))
manaBar:setValue(mana, 0, maxMana) manaBar:setValue(mana, 0, maxMana)

View File

@@ -0,0 +1,116 @@
extraHotkeys = {}
function addExtraHotkey(name, description, callback)
table.insert(extraHotkeys, {
name = name:lower(),
description = tr(description),
callback = callback
})
end
function setupExtraHotkeys(combobox)
addExtraHotkey("none", "None", nil)
addExtraHotkey("cancelAttack", "Stop attacking", function(repeated)
if not repeated then
g_game.attack(nil)
end
end)
addExtraHotkey("attackNext", "Attack next target from battle list", function(repeated)
if repeated or not modules.game_battle then
return
end
local battlePanel = modules.game_battle.battlePanel
local attackedCreature = g_game.getAttackingCreature()
local nextChild = nil
local breakNext = false
for i, child in ipairs(battlePanel:getChildren()) do
if not child.creature or child:isDisabled() then
break
end
nextChild = child
if breakNext then
break
end
if child.creature == attackedCreature then
breakNext = true
nextChild = battlePanel:getFirstChild()
end
end
if nextChild and nextChild.creature ~= attackedCreature then
g_game.attack(nextChild.creature)
end
end)
addExtraHotkey("attackPrevious", "Attack previous target from battle list", function(repeated)
if repeated or not modules.game_battle then
return
end
local battlePanel = modules.game_battle.battlePanel
local attackedCreature = g_game.getAttackingCreature()
local prevChild = battlePanel:getLastChild()
for i, child in ipairs(battlePanel:getChildren()) do
if not child.creature or child:isDisabled() then
break
end
if child.creature == attackedCreature then
break
end
prevChild = child
end
if prevChild and prevChild.creature ~= attackedCreature then
g_game.attack(prevChild.creature)
end
end)
addExtraHotkey("toogleWsad", "Enable/disable wsad walking", function(repeated)
if repeated or not modules.game_console then
return
end
if not modules.game_console.consoleToggleChat:isChecked() then
modules.game_console.disableChat(true)
else
modules.game_console.enableChat(true)
end
end)
for index, actionDetails in ipairs(extraHotkeys) do
combobox:addOption(actionDetails.description)
end
end
function executeExtraHotkey(action, repeated)
action = action:lower()
for index, actionDetails in ipairs(extraHotkeys) do
if actionDetails.name == action and actionDetails.callback then
actionDetails.callback(repeated)
end
end
end
function translateActionToActionComboboxIndex(action)
action = action:lower()
for index, actionDetails in ipairs(extraHotkeys) do
if actionDetails.name == action then
return index
end
end
return 1
end
function translateActionComboboxIndexToAction(index)
if index > 1 and index <= #extraHotkeys then
return extraHotkeys[index].name
end
return nil
end
function getActionDescription(action)
action = action:lower()
for index, actionDetails in ipairs(extraHotkeys) do
if actionDetails.name == action then
return actionDetails.description
end
end
return "invalid action"
end

View File

@@ -10,6 +10,7 @@ HotkeyColors = {
itemUseSelf = '#00FF00', itemUseSelf = '#00FF00',
itemUseTarget = '#FF0000', itemUseTarget = '#FF0000',
itemUseWith = '#F5B325', itemUseWith = '#F5B325',
extraAction = '#FFAA00'
} }
hotkeysManagerLoaded = false hotkeysManagerLoaded = false
@@ -76,6 +77,10 @@ function init()
g_keyboard.bindKeyPress('Down', function() currentHotkeys:focusNextChild(KeyboardFocusReason) end, hotkeysWindow) g_keyboard.bindKeyPress('Down', function() currentHotkeys:focusNextChild(KeyboardFocusReason) end, hotkeysWindow)
g_keyboard.bindKeyPress('Up', function() currentHotkeys:focusPreviousChild(KeyboardFocusReason) end, hotkeysWindow) g_keyboard.bindKeyPress('Up', function() currentHotkeys:focusPreviousChild(KeyboardFocusReason) end, hotkeysWindow)
if hotkeysWindow.action and setupExtraHotkeys then
setupExtraHotkeys(hotkeysWindow.action)
end
connect(g_game, { connect(g_game, {
onGameStart = online, onGameStart = online,
onGameEnd = offline onGameEnd = offline
@@ -217,7 +222,8 @@ function save()
itemId = child.itemId, itemId = child.itemId,
subType = child.subType, subType = child.subType,
useType = child.useType, useType = child.useType,
value = child.value value = child.value,
action = child.action
} }
end end
@@ -310,6 +316,7 @@ function startChooseItem()
end end
function clearObject() function clearObject()
currentHotkeyLabel.action = nil
currentHotkeyLabel.itemId = nil currentHotkeyLabel.itemId = nil
currentHotkeyLabel.subType = nil currentHotkeyLabel.subType = nil
currentHotkeyLabel.useType = nil currentHotkeyLabel.useType = nil
@@ -358,6 +365,7 @@ function addKeyCombo(keyCombo, keySettings, focus)
currentHotkeyLabel = hotkeyLabel currentHotkeyLabel = hotkeyLabel
hotkeyLabel.keyCombo = keyCombo hotkeyLabel.keyCombo = keyCombo
hotkeyLabel.autoSend = toboolean(keySettings.autoSend) hotkeyLabel.autoSend = toboolean(keySettings.autoSend)
hotkeyLabel.action = keySettings.action
hotkeyLabel.itemId = tonumber(keySettings.itemId) hotkeyLabel.itemId = tonumber(keySettings.itemId)
hotkeyLabel.subType = tonumber(keySettings.subType) hotkeyLabel.subType = tonumber(keySettings.subType)
hotkeyLabel.useType = tonumber(keySettings.useType) hotkeyLabel.useType = tonumber(keySettings.useType)
@@ -368,6 +376,7 @@ function addKeyCombo(keyCombo, keySettings, focus)
hotkeyLabel.itemId = nil hotkeyLabel.itemId = nil
hotkeyLabel.subType = nil hotkeyLabel.subType = nil
hotkeyLabel.useType = nil hotkeyLabel.useType = nil
hotkeyLabel.action = nil
hotkeyLabel.value = '' hotkeyLabel.value = ''
end end
@@ -380,13 +389,13 @@ function addKeyCombo(keyCombo, keySettings, focus)
end end
end end
boundCombosCallback[keyCombo] = function() prepareKeyCombo(keyCombo) end boundCombosCallback[keyCombo] = function(k, c, ticks) prepareKeyCombo(keyCombo, ticks) end
g_keyboard.bindKeyPress(keyCombo, boundCombosCallback[keyCombo], gameRootPanel) g_keyboard.bindKeyPress(keyCombo, boundCombosCallback[keyCombo], gameRootPanel)
if not keyCombo:lower():find("ctrl") then if not keyCombo:lower():find("ctrl") then
local keyComboCtrl = "Ctrl+" .. keyCombo local keyComboCtrl = "Ctrl+" .. keyCombo
if not boundCombosCallback[keyComboCtrl] then if not boundCombosCallback[keyComboCtrl] then
boundCombosCallback[keyComboCtrl] = function() prepareKeyCombo(keyComboCtrl) end boundCombosCallback[keyComboCtrl] = function(k, c, ticks) prepareKeyCombo(keyComboCtrl, ticks) end
g_keyboard.bindKeyPress(keyComboCtrl, boundCombosCallback[keyComboCtrl], gameRootPanel) g_keyboard.bindKeyPress(keyComboCtrl, boundCombosCallback[keyComboCtrl], gameRootPanel)
end end
end end
@@ -400,9 +409,9 @@ function addKeyCombo(keyCombo, keySettings, focus)
configValueChanged = true configValueChanged = true
end end
function prepareKeyCombo(keyCombo, repeated) function prepareKeyCombo(keyCombo, ticks)
local hotKey = hotkeyList[keyCombo] local hotKey = hotkeyList[keyCombo]
if (keyCombo:lower():find("ctrl") and not hotKey) or (hotKey and hotKey.itemId == nil and (not hotKey.value or #hotKey.value == 0)) then if (keyCombo:lower():find("ctrl") and not hotKey) or (hotKey and hotKey.itemId == nil and (not hotKey.value or #hotKey.value == 0) and not hotKey.action) then
keyCombo = keyCombo:gsub("Ctrl%+", "") keyCombo = keyCombo:gsub("Ctrl%+", "")
keyCombo = keyCombo:gsub("ctrl%+", "") keyCombo = keyCombo:gsub("ctrl%+", "")
hotKey = hotkeyList[keyCombo] hotKey = hotkeyList[keyCombo]
@@ -411,14 +420,14 @@ function prepareKeyCombo(keyCombo, repeated)
return return
end end
if hotKey.itemId == nil then -- say if hotKey.itemId == nil and hotKey.action == nil then -- say
scheduleEvent(function() doKeyCombo(keyCombo) end, g_settings.getNumber('hotkeyDelay')) scheduleEvent(function() doKeyCombo(keyCombom, ticks >= 5) end, g_settings.getNumber('hotkeyDelay'))
else else
doKeyCombo(keyCombo) doKeyCombo(keyCombo, ticks >= 5)
end end
end end
function doKeyCombo(keyCombo) function doKeyCombo(keyCombo, repeated)
if not g_game.isOnline() then return end if not g_game.isOnline() then return end
if modules.game_console and modules.game_console.isChatEnabled() then if modules.game_console and modules.game_console.isChatEnabled() then
if keyCombo:len() == 1 then if keyCombo:len() == 1 then
@@ -440,7 +449,9 @@ function doKeyCombo(keyCombo)
return return
end end
if hotKey.itemId == nil then if hotKey.action then
executeExtraHotkey(hotKey.action, repeated)
elseif hotKey.itemId == nil then
if not hotKey.value or #hotKey.value == 0 then return end if not hotKey.value or #hotKey.value == 0 then return end
if hotKey.autoSend then if hotKey.autoSend then
modules.game_console.sendMessage(hotKey.value) modules.game_console.sendMessage(hotKey.value)
@@ -505,7 +516,10 @@ end
function updateHotkeyLabel(hotkeyLabel) function updateHotkeyLabel(hotkeyLabel)
if not hotkeyLabel then return end if not hotkeyLabel then return end
if hotkeyLabel.useType == HOTKEY_MANAGER_USEONSELF then if hotkeyLabel.action ~= nil then
hotkeyLabel:setText(tr('%s: (Action: %s)', hotkeyLabel.keyCombo, getActionDescription(hotkeyLabel.action)))
hotkeyLabel:setColor(HotkeyColors.extraAction)
elseif hotkeyLabel.useType == HOTKEY_MANAGER_USEONSELF then
hotkeyLabel:setText(tr('%s: (use object on yourself)', hotkeyLabel.keyCombo)) hotkeyLabel:setText(tr('%s: (use object on yourself)', hotkeyLabel.keyCombo))
hotkeyLabel:setColor(HotkeyColors.itemUseSelf) hotkeyLabel:setColor(HotkeyColors.itemUseSelf)
elseif hotkeyLabel.useType == HOTKEY_MANAGER_USEONTARGET then elseif hotkeyLabel.useType == HOTKEY_MANAGER_USEONTARGET then
@@ -532,8 +546,22 @@ function updateHotkeyLabel(hotkeyLabel)
end end
function updateHotkeyForm(reset) function updateHotkeyForm(reset)
local hasCustomAction = hotkeysWindow.action and hotkeysWindow.action.currentIndex > 1
configValueChanged = true configValueChanged = true
if hotkeysWindow.action then
if currentHotkeyLabel then if currentHotkeyLabel then
hotkeysWindow.action:enable()
if currentHotkeyLabel.action then
hotkeysWindow.action:setCurrentIndex(translateActionToActionComboboxIndex(currentHotkeyLabel.action), true)
else
hotkeysWindow.action:setCurrentIndex(1, true)
end
else
hotkeysWindow.action:disable()
hotkeysWindow.action:setCurrentIndex(1, true)
end
end
if currentHotkeyLabel and not hasCustomAction then
removeHotkeyButton:enable() removeHotkeyButton:enable()
if currentHotkeyLabel.itemId ~= nil then if currentHotkeyLabel.itemId ~= nil then
hotkeyText:clearText() hotkeyText:clearText()
@@ -601,12 +629,22 @@ end
function removeHotkey() function removeHotkey()
if currentHotkeyLabel == nil then return end if currentHotkeyLabel == nil then return end
local gameRootPanel = modules.game_interface.getRootPanel() local gameRootPanel = modules.game_interface.getRootPanel()
configValueChanged = true
g_keyboard.unbindKeyPress(currentHotkeyLabel.keyCombo, boundCombosCallback[currentHotkeyLabel.keyCombo], gameRootPanel) g_keyboard.unbindKeyPress(currentHotkeyLabel.keyCombo, boundCombosCallback[currentHotkeyLabel.keyCombo], gameRootPanel)
boundCombosCallback[currentHotkeyLabel.keyCombo] = nil boundCombosCallback[currentHotkeyLabel.keyCombo] = nil
currentHotkeyLabel:destroy() currentHotkeyLabel:destroy()
currentHotkeyLabel = nil currentHotkeyLabel = nil
end end
function updateHotkeyAction()
if not hotkeysManagerLoaded then return end
if currentHotkeyLabel == nil then return end
configValueChanged = true
currentHotkeyLabel.action = translateActionComboboxIndexToAction(hotkeysWindow.action.currentIndex)
updateHotkeyLabel(currentHotkeyLabel)
updateHotkeyForm()
end
function onHotkeyTextChange(value) function onHotkeyTextChange(value)
if not hotkeysManagerLoaded then return end if not hotkeysManagerLoaded then return end
if currentHotkeyLabel == nil then return end if currentHotkeyLabel == nil then return end
@@ -614,6 +652,7 @@ function onHotkeyTextChange(value)
if value == '' then if value == '' then
currentHotkeyLabel.autoSend = false currentHotkeyLabel.autoSend = false
end end
configValueChanged = true
updateHotkeyLabel(currentHotkeyLabel) updateHotkeyLabel(currentHotkeyLabel)
updateHotkeyForm() updateHotkeyForm()
end end
@@ -622,6 +661,7 @@ function onSendAutomaticallyChange(autoSend)
if not hotkeysManagerLoaded then return end if not hotkeysManagerLoaded then return end
if currentHotkeyLabel == nil then return end if currentHotkeyLabel == nil then return end
if not currentHotkeyLabel.value or #currentHotkeyLabel.value == 0 then return end if not currentHotkeyLabel.value or #currentHotkeyLabel.value == 0 then return end
configValueChanged = true
currentHotkeyLabel.autoSend = autoSend currentHotkeyLabel.autoSend = autoSend
updateHotkeyLabel(currentHotkeyLabel) updateHotkeyLabel(currentHotkeyLabel)
updateHotkeyForm() updateHotkeyForm()
@@ -630,6 +670,7 @@ end
function onChangeUseType(useTypeWidget) function onChangeUseType(useTypeWidget)
if not hotkeysManagerLoaded then return end if not hotkeysManagerLoaded then return end
if currentHotkeyLabel == nil then return end if currentHotkeyLabel == nil then return end
configValueChanged = true
if useTypeWidget == useOnSelf then if useTypeWidget == useOnSelf then
currentHotkeyLabel.useType = HOTKEY_MANAGER_USEONSELF currentHotkeyLabel.useType = HOTKEY_MANAGER_USEONSELF
elseif useTypeWidget == useOnTarget then elseif useTypeWidget == useOnTarget then

View File

@@ -4,6 +4,6 @@ Module
author: andrefaramir, BeniS author: andrefaramir, BeniS
website: https://github.com/edubart/otclient website: https://github.com/edubart/otclient
sandboxed: true sandboxed: true
scripts: [ hotkeys_manager ] scripts: [ hotkeys_extra, hotkeys_manager ]
@onLoad: init() @onLoad: init()
@onUnload: terminate() @onUnload: terminate()

View File

@@ -11,7 +11,7 @@ HotkeyListLabel < UILabel
MainWindow MainWindow
id: hotkeysWindow id: hotkeysWindow
!text: tr('Hotkeys') !text: tr('Hotkeys')
size: 340 445 size: 370 475
@onEnter: modules.game_hotkeys.ok() @onEnter: modules.game_hotkeys.ok()
@onEscape: modules.game_hotkeys.cancel() @onEscape: modules.game_hotkeys.cancel()
@@ -80,6 +80,34 @@ MainWindow
margin-top: 8 margin-top: 8
@onClick: modules.game_hotkeys.removeHotkey() @onClick: modules.game_hotkeys.removeHotkey()
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
Label
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 10
!text: tr('Extra action:')
ComboBox
id: action
anchors.left: prev.right
anchors.right: parent.right
anchors.top: prev.top
margin-left: 5
margin-top: -4
enabled: false
@onOptionChange: modules.game_hotkeys.updateHotkeyAction()
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
Label Label
id: hotKeyTextLabel id: hotKeyTextLabel
!text: tr('Edit hotkey text:') !text: tr('Edit hotkey text:')
@@ -87,7 +115,7 @@ MainWindow
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: prev.bottom anchors.top: prev.bottom
margin-top: 10 margin-top: 6
TextEdit TextEdit
id: hotkeyText id: hotkeyText
@@ -174,7 +202,7 @@ MainWindow
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: next.top anchors.bottom: next.top
margin-bottom: 10 margin-bottom: 5
Button Button
id: okButton id: okButton

View File

@@ -910,7 +910,9 @@ function updateSize()
local newMargin = modules.game_console.consolePanel:getMarginLeft() local newMargin = modules.game_console.consolePanel:getMarginLeft()
newMargin = math.max(0, newMargin) newMargin = math.max(0, newMargin)
newMargin = math.min(modules.game_console.consolePanel:getParent():getWidth() - modules.game_console.consolePanel:getWidth(), newMargin) newMargin = math.min(modules.game_console.consolePanel:getParent():getWidth() - modules.game_console.consolePanel:getWidth(), newMargin)
bottomSplitter:setMarginLeft(newMargin)
modules.game_console.consolePanel:setMarginLeft(newMargin) modules.game_console.consolePanel:setMarginLeft(newMargin)
bottomSplitter:setMarginLeft(newMargin)
end end
if not classic then if not classic then

View File

@@ -11,6 +11,7 @@ lastWalk = 0
lastTurn = 0 lastTurn = 0
lastTurnDirection = 0 lastTurnDirection = 0
lastStop = 0 lastStop = 0
lastManualWalk = 0
turnKeys = {} turnKeys = {}
function init() function init()
@@ -254,6 +255,7 @@ function onWalkFinish(player)
end end
function walk(dir) function walk(dir)
lastManualWalk = g_clock.millis()
local player = g_game.getLocalPlayer() local player = g_game.getLocalPlayer()
if not player or g_game.isDead() or player:isDead() then if not player or g_game.isDead() or player:isDead() then
return return

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +0,0 @@
GPU ANGLE (Intel(R) UHD Graphics 620 Direct3D9Ex vs_3_0 ps_3_0)
OpenGL OpenGL ES 2.0 (ANGLE 2.1.a502c749b249)
== application started at Nov 01 2019 03:27:53
OTClientV8 0.999 beta rev 0 (alpha) made by otclient.ovh built on Oct 31 2019 for arch x86
[Atlas] Texture size is: 4096x4096 (max: 8192x8192)
Login to otclient.ovh:7172
Exiting application..

Binary file not shown.

Binary file not shown.