From 1d9d8863ff0669132c97f177be51e07ad39e73e5 Mon Sep 17 00:00:00 2001 From: Eduardo Dantas Date: Thu, 7 Nov 2024 18:47:26 -0300 Subject: [PATCH] perf: remove "onSpawn" and "onHear" EventCallbacks --- .../iron_servant_transformation.lua | 31 ----- data/scripts/actions/items/cobra_flask.lua | 16 --- data/scripts/eventcallbacks/README.md | 19 +-- .../eventcallbacks/creature/on_hear.lua | 5 - .../eventcallbacks/monster/on_spawn.lua | 27 ----- .../monsters/spawns/spawn_monster.cpp | 2 - src/creatures/npcs/spawns/spawn_npc.cpp | 3 - src/creatures/players/player.cpp | 4 - src/game/game.cpp | 4 - src/lua/callbacks/callbacks_definitions.hpp | 4 - src/lua/callbacks/event_callback.cpp | 84 ------------- src/lua/callbacks/event_callback.hpp | 5 - src/lua/creature/events.cpp | 110 ------------------ src/lua/creature/events.hpp | 10 -- .../functions/core/game/game_functions.cpp | 2 - 15 files changed, 2 insertions(+), 324 deletions(-) delete mode 100644 data-otservbr-global/scripts/world_changes/iron_servant_transformation.lua delete mode 100644 data/scripts/eventcallbacks/creature/on_hear.lua delete mode 100644 data/scripts/eventcallbacks/monster/on_spawn.lua diff --git a/data-otservbr-global/scripts/world_changes/iron_servant_transformation.lua b/data-otservbr-global/scripts/world_changes/iron_servant_transformation.lua deleted file mode 100644 index e62cd23c876..00000000000 --- a/data-otservbr-global/scripts/world_changes/iron_servant_transformation.lua +++ /dev/null @@ -1,31 +0,0 @@ -local ironServantTransformation = EventCallback("IronServantTransformationOnSpawn") - -ironServantTransformation.monsterOnSpawn = function(monster, position) - if monster:getName():lower() ~= "iron servant replica" then - return - end - - local chance = math.random(100) - if Game.getStorageValue(Storage.Quest.U11_02.ForgottenKnowledge.MechanismDiamond) >= 1 and Game.getStorageValue(Storage.Quest.U11_02.ForgottenKnowledge.MechanismGolden) >= 1 then - if chance > 30 then - local monsterType = math.random(2) == 1 and "diamond servant replica" or "golden servant replica" - Game.createMonster(monsterType, monster:getPosition(), false, true) - monster:remove() - end - return - end - - if Game.getStorageValue(Storage.Quest.U11_02.ForgottenKnowledge.MechanismDiamond) >= 1 and chance > 30 then - Game.createMonster("diamond servant replica", monster:getPosition(), false, true) - monster:remove() - return - end - - if Game.getStorageValue(Storage.Quest.U11_02.ForgottenKnowledge.MechanismGolden) >= 1 and chance > 30 then - Game.createMonster("golden servant replica", monster:getPosition(), false, true) - monster:remove() - end - return true -end - -ironServantTransformation:register() diff --git a/data/scripts/actions/items/cobra_flask.lua b/data/scripts/actions/items/cobra_flask.lua index c36d42983c5..0556373afae 100644 --- a/data/scripts/actions/items/cobra_flask.lua +++ b/data/scripts/actions/items/cobra_flask.lua @@ -1,19 +1,3 @@ -local applyCobraFlaskEffectOnMonsterSpawn = EventCallback("CobraFlaskEffectOnMonsterSpawn") - -applyCobraFlaskEffectOnMonsterSpawn.monsterOnSpawn = function(monster, position) - if table.contains({ "cobra scout", "cobra vizier", "cobra assassin" }, monster:getName():lower()) then - if Game.getStorageValue(Global.Storage.CobraFlask) >= os.time() then - monster:setHealth(monster:getMaxHealth() * 0.75) - monster:getPosition():sendMagicEffect(CONST_ME_GREEN_RINGS) - else - Game.setStorageValue(Global.Storage.CobraFlask, -1) - end - end - return true -end - -applyCobraFlaskEffectOnMonsterSpawn:register() - local cobraFlask = Action() function cobraFlask.onUse(player, item, fromPosition, target, toPosition, isHotkey) diff --git a/data/scripts/eventcallbacks/README.md b/data/scripts/eventcallbacks/README.md index 6e0bacfcd6e..bbcee5de3c4 100644 --- a/data/scripts/eventcallbacks/README.md +++ b/data/scripts/eventcallbacks/README.md @@ -16,7 +16,6 @@ Event callbacks are available for several categories of game entities, such as ` - `(bool)` `creatureOnChangeOutfit` - `(ReturnValue)` `creatureOnAreaCombat` - `(ReturnValue)` `creatureOnTargetCombat` -- `(void)` `creatureOnHear` - `(void)` `creatureOnDrainHealth` - `(void)` `creatureOnCombat` - `(bool)` `partyOnJoin` @@ -51,8 +50,6 @@ Event callbacks are available for several categories of game entities, such as ` - `(void)` `playerOnWalk` - `(void)` `monsterOnDropLoot` - `(void)` `monsterPostDropLoot` -- `(void)` `monsterOnSpawn` -- `(void)` `npcOnSpawn` ## Event Callback Usage @@ -102,20 +99,8 @@ callback:register() ```lua local callback = EventCallback("UniqueCallbackName") -function callback.monsterOnSpawn(monster, position) - -- custom behavior when a monster spawns -end - -callback:register() -``` - -### Npc Callback - -```lua -local callback = EventCallback("UniqueCallbackName") - -function callback.npcOnSpawn(npc, position) - -- custom behavior when a npc spawns +function callback.monsterOnDropLoot(monster, corpse) + logger.info("Monster {} has corpse {}", monster:getName(), corpse:getName()); end callback:register() diff --git a/data/scripts/eventcallbacks/creature/on_hear.lua b/data/scripts/eventcallbacks/creature/on_hear.lua deleted file mode 100644 index 2954c81c8fb..00000000000 --- a/data/scripts/eventcallbacks/creature/on_hear.lua +++ /dev/null @@ -1,5 +0,0 @@ -local callback = EventCallback("CreatureOnHearBaseEvent") - -function callback.creatureOnHear(creature, speaker, words, type) end - -callback:register() diff --git a/data/scripts/eventcallbacks/monster/on_spawn.lua b/data/scripts/eventcallbacks/monster/on_spawn.lua deleted file mode 100644 index 5a490a8edac..00000000000 --- a/data/scripts/eventcallbacks/monster/on_spawn.lua +++ /dev/null @@ -1,27 +0,0 @@ -local callback = EventCallback("MonsterOnSpawnBase") - -function callback.monsterOnSpawn(monster, position) - if not monster then - return - end - - HazardMonster.onSpawn(monster, position) - - if monster:getType():isRewardBoss() then - monster:setReward(true) - end - - if not monster:getType():canSpawn(position) then - monster:remove() - else - local spec = Game.getSpectators(position, false, false) - for _, creatureId in pairs(spec) do - local monster = Monster(creatureId) - if monster and not monster:getType():canSpawn(position) then - monster:remove() - end - end - end -end - -callback:register() diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index 7d7bbc84e34..3a915d737b2 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -232,9 +232,7 @@ bool SpawnMonster::spawnMonster(uint32_t spawnMonsterId, spawnBlock_t &sb, const spawnedMonsterMap[spawnMonsterId] = monster; sb.lastSpawn = OTSYS_TIME(); - g_events().eventMonsterOnSpawn(monster, sb.pos); monster->onSpawn(); - g_callbacks().executeCallback(EventCallback_t::monsterOnSpawn, &EventCallback::monsterOnSpawn, monster, sb.pos); return true; } diff --git a/src/creatures/npcs/spawns/spawn_npc.cpp b/src/creatures/npcs/spawns/spawn_npc.cpp index bf3b6a1bc65..404f6ce588e 100644 --- a/src/creatures/npcs/spawns/spawn_npc.cpp +++ b/src/creatures/npcs/spawns/spawn_npc.cpp @@ -202,9 +202,6 @@ bool SpawnNpc::spawnNpc(uint32_t spawnId, const std::shared_ptr &npcTyp spawnedNpcMap.insert(spawned_pair(spawnId, npc)); spawnNpcMap[spawnId].lastSpawnNpc = OTSYS_TIME(); - - g_events().eventNpcOnSpawn(npc, pos); - g_callbacks().executeCallback(EventCallback_t::npcOnSpawn, &EventCallback::npcOnSpawn, npc, pos); return true; } diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 923b153a99a..fcf83ccdecb 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -8713,10 +8713,6 @@ bool Player::saySpell(SpeakClasses type, const std::string &text, bool isGhostMo } tmpPlayer->onCreatureSay(static_self_cast(), type, text); - if (static_self_cast() != tmpPlayer) { - g_events().eventCreatureOnHear(tmpPlayer, getPlayer(), text, type); - g_callbacks().executeCallback(EventCallback_t::creatureOnHear, &EventCallback::creatureOnHear, tmpPlayer, getPlayer(), text, type); - } } return true; } diff --git a/src/game/game.cpp b/src/game/game.cpp index 780ce5b7303..140a6d8e62f 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -6397,10 +6397,6 @@ bool Game::internalCreatureSay(const std::shared_ptr &creature, SpeakC // event method for (const auto &spectator : spectators) { spectator->onCreatureSay(creature, type, text); - if (creature != spectator) { - g_events().eventCreatureOnHear(spectator, creature, text, type); - g_callbacks().executeCallback(EventCallback_t::creatureOnHear, &EventCallback::creatureOnHear, spectator, creature, text, type); - } } return true; } diff --git a/src/lua/callbacks/callbacks_definitions.hpp b/src/lua/callbacks/callbacks_definitions.hpp index 6c19cc809c9..faea6b2d1e2 100644 --- a/src/lua/callbacks/callbacks_definitions.hpp +++ b/src/lua/callbacks/callbacks_definitions.hpp @@ -23,7 +23,6 @@ enum class EventCallback_t : uint16_t { creatureOnChangeOutfit, creatureOnAreaCombat, creatureOnTargetCombat, - creatureOnHear, creatureOnDrainHealth, creatureOnCombat, // Party @@ -62,9 +61,6 @@ enum class EventCallback_t : uint16_t { // Monster monsterOnDropLoot, monsterPostDropLoot, - monsterOnSpawn, - // Npc - npcOnSpawn, // Zone zoneBeforeCreatureEnter, zoneBeforeCreatureLeave, diff --git a/src/lua/callbacks/event_callback.cpp b/src/lua/callbacks/event_callback.cpp index 3d95543f1b9..1675cdef440 100644 --- a/src/lua/callbacks/event_callback.cpp +++ b/src/lua/callbacks/event_callback.cpp @@ -154,33 +154,6 @@ ReturnValue EventCallback::creatureOnTargetCombat(const std::shared_ptr &creature, const std::shared_ptr &speaker, const std::string &words, SpeakClasses type) const { - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("[EventCallback::creatureOnHear - " - "Creature {} speaker {}] " - "Call stack overflow. Too many lua script calls being nested.", - creature->getName(), speaker->getName()); - return; - } - - ScriptEnvironment* scriptEnvironment = LuaScriptInterface::getScriptEnv(); - scriptEnvironment->setScriptId(getScriptId(), getScriptInterface()); - - lua_State* L = getScriptInterface()->getLuaState(); - getScriptInterface()->pushFunction(getScriptId()); - - LuaScriptInterface::pushUserdata(L, creature); - LuaScriptInterface::setCreatureMetatable(L, -1, creature); - - LuaScriptInterface::pushUserdata(L, speaker); - LuaScriptInterface::setCreatureMetatable(L, -1, speaker); - - LuaScriptInterface::pushString(L, words); - lua_pushnumber(L, type); - - getScriptInterface()->callVoidFunction(4); -} - void EventCallback::creatureOnDrainHealth(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) const { if (!LuaScriptInterface::reserveScriptEnv()) { g_logger().error("[EventCallback::creatureOnDrainHealth - " @@ -1162,63 +1135,6 @@ void EventCallback::monsterPostDropLoot(const std::shared_ptr &monster, return getScriptInterface()->callVoidFunction(2); } -void EventCallback::monsterOnSpawn(const std::shared_ptr &monster, const Position &position) const { - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("{} - " - "Position {}" - ". Call stack overflow. Too many lua script calls being nested.", - __FUNCTION__, position.toString()); - return; - } - - ScriptEnvironment* scriptEnvironment = LuaScriptInterface::getScriptEnv(); - scriptEnvironment->setScriptId(getScriptId(), getScriptInterface()); - - lua_State* L = getScriptInterface()->getLuaState(); - getScriptInterface()->pushFunction(getScriptId()); - - LuaScriptInterface::pushUserdata(L, monster); - LuaScriptInterface::setMetatable(L, -1, "Monster"); - LuaScriptInterface::pushPosition(L, position); - - if (LuaScriptInterface::protectedCall(L, 2, 1) != 0) { - LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L)); - } else { - lua_pop(L, 1); - } - - LuaScriptInterface::resetScriptEnv(); -} - -// Npc -void EventCallback::npcOnSpawn(const std::shared_ptr &npc, const Position &position) const { - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("{} - " - "Position {}" - ". Call stack overflow. Too many lua script calls being nested.", - __FUNCTION__, position.toString()); - return; - } - - ScriptEnvironment* scriptEnvironment = LuaScriptInterface::getScriptEnv(); - scriptEnvironment->setScriptId(getScriptId(), getScriptInterface()); - - lua_State* L = getScriptInterface()->getLuaState(); - getScriptInterface()->pushFunction(getScriptId()); - - LuaScriptInterface::pushUserdata(L, npc); - LuaScriptInterface::setMetatable(L, -1, "Npc"); - LuaScriptInterface::pushPosition(L, position); - - if (LuaScriptInterface::protectedCall(L, 2, 1) != 0) { - LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L)); - } else { - lua_pop(L, 1); - } - - LuaScriptInterface::resetScriptEnv(); -} - bool EventCallback::zoneBeforeCreatureEnter(const std::shared_ptr &zone, const std::shared_ptr &creature) const { if (!LuaScriptInterface::reserveScriptEnv()) { g_logger().error("[EventCallback::zoneBeforeCreatureEnter - " diff --git a/src/lua/callbacks/event_callback.hpp b/src/lua/callbacks/event_callback.hpp index fb0eb760a20..514c7feafff 100644 --- a/src/lua/callbacks/event_callback.hpp +++ b/src/lua/callbacks/event_callback.hpp @@ -96,7 +96,6 @@ class EventCallback final : public Script { bool creatureOnChangeOutfit(const std::shared_ptr &creature, const Outfit_t &outfit) const; ReturnValue creatureOnAreaCombat(const std::shared_ptr &creature, const std::shared_ptr &tile, bool aggressive) const; ReturnValue creatureOnTargetCombat(const std::shared_ptr &creature, const std::shared_ptr &target) const; - void creatureOnHear(const std::shared_ptr &creature, const std::shared_ptr &speaker, const std::string &words, SpeakClasses type) const; void creatureOnDrainHealth(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) const; void creatureOnCombat(std::shared_ptr attacker, std::shared_ptr target, CombatDamage &damage) const; @@ -137,10 +136,6 @@ class EventCallback final : public Script { // Monster void monsterOnDropLoot(const std::shared_ptr &monster, const std::shared_ptr &corpse) const; void monsterPostDropLoot(const std::shared_ptr &monster, const std::shared_ptr &corpse) const; - void monsterOnSpawn(const std::shared_ptr &monster, const Position &position) const; - - // Npc - void npcOnSpawn(const std::shared_ptr &npc, const Position &position) const; // Zone bool zoneBeforeCreatureEnter(const std::shared_ptr &zone, const std::shared_ptr &creature) const; diff --git a/src/lua/creature/events.cpp b/src/lua/creature/events.cpp index 57a8ff45d31..9e03858107b 100644 --- a/src/lua/creature/events.cpp +++ b/src/lua/creature/events.cpp @@ -62,8 +62,6 @@ bool Events::loadFromXml() { info.creatureOnAreaCombat = event; } else if (methodName == "onTargetCombat") { info.creatureOnTargetCombat = event; - } else if (methodName == "onHear") { - info.creatureOnHear = event; } else if (methodName == "onDrainHealth") { info.creatureOnDrainHealth = event; } else { @@ -136,17 +134,9 @@ bool Events::loadFromXml() { } else if (className == "Monster") { if (methodName == "onDropLoot") { info.monsterOnDropLoot = event; - } else if (methodName == "onSpawn") { - info.monsterOnSpawn = event; } else { g_logger().warn("{} - Unknown monster method: {}", __FUNCTION__, methodName); } - } else if (className == "Npc") { - if (methodName == "onSpawn") { - info.monsterOnSpawn = event; - } else { - g_logger().warn("{} - Unknown npc method: {}", __FUNCTION__, methodName); - } } else { g_logger().warn("{} - Unknown class: {}", __FUNCTION__, className); } @@ -154,74 +144,6 @@ bool Events::loadFromXml() { return true; } -// Monster -void Events::eventMonsterOnSpawn(const std::shared_ptr &monster, const Position &position) { - // Monster:onSpawn(position) or Monster.onSpawn(self, position) - if (info.monsterOnSpawn == -1) { - return; - } - - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("{} - " - "Position {}" - ". Call stack overflow. Too many lua script calls being nested.", - __FUNCTION__, position.toString()); - return; - } - - ScriptEnvironment* env = LuaScriptInterface::getScriptEnv(); - env->setScriptId(info.monsterOnSpawn, &scriptInterface); - - lua_State* L = scriptInterface.getLuaState(); - scriptInterface.pushFunction(info.monsterOnSpawn); - - LuaScriptInterface::pushUserdata(L, monster); - LuaScriptInterface::setMetatable(L, -1, "Monster"); - LuaScriptInterface::pushPosition(L, position); - - if (LuaScriptInterface::protectedCall(L, 2, 1) != 0) { - LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L)); - } else { - lua_pop(L, 1); - } - - LuaScriptInterface::resetScriptEnv(); -} - -// Npc -void Events::eventNpcOnSpawn(const std::shared_ptr &npc, const Position &position) { - // Npc:onSpawn(position) or Npc.onSpawn(self, position) - if (info.npcOnSpawn == -1) { - return; - } - - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("{} - " - "Position {}" - ". Call stack overflow. Too many lua script calls being nested.", - __FUNCTION__, position.toString()); - return; - } - - ScriptEnvironment* env = LuaScriptInterface::getScriptEnv(); - env->setScriptId(info.npcOnSpawn, &scriptInterface); - - lua_State* L = scriptInterface.getLuaState(); - scriptInterface.pushFunction(info.npcOnSpawn); - - LuaScriptInterface::pushUserdata(L, npc); - LuaScriptInterface::setMetatable(L, -1, "Npc"); - LuaScriptInterface::pushPosition(L, position); - - if (LuaScriptInterface::protectedCall(L, 2, 1) != 0) { - LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L)); - } else { - lua_pop(L, 1); - } - - LuaScriptInterface::resetScriptEnv(); -} - Events &Events::getInstance() { return inject(); } @@ -342,38 +264,6 @@ ReturnValue Events::eventCreatureOnTargetCombat(const std::shared_ptr return returnValue; } -void Events::eventCreatureOnHear(const std::shared_ptr &creature, const std::shared_ptr &speaker, const std::string &words, SpeakClasses type) { - // Creature:onHear(speaker, words, type) - if (info.creatureOnHear == -1) { - return; - } - - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("[Events::eventCreatureOnHear - " - "Creature {} speaker {}] " - "Call stack overflow. Too many lua script calls being nested.", - creature->getName(), speaker->getName()); - return; - } - - ScriptEnvironment* env = LuaScriptInterface::getScriptEnv(); - env->setScriptId(info.creatureOnHear, &scriptInterface); - - lua_State* L = scriptInterface.getLuaState(); - scriptInterface.pushFunction(info.creatureOnHear); - - LuaScriptInterface::pushUserdata(L, creature); - LuaScriptInterface::setCreatureMetatable(L, -1, creature); - - LuaScriptInterface::pushUserdata(L, speaker); - LuaScriptInterface::setCreatureMetatable(L, -1, speaker); - - LuaScriptInterface::pushString(L, words); - lua_pushnumber(L, type); - - scriptInterface.callVoidFunction(4); -} - void Events::eventCreatureOnDrainHealth(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) { if (info.creatureOnDrainHealth == -1) { return; diff --git a/src/lua/creature/events.hpp b/src/lua/creature/events.hpp index a74cbaf3ccf..59d6b2f20d0 100644 --- a/src/lua/creature/events.hpp +++ b/src/lua/creature/events.hpp @@ -41,7 +41,6 @@ class Events { int32_t creatureOnChangeOutfit = -1; int32_t creatureOnAreaCombat = -1; int32_t creatureOnTargetCombat = -1; - int32_t creatureOnHear = -1; int32_t creatureOnDrainHealth = -1; // Party @@ -78,10 +77,6 @@ class Events { // Monster int32_t monsterOnDropLoot = -1; - int32_t monsterOnSpawn = -1; - - // Npc - int32_t npcOnSpawn = -1; }; public: @@ -99,7 +94,6 @@ class Events { bool eventCreatureOnChangeOutfit(const std::shared_ptr &creature, const Outfit_t &outfit); ReturnValue eventCreatureOnAreaCombat(const std::shared_ptr &creature, const std::shared_ptr &tile, bool aggressive); ReturnValue eventCreatureOnTargetCombat(const std::shared_ptr &creature, const std::shared_ptr &target); - void eventCreatureOnHear(const std::shared_ptr &creature, const std::shared_ptr &speaker, const std::string &words, SpeakClasses type); void eventCreatureOnDrainHealth(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary); // Party @@ -135,10 +129,6 @@ class Events { // Monster void eventMonsterOnDropLoot(const std::shared_ptr &monster, const std::shared_ptr &corpse); - void eventMonsterOnSpawn(const std::shared_ptr &monster, const Position &position); - - // Monster - void eventNpcOnSpawn(const std::shared_ptr &npc, const Position &position); private: LuaScriptInterface scriptInterface; diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index 16133833bbc..f1445b628b6 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -444,8 +444,6 @@ int GameFunctions::luaGameCreateMonster(lua_State* L) { const bool extended = getBoolean(L, 3, false); const bool force = getBoolean(L, 4, false); if (g_game().placeCreature(monster, position, extended, force)) { - g_events().eventMonsterOnSpawn(monster, position); - g_callbacks().executeCallback(EventCallback_t::monsterOnSpawn, &EventCallback::monsterOnSpawn, monster, position); monster->onSpawn(); const auto &mtype = monster->getMonsterType(); if (mtype && mtype->info.raceid > 0 && mtype->info.bosstiaryRace == BosstiaryRarity_t::RARITY_ARCHFOE) {