• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Solved Block parcel movement otclient 7.4

Joined
Oct 12, 2020
Messages
45
Solutions
1
Reaction score
5
Location
Detroit, MI
How it is

giphy.gif

How it should be
giphy.gif
Looking to fix blocking parcel movement in otclient, for 7.4 - 7.72 server.
Can't find a fix anywhere, maybe I don't know how to word it exactly for a search. I just see people showing it off, never seen the code or files.
If you even have a hint or theory of where it could be or how to fix it, I'll take it.

Thanks for looking,
Max
 
Last edited:
Solution
Where can i check about this in otcv8? or mehah oyclient? I was checking, with otcv8 i don't have sources and mehah otc sources are a bit different. I have added parcel_block feature to my server 8.6 and with otc is partially working, because when parcel are stacked the players path is blocked but it seems like they want to keep walking, exactly like in the first gift.
I'm using tfs 1.3 and i have added this code taken from nostalrius git parcel block feature configurable in config.lua
 
If you are using mehah otclient, you can modify it in walking.lua, near playerTile:hasElevation(3), just add elevation check in client to avoid that. If you are using edubart or other otclients that need to recompile then check this thread:
 
Yes im testing with otcv8 and mehah otc should i change this , near playerTile:hasElevation(3), j to 2? ow how
i have server sido coe but not client side for meha otc

this is what i found at walking.lua
Lua:
    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
    elseif not toTile then
      player:lockWalk(100) -- bug fix for missing stairs down on map
    else
      if g_app.isMobile() and dir <= Directions.West then
        turn(dir, ticks > 0)
      end
      return -- not walkable tile
    end
  end
could you share you client side code?
 
Last edited:
Yes im testing with otcv8 and mehah otc should i change this , near playerTile:hasElevation(3), j to 2? ow how
i have server sido coe but not client side for meha otc

this is what i found at walking.lua
Lua:
    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
    elseif not toTile then
      player:lockWalk(100) -- bug fix for missing stairs down on map
    else
      if g_app.isMobile() and dir <= Directions.West then
        turn(dir, ticks > 0)
      end
      return -- not walkable tile
    end
  end
