[Question] Player Inv Add/Remove change variable - callbacks [Answered]

Post Reply
User avatar
sirrobzeroone
Member
Posts: 593
Joined: Mon Jul 16, 2018 07:56
GitHub: sirrobzeroone
Contact:

[Question] Player Inv Add/Remove change variable - callbacks [Answered]

by sirrobzeroone » Post

I have a static variable for all players which can be changed depending on what Item/s they hold in there Player Inventory.

I could just do an on global step, check all logged in players inventories and update the player variable, but just trying to see if there's a better way to do this since I only need to change/update the variable when the item is added or removed from the player inventory, I expect this will not be very often so I'm basically checking all logged in players for no reason using a global step, I could set the time quiet high like every 30/60secs but even then seems like a unnecessary addition to global step to me....

I can see with Node and Detached Inventories there on_put, on_move and on_take. But no equivalent for player inventories....well not that I can see.

I don't understand callbacks at all, which might be because I tried seeing how 3darmor did it but it uses a detached inventory so Im not confident it isn't leveraging on_put et al.

I did find a simple Lua explanation On stackover flow -https://stackoverflow.com/questions/506 ... -parameter

Code: Select all

callback = function ()
    ... do stuff ...
end

function caller(callback)
    callback()
end

-- run caller function
caller(callback)


I understand the first code block define your function in my case it would be for player update variable X. However I don't understand what step 2 does is it in some way tieing the callback function to the main function? Three is the function running when caller is run well I think because if thats the case Im not sure what step2 does then, so clearly Im not understanding step2 at all. I am struggling to tie the very simple theory above into an actual example usable in game I tried understanding 3d armors callbacks but I cant follow what is what.

Using 3d armor on equip call back, this looks like Step 1 at the beginning but then inside the code block I get lost as it looks more like step2 above ie we are tieing our function to on_equip....except I then cant dig out any example of what step 1 is....

Code: Select all

armor.register_on_equip = function(self, func)
	if type(func) == "function" then
		table.insert(self.registered_callbacks.on_equip, func)
	end
end


Essentially i'm way out of my depth and I have too many things I dont know. Like does player_inv even have a function to tie a callback too. Even if it does which i don't know I'm then not sure how the theory above on callbacks ties into a real example. Lastly I don't even know from a programing Lua angle if a callback is more efficient in this case it seems it would be to me but then I have exactly zero expertise with callbacks....

Its more than possible I've missed some cool info somewhere but I haven't been able to dig anything up. Found this interesting post from SK which ive tried following through but at the end uses the built in minetest.register_on_dignode to trigger the callback and from what i can see player inv doesn't seem to have something like that I could tap into so I back to stepone.....
viewtopic.php?p=365175#p365175

As always I appreciate the help and I hope the above babbling makes some sense. I'll keep reading around myself but wanted to put a question up as Im coming up very blank. Im more than happy to take links to general Lua help files :).
Last edited by sirrobzeroone on Fri Sep 24, 2021 23:00, edited 1 time in total.

User avatar
Skamiz Kazzarch
Member
Posts: 613
Joined: Fri Mar 09, 2018 20:34
GitHub: Skamiz
In-game: Skamiz
Location: la lojbaugag.

Re: [Question] Player Inv Add/Remove change variable - callbacks

by Skamiz Kazzarch » Post

The equivalent of on_put, on_move and on_take for the player is this:

Code: Select all

* `minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info))`
    * Determines how much of a stack may be taken, put or moved to a
      player inventory.
    * `player` (type `ObjectRef`) is the player who modified the inventory
      `inventory` (type `InvRef`).
    * List of possible `action` (string) values and their
      `inventory_info` (table) contents:
        * `move`: `{from_list=string, to_list=string, from_index=number, to_index=number, count=number}`
        * `put`:  `{listname=string, index=number, stack=ItemStack}`
        * `take`: Same as `put`
    * Return a numeric value to limit the amount of items to be taken, put or
      moved. A value of `-1` for `take` will make the source stack infinite.
* `minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info))`
    * Called after a take, put or move event from/to/in a player inventory
    * Function arguments: see `minetest.register_allow_player_inventory_action`
    * Does not accept or handle any return value.
    

But I think I remember reading that it woks only in formspecs, so picking an item of the ground or throwing it out doesn't trigger this.

I can try explaining callback later when I have more time.

User avatar
Skamiz Kazzarch
Member
Posts: 613
Joined: Fri Mar 09, 2018 20:34
GitHub: Skamiz
In-game: Skamiz
Location: la lojbaugag.

Re: [Question] Player Inv Add/Remove change variable - callbacks

by Skamiz Kazzarch » Post

Bearing in mind that I am not a professional programmer:
A callback is when a function calls another one, without knowing beforehand which one.
Ok, that is more confusing then anything. Let's try with an example.

The globalstep mechanic uses a callbacks.
The engine knows that you might want to execute code on every step. But it doesn't know what you want to do, so it provides you with a hook in the form of 'minetest.register_globalstep()' which allows you to pass it your custom function and then calls it on every server step.

'on_metadata_inventory_take' is a callback.
You pass it your function, and it gets called every time an item is moved from the nodes inventory to another inventory.

My understanding is that a callback isn't a function as such. It is the mechanic of handing over control of when your code is called to someone else.

And you don't always hand over control to the engine. Take for example this mod: https://content.minetest.net/packages/B ... /controls/
It creates callbacks for when a key is pressed/held/released. So instead of manually checking every server step if the sneak key is in a pressed after it was in a released state in the previous step and then print to chat that you started sneaking you just do:

Code: Select all

controls.register_on_press(function(player, control_name)
	if control_name ~= "sneak" then return
	minetest.chat_send_all("Player " .. player:get_player_name() .. " started sneaking")
end)
And trust the 'controls' mod to figure out when to run your code. (The code is only some 70 lines long so check it out.)

In this sense a lot of the lua API is using callbacks, you probably just don't think of them as such.


Going back to your case. you have your function update_player_variables.
Ideally you would register it to a callback which calls it every time the player inventory changes and then let the engine deal with the rest.

Sadly I don't think such a callback is implemented in the engine and implementing it in lua would probably just end up on relying on globalstep anyway.

You can use the callback mentioned in my previous post to detect when an inventory changes as a result of formspec actions. eg.: Dragging and dropping stack from/to chests and such.
But there is no way to detect when an inventory changes as a result of code adding/removing items. (short of overriding all functions which return an 'InvRef' and implementing your own callbacks) Which is what happens when you pick something of the ground / drop it.

I feel like this isn't a particularly good explanation, but I hope it clears thing up for you at least a little bit.

User avatar
sirrobzeroone
Member
Posts: 593
Joined: Mon Jul 16, 2018 07:56
GitHub: sirrobzeroone
Contact:

Re: [Question] Player Inv Add/Remove change variable - callbacks

by sirrobzeroone » Post

Thanks Skamiz Kazzarch, yes it does help and I hadn't uncovered - minetest.register_allow_player_inventory_action so I will have a look at using that.

I think if I can keep as much as I can out of global step the better, might mean a few extra checks on death which is the main one I can think of that could possibly remove the item without using formspec.

I'm looking at the above to try and streamline and update the thirsty mod as much as I can.

Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests