Player and Entity Inventory Handlers

prestidigitator
Member
 
Posts: 640
Joined: Thu Feb 21, 2013 23:54

Player and Entity Inventory Handlers

by prestidigitator » Fri Feb 22, 2013 19:24

(This is a suggestion for a mod API feature that would greatly enhance things like armor, custom inventories, custom crafting, etc.)

We have interfaces for handling changes to node inventories and detached inventories. What is missing is handling changes to entity inventories, including player inventories. This would be invaluable for things like custom games, armor, and custom crafting mods. It CAN be done now by creating a separate detached inventory for each player, mangling the name using the player's name, and being careful with permissions "just in case", so it isn't shared between players. However, this defeats the purpose of a "detached" inventory and REALLY isn't pretty (it gets even uglier for Lua entity instances...).

The design I would suggest is to add methods to the InvRef object so that handlers could be set for ANY inventory in the game (underneath they might have to be polymorphic on the type of object the inventory belongs to). This could look like:

Code: Select all
inv = minetest.get_inventory(location)

-- event is one of: "allow_move", "allow_put", "allow_take", "on_move", "on_put", "on_take"
-- Later it might even be extensible to things like "on_save" and "on_load"....
oldHandlerFunc = inv:get_handler(event)
inv:set_handler(event, newHandlerFunc)


As an example of how this could be used, here is a bit of mod code that uses a Chain of Responsibility pattern to do something special with an "armor" inventory list in the player's inventory:

Code: Select all
local playerInv = minetest.get_inventory({ type = "player", name = playername })
local oldInvPutHandler = playerInv:get_handler("on_put")
playerInv:set_handler(
   "on_put",
   function(inv, listname, index, stack, player)
      if listname ~= "armor" then
         return oldInvPutHandler(inv, listname, index, stack, player)
      end

      -- Type of armor and size of stack already checked in separate "allow_put" handler.

      minetest.log(
         "info",
         "Player "..player:get_player_name().." equipped armor "..stack:get_name().." to slot "..index)

      -- Handle behavior of equipped armor
   end)
Last edited by prestidigitator on Fri Feb 22, 2013 19:33, edited 1 time in total.
 

User avatar
rubenwardy
Moderator
 
Posts: 5965
Joined: Tue Jun 12, 2012 18:11
Location: United Kingdom
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
 

User avatar
PilzAdam
Member
 
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
Location: Germany
GitHub: PilzAdam
IRC: PilzAdam

by PilzAdam » Fri Feb 22, 2013 19:29

You actually can modify the inventory of an player:
Code: Select all
minetest.get_inventory(location) -> InvRef
^ location = eg. {type="player", name="celeron55"}
                 {type="node", pos={x=, y=, z=}}
                 {type="detached", name="creative"}

The only thing that hasnt an inventory are Lua SAOs.
 

prestidigitator
Member
 
Posts: 640
Joined: Thu Feb 21, 2013 23:54

by prestidigitator » Fri Feb 22, 2013 19:38

PilzAdam wrote:You actually can modify the inventory of an player:
Code: Select all
minetest.get_inventory(location) -> InvRef
^ location = eg. {type="player", name="celeron55"}
                 {type="node", pos={x=, y=, z=}}
                 {type="detached", name="creative"}

The only thing that hasnt an inventory are Lua SAOs.


Oh, I know you can get and change player inventories, but you can't deal with move/put/take events in a nice way. The only real option for that would be to run a method on a very fast periodic timer and try to apply some really complex custom logic to figure out exactly what changes had been made to the inventories of EVERY PLAYER IN THE GAME, figure out how to handle them, and undo them somehow if the change is inappropriate (e.g. equipping a torch as a helmet). Also, for custom crafting this would probably open up holes where players could duplicate items.

I didn't realize Lua entities don't have inventories. Well, that could actually be changed in a mod using this API! You could allow a mod to put an object with a custom implementation of "InvRef" inside the entity instance itself, and the rest is history.
Last edited by prestidigitator on Fri Feb 22, 2013 19:39, edited 1 time in total.
 

prestidigitator
Member
 
Posts: 640
Joined: Thu Feb 21, 2013 23:54

by prestidigitator » Fri Feb 22, 2013 19:47

Here's another interesting side effect of this. ALL crafting could be moved to the Lua side entirely. The default crafting would just be a default set of handlers installed on player objects, that deal only with changes to the "craft" and "craftpreview" inventory lists. Mods would be free to either replace them or wrap their behavior as I showed in the first post.

The only thing that would be left to the actual engine (EDIT: apart from passing these events to the Lua code) is loading and saving the inventories on player join/exit and map chunk load/unload.
Last edited by prestidigitator on Fri Feb 22, 2013 20:02, edited 1 time in total.
 


Return to Feature Discussion



Who is online

Users browsing this forum: No registered users and 3 guests