• 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.4.2 onMoveItem does not react?

Marko999x

999x era
Premium User
Joined
Dec 14, 2017
Messages
2,864
Solutions
82
Reaction score
1,967
Location
Germany
For some reason item can still be moved, idk why.
It worked perfect on TFS 1.5 while TFS 1.4.2 react weird.
Maybe you guys can see the problem here :D

Lua:
local ids = {9999, 6000}

local ec = EventCallback

ec.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if table.contains(ids, item:getActionId()) and toPosition.x ~= CONTAINER_POSITION then
        self:sendTextMessage(MESSAGE_INFO_DESCR, 'This item can not be moved.')
        return RETURNVALUE_NOTPOSSIBLE
    end
    return RETURNVALUE_NOERROR

end
ec:register()
 
Last edited:
For some reason item can still be moved, idk why.
It worked perfect on TFS 1.5 while TFS 1.4.2 react weird.
Maybe you guys can see the problem here :D

Lua:
local ids = {9999, 6000}

local ec = EventCallback

ec.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if table.contains(ids, item:getActionId()) and toPosition.x ~= CONTAINER_POSITION then
        self:sendTextMessage(MESSAGE_INFO_DESCR, 'This item can not be moved.')
        print(1)
        return RETURNVALUE_NOTPOSSIBLE
    end
    print(2)
    return RETURNVALUE_NOERROR

ec:register(-11)
end
Maybe change NOERROR to true and NOTPOSSIBLE to false?
 
Maybe change NOERROR to true and NOTPOSSIBLE to false?

I've tried everything but nothing has worked

Tried true,false,notpossible,not error and used print to see if something is wrong but it didn't work.
Ended up using Nekiros onMoveItem code and this is working with return true and false :p
 
I've tried everything but nothing has worked

Tried true,false,notpossible,not error and used print to see if something is wrong but it didn't work.
Ended up using Nekiros onMoveItem code and this is working with return true and false :p
Share nekiro code please?
 
Share nekiro code please?

events.cpp
C++:
bool Events::eventPlayerOnMoveItem(Player* player, Item* item, uint16_t count, const Position& fromPosition, const Position& toPosition, Cylinder* fromCylinder, Cylinder* toCylinder)
{
    // Player:onMoveItem(item, count, fromPosition, toPosition) or Player.onMoveItem(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if (info.playerOnMoveItem == -1) {
        return true;
    }

    if (!scriptInterface.reserveScriptEnv()) {
        std::cout << "[Error - Events::eventPlayerOnMoveItem] Call stack overflow" << std::endl;
        return false;
    }

    ScriptEnvironment* env = scriptInterface.getScriptEnv();
    env->setScriptId(info.playerOnMoveItem, &scriptInterface);

    lua_State* L = scriptInterface.getLuaState();
    scriptInterface.pushFunction(info.playerOnMoveItem);

    LuaScriptInterface::pushUserdata<Player>(L, player);
    LuaScriptInterface::setMetatable(L, -1, "Player");

    LuaScriptInterface::pushUserdata<Item>(L, item);
    LuaScriptInterface::setItemMetatable(L, -1, item);

    lua_pushnumber(L, count);
    LuaScriptInterface::pushPosition(L, fromPosition);
    LuaScriptInterface::pushPosition(L, toPosition);

    LuaScriptInterface::pushCylinder(L, fromCylinder);
    LuaScriptInterface::pushCylinder(L, toCylinder);

    return scriptInterface.callFunction(7);
}

events.h
C++:
    bool eventPlayerOnMoveItem(Player* player, Item* item, uint16_t count, const Position& fromPosition, const Position& toPosition, Cylinder* fromCylinder, Cylinder* toCylinder);

