summaryrefslogtreecommitdiff
path: root/src/script/cpp_api
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/cpp_api')
-rw-r--r--src/script/cpp_api/s_item.cpp21
-rw-r--r--src/script/cpp_api/s_item.h14
2 files changed, 26 insertions, 9 deletions
diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp
index 48dce14f3..b1916070e 100644
--- a/src/script/cpp_api/s_item.cpp
+++ b/src/script/cpp_api/s_item.cpp
@@ -59,13 +59,14 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
return true;
}
-bool ScriptApiItem::item_OnPlace(ItemStack &item,
+bool ScriptApiItem::item_OnPlace(Optional<ItemStack> &ret_item,
ServerActiveObject *placer, const PointedThing &pointed)
{
SCRIPTAPI_PRECHECKHEADER
int error_handler = PUSH_ERROR_HANDLER(L);
+ const ItemStack &item = *ret_item;
// Push callback function on stack
if (!getItemCallback(item.name.c_str(), "on_place"))
return false;
@@ -82,22 +83,25 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
PCALL_RES(lua_pcall(L, 3, 1, error_handler));
if (!lua_isnil(L, -1)) {
try {
- item = read_item(L, -1, getServer()->idef());
+ ret_item = read_item(L, -1, getServer()->idef());
} catch (LuaError &e) {
throw WRAP_LUAERROR(e, "item=" + item.name);
}
+ } else {
+ ret_item = nullopt;
}
lua_pop(L, 2); // Pop item and error handler
return true;
}
-bool ScriptApiItem::item_OnUse(ItemStack &item,
+bool ScriptApiItem::item_OnUse(Optional<ItemStack> &ret_item,
ServerActiveObject *user, const PointedThing &pointed)
{
SCRIPTAPI_PRECHECKHEADER
int error_handler = PUSH_ERROR_HANDLER(L);
+ const ItemStack &item = *ret_item;
// Push callback function on stack
if (!getItemCallback(item.name.c_str(), "on_use"))
return false;
@@ -109,22 +113,25 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
PCALL_RES(lua_pcall(L, 3, 1, error_handler));
if(!lua_isnil(L, -1)) {
try {
- item = read_item(L, -1, getServer()->idef());
+ ret_item = read_item(L, -1, getServer()->idef());
} catch (LuaError &e) {
throw WRAP_LUAERROR(e, "item=" + item.name);
}
+ } else {
+ ret_item = nullopt;
}
lua_pop(L, 2); // Pop item and error handler
return true;
}
-bool ScriptApiItem::item_OnSecondaryUse(ItemStack &item,
+bool ScriptApiItem::item_OnSecondaryUse(Optional<ItemStack> &ret_item,
ServerActiveObject *user, const PointedThing &pointed)
{
SCRIPTAPI_PRECHECKHEADER
int error_handler = PUSH_ERROR_HANDLER(L);
+ const ItemStack &item = *ret_item;
if (!getItemCallback(item.name.c_str(), "on_secondary_use"))
return false;
@@ -134,10 +141,12 @@ bool ScriptApiItem::item_OnSecondaryUse(ItemStack &item,
PCALL_RES(lua_pcall(L, 3, 1, error_handler));
if (!lua_isnil(L, -1)) {
try {
- item = read_item(L, -1, getServer()->idef());
+ ret_item = read_item(L, -1, getServer()->idef());
} catch (LuaError &e) {
throw WRAP_LUAERROR(e, "item=" + item.name);
}
+ } else {
+ ret_item = nullopt;
}
lua_pop(L, 2); // Pop item and error handler
return true;
diff --git a/src/script/cpp_api/s_item.h b/src/script/cpp_api/s_item.h
index 25a3501f9..5015d8bd4 100644
--- a/src/script/cpp_api/s_item.h
+++ b/src/script/cpp_api/s_item.h
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "cpp_api/s_base.h"
#include "irr_v3d.h"
+#include "util/Optional.h"
struct PointedThing;
struct ItemStack;
@@ -35,13 +36,20 @@ class ScriptApiItem
: virtual public ScriptApiBase
{
public:
+ /*
+ * Functions with Optional<ItemStack> are for callbacks where Lua may
+ * want to prevent the engine from modifying the inventory after it's done.
+ * This has a longer backstory where on_use may need to empty the player's
+ * inventory without the engine interfering (see issue #6546).
+ */
+
bool item_OnDrop(ItemStack &item,
ServerActiveObject *dropper, v3f pos);
- bool item_OnPlace(ItemStack &item,
+ bool item_OnPlace(Optional<ItemStack> &item,
ServerActiveObject *placer, const PointedThing &pointed);
- bool item_OnUse(ItemStack &item,
+ bool item_OnUse(Optional<ItemStack> &item,
ServerActiveObject *user, const PointedThing &pointed);
- bool item_OnSecondaryUse(ItemStack &item,
+ bool item_OnSecondaryUse(Optional<ItemStack> &item,
ServerActiveObject *user, const PointedThing &pointed);
bool item_OnCraft(ItemStack &item, ServerActiveObject *user,
const InventoryList *old_craft_grid, const InventoryLocation &craft_inv);