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

TFS 1.2 Problem with fields, fields is not "under" level doors.

anyeor

Member
Joined
Jan 6, 2010
Messages
108
Solutions
2
Reaction score
16
Hello,

Can anyone tell me in what function in tfs need to be changed so that the fields are under level doors, or that the door and ladders are always above the objects so that if there are objects under the ladder, you could use it?

Thanks!
 
Hello,

Can anyone tell me in what function in tfs need to be changed so that the fields are under level doors, or that the door and ladders are always above the objects so that if there are objects under the ladder, you could use it?

Thanks!
There may be something within sources, I'm not 100% sure. But I believe this is client sided. Are you using tibia client or OtClient?
If you are using OTC then there is a way within a lua script to determine the stack position on tiles.
 
Fairly certain this is clientside but you should be able to use ladders through fields, they have a property called "forceUse" (I think?) which allows this. Doors don't seem to have this property so you would have to get creative with a solution to this unless you wanted to use a custom dat/spr.

Off the top of my head, you could set an action on fields which when used, checks the tile for a door. If it finds a door, open or close it.
From there you would just have to mess with cosmetics such as pushing items out of the door and/or removing the field. It may also be possible to "recreate" the door at the position once you open/close it to force it on top of the field/items. This seems a bit janky but such is life when you are trying to build around the normal client.
 
Hello,

Can anyone tell me in what function in tfs need to be changed so that the fields are under level doors, or that the door and ladders are always above the objects so that if there are objects under the ladder, you could use it?

Thanks!
I better idea would be to just query the tile where it checks to see if there is a ladder, door, rope spot or hole in the stack and then proceed as normal allowing you to execute opening/closing the door or using the ladder/rope spot/hole.
 
Can anyone help me? :(
The main problem is the client sends the item that is to be used before the server picks it up. You could do a source edit to get the tile and check if tile has a door or not but it would be easier to use in Lua.

I've made this work around, you'll have to register the onUse action for all field items you want this to apply to and you'll also have to add all ladder id's in the ladder array.

If you want to keep the field item there when door is shut then remove the line with "item:remove()".

Lua:
local ladders = {1386} -- add ladder id's here

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

    local tile_items, player_pos = tile:getItems(), player:getPosition()
    for key, tile_item in pairs(tile_items) do
        if player_pos ~= toPosition and isInArray(levelDoors, tile_item.itemid) then
            if tile_item.actionid > 0 and player:getLevel() >= tile_item.actionid - 1000 then
                item:transform(tile_item.itemid + 1)
                player:teleportTo(toPosition, true)
            else
                player:sendTextMessage(MESSAGE_INFO_DESCR, "Only the worthy may pass.")
            end
            break
        elseif isInArray(verticalOpenDoors, tile_item.itemid) or isInArray(horizontalOpenDoors, tile_item.itemid) then
            local doorCreature, original_id = Tile(toPosition):getTopCreature(), tile_item.itemid
            if doorCreature then
                toPosition.x = toPosition.x + 1
                local query = Tile(toPosition):queryAdd(doorCreature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING))
                if query ~= RETURNVALUE_NOERROR then
                    toPosition.x = toPosition.x - 1
                    toPosition.y = toPosition.y + 1
                    query = Tile(toPosition):queryAdd(doorCreature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING))
                end
   
                if query ~= RETURNVALUE_NOERROR then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, Game.getReturnMessage(query))
                    return true
                end
   

                doorCreature:teleportTo(toPosition, true)
            end

            item:remove()
            if original_id == tile_item.itemid then
                tile_item:transform(tile_item.itemid - 1)
            end
            break
        elseif isInArray(ladders, tile_item.itemid) then
            player:teleportTo(toPosition:moveUpstairs())
            break
        end
    end
    return true
end
 
Last edited:
The main problem is the client sends the item that is to be used before the server picks it up. You could do a source edit to get the tile and check if tile has a door or not but it would be easier to use in Lua.

I've made this work around, you'll have to register the onUse action for all field items you want this to apply to and you'll also have to add all ladder id's in the ladder array.

If you want to keep the field item there when door is shut then remove the line with "item:remove()".

Lua:
local ladders = {1386} -- add ladder id's here

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

    local tile_items, player_pos = tile:getItems(), player:getPosition()
    for key, tile_item in pairs(tile_items) do
        if player_pos ~= toPosition and isInArray(levelDoors, tile_item.itemid) then
            if tile_item.actionid > 0 and player:getLevel() >= tile_item.actionid - 1000 then
                item:transform(tile_item.itemid + 1)
                player:teleportTo(toPosition, true)
            else
                player:sendTextMessage(MESSAGE_INFO_DESCR, "Only the worthy may pass.")
            end
            break
        elseif isInArray(verticalOpenDoors, tile_item.itemid) or isInArray(horizontalOpenDoors, tile_item.itemid) then
            local doorCreature, original_id = Tile(toPosition):getTopCreature(), tile_item.itemid
            if doorCreature then
                toPosition.x = toPosition.x + 1
                local query = Tile(toPosition):queryAdd(doorCreature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING))
                if query ~= RETURNVALUE_NOERROR then
                    toPosition.x = toPosition.x - 1
                    toPosition.y = toPosition.y + 1
                    query = Tile(toPosition):queryAdd(doorCreature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING))
                end
  
                if query ~= RETURNVALUE_NOERROR then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, Game.getReturnMessage(query))
                    return true
                end
  

                doorCreature:teleportTo(toPosition, true)
            end

            item:remove()
            if original_id == tile_item.itemid then
                tile_item:transform(tile_item.itemid - 1)
            end
            break
        elseif isInArray(ladders, tile_item.itemid) then
            player:teleportTo(toPosition:moveUpstairs())
            break
        end
    end
    return true
end
Hello, big thanks for answer! I need fix in source codes, my tile.cpp like this: /** * The Forgotten Server - a free and open-source MMORPG server emulator * - Pastebin.com (https://pastebin.com/6nXnGVC1) what is name of function to fix it? Thanks a lot!
 
Why do you need a source code fix with this Lua edit will work the same way?
I start the adventure with C ++ and I want to learn how to solve similar problems in the future :) Thanks to the fact that you support my knowledge, I think it is a good investment in personal development.
 
I start the adventure with C ++ and I want to learn how to solve similar problems in the future :) Thanks to the fact that you support my knowledge, I think it is a good investment in personal development.
Well if you need to do it in source code, it's picked up from the client in function ProtocolGame::parseUseItem then it's sent to Game::playerUseItem.
 
You are not carefully reading my post. I've told you what to do:
you'll have to register the onUse action for all field items you want this to apply to
So register them in your actions.xml and set the itemid to the field item's id and this script will go in the scripts folder within that directory. You'll have to repeat this for ALL field items (ex: fire field, energy field, poison field) and for all sizes of it because fields decay to other item id's as they get smaller.

Take a moment to read through the actions directory and learn how these function are handled.

You say you're on the adventure to learn but so far it looks like you are not trying very hard to solve your problem, especially when someone is literally handing the solution to you.
 
Back
Top