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);