could you share you client side code?
I use edubart, and my code is like the post i sent you above: Wrong behaviour when walking into stacked items (like 2 or more parcels) (https://otland.net/threads/wrong-behaviour-when-walking-into-stacked-items-like-2-or-more-parcels.276474/)

You just have to add after:
Lua:
if (toTile and toTile:isWalkable()) then
This:
Lua:
    local playerTile = player:getTile()
 if (playerTile and (toTile:hasElevation() - playerTile:hasElevation() <= 1) or (playerTile:hasElevation() > 3))
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end

I haven't tested it but should work, just check the post i sent you and use the logic in there, basically you have to check that your elevation - the elevation of the tile you're going to step is not higher than 1, else then lock the walk.
 
Last edited:
I use edubart, and my code is like the post i sent you above: Wrong behaviour when walking into stacked items (like 2 or more parcels) (https://otland.net/threads/wrong-behaviour-when-walking-into-stacked-items-like-2-or-more-parcels.276474/)

You just have to add after:
Lua:
if (toTile and toTile:isWalkable()) then
This:
Lua:
    local playerTile = player:getTile()
 if (playerTile and (toTile:hasElevation() - playerTile:hasElevation() <= 1) or (playerTile:hasElevation() > 3))
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end

I haven't tested it but should work, just check the post i sent you and use the logic in there, basically you have to check that your elevation - the elevation of the tile you're going to step is not higher than 1, else then lock the walk.12.png
i placed the code and it was sending error saying it was waiting for a then before player so i added it but i can't walk with arrows keys now


EDIT : I ADDED AN END AT THE end of the code but i can't still walk with arrows
Lua:
 if toTile and toTile:isWalkable() then
     local playerTile = player:getTile()
 if (playerTile and (toTile:hasElevation() - playerTile:hasElevation() <= 1) or (playerTile:hasElevation() > 3))
    player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
Post automatically merged:

edit i was copy it wrong, now i did okey but im still having errors
12.png
so i added then keyword to the script also end but now it doesn't works i can't walk with arrows key
Lua:
smartWalkDirs = {}
smartWalkDir = nil
wsadWalking = false
nextWalkDir = nil
lastWalkDir = nil
lastFinishedStep = 0
autoWalkEvent = nil
firstStep = true
walkLock = 0
walkEvent = nil
lastWalk = 0
lastTurn = 0
lastTurnDirection = 0
lastStop = 0
lastManualWalk = 0
autoFinishNextServerWalk = 0
turnKeys = {}

function init()
  connect(LocalPlayer, {
    onPositionChange = onPositionChange,
    onWalk = onWalk,
    onTeleport = onTeleport,
    onWalkFinish = onWalkFinish,
    onCancelWalk = onCancelWalk
  })

  modules.game_interface.getRootPanel().onFocusChange = stopSmartWalk
  bindKeys()
end

function terminate()
  disconnect(LocalPlayer, {
    onPositionChange = onPositionChange,
    onWalk = onWalk,
    onTeleport = onTeleport,
    onWalkFinish = onWalkFinish
  })
  removeEvent(autoWalkEvent)
  stopSmartWalk()
  unbindKeys()
  disableWSAD()
end

function bindKeys()
  bindWalkKey('Up', North)
  bindWalkKey('Right', East)
  bindWalkKey('Down', South)
  bindWalkKey('Left', West)
  bindWalkKey('Numpad8', North)
  bindWalkKey('Numpad9', NorthEast)
  bindWalkKey('Numpad6', East)
  bindWalkKey('Numpad3', SouthEast)
  bindWalkKey('Numpad2', South)
  bindWalkKey('Numpad1', SouthWest)
  bindWalkKey('Numpad4', West)
  bindWalkKey('Numpad7', NorthWest)

  bindTurnKey('Ctrl+Up', North)
  bindTurnKey('Ctrl+Right', East)
  bindTurnKey('Ctrl+Down', South)
  bindTurnKey('Ctrl+Left', West)
  bindTurnKey('Ctrl+Numpad8', North)
  bindTurnKey('Ctrl+Numpad6', East)
  bindTurnKey('Ctrl+Numpad2', South)
  bindTurnKey('Ctrl+Numpad4', West)
end

function unbindKeys()
  unbindWalkKey('Up', North)
  unbindWalkKey('Right', East)
  unbindWalkKey('Down', South)
  unbindWalkKey('Left', West)
  unbindWalkKey('Numpad8', North)
  unbindWalkKey('Numpad9', NorthEast)
  unbindWalkKey('Numpad6', East)
  unbindWalkKey('Numpad3', SouthEast)
  unbindWalkKey('Numpad2', South)
  unbindWalkKey('Numpad1', SouthWest)
  unbindWalkKey('Numpad4', West)
  unbindWalkKey('Numpad7', NorthWest)

  unbindTurnKey('Ctrl+Up', North)
  unbindTurnKey('Ctrl+Right', East)
  unbindTurnKey('Ctrl+Down', South)
  unbindTurnKey('Ctrl+Left', West)
  unbindTurnKey('Ctrl+Numpad8', North)
  unbindTurnKey('Ctrl+Numpad6', East)
  unbindTurnKey('Ctrl+Numpad2', South)
  unbindTurnKey('Ctrl+Numpad4', West)
end

function enableWSAD()
  if wsadWalking then
    return
  end
  wsadWalking = true
  local player = g_game.getLocalPlayer()
  if player then
    player:lockWalk(100) -- 100 ms walk lock for all directions 
  end

  bindWalkKey("W", North)
  bindWalkKey("D", East)
  bindWalkKey("S", South)
  bindWalkKey("A", West)

  bindTurnKey("Ctrl+W", North)
  bindTurnKey("Ctrl+D", East)
  bindTurnKey("Ctrl+S", South)
  bindTurnKey("Ctrl+A", West)

  bindWalkKey("E", NorthEast)
  bindWalkKey("Q", NorthWest)
  bindWalkKey("C", SouthEast)
  bindWalkKey("Z", SouthWest)
end

function disableWSAD()
  if not wsadWalking then
    return
  end
  wsadWalking = false

  unbindWalkKey("W")
  unbindWalkKey("D")
  unbindWalkKey("S")
  unbindWalkKey("A")

  unbindTurnKey("Ctrl+W")
  unbindTurnKey("Ctrl+D")
  unbindTurnKey("Ctrl+S")
  unbindTurnKey("Ctrl+A")

  unbindWalkKey("E")
  unbindWalkKey("Q")
  unbindWalkKey("C")
  unbindWalkKey("Z")
end

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

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

function bindTurnKey(key, dir)
  turnKeys[key] = dir
  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

function unbindTurnKey(key)
  turnKeys[key] = nil
  local gameRootPanel = modules.game_interface.getRootPanel()
  g_keyboard.unbindKeyDown(key, gameRootPanel)
  g_keyboard.unbindKeyPress(key, gameRootPanel)
  g_keyboard.unbindKeyUp(key, gameRootPanel)
end

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

function changeWalkDir(dir, pop)
  while table.removevalue(smartWalkDirs, dir) do end
  if pop then
    if #smartWalkDirs == 0 then
      stopSmartWalk()
      return
    end
  else
    table.insert(smartWalkDirs, 1, dir)
  end

  smartWalkDir = smartWalkDirs[1]
  if modules.client_options.getOption('smartWalk') and #smartWalkDirs > 1 then
    for _,d in pairs(smartWalkDirs) do
      if (smartWalkDir == North and d == West) or (smartWalkDir == West and d == North) then
        smartWalkDir = NorthWest
        break
      elseif (smartWalkDir == North and d == East) or (smartWalkDir == East and d == North) then
        smartWalkDir = NorthEast
        break
      elseif (smartWalkDir == South and d == West) or (smartWalkDir == West and d == South) then
        smartWalkDir = SouthWest
        break
      elseif (smartWalkDir == South and d == East) or (smartWalkDir == East and d == South) then
        smartWalkDir = SouthEast
        break
      end
    end
  end
end

function smartWalk(dir, ticks)
  walkEvent = scheduleEvent(function()
    if g_keyboard.getModifiers() == KeyboardNoModifier then
      local direction = smartWalkDir or dir
      walk(direction, ticks)
      return true
    end
    return false
  end, 20)
end

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

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

function onPositionChange(player, newPos, oldPos)
end

function onWalk(player, newPos, oldPos)
  if autoFinishNextServerWalk + 200 > g_clock.millis() then
    player:finishServerWalking()
  end
end

function onTeleport(player, newPos, oldPos)
  if not newPos or not oldPos then
    return
  end
  -- floor change is also teleport
  if math.abs(newPos.x - oldPos.x) >= 3 or math.abs(newPos.y - oldPos.y) >= 3 or math.abs(newPos.z - oldPos.z) >= 2 then
    -- far teleport, lock walk for 100ms
    walkLock = g_clock.millis() + g_settings.getNumber('walkTeleportDelay')
  else
    walkLock = g_clock.millis() + g_settings.getNumber('walkStairsDelay')
  end
  nextWalkDir = nil -- cancel autowalk
end

function onWalkFinish(player)
  lastFinishedStep = g_clock.millis()
  if nextWalkDir ~= nil then
    removeEvent(autoWalkEvent)
    autoWalkEvent = addEvent(function() if nextWalkDir ~= nil then walk(nextWalkDir, 0) end end, false)
  end
end

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

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

  if player:isWalkLocked() then
    nextWalkDir = nil
    return
  end

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

  if player:isAutoWalking() then
    if lastStop + 100 < g_clock.millis() then
      lastStop = g_clock.millis()
      player:stopAutoWalk()
      g_game.stop()
    end
  end
  
  local dash = false
  local ignoredCanWalk = false
  if not g_game.getFeature(GameNewWalking) then
    dash = g_settings.getBoolean("dash", false)
  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 dash then
      ignoredCanWalk = true
    else
      if ticksToNextWalk < 500 and (lastWalkDir ~= dir or ticks == 0) 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
  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

  local toPos = player:getPrewalkingPosition(true)
  if dir == North then
    toPos.y = toPos.y - 1
  elseif dir == East then
    toPos.x = toPos.x + 1
  elseif dir == South then
    toPos.y = toPos.y + 1
  elseif dir == West then
    toPos.x = toPos.x - 1
  elseif dir == NorthEast then
    toPos.x = toPos.x + 1
    toPos.y = toPos.y - 1
  elseif dir == SouthEast then
    toPos.x = toPos.x + 1
    toPos.y = toPos.y + 1
  elseif dir == SouthWest then
    toPos.x = toPos.x - 1
    toPos.y = toPos.y + 1
  elseif dir == NorthWest then
    toPos.x = toPos.x - 1
    toPos.y = toPos.y - 1
  end
  local toTile = g_map.getTile(toPos)

  if walkLock >= g_clock.millis() and lastWalkDir == dir then
    nextWalkDir = nil
    return
  end

  if firstStep and lastWalkDir == dir and lastWalk + g_settings.getNumber('walkFirstStepDelay') > g_clock.millis() then
    firstStep = false
    walkLock = lastWalk + g_settings.getNumber('walkFirstStepDelay')
    return
  end
 
  if dash and lastWalkDir == dir and lastWalk + 50 > g_clock.millis() then
    return
  end
 
  firstStep = (not player:isWalking() and lastFinishedStep + 100 < g_clock.millis() and walkLock + 100 < g_clock.millis())
  if player:isServerWalking() and not dash then
    walkLock = walkLock + math.max(g_settings.getNumber('walkFirstStepDelay'), 100)
  end
 
  nextWalkDir = nil
  removeEvent(autoWalkEvent)
  autoWalkEvent = nil
  local preWalked = false
  if toTile and toTile:isWalkable() then

 if toTile and toTile:isWalkable() then
     local playerTile = player:getTile()
 if (playerTile and (toTile:hasElevation() - playerTile:hasElevation() <= 1) or (playerTile:hasElevation() > 3)) then
    player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
       player:preWalk(dir)
      preWalked = true
    end
   -- 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
    elseif not toTile then
      player:lockWalk(100) -- bug fix for missing stairs down on map
    else
      if g_app.isMobile() and dir <= Directions.West then
        turn(dir, ticks > 0)
      end
      return -- not walkable tile
    end
  end

  if player:isServerWalking() and not dash then
    g_game.stop()
    player:finishServerWalking()
    autoFinishNextServerWalk = g_clock.millis() + 200
  end
  g_game.walk(dir, preWalked)
 
  if not firstStep and lastWalkDir ~= dir then
    walkLock = g_clock.millis() + g_settings.getNumber('walkTurnDelay') 
  end
 
  lastWalkDir = dir
  lastWalk = g_clock.millis()
  return true
end

function turn(dir, repeated)
  local player = g_game.getLocalPlayer()
  if player:isWalking() and player:getWalkDirection() == dir and not player:isServerWalking() then
    return
  end
 
  removeEvent(walkEvent)
 
  if not repeated or (lastTurn + 100 < g_clock.millis()) then
    g_game.turn(dir)
    changeWalkDir(dir)
    lastTurn = g_clock.millis()
    if not repeated then
      lastTurn = g_clock.millis() + 50
    end
    lastTurnDirection = dir
    nextWalkDir = nil
    player:lockWalk(g_settings.getNumber('walkCtrlTurnDelay'))
  end
end

function checkTurn()
  for keys, direction in pairs(turnKeys) do
    if g_keyboard.areKeysPressed(keys) then
      turn(direction, false)
    end
  end
end
end
anyway i tested with mouse and the player is still trying to walk over the parcel despite of that the server does not allows it
 
Last edited:
Try printing in the console the result of totile elevation - player elevation. I am not familiar with otc8 but you try different things, try deleting the lock walk after the else too. For map clicking you need to find where is that code, its not the same code than arrows.
 
Try printing in the console the result of totile elevation - player elevation. I am not familiar with otc8 but you try different things, try deleting the lock walk after the else too. For map clicking you need to find where is that code, its not the same code than arrows.
Lua:
 nextWalkDir = nil
  removeEvent(autoWalkEvent)
  autoWalkEvent = nil
  local preWalked = false
  if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:hasElevation() - playerTile:hasElevation() <= 1) or (playerTile:hasElevation() > 3)) then
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
  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
    elseif not toTile then
      player:lockWalk(100) -- bug fix for missing stairs down on map
    else
      if g_a

