• 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 onMoveItem bug????

silveralol

Advanced OT User
Joined
Mar 16, 2010
Messages
1,480
Solutions
9
Reaction score
211
Hi, I need some support with it, well, I want to make possible move only gold to some container, then I use some script onMoveItem...
Code:
if toPosition.x == CONTAINER_POSITION then
        local containerId = toPosition.y - 64
        local container = self:getContainerById(containerId)      
        if not container then
            return true
        end

        local itemId = container:getId()
        if itemId == containerID then
            if not isInArray({2148, 2152, 2160}, item.itemid) then
                self:sendTextMessage(MESSAGE_STATUS_SMALL, 'You can only put money in the pounch.')
                return false
            end
        end
the behavior at this moment:
1 - if I'm with the container opened as a normal backpack and try move others items I get the message "you can only put....."
2 - if I try move an item to the container closed, just move to the item(container), the item out of the array will be moved to inside of the container :S
seems that the toPosition is diferent in both cases
then I make a VERY GOOD IMAGE (I'M THE KING OF THE PAINT :rolleyes::oops:)
lXA7yqZ.png

now is more easy to understand I guess.
 
Last edited:
Why do you change the y position -64?
Why not just use the position it gives?

I'm assuming "onThrow" for 0.3.7 is the same as onMoveItem in 1.2?

-- 2 hours later of tinkering with my test script..
errr.. this turned out to be much more complicated then I originally thought. :eek:

-- another 2 hours later
:/
Everything I've tried has not worked.

I can test if the item is being moved to or from an inventory slot.. or if the container item being moved into is the correct item_id.. (opened container -> move to slot -> find container id of opened container)

But I can't for the life of me get the position of a specific item, as it currently appears in the players inventory.
There's simply no function I can find to do it.

toPosition returns the correct position inside the inventory for the item being moved.. but no current lua function will return a UID of an item in the position it is being moved into.

Or Flip side, I can't use any lua function to find the position of an item as it appears inside a players inventory, even if I search the players inventory for all item's to find their UID's, to attempt to compare positions of the moved item, and the UID of the item I'm comparing it to inside the inventory.. Because all lua functions grab the floor position, not the inventory position.


I'm fairly positive I've exhausted all options available on pre-1.x servers to create the 'money bag', without source editing.

I'm actually stuck with the same issue you are explaining above.

Welp, Good luck!

Oh I had an interesting idea.. just as I finished the thread..

This is such a lame 'hack' but I'm sure it would work.

Search through finding all money_bags UID's..

Then doAddContainerItemEx to the money bag..
Then do the same check as you were originally doing to compare the position of the money bag.. from inside the container itself..
Store those positions in a local.. then compare those stored positions against the toPosition positions.
If they are the same, then you know your attempting to add the item into that container item..
Then you can check if the item is in the array of money.
If all the positions do not match, you know that position is not any of the money bag's you have on the player.

Welp, Good luck again!

The above idea sounds good in my head. haha
 
Why do you change the y position -64?
Why not just use the position it gives?

I'm assuming "onThrow" for 0.3.7 is the same as onMoveItem in 1.2?

-- 2 hours later of tinkering with my test script..
errr.. this turned out to be much more complicated then I originally thought. :eek:

-- another 2 hours later
:/
Everything I've tried has not worked.

I can test if the item is being moved to or from an inventory slot.. or if the container item being moved into is the correct item_id.. (opened container -> move to slot -> find container id of opened container)

But I can't for the life of me get the position of a specific item, as it currently appears in the players inventory.
There's simply no function I can find to do it.

toPosition returns the correct position inside the inventory for the item being moved.. but no current lua function will return a UID of an item in the position it is being moved into.

Or Flip side, I can't use any lua function to find the position of an item as it appears inside a players inventory, even if I search the players inventory for all item's to find their UID's, to attempt to compare positions of the moved item, and the UID of the item I'm comparing it to inside the inventory.. Because all lua functions grab the floor position, not the inventory position.


I'm fairly positive I've exhausted all options available on pre-1.x servers to create the 'money bag', without source editing.

I'm actually stuck with the same issue you are explaining above.

Welp, Good luck!

Oh I had an interesting idea.. just as I finished the thread..

This is such a lame 'hack' but I'm sure it would work.

Search through finding all money_bags UID's..

Then doAddContainerItemEx to the money bag..
Then do the same check as you were originally doing to compare the position of the money bag.. from inside the container itself..
Store those positions in a local.. then compare those stored positions against the toPosition positions.
If they are the same, then you know your attempting to add the item into that container item..
Then you can check if the item is in the array of money.
If all the positions do not match, you know that position is not any of the money bag's you have on the player.

Welp, Good luck again!

The above idea sounds good in my head. haha
Omg, you could've just asked me in discord instead of wasting so much time with something that simple LOL.

Code:
if toPosition.x == CONTAINER_POSITION then
        local containerId = toPosition.y - 64
        local container = self:getContainerById(containerId)   
        if not container then
            return true
        end

        local itemId = container:getId()
        local moveToItem = container:getItem(toPosition.z)
        if itemId == containerID or (moveToItem and moveToItem:getId() == containerID) then
            if not isInArray({2148, 2152, 2160}, item.itemid) then
                self:sendTextMessage(MESSAGE_STATUS_SMALL, 'You can only put money in the pounch.')
                return false
            end
        end

containerId and containerID. So confusing, I would change it.

(Just bumped an old thread that has similar code you can check it there, posted in the wrong place.)
 
Omg, you could've just asked me in discord instead of wasting so much time with something that simple LOL.

Code:
if toPosition.x == CONTAINER_POSITION then
        local containerId = toPosition.y - 64
        local container = self:getContainerById(containerId) 
        if not container then
            return true
        end

        local itemId = container:getId()
        local moveToItem = container:getItem(toPosition.z)
        if itemId == containerID or (moveToItem and moveToItem:getId() == containerID) then
            if not isInArray({2148, 2152, 2160}, item.itemid) then
                self:sendTextMessage(MESSAGE_STATUS_SMALL, 'You can only put money in the pounch.')
                return false
            end
        end

containerId and containerID. So confusing, I would change it.

(Just bumped an old thread that has similar code you can check it there, posted in the wrong place.)
Notice I said pre-1.x servers. :p
I don't have some of these functions to check the same way as you guys are.
If I parse through the main backpack to get the player items, in order to find the uid's of the loot bag, I can't grab the actual inventory positions of those items.
So checking for toPosition.z returns the floors z position, not the containers space id.

I'm assuming self:getContainerById is performing the same action as me parsing through the character inventory, and finding the uid of the item.. but I don't understand how using the y position by itself, provides you any clue as to whether the item is being moved into or onto another container object?

I'm not even sure why it's being checked at all. :confused:
Doesn't checking toPosition.x check if it's being moved into the inventory somewhere?
Don't we want to check if the coin bag is in the inventory slot?

Like if they have it as their backpack space.. and you move any item onto that slot.. wouldn't the player be able to insert that item into the coin bag.. since it returns true.. as not being inside a container object?

Maybe I'm just stupid as fuck...

Can you explain what's going on?
 
Notice I said pre-1.x servers. :p
I don't have some of these functions to check the same way as you guys are.
If I parse through the main backpack to get the player items, in order to find the uid's of the loot bag, I can't grab the actual inventory positions of those items.
So checking for toPosition.z returns the floors z position, not the containers space id.

I'm assuming self:getContainerById is performing the same action as me parsing through the character inventory, and finding the uid of the item.. but I don't understand how using the y position by itself, provides you any clue as to whether the item is being moved into or onto another container object?

I'm not even sure why it's being checked at all. :confused:
Doesn't checking toPosition.x check if it's being moved into the inventory somewhere?
Don't we want to check if the coin bag is in the inventory slot?

Like if they have it as their backpack space.. and you move any item onto that slot.. wouldn't the player be able to insert that item into the coin bag.. since it returns true.. as not being inside a container object?

Maybe I'm just stupid as fuck...

Can you explain what's going on?
Oh well... Idk for pre 1.x, does this even make sense in pre 1.x you don't have onMoveItem I believe. idk

The toPosition.y is the "cylinder" that the item is being moved to (aka the container windows) when its from >= 64. (If its less then it could be also an inventory slot.)

For example If I open 2 containers in my client and move one item to the second, that one would be 1 and the other 0 (65-64 and 64-64), so Player.getContainerById gets the container that is opened for the client.

The toPosition.x is just to say its a container position.

The toPosition.z is the actual slot position that the player moved the item to.

But you are right with the script I sent if the container is in an inventory slot it will bug, to solve you just have to check if z is an inventory slot id and check but i'm lazy and sleepy gn;
 
Oh well... Idk for pre 1.x, does this even make sense in pre 1.x you don't have onMoveItem I believe. idk

The toPosition.y is the "cylinder" that the item is being moved to (aka the container windows) when its from >= 64. (If its less then it could be also an inventory slot.)

For example If I open 2 containers in my client and move one item to the second, that one would be 1 and the other 0 (65-64 and 64-64), so Player.getContainerById gets the container that is opened for the client.

The toPosition.x is just to say its a container position.

The toPosition.z is the actual slot position that the player moved the item to.

But you are right with the script I sent if the container is in an inventory slot it will bug, to solve you just have to check if z is an inventory slot id and check but i'm lazy and sleepy gn;
Yeah we have something similar
Code:
function onThrow(cid, item, fromPosition, toPosition)
    if toPosition.x ==CONTAINER_POSITION then -- I have to replace this with a number over 65k. (I find it with print)
        -- is in inventory.

But like you said toPosition.y is the cylinder, first opened backpack = 64, next is 65, next is 66, et cetera.
toPosition.z = container slot position.


:/
I'll just settle with it being out of my knowledge level, and/or 0.x script capabilities.
I can't wrap my head around it not being broken as-is.

When I read the script I see it doing this..

Check if item is being moved into inventory..
Check if item is being moved into a container.. located at y position 0.. -- (Which is literally nothing? helmet = 1..)
Find the container_id of the container your moving it into.. -- (which is impossible to find.. But let's pretend this is the backpack you've moved the item into..?)
return true if the container item you found is not a container.. -- (this determines if the item is placed into a container.. or on the ground?)
-- (^ I see this as a problem.. as if they move the item onto the main backpack.. which the player has replaced with the gold bag.. they can get items into it.)


Then this part really fudge me up..

itemId == containerID --(if we get rid of the locals....)

container:getId(self:getContainerById(toPosition.y - 64)) == toPosition.y - 64

Your checking if the UID of the container is equal to the y position of 0/1/2/3/et cetera?

OR you check...

(moveToItem and moveToItem:getId() == containerID)

If the UID and the itemID at the z position is equal to the y position of 0/1/2/3/et cetera?

The Y value always has a changing number.. so idk how this script works at all.. and I have no idea how they are grabbing the correct container to accurately check the variables..

Please senpai break it down for me. :oops::oops:

This is my function
.. but if you can explain how yours is working.., I might/should be able to wrap my head around it. <3 <3
 
Main goal: You should only be able to move the items {2148, 2152, 2160} inside the container with itemid = containerID

We only have those arguments:
function Player: onMoveItem(item, count, fromPosition, toPosition)

So how can we do it?

There are 3 cases to be checked:
1) Player move item directly inside the container
Example: Move item to the container window

