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

Help with rope action 7.4

Terotrificy

Veteran OT User
Joined
Oct 18, 2020
Messages
401
Solutions
13
Reaction score
254
Location
Santiago, Chile.
I'm using Othire 1.0.

How it is supposed to work:
You can't use rope if creature or item is on rope spot, fluids like blood doesn't prevent you of using rope spot.

Problem:
When fluid is on rope spot, you can use rope even if creature or item is above it.

Action Script:


Lua:
-- Rope for 7.4 protocol.
function onUse(cid, item, frompos, item2, topos)
    newPos = {x = topos.x, y = topos.y, z = topos.z, stackpos = 0}
    groundItem = getThingfromPos(newPos)
    blockingItem = getThingfromPos({x = topos.x, y = topos.y, z = topos.z, stackpos = 1})
    if(isInArray(ROPE_SPOT, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        newPos.z = newPos.z - 1
        if((blockingItem.itemid > 0 and not isInArray(POOLS, blockingItem.itemid)) or isCreature(groundItem.uid)) then
           doPlayerSendCancel(cid, "You cannot use this object.")
       else
           doTeleportThing(cid, newPos)
        end
    elseif(isInArray(OPENED_HOLE, groundItem.itemid) == TRUE or isInArray(OPENED_HOLE, item2.itemid) == TRUE or isInArray(OPENED_TRAP, groundItem.itemid) == TRUE or isInArray(DOWN_LADDER, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        downPos = {x = topos.x, y = topos.y, z = topos.z + 1, stackpos = 255}
        downItem = getThingfromPos(downPos)
        if(downItem.itemid > 0) then
            doTeleportThing(downItem.uid, newPos)
        else
            doPlayerSendCancel(cid, "You cannot use this object.")
        end
    end
    return true
end

PD: POOLS, OPENED_HOLE and DOWN_LADDER tables are working just fine.
 
Solution
I'm using Othire 1.0.

How it is supposed to work:
You can't use rope if creature or item is on rope spot, fluids like blood doesn't prevent you of using rope spot.

Problem:
When fluid is on rope spot, you can use rope even if creature or item is above it.

Action Script:


Lua:
-- Rope for 7.4 protocol.
function onUse(cid, item, frompos, item2, topos)
    newPos = {x = topos.x, y = topos.y, z = topos.z, stackpos = 0}
    groundItem = getThingfromPos(newPos)
    blockingItem = getThingfromPos({x = topos.x, y = topos.y, z = topos.z, stackpos = 1})
    if(isInArray(ROPE_SPOT, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        newPos.z = newPos.z - 1
        if((blockingItem.itemid > 0 and not...
I'm using Othire 1.0.

How it is supposed to work:
You can't use rope if creature or item is on rope spot, fluids like blood doesn't prevent you of using rope spot.

Problem:
When fluid is on rope spot, you can use rope even if creature or item is above it.

Action Script:


Lua:
-- Rope for 7.4 protocol.
function onUse(cid, item, frompos, item2, topos)
    newPos = {x = topos.x, y = topos.y, z = topos.z, stackpos = 0}
    groundItem = getThingfromPos(newPos)
    blockingItem = getThingfromPos({x = topos.x, y = topos.y, z = topos.z, stackpos = 1})
    if(isInArray(ROPE_SPOT, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        newPos.z = newPos.z - 1
        if((blockingItem.itemid > 0 and not isInArray(POOLS, blockingItem.itemid)) or isCreature(groundItem.uid)) then
           doPlayerSendCancel(cid, "You cannot use this object.")
       else
           doTeleportThing(cid, newPos)
        end
    elseif(isInArray(OPENED_HOLE, groundItem.itemid) == TRUE or isInArray(OPENED_HOLE, item2.itemid) == TRUE or isInArray(OPENED_TRAP, groundItem.itemid) == TRUE or isInArray(DOWN_LADDER, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        downPos = {x = topos.x, y = topos.y, z = topos.z + 1, stackpos = 255}
        downItem = getThingfromPos(downPos)
        if(downItem.itemid > 0) then
            doTeleportThing(downItem.uid, newPos)
        else
            doPlayerSendCancel(cid, "You cannot use this object.")
        end
    end
    return true
end

PD: POOLS, OPENED_HOLE and DOWN_LADDER tables are working just fine.
Try this
Lua:
-- Rope for 7.4 protocol.
function onUse(cid, item, frompos, item2, topos)
    local newPos = {x = topos.x, y = topos.y, z = topos.z, stackpos = 0}
    local groundItem = getThingfromPos(newPos)
    local blockingItem = getThingfromPos({x = topos.x, y = topos.y, z = topos.z, stackpos = 255})
    if(isInArray(ROPE_SPOT, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        newPos.z = newPos.z - 1
        if((blockingItem.itemid > 0 and not isInArray(POOLS, blockingItem.itemid)) or isCreature(blockingItem.uid)) then
            doPlayerSendCancel(cid, "You cannot use this object.")
        else
            doTeleportThing(cid, newPos)
        end
    elseif(isInArray(OPENED_HOLE, groundItem.itemid) == TRUE or isInArray(OPENED_HOLE, item2.itemid) == TRUE or isInArray(OPENED_TRAP, groundItem.itemid) == TRUE or isInArray(DOWN_LADDER, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        local downPos = {x = topos.x, y = topos.y, z = topos.z + 1, stackpos = 255}
        local downItem = getThingfromPos(downPos)
        if(downItem.itemid > 0) then
            doTeleportThing(downItem.uid, newPos)
        else
            doPlayerSendCancel(cid, "You cannot use this object.")
        end
    end
    return true
end
 
Solution
I didn't get the code right. now blood works with item on top not to go up. ty
Try this
Lua:
-- Rope for 7.4 protocol.
function onUse(cid, item, frompos, item2, topos)
    local newPos = {x = topos.x, y = topos.y, z = topos.z, stackpos = 0}
    local groundItem = getThingfromPos(newPos)
    local blockingItem = getThingfromPos({x = topos.x, y = topos.y, z = topos.z, stackpos = 255})
    if(isInArray(ROPE_SPOT, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        newPos.z = newPos.z - 1
        if((blockingItem.itemid > 0 and not isInArray(POOLS, blockingItem.itemid)) or isCreature(blockingItem.uid)) then
            doPlayerSendCancel(cid, "You cannot use this object.")
        else
            doTeleportThing(cid, newPos)
        end
    elseif(isInArray(OPENED_HOLE, groundItem.itemid) == TRUE or isInArray(OPENED_HOLE, item2.itemid) == TRUE or isInArray(OPENED_TRAP, groundItem.itemid) == TRUE or isInArray(DOWN_LADDER, groundItem.itemid) == TRUE) then
        newPos.y = newPos.y + 1
        local downPos = {x = topos.x, y = topos.y, z = topos.z + 1, stackpos = 255}
        local downItem = getThingfromPos(downPos)
        if(downItem.itemid > 0) then
            doTeleportThing(downItem.uid, newPos)
        else
            doPlayerSendCancel(cid, "You cannot use this object.")
        end
    end
    return true
end
 
bump the script still has an error it ropes when there is item on liquid ( e.g put mace aswell on top of liquid it doesnt check full stack only if there is pool it stacks up.)
would itemEx check be better?
 
Last edited:
I'd check item2 (taret) as its assigned once someone clicks on the rope spot (e.g. when player is few SQM from spot and uses rope).
Unlike groundItem which is evaluated once action is executed based on target position, thus there's no way to do the trick with lootbags & autowalk:

 
I'd check item2 (taret) as its assigned once someone clicks on the rope spot (e.g. when player is few SQM from spot and uses rope).
Unlike groundItem which is evaluated once action is executed based on target position, thus there's no way to do the trick with lootbags & autowalk:

what trick?
 
@Jpstafe Just like shown on the video, stay few SQM from rope spot, use rope on it, player walks towards the spot, so now player can throw a lootbag onto the spot. Results: user can rope as he clicked when spot was clear, there's a bag on the spot so you can use rope on the hole to get the bag up.
For TFS 1.x you need to reduce timeBetweenActions to be able to throw something on the spot immediately after using rope.
 
@Jpstafe Just like shown on the video, stay few SQM from rope spot, use rope on it, player walks towards the spot, so now player can throw a lootbag onto the spot. Results: user can rope as he clicked when spot was clear, there's a bag on the spot so you can use rope on the hole to get the bag up.
For TFS 1.x you need to reduce timeBetweenActions to be able to throw something on the spot immediately after using rope.
If you want it to be like the real 7.4 with the trick working properly - there should be no restriction on the server's side at all. Which means that the server should proceed the action regardless of whether there are items on top of that square (but of course only if the rope was actually used on the ropespot, and not those top items). That restriction was handled purely on the client's side. It was the client that would normally stop you from roping from a trashed ropespot, not the server.
Morever, this applies to any 'use', 'use with' and 'move' action that invloves an object with other objects on top of it.
 
If you want it to be like the real 7.4 with the trick working properly - there should be no restriction on the server's side at all. Which means that the server should proceed the action regardless of whether there are items on top of that square (but of course only if the rope was actually used on the ropespot, and not those top items). That restriction was handled purely on the client's side. It was the client that would normally stop you from roping from a trashed ropespot, not the server.
Morever, this applies to any 'use', 'use with' and 'move' action that invloves an object with other objects on top of it.
Yea but it anyway worked similar, it checked whether it was clear rope spot once user clicked "use with" on it. Wich is exactly what you get in target of onUse, target is saved and persisted for the action until creature walks close to the rope spot (next to it), action gets executed and you can check what was the target at the time user initialized that click action. Even if someone in the meantime threw something on that rope spot target would still point to the clear rope spot as it was empty when user clicked on it, at least it works like that on TFS 1.x
Lua:
onUseRope(player, item, fromPosition, target, toPosition, isHotkey)

I'm only not sure about behavior once spot was covered with items, was player immeditiely stoped with error message "Sorry not possible" or he anyway started to walk towards the rope spot to display fail message once he's was next to it.

But most of the scripts simply take toPostion and check top item but it's already to late as LUA onUse action is executed only if user is 1SQM from rope spot and it's already too late to check, and I guess target was meant for such use cases to check what was initial target of action. It would be even unsafe to skip server check of target as client (custom otclient) could then trick the server to always think it clicked on empty rope spot.
C++:
void Game::playerUseItemEx(uint32_t playerId, const Position& fromPos, uint8_t fromStackPos, uint16_t fromSpriteId,
                           const Position& toPos, uint8_t toStackPos, uint16_t toSpriteId)

From what I also remember on some newer Tibia.dat rope spots were configured to be always on top so no matter what was on the top, target was always set to the rope spot. But changing that and checking target in action could allow to implement similar behavior but checks would be on server side.

Regarding these other actions move, so it was like if someone threw something on the item I'm currently "drraging" it would prevent server from letting me move the item as some item was thrown on top of that in the meantime or did I get that wrong?
Yea similar behavior actualy would be that it remembers that player starter "dragging" it when there was nothing on top of it so client can send action to server as player had it "in hands" before someone threw garbe on top of it. Yeaa that makes sense:
C++:
void Game::playerMoveThing(uint32_t playerId, const Position& fromPos, uint16_t spriteId, uint8_t fromStackPos,
                           const Position& toPos, uint8_t count)
 
Last edited:
I'm only not sure about behavior once spot was covered with items, was player immeditiely stoped with error message "Sorry not possible" or he anyway started to walk towards the rope spot to display fail message once he's was next to it.
If you only managed to send the packet of using a rope on a ropespot - it worked. There was no "sorry, not possible" message, regardless of how long it took to execute the action, and how much stuff was put on that ropespot in the meantime. That message would only appear if the rope was used on another item laying on a ropespot (client side).

It would be even unsafe to skip server check of target as client (custom otclient) could then trick the server to always think it clicked on empty rope spot.
You're right, but that's the way it worked.

From what I also remember on some newer Tibia.dat rope spots were configured to be always on top so no matter what was on the top, target was always set to the rope spot.
Those flags in Tibia.dat are for the client to know what should be drawn on the top or bottom. Ropespot had neither of these, because it was ground.
The difference later was the 'useable' flag and how the client interpreted it (in the code). Plus on the server's side they added ForceUse flag to the ropespots (same as the ladders had). This caused the action to be executed always on that object if it was only present on that square, regardless of its position on the stack. That's why in later versions you couldn't open containers (dead bodies for instance) or attack a creature on a ropespot (same as you can't do that under a ladder), because that flag made the ropespot take over these actions. But back in 7.4 you could still do that.

Regarding these other actions move, so it was like if someone threw something on the item I'm currently "drraging" it would prevent server from letting me move the item as some item was thrown on top of that in the meantime or did I get that wrong?
No, it's the opposite. In 7.4 the server would still allow you to move that item even if there was trash put on top of it. You could hold your mouse, wait for someone to throw other items, and you would still be able to retrieve your item from the bottom.
In later versions (>= 7.5) you couldn't do that anymore.

There was also a trick that allowed you to retrieve an item from the bottom, without pre-dragging and holding your mouse button. You only needed another item with the same ID as the one to retrieve. Than you had to put it on the top of the same stack, and try to 'move' from that square twice (as fast as possible). The server would receive two packets of moving an item of that ID from that exact square - and it would move both items. Because the server only checked if they existed on that square, but not their position on the stack. Using this trick you could for example easily retrieve your spears from under a poison field after killing a slime.

1mdxYWK.gif


Yea similar behavior actualy would be that it remembers that player starter "dragging" it when there was nothing on top of it so client can send action to server as player had it "in hands" before someone threw garbe on top of it.
It's not about remembering, it's just that there was no position-on-the-stack check on the server's side during these actions (use, use on, move). It was the client that normally would prevent you from moving/using stuff from the bottom, but you could still overcome that with these tricks (roping a lootbag, holding mouse button while dragging, double-retrieve etc.). You could manipulate the client also, as you said.
 
Last edited:
Back
Top