game.cpp
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*/)
{
    Player* actorPlayer = actor ? actor->getPlayer() : nullptr;
    if (actorPlayer && fromPos && toPos) {
        if (!g_events->eventPlayerOnMoveItem(actorPlayer, item, count, *fromPos, *toPos, fromCylinder, toCylinder)) {
            return RETURNVALUE_NOTPOSSIBLE;
        }
    }

    Item* toItem = nullptr;

    Cylinder* subCylinder;
    int floorN = 0;

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

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

    //destination is the same as the source?
    if (item == toItem) {
        return RETURNVALUE_NOERROR; //silently ignore move
    }

    //check if we can add this item
    ReturnValue ret = toCylinder->queryAdd(index, *item, count, flags, actor);
    if (ret == RETURNVALUE_NEEDEXCHANGE) {
        //check if we can add it to source cylinder
        ret = fromCylinder->queryAdd(fromCylinder->getThingIndex(item), *toItem, toItem->getItemCount(), 0);
        if (ret == RETURNVALUE_NOERROR) {
            if (actorPlayer && fromPos && toPos && !g_events->eventPlayerOnMoveItem(actorPlayer, toItem, count, *toPos, *fromPos, toCylinder, fromCylinder)) {
                return RETURNVALUE_NOTPOSSIBLE;
            }

            //check how much we can move
            uint32_t maxExchangeQueryCount = 0;
            ReturnValue retExchangeMaxCount = fromCylinder->queryMaxCount(INDEX_WHEREEVER, *toItem, toItem->getItemCount(), maxExchangeQueryCount, 0);

            if (retExchangeMaxCount != RETURNVALUE_NOERROR && maxExchangeQueryCount == 0) {
                return retExchangeMaxCount;
            }

            if (toCylinder->queryRemove(*toItem, toItem->getItemCount(), flags, actor) == RETURNVALUE_NOERROR) {
                int32_t oldToItemIndex = toCylinder->getThingIndex(toItem);
                toCylinder->removeThing(toItem, toItem->getItemCount());
                fromCylinder->addThing(toItem);

                if (oldToItemIndex != -1) {
                    toCylinder->postRemoveNotification(toItem, fromCylinder, oldToItemIndex);
                }

                int32_t newToItemIndex = fromCylinder->getThingIndex(toItem);
                if (newToItemIndex != -1) {
                    fromCylinder->postAddNotification(toItem, toCylinder, newToItemIndex);
                }

                ret = toCylinder->queryAdd(index, *item, count, flags);

                if (actorPlayer && fromPos && toPos) {
                    g_events->eventPlayerOnItemMoved(actorPlayer, toItem, toItem->getItemCount(), *toPos, *fromPos, toCylinder, fromCylinder);
                }

                toItem = nullptr;
            }
        }
    }

    if (ret != RETURNVALUE_NOERROR) {
        return ret;
    }

    //check how much we can move
    uint32_t maxQueryCount = 0;
    ReturnValue retMaxCount = toCylinder->queryMaxCount(index, *item, count, maxQueryCount, flags);
    if (retMaxCount != RETURNVALUE_NOERROR && maxQueryCount == 0) {
        return retMaxCount;
    }

    uint32_t m;
    if (item->isStackable()) {
        m = std::min<uint32_t>(count, maxQueryCount);
    } else {
        m = maxQueryCount;
    }

    Item* moveItem = item;

    //check if we can remove this item
    ret = fromCylinder->queryRemove(*item, m, flags, actor);
    if (ret != RETURNVALUE_NOERROR) {
        return ret;
    }

    if (tradeItem) {
        if (toCylinder->getItem() == tradeItem) {
            return RETURNVALUE_NOTENOUGHROOM;
        }

        Cylinder* tmpCylinder = toCylinder->getParent();
        while (tmpCylinder) {
            if (tmpCylinder->getItem() == tradeItem) {
                return RETURNVALUE_NOTENOUGHROOM;
            }

            tmpCylinder = tmpCylinder->getParent();
        }
    }

    //remove the item
    int32_t itemIndex = fromCylinder->getThingIndex(item);
    Item* updateItem = nullptr;
    fromCylinder->removeThing(item, m);

    //update item(s)
    if (item->isStackable()) {
        uint32_t n;

        if (item->equals(toItem)) {
            n = std::min<uint32_t>(100 - toItem->getItemCount(), m);
            toCylinder->updateThing(toItem, toItem->getID(), toItem->getItemCount() + n);
            updateItem = toItem;
        } else {
            n = 0;
        }

        int32_t newCount = m - n;
        if (newCount > 0) {
            moveItem = item->clone();
            moveItem->setItemCount(newCount);
        } else {
            moveItem = nullptr;
        }

        if (item->isRemoved()) {
            ReleaseItem(item);
        }
    }

    //add item
    if (moveItem /*m - n > 0*/) {
        toCylinder->addThing(index, moveItem);
    }

    if (itemIndex != -1) {
        fromCylinder->postRemoveNotification(item, toCylinder, itemIndex);
    }

    if (moveItem) {
        int32_t moveItemIndex = toCylinder->getThingIndex(moveItem);
        if (moveItemIndex != -1) {
            toCylinder->postAddNotification(moveItem, fromCylinder, moveItemIndex);
        }
    }

    if (updateItem) {
        int32_t updateItemIndex = toCylinder->getThingIndex(updateItem);
        if (updateItemIndex != -1) {
            toCylinder->postAddNotification(updateItem, fromCylinder, updateItemIndex);
        }
    }

    if (_moveItem) {
        if (moveItem) {
            *_moveItem = moveItem;
        } else {
            *_moveItem = item;
        }
    }

    //we could not move all, inform the player
    if (item->isStackable() && maxQueryCount < count) {
        return retMaxCount;
    }

    if (moveItem && moveItem->getDuration() > 0) {
        if (moveItem->getDecaying() != DECAYING_TRUE) {
            moveItem->incrementReferenceCounter();
            moveItem->setDecaying(DECAYING_TRUE);
            toDecayItems.push_front(moveItem);
        }
    }

    if (actorPlayer && fromPos && toPos) {
        g_events->eventPlayerOnItemMoved(actorPlayer, item, count, *fromPos, *toPos, fromCylinder, toCylinder);
    }

    return ret;
}
 