Edit: i was placing the code in the wrong line
now i did this and i can walk with arrows, but the code itself does not works, i don't have any errors in console.
Lua:
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
      local playerTile = player:getTile()
 if (playerTile and (toTile:hasElevation() - playerTile:hasElevation() <= 1) or (playerTile:hasElevation() > 3)) then
      --player:lockWalk(100)
    elseif player:isServerWalking() then
      g_game.stop()
      return
    elseif not toTile then
      player:lockWalk(100) -- bug fix for missing stairs down on map
    else
      if g_app.isMobile() and dir <= Directions.West then
        turn(dir, ticks > 0)
      end
      return -- not walkable tile
    end
  end
end
Code:
== application started at Jun 28 2021 12:38:27
ForgottenServer 3.0 rev 83 (dev) made by otclient.net built on May 26 2021 for arch x86
Connecting to: forgottenserver.ddns.net:7171
Login to xxx.xxx.xxx.xxx:7172
Post automatically merged:

MY BAD ! YES IM HAVINGG ERRORS AT CONSOLE
Code:
ERROR: lua function callback failed: /modules/game_walking/walking.lua:368: attempt to perform arithmetic on a boolean value
stack traceback:
    [C]: in function '__sub'
    /modules/game_walking/walking.lua:368: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:368: attempt to perform arithmetic on a boolean value
