Skip to content

Commit bd6d466

Browse files
committedNov 1, 2013
Add a callback: minetest.register_on_craft(itemstack, player,
old_craft_grid, craft_inv) and minetest.register_craft_predict(itemstack, player, old_craft_grid, craft_inv)
1 parent 2f10cfb commit bd6d466

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed
 

‎builtin/misc_register.lua

+16
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,20 @@ function minetest.register_biome(biome)
230230
register_biome_raw(biome)
231231
end
232232

233+
function minetest.on_craft(itemstack, player, old_craft_list, craft_inv)
234+
for _, func in ipairs(minetest.registered_on_crafts) do
235+
itemstack = func(itemstack, player, old_craft_list, craft_inv) or itemstack
236+
end
237+
return itemstack
238+
end
239+
240+
function minetest.craft_predict(itemstack, player, old_craft_list, craft_inv)
241+
for _, func in ipairs(minetest.registered_craft_predicts) do
242+
itemstack = func(itemstack, player, old_craft_list, craft_inv) or itemstack
243+
end
244+
return itemstack
245+
end
246+
233247
-- Alias the forbidden item names to "" so they can't be
234248
-- created via itemstrings (e.g. /give)
235249
local name
@@ -327,4 +341,6 @@ minetest.registered_on_joinplayers, minetest.register_on_joinplayer = make_regis
327341
minetest.registered_on_leaveplayers, minetest.register_on_leaveplayer = make_registration()
328342
minetest.registered_on_player_receive_fields, minetest.register_on_player_receive_fields = make_registration_reverse()
329343
minetest.registered_on_cheats, minetest.register_on_cheat = make_registration()
344+
minetest.registered_on_crafts, minetest.register_on_craft = make_registration()
345+
minetest.registered_craft_predicts, minetest.register_craft_predict = make_registration()
330346

‎doc/lua_api.txt

+9
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,15 @@ minetest.register_on_player_receive_fields(func(player, formname, fields))
11451145
minetest.register_on_mapgen_init(func(MapgenParams))
11461146
^ Called just before the map generator is initialized but before the environment is initialized
11471147
^ MapgenParams consists of a table with the fields mgname, seed, water_level, and flags
1148+
minetest.register_on_craft(func(itemstack, player, old_craft_grid, craft_inv))
1149+
^ Called when player crafts something
1150+
^ itemstack is the output
1151+
^ old_craft_grid contains the recipe (Note: the one in the inventory is cleared)
1152+
^ craft_inv is the inventory with the crafting grid
1153+
^ Return either an ItemStack, to replace the output, or nil, to not modify it
1154+
minetest.register_craft_predict(func(itemstack, player, old_craft_grid, craft_inv))
1155+
^ The same as before, except that it is called before the player crafts, to make
1156+
^ craft prediction, and it should not change anything.
11481157

11491158
Other registration functions:
11501159
minetest.register_chatcommand(cmd, chatcommand definition)

‎src/inventorymanager.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -724,13 +724,19 @@ void ICraftAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGam
724724
}
725725

726726
ItemStack crafted;
727+
ItemStack craftresultitem;
727728
int count_remaining = count;
728729
bool found = getCraftingResult(inv_craft, crafted, false, gamedef);
730+
PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv);
731+
found = !crafted.empty();
729732

730733
while(found && list_craftresult->itemFits(0, crafted))
731734
{
735+
InventoryList saved_craft_list = *list_craft;
736+
732737
// Decrement input and add crafting output
733738
getCraftingResult(inv_craft, crafted, true, gamedef);
739+
PLAYER_TO_SA(player)->item_OnCraft(crafted, player, &saved_craft_list, craft_inv);
734740
list_craftresult->addItem(0, crafted);
735741
mgr->setInventoryModified(craft_inv);
736742

@@ -747,6 +753,8 @@ void ICraftAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGam
747753

748754
// Get next crafting result
749755
found = getCraftingResult(inv_craft, crafted, false, gamedef);
756+
PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv);
757+
found = !crafted.empty();
750758
}
751759

752760
infostream<<"ICraftAction::apply(): crafted "

