diff --git a/data/events/events.xml b/data/events/events.xml index 0ae0492..d3d2d8a 100644 --- a/data/events/events.xml +++ b/data/events/events.xml @@ -6,6 +6,7 @@ + @@ -34,9 +35,9 @@ - + diff --git a/data/events/scripts/creature.lua b/data/events/scripts/creature.lua index 5a52b8f..f25abd2 100644 --- a/data/events/scripts/creature.lua +++ b/data/events/scripts/creature.lua @@ -22,3 +22,9 @@ end function Creature:onChangeZone(fromZone, toZone) if hasEvent.onChangeZone then Event.onChangeZone(self, fromZone, toZone) end end + +function Creature:onUpdateStorage(key, value, oldValue, isSpawn) + if hasEvent.onUpdateStorage then + Event.onUpdateStorage(self, key, value, oldValue, isSpawn) + end +end diff --git a/data/events/scripts/player.lua b/data/events/scripts/player.lua index 6f21afe..ad838eb 100644 --- a/data/events/scripts/player.lua +++ b/data/events/scripts/player.lua @@ -126,7 +126,7 @@ function Player:onNetworkMessage(recvByte, msg) local handler = PacketHandlers[recvByte] if not handler then print(string.format( - "Player: %s sent an unknown packet header: 0x%02X with %d bytes!\n", + "Player: %s sent an unknown packet header: 0x%02X with %d bytes!", self:getName(), recvByte, msg:len())) return end @@ -149,3 +149,7 @@ end function Player:onAccountManager(text) if hasEvent.onAccountManager then Event.onAccountManager(self, text) end end + +function Player:onRotateItem(item) + if hasEvent.onRotateItem then return Event.onRotateItem(self, item) end +end diff --git a/data/lib/compat/compat.lua b/data/lib/compat/compat.lua index 63dfd31..6ab8aba 100644 --- a/data/lib/compat/compat.lua +++ b/data/lib/compat/compat.lua @@ -1728,33 +1728,31 @@ function doMoveCreature(cid, direction) return c ~= nil and c:move(direction) end -do - local exclude = { - [2] = {"is"}, - [3] = {"get", "set", "add", "can"}, - [4] = {"need"} - } - - local function exists(name) +function createFunctions(class) + local exclude = {[2] = {"is"}, [3] = {"get", "set", "add", "can"}, [4] = {"need"}} + local temp = {} + for name, func in pairs(class) do + local add = true for strLen, strTable in pairs(exclude) do - if table.contains(strTable, name:sub(1, strLen)) then return true end + if table.contains(strTable, name:sub(1, strLen)) then + add = false + end end - end - - function createFunctions(class) - local temp = {} - for name, func in pairs(class) do - if not exists(name) then - local str = name:sub(1, 1):upper() .. name:sub(2) - local get = "get" .. str - local set = "set" .. str - if not class[get] and not class[set] then - class[get] = function(self) return func(self) end - class[set] = function(self, ...) return func(self, ...) end - end + if add then + local str = name:sub(1, 1):upper() .. name:sub(2) + local getFunc = function(self) return func(self) end + local setFunc = function(self, ...) return func(self, ...) end + local get = "get" .. str + local set = "set" .. str + if not (rawget(class, get) and rawget(class, set)) then + table.insert(temp, {set, setFunc, get, getFunc}) end end end + for _, func in ipairs(temp) do + rawset(class, func[1], func[2]) + rawset(class, func[3], func[4]) + end end function isNumber(str) return tonumber(str) ~= nil end diff --git a/data/lib/core/item.lua b/data/lib/core/item.lua index 6196c6f..5fa9676 100644 --- a/data/lib/core/item.lua +++ b/data/lib/core/item.lua @@ -37,7 +37,7 @@ do key = ITEM_ATTRIBUTE_WRITER, cmp = function(v) return v ~= "" end } - }kattyleeg niall1304k. + } function setAuxFunctions() for name, def in pairs(aux) do diff --git a/data/scripts/eventcallbacks/player/default_onRotateItem.lua b/data/scripts/eventcallbacks/player/default_onRotateItem.lua new file mode 100644 index 0000000..cdcbb1d --- /dev/null +++ b/data/scripts/eventcallbacks/player/default_onRotateItem.lua @@ -0,0 +1,8 @@ +local event = Event() + +function event.onRotateItem(player, item) + local newId = item:getType():getRotateTo() + if newId ~= 0 then item:transform(newId) end +end + +event:register() diff --git a/data/scripts/lib/event_callbacks.lua b/data/scripts/lib/event_callbacks.lua index ef036be..0920016 100644 --- a/data/scripts/lib/event_callbacks.lua +++ b/data/scripts/lib/event_callbacks.lua @@ -30,6 +30,7 @@ ec.onAreaCombat = {returnValue = true} ec.onTargetCombat = {returnValue = true} ec.onHear = {} ec.onChangeZone = {} +ec.onUpdateStorage = {} -- Party ec.onJoin = {} ec.onLeave = {} @@ -57,9 +58,9 @@ ec.onTurn = {} ec.onGainExperience = {[3] = 1} ec.onLoseExperience = {[2] = 1} ec.onGainSkillTries = {[3] = 1} -ec.onUpdateStorage = {} ec.onUpdateInventory = {} ec.onAccountManager = {} +ec.onRotateItem = {} -- Monster ec.onDropLoot = {} ec.onSpawn = {} diff --git a/src/events.cpp b/src/events.cpp index c0e8076..e6acdc3 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -112,6 +112,8 @@ bool Events::load() info.playerOnUpdateInventory = event; } else if (methodName == "onAccountManager") { info.playerOnAccountManager = event; + } else if (methodName == "onRotateItem") { + info.playerOnRotateItem = event; } else { std::cout << "[Warning - Events::load] Unknown player method: " << methodName << std::endl; } @@ -1183,6 +1185,33 @@ void Events::eventPlayerOnAccountManager(Player* player, std::string_view text) scriptInterface.callVoidFunction(2); } +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.callVoidFunction(2); +} + void Events::eventMonsterOnDropLoot(Monster* monster, Container* corpse) { // Monster:onDropLoot(corpse) diff --git a/src/events.h b/src/events.h index b66d2d8..77965ec 100644 --- a/src/events.h +++ b/src/events.h @@ -59,6 +59,7 @@ class Events int32_t playerOnNetworkMessage = -1; int32_t playerOnUpdateInventory = -1; int32_t playerOnAccountManager = -1; + int32_t playerOnRotateItem = -1; // Monster int32_t monsterOnDropLoot = -1; @@ -113,6 +114,7 @@ class Events void eventPlayerOnNetworkMessage(Player* player, uint8_t recvByte, NetworkMessage* msg); void eventPlayerOnUpdateInventory(Player* player, Item* item, const slots_t slot, const bool equip); void eventPlayerOnAccountManager(Player* player, std::string_view text); + void eventPlayerOnRotateItem(Player* player, Item* item); // Monster void eventMonsterOnDropLoot(Monster* monster, Container* corpse); diff --git a/src/game.cpp b/src/game.cpp index 4913bf1..ad1ce9b 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2361,10 +2361,7 @@ void Game::playerRotateItem(uint32_t playerId, const Position& pos, uint8_t stac return; } - uint16_t newId = Item::items[item->getID()].rotateTo; - if (newId != 0) { - transformItem(item, newId); - } + g_events->eventPlayerOnRotateItem(player, item); } void Game::playerWriteItem(uint32_t playerId, uint32_t windowTextId, std::string_view text) diff --git a/src/luascript.cpp b/src/luascript.cpp index 1d712d5..6a47d60 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -2761,6 +2761,7 @@ void LuaScriptInterface::registerFunctions() registerMethod("ItemType", "getRequiredLevel", LuaScriptInterface::luaItemTypeGetRequiredLevel); registerMethod("ItemType", "getAmmoType", LuaScriptInterface::luaItemTypeGetAmmoType); registerMethod("ItemType", "getCorpseType", LuaScriptInterface::luaItemTypeGetCorpseType); + registerMethod("ItemType", "getRotateTo", LuaScriptInterface::luaItemTypeGetRotateTo); registerMethod("ItemType", "getAbilities", LuaScriptInterface::luaItemTypeGetAbilities); @@ -12121,6 +12122,18 @@ int LuaScriptInterface::luaItemTypeGetCorpseType(lua_State* L) return 1; } +int LuaScriptInterface::luaItemTypeGetRotateTo(lua_State* L) +{ + // itemType:getRotateTo() + const ItemType* itemType = getUserdata(L, 1); + if (itemType) { + lua_pushinteger(L, itemType->rotateTo); + } else { + lua_pushnil(L); + } + return 1; +} + int LuaScriptInterface::luaItemTypeGetAbilities(lua_State* L) { // itemType:getAbilities() diff --git a/src/luascript.h b/src/luascript.h index 52bac77..e2c824b 100644 --- a/src/luascript.h +++ b/src/luascript.h @@ -1243,6 +1243,7 @@ class LuaScriptInterface static int luaItemTypeGetRequiredLevel(lua_State* L); static int luaItemTypeGetAmmoType(lua_State* L); static int luaItemTypeGetCorpseType(lua_State* L); + static int luaItemTypeGetRotateTo(lua_State* L); static int luaItemTypeHasShowCount(lua_State* L); static int luaItemTypeGetAbilities(lua_State* L); static int luaItemTypeHasShowAttributes(lua_State* L);