stack traceback:
    [C]: in function '__sub'
    /modules/game_walking/walking.lua:368: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:368: attempt to perform arithmetic on a boolean value
stack traceback:
    [C]: in function '__sub'
    /modules/game_walking/walking.lua:368: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:368: attempt to perform arithmetic on a boolean value
stack traceback:
    [C]: in function '__sub'
    /modules/game_walking/walking.lua:368: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:368: attempt to perform arithmetic on a boolean value
stack traceback:
    [C]: in function '__sub'
    /modules/game_walking/walking.lua:368: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:368: attempt to perform arithmetic on a boolean value
stack traceback:
    [C]: in function '__sub'
    /modules/game_walking/walking.lua:368: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:368: attempt to perform arithmetic on a boolean value
stack traceback:
    [C]: in function '__sub'
    /modules/game_walking/walking.lua:368: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:368: attempt to perform arithmetic on a boolean value
stack traceback:
    [C]: in function '__sub'
    /modules/game_walking/walking.lua:368: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>

THIS IS YOUR CODE ( i have changed hasElevation to getElevtion because, kay told me. but didn't work i don't get errors with it but cant walk
Lua:
  if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:hasElevation() - playerTile:hasElevation() <= 1) or (playerTile:hasElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
the full script walking.lua
Code:
smartWalkDirs = {}
smartWalkDir = nil
wsadWalking = false
nextWalkDir = nil
lastWalkDir = nil
lastFinishedStep = 0
autoWalkEvent = nil
firstStep = true
walkLock = 0
walkEvent = nil
lastWalk = 0
lastTurn = 0
lastTurnDirection = 0
lastStop = 0
lastManualWalk = 0
autoFinishNextServerWalk = 0
turnKeys = {}

function init()
  connect(LocalPlayer, {
    onPositionChange = onPositionChange,
    onWalk = onWalk,
    onTeleport = onTeleport,
    onWalkFinish = onWalkFinish,
    onCancelWalk = onCancelWalk
  })

  modules.game_interface.getRootPanel().onFocusChange = stopSmartWalk
  bindKeys()
end

function terminate()
  disconnect(LocalPlayer, {
    onPositionChange = onPositionChange,
    onWalk = onWalk,
    onTeleport = onTeleport,
    onWalkFinish = onWalkFinish
  })
  removeEvent(autoWalkEvent)
  stopSmartWalk()
  unbindKeys()
  disableWSAD()
end

function bindKeys()
  bindWalkKey('Up', North)
  bindWalkKey('Right', East)
  bindWalkKey('Down', South)
  bindWalkKey('Left', West)
  bindWalkKey('Numpad8', North)
  bindWalkKey('Numpad9', NorthEast)
  bindWalkKey('Numpad6', East)
  bindWalkKey('Numpad3', SouthEast)
  bindWalkKey('Numpad2', South)
  bindWalkKey('Numpad1', SouthWest)
  bindWalkKey('Numpad4', West)
  bindWalkKey('Numpad7', NorthWest)

  bindTurnKey('Ctrl+Up', North)
  bindTurnKey('Ctrl+Right', East)
  bindTurnKey('Ctrl+Down', South)
  bindTurnKey('Ctrl+Left', West)
  bindTurnKey('Ctrl+Numpad8', North)
  bindTurnKey('Ctrl+Numpad6', East)
  bindTurnKey('Ctrl+Numpad2', South)
  bindTurnKey('Ctrl+Numpad4', West)
end

function unbindKeys()
  unbindWalkKey('Up', North)
  unbindWalkKey('Right', East)
  unbindWalkKey('Down', South)
  unbindWalkKey('Left', West)
  unbindWalkKey('Numpad8', North)
  unbindWalkKey('Numpad9', NorthEast)
  unbindWalkKey('Numpad6', East)
  unbindWalkKey('Numpad3', SouthEast)
  unbindWalkKey('Numpad2', South)
  unbindWalkKey('Numpad1', SouthWest)
  unbindWalkKey('Numpad4', West)
  unbindWalkKey('Numpad7', NorthWest)

  unbindTurnKey('Ctrl+Up', North)
  unbindTurnKey('Ctrl+Right', East)
  unbindTurnKey('Ctrl+Down', South)
  unbindTurnKey('Ctrl+Left', West)
  unbindTurnKey('Ctrl+Numpad8', North)
  unbindTurnKey('Ctrl+Numpad6', East)
  unbindTurnKey('Ctrl+Numpad2', South)
  unbindTurnKey('Ctrl+Numpad4', West)
end

function enableWSAD()
  if wsadWalking then
    return
  end
  wsadWalking = true
  local player = g_game.getLocalPlayer()
  if player then
    player:lockWalk(100) -- 100 ms walk lock for all directions  
  end

  bindWalkKey("W", North)
  bindWalkKey("D", East)
  bindWalkKey("S", South)
  bindWalkKey("A", West)

  bindTurnKey("Ctrl+W", North)
  bindTurnKey("Ctrl+D", East)
  bindTurnKey("Ctrl+S", South)
  bindTurnKey("Ctrl+A", West)

  bindWalkKey("E", NorthEast)
  bindWalkKey("Q", NorthWest)
  bindWalkKey("C", SouthEast)
  bindWalkKey("Z", SouthWest)
end

function disableWSAD()
  if not wsadWalking then
    return
  end
  wsadWalking = false

  unbindWalkKey("W")
  unbindWalkKey("D")
  unbindWalkKey("S")
  unbindWalkKey("A")

  unbindTurnKey("Ctrl+W")
  unbindTurnKey("Ctrl+D")
  unbindTurnKey("Ctrl+S")
  unbindTurnKey("Ctrl+A")

  unbindWalkKey("E")
  unbindWalkKey("Q")
  unbindWalkKey("C")
  unbindWalkKey("Z")
end

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

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

function bindTurnKey(key, dir)
  turnKeys[key] = dir
  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

function unbindTurnKey(key)
  turnKeys[key] = nil
  local gameRootPanel = modules.game_interface.getRootPanel()
  g_keyboard.unbindKeyDown(key, gameRootPanel)
  g_keyboard.unbindKeyPress(key, gameRootPanel)
  g_keyboard.unbindKeyUp(key, gameRootPanel)
end

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

function changeWalkDir(dir, pop)
  while table.removevalue(smartWalkDirs, dir) do end
  if pop then
    if #smartWalkDirs == 0 then
      stopSmartWalk()
      return
    end
  else
    table.insert(smartWalkDirs, 1, dir)
  end

  smartWalkDir = smartWalkDirs[1]
  if modules.client_options.getOption('smartWalk') and #smartWalkDirs > 1 then
    for _,d in pairs(smartWalkDirs) do
      if (smartWalkDir == North and d == West) or (smartWalkDir == West and d == North) then
        smartWalkDir = NorthWest
        break
      elseif (smartWalkDir == North and d == East) or (smartWalkDir == East and d == North) then
        smartWalkDir = NorthEast
        break
      elseif (smartWalkDir == South and d == West) or (smartWalkDir == West and d == South) then
        smartWalkDir = SouthWest
        break
      elseif (smartWalkDir == South and d == East) or (smartWalkDir == East and d == South) then
        smartWalkDir = SouthEast
        break
      end
    end
  end
end

function smartWalk(dir, ticks)
  walkEvent = scheduleEvent(function()
    if g_keyboard.getModifiers() == KeyboardNoModifier then
      local direction = smartWalkDir or dir
      walk(direction, ticks)
      return true
    end
    return false
  end, 20)
end

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

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

function onPositionChange(player, newPos, oldPos)
end

function onWalk(player, newPos, oldPos)
  if autoFinishNextServerWalk + 200 > g_clock.millis() then
    player:finishServerWalking()
  end
end

function onTeleport(player, newPos, oldPos)
  if not newPos or not oldPos then
    return
  end
  -- floor change is also teleport
  if math.abs(newPos.x - oldPos.x) >= 3 or math.abs(newPos.y - oldPos.y) >= 3 or math.abs(newPos.z - oldPos.z) >= 2 then
    -- far teleport, lock walk for 100ms
    walkLock = g_clock.millis() + g_settings.getNumber('walkTeleportDelay')
  else
    walkLock = g_clock.millis() + g_settings.getNumber('walkStairsDelay')
  end
  nextWalkDir = nil -- cancel autowalk
end

function onWalkFinish(player)
  lastFinishedStep = g_clock.millis()
  if nextWalkDir ~= nil then
    removeEvent(autoWalkEvent)
    autoWalkEvent = addEvent(function() if nextWalkDir ~= nil then walk(nextWalkDir, 0) end end, false)
  end
end

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

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

  if player:isWalkLocked() then
    nextWalkDir = nil
    return
  end

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

  if player:isAutoWalking() then
    if lastStop + 100 < g_clock.millis() then
      lastStop = g_clock.millis()
      player:stopAutoWalk()
      g_game.stop()
    end
  end
   
  local dash = false
  local ignoredCanWalk = false
  if not g_game.getFeature(GameNewWalking) then
    dash = g_settings.getBoolean("dash", false)
  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 dash then
      ignoredCanWalk = true
    else
      if ticksToNextWalk < 500 and (lastWalkDir ~= dir or ticks == 0) 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
  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

  local toPos = player:getPrewalkingPosition(true)
  if dir == North then
    toPos.y = toPos.y - 1
  elseif dir == East then
    toPos.x = toPos.x + 1
  elseif dir == South then
    toPos.y = toPos.y + 1
  elseif dir == West then
    toPos.x = toPos.x - 1
  elseif dir == NorthEast then
    toPos.x = toPos.x + 1
    toPos.y = toPos.y - 1
  elseif dir == SouthEast then
    toPos.x = toPos.x + 1
    toPos.y = toPos.y + 1
  elseif dir == SouthWest then
    toPos.x = toPos.x - 1
    toPos.y = toPos.y + 1
  elseif dir == NorthWest then
    toPos.x = toPos.x - 1
    toPos.y = toPos.y - 1
  end
  local toTile = g_map.getTile(toPos)

  if walkLock >= g_clock.millis() and lastWalkDir == dir then
    nextWalkDir = nil
    return
  end

  if firstStep and lastWalkDir == dir and lastWalk + g_settings.getNumber('walkFirstStepDelay') > g_clock.millis() then
    firstStep = false
    walkLock = lastWalk + g_settings.getNumber('walkFirstStepDelay')
    return
  end
 
  if dash and lastWalkDir == dir and lastWalk + 50 > g_clock.millis() then
    return
  end
 
  firstStep = (not player:isWalking() and lastFinishedStep + 100 < g_clock.millis() and walkLock + 100 < g_clock.millis())
  if player:isServerWalking() and not dash then
    walkLock = walkLock + math.max(g_settings.getNumber('walkFirstStepDelay'), 100)
  end
 
  nextWalkDir = nil
  removeEvent(autoWalkEvent)
  autoWalkEvent = nil
  local preWalked = false
  if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:hasElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    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
    elseif not toTile then
      player:lockWalk(100) -- bug fix for missing stairs down on map
    else
      if g_app.isMobile() and dir <= Directions.West then
        turn(dir, ticks > 0)
      end
      return -- not walkable tile
    end
  end

  if player:isServerWalking() and not dash then
    g_game.stop()
    player:finishServerWalking()
    autoFinishNextServerWalk = g_clock.millis() + 200
  end
  g_game.walk(dir, preWalked)
 
  if not firstStep and lastWalkDir ~= dir then
    walkLock = g_clock.millis() + g_settings.getNumber('walkTurnDelay')  
  end
 
  lastWalkDir = dir
  lastWalk = g_clock.millis()
  return true
end

function turn(dir, repeated)
  local player = g_game.getLocalPlayer()
  if player:isWalking() and player:getWalkDirection() == dir and not player:isServerWalking() then
    return
  end
 
  removeEvent(walkEvent)
 
  if not repeated or (lastTurn + 100 < g_clock.millis()) then
    g_game.turn(dir)
    changeWalkDir(dir)
    lastTurn = g_clock.millis()
    if not repeated then
      lastTurn = g_clock.millis() + 50
    end
    lastTurnDirection = dir
    nextWalkDir = nil
    player:lockWalk(g_settings.getNumber('walkCtrlTurnDelay'))
  end
end

function checkTurn()
  for keys, direction in pairs(turnKeys) do
    if g_keyboard.areKeysPressed(keys) then
      turn(direction, false)
    end
  end
end
 
Last edited:
Well the error is because hasElevation is returning you a boolean value (true or false, 1 or 0) instead of the value of the elevation. Basically there you're doing a math (the boolean value of has elevation - getelevation of playertile) that is not possible. That's why i linked you the other thread where i had the same problem, and i has to make my own function to check for the elevation. If kay told you getElevation i guess that function then does exist, it should be like this:


Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
 
Last edited:
Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
      playerreWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    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)
