• 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!

Lua TFS 1.5 downgrade 772 classic rope behaviour

Gover

Member
Joined
Sep 3, 2009
Messages
72
Reaction score
19
Hello,
I'm trying to change the rope script in this distro to work the same as in old days.
Classic script included in distro do not allow to rope monsters and also it allows to use rope when some items/player/monster/creature are on the ropeSpot.
I have added two more conditions in "if thing:isPlayer() then" and now it looks: "if thing:isPlayer() or thing:isCreature() or thing:isMonster() then". Now roping monsters is possible, but i do not know how to block usage of rope when an item is present on the tile.
Thanks in advance for help :)


LUA:
local holeId = {
    294, 369, 370, 383, 392, 408, 409, 410, 427, 428, 429, 430, 462, 469, 470, 482,
    484, 485, 489, 924, 1369, 3135, 3136, 4835, 4837, 7933, 7938, 8170, 8249, 8250,
    8251, 8252, 8254, 8255, 8256, 8276, 8277, 8279, 8281, 8284, 8285, 8286, 8323,
    8567, 8585, 8595, 8596, 8972, 9606, 9625, 13190, 14461, 19519, 21536
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local tile = Tile(toPosition)
    if not tile then
        return false
    end

    if table.contains(ropeSpots, tile:getGround():getId()) or tile:getItemById(14435) then
        if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and player:isPzLocked() then
            player:sendCancelMessage(RETURNVALUE_PLAYERISPZLOCKED)
            return true
        end
        player:teleportTo(toPosition, false)
        return true
    elseif table.contains(holeId, target.itemid) then
        toPosition.z = toPosition.z + 1
        tile = Tile(toPosition)
        if tile then
            local thing = tile:getTopVisibleThing()
            if thing:isPlayer() then
                if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and thing:isPzLocked() then
                    return false
                end
                return thing:teleportTo(toPosition, false)
            end
            if thing:isItem() and thing:getType():isMovable() then
                return thing:moveTo(toPosition:moveUpstairs())
            end
        end
        player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return true
    end
    return false
end
 
Hello,
I'm trying to change the rope script in this distro to work the same as in old days.
Classic script included in distro do not allow to rope monsters and also it allows to use rope when some items/player/monster/creature are on the ropeSpot.
I have added two more conditions in "if thing:isPlayer() then" and now it looks: "if thing:isPlayer() or thing:isCreature() or thing:isMonster() then". Now roping monsters is possible, but i do not know how to block usage of rope when an item is present on the tile.
Thanks in advance for help :)


LUA:
local holeId = {
    294, 369, 370, 383, 392, 408, 409, 410, 427, 428, 429, 430, 462, 469, 470, 482,
    484, 485, 489, 924, 1369, 3135, 3136, 4835, 4837, 7933, 7938, 8170, 8249, 8250,
    8251, 8252, 8254, 8255, 8256, 8276, 8277, 8279, 8281, 8284, 8285, 8286, 8323,
    8567, 8585, 8595, 8596, 8972, 9606, 9625, 13190, 14461, 19519, 21536
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local tile = Tile(toPosition)
    if not tile then
        return false
    end

    if table.contains(ropeSpots, tile:getGround():getId()) or tile:getItemById(14435) then
        if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and player:isPzLocked() then
            player:sendCancelMessage(RETURNVALUE_PLAYERISPZLOCKED)
            return true
        end
        player:teleportTo(toPosition, false)
        return true
    elseif table.contains(holeId, target.itemid) then
        toPosition.z = toPosition.z + 1
        tile = Tile(toPosition)
        if tile then
            local thing = tile:getTopVisibleThing()
            if thing:isPlayer() then
                if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and thing:isPzLocked() then
                    return false
                end
                return thing:teleportTo(toPosition, false)
            end
            if thing:isItem() and thing:getType():isMovable() then
                return thing:moveTo(toPosition:moveUpstairs())
            end
        end
        player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return true
    end
    return false
end

Hi,

LUA:
if target.itemid == {item_id} then
     return false
end
 
Hi,

LUA:
if target.itemid == {item_id} then
     return false
end
Hello,
Thanks for answer.
I tried to use this condition inside the script, but it looks like it do not work :( (or I don't know how to use it).

I combined two conditions from roping something below and have added it inside if above. It is working now, but i think it will make a lot of issues (with cheking if item is moveable for example - it allows to rope when e.g. poison field is present on the tile). And I would like to make it work with this lootbag trick (when player make first action to rope on clear tile, and move a bag a second before getting up) - but it is not working with my editing :( Maybe it is connected with this delays inside game.h:
C++:
static constexpr int32_t RANGE_USE_ITEM_INTERVAL = 400;
static constexpr int32_t RANGE_USE_ITEM_EX_INTERVAL = 400;

LUA:
    if table.contains(ropeSpots, tile:getGround():getId()) then
        if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and player:isPzLocked() then
            player:sendCancelMessage(RETURNVALUE_PLAYERISPZLOCKED)
            return true
        end
        local thing = tile:getTopVisibleThing()
        if thing:isPlayer() or thing:isCreature() or thing:isMonster() or thing:isItem() and thing:getType():isMovable()  then
            player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        else
        player:teleportTo(toPosition, false)
        end
        return true

Will try to test addEvent to delay player:teleportTo(toPosition, false) function (to give some time for player to move a bag).

Get the delay working, and now moving bag and then using rope (right before bag is moved) working fine:

LUA:
local holeId = {
    294, 369, 370, 383, 392, 408, 409, 410, 427, 428, 429, 430, 462, 469, 470, 482,
    484, 485, 489, 924, 1369, 3135, 3136, 4835, 4837, 7933, 7938, 8170, 8249, 8250,
    8251, 8252, 8254, 8255, 8256, 8276, 8277, 8279, 8281, 8284, 8285, 8286, 8323,
    8567, 8585, 8595, 8596, 8972, 9606, 9625, 13190, 14461, 19519, 21536
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local tile = Tile(toPosition)
    if not tile then
        return false
    end

    if table.contains(ropeSpots, tile:getGround():getId()) then
        if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and player:isPzLocked() then
            player:sendCancelMessage(RETURNVALUE_PLAYERISPZLOCKED)
            return true
        end
        local thing = tile:getTopVisibleThing()
        if thing:isPlayer() or thing:isCreature() or thing:isMonster() or thing:isItem() and thing:getType():isMovable()  then
            player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        else
       
        local function teleport(cid, position)
            local player = Player(cid)
            if player then
            player:teleportTo(toPosition, false)
            end
        end
        addEvent(teleport, 500, player:getId(), Position(x, y, z))
        end
        return true
    elseif table.contains(holeId, target.itemid) then
        toPosition.z = toPosition.z + 1
        tile = Tile(toPosition)
        if tile then
            local thing = tile:getTopVisibleThing()
            if thing:isPlayer() or thing:isCreature() or thing:isMonster() then
                if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and thing:isPzLocked() then
                    return false
                end
                return thing:teleportTo(toPosition, false)
            end
            if thing:isItem() and thing:getType():isMovable() then
                return thing:moveTo(toPosition:moveUpstairs())
            end
        end
        player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return true
    end
    return false
end

Maybe someone will find a better way to achieve this? and to maybe restrict the item on ropeSpot in different way than with thing:getType():isMovable(). I think it is not well written, so any correction is welcome. Would appreciate any help :)
 
Last edited:
Back
Top