• 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+ Trying to block player from putting a bag in a backpack or bag in a bag TFS 1.4.2

TheoldSchoolWay

New Member
Joined
Nov 27, 2022
Messages
5
Reaction score
1
Hey guys, I've working with TFS 1.4.2 and I am struggling to find a way to block the player from putting a bag(or backpack/crate/any other container) inside their currently equipped backpack. Im sure it has something to do with the onEquip function but try as i might i cant get it to work. I cant even get anything i have tried not to throw an error(c++ exception). Also, I'm trying to do this as a rev script.

Basically I cant figure out how to use onEquip(if that's what I even need) as a revscript. Can someone point me in the right direction?
 
Hey guys, I've working with TFS 1.4.2 and I am struggling to find a way to block the player from putting a bag(or backpack/crate/any other container) inside their currently equipped backpack. Im sure it has something to do with the onEquip function but try as i might i cant get it to work. I cant even get anything i have tried not to throw an error(c++ exception). Also, I'm trying to do this as a rev script.

Basically I cant figure out how to use onEquip(if that's what I even need) as a revscript. Can someone point me in the right direction?
data/scripts/script.lua
Lua:
local ec = EventCallback

function ec.onMoveItem(player, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if toPosition.x ~= CONTAINER_POSITION or not item:getType():isContainer() then
        return RETURNVALUE_NOERROR
    end

    if toCylinder == player or toCylinder:getTopParent() == player then
        if bit.band(toPosition.y, 0x40) == 0 then
            local slotItem = player:getSlotItem(toPosition.y)
            if slotItem and slotItem:getType():isContainer() then
                return RETURNVALUE_NOTMOVEABLE
            end
        else
            return RETURNVALUE_NOTMOVEABLE
        end
    end
    return RETURNVALUE_NOERROR
end

ec:register(-11)

If returnvalue doesn't work for you, use booleans:
Lua:
local ec = EventCallback

function ec.onMoveItem(player, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if toPosition.x ~= CONTAINER_POSITION or not item:getType():isContainer() then
        return true
    end

    if toCylinder == player or toCylinder:getTopParent() == player then
        if bit.band(toPosition.y, 0x40) == 0 then
            local slotItem = player:getSlotItem(toPosition.y)
            if slotItem and slotItem:getType():isContainer() then
                return false
            end
        else
            return false
        end
    end
    return true
end

ec:register(-11)

Notes:
It is possible that someone manages to stack backpacks inside others through other means, such as with trade or an npc, ect...
I haven't tried all the scenarios though.
 
Last edited:
Thanks so much for this. It is definitely a start, however I tried both versions with no success. Putting print statements in before each return shows that the script is firing, but nothing is being blocked. Would it be simpler if i used an action id on all bps or something?
PS: What does -11 mean at the end?
 
Thanks so much for this. It is definitely a start, however I tried both versions with no success. Putting print statements in before each return shows that the script is firing, but nothing is being blocked. Would it be simpler if i used an action id on all bps or something?
PS: What does -11 mean at the end?
If the script is executed until these two return false the object should not move.
I tried it on my test server and it works perfectly.
1673136754831.png
In case neither return works, make sure you have the onMoveItem event enabled in the events.xml file.
If it still doesn't work... then I'd be hard pressed to think that you're actually using official TFS 1.4.2, I don't recall this event not working on that release version.

the number that is sent as an argument in the registry, is the order of execution of the script, the default script is executed at index 0, so -11 being less than 0, this script will be executed first before the script EC = data/scripts/eventcallbacks/player/default_onMoveItem.lua

It doesn't matter much in this specific case, but it's good that you ask, because this is how I explain it to you right now.
If this script were executed at an index greater than 0, then EC would be executed first, before the script I posted.
The small advantage of running first is that we avoid all the unnecessary checking of the default script.

If you wonder in which case the order of execution is more relevant, the answer is:
in experience/skill gain or experience/skill loss events and possibly in an onDamage event if you're in OTBR
 
Back
Top