same errors
Code:
ERROR: lua function callback failed: /modules/game_walking/walking.lua:369: attempt to call global 'playerreWalk' (a nil value)
stack traceback:
    [C]: in function 'playerreWalk'
    /modules/game_walking/walking.lua:369: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:369: attempt to call global 'playerreWalk' (a nil value)
stack traceback:
 
Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
      playerreWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    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)
same errors
Code:
ERROR: lua function callback failed: /modules/game_walking/walking.lua:369: attempt to call global 'playerreWalk' (a nil value)
stack traceback:
    [C]: in function 'playerreWalk'
    /modules/game_walking/walking.lua:369: in function 'walk'
    /modules/game_walking/walking.lua:211: in function </modules/game_walking/walking.lua:208>
ERROR: lua function callback failed: /modules/game_walking/walking.lua:369: attempt to call global 'playerreWalk' (a nil value)
stack traceback:
Yes it was my fault at the code, just copy the refreshed code i edited above and try again, here.
 
Thanks. Ain't getting errors now. but the same. can't walk unless im in front of stacked parcels. i pressed arrows it walk two sqm and simply stopped and can't walk anymore
Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
  else
    local playerTile = player:getTile()
 
Thanks. Ain't getting errors now. but the same. can't walk unless im in front of stacked parcels. i pressed arrows it walk two sqm and simply stopped and can't walk anymore
Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
  else
    local playerTile = player:getTile()