2) Player move item to container that is inside another container
Example: Move item to the container window but the destination is another container

3) Player move item to slot that is a container
Example: Move item to the backpack slot when you have a container equiped there.

So how can we do this having only those arguments. Well, turns out that we only need the toPosition to know all this stuff:

toPosition.x = When it's CONTAINER_POSITION (aka 65535, 0xFFFF) the player is moving the item to a container position (That can be a slot or a container window).

toPosition.y = The cylinder.
When it's >= 64, it means the player is moving the item to a container window of id (toPosition.y - 64) we can use this to get the container that the player is moving the item to.
When it's >= 1 (CONST_SLOT_HEAD) and <= 10 (CONST_SLOT_AMMO), it means the plyer is moving it to the slot position.

toPosition.z = If the toPosition.y >= 64, then this will tell us which slotId was the targeted slot that the player moved the item.

So now the functions to get the information we need:

player:getContainerById(containerId)
This will return the Container object if it exists in the client of the player.

container:getId()
This may confuse you but this wont return the containerId that we were talking about before, this will return the itemid of the actual container so now we can use this to check the itemid of the container that the player moved the item to. (number 1)

container:getItem(slotId)
This will get the item in the position slotId of the container so now we can check the destination item that the player moved the item to (number 2)

player:getSlotItem(slotId)
This can be used to check when toPosition.y >= 1 and <= 10 to get the item destination that the player moved the item to (number 3)

