• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Lua use with block item

Darius93

Active Member
Joined
Oct 16, 2022
Messages
88
Reaction score
27
Hello, I have a problem. I have an item that I can click “Use with,” and when I select “Use with” and then click on some tile, it puts the item into my backpack even though moving the item is supposed to be blocked.


And how to fix it?
TFS 1.2:
C++:
// Player:onMoveItem(item, count, fromPosition, toPosition) or Player.onMoveItem(self, item, count, fromPosition, toPosition)

LUA:
    if item.itemid == 2421 then
        self:sendCancelMessage("Nie mozesz przesunac tego przedmiotu.")
        return false
    end

Can this be blocked? At least in C++ it's for life for itemid 2421
 
LUA:
ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, int32_t index,
                                   Item* item, uint32_t count, Item** _moveItem, uint32_t flags /*= 0*/, Creature* actor/* = nullptr*/, Item* tradeItem/* = nullptr*/)
{
    Item* toItem = nullptr;

    Cylinder* subCylinder;
    int floorN = 0;

    while ((subCylinder = toCylinder->queryDestination(index, *item, &toItem, flags)) != toCylinder) {
        toCylinder = subCylinder;
        flags = 0;

        //to prevent infinite loop
        if (++floorN >= MAP_MAX_LAYERS) {
            break;
        }
    }


    // === BLOCK MOVING ITEM 2421 INTO PLAYER INVENTORY OR BACKPACK ===
    if (item->getID() == 2421) {

        // 1. Jeśli celem jest Player (ekwipunek)
        if (dynamic_cast<Player*>(toCylinder)) {
            return RETURNVALUE_NOTPOSSIBLE;
        }

        // 2. Jeśli celem jest Container, sprawdzamy kto go posiada
        if (Container* container = dynamic_cast<Container*>(toCylinder)) {

            Cylinder* parent = container->getParent();

            while (parent) {
                // Jeśli któryś rodzic jest graczem → plecak/equipment gracza
                if (dynamic_cast<Player*>(parent)) {
                    return RETURNVALUE_NOTPOSSIBLE;
                }

                parent = parent->getParent();
            }
        }
    }
    // === END BLOCK ===


It works :D
 
Creating a maintainable server requires you to think forward, and GPT won't do it for you.
You should never fix ad hoc. What if you find another item you want to block?

The problem is this if statement, it executes after we already scheduled the walk and item collecting (in L#972)
I suggest you move it to the top of Game::internalMoveItem, so it will returns in the aforementioned line.
Just make sure that you avoid calling that event if actor, fromPos, toPos are nullptr (by default - they are) or if they are dereferenced further down the line.

so it looks something like this
C++:
ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, int32_t index,
                                   Item* item, uint32_t count, Item** _moveItem, uint32_t flags /*= 0*/, Creature* actor/* = nullptr*/, Item* tradeItem/* = nullptr*/, const Position* fromPos /*= nullptr*/, const Position* toPos/*= nullptr*/){
    if (actor && fromPos && toPos) {
        const ReturnValue ret = g_events->eventPlayerOnMoveItem(actor, item, count, *fromPos, *toPos, fromCylinder, toCylinder);
        if (ret != RETURNVALUE_NOERROR) {
            return ret;
        }
    }
 
    ...
 
Last edited:
Back
Top