try this:

Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else 
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
  else
    local playerTile = player:getTile()
 
try this:

Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
  else
    local playerTile = player:getTile()
same u.u
 
I think you can't walk because the maths between your elevation (should be 1) and the elevation of the tile you're going to (should be 1) is more than 1, try this:

Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() > 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
  else
    local playerTile = player:getTile()
 
shouldn't it be GeTHEIGHT instead of elevation?
Heigh stack feature · joseluis2g/my-nostalrius@93e0194 (https://github.com/joseluis2g/my-nostalrius/commit/93e019428ed3b2d25d4b73f147a963beb185c706) this is what i added
and checked tile.cpp
Lua:
bool Tile::hasHeight(uint32_t n) const
{
    uint32_t height = 0;

    if (ground) {
        if (ground->hasProperty(CONST_PROP_HASHEIGHT)) {
            ++height;
        }

        if (n == height) {
            return true;
        }
    }

    if (const TileItemVector* items = getItemList()) {
        for (const Item* item : *items) {
            if (item->hasProperty(CONST_PROP_HASHEIGHT)) {
                ++height;
            }

            if (n == height) {
                return true;
            }
        }
    }
    return false;
}
Post automatically merged:

I think you can't walk because the maths between your elevation (should be 1) and the elevation of the tile you're going to (should be 1) is more than 1, try this:

Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() > 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
  else
    local playerTile = player:getTile()
going to check
Post automatically merged:

I think you can't walk because the maths between your elevation (should be 1) and the elevation of the tile you're going to (should be 1) is more than 1, try this:

Lua:
if toTile and toTile:isWalkable() then
      local playerTile = player:getTile()
 if (playerTile and (toTile:getElevation() - playerTile:getElevation() > 1) or (playerTile:getElevation() > 3)) then
      player:preWalk(dir)
      preWalked = true
      else player:lockWalk(100)
      end
    if not player:isServerWalking() and not ignoredCanWalk then
      player:preWalk(dir)
      preWalked = true
    end
  else
    local playerTile = player:getTile()
Yeah now i can walk but i jumps even more jajaj weird
 
Lua:
 nextWalkDir = nil
  removeEvent(autoWalkEvent)
  autoWalkEvent = nil
  local preWalked = false
  local playerTile = player:getTile()
   if toTile and toTile:isWalkable() then
    if not player:isServerWalking() and not ignoredCanWalk then
        if (playerTile and (toTile:getElevation() - playerTile:getElevation() <= 1) or (playerTile:getElevation() > 3)) then
            player:preWalk(dir)
            preWalked = true
        end
    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
    elseif not toTile then
      player:lockWalk(100) -- bug fix for missing stairs down on map
    else
      if g_app.isMobile() and dir <= Directions.West then
        turn(dir, ticks > 0)
      end
      return -- not walkable tile
    end
  end
 
Up i have a similar problem with invisible creatures, the players want to walk but it should not be able to so how to fix this? i know it's client side issue
 
Back
Top