With those functions we can know everything about the destination that the item is being moved and decide if it should be able to move the item or not.

Sadly, for 0.x there isn't any function equivalent to getContainerById, so you would need to code it. (It is not possible to do it without this, you don't even need to try. However it would be fairly simple because this function is already implemented in the source, it's just not passed to Lua.)
 
Last edited:
IN the example script you showed though, don't we still have to check the inventory slots, before determining if it's inside a container?
As it stands right now, if we dropped an item into the backpack slot, and the backpack slot contained the gold bag, wouldn't it "return true", and allow any item to pass into it?

and blah, these functions definitely don't exist in 0.3.7 :p
 
IN the example script you showed though, don't we still have to check the inventory slots, before determining if it's inside a container?
As it stands right now, if we dropped an item into the backpack slot, and the backpack slot contained the gold bag, wouldn't it "return true", and allow any item to pass into it?

and blah, these functions definitely don't exist in 0.3.7 :p
Yes, I didn't add the slot check. The only function that 0.x doesn't have is getContainerById
 
I've just leave it as-is. :p

I can't compile, as I'm a noob, and I can only barely grasp your explanation, as the z/y positions with the lua commands act strangely, as you've stated.
I don't need this script, so I'm just gonna let it stand and soak in for awhile.

But thanks, I was sure the script was missing something, and that was eating me up, cuz it was fundamentally broken, before going into the containers and looking around for them. xD

