• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

TFS 1.X+ SetMovementBlocked Infinite Loop Bug

Tbol

Well-Known Member
Joined
Apr 7, 2019
Messages
625
Reaction score
71
Hello i found a interesting bug if you get stunned near floorchange (stairs) and you try to run to the second floor while you are stunned you get stuck in a infinite stun loop and you cannot escape it unless you click on the map with the mouse, but sometimes even that doesnt work. Any ideas how to solve it?
This is the commit - Creature:isMovementBlocked and Create:setMovementBlocked (#2553) · otland/forgottenserver@3b42c0e (https://github.com/otland/forgottenserver/commit/3b42c0eefc4bf48074fffb72a3ce623feb3a6c94)
 
I can see multiple scripts using setMovementBlocked and interfering with one another, but if every setMovementBlocked(true) is matched with a setMovementBlocked(false), the only side-effect you should notice is a shorter movement block. You mentioned stuns but looking at the TFS repo I didn't find anything related. It would help if you showed how setMovementBlocked is being used.
 
I can see multiple scripts using setMovementBlocked and interfering with one another, but if every setMovementBlocked(true) is matched with a setMovementBlocked(false), the only side-effect you should notice is a shorter movement block. You mentioned stuns but looking at the TFS repo I didn't find anything related. It would help if you showed how setMovementBlocked is being used.
This is how its used in that script hat bug out if they get stun on the stairs
LUA:
local function tryTeleport(position)
    local tile = Tile(position)
    return tile and tile:isWalkable() and not Creature(tile:getTopCreature()) and not tile:hasFlag(TILESTATE_PROTECTIONZONE) and not tile:hasFlag(TILESTATE_TELEPORT) and not tile:hasFlag(TILESTATE_FLOORCHANGE) and not tile:hasFlag(TILESTATE_BLOCKSOLID) and not tile:hasFlag(TILESTATE_IMMOVABLEBLOCKSOLID)
end

local function pushTarget(playerId, targetId)
    local player = Player(playerId)
    local target = Creature(targetId)

    if not player or not target or player == target then
        return false
    end

    if target:isMovementBlocked() then
        return false
    end

    local playerPosition = player:getPosition()
    local targetPosition = target:getPosition()

    if playerPosition.z ~= targetPosition.z then
        return false
    end

    local nextPosition = getPushPosition(playerPosition, targetPosition)

    if tryTeleport(nextPosition) then
        target:teleportTo(nextPosition)
        --targetPosition:sendMagicEffect(CONST_ME_POFF)
        return true
    else
        --targetPosition:sendMagicEffect(CONST_ME_STUN)
        doCreatureSay(targetId, '~STUNNED~', TALKTYPE_ORANGE_1)
        addEvent(function(targetId)
          local t = Creature(targetId)
          if t then
          t:setMovementBlocked(false)
          end
          end, config.stunTime * 1000, targetId)
          target:setMovementBlocked(true)
        return false
    end
end
 
Unless something wrong happens while executing that delayed event, it should work fine. But you said it was mixing stuns with changing floors that triggered the bug so setMovementBlocked is probably being used somewhere else. But then you also mentioned that clicking on the map fixes the issue sometimes, and this reminds me of some other bug related to not properly sending a CancelWalk back to the client, so it gets stuck waiting for walk confirmation/snapback which sometimes gets resolved by clicking on the map. Does the character snapback or does it take a step while stunned?
 
Unless something wrong happens while executing that delayed event, it should work fine. But you said it was mixing stuns with changing floors that triggered the bug so setMovementBlocked is probably being used somewhere else. But then you also mentioned that clicking on the map fixes the issue sometimes, and this reminds me of some other bug related to not properly sending a CancelWalk back to the client, so it gets stuck waiting for walk confirmation/snapback which sometimes gets resolved by clicking on the map. Does the character snapback or does it take a step while stunned?
Yes he takes a step while stunned and it gets stuck in that infinite loop
 
Yes he takes a step while stunned and it gets stuck in that infinite loop
Sounds like client error. What client do you use? Tibia? OTCR? OTCv8? Try with official Tibia client.
Problem is that on RL Tibia - at least on old protocols - there was no code to stop players movement, so client did not have to implement code for this.

Only similar situation would be stairs with "Protection Zone" on their tile outside protection zone. Client would think it can go by these stairs and server would not allow that.
I would check that kind of map design. If it works fine, I would check what packets client receives vs. when you are stunned and there is no PZ on stairs.
 
Sounds like client error. What client do you use? Tibia? OTCR? OTCv8? Try with official Tibia client.
Problem is that on RL Tibia - at least on old protocols - there was no code to stop players movement, so client did not have to implement code for this.

Only similar situation would be stairs with "Protection Zone" on their tile outside protection zone. Client would think it can go by these stairs and server would not allow that.
I would check that kind of map design. If it works fine, I would check what packets client receives vs. when you are stunned and there is no PZ on stairs.
Using OTCv8, what i noticed aswell when the player gets stuck in that loop for other player it just looks like hes just standing on the stairs but for the player that is stuck hes seeing his character walking in place
 
Dont use setMovementBlocked. It's bad implementation. Its prone to race condition, which results in infinite stun. Two scripts sets the boolean and unsets at different times and you can end up with infinite stun. Add new CONDITION_STUN. Either way the stair problem sounds like missing sendCancelWalk
 
Dont use setMovementBlocked. It's bad implementation. Its prone to race condition, which results in infinite stun. Two scripts sets the boolean and unsets at different times and you can end up with infinite stun. Add new CONDITION_STUN. Either way the stair problem sounds like missing sendCancelWalk
Sadly dont know how to create new stun condition because there is no comits related to it
 
Back
Top