• 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.X+ Why doRemoveItemById works so weirdly?

overdriven

Active Member
Joined
Mar 10, 2020
Messages
70
Solutions
1
Reaction score
42
Scenario: a lever removing blocking item. After many trial end error iterations I've finally made it working but code wise it just doesn't seem right:

Lua:
local blockingStonePos = {x = 32620, y = 31971, z = 11}
 
function onUse(player, item, fromPosition, itemEx, toPosition)
    if(item.actionid == 52413) then
            if(item.itemid == 1945) then
                doTransformItem(item.uid, 1946)
                doCreateItem(1304,1,blockingStonePos)

            elseif(item.itemid == 1946) then
                doTransformItem(item.uid, 1945)
                doRemoveItem(getTileItemById(blockingStonePos,1304).uid, 1) -- with stack pos 1 alone it doesn't work!
                doRemoveItem(getTileItemById(blockingStonePos,1304).uid, 2) -- with stack pos 2 alone it doesn't work!
            end
    end
    return true
end

Why do I have to remove the item twice?

If I try to remove the item from first stack position it doesn't do anything. If I try to remove it from second stack pos it doesn't work either. Only when I remove simultaneously from first and second stack pos it works. Very weird.

I'm using TFS 1.5 with Nekiro's downgrade (github.com/nekiro/TFS-1.5-Downgrades/tree/7.72).
 
Scenario: a lever removing blocking item. After many trial end error iterations I've finally made it working but code wise it just doesn't seem right:

Lua:
local blockingStonePos = {x = 32620, y = 31971, z = 11}
 
function onUse(player, item, fromPosition, itemEx, toPosition)
    if(item.actionid == 52413) then
            if(item.itemid == 1945) then
                doTransformItem(item.uid, 1946)
                doCreateItem(1304,1,blockingStonePos)

            elseif(item.itemid == 1946) then
                doTransformItem(item.uid, 1945)
                doRemoveItem(getTileItemById(blockingStonePos,1304).uid, 1) -- with stack pos 1 alone it doesn't work!
                doRemoveItem(getTileItemById(blockingStonePos,1304).uid, 2) -- with stack pos 2 alone it doesn't work!
            end
    end
    return true
end

Why do I have to remove the item twice?

If I try to remove the item from first stack position it doesn't do anything. If I try to remove it from second stack pos it doesn't work either. Only when I remove simultaneously from first and second stack pos it works. Very weird.

I'm using TFS 1.5 with Nekiro's downgrade (github.com/nekiro/TFS-1.5-Downgrades/tree/7.72).
Assuming that there isn't a map mistake, and there are actually 2 stone's on that position..

Lever 1945 is the left position.
My guess is that you are flopping the lever and adding an additional item to that position, then flopping it a second time and attempting to remove.

So the solution is to swap your conditions around.
The 'blocking item' should be removed when 1945 is used, and it should then be re-added when the lever is used at 1946.

Or (and the way I'm going to code it for you) we ignore the lever's id entirely, and just check the tile to see if the blocking item is there.
If it's there, remove it.
If it's not there, add it.

Either way, you should get used to using tfs 1.x functions instead of using the compat functions.
It'll make your life a lot easier.

Lua:
local blockingItemPos = Position(32620, 31971, 11)
local blockingItemId = 1304
local levers = {1945, 1946}
 
function onUse(player, item, fromPosition, target, toPosition)
    local tile = Tile(blockingItemPos)
    if not tile then
        print("Position is incorrect, or there is no tile on this location.")
        return true
    end
   
    local blockingItem = tile:getItemById(blockingItemId)
   
    if blockingItem then
        blockingItem:remove()
    else
        Game.createItem(blockingItemId, 1, blockingItemPos)
    end
   
    item:transform(item:getId() == levers[1] and levers[2] or levers[1])
    return true
end
 
Of course (-‸ლ) First time I was pulling the lever I was in fact adding an item on top of existing same item. I totally forgot there can be same blocking items on one stack. And there was no way I could notice that from client side, since they look the same.

I've used this occasion to improve the code and check if there are no creatures and no items at all before restoring stone.

Lua:
-- restore obstacle (BUT only if there is no item AND no creature there)
local tile = Tile(blockingItemPos)
if (getTableLength(tile:getItems()) == 0 and tile:getTopCreature() == nil) then
   -- doCreateItem(1304,1,blockingItemPos)
   Game.createItem(blockingItemId, 1, blockingItemPos) -- new TFS 1.x function
end

getTableLength is my custom utility function to count items on tile, but maybe there is a out-of-the-box equivalent in TFS for that already?

Thanks for the hint about tfs 1.x functions. I was looking at old posts and everywhere old syntax was used.
 
Last edited:
getTableLength is my custom utility function to count items on tile, but maybe there is a out-of-the-box equivalent in TFS for that already?
tile:getItemCount() or #tile:getItems()

Also its a good practice to first validate userdata, in this case Tile otherwise it could crash your server
Lua:
local tile = Tile(blockingItemPos)
if tile and #tile:getItems() == 0 and not tile:getTopCreature() then
    Game.createItem(blockingItemId, 1, blockingItemPos) -- new TFS 1.x function
end
 
Back
Top