I like to work in by layers, and missing the very first layer of the script was throwing me so hard.

Thanks for all your time. o/
 
Omg, you could've just asked me in discord instead of wasting so much time with something that simple LOL.

Code:
if toPosition.x == CONTAINER_POSITION then
        local containerId = toPosition.y - 64
        local container = self:getContainerById(containerId) 
        if not container then
            return true
        end

        local itemId = container:getId()
        local moveToItem = container:getItem(toPosition.z)
        if itemId == containerID or (moveToItem and moveToItem:getId() == containerID) then
            if not isInArray({2148, 2152, 2160}, item.itemid) then
                self:sendTextMessage(MESSAGE_STATUS_SMALL, 'You can only put money in the pounch.')
                return false
            end
        end

containerId and containerID. So confusing, I would change it.

(Just bumped an old thread that has similar code you can check it there, posted in the wrong place.)
very much thank you, it work! The containerID is the ID of the bag, Then I just test it with the id correct, and it works fine..
@MatheusMkalo I would give you an idea, we can make an "arrow/bolt bag", using the same script we can handle move only arrows to the bag, the thing that seems complicate is make the stuff to throw the arrows from inside of the bag, what you think ?
 
very much thank you, it work! The containerID is the ID of the bag, Then I just test it with the id correct, and it works fine..
@MatheusMkalo I would give you an idea, we can make an "arrow/bolt bag", using the same script we can handle move only arrows to the bag, the thing that seems complicate is make the stuff to throw the arrows from inside of the bag, what you think ?
it's pretty much the same script (if i understood you correctly)
 
Last edited:
very much thank you, it work! The containerID is the ID of the bag, Then I just test it with the id correct, and it works fine..
@MatheusMkalo I would give you an idea, we can make an "arrow/bolt bag", using the same script we can handle move only arrows to the bag, the thing that seems complicate is make the stuff to throw the arrows from inside of the bag, what you think ?
As I said, this is not going to work if the inventory is equiped in the player, you have to check the toPosition.y.

For ammo: https://github.com/otland/forgottenserver/blob/master/src/player.cpp#L220-L229
 
Back
Top