• 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+ Check container/toCylinder

peteralto

Member
Joined
Nov 1, 2020
Messages
116
Solutions
1
Reaction score
22
I'm trying to insert a check inside the onMoveItem player. I would like to prevent the player from moving an item from the ring slot to a container that has the term dead in the name.

I tried the following code:
LUA:
if fromPosition.y == CONST_SLOT_RING and toCylinder then
        local isContainerOrCorpse = toCylinder:isContainer() or toCylinder:isCorpse()
        if isContainerOrCorpse then
            local containerName = toCylinder:getName()
            if containerName and string.find(containerName:lower(), "dead") then
                return false
            end
        end
    end

Apparently the check works, but when trying to move the item to a tile, for example, I am blocked and receive an error:
Lua Script Error: [Event Interface]
data/events/scripts/player.lua: Player@onMoveItem
...ata\scripts\eventcallbacks\player\default_onMoveItem.lua:87: attempt to call method 'isContainer' (a nil value)
 
Try to change:
LUA:
if fromPosition.y == CONST_SLOT_RING and toCylinder then
to:
LUA:
if fromPosition.y == CONST_SLOT_RING and toCylinder and Container(toCylinder) then
Container(toCylinder) will check (convert toCylinder into Container object in C++ or return nil [false], if it fails), if toCylinder is kind of Container (BP/bag and dead body are kinds of Container)
toCylinder is very wide range of objects in OTS (almost everything except Item is kind of Cylinder). It can be Container, but it can be also Player (add into slot of player) or Tile (drop on ground).
 
The container constructor expects a unique id so it won't work, you must explicitly check if is an item and then a container

LUA:
if fromPosition.y == CONST_SLOT_RING and (toCylinder and toCylinder:isItem() and toCylinder:isContainer()) then

    local parent = toCylinder
    while(parent) do

        if not parent:isItem() then
            break
        end

        if parent:getName():match("dead") then
            return false
        end

        parent = parent:getParent()
    end
end

This code should cover child containers too (just in case is necessary).

There is still some flaws, such as match method matching unexpected words (you could use the isCorpse method instead) or the check not working if the container (the one with 'dead' on his name) is a subcontainer and you add/move an item to the container without it being open (toCylinder will be the parent, not the actual container).
 
The container constructor expects a unique id so it won't work,
They fucked-up that engine to point I cannot even imagine.
How Lua can be so out-of-date? x:isContainer() works on some objects - not all - and Container(x) fails to detect Container structure in C++.
 
How Lua can be so out-of-date? x:isContainer() works on some objects - not all - and Container(x) fails to detect Container structure in C++.
Ah my bad, you can call the isContainer() method on the base classes (I just checked) but yes.. I agree on the constructor part but I assume there must be a reason behind? Otherwise makes no sense because you can actually do what you suggested but with the Player constructor only.
 
Try to change:
LUA:
if fromPosition.y == CONST_SLOT_RING and toCylinder then
to:
LUA:
if fromPosition.y == CONST_SLOT_RING and toCylinder and Container(toCylinder) then
Container(toCylinder) will check (convert toCylinder into Container object in C++ or return nil [false], if it fails), if toCylinder is kind of Container (BP/bag and dead body are kinds of Container)
toCylinder is very wide range of objects in OTS (almost everything except Item is kind of Cylinder). It can be Container, but it can be also Player (add into slot of player) or Tile (drop on ground).
It didn't really work that way, but there were no errors either.


The container constructor expects a unique id so it won't work, you must explicitly check if is an item and then a container

LUA:
if fromPosition.y == CONST_SLOT_RING and (toCylinder and toCylinder:isItem() and toCylinder:isContainer()) then

    local parent = toCylinder
    while(parent) do

        if not parent:isItem() then
            break
        end

        if parent:getName():match("dead") then
            return false
        end

        parent = parent:getParent()
    end
end

This code should cover child containers too (just in case is necessary).

There is still some flaws, such as match method matching unexpected words (you could use the isCorpse method instead) or the check not working if the container (the one with 'dead' on his name) is a subcontainer and you add/move an item to the container without it being open (toCylinder will be the parent, not the actual container).
This way worked.
What would the code look like using the isCorpse method? Thank you.
 
They fucked-up that engine to point I cannot even imagine.
How Lua can be so out-of-date? x:isContainer() works on some objects - not all - and Container(x) fails to detect Container structure in C++.
I agree that the whole "isSomething" implementation is poor, because its in every single table in lua added by hand, so some classes are missing it.
Containers never supported anything else than uid in lua constructor though.
 
Back
Top