mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Fix item duplication if player dies during interact callback (alternative) (#11662)
This commit is contained in:
parent
d4b89eb106
commit
660e63dbae
7 changed files with 118 additions and 56 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue