diff --git a/init.lua b/init.lua index 963479c..fc5659c 100644 --- a/init.lua +++ b/init.lua @@ -20,6 +20,7 @@ Servers = { -- OTClientV8ClassicWithFeatures = "otclient.ovh:7171:1099:25:30:80:90", -- OTClientV8Classic = "otclient.ovh:7171:1099" } +USE_NEW_ENERGAME = false -- uses entergamev2 based on websockets instead of entergame ALLOW_CUSTOM_SERVERS = true -- if true it shows option ANOTHER on server list -- CONFIG END diff --git a/modules/client/client.otmod b/modules/client/client.otmod index df46432..751d788 100644 --- a/modules/client/client.otmod +++ b/modules/client/client.otmod @@ -16,6 +16,7 @@ Module - client_background - client_options - client_entergame + - client_entergamev2 - client_terminal - client_stats - client_news diff --git a/modules/client_entergame/characterlist.lua b/modules/client_entergame/characterlist.lua index b976509..155a745 100644 --- a/modules/client_entergame/characterlist.lua +++ b/modules/client_entergame/characterlist.lua @@ -176,6 +176,7 @@ end -- public functions function CharacterList.init() + if USE_NEW_ENERGAME then return end connect(g_game, { onLoginError = onGameLoginError }) connect(g_game, { onLoginToken = onGameLoginToken }) connect(g_game, { onUpdateNeeded = onGameUpdateNeeded }) @@ -191,6 +192,7 @@ function CharacterList.init() end function CharacterList.terminate() + if USE_NEW_ENERGAME then return end disconnect(g_game, { onLoginError = onGameLoginError }) disconnect(g_game, { onLoginToken = onGameLoginToken }) disconnect(g_game, { onUpdateNeeded = onGameUpdateNeeded }) diff --git a/modules/client_entergame/entergame.lua b/modules/client_entergame/entergame.lua index bf10bce..b26799e 100644 --- a/modules/client_entergame/entergame.lua +++ b/modules/client_entergame/entergame.lua @@ -186,6 +186,7 @@ end -- public functions function EnterGame.init() + if USE_NEW_ENERGAME then return end enterGame = g_ui.displayUI('entergame') serverSelectorPanel = enterGame:getChildById('serverSelectorPanel') @@ -246,6 +247,7 @@ function EnterGame.init() end function EnterGame.terminate() + if USE_NEW_ENERGAME then return end g_keyboard.unbindKeyDown('Ctrl+G') enterGame:destroy() diff --git a/modules/client_entergame/entergame_new.otui b/modules/client_entergame/entergame_new.otui deleted file mode 100644 index 8f4e83e..0000000 --- a/modules/client_entergame/entergame_new.otui +++ /dev/null @@ -1,50 +0,0 @@ -StaticWindow - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - margin-right: 20 - id: newLoginPanel - width: 240 - height: 320 - !text: tr('Quick Login & Registration') - - UIButton - id: qrcode - width: 200 - height: 200 - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - image-fixed-ratio: true - image-smooth: false - margin-top: 5 - - UIButton - id: quathlogo - width: 66 - height: 40 - anchors.verticalCenter: prev.verticalCenter - anchors.horizontalCenter: prev.horizontalCenter - image-fixed-ratio: true - image-smooth: false - image-source: /images/ui/qauth - - Label - anchors.top: qrcode.bottom - anchors.left: qrcode.left - anchors.right: qrcode.right - text-align: center - text-auto-resize: true - !text: tr("Scan or click QR code\nto register or login") - height: 40 - margin-top: 10 - margin-bottom: 5 - - Button - anchors.top: prev.bottom - anchors.left: parent.left - anchors.right: parent.right - text-align: center - !text: tr("Click to get PC/Android/iOS app") - height: 20 - margin-top: 10 - color: #FFFFFF - @onClick: g_platform.openUrl("http://qauth.co") \ No newline at end of file diff --git a/modules/client_entergamev2/entergamev2.lua b/modules/client_entergamev2/entergamev2.lua new file mode 100644 index 0000000..1dbe9c4 --- /dev/null +++ b/modules/client_entergamev2/entergamev2.lua @@ -0,0 +1,5 @@ +function init() +end + +function terminate() +end diff --git a/modules/client_entergamev2/entergamev2.otmod b/modules/client_entergamev2/entergamev2.otmod new file mode 100644 index 0000000..1b54369 --- /dev/null +++ b/modules/client_entergamev2/entergamev2.otmod @@ -0,0 +1,10 @@ +Module + name: client_entergamev2 + description: Manages enter game and character list windows + author: otclient.ovh + website: http://otclient.ovh + sandboxed: true + scripts: [ entergamev2 ] + @onLoad: init() + @onUnload: terminate() + \ No newline at end of file diff --git a/modules/client_options/game.otui b/modules/client_options/game.otui index 12cef0a..342f077 100644 --- a/modules/client_options/game.otui +++ b/modules/client_options/game.otui @@ -17,8 +17,8 @@ Panel !tooltip: tr('Disable chat and allow walk using WSAD keys') OptionCheckBox - id: extentedPreWalking - !text: tr('Enable smooth walking (DASH)') + id: dash + !text: tr('Enable fast walking (DASH)') !tooltip: tr('Allows to execute next move without server confirmation of previous one') OptionCheckBox diff --git a/modules/client_options/options.lua b/modules/client_options/options.lua index 529b454..894958b 100644 --- a/modules/client_options/options.lua +++ b/modules/client_options/options.lua @@ -6,7 +6,7 @@ local defaultOptions = { classicView = true, classicControl = true, smartWalk = false, - extentedPreWalking = true, + dash = false, autoChaseOverride = true, showStatusMessagesInConsole = true, showEventMessagesInConsole = true, @@ -292,7 +292,7 @@ function setOption(key, value, force) addEvent(function() modules.game_interface.updateStretchShrink() end) - elseif key == 'extentedPreWalking' then + elseif key == 'dash' then if value then g_game.setMaxPreWalkingSteps(2) else diff --git a/modules/corelib/ui/uiwindow.lua b/modules/corelib/ui/uiwindow.lua index 4c0e2ce..39208df 100644 --- a/modules/corelib/ui/uiwindow.lua +++ b/modules/corelib/ui/uiwindow.lua @@ -25,7 +25,7 @@ end function UIWindow:onDragEnter(mousePos) if self.static then - return + return false end self:breakAnchors() self.movingReference = { x = mousePos.x - self:getX(), y = mousePos.y - self:getY() } diff --git a/modules/game_bot/bot.lua b/modules/game_bot/bot.lua index d4b49e8..d5a273b 100644 --- a/modules/game_bot/bot.lua +++ b/modules/game_bot/bot.lua @@ -23,6 +23,7 @@ function init() g_ui.importStyle("ui/basic.otui") g_ui.importStyle("ui/panels.otui") g_ui.importStyle("ui/config.otui") + g_ui.importStyle("ui/icons.otui") connect(g_game, { onGameStart = online, @@ -89,14 +90,19 @@ function clear() for i, socket in pairs(botWebSockets) do g_http.cancel(socket) + botWebSockets[i] = nil end - botWebSockets = {} for i, widget in pairs(g_ui.getRootWidget():getChildren()) do if widget.botWidget then widget:destroy() end end + for i, widget in pairs(modules.game_interface.gameMapPanel:getChildren()) do + if widget.botWidget then + widget:destroy() + end + end local gameMapPanel = modules.game_interface.getMapPanel() if gameMapPanel then @@ -149,7 +155,8 @@ function refresh() end configList:setCurrentOption(settings[index].config) if configList:getCurrentOption().text ~= settings[index].config then - settings[index].enabled = false + settings[index].config = configList:getCurrentOption().text + settings[index].enabled = false end enableButton:setOn(settings[index].enabled) diff --git a/modules/game_bot/config.otui b/modules/game_bot/config.otui deleted file mode 100644 index 5c7736a..0000000 --- a/modules/game_bot/config.otui +++ /dev/null @@ -1,75 +0,0 @@ -ConfigTabBar < MoveableTabBar - height: 22 - -ConfigTabBarButton < MoveableTabBarButton - height: 22 - padding: 15 - -ConfigTabBarPanel < MoveableTabBarPanel - -MainWindow - id: configWindow - size: 650 497 - !text: tr("Config editor") - - Label - id: description - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - text-auto-resize: true - text-align: left - text-wrap: true - !text: tr("For more informations how to edit config, click 'Documentation' button") - - ConfigTabBar - id: configTab - anchors.left: parent.left - anchors.top: prev.bottom - anchors.right: parent.right - margin-top: 5 - tab-spacing: 2 - movable: false - - MultilineTextEdit - id: text - anchors.top: textScroll.top - anchors.left: parent.left - anchors.right: textScroll.left - anchors.bottom: textScroll.bottom - vertical-scrollbar: textScroll - text-wrap: true - - VerticalScrollBar - id: textScroll - anchors.top: configTab.bottom - anchors.bottom: okButton.top - anchors.right: parent.right - margin-bottom: 10 - step: 16 - pixels-scroll: true - - Button - id: documentationButton - !text: tr('Documentation') - anchors.bottom: parent.bottom - anchors.left: parent.left - width: 150 - @onClick: scheduleEvent(function() g_platform.openUrl("https://github.com/OTCv8/otclientv8_bot") end, 50) - - Button - id: okButton - !text: tr('Ok') - anchors.bottom: parent.bottom - anchors.right: next.left - margin-right: 10 - width: 60 - @onClick: modules.game_bot.saveEditedConfig() - - Button - id: cancelButton - !text: tr('Cancel') - anchors.bottom: parent.bottom - anchors.right: parent.right - width: 60 - @onClick: self:getParent():hide() diff --git a/modules/game_bot/default_config/icons.lua b/modules/game_bot/default_config/icons.lua new file mode 100644 index 0000000..396bef1 --- /dev/null +++ b/modules/game_bot/default_config/icons.lua @@ -0,0 +1,38 @@ + + +addIcon("dancing", {outfit={mount=0,feet=0,legs=0,body=176,type=128,auxType=0,addons=3,head=48}, hotkey="F5", text="dance"}, macro(100, "dance", function() + turn(math.random(0,3)) +end)) + +addIcon("ctrl", {outfit={mount=0,feet=10,legs=10,body=176,type=129,auxType=0,addons=3,head=48}, text="press ctrl to move icon"}, function(widget, enabled) + if enabled then + info("icon on") + else + info("icon off") + end +end) + +addIcon("mount", {outfit={mount=848,feet=10,legs=10,body=176,type=129,auxType=0,addons=3,head=48}}, function(widget, enabled) + if enabled then + info("icon mount on") + else + info("icon mount off") + end +end) + +addIcon("mount 2", {outfit={mount=849,feet=10,legs=10,body=176,type=140,auxType=0,addons=3,head=48}, switchable=false}, function(widget, enabled) + info("icon mount 2 pressed") +end) + +addIcon("item", {item=3380, hotkey="F6", switchable=false}, function(widget, enabled) + info("icon clicked") +end) + +addIcon("item2", {item={id=3043, count=100}, switchable=true}, function(widget, enabled) + info("icon 2 clicked") +end) + +addIcon("text", {text="text\nonly\nicon", switchable=true}, function(widget, enabled) + info("icon with text clicked") +end) + diff --git a/modules/game_bot/defaultconfig.lua b/modules/game_bot/defaultconfig.lua deleted file mode 100644 index e4efcd5..0000000 --- a/modules/game_bot/defaultconfig.lua +++ /dev/null @@ -1,305 +0,0 @@ -botDefaultConfig = { - configs = { - {name = "Default", script = [=[ ---Default ---IMPORTANT ---In 1st config (default) editions are not saved, just select and edit other config - ---#main - ---#panels - -local healTab = addTab("HP") -local batTab = addTab("Batt") -local caveTab = addTab("Cave") -local toolsTab = addTab("Tools") - -Panels.TradeMessage() -Panels.AutoStackItems() - -addButton("discord", "Discord & Help", function() - g_platform.openUrl("https://discord.gg/yhqBE4A") -end) - -addButton("forum", "Forum", function() - g_platform.openUrl("https://otland.net/forums/otclient.494/") -end) - -addButton("github", "Documentation", function() - g_platform.openUrl("https://github.com/OTCv8/otclientv8_bot") -end) - -addSeparator("sep") - -Panels.Haste(healTab) -Panels.ManaShield(healTab) -Panels.AntiParalyze(healTab) -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(batTab) -Panels.AttackItem(batTab) - -Panels.AttackLeaderTarget(batTab) -Panels.LimitFloor(batTab) -Panels.AntiPush(batTab) - -local waypoints = Panels.Waypoints(caveTab) -local attacking = Panels.Attacking(caveTab) -local looting = Panels.Looting(caveTab) -addButton("tutorial", "Help & Tutorials", function() - g_platform.openUrl("https://github.com/OTCv8/otclientv8_bot") -end, caveTab) - ---#macros - -macro(1000, "exchange money", function() - local containers = getContainers() - for i, container in pairs(containers) do - for j, item in ipairs(container:getItems()) do - if item:isStackable() and (item:getId() == 3035 or item:getId() == 3031) and item:getCount() == 100 then - g_game.use(item) - return - end - end - end -end) - -macro(1000, "this macro does nothing", "f7", function() - -end) - -macro(100, "debug pathfinding", nil, function() - for i, tile in ipairs(g_map.getTiles(posz())) do - tile:setText("") - end - local path = findEveryPath(pos(), 20, { - ignoreNonPathable = false - }) - local total = 0 - for i, p in pairs(path) do - local s = i:split(",") - local pos = {x=tonumber(s[1]), y=tonumber(s[2]), z=tonumber(s[3])} - local tile = g_map.getTile(pos) - if tile then - tile:setText(p[2]) - end - total = total + 1 - end -end) - -macro(1000, "speed hack", nil, function() - player:setSpeed(1000) -end) - - ---#hotkeys - -hotkey("f5", "example hotkey", function() - info("Wow, you clicked f5 hotkey") -end) - -singlehotkey("ctrl+f6", "singlehotkey", function() - info("Wow, you clicked f6 singlehotkey") - usewith(268, player) -end) - -singlehotkey("ctrl+f8", "play alarm", function() - playAlarm() -end) - -singlehotkey("ctrl+f9", "stop alarm", function() - stopSound() -end) - ---#callbacks - -local positionLabel = addLabel("positionLabel", "") -onPlayerPositionChange(function() - positionLabel:setText("Pos: " .. posx() .. "," .. posy() .. "," .. posz()) -end) - -local s = addSwitch("sdSound", "Play sound when using sd", function(widget) - storage.sdSound = not storage.sdSound - widget:setOn(storage.sdSound) -end) -s:setOn(storage.sdSound) - -onUseWith(function(pos, itemId) - if storage.sdSound and itemId == 3155 then - playSound("/sounds/magnum.ogg") - end -end) - ---#other - -macro(100, "hide useless tiles", "", function() - for i, tile in ipairs(g_map.getTiles(posz())) do - if not tile:isWalkable(true) then - tile:setFill('black') - end - end -end) - -addLabel("mapinfo", "You can use ctrl + plus and ctrl + minus to zoom in / zoom out map") - -]=]}, - {name = "UI & Healing", script = [=[ --- UI & healing -info("Tested on 10.99") - ---#main -local healthPanel = setupUI([[ -Panel - id: healingPanel - height: 150 - margin-top: 3 - - Label - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - text: Use item if - text-align: center - - BotItem - id: item1 - anchors.left: parent.left - anchors.top: prev.bottom - - Label - id: label1 - 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: prev.left - anchors.right: prev.right - anchors.top: prev.bottom - margin-top: 5 - minimum: 0 - maximum: 100 - step: 1 - - BotItem - id: item2 - anchors.left: parent.left - anchors.top: item1.bottom - margin-top: 3 - - Label - id: label2 - anchors.left: prev.right - anchors.right: parent.right - anchors.top: prev.top - margin: 0 5 0 5 - text-align: center - - HorizontalScrollBar - id: scroll2 - anchors.left: label2.left - anchors.right: label2.horizontalCenter - anchors.top: label2.bottom - margin-top: 5 - minimum: 0 - maximum: 100 - step: 1 - - HorizontalScrollBar - id: scroll3 - anchors.left: label2.horizontalCenter - anchors.right: label2.right - anchors.top: label2.bottom - margin-top: 5 - minimum: 0 - maximum: 100 - step: 1 - - Label - anchors.top: item2.bottom - anchors.left: parent.left - anchors.right: parent.right - margin-top: 3 - text: Drag item to change it - text-align: center - - HorizontalSeparator - anchors.top: prev.bottom - anchors.left: parent.left - anchors.right: parent.right - margin-top: 3 -]]) - -healthPanel.item1:setItemId(storage.healItem1 or 266) -healthPanel.item1.onItemChange = function(widget, item) - storage.healItem1 = item:getId() - widget:setItemId(storage.healItem1) -end - -healthPanel.item2:setItemId(storage.healItem2 or 268) -healthPanel.item2.onItemChange = function(widget, item) - storage.healItem2 = item:getId() - widget:setItemId(storage.healItem2) -end - -healthPanel.scroll1.onValueChange = function(scroll, value) - storage.healPercent1 = value - healthPanel.label1:setText("0% <= hp <= " .. storage.healPercent1 .. "%") -end -healthPanel.scroll1:setValue(storage.healPercent1 or 50) - -healthPanel.scroll2.onValueChange = function(scroll, value) - storage.healPercent2 = value - healthPanel.label2:setText("" .. storage.healPercent2 .. "% <= mana <= " .. storage.healPercent3 .. "%") -end -healthPanel.scroll3.onValueChange = function(scroll, value) - storage.healPercent3 = value - healthPanel.label2:setText("" .. storage.healPercent2 .. "% <= mana <= " .. storage.healPercent3 .. "%") -end -healthPanel.scroll2:setValue(storage.healPercent2 or 40) -healthPanel.scroll3:setValue(storage.healPercent3 or 60) - -macro(25, function() - if not storage.healItem1 then - return - end - if healthPanel.scroll1:getValue() >= hppercent() then - useWith(storage.healItem1, player) - delay(500) - end -end) -macro(25, function() - if not storage.healItem2 then - return - end - if storage.healPercent2 <= manapercent() and manapercent() <= storage.healPercent3 then - useWith(storage.healItem2, player) - delay(500) - end -end) - ---#macros - ---#hotkeys - ---#callbacks - ---#other -]=]}, - {}, {}, {}, {} - }, - enabled = false, - selectedConfig = 1 -} \ No newline at end of file diff --git a/modules/game_bot/edit.otui b/modules/game_bot/edit.otui index ed5bc86..07de46f 100644 --- a/modules/game_bot/edit.otui +++ b/modules/game_bot/edit.otui @@ -82,34 +82,42 @@ MainWindow !text: tr("To reload configs just press On and Off in bot window.\nTo learn more about bot click Tutorials button.") Button - !text: tr('Tutorials') + !text: tr('Documentation') anchors.bottom: parent.bottom anchors.left: parent.left - width: 100 + width: 118 + @onClick: g_platform.openUrl("http://otclient.ovh/bot.php?documentation") + + Button + !text: tr('Tutorials') + anchors.bottom: parent.bottom + anchors.left: prev.right + margin-left: 5 + width: 80 @onClick: g_platform.openUrl("http://otclient.ovh/bot.php?tutorials") Button !text: tr('Scripts') anchors.bottom: parent.bottom anchors.left: prev.right - margin-left: 10 - width: 100 + margin-left: 5 + width: 80 @onClick: g_platform.openUrl("http://otclient.ovh/bot.php?scripts") Button !text: tr('Forum') anchors.bottom: parent.bottom anchors.left: prev.right - margin-left: 10 - width: 100 + margin-left: 5 + width: 80 @onClick: g_platform.openUrl("http://otclient.ovh/bot.php?forum") Button !text: tr('Discord') anchors.bottom: parent.bottom anchors.left: prev.right - margin-left: 10 - width: 100 + margin-left: 5 + width: 80 @onClick: g_platform.openUrl("http://otclient.ovh/bot.php?discord") Button diff --git a/modules/game_bot/executor.lua b/modules/game_bot/executor.lua index 1cb7593..eb58fc6 100644 --- a/modules/game_bot/executor.lua +++ b/modules/game_bot/executor.lua @@ -30,7 +30,7 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, webs context.storage._macros = {} -- active macros end - -- macros, hotkeys, scheduler, callbacks + -- macros, hotkeys, scheduler, icons, callbacks context._macros = {} context._hotkeys = {} context._scheduler = {} @@ -123,9 +123,9 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, webs context.time = g_clock.millis() 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 macro.lastExecution + macro.timeout <= context.now and (macro.name == nil or macro.name:len() < 1 or macro.enabled) then local status, result = pcall(function() - if macro.callback() then + if macro.callback(macro) then macro.lastExecution = context.now end end) diff --git a/modules/game_bot/functions.lua b/modules/game_bot/functions.lua deleted file mode 100644 index 3031ca2..0000000 --- a/modules/game_bot/functions.lua +++ /dev/null @@ -1,123 +0,0 @@ --- In this file are declared extra functions and variables for bot --- It has been made to make most common functions shorter, for eg. hp() instead of player:getHealth() - -function setupFunctions(context) - -- player releated - 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 - - -- game releated - context.say = g_game.talk - context.talk = g_game.talk - 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 - - -- map releated - 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 - - -- tools - 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 -end \ No newline at end of file diff --git a/modules/game_bot/functions/callbacks.lua b/modules/game_bot/functions/callbacks.lua index ab4b87d..60386fc 100644 --- a/modules/game_bot/functions/callbacks.lua +++ b/modules/game_bot/functions/callbacks.lua @@ -8,12 +8,24 @@ context.callback = function(callbackType, callback) if callbackType == "onAddThing" or callbackType == "onRemoveThing" then g_game.enableTileThingLuaCallback(true) end + + local desc = "lua" + local info = debug.getinfo(2, "Sl") + if info then + desc = info.short_src .. ":" .. info.currentline + end + local callbackData = {} table.insert(context._callbacks[callbackType], function(...) if not callbackData.delay or callbackData.delay < context.now then local prevExecution = context._currentExecution context._currentExecution = callbackData + local start = g_clock.realMillis() callback(...) + local executionTime = g_clock.realMillis() - start + if executionTime > 100 then + context.warning("Slow " .. callbackType .. " (" .. executionTime .. "ms): " .. desc) + end context._currentExecution = prevExecution end end) diff --git a/modules/game_bot/functions/icon.lua b/modules/game_bot/functions/icon.lua new file mode 100644 index 0000000..2cf957f --- /dev/null +++ b/modules/game_bot/functions/icon.lua @@ -0,0 +1,174 @@ +local context = G.botContext + +local iconsWithoutPosition = 0 + +context.addIcon = function(id, options, callback) +--[[ + Available options: + item: {id=2160, count=100} + outfit: outfit table ({}) + text: string + x: float (0.0 - 1.0) + y: float (0.0 - 1.0) + width: number + height: number + hotkey: string + switchable: true / false [default: true] + movable: true / false [default: true] + phantom: true / false [defaule: false] +]]-- + local panel = modules.game_interface.gameMapPanel + if type(id) ~= "string" or id:len() < 1 then + return context.error("Invalid id for addIcon") + end + if options.switchable == false and type(callback) ~= 'function' then + return context.error("Invalid callback for addIcon") + end + if type(context.storage._icons) ~= "table" then + context.storage._icons = {} + end + if type(context.storage._icons[id]) ~= "table" then + context.storage._icons[id] = {} + end + local config = context.storage._icons[id] + local widget = g_ui.createWidget("BotIcon", panel) + widget.botWidget = true + + if type(config.x) ~= 'number' and type(config.y) ~= 'number' then + if type(options.x) == 'number' and type(options.y) == 'number' then + config.x = math.min(1.0, math.max(0.0, options.x)) + config.y = math.min(1.0, math.max(0.0, options.y)) + else + config.x = 0.01 + math.floor(iconsWithoutPosition / 5) / 10 + config.y = 0.05 + (iconsWithoutPosition % 5) / 5 + iconsWithoutPosition = iconsWithoutPosition + 1 + end + end + + if options.item then + if type(options.item) == 'number' then + widget.item:setItemId(options.item) + else + widget.item:setItemId(options.item.id) + widget.item:setItemCount(options.item.count or 1) + widget.item:setShowCount(false) + end + end + + if options.outfit then + widget.creature:setOutfit(options.outfit) + end + + if options.switchable == false then + widget.status:hide() + widget.status:setOn(true) + else + widget.status:setOn(config.enabled) + end + + if options.text then + if options.switchable ~= false then + widget.status:hide() + if widget.status:isOn() then + widget.text:setColor('green') + else + widget.text:setColor('red') + end + end + widget.text:setText(options.text) + end + + widget.setOn = function(val) + widget.status:setOn(val) + if widget.status:isOn() then + widget.text:setColor('green') + else + widget.text:setColor('red') + end + config.enabled = widget.status:isOn() + end + + widget.onClick = function(widget) + if options.switchable ~= false then + widget.setOn(not widget.status:isOn()) + if type(callback) == 'table' then + callback.setOn(config.enabled) + return + end + end + + callback(widget, widget.status:isOn()) + end + + if options.hotkey then + widget.hotkey:setText(options.hotkey) + context.hotkey(options.hotkey, "", function() + widget:onClick() + end, nil, options.switchable ~= false) + else + widget.hotkey:hide() + end + + if options.movable ~= false then + widget.onDragEnter = function(widget, mousePos) + if not g_keyboard.isCtrlPressed() then + return false + end + widget:breakAnchors() + widget.movingReference = { x = mousePos.x - widget:getX(), y = mousePos.y - widget:getY() } + return true + end + + widget.onDragMove = function(widget, mousePos, moved) + local parentRect = widget:getParent():getRect() + local x = math.min(math.max(parentRect.x, mousePos.x - widget.movingReference.x), parentRect.x + parentRect.width - widget:getWidth()) + local y = math.min(math.max(parentRect.y, mousePos.y - widget.movingReference.y), parentRect.y + parentRect.height - widget:getHeight()) + widget:move(x, y) + return true + end + + widget.onDragLeave = function(widget, pos) + local parent = widget:getParent() + local parentRect = parent:getRect() + local x = widget:getX() - parentRect.x + local y = widget:getY() - parentRect.y + local width = parentRect.width - widget:getWidth() + local height = parentRect.height - widget:getHeight() + + config.x = math.min(1, math.max(0, x / width)) + config.y = math.min(1, math.max(0, y / height)) + widget:addAnchor(AnchorHorizontalCenter, 'parent', AnchorHorizontalCenter) + widget:addAnchor(AnchorVerticalCenter, 'parent', AnchorVerticalCenter) + + widget:setMarginTop(height * (-0.5 + config.x)) + widget:setMarginLeft(width * (-0.5 + config.y)) + return true + end + end + + widget.onGeometryChange = function(widget, oldRect, newRect) + if widget:isDragging() then return end + local parent = widget:getParent() + local parentRect = parent:getRect() + local width = parentRect.width - widget:getWidth() + local height = parentRect.height - widget:getHeight() + widget:setMarginTop(height * (-0.5 + config.y)) + widget:setMarginLeft(width * (-0.5 + config.x)) + end + + if options.phantom ~= true then + widget.onMouseRelease = function() + return true + end + end + + if options.switchable ~= false then + if type(callback) == 'table' then + callback.setOn(config.enabled) + callback.icon = widget + else + callback(widget, widget.status:isOn()) + end + end + return widget +end \ No newline at end of file diff --git a/modules/game_bot/functions/main.lua b/modules/game_bot/functions/main.lua index 54873e0..aaaa415 100644 --- a/modules/game_bot/functions/main.lua +++ b/modules/game_bot/functions/main.lua @@ -34,33 +34,89 @@ context.macro = function(timeout, name, hotkey, callback, parent) hotkey = retranslateKeyComboDesc(hotkey) end - local switch = nil - if name:len() > 0 then - if context.storage._macros[name] == nil then - context.storage._macros[name] = false + table.insert(context._macros, { + enabled = false, + name = name, + timeout = timeout, + lastExecution = context.now, + hotkey = hotkey, + }) + local macro = context._macros[#context._macros] + + macro.isOn = function() + return macro.enabled + end + macro.isOff = function() + return not macro.enabled + end + macro.toggle = function(widget) + if macro.isOn() then + macro.setOff() + else + macro.setOn() end - switch = context._addMacroSwitch(name, hotkey, parent) + end + macro.setOn = function(val) + if val == false then + return macro.setOff() + end + macro.enabled = true + context.storage._macros[name] = true + if macro.switch then + macro.switch:setOn(true) + end + if macro.icon then + macro.icon.setOn(true) + end + end + macro.setOff = function(val) + if val == false then + return macro.setOn() + end + macro.enabled = false + context.storage._macros[name] = false + if macro.switch then + macro.switch:setOn(false) + end + if macro.icon then + macro.icon.setOn(false) + end + end + + if name:len() > 0 then + -- creature switch + local text = name + if hotkey:len() > 0 then + text = name .. " [" .. hotkey .. "]" + end + macro.switch = context.addSwitch("macro_" .. (#context._macros + 1), text, macro.toggle, parent) + + -- load state + if context.storage._macros[name] == true then + macro.setOn() + end + end + + local desc = "lua" + local info = debug.getinfo(2, "Sl") + if info then + desc = info.short_src .. ":" .. info.currentline 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() + macro.callback = function(macro) + if not macro.delay or macro.delay < context.now then + context._currentExecution = macro + local start = g_clock.realMillis() + callback(macro) + local executionTime = g_clock.realMillis() - start + if executionTime > 100 then + context.warning("Slow macro (" .. executionTime .. "ms): " .. macro.name .. " - " .. desc) + end context._currentExecution = nil return true end end - - return macroData + return macro end -- hotkey(keys, callback) @@ -94,11 +150,22 @@ context.hotkey = function(keys, name, callback, parent, single) single = single } + local desc = "lua" + local info = debug.getinfo(2, "Sl") + if info then + desc = info.short_src .. ":" .. info.currentline + end + local hotkeyData = context._hotkeys[keys] hotkeyData.callback = function() if not hotkeyData.delay or hotkeyData.delay < context.now then context._currentExecution = hotkeyData + local start = g_clock.realMillis() callback() + local executionTime = g_clock.realMillis() - start + if executionTime > 100 then + context.warning("Slow hotkey (" .. executionTime .. "ms): " .. hotkeyData.name .. " - " .. desc) + end context._currentExecution = nil return true end diff --git a/modules/game_bot/functions/map.lua b/modules/game_bot/functions/map.lua index c6ade18..eddd98a 100644 --- a/modules/game_bot/functions/map.lua +++ b/modules/game_bot/functions/map.lua @@ -132,7 +132,6 @@ context.findPath = function(startPos, destPos, maxDist, params) local destPosStr = destPos.x .. "," .. destPos.y .. "," .. destPos.z params["destination"] = destPosStr local paths = context.findAllPaths(startPos, maxDist, params) - local marginMin = params.marginMin or params.minMargin local marginMax = params.marginMax or params.maxMargin if type(marginMin) == 'number' and type(marginMax) == 'number' then @@ -143,6 +142,7 @@ context.findPath = function(startPos, destPos, maxDist, params) if math.abs(x) >= marginMin or math.abs(y) >= marginMin then local dest = (destPos.x + x) .. "," .. (destPos.y + y) .. "," .. destPos.z local node = paths[dest] + print(node) if node and (not bestCandidate or bestCandidate[1] > node[1]) then bestCandidate = node bestCandidatePos = dest @@ -195,3 +195,7 @@ context.autoWalk = function(destination, maxDist, params) return true end +context.getTileUnderCursor = function() + if not modules.game_interface.gameMapPanel.mousePos then return end + return modules.game_interface.gameMapPanel:getTile(modules.game_interface.gameMapPanel.mousePos) +end \ No newline at end of file diff --git a/modules/game_bot/functions/server.lua b/modules/game_bot/functions/server.lua index 5174e4e..5fc733f 100644 --- a/modules/game_bot/functions/server.lua +++ b/modules/game_bot/functions/server.lua @@ -3,6 +3,7 @@ local context = G.botContext context.BotServer = {} context.BotServer.url = "ws://bot.otclient.ovh:8000/" context.BotServer.timeout = 3 +context.BotServer.ping = 0 context.BotServer._callbacks = {} context.BotServer._lastMessageId = 0 context.BotServer._wasConnected = true -- show first warning @@ -24,6 +25,7 @@ context.BotServer.init = function(name, channel) end context.BotServer._wasConnected = true if message["type"] == "ping" then + context.BotServer.ping = message["ping"] return context.BotServer._websocket.send({type="ping"}) end if message["type"] == "message" then diff --git a/modules/game_bot/panels/looting.lua b/modules/game_bot/panels/looting.lua index 1ac745b..e665bb0 100644 --- a/modules/game_bot/panels/looting.lua +++ b/modules/game_bot/panels/looting.lua @@ -59,7 +59,7 @@ Panel anchors.right: parent.right anchors.left: parent.left vertical-scrollbar: scrollBar - margin-right: 10 + margin-right: 5 margin-top: 2 height: 70 layout: @@ -67,7 +67,7 @@ Panel cell-size: 34 34 flow: true - VerticalScrollBar + BotSmallScrollBar id: scrollBar anchors.top: prev.top anchors.bottom: prev.bottom diff --git a/modules/game_bot/ui/basic.otui b/modules/game_bot/ui/basic.otui index cc0a05d..04edb22 100644 --- a/modules/game_bot/ui/basic.otui +++ b/modules/game_bot/ui/basic.otui @@ -38,6 +38,67 @@ BotSeparator < HorizontalSeparator margin-top: 5 margin-bottom: 3 +BotSmallScrollBar < UIScrollBar + orientation: vertical + margin-bottom: 1 + step: 20 + width: 8 + image-source: /images/ui/scrollbar + image-clip: 39 0 13 65 + image-border: 1 + pixels-scroll: true + + UIButton + id: decrementButton + anchors.top: parent.top + anchors.left: parent.left + image-source: /images/ui/scrollbar + image-clip: 0 0 13 13 + image-color: #ffffffff + size: 8 8 + $hover: + image-clip: 13 0 13 13 + $pressed: + image-clip: 26 0 13 13 + $disabled: + image-color: #ffffff66 + + UIButton + id: incrementButton + anchors.bottom: parent.bottom + anchors.right: parent.right + size: 8 8 + image-source: /images/ui/scrollbar + image-clip: 0 13 13 13 + image-color: #ffffffff + $hover: + image-clip: 13 13 13 13 + $pressed: + image-clip: 26 13 13 13 + $disabled: + image-color: #ffffff66 + + UIButton + id: sliderButton + anchors.centerIn: parent + size: 8 11 + image-source: /images/ui/scrollbar + image-clip: 0 26 13 13 + image-border: 2 + image-color: #ffffffff + $hover: + image-clip: 13 26 13 13 + $pressed: + image-clip: 26 26 13 13 + $disabled: + image-color: #ffffff66 + + Label + id: valueLabel + anchors.fill: parent + color: white + text-align: center + BotPanel < Panel ScrollablePanel id: content @@ -49,70 +110,11 @@ BotPanel < Panel layout: type: verticalBox - UIScrollBar + BotSmallScrollBar id: botPanelScroll - orientation: vertical anchors.top: parent.top anchors.bottom: parent.bottom anchors.right: parent.right - margin-bottom: 1 - step: 20 - width: 8 - image-source: /images/ui/scrollbar - image-clip: 39 0 13 65 - image-border: 1 - pixels-scroll: true - - UIButton - id: decrementButton - anchors.top: parent.top - anchors.left: parent.left - image-source: /images/ui/scrollbar - image-clip: 0 0 13 13 - image-color: #ffffffff - size: 8 8 - $hover: - image-clip: 13 0 13 13 - $pressed: - image-clip: 26 0 13 13 - $disabled: - image-color: #ffffff66 - - UIButton - id: incrementButton - anchors.bottom: parent.bottom - anchors.right: parent.right - size: 8 8 - image-source: /images/ui/scrollbar - image-clip: 0 13 13 13 - image-color: #ffffffff - $hover: - image-clip: 13 13 13 13 - $pressed: - image-clip: 26 13 13 13 - $disabled: - image-color: #ffffff66 - - UIButton - id: sliderButton - anchors.centerIn: parent - size: 8 11 - image-source: /images/ui/scrollbar - image-clip: 0 26 13 13 - image-border: 2 - image-color: #ffffffff - $hover: - image-clip: 13 26 13 13 - $pressed: - image-clip: 26 26 13 13 - $disabled: - image-color: #ffffff66 - - Label - id: valueLabel - anchors.fill: parent - color: white - text-align: center CaveBotLabel < Label background-color: alpha diff --git a/modules/game_bot/ui/botitemcontainer.lua b/modules/game_bot/ui/botitemcontainer.lua deleted file mode 100644 index e69de29..0000000 diff --git a/modules/game_bot/ui/botwaypoints.lua b/modules/game_bot/ui/botwaypoints.lua deleted file mode 100644 index e69de29..0000000 diff --git a/modules/game_bot/ui/icons.otui b/modules/game_bot/ui/icons.otui new file mode 100644 index 0000000..5de4524 --- /dev/null +++ b/modules/game_bot/ui/icons.otui @@ -0,0 +1,60 @@ +BotIcon < UIWidget + size: 50 50 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + focusable: false + phantom: false + draggable: true + + UIItem + id: item + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + margin-top: 6 + virtual: true + phantom: true + size: 32 32 + + UICreature + id: creature + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + margin-top: 0 + size: 48 48 + phantom: true + + UIWidget + id: status + anchors.top: parent.top + anchors.left: parent.left + size: 18 10 + color: black + font: terminus-10px + phantom: true + + $on: + text: ON + background: green + + $!on: + text: OFF + background: red + + UIWidget + id: hotkey + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + size: 18 10 + color: white + phantom: true + text-align: right + + UIWidget + id: text + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + text-wrap: true + text-auto-resize: true + phantom: true diff --git a/modules/game_features/features.lua b/modules/game_features/features.lua index 94392e3..088fdb7 100644 --- a/modules/game_features/features.lua +++ b/modules/game_features/features.lua @@ -11,6 +11,7 @@ function updateFeatures(version) -- you can add custom features here, list of them is in the modules\gamelib\const.lua g_game.enableFeature(GameBot) + g_game.enableFeature(GameExtendedOpcode) --g_game.enableFeature(GameMinimapLimitedToSingleFloor) -- it will generate minimap only for current floor --g_game.enableFeature(GameSpritesAlphaChannel) diff --git a/modules/game_interface/widgets/uigamemap.lua b/modules/game_interface/widgets/uigamemap.lua index 221ec83..c91175d 100644 --- a/modules/game_interface/widgets/uigamemap.lua +++ b/modules/game_interface/widgets/uigamemap.lua @@ -112,7 +112,6 @@ function UIGameMap:onMouseRelease(mousePosition, mouseButton) if not self.allowNextRelease and not self.markingMouseRelease then return true end - local autoWalkPos = self:getPosition(mousePosition) local positionOffset = self:getPositionOffset(mousePosition) diff --git a/modules/game_interface/widgets/uiitem.lua b/modules/game_interface/widgets/uiitem.lua deleted file mode 100644 index c9f3db8..0000000 --- a/modules/game_interface/widgets/uiitem.lua +++ /dev/null @@ -1,118 +0,0 @@ -function UIItem:onDragEnter(mousePos) - if self:isVirtual() then return false end - - local item = self:getItem() - if not item then return false end - - self:setBorderWidth(1) - self.currentDragThing = item - g_mouse.pushCursor('target') - return true -end - -function UIItem:onDragLeave(droppedWidget, mousePos) - if self:isVirtual() then return false end - self.currentDragThing = nil - g_mouse.popCursor('target') - self:setBorderWidth(0) - self.hoveredWho = nil - return true -end - -function UIItem:onDrop(widget, mousePos, forced) - if not self:canAcceptDrop(widget, mousePos) and not forced then return false end - - local item = widget.currentDragThing - if not item or not item:isItem() then return false end - - if self.selectable then - if self.onItemChange then - self.onItemChange(self, item) - end - return - end - - local toPos = self.position - - local itemPos = item:getPosition() - if itemPos.x == toPos.x and itemPos.y == toPos.y and itemPos.z == toPos.z then return false end - - if item:getCount() > 1 then - modules.game_interface.moveStackableItem(item, toPos) - else - g_game.move(item, toPos, 1) - end - - self:setBorderWidth(0) - return true -end - -function UIItem:onDestroy() - if self == g_ui.getDraggingWidget() and self.hoveredWho then - self.hoveredWho:setBorderWidth(0) - end - - if self.hoveredWho then - self.hoveredWho = nil - end -end - -function UIItem:onHoverChange(hovered) - UIWidget.onHoverChange(self, hovered) - - if self:isVirtual() or not self:isDraggable() then return end - - local draggingWidget = g_ui.getDraggingWidget() - if draggingWidget and self ~= draggingWidget then - local gotMap = draggingWidget:getClassName() == 'UIGameMap' - local gotItem = draggingWidget:getClassName() == 'UIItem' and not draggingWidget:isVirtual() - if hovered and (gotItem or gotMap) then - self:setBorderWidth(1) - draggingWidget.hoveredWho = self - else - self:setBorderWidth(0) - draggingWidget.hoveredWho = nil - end - end -end - -function UIItem:onMouseRelease(mousePosition, mouseButton) - if self.cancelNextRelease then - self.cancelNextRelease = false - return true - end - - if self:isVirtual() then return false end - - local item = self:getItem() - if not item or not self:containsPoint(mousePosition) then return false end - - if modules.client_options.getOption('classicControl') and - ((g_mouse.isPressed(MouseLeftButton) and mouseButton == MouseRightButton) or - (g_mouse.isPressed(MouseRightButton) and mouseButton == MouseLeftButton)) then - g_game.look(item) - self.cancelNextRelease = true - return true - elseif modules.game_interface.processMouseAction(mousePosition, mouseButton, nil, item, item, nil, nil) then - return true - end - return false -end - -function UIItem:canAcceptDrop(widget, mousePos) - if not self.selectable and (self:isVirtual() or not self:isDraggable()) then return false end - if not widget or not widget.currentDragThing then return false end - - local children = rootWidget:recursiveGetChildrenByPos(mousePos) - for i=1,#children do - local child = children[i] - if child == self then - return true - elseif not child:isPhantom() then - return false - end - end - - error('Widget ' .. self:getId() .. ' not in drop list.') - return false -end diff --git a/modules/game_shop/shop.lua b/modules/game_shop/shop.lua index dd2589d..1d9b39e 100644 --- a/modules/game_shop/shop.lua +++ b/modules/game_shop/shop.lua @@ -26,7 +26,6 @@ end -- public functions function init() connect(g_game, { onGameStart = check, onGameEnd = hide }) - ProtocolGame.registerExtendedJSONOpcode(SHOP_EXTENTED_OPCODE, onExtendedJSONOpcode) if g_game.isOnline() then diff --git a/modules/game_walking/walking.lua b/modules/game_walking/walking.lua index 762254c..dd1c869 100644 --- a/modules/game_walking/walking.lua +++ b/modules/game_walking/walking.lua @@ -266,38 +266,44 @@ function walk(dir) g_game.cancelFollow() end - if player:isAutoWalking() or player:isServerWalking() then + if player:isAutoWalking() then if lastStop + 100 < g_clock.millis() then lastStop = g_clock.millis() - if player:isAutoWalking() then - player:stopAutoWalk() - end + player:stopAutoWalk() g_game.stop() end - return end if player:isWalkLocked() then nextWalkDir = nil return end - + + local dash = false + local ignoredCanWalk = false + if not g_game.getFeature(GameNewWalking) then + dash = g_settings.getBoolean("dash", true) + end + local ticksToNextWalk = player:getStepTicksLeft() if not player:canWalk(dir) then -- canWalk return false when previous walk is not finished or not confirmed by server - if ticksToNextWalk < 500 and lastWalkDir ~= dir then - nextWalkDir = dir + if dash then + ignoredCanWalk = true + else + if ticksToNextWalk < 500 and lastWalkDir ~= dir then + nextWalkDir = dir + end + if ticksToNextWalk < 30 and lastFinishedStep + 400 > g_clock.millis() and nextWalkDir == nil then -- clicked walk 20 ms too early, try to execute again as soon possible to keep smooth walking + nextWalkDir = dir + end + return end - if ticksToNextWalk < 30 and lastFinishedStep + 400 > g_clock.millis() and nextWalkDir == nil then -- clicked walk 20 ms too early, try to execute again as soon possible to keep smooth walking - nextWalkDir = dir - end - return end --if nextWalkDir ~= nil and lastFinishedStep + 200 < g_clock.millis() then -- print("Cancel " .. nextWalkDir) -- nextWalkDir = nil --end - if nextWalkDir ~= nil and nextWalkDir ~= lastWalkDir then dir = nextWalkDir end @@ -336,25 +342,34 @@ function walk(dir) walkLock = lastWalk + g_settings.getNumber('walkFirstStepDelay') return end + + if dash and lastWalkDir == dir and lastWalk + 30 > g_clock.millis() then + walkLock = lastWalk + g_settings.getNumber('walkFirstStepDelay') + return + end - firstStep = not player:isWalking() and lastFinishedStep + 100 < g_clock.millis() and walkLock + 100 < g_clock.millis() + firstStep = (not player:isWalking() and lastFinishedStep + 100 < g_clock.millis() and walkLock + 100 < g_clock.millis()) or (player:isServerWalking() and not dash) nextWalkDir = nil removeEvent(autoWalkEvent) autoWalkEvent = nil - local preWalked = false if toTile and toTile:isWalkable() then - player:preWalk(dir) - preWalked = true + if not player:isServerWalking() and not ignoredCanWalk then + player:preWalk(dir) + preWalked = true + end else local playerTile = player:getTile() if (playerTile and playerTile:hasElevation(3) and canChangeFloorUp(toPos)) or canChangeFloorDown(toPos) or (toTile and toTile:isEmpty() and not toTile:isBlocking()) then player:lockWalk(100) + elseif player:isServerWalking() then + g_game.stop() + return else return end end - + g_game.walk(dir, preWalked) if not firstStep and lastWalkDir ~= dir then diff --git a/modules/game_walking/walking.otmod b/modules/game_walking/walking.otmod index d722695..9e4d991 100644 --- a/modules/game_walking/walking.otmod +++ b/modules/game_walking/walking.otmod @@ -4,5 +4,6 @@ Module author: otclient.ovh website: http://otclient.ovh scripts: [ walking ] + dependencies: [ game_interface ] @onLoad: init() @onUnload: terminate() diff --git a/otclient_dx.exe b/otclient_dx.exe index e48ab1f..73b5430 100644 Binary files a/otclient_dx.exe and b/otclient_dx.exe differ diff --git a/otclient_gl.exe b/otclient_gl.exe index f285c66..afd50aa 100644 Binary files a/otclient_gl.exe and b/otclient_gl.exe differ diff --git a/otclient_linux b/otclient_linux index accdce1..a70e360 100644 Binary files a/otclient_linux and b/otclient_linux differ diff --git a/pdb/otclient_dx.zip b/pdb/otclient_dx.zip index 888a45a..96a153b 100644 Binary files a/pdb/otclient_dx.zip and b/pdb/otclient_dx.zip differ diff --git a/pdb/otclient_gl.zip b/pdb/otclient_gl.zip index 07d3304..cd6692a 100644 Binary files a/pdb/otclient_gl.zip and b/pdb/otclient_gl.zip differ