‎src/script/cpp_api/s_item.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2222
#include "common/c_converter.h"
2323
#include "common/c_content.h"
2424
#include "lua_api/l_item.h"
25+
#include "lua_api/l_inventory.h"
2526
#include "server.h"
2627
#include "log.h"
2728
#include "util/pointedthing.h"
29+
#include "inventory.h"
30+
#include "inventorymanager.h"
2831

2932
bool ScriptApiItem::item_OnDrop(ItemStack &item,
3033
ServerActiveObject *dropper, v3f pos)
@@ -86,6 +89,54 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
8689
return true;
8790
}
8891

92+
bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
93+
const InventoryList *old_craft_grid, const InventoryLocation &craft_inv)
94+
{
95+
SCRIPTAPI_PRECHECKHEADER
96+
97+
lua_getglobal(L, "minetest");
98+
lua_getfield(L, -1, "on_craft");
99+
LuaItemStack::create(L, item);
100+
objectrefGetOrCreate(user);
101+
102+
//Push inventory list
103+
std::vector<ItemStack> items;
104+
for(u32 i=0; i<old_craft_grid->getSize(); i++)
105+
items.push_back(old_craft_grid->getItem(i));
106+
push_items(L, items);
107+
108+
InvRef::create(L, craft_inv);
109+
if(lua_pcall(L, 4, 1, 0))
110+
scriptError("error: %s", lua_tostring(L, -1));
111+
if(!lua_isnil(L, -1))
112+
item = read_item(L,-1, getServer());
113+
return true;
114+
}
115+
116+
bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
117+
const InventoryList *old_craft_grid, const InventoryLocation &craft_inv)
118+
{
119+
SCRIPTAPI_PRECHECKHEADER
120+
121+
lua_getglobal(L, "minetest");
122+
lua_getfield(L, -1, "craft_predict");
123+
LuaItemStack::create(L, item);
124+
objectrefGetOrCreate(user);
125+
126+
//Push inventory list
127+
std::vector<ItemStack> items;
128+
for(u32 i=0; i<old_craft_grid->getSize(); i++)
129+
items.push_back(old_craft_grid->getItem(i));
130+
push_items(L, items);
131+
132+
InvRef::create(L, craft_inv);
133+
if(lua_pcall(L, 4, 1, 0))
134+
scriptError("error: %s", lua_tostring(L, -1));
135+
if(!lua_isnil(L, -1))
136+
item = read_item(L,-1, getServer());
137+
return true;
138+
}
139+
89140
// Retrieves minetest.registered_items[name][callbackname]
90141
// If that is nil or on error, return false and stack is unchanged
91142
// If that is a function, returns true and pushes the

‎src/script/cpp_api/s_item.h

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class ServerActiveObject;
2929
struct ItemDefinition;
3030
class LuaItemStack;
3131
class ModApiItemMod;
32+
class InventoryList;
33+
class InventoryLocation;
3234

3335
class ScriptApiItem
3436
: virtual public ScriptApiBase
@@ -40,6 +42,10 @@ class ScriptApiItem
4042
ServerActiveObject *placer, const PointedThing &pointed);
4143
bool item_OnUse(ItemStack &item,
4244
ServerActiveObject *user, const PointedThing &pointed);
45+
bool item_OnCraft(ItemStack &item, ServerActiveObject *user,
46+
const InventoryList *old_craft_grid, const InventoryLocation &craft_inv);
47+
bool item_CraftPredict(ItemStack &item, ServerActiveObject *user,
48+
const InventoryList *old_craft_grid, const InventoryLocation &craft_inv);
4349

4450
protected:
4551
friend class LuaItemStack;

‎src/server.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -4775,7 +4775,10 @@ void Server::UpdateCrafting(u16 peer_id)
47754775

47764776
// Get a preview for crafting
47774777
ItemStack preview;
4778+
InventoryLocation loc;
4779+
loc.setPlayer(player->getName());
47784780
getCraftingResult(&player->inventory, preview, false, this);
4781+
m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), (&player->inventory)->getList("craft"), loc);
47794782

47804783
// Put the new preview in
47814784
InventoryList *plist = player->inventory.getList("craftpreview");

0 commit comments

Comments
 (0)
Please sign in to comment.