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

Lua [TFS 0.4] block player to add item to certain container

magista

RL name " Amir reda "
Joined
Jul 22, 2011
Messages
157
Solutions
1
Reaction score
21
Location
Egypt
I am trying to make event bag which will be given to a player after wining the event. I need to block player to add any item to this event bag and give him error message " You can't add items to this bag ".

idk if there is a function to check when player add items to bag or not. so do someone have an idea about how to create this function ?
 
Solution
Okey i created some codes for u can use depot chest for reward chest.
you need go to

luascript.cpp
search this
C++:
//getPlayerDepotItems(cid, depotid)
    lua_register(m_luaState, "getPlayerDepotItems", LuaInterface::luaGetPlayerDepotItems);
put this after
C++:
//getPlayerDepotId(cid, depotid)
    lua_register(m_luaState, "getPlayerDepotId", LuaInterface::luaGetPlayerDepotId);
search
C++:
int32_t LuaInterface::luaGetPlayerDepotItems(lua_State* L)
and put this after
C++:
int32_t LuaInterface::luaGetPlayerDepotId(lua_State* L)
{
    //getPlayerDepotId(cid, depotid)
    uint32_t depotid = popNumber(L);

    ScriptEnviroment* env = getEnv();
    if(Player* player = env->getPlayerByUID(popNumber(L)))
    {
        if(depotid)...
I'm pretty sure there isn't enough functionality by default to accomplish this, and would need to be done via source edit.

Some of the most annoying scenario's occur when the player is receiving items, from the server.
When that happens, it only checks for available space in the player inventory.. and if all the spaces are full except your event bag.. then it'll shove shit into the event bag.

1) npc buy / sell (items being bought, or gold/platinum/crystal coins being pushed into the container)
2) player trade - if no space, then entire items / containers could be put into the event bag.. and then the player would bypass all of your checks by using the container inside.
3/4) getting loot from an auto-looter or from a quest reward.. et cetera. All the same issue.

--
But maybe I'm over-thinking it, and there is a solution out there.

Good luck in finding it.
 
I'm pretty sure there isn't enough functionality by default to accomplish this, and would need to be done via source edit.

Some of the most annoying scenario's occur when the player is receiving items, from the server.
When that happens, it only checks for available space in the player inventory.. and if all the spaces are full except your event bag.. then it'll shove shit into the event bag.

1) npc buy / sell (items being bought, or gold/platinum/crystal coins being pushed into the container)
2) player trade - if no space, then entire items / containers could be put into the event bag.. and then the player would bypass all of your checks by using the container inside.
3/4) getting loot from an auto-looter or from a quest reward.. et cetera. All the same issue.

--
But maybe I'm over-thinking it, and there is a solution out there.

Good luck in finding it.

Actually you are tottaly right but lets say i will make a event reward depot chest wich send the event bag to this chest (bag will not be pickable) and once player taking all the event items the bag will be deleted - but again i need to block player to add items, what i am thinking is to add this event bag id to the same function which return RET_DEPOTISFULL or something similar.
 
I don't know of any TFS 0.4 where you can do this via lua, since no onMoveItem event exists, and if it does exist it surely doesn't have the value toCylinder, we also don't have a method to get the object in question based on the position on the client.

so the fastest option would be to add an IF here

example
C++:
if (toCylinder->isItem() && toCylinder->getId() == XXXX) {
    player->sendCancelMessage(RET_NOTMOVEABLE);
    return false;
}

In this way it would block any movement of objects towards the container that has the specific ID in the XXXX

The other option would be to improve the onMoveItem event and add extra information to it, such as toCylinder, so that you could handle it in lua.
 
I don't know of any TFS 0.4 where you can do this via lua, since no onMoveItem event exists, and if it does exist it surely doesn't have the value toCylinder, we also don't have a method to get the object in question based on the position on the client.

so the fastest option would be to add an IF here

example
C++:
if (toCylinder->isItem() && toCylinder->getId() == XXXX) {
    player->sendCancelMessage(RET_NOTMOVEABLE);
    return false;
}

In this way it would block any movement of objects towards the container that has the specific ID in the XXXX

The other option would be to improve the onMoveItem event and add extra information to it, such as toCylinder, so that you could handle it in lua.
I think it has this
Lua:
onThrow(cid, item, fromPosition, toPosition)

and toPosition.z is the container position.. when toPosition.x is 65535

So you could feasibly check if there is an item at that position, maybe?

idk if there is a function to check the parent container tho.

 
I think it has this
Lua:
onThrow(cid, item, fromPosition, toPosition)

and toPosition.z is the container position.. when toPosition.x is 65535

So you could feasibly check if there is an item at that position, maybe?

idk if there is a function to check the parent container tho.

You can only tell if it's a container position, but if you block this, then all containers would be blocked.
The idea is to block only a specific backpack, whether it has an actionId, or a specific itemId or uniqueId, ect...
 