Ah, you were talking about the c+ code, I thought it was a lua code hahaha, thank you, I use tfs 1.5, I thought the error could be in the end of your script that came after ec:register(-11) and not before like others script, also in the self part, in other script 1.4 use player or in another part, I wanted compare to see and learn

thanks friend
 
ec:register(-11)
I just looked over and you should move that line, to outside the function. You don't register it inside its call or it will never be registered... that is most likely the reason.

I have also never ever seen negative values used to register... why? Must you use a negative value? Is there no other way around it? I would definitely recommend against that, as I am not sure off the top of my head its even supported in 1.4.2, or even master for that matter.
 
I just looked over and you should move that line, to outside the function. You don't register it inside its call or it will never be registered... that is most likely the reason.

I have also never ever seen negative values used to register... why? Must you use a negative value? Is there no other way around it? I would definitely recommend against that, as I am not sure off the top of my head its even supported in 1.4.2, or even master for that matter.

Otland shows the code wrong or I copy pasted it like a idiot lol
The register was outside of the function ofc :D
And -11 was just a testing.
Sarah wesker said using -1 as example can solve some situation so in that case the script gets first called over a other onMoveItem function which has no number as register
 
Otland shows the code wrong or I copy pasted it like a idiot lol
The register was outside of the function ofc :D
And -11 was just a testing.
Sarah wesker said using -1 as example can solve some situation so in that case the script gets first called over a other onMoveItem function which has no number as register
I'm sure that is true, but there are many things that may accept -1, but not -11.

You said it was for testing only, well have you tried it without using -11, but something more valid like 0 or 1?
Post automatically merged:

Quick question... the item that is causing you a problem wouldn't happen to be an equipment item? I only ask because I found this commit that came out about a half a year after the release of 1.4.2

 
Last edited:
I'm sure that is true, but there are many things that may accept -1, but not -11.

You said it was for testing only, well have you tried it without using -11, but something more valid like 0 or 1?
Post automatically merged:

Quick question... the item that is causing you a problem wouldn't happen to be an equipment item? I only ask because I found this commit that came out about a half a year after the release of 1.4.2

Yes i've tested it with 0 and 1 and -1 and I've tested it with the commit aswell but it was still buggy
 
Last edited:
Try this:

Lua:
local ids = {9999, 6000}

local ec = EventCallback

ec.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if table.contains(ids, item:getActionId()) and toPosition.x ~= CONTAINER_POSITION then
        self:sendTextMessage(MESSAGE_INFO_DESCR, 'This item can not be moved.')
        print(1)
        return RETURNVALUE_NOTPOSSIBLE
    end
    print(2)
    return RETURNVALUE_NOERROR
