diff --git a/data/events/events.xml b/data/events/events.xml index 80af8717cf..910b93a513 100644 --- a/data/events/events.xml +++ b/data/events/events.xml @@ -28,6 +28,7 @@ + diff --git a/data/events/scripts/player.lua b/data/events/scripts/player.lua index e502d02d1b..d2cf4112a4 100644 --- a/data/events/scripts/player.lua +++ b/data/events/scripts/player.lua @@ -99,6 +99,14 @@ function Player:onReportBug(message, position, category) return true end +function Player:onRotateItem(item) + local onRotateItem = EventCallback.onRotateItem + if onRotateItem then + return onRotateItem(self, item) + end + return true +end + function Player:onTurn(direction) local onTurn = EventCallback.onTurn if onTurn then diff --git a/data/scripts/eventcallbacks/player/default_onRotateItem.lua b/data/scripts/eventcallbacks/player/default_onRotateItem.lua new file mode 100644 index 0000000000..fe7696bc31 --- /dev/null +++ b/data/scripts/eventcallbacks/player/default_onRotateItem.lua @@ -0,0 +1,10 @@ +local ec = EventCallback + +ec.onRotateItem = function(self, item) + local newId = item:getType():getRotateTo() + if newId ~= 0 then + item:transform(newId) + end +end + +ec:register() diff --git a/data/scripts/lib/event_callbacks.lua b/data/scripts/lib/event_callbacks.lua index 000c957111..3d7c6445ab 100644 --- a/data/scripts/lib/event_callbacks.lua +++ b/data/scripts/lib/event_callbacks.lua @@ -52,6 +52,7 @@ ec.onMoveCreature = {} ec.onReportRuleViolation = {} ec.onReportBug = {} ec.onTurn = {} +ec.onRotateItem = {} ec.onGainExperience = {[3] = 1} ec.onLoseExperience = {[2] = 1} ec.onGainSkillTries = {[3] = 1} diff --git a/src/events.cpp b/src/events.cpp index 775afd3f5e..1c5268ab77 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -104,6 +104,8 @@ bool Events::load() info.playerOnReportRuleViolation = event; } else if (methodName == "onReportBug") { info.playerOnReportBug = event; + } else if (methodName == "onRotateItem") { + info.playerOnRotateItem = event; } else if (methodName == "onTurn") { info.playerOnTurn = event; } else if (methodName == "onGainExperience") { @@ -899,6 +901,33 @@ bool Events::eventPlayerOnReportBug(Player* player, const std::string& message, return scriptInterface.callFunction(4); } +void Events::eventPlayerOnRotateItem(Player* player, Item* item) +{ + // Player:onRotateItem(item) + if (info.playerOnRotateItem == -1) { + return; + } + + if (!scriptInterface.reserveScriptEnv()) { + std::cout << "[Error - Events::eventPlayerOnRotateItem] Call stack overflow" << std::endl; + return; + } + + ScriptEnvironment* env = scriptInterface.getScriptEnv(); + env->setScriptId(info.playerOnRotateItem, &scriptInterface); + + lua_State* L = scriptInterface.getLuaState(); + scriptInterface.pushFunction(info.playerOnRotateItem); + + LuaScriptInterface::pushUserdata(L, player); + LuaScriptInterface::setMetatable(L, -1, "Player"); + + LuaScriptInterface::pushUserdata(L, item); + LuaScriptInterface::setItemMetatable(L, -1, item); + + scriptInterface.callFunction(2); +} + bool Events::eventPlayerOnTurn(Player* player, Direction direction) { // Player:onTurn(direction) or Player.onTurn(self, direction) diff --git a/src/events.h b/src/events.h index c6563450e7..1546e3c7c2 100644 --- a/src/events.h +++ b/src/events.h @@ -50,6 +50,7 @@ class Events int32_t playerOnMoveCreature = -1; int32_t playerOnReportRuleViolation = -1; int32_t playerOnReportBug = -1; + int32_t playerOnRotateItem = -1; int32_t playerOnTurn = -1; int32_t playerOnTradeRequest = -1; int32_t playerOnTradeAccept = -1; @@ -108,6 +109,7 @@ class Events uint8_t reportReason, const std::string& comment, const std::string& translation); bool eventPlayerOnReportBug(Player* player, const std::string& message, const Position& position, uint8_t category); + void eventPlayerOnRotateItem(Player* player, Item* item); bool eventPlayerOnTurn(Player* player, Direction direction); bool eventPlayerOnTradeRequest(Player* player, Player* target, Item* item); bool eventPlayerOnTradeAccept(Player* player, Player* target, Item* item, Item* targetItem); diff --git a/src/game.cpp b/src/game.cpp index 433ea30543..6de690c024 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2443,10 +2443,7 @@ void Game::playerRotateItem(uint32_t playerId, const Position& pos, uint8_t stac podium->setDirection(static_cast((podium->getDirection() + 1) % 4)); updatePodium(podium); } else { - uint16_t newId = Item::items[item->getID()].rotateTo; - if (newId != 0) { - transformItem(item, newId); - } + g_events->eventPlayerOnRotateItem(player, item); } } diff --git a/src/luascript.cpp b/src/luascript.cpp index 4528841690..a83d63ba87 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -2935,6 +2935,7 @@ void LuaScriptInterface::registerFunctions() registerMethod("ItemType", "isMagicField", LuaScriptInterface::luaItemTypeIsMagicField); registerMethod("ItemType", "isUseable", LuaScriptInterface::luaItemTypeIsUseable); registerMethod("ItemType", "isPickupable", LuaScriptInterface::luaItemTypeIsPickupable); + registerMethod("ItemType", "isRotatable", LuaScriptInterface::luaItemTypeIsRotatable); registerMethod("ItemType", "getType", LuaScriptInterface::luaItemTypeGetType); registerMethod("ItemType", "getGroup", LuaScriptInterface::luaItemTypeGetGroup); @@ -2942,6 +2943,7 @@ void LuaScriptInterface::registerFunctions() registerMethod("ItemType", "getClientId", LuaScriptInterface::luaItemTypeGetClientId); registerMethod("ItemType", "getName", LuaScriptInterface::luaItemTypeGetName); registerMethod("ItemType", "getPluralName", LuaScriptInterface::luaItemTypeGetPluralName); + registerMethod("ItemType", "getRotateTo", LuaScriptInterface::luaItemTypeGetRotateTo); registerMethod("ItemType", "getArticle", LuaScriptInterface::luaItemTypeGetArticle); registerMethod("ItemType", "getDescription", LuaScriptInterface::luaItemTypeGetDescription); registerMethod("ItemType", "getSlotPosition", LuaScriptInterface::luaItemTypeGetSlotPosition); @@ -12729,6 +12731,18 @@ int LuaScriptInterface::luaItemTypeIsPickupable(lua_State* L) return 1; } +int LuaScriptInterface::luaItemTypeIsRotatable(lua_State* L) +{ + // itemType:isRotatable() + const ItemType* itemType = getUserdata(L, 1); + if (itemType) { + pushBoolean(L, itemType->rotatable); + } else { + lua_pushnil(L); + } + return 1; +} + int LuaScriptInterface::luaItemTypeGetType(lua_State* L) { // itemType:getType() @@ -12801,6 +12815,18 @@ int LuaScriptInterface::luaItemTypeGetPluralName(lua_State* L) return 1; } +int LuaScriptInterface::luaItemTypeGetRotateTo(lua_State* L) +{ + // itemType:getRotateTo() + const ItemType* itemType = getUserdata(L, 1); + if (itemType) { + lua_pushnumber(L, itemType->rotateTo); + } else { + lua_pushnil(L); + } + return 1; +} + int LuaScriptInterface::luaItemTypeGetArticle(lua_State* L) { // itemType:getArticle() diff --git a/src/luascript.h b/src/luascript.h index 2b9f1047e2..86b072139b 100644 --- a/src/luascript.h +++ b/src/luascript.h @@ -1203,6 +1203,7 @@ class LuaScriptInterface static int luaItemTypeIsMagicField(lua_State* L); static int luaItemTypeIsUseable(lua_State* L); static int luaItemTypeIsPickupable(lua_State* L); + static int luaItemTypeIsRotatable(lua_State* L); static int luaItemTypeGetType(lua_State* L); static int luaItemTypeGetGroup(lua_State* L); @@ -1210,6 +1211,7 @@ class LuaScriptInterface static int luaItemTypeGetClientId(lua_State* L); static int luaItemTypeGetName(lua_State* L); static int luaItemTypeGetPluralName(lua_State* L); + static int luaItemTypeGetRotateTo(lua_State* L); static int luaItemTypeGetArticle(lua_State* L); static int luaItemTypeGetDescription(lua_State* L); static int luaItemTypeGetSlotPosition(lua_State* L);