diff --git a/src/canary_server.cpp b/src/canary_server.cpp index 687fa51b6cd..8dfbcfc954c 100644 --- a/src/canary_server.cpp +++ b/src/canary_server.cpp @@ -9,6 +9,7 @@ #include "canary_server.hpp" +#include "core.hpp" #include "config/configmanager.hpp" #include "creatures/npcs/npcs.hpp" #include "creatures/players/grouping/familiars.hpp" @@ -31,8 +32,7 @@ #include "server/network/protocol/protocollogin.hpp" #include "server/network/protocol/protocolstatus.hpp" #include "server/network/webhook/webhook.hpp" - -#include "core.hpp" +#include "creatures/players/vocations/vocation.hpp" CanaryServer::CanaryServer( Logger &logger, @@ -322,6 +322,7 @@ void CanaryServer::initializeDatabase() { && !DatabaseManager::optimizeTables()) { logger.debug("No tables were optimized"); } + g_logger().info("Database connection established!"); } void CanaryServer::loadModules() { diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index a63f42093db..d02ce99fbc5 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -15,12 +15,14 @@ #include "creatures/monsters/monster.hpp" #include "creatures/monsters/monsters.hpp" #include "creatures/players/grouping/party.hpp" +#include "creatures/players/player.hpp" #include "creatures/players/imbuements/imbuements.hpp" #include "creatures/players/wheel/player_wheel.hpp" #include "game/game.hpp" #include "game/scheduling/dispatcher.hpp" #include "io/iobestiary.hpp" #include "io/ioprey.hpp" +#include "creatures/players/vocations/vocation.hpp" #include "items/weapons/weapons.hpp" #include "lib/metrics/metrics.hpp" #include "lua/callbacks/event_callback.hpp" diff --git a/src/creatures/combat/spells.cpp b/src/creatures/combat/spells.cpp index 0d66602ddca..8653b018234 100644 --- a/src/creatures/combat/spells.cpp +++ b/src/creatures/combat/spells.cpp @@ -20,7 +20,8 @@ #include "game/game.hpp" #include "lua/global/lua_variant.hpp" #include "lua/scripts/lua_environment.hpp" -#include "lua/scripts/luascript.hpp" +#include "lua/scripts/scripts.hpp" +#include "lib/di/container.hpp" std::array(WheelSpellBoost_t::TOTAL_COUNT)> wheelOfDestinyRegularBoost = { 0 }; std::array(WheelSpellBoost_t::TOTAL_COUNT)> wheelOfDestinyUpgradedBoost = { 0 }; @@ -277,29 +278,45 @@ Position Spells::getCasterPosition(const std::shared_ptr &creature, Di return getNextPosition(dir, creature->getPosition()); } +LuaScriptInterface* BaseSpell::getScriptInterface() const { + return &g_scripts().getScriptInterface(); +} + +bool BaseSpell::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[MoveEvent::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; +} + +int32_t BaseSpell::getScriptId() const { + return m_scriptId; +} + +void BaseSpell::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool BaseSpell::isLoadedScriptId() const { + return m_scriptId != 0; +} + CombatSpell::CombatSpell(const std::shared_ptr &newCombat, bool newNeedTarget, bool newNeedDirection) : - Script(&g_spells().getScriptInterface()), m_combat(newCombat), needDirection(newNeedDirection), needTarget(newNeedTarget) { - // Empty -} - -bool CombatSpell::loadScriptCombat() { - m_combat = g_luaEnvironment().getCombatObject(g_luaEnvironment().lastCombatId); - return m_combat != nullptr; } std::shared_ptr CombatSpell::getCombat() const { return m_combat; } -std::string CombatSpell::getScriptTypeName() const { - return "onCastSpell"; -} - bool CombatSpell::castSpell(const std::shared_ptr &creature) { - if (isLoadedCallback()) { + if (isLoadedScriptId()) { LuaVariant var; var.type = VARIANT_POSITION; @@ -346,7 +363,7 @@ bool CombatSpell::castSpell(const std::shared_ptr &creature, const std return false; } - if (isLoadedCallback()) { + if (isLoadedScriptId()) { LuaVariant var; if (combat->hasArea()) { var.type = VARIANT_POSITION; @@ -412,6 +429,8 @@ bool CombatSpell::executeCastSpell(const std::shared_ptr &creature, co return getScriptInterface()->callFunction(2); } +Spell::Spell() = default; + bool Spell::playerSpellCheck(const std::shared_ptr &player) const { if (player->hasFlag(PlayerFlags_t::CannotUseSpells)) { return false; @@ -1030,6 +1049,8 @@ void Spell::setLockedPZ(bool b) { pzLocked = b; } +InstantSpell::InstantSpell() = default; + bool InstantSpell::playerCastInstant(const std::shared_ptr &player, std::string ¶m) const { if (!playerSpellCheck(player)) { return false; @@ -1161,10 +1182,6 @@ bool InstantSpell::canThrowSpell(const std::shared_ptr &creature, cons return true; } -std::string InstantSpell::getScriptTypeName() const { - return "onCastSpell"; -} - bool InstantSpell::castSpell(const std::shared_ptr &creature) { LuaVariant var; var.instantName = getName(); @@ -1294,6 +1311,33 @@ bool InstantSpell::canCast(const std::shared_ptr &player) const { return false; } +LuaScriptInterface* RuneSpell::getScriptInterface() const { + return &g_scripts().getScriptInterface(); +} + +bool RuneSpell::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[MoveEvent::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; +} + +int32_t RuneSpell::getScriptId() const { + return m_scriptId; +} + +void RuneSpell::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool RuneSpell::isLoadedScriptId() const { + return m_scriptId != 0; +} + ReturnValue RuneSpell::canExecuteAction(const std::shared_ptr &player, const Position &toPos) { if (player->hasFlag(PlayerFlags_t::CannotUseSpells)) { return RETURNVALUE_CANNOTUSETHISOBJECT; @@ -1329,7 +1373,7 @@ bool RuneSpell::executeUse(const std::shared_ptr &player, const std::sha } // If script not loaded correctly, return - if (!isLoadedCallback()) { + if (!isLoadedScriptId()) { return false; } @@ -1391,13 +1435,9 @@ bool RuneSpell::castSpell(const std::shared_ptr &creature, const std:: return internalCastSpell(creature, var, false); } -std::string RuneSpell::getScriptTypeName() const { - return "onCastSpell"; -} - bool RuneSpell::internalCastSpell(const std::shared_ptr &creature, const LuaVariant &var, bool isHotkey) const { bool result; - if (isLoadedCallback()) { + if (isLoadedScriptId()) { result = executeCastSpell(creature, var, isHotkey); } else { result = false; diff --git a/src/creatures/combat/spells.hpp b/src/creatures/combat/spells.hpp index c12c3af3686..62abc5b2e2f 100644 --- a/src/creatures/combat/spells.hpp +++ b/src/creatures/combat/spells.hpp @@ -10,7 +10,6 @@ #pragma once #include "lua/creature/actions.hpp" -#include "lua/scripts/scripts.hpp" enum class WheelSpellBoost_t : uint8_t; enum class WheelSpellGrade_t : uint8_t; @@ -18,12 +17,17 @@ enum class WheelSpellGrade_t : uint8_t; class InstantSpell; class RuneSpell; class Spell; +class Combat; +class Player; +class Creature; +class LuaScriptInterface; struct LuaVariant; +struct Position; using VocSpellMap = std::map; -class Spells final : public Scripts { +class Spells { public: Spells(); ~Spells(); @@ -79,11 +83,19 @@ class BaseSpell { virtual bool castSpell(const std::shared_ptr &creature) = 0; virtual bool castSpell(const std::shared_ptr &creature, const std::shared_ptr &target) = 0; + LuaScriptInterface* getScriptInterface() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; + + int32_t m_scriptId {}; + SoundEffect_t soundImpactEffect = SoundEffect_t::SILENCE; SoundEffect_t soundCastEffect = SoundEffect_t::SPELL_OR_RUNE; }; -class CombatSpell final : public Script, public BaseSpell, public std::enable_shared_from_this { +class CombatSpell final : public BaseSpell, public std::enable_shared_from_this { public: // Constructor CombatSpell(const std::shared_ptr &newCombat, bool newNeedTarget, bool newNeedDirection); @@ -98,12 +110,9 @@ class CombatSpell final : public Script, public BaseSpell, public std::enable_sh // Scripting spell bool executeCastSpell(const std::shared_ptr &creature, const LuaVariant &var) const; - bool loadScriptCombat(); std::shared_ptr getCombat() const; private: - std::string getScriptTypeName() const override; - std::shared_ptr m_combat; bool needDirection; @@ -112,7 +121,7 @@ class CombatSpell final : public Script, public BaseSpell, public std::enable_sh class Spell : public BaseSpell { public: - Spell() = default; + Spell(); [[nodiscard]] const std::string &getName() const; void setName(std::string n); @@ -268,10 +277,9 @@ class Spell : public BaseSpell { friend class SpellFunctions; }; -class InstantSpell final : public Script, public Spell { +class InstantSpell final : public Spell { public: - using Script::Script; - + InstantSpell(); bool playerCastInstant(const std::shared_ptr &player, std::string ¶m) const; bool castSpell(const std::shared_ptr &creature) override; @@ -295,8 +303,6 @@ class InstantSpell final : public Script, public Spell { bool canThrowSpell(const std::shared_ptr &creature, const std::shared_ptr &target) const; private: - [[nodiscard]] std::string getScriptTypeName() const override; - bool needDirection = false; bool hasParam = false; bool hasPlayerNameParam = false; @@ -308,6 +314,12 @@ class RuneSpell final : public Action, public Spell { public: using Action::Action; + LuaScriptInterface* getScriptInterface() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; + ReturnValue canExecuteAction(const std::shared_ptr &player, const Position &toPos) override; bool hasOwnErrorHandler() override; std::shared_ptr getTarget(const std::shared_ptr &, const std::shared_ptr &targetCreature, const Position &, uint8_t) const override; @@ -327,10 +339,10 @@ class RuneSpell final : public Action, public Spell { void setCharges(uint32_t c); private: - [[nodiscard]] std::string getScriptTypeName() const override; - bool internalCastSpell(const std::shared_ptr &creature, const LuaVariant &var, bool isHotkey) const; + int32_t m_scriptId {}; + uint16_t runeId = 0; uint32_t charges = 0; bool hasCharges = false; diff --git a/src/creatures/monsters/monsters.cpp b/src/creatures/monsters/monsters.cpp index 87fd967ab46..cd33e12e248 100644 --- a/src/creatures/monsters/monsters.cpp +++ b/src/creatures/monsters/monsters.cpp @@ -16,6 +16,7 @@ #include "game/game.hpp" #include "items/weapons/weapons.hpp" #include "lua/scripts/luascript.hpp" +#include "lib/di/container.hpp" void MonsterType::loadLoot(const std::shared_ptr &monsterType, LootBlock lootBlock) const { if (lootBlock.childLoot.empty()) { diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index 153db66dee4..7d7bbc84e34 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -327,7 +327,7 @@ void SpawnMonster::scheduleSpawn(uint32_t spawnMonsterId, spawnBlock_t &sb, cons } void SpawnMonster::cleanup() { - for (auto it = spawnedMonsterMap.begin(); it != spawnedMonsterMap.end(); ) { + for (auto it = spawnedMonsterMap.begin(); it != spawnedMonsterMap.end();) { const auto &monster = it->second; if (!monster || monster->isRemoved()) { auto spawnIt = spawnMonsterMap.find(it->first); diff --git a/src/creatures/npcs/npcs.cpp b/src/creatures/npcs/npcs.cpp index cff44588d71..53ed757336f 100644 --- a/src/creatures/npcs/npcs.cpp +++ b/src/creatures/npcs/npcs.cpp @@ -14,6 +14,7 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/luascript.hpp" #include "lua/scripts/scripts.hpp" +#include "lib/di/container.hpp" bool NpcType::canSpawn(const Position &pos) const { bool canSpawn = true; diff --git a/src/game/functions/game_reload.cpp b/src/game/functions/game_reload.cpp index 10f20595042..5de3e98b0b0 100644 --- a/src/game/functions/game_reload.cpp +++ b/src/game/functions/game_reload.cpp @@ -22,6 +22,7 @@ #include "lua/modules/modules.hpp" #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/scripts.hpp" +#include "creatures/players/vocations/vocation.hpp" GameReload::GameReload() = default; GameReload::~GameReload() = default; diff --git a/src/game/game.cpp b/src/game/game.cpp index 4018c1b2f90..bb68947214b 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -62,6 +62,7 @@ #include "server/server.hpp" #include "utils/tools.hpp" #include "utils/wildcardtree.hpp" +#include "creatures/players/vocations/vocation.hpp" #include "enums/account_coins.hpp" #include "enums/account_errors.hpp" diff --git a/src/game/game_definitions.hpp b/src/game/game_definitions.hpp index e122cdf979f..50fa1307764 100644 --- a/src/game/game_definitions.hpp +++ b/src/game/game_definitions.hpp @@ -54,7 +54,7 @@ enum Faction_t { FACTION_LAST = FACTION_FAFNAR, }; -enum LightState_t { +enum LightState_t : uint8_t { LIGHT_STATE_DAY, LIGHT_STATE_NIGHT, LIGHT_STATE_SUNSET, diff --git a/src/game/scheduling/task.cpp b/src/game/scheduling/task.cpp index b3a79f7ab18..1edd246a702 100644 --- a/src/game/scheduling/task.cpp +++ b/src/game/scheduling/task.cpp @@ -15,22 +15,22 @@ std::atomic_uint_fast64_t Task::LAST_EVENT_ID = 0; -Task::Task(uint32_t expiresAfterMs, std::function &&f, std::string_view context, const std::source_location &location) : - func(std::move(f)), context(context), functionName(location.function_name()), utime(OTSYS_TIME()), +Task::Task(uint32_t expiresAfterMs, std::function &&f, std::string_view context) : + func(std::move(f)), context(context), utime(OTSYS_TIME()), expiration(expiresAfterMs > 0 ? OTSYS_TIME() + expiresAfterMs : 0) { if (this->context.empty()) { - g_logger().error("[{}]: task context cannot be empty! Function: {}", __FUNCTION__, functionName); + g_logger().error("[{}]: task context cannot be empty!", __FUNCTION__); return; } assert(!this->context.empty() && "Context cannot be empty!"); } -Task::Task(std::function &&f, std::string_view context, uint32_t delay, bool cycle /* = false*/, bool log /*= true*/, const std::source_location &location) : - func(std::move(f)), context(context), functionName(location.function_name()), utime(OTSYS_TIME() + delay), delay(delay), +Task::Task(std::function &&f, std::string_view context, uint32_t delay, bool cycle /* = false*/, bool log /*= true*/) : + func(std::move(f)), context(context), utime(OTSYS_TIME() + delay), delay(delay), cycle(cycle), log(log) { if (this->context.empty()) { - g_logger().error("[{}]: task context cannot be empty! Function: {}", __FUNCTION__, functionName); + g_logger().error("[{}]: task context cannot be empty!", __FUNCTION__); return; } @@ -48,15 +48,15 @@ bool Task::execute() const { } if (hasExpired()) { - g_logger().info("The task '{}' has expired, it has not been executed in {}. Function: {}", getContext(), expiration - utime, functionName); + g_logger().info("The task '{}' has expired, it has not been executed in {}.", getContext(), expiration - utime); return false; } if (log) { if (hasTraceableContext()) { - g_logger().trace("Executing task {}. Function: {}", getContext(), functionName); + g_logger().trace("Executing task {}.", getContext()); } else { - g_logger().debug("Executing task {}. Function: {}", getContext(), functionName); + g_logger().debug("Executing task {}.", getContext()); } } diff --git a/src/game/scheduling/task.hpp b/src/game/scheduling/task.hpp index 948bdea0215..c01dbe2f676 100644 --- a/src/game/scheduling/task.hpp +++ b/src/game/scheduling/task.hpp @@ -13,9 +13,9 @@ class Dispatcher; class Task { public: - Task(uint32_t expiresAfterMs, std::function &&f, std::string_view context, const std::source_location &location = std::source_location::current()); + Task(uint32_t expiresAfterMs, std::function &&f, std::string_view context); - Task(std::function &&f, std::string_view context, uint32_t delay, bool cycle = false, bool log = true, const std::source_location &location = std::source_location::current()); + Task(std::function &&f, std::string_view context, uint32_t delay, bool cycle = false, bool log = true); ~Task() = default; @@ -37,10 +37,6 @@ class Task { return context; } - [[nodiscard]] std::string_view getFunctionName() const { - return functionName; - } - [[nodiscard]] auto getTime() const { return utime; } @@ -106,7 +102,6 @@ class Task { std::function func; std::string context; - std::string functionName; int64_t utime = 0; int64_t expiration = 0; diff --git a/src/items/functions/item/item_parse.cpp b/src/items/functions/item/item_parse.cpp index 761740bfc2d..49f23609807 100644 --- a/src/items/functions/item/item_parse.cpp +++ b/src/items/functions/item/item_parse.cpp @@ -15,6 +15,7 @@ #include "utils/pugicast.hpp" #include "utils/tools.hpp" #include "creatures/combat/combat.hpp" +#include "lua/scripts/scripts.hpp" void ItemParse::initParse(const std::string &stringValue, pugi::xml_node attributeNode, pugi::xml_attribute valueAttribute, ItemType &itemType) { // Parse all item attributes @@ -974,7 +975,7 @@ void ItemParse::parseHouseRelated(std::string_view stringValue, pugi::xml_attrib void ItemParse::createAndRegisterScript(ItemType &itemType, pugi::xml_node attributeNode, MoveEvent_t eventType /*= MOVE_EVENT_NONE*/, WeaponType_t weaponType /*= WEAPON_NONE*/) { std::shared_ptr moveevent; if (eventType != MOVE_EVENT_NONE) { - moveevent = std::make_shared(&g_moveEvents().getScriptInterface()); + moveevent = std::make_shared(); moveevent->setItemId(itemType.id); moveevent->setEventType(eventType); @@ -996,11 +997,11 @@ void ItemParse::createAndRegisterScript(ItemType &itemType, pugi::xml_node attri std::shared_ptr weapon = nullptr; if (weaponType != WEAPON_NONE) { if (weaponType == WEAPON_DISTANCE || weaponType == WEAPON_AMMO || weaponType == WEAPON_MISSILE) { - weapon = std::make_shared(&g_weapons().getScriptInterface()); + weapon = std::make_shared(); } else if (weaponType == WEAPON_WAND) { - weapon = std::make_shared(&g_weapons().getScriptInterface()); + weapon = std::make_shared(); } else { - weapon = std::make_shared(&g_weapons().getScriptInterface()); + weapon = std::make_shared(); } weapon->weaponType = weaponType; diff --git a/src/items/weapons/weapons.cpp b/src/items/weapons/weapons.cpp index 81e59f6a739..8adb10e0f1f 100644 --- a/src/items/weapons/weapons.cpp +++ b/src/items/weapons/weapons.cpp @@ -13,12 +13,20 @@ #include "creatures/combat/combat.hpp" #include "game/game.hpp" #include "lua/creature/events.hpp" +#include "creatures/players/player.hpp" +#include "creatures/players/vocations/vocation.hpp" +#include "lib/di/container.hpp" +#include "lua/scripts/scripts.hpp" #include "lua/global/lua_variant.hpp" Weapons::Weapons() = default; Weapons::~Weapons() = default; +Weapons &Weapons::getInstance() { + return inject(); +} + WeaponShared_ptr Weapons::getWeapon(const std::shared_ptr &item) const { if (!item) { return nullptr; @@ -77,6 +85,35 @@ int32_t Weapons::getMaxWeaponDamage(uint32_t level, int32_t attackSkill, int32_t } } +Weapon::Weapon() = default; + +LuaScriptInterface* Weapon::getScriptInterface() const { + return &g_scripts().getScriptInterface(); +} + +bool Weapon::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[MoveEvent::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; +} + +int32_t Weapon::getScriptId() const { + return m_scriptId; +} + +void Weapon::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool Weapon::isLoadedScriptId() const { + return m_scriptId != 0; +} + void Weapon::configureWeapon(const ItemType &it) { id = it.id; } @@ -203,7 +240,7 @@ void Weapon::internalUseWeapon(const std::shared_ptr &player, const std: } } - if (isLoadedCallback()) { + if (isLoadedScriptId()) { if (cleavePercent != 0) { return; } @@ -259,7 +296,7 @@ void Weapon::internalUseWeapon(const std::shared_ptr &player, const std: } void Weapon::internalUseWeapon(const std::shared_ptr &player, const std::shared_ptr &item, const std::shared_ptr &tile) const { - if (isLoadedCallback()) { + if (isLoadedScriptId()) { LuaVariant var; var.type = VARIANT_TARGETPOSITION; var.pos = tile->getPosition(); @@ -424,8 +461,31 @@ bool Weapon::calculateSkillFormula(const std::shared_ptr &player, int32_ return shouldCalculateSecondaryDamage; } -WeaponMelee::WeaponMelee(LuaScriptInterface* interface) : - Weapon(interface) { +void Weapon::addVocWeaponMap(const std::string &vocName) { + const int32_t vocationId = g_vocations().getVocationId(vocName); + if (vocationId != -1) { + vocWeaponMap[vocationId] = true; + } +} + +std::shared_ptr Weapon::getCombat() const { + if (!m_combat) { + g_logger().error("Weapon::getCombat() - m_combat is nullptr"); + return nullptr; + } + + return m_combat; +} + +std::shared_ptr Weapon::getCombat() { + if (!m_combat) { + m_combat = std::make_shared(); + } + + return m_combat; +} + +WeaponMelee::WeaponMelee() { // Add combat type and blocked attributes to the weapon params.blockedByArmor = true; params.blockedByShield = true; @@ -573,8 +633,7 @@ int32_t WeaponMelee::getWeaponDamage(const std::shared_ptr &player, cons return -normal_random(minValue, (maxValue * static_cast(player->getVocation()->meleeDamageMultiplier))); } -WeaponDistance::WeaponDistance(LuaScriptInterface* interface) : - Weapon(interface) { +WeaponDistance::WeaponDistance() { // Add combat type and distance effect to the weapon params.blockedByArmor = true; params.combatType = COMBAT_PHYSICALDAMAGE; @@ -874,6 +933,8 @@ bool WeaponDistance::getSkillType(const std::shared_ptr &player, const s return true; } +WeaponWand::WeaponWand() = default; + void WeaponWand::configureWeapon(const ItemType &it) { params.distanceEffect = it.shootType; const_cast(it).combatType = params.combatType; diff --git a/src/items/weapons/weapons.hpp b/src/items/weapons/weapons.hpp index bbe15e12a7d..dca7d814033 100644 --- a/src/items/weapons/weapons.hpp +++ b/src/items/weapons/weapons.hpp @@ -9,24 +9,29 @@ #pragma once -#include "lua/scripts/luascript.hpp" -#include "creatures/players/player.hpp" -#include "lua/scripts/scripts.hpp" -#include "creatures/combat/combat.hpp" #include "utils/utils_definitions.hpp" -#include "creatures/players/vocations/vocation.hpp" +#include "creatures/creatures_definitions.hpp" +#include "creatures/combat/combat.hpp" class Weapon; class WeaponMelee; class WeaponDistance; class WeaponWand; +class LuaScriptInterface; +class Combat; +class Player; +class Creature; +class Item; +class ItemType; +class Vocation; +class Tile; struct LuaVariant; using WeaponUnique_ptr = std::unique_ptr; using WeaponShared_ptr = std::shared_ptr; -class Weapons final : public Scripts { +class Weapons { public: Weapons(); ~Weapons(); @@ -35,9 +40,7 @@ class Weapons final : public Scripts { Weapons(const Weapons &) = delete; Weapons &operator=(const Weapons &) = delete; - static Weapons &getInstance() { - return inject(); - } + static Weapons &getInstance(); WeaponShared_ptr getWeapon(const std::shared_ptr &item) const; @@ -53,10 +56,9 @@ class Weapons final : public Scripts { constexpr auto g_weapons = Weapons::getInstance; -class Weapon : public Script { +class Weapon { public: - using Script::Script; - + Weapon(); virtual void configureWeapon(const ItemType &it); virtual bool interruptSwing() const { return false; @@ -162,12 +164,7 @@ class Weapon : public Script { wieldInfo |= info; } - void addVocWeaponMap(const std::string &vocName) { - const int32_t vocationId = g_vocations().getVocationId(vocName); - if (vocationId != -1) { - vocWeaponMap[vocationId] = true; - } - } + void addVocWeaponMap(const std::string &vocName); const std::string &getVocationString() const { return vocationString; @@ -204,30 +201,25 @@ class Weapon : public Script { return weaponType; } - std::shared_ptr getCombat() const { - if (!m_combat) { - g_logger().error("Weapon::getCombat() - m_combat is nullptr"); - return nullptr; - } + std::shared_ptr getCombat() const; - return m_combat; - } - - std::shared_ptr getCombat() { - if (!m_combat) { - m_combat = std::make_shared(); - } - - return m_combat; - } + std::shared_ptr getCombat(); bool calculateSkillFormula(const std::shared_ptr &player, int32_t &attackSkill, int32_t &attackValue, float &attackFactor, int16_t &elementAttack, CombatDamage &damage, bool useCharges = false) const; + LuaScriptInterface* getScriptInterface() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; + protected: void internalUseWeapon(const std::shared_ptr &player, const std::shared_ptr &item, const std::shared_ptr &target, int32_t damageModifier, int32_t cleavePercent = 0) const; void internalUseWeapon(const std::shared_ptr &player, const std::shared_ptr &item, const std::shared_ptr &tile) const; private: + int32_t m_scriptId {}; + virtual bool getSkillType(const std::shared_ptr &, const std::shared_ptr &, skills_t &, uint32_t &) const { return false; } @@ -276,11 +268,7 @@ class Weapon : public Script { class WeaponMelee final : public Weapon { public: - explicit WeaponMelee(LuaScriptInterface* interface); - - std::string getScriptTypeName() const override { - return "onUseWeapon"; - } + explicit WeaponMelee(); void configureWeapon(const ItemType &it) override; @@ -301,11 +289,7 @@ class WeaponMelee final : public Weapon { class WeaponDistance final : public Weapon { public: - explicit WeaponDistance(LuaScriptInterface* interface); - - std::string getScriptTypeName() const override { - return "onUseWeapon"; - } + explicit WeaponDistance(); void configureWeapon(const ItemType &it) override; bool interruptSwing() const override { @@ -330,11 +314,7 @@ class WeaponDistance final : public Weapon { class WeaponWand : public Weapon { public: - using Weapon::Weapon; - - std::string getScriptTypeName() const override { - return "onUseWeapon"; - } + explicit WeaponWand(); void configureWeapon(const ItemType &it) override; diff --git a/src/lua/callbacks/event_callback.cpp b/src/lua/callbacks/event_callback.cpp index 3d95543f1b9..6da22412943 100644 --- a/src/lua/callbacks/event_callback.cpp +++ b/src/lua/callbacks/event_callback.cpp @@ -14,6 +14,7 @@ #include "game/zones/zone.hpp" #include "items/containers/container.hpp" #include "items/item.hpp" +#include "lua/scripts/scripts.hpp" /** * @class EventCallback @@ -24,26 +25,52 @@ * * @see Script */ -EventCallback::EventCallback(LuaScriptInterface* scriptInterface, const std::string &callbackName, bool skipDuplicationCheck) : - Script(scriptInterface), m_callbackName(callbackName), m_skipDuplicationCheck(skipDuplicationCheck) { -} +EventCallback::EventCallback(const std::string &callbackName, bool skipDuplicationCheck) : + m_callbackName(callbackName), m_skipDuplicationCheck(skipDuplicationCheck) { } -std::string EventCallback::getName() const { - return m_callbackName; +LuaScriptInterface* EventCallback::getScriptInterface() const { + return &g_scripts().getScriptInterface(); } -bool EventCallback::skipDuplicationCheck() const { - return m_skipDuplicationCheck; +bool EventCallback::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[EventCallback::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; } std::string EventCallback::getScriptTypeName() const { return m_scriptTypeName; } -void EventCallback::setScriptTypeName(const std::string_view newName) { +void EventCallback::setScriptTypeName(std::string_view newName) { m_scriptTypeName = newName; } +int32_t EventCallback::getScriptId() const { + return m_scriptId; +} + +void EventCallback::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool EventCallback::isLoadedScriptId() const { + return m_scriptId != 0; +} + +std::string EventCallback::getName() const { + return m_callbackName; +} + +bool EventCallback::skipDuplicationCheck() const { + return m_skipDuplicationCheck; +} + EventCallback_t EventCallback::getType() const { return m_callbackType; } diff --git a/src/lua/callbacks/event_callback.hpp b/src/lua/callbacks/event_callback.hpp index fb0eb760a20..8cd52c04863 100644 --- a/src/lua/callbacks/event_callback.hpp +++ b/src/lua/callbacks/event_callback.hpp @@ -13,7 +13,6 @@ #include "creatures/creatures_definitions.hpp" #include "items/items_definitions.hpp" #include "utils/utils_definitions.hpp" -#include "lua/scripts/scripts.hpp" class Creature; class Player; @@ -22,6 +21,25 @@ class Party; class ItemType; class Monster; class Zone; +class LuaScriptInterface; +class Thing; +class Item; +class Cylinder; +class Npc; +class Container; + +struct Position; +struct CombatDamage; +struct Outfit_t; + +enum Direction : uint8_t; +enum ReturnValue : uint16_t; +enum SpeakClasses : uint8_t; +enum Slots_t : uint8_t; +enum ZoneType_t : uint8_t; +enum skills_t : int8_t; +enum CombatType_t : uint8_t; +enum TextColor_t : uint8_t; /** * @class EventCallback @@ -31,19 +49,23 @@ class Zone; * registration, and execution of custom behavior tied to specific game events. * @note It inherits from the Script class, providing scripting capabilities. */ -class EventCallback final : public Script { +class EventCallback { private: EventCallback_t m_callbackType = EventCallback_t::none; ///< The type of the event callback. std::string m_scriptTypeName; ///< The name associated with the script type. std::string m_callbackName; ///< The name of the callback. bool m_skipDuplicationCheck = false; ///< Whether the callback is silent error for already registered log error. + int32_t m_scriptId {}; + public: - /** - * @brief Constructor that initializes the EventCallback with a given script interface. - * @param scriptInterface Pointer to the LuaScriptInterface object. - */ - explicit EventCallback(LuaScriptInterface* scriptInterface, const std::string &callbackName, bool silentAlreadyRegistered); + explicit EventCallback(const std::string &callbackName, bool silentAlreadyRegistered); + + LuaScriptInterface* getScriptInterface() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; /** * @brief Retrieves the callback name. @@ -61,7 +83,7 @@ class EventCallback final : public Script { * @brief Retrieves the script type name. * @return The script type name as a string. */ - std::string getScriptTypeName() const override; + std::string getScriptTypeName() const; /** * @brief Sets a new script type name. diff --git a/src/lua/callbacks/events_callbacks.hpp b/src/lua/callbacks/events_callbacks.hpp index 8913ee1dc4b..df321bbd02d 100644 --- a/src/lua/callbacks/events_callbacks.hpp +++ b/src/lua/callbacks/events_callbacks.hpp @@ -11,7 +11,6 @@ #include "lua/callbacks/callbacks_definitions.hpp" #include "lua/callbacks/event_callback.hpp" -#include "lua/scripts/luascript.hpp" class EventCallback; @@ -81,7 +80,7 @@ class EventsCallbacks { } for (const auto &entry : it->second) { - if (entry.callback && entry.callback->isLoadedCallback()) { + if (entry.callback && entry.callback->isLoadedScriptId()) { std::invoke(callbackFunc, *entry.callback, args...); } } @@ -102,7 +101,7 @@ class EventsCallbacks { } for (const auto &entry : it->second) { - if (entry.callback && entry.callback->isLoadedCallback()) { + if (entry.callback && entry.callback->isLoadedScriptId()) { ReturnValue callbackResult = std::invoke(callbackFunc, *entry.callback, args...); if (callbackResult != RETURNVALUE_NOERROR) { return callbackResult; @@ -128,7 +127,7 @@ class EventsCallbacks { } for (const auto &entry : it->second) { - if (entry.callback && entry.callback->isLoadedCallback()) { + if (entry.callback && entry.callback->isLoadedScriptId()) { bool callbackResult = std::invoke(callbackFunc, *entry.callback, args...); allCallbacksSucceeded &= callbackResult; } diff --git a/src/lua/creature/actions.cpp b/src/lua/creature/actions.cpp index b79cb5d03c7..2ee02fac9ab 100644 --- a/src/lua/creature/actions.cpp +++ b/src/lua/creature/actions.cpp @@ -19,10 +19,16 @@ #include "items/containers/depot/depotlocker.hpp" #include "items/containers/rewards/reward.hpp" #include "items/containers/rewards/rewardchest.hpp" +#include "lua/scripts/scripts.hpp" +#include "lib/di/container.hpp" Actions::Actions() = default; Actions::~Actions() = default; +Actions &Actions::getInstance() { + return inject(); +} + void Actions::clear() { useItemMap.clear(); uniqueItemMap.clear(); @@ -273,7 +279,7 @@ ReturnValue Actions::internalUseItem(const std::shared_ptr &player, cons } if (action != nullptr) { - if (action->isLoadedCallback()) { + if (action->isLoadedScriptId()) { if (action->executeUse(player, item, pos, nullptr, pos, isHotkey)) { return RETURNVALUE_NOERROR; } @@ -495,8 +501,34 @@ void Actions::showUseHotkeyMessage(const std::shared_ptr &player, const */ // Action constructor -Action::Action(LuaScriptInterface* interface) : - Script(interface) { } +Action::Action() = default; + +LuaScriptInterface* Action::getScriptInterface() const { + return &g_scripts().getScriptInterface(); +} + +bool Action::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[MoveEvent::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; +} + +int32_t Action::getScriptId() const { + return m_scriptId; +} + +void Action::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool Action::isLoadedScriptId() const { + return m_scriptId != 0; +} ReturnValue Action::canExecuteAction(const std::shared_ptr &player, const Position &toPos) { if (!allowFarUse) { diff --git a/src/lua/creature/actions.hpp b/src/lua/creature/actions.hpp index ed5c6adc399..f0d73811354 100644 --- a/src/lua/creature/actions.hpp +++ b/src/lua/creature/actions.hpp @@ -9,16 +9,20 @@ #pragma once -#include "lua/scripts/scripts.hpp" #include "declarations.hpp" -#include "lua/scripts/luascript.hpp" class Action; +class LuaScriptInterface; +class Player; +class Item; +class Creature; +class Thing; + struct Position; -class Action : public Script { +class Action { public: - explicit Action(LuaScriptInterface* interface); + explicit Action(); // Scripting virtual bool executeUse(const std::shared_ptr &player, const std::shared_ptr &item, const Position &fromPosition, const std::shared_ptr &target, const Position &toPosition, bool isHotkey); @@ -104,10 +108,14 @@ class Action : public Script { virtual std::shared_ptr getTarget(const std::shared_ptr &player, const std::shared_ptr &targetCreature, const Position &toPosition, uint8_t toStackPos) const; + LuaScriptInterface* getScriptInterface() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; + private: - std::string getScriptTypeName() const override { - return "onUse"; - } + int32_t m_scriptId {}; std::function &player, const std::shared_ptr &item, @@ -130,7 +138,7 @@ class Action : public Script { friend class Actions; }; -class Actions final : public Scripts { +class Actions { public: Actions(); ~Actions(); @@ -139,9 +147,7 @@ class Actions final : public Scripts { Actions(const Actions &) = delete; Actions &operator=(const Actions &) = delete; - static Actions &getInstance() { - return inject(); - } + static Actions &getInstance(); bool useItem(const std::shared_ptr &player, const Position &pos, uint8_t index, const std::shared_ptr &item, bool isHotkey); bool useItemEx(const std::shared_ptr &player, const Position &fromPos, const Position &toPos, uint8_t toStackPos, const std::shared_ptr &item, bool isHotkey, const std::shared_ptr &creature = nullptr); diff --git a/src/lua/creature/creatureevent.cpp b/src/lua/creature/creatureevent.cpp index 575394b605c..db6514f219e 100644 --- a/src/lua/creature/creatureevent.cpp +++ b/src/lua/creature/creatureevent.cpp @@ -11,6 +11,8 @@ #include "creatures/players/player.hpp" #include "items/item.hpp" +#include "lua/scripts/scripts.hpp" +#include "lib/di/container.hpp" void CreatureEvents::clear() { for (const auto &[name, event] : creatureEvents) { @@ -104,8 +106,34 @@ bool CreatureEvents::playerAdvance( ======================= */ -CreatureEvent::CreatureEvent(LuaScriptInterface* interface) : - Script(interface) { } +CreatureEvent::CreatureEvent() { } + +LuaScriptInterface* CreatureEvent::getScriptInterface() const { + return &g_scripts().getScriptInterface(); +} + +bool CreatureEvent::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[MoveEvent::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; +} + +int32_t CreatureEvent::getScriptId() const { + return m_scriptId; +} + +void CreatureEvent::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool CreatureEvent::isLoadedScriptId() const { + return m_scriptId != 0; +} void CreatureEvents::removeInvalidEvents() { std::erase_if(creatureEvents, [](const auto &pair) { @@ -160,15 +188,11 @@ std::string CreatureEvent::getScriptTypeName() const { void CreatureEvent::copyEvent(const std::shared_ptr &creatureEvent) { setScriptId(creatureEvent->getScriptId()); - setScriptInterface(creatureEvent->getScriptInterface()); - setLoadedCallback(creatureEvent->isLoadedCallback()); loaded = creatureEvent->loaded; } void CreatureEvent::clearEvent() { setScriptId(0); - setScriptInterface(nullptr); - setLoadedCallback(false); loaded = false; } diff --git a/src/lua/creature/creatureevent.hpp b/src/lua/creature/creatureevent.hpp index 5000a4b2e0a..1d5c612a68c 100644 --- a/src/lua/creature/creatureevent.hpp +++ b/src/lua/creature/creatureevent.hpp @@ -9,14 +9,21 @@ #pragma once -#include "lua/scripts/scripts.hpp" +#include "lua/lua_definitions.hpp" class CreatureEvent; class LuaScriptInterface; +class Creature; +class Player; +class Item; -class CreatureEvent final : public Script { +struct CombatDamage; + +enum skills_t : int8_t; + +class CreatureEvent { public: - explicit CreatureEvent(LuaScriptInterface* interface); + explicit CreatureEvent(); CreatureEventType_t getEventType() const { return type; @@ -53,17 +60,23 @@ class CreatureEvent final : public Script { void executeHealthChange(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatDamage &damage) const; void executeManaChange(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatDamage &damage) const; void executeExtendedOpcode(const std::shared_ptr &player, uint8_t opcode, const std::string &buffer) const; - // + + std::string getScriptTypeName() const; + LuaScriptInterface* getScriptInterface() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; private: - std::string getScriptTypeName() const override; + int32_t m_scriptId {}; std::string eventName; CreatureEventType_t type = CREATURE_EVENT_NONE; bool loaded = false; }; -class CreatureEvents final : public Scripts { +class CreatureEvents { public: CreatureEvents() = default; diff --git a/src/lua/creature/movement.cpp b/src/lua/creature/movement.cpp index 684f0844ee1..fbf09f46e93 100644 --- a/src/lua/creature/movement.cpp +++ b/src/lua/creature/movement.cpp @@ -16,6 +16,12 @@ #include "lua/callbacks/event_callback.hpp" #include "lua/callbacks/events_callbacks.hpp" #include "lua/creature/events.hpp" +#include "lua/scripts/scripts.hpp" +#include "lib/di/container.hpp" + +MoveEvents &MoveEvents::getInstance() { + return inject(); +} void MoveEvents::clear() { uniqueIdMap.clear(); @@ -384,8 +390,8 @@ uint32_t MoveEvents::onItemMove(const std::shared_ptr &item, const std::sh MoveEvent class ================ */ -MoveEvent::MoveEvent(LuaScriptInterface* interface) : - Script(interface) { } + +MoveEvent::MoveEvent() = default; std::string MoveEvent::getScriptTypeName() const { switch (eventType) { @@ -411,6 +417,33 @@ std::string MoveEvent::getScriptTypeName() const { } } +LuaScriptInterface* MoveEvent::getScriptInterface() const { + return &g_scripts().getScriptInterface(); +} + +bool MoveEvent::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[MoveEvent::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; +} + +int32_t MoveEvent::getScriptId() const { + return m_scriptId; +} + +void MoveEvent::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool MoveEvent::isLoadedScriptId() const { + return m_scriptId != 0; +} + uint32_t MoveEvent::StepInField(const std::shared_ptr &creature, const std::shared_ptr &item, const Position &) { if (creature == nullptr) { g_logger().error("[MoveEvent::StepInField] - Creature is nullptr"); @@ -676,7 +709,7 @@ void MoveEvent::setEventType(MoveEvent_t type) { } uint32_t MoveEvent::fireStepEvent(const std::shared_ptr &creature, const std::shared_ptr &item, const Position &pos) const { - if (isLoadedCallback()) { + if (isLoadedScriptId()) { return executeStep(creature, item, pos); } else { return stepFunction(creature, item, pos); @@ -714,23 +747,24 @@ bool MoveEvent::executeStep(const std::shared_ptr &creature, const std return false; } + const auto scriptInterface = getScriptInterface(); ScriptEnvironment* env = LuaScriptInterface::getScriptEnv(); - env->setScriptId(getScriptId(), getScriptInterface()); + env->setScriptId(getScriptId(), scriptInterface); - lua_State* L = getScriptInterface()->getLuaState(); + lua_State* L = scriptInterface->getLuaState(); - getScriptInterface()->pushFunction(getScriptId()); + scriptInterface->pushFunction(getScriptId()); LuaScriptInterface::pushUserdata(L, creature); LuaScriptInterface::setCreatureMetatable(L, -1, creature); LuaScriptInterface::pushThing(L, item); LuaScriptInterface::pushPosition(L, pos); LuaScriptInterface::pushPosition(L, fromPosition); - return getScriptInterface()->callFunction(4); + return scriptInterface->callFunction(4); } uint32_t MoveEvent::fireEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t toSlot, bool isCheck) { - if (isLoadedCallback()) { + if (isLoadedScriptId()) { if (!equipFunction || equipFunction(static_self_cast(), player, item, toSlot, isCheck) == 1) { if (executeEquip(player, item, toSlot, isCheck)) { return 1; @@ -768,7 +802,7 @@ bool MoveEvent::executeEquip(const std::shared_ptr &player, const std::s } uint32_t MoveEvent::fireAddRemItem(const std::shared_ptr &item, const std::shared_ptr &fromTile, const Position &pos) const { - if (isLoadedCallback()) { + if (isLoadedScriptId()) { return executeAddRemItem(item, fromTile, pos); } else { return moveFunction(item, fromTile, pos); @@ -800,7 +834,7 @@ bool MoveEvent::executeAddRemItem(const std::shared_ptr &item, const std:: } uint32_t MoveEvent::fireAddRemItem(const std::shared_ptr &item, const Position &pos) const { - if (isLoadedCallback()) { + if (isLoadedScriptId()) { return executeAddRemItem(item, pos); } else { return moveFunction(item, nullptr, pos); diff --git a/src/lua/creature/movement.hpp b/src/lua/creature/movement.hpp index 58f42296f40..dbf995ed581 100644 --- a/src/lua/creature/movement.hpp +++ b/src/lua/creature/movement.hpp @@ -12,7 +12,6 @@ #include "declarations.hpp" #include "items/item.hpp" #include "lua/functions/events/move_event_functions.hpp" -#include "lua/scripts/scripts.hpp" #include "creatures/players/vocations/vocation.hpp" class MoveEvent; @@ -23,7 +22,7 @@ struct MoveEventList { using VocEquipMap = std::map; -class MoveEvents final : public Scripts { +class MoveEvents { public: MoveEvents() = default; ~MoveEvents() = default; @@ -32,9 +31,7 @@ class MoveEvents final : public Scripts { MoveEvents(const MoveEvents &) = delete; MoveEvents &operator=(const MoveEvents &) = delete; - static MoveEvents &getInstance() { - return inject(); - } + static MoveEvents &getInstance(); uint32_t onCreatureMove(const std::shared_ptr &creature, const std::shared_ptr &tile, MoveEvent_t eventType); uint32_t onPlayerEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot, bool isCheck); @@ -129,9 +126,9 @@ class MoveEvents final : public Scripts { constexpr auto g_moveEvents = MoveEvents::getInstance; -class MoveEvent final : public Script, public SharedObject { +class MoveEvent final : public SharedObject { public: - explicit MoveEvent(LuaScriptInterface* interface); + explicit MoveEvent(); MoveEvent_t getEventType() const; void setEventType(MoveEvent_t type); @@ -245,8 +242,15 @@ class MoveEvent final : public Script, public SharedObject { static uint32_t EquipItem(const std::shared_ptr &moveEvent, const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot, bool boolean); static uint32_t DeEquipItem(const std::shared_ptr &, const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot, bool boolean); + std::string getScriptTypeName() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; + LuaScriptInterface* getScriptInterface() const; + private: - std::string getScriptTypeName() const override; + int32_t m_scriptId {}; uint32_t slot = SLOTP_WHEREEVER; diff --git a/src/lua/creature/talkaction.cpp b/src/lua/creature/talkaction.cpp index 77323d9acf2..abe9303a5ba 100644 --- a/src/lua/creature/talkaction.cpp +++ b/src/lua/creature/talkaction.cpp @@ -13,10 +13,15 @@ #include "creatures/players/grouping/groups.hpp" #include "creatures/players/player.hpp" #include "lua/scripts/scripts.hpp" +#include "lib/di/container.hpp" TalkActions::TalkActions() = default; TalkActions::~TalkActions() = default; +TalkActions &TalkActions::getInstance() { + return inject(); +} + void TalkActions::clear() { talkActions.clear(); } @@ -80,6 +85,33 @@ TalkActionResult_t TalkActions::checkPlayerCanSayTalkAction(const std::shared_pt return TALKACTION_CONTINUE; } +LuaScriptInterface* TalkAction::getScriptInterface() const { + return &g_scripts().getScriptInterface(); +} + +bool TalkAction::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[MoveEvent::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; +} + +int32_t TalkAction::getScriptId() const { + return m_scriptId; +} + +void TalkAction::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool TalkAction::isLoadedScriptId() const { + return m_scriptId != 0; +} + bool TalkAction::executeSay(const std::shared_ptr &player, const std::string &words, const std::string ¶m, SpeakClasses type) const { // onSay(player, words, param, type) if (!LuaScriptInterface::reserveScriptEnv()) { @@ -101,7 +133,7 @@ bool TalkAction::executeSay(const std::shared_ptr &player, const std::st LuaScriptInterface::pushString(L, words); LuaScriptInterface::pushString(L, param); - lua_pushnumber(L, type); + LuaScriptInterface::pushNumber(L, static_cast(type)); return getScriptInterface()->callFunction(4); } diff --git a/src/lua/creature/talkaction.hpp b/src/lua/creature/talkaction.hpp index d11a5487924..4040a10f873 100644 --- a/src/lua/creature/talkaction.hpp +++ b/src/lua/creature/talkaction.hpp @@ -10,19 +10,16 @@ #pragma once #include "account/account.hpp" -#include "lua/global/baseevents.hpp" #include "utils/utils_definitions.hpp" #include "declarations.hpp" -#include "lua/scripts/luascript.hpp" -#include "lua/scripts/scripts.hpp" +class Player; +class LuaScriptInterface; class TalkAction; using TalkAction_ptr = std::shared_ptr; -class TalkAction final : public Script { +class TalkAction final { public: - using Script::Script; - const std::string &getWords() const { return m_word; } @@ -58,10 +55,14 @@ class TalkAction final : public Script { void setGroupType(uint8_t newGroupType); const uint8_t &getGroupType() const; + LuaScriptInterface* getScriptInterface() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; + private: - std::string getScriptTypeName() const override { - return "onSay"; - } + int32_t m_scriptId {}; std::string m_word; std::string m_description; @@ -69,7 +70,7 @@ class TalkAction final : public Script { uint8_t m_groupType = 0; }; -class TalkActions final : public Scripts { +class TalkActions { public: TalkActions(); ~TalkActions(); @@ -78,9 +79,7 @@ class TalkActions final : public Scripts { TalkActions(const TalkActions &) = delete; TalkActions &operator=(const TalkActions &) = delete; - static TalkActions &getInstance() { - return inject(); - } + static TalkActions &getInstance(); bool checkWord(const std::shared_ptr &player, SpeakClasses type, const std::string &words, std::string_view word, const TalkAction_ptr &talkActionPtr) const; TalkActionResult_t checkPlayerCanSayTalkAction(const std::shared_ptr &player, SpeakClasses type, const std::string &words) const; diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index 16133833bbc..a950afce950 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -14,6 +14,7 @@ #include "creatures/monsters/monsters.hpp" #include "creatures/npcs/npc.hpp" #include "creatures/players/achievement/player_achievement.hpp" +#include "creatures/players/player.hpp" #include "game/functions/game_reload.hpp" #include "game/game.hpp" #include "game/scheduling/dispatcher.hpp" diff --git a/src/lua/functions/core/game/global_functions.cpp b/src/lua/functions/core/game/global_functions.cpp index 14d87e5afb2..6a9edd807fd 100644 --- a/src/lua/functions/core/game/global_functions.cpp +++ b/src/lua/functions/core/game/global_functions.cpp @@ -10,9 +10,11 @@ #include "lua/functions/core/game/global_functions.hpp" #include "config/configmanager.hpp" +#include "creatures/creature.hpp" #include "creatures/combat/condition.hpp" #include "creatures/interactions/chat.hpp" #include "creatures/players/wheel/player_wheel.hpp" +#include "creatures/players/player.hpp" #include "game/game.hpp" #include "game/scheduling/dispatcher.hpp" #include "game/scheduling/save_manager.hpp" diff --git a/src/lua/functions/creatures/combat/combat_functions.cpp b/src/lua/functions/creatures/combat/combat_functions.cpp index 27d3a76ef04..8b659f74ab3 100644 --- a/src/lua/functions/creatures/combat/combat_functions.cpp +++ b/src/lua/functions/creatures/combat/combat_functions.cpp @@ -9,15 +9,18 @@ #include "lua/functions/creatures/combat/combat_functions.hpp" +#include "creatures/creature.hpp" #include "creatures/combat/combat.hpp" #include "creatures/combat/condition.hpp" #include "game/game.hpp" #include "lua/global/lua_variant.hpp" #include "lua/scripts/lua_environment.hpp" +#include "creatures/players/player.hpp" int CombatFunctions::luaCombatCreate(lua_State* L) { // Combat() - pushUserdata(L, g_luaEnvironment().createCombatObject(getScriptEnv()->getScriptInterface())); + std::shared_ptr combat = std::make_shared(); + pushUserdata(L, combat); setMetatable(L, -1, "Combat"); return 1; } diff --git a/src/lua/functions/creatures/combat/spell_functions.cpp b/src/lua/functions/creatures/combat/spell_functions.cpp index 1a19485afd4..707c2b813f7 100644 --- a/src/lua/functions/creatures/combat/spell_functions.cpp +++ b/src/lua/functions/creatures/combat/spell_functions.cpp @@ -67,13 +67,13 @@ int SpellFunctions::luaSpellCreate(lua_State* L) { } if (spellType == SPELL_INSTANT) { - const auto &spell = std::make_shared(getScriptEnv()->getScriptInterface()); + const auto &spell = std::make_shared(); pushUserdata(L, spell); setMetatable(L, -1, "Spell"); spell->spellType = SPELL_INSTANT; return 1; } else if (spellType == SPELL_RUNE) { - const auto &runeSpell = std::make_shared(getScriptEnv()->getScriptInterface()); + const auto &runeSpell = std::make_shared(); pushUserdata(L, runeSpell); setMetatable(L, -1, "Spell"); runeSpell->spellType = SPELL_RUNE; @@ -90,19 +90,17 @@ int SpellFunctions::luaSpellOnCastSpell(lua_State* L) { if (spell) { if (spell->spellType == SPELL_INSTANT) { const auto &instant = std::static_pointer_cast(spell); - if (!instant->loadCallback()) { + if (!instant->loadScriptId()) { pushBoolean(L, false); return 1; } - instant->setLoadedCallback(true); pushBoolean(L, true); } else if (spell->spellType == SPELL_RUNE) { const auto &rune = std::static_pointer_cast(spell); - if (!rune->loadCallback()) { + if (!rune->loadScriptId()) { pushBoolean(L, false); return 1; } - rune->setLoadedCallback(true); pushBoolean(L, true); } } else { @@ -123,7 +121,7 @@ int SpellFunctions::luaSpellRegister(lua_State* L) { if (spell->spellType == SPELL_INSTANT) { const auto &spellBase = getUserdataShared(L, 1); const auto &instant = std::static_pointer_cast(spellBase); - if (!instant->isLoadedCallback()) { + if (!instant->isLoadedScriptId()) { pushBoolean(L, false); return 1; } @@ -142,7 +140,7 @@ int SpellFunctions::luaSpellRegister(lua_State* L) { iType.runeLevel = rune->getLevel(); iType.charges = rune->getCharges(); } - if (!rune->isLoadedCallback()) { + if (!rune->isLoadedScriptId()) { pushBoolean(L, false); return 1; } diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index dba47d7ed51..07ad6b414a6 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -32,6 +32,7 @@ #include "items/containers/rewards/reward.hpp" #include "items/item.hpp" #include "map/spectators.hpp" +#include "kv/kv.hpp" #include "enums/account_coins.hpp" #include "enums/account_errors.hpp" diff --git a/src/lua/functions/events/action_functions.cpp b/src/lua/functions/events/action_functions.cpp index a21ab37ebd9..f39eae1680a 100644 --- a/src/lua/functions/events/action_functions.cpp +++ b/src/lua/functions/events/action_functions.cpp @@ -15,7 +15,7 @@ int ActionFunctions::luaCreateAction(lua_State* L) { // Action() - const auto action = std::make_shared(getScriptEnv()->getScriptInterface()); + const auto action = std::make_shared(); pushUserdata(L, action); setMetatable(L, -1, "Action"); return 1; @@ -25,11 +25,10 @@ int ActionFunctions::luaActionOnUse(lua_State* L) { // action:onUse(callback) const auto &action = getUserdataShared(L, 1); if (action) { - if (!action->loadCallback()) { + if (!action->loadScriptId()) { pushBoolean(L, false); return 1; } - action->setLoadedCallback(true); pushBoolean(L, true); } else { reportErrorFunc(getErrorDesc(LUA_ERROR_ACTION_NOT_FOUND)); @@ -42,7 +41,7 @@ int ActionFunctions::luaActionRegister(lua_State* L) { // action:register() const auto &action = getUserdataShared(L, 1); if (action) { - if (!action->isLoadedCallback()) { + if (!action->isLoadedScriptId()) { pushBoolean(L, false); return 1; } diff --git a/src/lua/functions/events/creature_event_functions.cpp b/src/lua/functions/events/creature_event_functions.cpp index ea4c05758d5..d87371b663d 100644 --- a/src/lua/functions/events/creature_event_functions.cpp +++ b/src/lua/functions/events/creature_event_functions.cpp @@ -14,7 +14,7 @@ int CreatureEventFunctions::luaCreateCreatureEvent(lua_State* L) { // CreatureEvent(eventName) - const auto creatureEvent = std::make_shared(getScriptEnv()->getScriptInterface()); + const auto creatureEvent = std::make_shared(); creatureEvent->setName(getString(L, 2)); pushUserdata(L, creatureEvent); setMetatable(L, -1, "CreatureEvent"); @@ -69,7 +69,7 @@ int CreatureEventFunctions::luaCreatureEventRegister(lua_State* L) { // creatureevent:register() const auto &creatureEvent = getUserdataShared(L, 1); if (creatureEvent) { - if (!creatureEvent->isLoadedCallback()) { + if (!creatureEvent->isLoadedScriptId()) { pushBoolean(L, false); return 1; } @@ -84,7 +84,7 @@ int CreatureEventFunctions::luaCreatureEventOnCallback(lua_State* L) { // creatureevent:onLogin / logout / etc. (callback) const auto &creatureEvent = getUserdataShared(L, 1); if (creatureEvent) { - if (!creatureEvent->loadCallback()) { + if (!creatureEvent->loadScriptId()) { pushBoolean(L, false); return 1; } diff --git a/src/lua/functions/events/event_callback_functions.cpp b/src/lua/functions/events/event_callback_functions.cpp index db59092f3af..3d4450d934d 100644 --- a/src/lua/functions/events/event_callback_functions.cpp +++ b/src/lua/functions/events/event_callback_functions.cpp @@ -39,7 +39,7 @@ int EventCallbackFunctions::luaEventCallbackCreate(lua_State* luaState) { } bool skipDuplicationCheck = getBoolean(luaState, 3, false); - const auto eventCallback = std::make_shared(getScriptEnv()->getScriptInterface(), callbackName, skipDuplicationCheck); + const auto eventCallback = std::make_shared(callbackName, skipDuplicationCheck); pushUserdata(luaState, eventCallback); setMetatable(luaState, -1, "EventCallback"); return 1; @@ -82,7 +82,7 @@ int EventCallbackFunctions::luaEventCallbackRegister(lua_State* luaState) { return 0; } - if (!callback->isLoadedCallback()) { + if (!callback->isLoadedScriptId()) { return 0; } @@ -103,12 +103,11 @@ int EventCallbackFunctions::luaEventCallbackLoad(lua_State* luaState) { return 1; } - if (!callback->loadCallback()) { + if (!callback->loadScriptId()) { reportErrorFunc("Cannot load callback"); return 1; } - callback->setLoadedCallback(true); pushBoolean(luaState, true); return 1; } diff --git a/src/lua/functions/events/global_event_functions.cpp b/src/lua/functions/events/global_event_functions.cpp index 32c9eccf2e5..c4e1b85a96a 100644 --- a/src/lua/functions/events/global_event_functions.cpp +++ b/src/lua/functions/events/global_event_functions.cpp @@ -14,7 +14,7 @@ #include "utils/tools.hpp" int GlobalEventFunctions::luaCreateGlobalEvent(lua_State* L) { - const auto global = std::make_shared(getScriptEnv()->getScriptInterface()); + const auto global = std::make_shared(); global->setName(getString(L, 2)); global->setEventType(GLOBALEVENT_NONE); pushUserdata(L, global); @@ -56,7 +56,7 @@ int GlobalEventFunctions::luaGlobalEventRegister(lua_State* L) { // globalevent:register() const auto &globalevent = getUserdataShared(L, 1); if (globalevent) { - if (!globalevent->isLoadedCallback()) { + if (!globalevent->isLoadedScriptId()) { pushBoolean(L, false); return 1; } @@ -76,7 +76,7 @@ int GlobalEventFunctions::luaGlobalEventOnCallback(lua_State* L) { // globalevent:onThink / record / etc. (callback) const auto &globalevent = getUserdataShared(L, 1); if (globalevent) { - if (!globalevent->loadCallback()) { + if (!globalevent->loadScriptId()) { pushBoolean(L, false); return 1; } diff --git a/src/lua/functions/events/move_event_functions.cpp b/src/lua/functions/events/move_event_functions.cpp index ac7727fb2a9..1a059562940 100644 --- a/src/lua/functions/events/move_event_functions.cpp +++ b/src/lua/functions/events/move_event_functions.cpp @@ -15,7 +15,7 @@ int MoveEventFunctions::luaCreateMoveEvent(lua_State* L) { // MoveEvent() - const auto moveevent = std::make_shared(getScriptEnv()->getScriptInterface()); + const auto moveevent = std::make_shared(); pushUserdata(L, moveevent); setMetatable(L, -1, "MoveEvent"); return 1; @@ -64,7 +64,7 @@ int MoveEventFunctions::luaMoveEventRegister(lua_State* L) { if (moveevent) { // If not scripted, register item event // Example: unscripted_equipments.lua - if (!moveevent->isLoadedCallback()) { + if (!moveevent->isLoadedScriptId()) { pushBoolean(L, g_moveEvents().registerLuaItemEvent(moveevent)); return 1; } @@ -80,7 +80,7 @@ int MoveEventFunctions::luaMoveEventOnCallback(lua_State* L) { // moveevent:onEquip / deEquip / etc. (callback) const auto &moveevent = getUserdataShared(L, 1); if (moveevent) { - if (!moveevent->loadCallback()) { + if (!moveevent->loadScriptId()) { pushBoolean(L, false); return 1; } diff --git a/src/lua/functions/events/talk_action_functions.cpp b/src/lua/functions/events/talk_action_functions.cpp index 1b87fec4b7d..3241a4c8937 100644 --- a/src/lua/functions/events/talk_action_functions.cpp +++ b/src/lua/functions/events/talk_action_functions.cpp @@ -22,7 +22,7 @@ int TalkActionFunctions::luaCreateTalkAction(lua_State* L) { wordsVector.push_back(getString(L, i)); } - const auto talkactionSharedPtr = std::make_shared(getScriptEnv()->getScriptInterface()); + const auto talkactionSharedPtr = std::make_shared(); talkactionSharedPtr->setWords(wordsVector); pushUserdata(L, talkactionSharedPtr); setMetatable(L, -1, "TalkAction"); @@ -38,7 +38,7 @@ int TalkActionFunctions::luaTalkActionOnSay(lua_State* L) { return 1; } - if (!talkactionSharedPtr->loadCallback()) { + if (!talkactionSharedPtr->loadScriptId()) { pushBoolean(L, false); return 1; } @@ -100,7 +100,7 @@ int TalkActionFunctions::luaTalkActionRegister(lua_State* L) { return 1; } - if (!talkactionSharedPtr->isLoadedCallback()) { + if (!talkactionSharedPtr->isLoadedScriptId()) { pushBoolean(L, false); return 1; } diff --git a/src/lua/functions/items/weapon_functions.cpp b/src/lua/functions/items/weapon_functions.cpp index 4a02b1c4b29..51c48ffbac1 100644 --- a/src/lua/functions/items/weapon_functions.cpp +++ b/src/lua/functions/items/weapon_functions.cpp @@ -21,35 +21,26 @@ int WeaponFunctions::luaCreateWeapon(lua_State* L) { case WEAPON_SWORD: case WEAPON_AXE: case WEAPON_CLUB: { - if (const auto &weaponPtr = g_luaEnvironment().createWeaponObject(getScriptEnv()->getScriptInterface())) { - pushUserdata(L, weaponPtr); - setMetatable(L, -1, "Weapon"); - weaponPtr->weaponType = type; - } else { - lua_pushnil(L); - } + auto weaponPtr = std::make_shared(); + pushUserdata(L, weaponPtr); + setMetatable(L, -1, "Weapon"); + weaponPtr->weaponType = type; break; } case WEAPON_MISSILE: case WEAPON_DISTANCE: case WEAPON_AMMO: { - if (const auto &weaponPtr = g_luaEnvironment().createWeaponObject(getScriptEnv()->getScriptInterface())) { - pushUserdata(L, weaponPtr); - setMetatable(L, -1, "Weapon"); - weaponPtr->weaponType = type; - } else { - lua_pushnil(L); - } + auto weaponPtr = std::make_shared(); + pushUserdata(L, weaponPtr); + setMetatable(L, -1, "Weapon"); + weaponPtr->weaponType = type; break; } case WEAPON_WAND: { - if (const auto &weaponPtr = g_luaEnvironment().createWeaponObject(getScriptEnv()->getScriptInterface())) { - pushUserdata(L, weaponPtr); - setMetatable(L, -1, "Weapon"); - weaponPtr->weaponType = type; - } else { - lua_pushnil(L); - } + auto weaponPtr = std::make_shared(); + pushUserdata(L, weaponPtr); + setMetatable(L, -1, "Weapon"); + weaponPtr->weaponType = type; break; } default: { @@ -122,7 +113,7 @@ int WeaponFunctions::luaWeaponOnUseWeapon(lua_State* L) { // weapon:onUseWeapon(callback) const WeaponShared_ptr &weapon = getUserdataShared(L, 1); if (weapon) { - if (!weapon->loadCallback()) { + if (!weapon->loadScriptId()) { pushBoolean(L, false); return 1; } diff --git a/src/lua/functions/lua_functions_loader.cpp b/src/lua/functions/lua_functions_loader.cpp index 894cf252c80..cb8d0d19d29 100644 --- a/src/lua/functions/lua_functions_loader.cpp +++ b/src/lua/functions/lua_functions_loader.cpp @@ -239,6 +239,14 @@ void LuaFunctionsLoader::pushString(lua_State* L, const std::string &value) { lua_pushlstring(L, value.c_str(), value.length()); } +void LuaFunctionsLoader::pushNumber(lua_State* L, lua_Number value) { + if (validateDispatcherContext(__FUNCTION__)) { + return; + } + + lua_pushnumber(L, value); +} + void LuaFunctionsLoader::pushCallback(lua_State* L, int32_t callback) { if (validateDispatcherContext(__FUNCTION__)) { return; diff --git a/src/lua/functions/lua_functions_loader.hpp b/src/lua/functions/lua_functions_loader.hpp index 9c5b65c14bb..50c5cade63a 100644 --- a/src/lua/functions/lua_functions_loader.hpp +++ b/src/lua/functions/lua_functions_loader.hpp @@ -26,6 +26,8 @@ class Guild; class Zone; class KV; +typedef double lua_Number; + struct LuaVariant; #define reportErrorFunc(a) reportError(__FUNCTION__, a, true) @@ -42,6 +44,7 @@ class LuaFunctionsLoader { static void pushThing(lua_State* L, const std::shared_ptr &thing); static void pushVariant(lua_State* L, const LuaVariant &var); static void pushString(lua_State* L, const std::string &value); + static void pushNumber(lua_State* L, lua_Number value); static void pushCallback(lua_State* L, int32_t callback); static void pushCylinder(lua_State* L, const std::shared_ptr &cylinder); diff --git a/src/lua/global/globalevent.cpp b/src/lua/global/globalevent.cpp index f7de024bda1..ae988a814de 100644 --- a/src/lua/global/globalevent.cpp +++ b/src/lua/global/globalevent.cpp @@ -12,10 +12,16 @@ #include "utils/tools.hpp" #include "game/game.hpp" #include "game/scheduling/dispatcher.hpp" +#include "lua/scripts/scripts.hpp" +#include "lib/di/container.hpp" GlobalEvents::GlobalEvents() = default; GlobalEvents::~GlobalEvents() = default; +GlobalEvents &GlobalEvents::getInstance() { + return inject(); +} + void GlobalEvents::clear() { // Stop events g_dispatcher().stopEvent(thinkEventId); @@ -184,8 +190,34 @@ GlobalEventMap GlobalEvents::getEventMap(GlobalEvent_t type) { } } -GlobalEvent::GlobalEvent(LuaScriptInterface* interface) : - Script(interface) { } +GlobalEvent::GlobalEvent() = default; + +LuaScriptInterface* GlobalEvent::getScriptInterface() const { + return &g_scripts().getScriptInterface(); +} + +bool GlobalEvent::loadScriptId() { + LuaScriptInterface &luaInterface = g_scripts().getScriptInterface(); + m_scriptId = luaInterface.getEvent(); + if (m_scriptId == -1) { + g_logger().error("[MoveEvent::loadScriptId] Failed to load event. Script name: '{}', Module: '{}'", luaInterface.getLoadingScriptName(), luaInterface.getInterfaceName()); + return false; + } + + return true; +} + +int32_t GlobalEvent::getScriptId() const { + return m_scriptId; +} + +void GlobalEvent::setScriptId(int32_t newScriptId) { + m_scriptId = newScriptId; +} + +bool GlobalEvent::isLoadedScriptId() const { + return m_scriptId != 0; +} std::string GlobalEvent::getScriptTypeName() const { switch (eventType) { diff --git a/src/lua/global/globalevent.hpp b/src/lua/global/globalevent.hpp index cc08bb9c771..763f1765be3 100644 --- a/src/lua/global/globalevent.hpp +++ b/src/lua/global/globalevent.hpp @@ -10,12 +10,17 @@ #pragma once #include "utils/utils_definitions.hpp" -#include "lua/scripts/scripts.hpp" +#include "lua/lua_definitions.hpp" +class LuaScriptInterface; class GlobalEvent; using GlobalEventMap = std::map>; -class GlobalEvents final : public Scripts { +enum LightState_t : uint8_t; + +struct LightInfo; + +class GlobalEvents { public: GlobalEvents(); ~GlobalEvents(); @@ -24,9 +29,7 @@ class GlobalEvents final : public Scripts { GlobalEvents(const GlobalEvents &) = delete; GlobalEvents &operator=(const GlobalEvents &) = delete; - static GlobalEvents &getInstance() { - return inject(); - } + static GlobalEvents &getInstance(); void startup() const; void shutdown() const; @@ -48,9 +51,9 @@ class GlobalEvents final : public Scripts { constexpr auto g_globalEvents = GlobalEvents::getInstance; -class GlobalEvent final : public Script { +class GlobalEvent { public: - explicit GlobalEvent(LuaScriptInterface* interface); + explicit GlobalEvent(); bool executePeriodChange(LightState_t lightState, LightInfo lightInfo) const; bool executeRecord(uint32_t current, uint32_t old) const; @@ -83,10 +86,17 @@ class GlobalEvent final : public Script { nextExecution = time; } + std::string getScriptTypeName() const; + LuaScriptInterface* getScriptInterface() const; + bool loadScriptId(); + int32_t getScriptId() const; + void setScriptId(int32_t newScriptId); + bool isLoadedScriptId() const; + private: - GlobalEvent_t eventType = GLOBALEVENT_NONE; + int32_t m_scriptId {}; - std::string getScriptTypeName() const override; + GlobalEvent_t eventType = GLOBALEVENT_NONE; std::string name; int64_t nextExecution = 0; diff --git a/src/lua/lua_definitions.hpp b/src/lua/lua_definitions.hpp index ace5ee32164..fa1bdcec01a 100644 --- a/src/lua/lua_definitions.hpp +++ b/src/lua/lua_definitions.hpp @@ -99,7 +99,7 @@ enum TalkActionResult_t { TALKACTION_FAILED, }; -enum GlobalEvent_t { +enum GlobalEvent_t : uint8_t { GLOBALEVENT_NONE, GLOBALEVENT_TIMER, diff --git a/src/lua/scripts/lua_environment.cpp b/src/lua/scripts/lua_environment.cpp index b4cc620b1ce..4473a21ec90 100644 --- a/src/lua/scripts/lua_environment.cpp +++ b/src/lua/scripts/lua_environment.cpp @@ -13,9 +13,14 @@ #include "lua/functions/lua_functions_loader.hpp" #include "lua/scripts/script_environment.hpp" #include "lua/global/lua_timer_event_descr.hpp" +#include "lib/di/container.hpp" bool LuaEnvironment::shuttingDown = false; +LuaEnvironment &LuaEnvironment::getInstance() { + return inject(); +} + static const std::unique_ptr &AreaCombatNull {}; LuaEnvironment::LuaEnvironment() : @@ -60,10 +65,6 @@ bool LuaEnvironment::closeState() { return false; } - for (const auto &combatEntry : combatIdMap) { - clearCombatObjects(combatEntry.first); - } - for (const auto &areaEntry : areaIdMap) { clearAreaObjects(areaEntry.first); } @@ -76,7 +77,6 @@ bool LuaEnvironment::closeState() { luaL_unref(luaState, LUA_REGISTRYINDEX, timerEventDesc.function); } - combatIdMap.clear(); areaIdMap.clear(); timerEvents.clear(); cacheFiles.clear(); @@ -94,31 +94,6 @@ LuaScriptInterface* LuaEnvironment::getTestInterface() { return testInterface; } -std::shared_ptr LuaEnvironment::getCombatObject(uint32_t id) const { - const auto it = combatMap.find(id); - if (it == combatMap.end()) { - return nullptr; - } - return it->second; -} - -std::shared_ptr LuaEnvironment::createCombatObject(LuaScriptInterface* interface) { - auto combat = std::make_shared(); - combatMap[++lastCombatId] = combat; - combatIdMap[interface].push_back(lastCombatId); - return combat; -} - -void LuaEnvironment::clearCombatObjects(LuaScriptInterface* interface) { - const auto it = combatIdMap.find(interface); - if (it == combatIdMap.end()) { - return; - } - - it->second.clear(); - combatMap.clear(); -} - const std::unique_ptr &LuaEnvironment::getAreaObject(uint32_t id) const { const auto it = areaMap.find(id); if (it == areaMap.end()) { diff --git a/src/lua/scripts/lua_environment.hpp b/src/lua/scripts/lua_environment.hpp index e7751bb4969..63efd2d7033 100644 --- a/src/lua/scripts/lua_environment.hpp +++ b/src/lua/scripts/lua_environment.hpp @@ -35,9 +35,7 @@ class LuaEnvironment final : public LuaScriptInterface { LuaEnvironment(const LuaEnvironment &) = delete; LuaEnvironment &operator=(const LuaEnvironment &) = delete; - static LuaEnvironment &getInstance() { - return inject(); - } + static LuaEnvironment &getInstance(); bool initState() override; bool reInitState() override; @@ -45,38 +43,6 @@ class LuaEnvironment final : public LuaScriptInterface { LuaScriptInterface* getTestInterface(); - std::shared_ptr getCombatObject(uint32_t id) const; - std::shared_ptr createCombatObject(LuaScriptInterface* interface); - void clearCombatObjects(LuaScriptInterface* interface); - - template - std::shared_ptr createWeaponObject(LuaScriptInterface* interface) { - auto weapon = std::make_shared(interface); - const auto weaponId = ++lastWeaponId; - weaponMap[weaponId] = weapon; - weaponIdMap[interface].push_back(weaponId); - return weapon; - } - - template - std::shared_ptr getWeaponObject(uint32_t id) const { - const auto it = weaponMap.find(id); - if (it == weaponMap.end()) { - return nullptr; - } - return it->second; - } - - void clearWeaponObjects(LuaScriptInterface* interface) { - const auto it = weaponIdMap.find(interface); - if (it == weaponIdMap.end()) { - return; - } - - it->second.clear(); - weaponMap.clear(); - } - const std::unique_ptr &getAreaObject(uint32_t id) const; uint32_t createAreaObject(LuaScriptInterface* interface); void clearAreaObjects(LuaScriptInterface* interface); @@ -96,14 +62,6 @@ class LuaEnvironment final : public LuaScriptInterface { phmap::flat_hash_map> areaIdMap; uint32_t lastAreaId = 0; - phmap::flat_hash_map> combatMap; - phmap::flat_hash_map> combatIdMap; - uint32_t lastCombatId = 0; - - std::unordered_map> weaponMap; - std::unordered_map> weaponIdMap; - uint32_t lastWeaponId = 0; - LuaScriptInterface* testInterface = nullptr; friend class LuaScriptInterface; diff --git a/src/lua/scripts/luascript.cpp b/src/lua/scripts/luascript.cpp index aa1b6011886..1a26095bdc4 100644 --- a/src/lua/scripts/luascript.cpp +++ b/src/lua/scripts/luascript.cpp @@ -28,7 +28,6 @@ LuaScriptInterface::~LuaScriptInterface() { } bool LuaScriptInterface::reInitState() { - g_luaEnvironment().clearCombatObjects(this); g_luaEnvironment().clearAreaObjects(this); closeState(); diff --git a/src/lua/scripts/scripts.cpp b/src/lua/scripts/scripts.cpp index 556ed1be50b..f4a141253c4 100644 --- a/src/lua/scripts/scripts.cpp +++ b/src/lua/scripts/scripts.cpp @@ -9,6 +9,7 @@ #include "lua/scripts/scripts.hpp" +#include "lib/di/container.hpp" #include "config/configmanager.hpp" #include "creatures/combat/spells.hpp" #include "creatures/monsters/monsters.hpp" @@ -24,6 +25,11 @@ Scripts::Scripts() : scriptInterface.initState(); } +Scripts &Scripts::getInstance() { + static Scripts instance; + return instance; +} + void Scripts::clearAllScripts() const { g_actions().clear(); g_creatureEvents().clear(); @@ -61,16 +67,18 @@ bool Scripts::loadEventSchedulerScripts(const std::string &fileName) { return false; } -bool Scripts::loadScripts(std::string loadPath, bool isLib, bool reload) { - const auto dir = std::filesystem::current_path() / loadPath; +bool Scripts::loadScripts(std::string_view folderName, bool isLib, bool reload) { + const auto dir = std::filesystem::current_path() / folderName; + // Checks if the folder exists and is really a folder if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) { - g_logger().error("Can not load folder {}", loadPath); + g_logger().error("Can not load folder {}", folderName); return false; } // Declare a string variable to store the last directory std::string lastDirectory; + // Recursive iterate through all entries in the directory for (const auto &entry : std::filesystem::recursive_directory_iterator(dir)) { // Get the filename of the entry as a string @@ -78,11 +86,14 @@ bool Scripts::loadScripts(std::string loadPath, bool isLib, bool reload) { std::string fileFolder = realPath.parent_path().filename().string(); // Script folder, example: "actions" std::string scriptFolder = realPath.parent_path().string(); + // Create a string_view for the fileFolder and scriptFolder strings const std::string_view fileFolderView(fileFolder); const std::string_view scriptFolderView(scriptFolder); + // Filename, example: "demon.lua" std::string file(realPath.filename().string()); + if (!std::filesystem::is_regular_file(entry) || realPath.extension() != ".lua") { // Skip this entry if it is not a regular file or does not have a .lua extension continue; diff --git a/src/lua/scripts/scripts.hpp b/src/lua/scripts/scripts.hpp index 10ed18ed4f4..2efedb04232 100644 --- a/src/lua/scripts/scripts.hpp +++ b/src/lua/scripts/scripts.hpp @@ -9,118 +9,27 @@ #pragma once -#include "lib/di/container.hpp" #include "lua/scripts/luascript.hpp" class Scripts { public: - Scripts(); - // non-copyable Scripts(const Scripts &) = delete; Scripts &operator=(const Scripts &) = delete; - static Scripts &getInstance() { - return inject(); - } + static Scripts &getInstance(); void clearAllScripts() const; bool loadEventSchedulerScripts(const std::string &fileName); - bool loadScripts(std::string folderName, bool isLib, bool reload); + bool loadScripts(std::string_view folderName, bool isLib, bool reload); LuaScriptInterface &getScriptInterface() { return scriptInterface; } - /** - * @brief Get the Script Id object - * - * @return int32_t - */ - int32_t getScriptId() const { - return scriptId; - } private: - int32_t scriptId = 0; LuaScriptInterface scriptInterface; + Scripts(); }; constexpr auto g_scripts = Scripts::getInstance; - -class Script { -public: - /** - * @brief Explicit construtor - * explicit, that is, it cannot be used for implicit conversions and - * copy-initialization. - * - * @param interface Lua Script Interface - */ - explicit Script(LuaScriptInterface* interface) : - scriptInterface(interface) { } - virtual ~Script() = default; - - /** - * @brief Check if script is loaded - * - * @return true - * @return false - */ - bool isLoadedCallback() const { - return loadedCallback; - } - void setLoadedCallback(bool loaded) { - loadedCallback = loaded; - } - - // Load revscriptsys callback - bool loadCallback() { - if (!scriptInterface) { - g_logger().error("[Script::loadCallback] scriptInterface is nullptr, scriptid = {}", scriptId); - return false; - } - - if (scriptId != 0) { - g_logger().error("[Script::loadCallback] scriptid is not zero, scriptid = {}, scriptName {}", scriptId, scriptInterface->getLoadingScriptName()); - return false; - } - - const int32_t id = scriptInterface->getEvent(); - if (id == -1) { - g_logger().error("[Script::loadCallback] Event {} not found for script with name {}", getScriptTypeName(), scriptInterface->getLoadingScriptName()); - return false; - } - - setLoadedCallback(true); - scriptId = id; - return true; - } - - // NOTE: Pure virtual method ( = 0) that must be implemented in derived classes - // Script type (Action, CreatureEvent, GlobalEvent, MoveEvent, Spell, Weapon) - virtual std::string getScriptTypeName() const = 0; - - // Method to access the scriptInterface in derived classes - virtual LuaScriptInterface* getScriptInterface() const { - return scriptInterface; - } - - virtual void setScriptInterface(LuaScriptInterface* newInterface) { - scriptInterface = newInterface; - } - - // Method to access the scriptId in derived classes - virtual int32_t getScriptId() const { - return scriptId; - } - virtual void setScriptId(int32_t newScriptId) { - scriptId = newScriptId; - } - -private: - // If script is loaded callback - bool loadedCallback = false; - - int32_t scriptId = 0; - LuaScriptInterface* scriptInterface = nullptr; -}; diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index c59f0d89c25..5f6bea22164 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -47,6 +47,7 @@ #include "lua/modules/modules.hpp" #include "server/network/message/outputmessage.hpp" #include "utils/tools.hpp" +#include "creatures/players/vocations/vocation.hpp" #include "enums/account_coins.hpp" #include "enums/account_group_type.hpp" diff --git a/src/server/signals.cpp b/src/server/signals.cpp index 29382c55809..1e6e0e4ece7 100644 --- a/src/server/signals.cpp +++ b/src/server/signals.cpp @@ -19,6 +19,7 @@ #include "lua/creature/events.hpp" #include "lua/global/globalevent.hpp" #include "lua/scripts/lua_environment.hpp" +#include "lib/di/container.hpp" Signals::Signals(asio::io_service &service) : set(service) {