Skip to content

Commit

Permalink
Better walking
Browse files Browse the repository at this point in the history
  • Loading branch information
nekiro committed Jan 10, 2025
1 parent aa7f8dc commit e9caf7e
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 178 deletions.
35 changes: 18 additions & 17 deletions modules/client_options/data_options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -150,27 +150,28 @@ return {
g_app.setDrawTexts(value)
end
},
walkFirstStepDelay = {
walkTurnDelay = {
value = 250,
action = function(value, options, controller, panels, extraWidgets)
panels.generalPanel:recursiveGetChildById('walkFirstStepDelay'):setText(string.format(
'Walk Delay after first step: %sms', value))
g_game.setWalkFirstStepDelay(value)
panels.generalPanel:recursiveGetChildById('walkTurnDelay'):setText(string.format(
'Walk delay after turn: %sms',
value))
end
},
walkTurnDelay = {
value = 100,
walkTeleportDelay = {
value = 250,
action = function(value, options, controller, panels, extraWidgets)
panels.generalPanel:recursiveGetChildById('walkTurnDelay'):setText(string.format(
'Walk delay after turn: %sms',
panels.generalPanel:recursiveGetChildById('walkTeleportDelay'):setText(string.format(
'Walk delay after teleport: %sms',
value))
g_game.setWalkTurnDelay(value)
end
},
turnDelay = {
value = 50,
walkStairsDelay = {
value = 250,
action = function(value, options, controller, panels, extraWidgets)
panels.generalPanel:recursiveGetChildById('turnDelay'):setText(string.format('Turn delay: %sms', value))
panels.generalPanel:recursiveGetChildById('walkStairsDelay'):setText(string.format(
'Walk delay after floor change: %sms',
value))
end
},
hotkeyDelay = {
Expand Down Expand Up @@ -418,7 +419,7 @@ return {
end
end
},
showExpiryInInvetory = {
showExpiryInInvetory = {
value = true,
event = nil,
action = function(value, options, controller, panels, extraWidgets)
Expand All @@ -431,7 +432,7 @@ return {
end, 100)
end
},
showExpiryInContainers = {
showExpiryInContainers = {
value = true,
event = nil,
action = function(value, options, controller, panels, extraWidgets)
Expand Down Expand Up @@ -463,10 +464,10 @@ return {
end, 100)
end
},
autoSwitchPreset = false,
listKeybindsPanel = {
autoSwitchPreset = false,
listKeybindsPanel = {
action = function(value, options, controller, panels, extraWidgets)
listKeybindsComboBox(value)
end
},
}
}
28 changes: 14 additions & 14 deletions modules/client_options/styles/controls/general.otui
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ UIWidget
height: 22

OptionScaleScroll
id: walkFirstStepDelay
!text: tr('Walk Delay after first step: 50ms')
id: walkTurnDelay
!text: tr('Walk delay after turn: 50ms')
anchors.fill: parent
&minimumScrollValue: 50
&minimumScrollValue: 10
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('walkFirstStepDelay')
self:setText(tr('Walk Delay after first step: %dms', value))
local value = modules.client_options.getOption('walkTurnDelay')
self:setText(tr('Walk delay after turn: %dms', value))

SmallReversedQtPanel
anchors.left: parent.left
Expand All @@ -132,14 +132,14 @@ UIWidget
height: 22

OptionScaleScroll
id: walkTurnDelay
!text: tr('Walk delay after turn: 50ms')
id: walkTeleportDelay
!text: tr('Walk delay after teleport: 200ms')
anchors.fill: parent
&minimumScrollValue: 50
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('walkTurnDelay')
local value = modules.client_options.getOption('walkTeleportDelay')
self:setText(tr('Walk delay after turn: %dms', value))

SmallReversedQtPanel
Expand All @@ -150,15 +150,15 @@ UIWidget
height: 22

OptionScaleScroll
id: turnDelay
!text: tr('Turn delay: 30ms')
id: walkStairsDelay
!text: tr('Walk delay after floor change: 200ms')
anchors.fill: parent
&minimumScrollValue: 30
&maximumScrollValue: 250
&minimumScrollValue: 50
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('turnDelay')
self:setText(tr('Turn delay: %dms', value))
local value = modules.client_options.getOption('walkStairsDelay')
self:setText(tr('Walk delay after turn: %dms', value))

QtButton
id: hotkeysButton
Expand Down
200 changes: 154 additions & 46 deletions modules/game_walk/walk.lua
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
local WALK_STEPS_RETRY = 10

local firstStep = false
local smartWalkDirs = {}
local smartWalkDir = nil
local lastDirTime = g_clock.millis()
local lastManualWalk = 0
local walkEvent = nil
local lastTurn = 0

function init()
connect(g_game, {
onGameStart = onGameStart,
}, true)
onTeleport = onTeleport,
})
connect(LocalPlayer, {
onWalk = onWalk,
onCancelWalk = onCancelWalk
})

bindKeys()
end

function terminate()
disconnect(g_game, {
onGameStart = onGameStart,
onTeleport = onTeleport,
})
disconnect(LocalPlayer, {
onWalk = onWalk,
})

stopSmartWalk()
Expand All @@ -25,8 +31,8 @@ end
function onGameStart()
modules.game_interface.getRootPanel().onFocusChange = stopSmartWalk

modules.game_joystick.addOnJoystickMoveListener(function(dir, firstStep)
g_game.walk(dir, firstStep)
modules.game_joystick.addOnJoystickMoveListener(function(dir)
g_game.walk(dir)
end)

-- open tibia has delay in auto walking
Expand Down Expand Up @@ -64,62 +70,55 @@ function bindKeys()
end

function bindWalkKey(key, dir)
local gameRootPanel = modules.game_interface.getRootPanel()
g_keyboard.bindKeyDown(key, function()
onWalkKeyDown(dir)
end, modules.game_interface.getRootPanel(), true)
changeWalkDir(dir)
end, gameRootPanel, true)
g_keyboard.bindKeyUp(key, function()
changeWalkDir(dir, true)
end, modules.game_interface.getRootPanel(), true)
g_keyboard.bindKeyPress(key, function()
smartWalk(dir)
end, modules.game_interface.getRootPanel())
end, gameRootPanel, true)
g_keyboard.bindKeyPress(key, function(_, _, ticks) smartWalk(dir, ticks) end, gameRootPanel)

g_keyboard.setKeyDelay(key, 10)
g_keyboard.setKeyDelay(key, 20)
end

function unbindWalkKey(key)
g_keyboard.unbindKeyDown(key, modules.game_interface.getRootPanel())
g_keyboard.unbindKeyUp(key, modules.game_interface.getRootPanel())
g_keyboard.unbindKeyPress(key, modules.game_interface.getRootPanel())
local gameRootPanel = modules.game_interface.getRootPanel()
g_keyboard.unbindKeyDown(key, gameRootPanel)
g_keyboard.unbindKeyUp(key, gameRootPanel)
g_keyboard.unbindKeyPress(key, gameRootPanel)

g_keyboard.setKeyDelay(key, 30)
g_keyboard.setKeyDelay(key, 20)
end

function bindTurnKey(key, dir)
local function callback(widget, code, repeatTicks)
if g_clock.millis() - lastDirTime >= modules.client_options.getOption('turnDelay') then
g_game.turn(dir)
changeWalkDir(dir)

lastDirTime = g_clock.millis()
end
if modules.game_interface then
local gameRootPanel = modules.game_interface.getRootPanel()
g_keyboard.bindKeyDown(key, function() turn(dir, false) end, gameRootPanel)
g_keyboard.bindKeyPress(key, function() turn(dir, true) end, gameRootPanel)
g_keyboard.bindKeyUp(key, function()
local player = g_game.getLocalPlayer()
if player then player:lockWalk(200) end
end, gameRootPanel)
end

g_keyboard.bindKeyPress(key, callback, modules.game_interface.getRootPanel())
end

function unbindTurnKey(key)
g_keyboard.unbindKeyPress(key, modules.game_interface.getRootPanel())
if modules.game_interface then
local gameRootPanel = modules.game_interface.getRootPanel()
g_keyboard.unbindKeyDown(key, gameRootPanel)
g_keyboard.unbindKeyPress(key, gameRootPanel)
g_keyboard.unbindKeyUp(key, gameRootPanel)
end
end

function stopSmartWalk()
smartWalkDirs = {}
smartWalkDir = nil
end

function onWalkKeyDown(dir)
if modules.client_options.getOption('autoChaseOverride') then
if g_game.isAttacking() and g_game.getChaseMode() == ChaseOpponent then
g_game.setChaseMode(DontChase)
end
end
firstStep = true
changeWalkDir(dir)
end

function changeWalkDir(dir, pop)
while table.removevalue(smartWalkDirs, dir) do
end
while table.removevalue(smartWalkDirs, dir) do end
if pop then
if #smartWalkDirs == 0 then
stopSmartWalk()
Expand Down Expand Up @@ -149,12 +148,121 @@ function changeWalkDir(dir, pop)
end
end

function smartWalk(dir)
if g_keyboard.getModifiers() ~= KeyboardNoModifier then
return false
function smartWalk(dir, ticks)
if walkEvent then
walkEvent:cancel()
end

g_game.walk(smartWalkDir or dir)
walkEvent = scheduleEvent(function()
if g_keyboard.getModifiers() ~= KeyboardNoModifier then
return
end

local direction = smartWalkDir or dir
walk(direction, ticks)
end, 10)
end

function walk(dir, ticks)
local player = g_game.getLocalPlayer()
if not player or g_game.isDead() or player:isDead() then
return
end

if player:isWalkLocked() then
cancelWalkEvent()
return
end

if not player:canWalk(dir) then
local ticksLeft = player:getStepTicksLeft()
if ticksLeft < 100 then
cancelWalkEvent()
walkEvent = scheduleEvent(function() walk(dir, ticks) end, ticksLeft)
end
return
end

if g_game.isFollowing() then
g_game.cancelFollow()
end

if player:isAutoWalking() then
player:stopAutoWalk()
g_game.stop()
end

local toPos = Position.translatedToDirection(player:getPosition(), dir)
local toTile = g_map.getTile(toPos)
if toTile and toTile:isWalkable() then
if not player:isPreWalking() then
player:preWalk(dir)
end
else
-- check for stairs/elevation steps
if not canChangeFloorDown(toPos) and not canChangeFloorUp(toPos) then
return false
end

player:lockWalk(200)
end

g_game.walk(dir)
return true
end
end

function turn(dir, repeated)
local player = g_game.getLocalPlayer()
if player:isWalking() and player:getDirection() == dir then
return
end

cancelWalkEvent()

local delay = repeated and 1000 or 200

if lastTurn + delay < g_clock.millis() then
g_game.turn(dir)
changeWalkDir(dir)
lastTurn = g_clock.millis()
player:lockWalk(g_settings.getNumber("walkTurnDelay"))
end
end

function canChangeFloorDown(pos)
pos.z = pos.z + 1
local toTile = g_map.getTile(pos)
return toTile and toTile:hasElevation(3)
end

function canChangeFloorUp(pos)
pos.z = pos.z - 1
local toTile = g_map.getTile(pos)
return toTile and toTile:isWalkable()
end

function cancelWalkEvent()
if walkEvent then
walkEvent:cancel()
walkEvent = nil
end
end

-- events
function onTeleport(player, newPos, oldPos)
if not newPos or not oldPos then
return
end

if Position.offsetX(newPos, oldPos) >= 3 or Position.offsetY(newPos, oldPos) >= 3 or Position.offsetZ(newPos, oldPos) >= 2 then
-- teleport
player:lockWalk(g_settings.getNumber("walkTeleportDelay"))
else
-- floor change is also teleport
player:lockWalk(g_settings.getNumber("walkStairsDelay"))
end
end

function onCancelWalk(player)
player:lockWalk(50)
end
Loading

0 comments on commit e9caf7e

Please sign in to comment.