end

ec:register()

I have basically moved last end above ec:register()
ec_onmoveitem.gif
 
Did you make changes to the source? I took your last modified script and tested it on mine, but it doesn't work. I don't understand how you managed to do that.
Nope, i didnt change sources, only the script. Well, check if the item has the action id from array and it should work. No idea why it doesnt, it looks pretty straightforward 🤷‍♂️

Edit
@Mateus Robeerto

go to events.xml and set it to "1"
XML:
<event class="Player" method="onMoveItem" enabled="1" />

with "0" the mentioned revscript doesn't work
 
Last edited:
Yeah I have to agree with @Unknown Soldier I can't reproduce this script having issues, and I have looked over the "modified" source code, and tfs master source code, and 1.4.2 source code, and I can't find any reason the script wouldn't work, which means there must be an issue with enabling or registering..
 
Its something with TFS 1.4.2 im pretty sure
Everything worked except onMoveItem

I've changed the source code function anyway (you can see the code above) so this thread can be closed :D
 
It has been activated for a long time... I don't know the reason why it's not working.
One more thing you can try to do is writing the same or similar code in player.lua directly.

Lua:
function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if item:getActionId() == 6000 then
        return RETURNVALUE_NOTPOSSIBLE
    end
                    
    if hasEventCallback(EVENT_CALLBACK_ONMOVEITEM) then
        return EventCallback(
            EVENT_CALLBACK_ONMOVEITEM,
            self,
            item,
            count,
            fromPosition,
            toPosition,
            fromCylinder,
            toCylinder
        )
    end
    return RETURNVALUE_NOERROR
end

If it still doesn't work, then I have no idea what could work and what could be the reason, but it seems prety strange that multiple people have the same issue
 
One more thing you can try to do is writing the same or similar code in player.lua directly.
Same thing, it's not working either... I downloaded a clean TFS 1.4.2 and tested it, still not working. How weird, hahaha. 🤣
Post automatically merged:

I managed to solve the problem... The item is no longer moving on the ground.



Regarding 'CONTAINER_POSITION,' I couldn't move items from the backpack to the ground. I realized, thought, and removed only that part, and now it's working perfectly.



Lua:
local blockedIDs = {9999, 6000}

local ec = EventCallback

ec.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if table.contains(blockedIDs, item:getActionId()) then
        self:sendTextMessage(MESSAGE_INFO_DESCR, 'This item cannot be moved.')
        return RETURNVALUE_NOTPOSSIBLE
    end
 
 
    return RETURNVALUE_NOERROR
end

ec:register(-11)

In relation to the matter of CONTAINER_POSITION, it serves to prevent items from the backpack from being placed on the ground, as well as to prohibit the retrieval of items from the ground for placement into the backpack. This mechanism ensures the adherence to these restrictions.. 😀
 
Last edited:
Same thing, it's not working either... I downloaded a clean TFS 1.4.2 and tested it, still not working. How weird, hahaha. 🤣
Post automatically merged:

I managed to solve the problem... The item is no longer moving on the ground.



Regarding 'CONTAINER_POSITION,' I couldn't move items from the backpack to the ground. I realized, thought, and removed only that part, and now it's working perfectly.



Lua:
local blockedIDs = {9999, 6000}

local ec = EventCallback

ec.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if table.contains(blockedIDs, item:getActionId()) then
        self:sendTextMessage(MESSAGE_INFO_DESCR, 'This item cannot be moved.')
        return RETURNVALUE_NOTPOSSIBLE
    end
 
 
    return RETURNVALUE_NOERROR
end

ec:register(-11)

In relation to the matter of CONTAINER_POSITION, it serves to prevent items from the backpack from being placed on the ground, as well as to prohibit the retrieval of items from the ground for placement into the backpack. This mechanism ensures the adherence to these restrictions.. 😀

Haha, what the heck? 😅

Now, just pasting your script - it doesn't work for me, unless I remove -11 from brackets, then I cannot move the item on the ground, but I CAN take it into inventory (bag/backpack).

Today I spent like 2 hours to find a way to prevent items from being taken into inventory... damn it
 
Back
Top