Okey i created some codes for u can use depot chest for reward chest.
you need go to

luascript.cpp
search this
C++:
//getPlayerDepotItems(cid, depotid)
    lua_register(m_luaState, "getPlayerDepotItems", LuaInterface::luaGetPlayerDepotItems);
put this after
C++:
//getPlayerDepotId(cid, depotid)
    lua_register(m_luaState, "getPlayerDepotId", LuaInterface::luaGetPlayerDepotId);
search
C++:
int32_t LuaInterface::luaGetPlayerDepotItems(lua_State* L)
and put this after
C++:
int32_t LuaInterface::luaGetPlayerDepotId(lua_State* L)
{
    //getPlayerDepotId(cid, depotid)
    uint32_t depotid = popNumber(L);

    ScriptEnviroment* env = getEnv();
    if(Player* player = env->getPlayerByUID(popNumber(L)))
    {
        if(depotid)
            lua_pushnumber(L, depotid);
        else
            lua_pushboolean(L, false);
    }
    else
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
    }

    return 1;
}

in luascript.h
search
C++:
static int32_t luaGetPlayerDepotItems(lua_State* L);
add this after
C++:
static int32_t luaGetPlayerDepotId(lua_State* L);

now go to data/creaturescripts/script
add this depotreward.lua Remember change depotidblock for your depottownidblock move items inside
Lua:
local depots = {2589, 2590, 2591, 2592}
local depotidblock = 2
function onMoveItem(moveItem, frompos, position, cid)
        local depotPos, depot = position, {}
        depotPos.stackpos = STACKPOS_GROUND
        while(true) do
            if(not getTileInfo(depotPos).depot) then
                break
            end
 
            depotPos.stackpos = depotPos.stackpos + 1
            depot = getThingFromPos(depotPos)
            if(depot.uid == 0) then
                break
            end
 
            if(isInArray(depots, depot.itemid)) then
                local depotid = getPlayerDepotId(cid, getDepotId(depot.uid))
                if(depotid == depotidblock) then
                doPlayerSendCancel(cid, "You cannot move items in to reward chest.")
                return false;
                end
                break
            end
        end

        return true
end
after add this in creaturescripts.xml
XML:
<event type="moveitem" name="MoveItemDepotReward" event="script" value="depotreward.lua"/>
remember add register into data/creaturescripts/login.lua
Lua:
registerCreatureEvent(cid, "MoveItemDepotReward")
 
Solution
Okey i created some codes for u can use depot chest for reward chest.
you need go to

luascript.cpp
search this
C++:
//getPlayerDepotItems(cid, depotid)
    lua_register(m_luaState, "getPlayerDepotItems", LuaInterface::luaGetPlayerDepotItems);
put this after
C++:
//getPlayerDepotId(cid, depotid)
    lua_register(m_luaState, "getPlayerDepotId", LuaInterface::luaGetPlayerDepotId);
search
C++:
int32_t LuaInterface::luaGetPlayerDepotItems(lua_State* L)
and put this after
C++:
int32_t LuaInterface::luaGetPlayerDepotId(lua_State* L)
{
    //getPlayerDepotId(cid, depotid)
    uint32_t depotid = popNumber(L);

    ScriptEnviroment* env = getEnv();
    if(Player* player = env->getPlayerByUID(popNumber(L)))
    {
        if(depotid)
            lua_pushnumber(L, depotid);
        else
            lua_pushboolean(L, false);
    }
    else
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
    }

    return 1;
}

in luascript.h
search
C++:
static int32_t luaGetPlayerDepotItems(lua_State* L);
add this after
C++:
static int32_t luaGetPlayerDepotId(lua_State* L);

now go to data/creaturescripts/script
add this depotreward.lua Remember change depotidblock for your depottownidblock move items inside
Lua:
local depots = {2589, 2590, 2591, 2592}
local depotidblock = 2
function onMoveItem(moveItem, frompos, position, cid)
        local depotPos, depot = position, {}
        depotPos.stackpos = STACKPOS_GROUND
        while(true) do
            if(not getTileInfo(depotPos).depot) then
                break
            end
 
            depotPos.stackpos = depotPos.stackpos + 1
            depot = getThingFromPos(depotPos)
            if(depot.uid == 0) then
                break
            end
 
            if(isInArray(depots, depot.itemid)) then
                local depotid = getPlayerDepotId(cid, getDepotId(depot.uid))
                if(depotid == depotidblock) then
                doPlayerSendCancel(cid, "You cannot move items in to reward chest.")
                return false;
                end
                break
            end
        end

        return true
end
after add this in creaturescripts.xml
XML:
<event type="moveitem" name="MoveItemDepotReward" event="script" value="depotreward.lua"/>
remember add register into data/creaturescripts/login.lua
Lua:
registerCreatureEvent(cid, "MoveItemDepotReward")

It is more than perfect.

Thanks @supermortaliz

Also thanks for everyone tried to help.
 
Back
Top