diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index d4a05414420..f2ac309c059 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -28,9 +28,6 @@ #include "creatures/monsters/monsters.h" #include "items/weapons/weapons.h" -extern Weapons* g_weapons; -extern Events* g_events; -extern Monsters g_monsters; CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const { @@ -57,7 +54,7 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const ); } else if (formulaType == COMBAT_FORMULA_SKILL) { Item* tool = player->getWeapon(); - const Weapon* weapon = g_weapons->getWeapon(tool); + const Weapon* weapon = g_weapons().getWeapon(tool); if (weapon) { damage.primary.value = normal_random( static_cast(minb), @@ -265,7 +262,7 @@ ReturnValue Combat::canDoCombat(Creature* caster, Tile* tile, bool aggressive) return RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE; } - return g_events->eventCreatureOnAreaCombat(caster, tile, aggressive); + return g_events().eventCreatureOnAreaCombat(caster, tile, aggressive); } bool Combat::isInPvpZone(const Creature* attacker, const Creature* target) @@ -381,7 +378,7 @@ ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target) } } } - return g_events->eventCreatureOnTargetCombat(attacker, target); + return g_events().eventCreatureOnTargetCombat(attacker, target); } void Combat::setPlayerCombatValues(formulaType_t newFormulaType, double newMina, double newMinb, double newMaxa, double newMaxb) @@ -501,7 +498,7 @@ void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatPa if (caster && caster->getPlayer()) { Item *item = caster->getPlayer()->getWeapon(); damage = applyImbuementElementalDamage(item, damage); - g_events->eventPlayerOnCombat(caster->getPlayer(), target, item, damage); + g_events().eventPlayerOnCombat(caster->getPlayer(), target, item, damage); if (target && target->getSkull() != SKULL_BLACK && target->getPlayer()) { damage.primary.value /= 2; @@ -578,7 +575,7 @@ void Combat::CombatConditionFunc(Creature* caster, Creature* target, const Comba } else if (caster && caster->getMonster()) { uint16_t playerCharmRaceid = player->parseRacebyCharm(CHARM_CLEANSE, false, 0); if (playerCharmRaceid != 0) { - MonsterType* mType = g_monsters.getMonsterType(caster->getName()); + const MonsterType* mType = g_monsters().getMonsterType(caster->getName()); if (mType && playerCharmRaceid == mType->info.raceid) { IOBestiary g_bestiary; Charm* charm = g_bestiary.getBestiaryCharm(CHARM_CLEANSE); @@ -903,7 +900,7 @@ void Combat::doCombatHealth(Creature* caster, Creature* target, CombatDamage& da if (target && target->getMonster() && damage.primary.type != COMBAT_HEALING) { uint16_t playerCharmRaceid = caster->getPlayer()->parseRacebyCharm(CHARM_LOW, false, 0); if (playerCharmRaceid != 0) { - MonsterType* mType = g_monsters.getMonsterType(target->getName()); + const MonsterType* mType = g_monsters().getMonsterType(target->getName()); if (mType && playerCharmRaceid == mType->info.raceid) { IOBestiary g_bestiary; Charm* charm = g_bestiary.getBestiaryCharm(CHARM_LOW); @@ -1106,7 +1103,7 @@ void ValueCallback::getMinMaxValues(Player* player, CombatDamage& damage, bool u case COMBAT_FORMULA_SKILL: { //onGetPlayerMinMaxValues(player, attackSkill, attackValue, attackFactor) Item* tool = player->getWeapon(); - const Weapon* weapon = g_weapons->getWeapon(tool); + const Weapon* weapon = g_weapons().getWeapon(tool); Item* item = nullptr; if (weapon) { diff --git a/src/creatures/combat/condition.cpp b/src/creatures/combat/condition.cpp index 67308329c9b..7daff812b55 100644 --- a/src/creatures/combat/condition.cpp +++ b/src/creatures/combat/condition.cpp @@ -22,7 +22,6 @@ #include "creatures/combat/condition.h" #include "game/game.h" -extern Monsters g_monsters; bool Condition::setParam(ConditionParam_t param, int32_t value) { @@ -1655,7 +1654,7 @@ void ConditionOutfit::serialize(PropWriteStream& propWriteStream) bool ConditionOutfit::startCondition(Creature* creature) { if ((outfit.lookType == 0 && outfit.lookTypeEx == 0) && !monsterName.empty()) { - MonsterType* monsterType = g_monsters.getMonsterType(monsterName); + const MonsterType* monsterType = g_monsters().getMonsterType(monsterName); if (monsterType) { setOutfit(monsterType->info.outfit); } else { @@ -1689,7 +1688,7 @@ void ConditionOutfit::addCondition(Creature* creature, const Condition* addCondi const ConditionOutfit& conditionOutfit = static_cast(*addCondition); if (!conditionOutfit.monsterName.empty() && conditionOutfit.monsterName.compare(monsterName) != 0) { - MonsterType* monsterType = g_monsters.getMonsterType(conditionOutfit.monsterName); + const MonsterType* monsterType = g_monsters().getMonsterType(conditionOutfit.monsterName); if (monsterType) { setOutfit(monsterType->info.outfit); } else { diff --git a/src/creatures/combat/spells.cpp b/src/creatures/combat/spells.cpp index ecdff128d6e..b76f6289e9e 100644 --- a/src/creatures/combat/spells.cpp +++ b/src/creatures/combat/spells.cpp @@ -25,12 +25,6 @@ #include "game/game.h" #include "lua/scripts/lua_environment.hpp" #include "utils/pugicast.h" - -extern Spells* g_spells; -extern Monsters g_monsters; -extern Vocations g_vocations; -extern LuaEnvironment g_luaEnvironment; - Spells::Spells() { scriptInterface.initState(); @@ -333,7 +327,7 @@ Position Spells::getCasterPosition(Creature* creature, Direction dir) } CombatSpell::CombatSpell(Combat* initCombat, bool initNeedTarget, bool initNeedDirection) : - Event(&g_spells->getScriptInterface()), + Event(&g_spells().getScriptInterface()), combat(initCombat), needDirection(initNeedDirection), needTarget(initNeedTarget) @@ -611,7 +605,7 @@ bool Spell::configureSpell(const pugi::xml_node& node) continue; } - int32_t vocationId = g_vocations.getVocationId(attr.as_string()); + int32_t vocationId = g_vocations().getVocationId(attr.as_string()); if (vocationId != -1) { attr = vocationNode.attribute("showInDescription"); vocSpellMap[vocationId] = !attr || attr.as_bool(); diff --git a/src/creatures/combat/spells.h b/src/creatures/combat/spells.h index dc981befe22..7b7798afae0 100644 --- a/src/creatures/combat/spells.h +++ b/src/creatures/combat/spells.h @@ -44,6 +44,13 @@ class Spells final : public BaseEvents Spells(const Spells&) = delete; Spells& operator=(const Spells&) = delete; + static Spells& getInstance() { + // Guaranteed to be destroyed + static Spells instance; + // Instantiated on first use + return instance; + } + Spell* getSpellByName(const std::string& name); RuneSpell* getRuneSpell(uint32_t id); RuneSpell* getRuneSpellByName(const std::string& name); @@ -88,6 +95,8 @@ class Spells final : public BaseEvents LuaScriptInterface scriptInterface { "Spell Interface" }; }; +constexpr auto g_spells = &Spells::getInstance; + using RuneSpellFunction = std::function; class BaseSpell diff --git a/src/creatures/creature.cpp b/src/creatures/creature.cpp index 52185e5bf37..4dc3b9111e5 100644 --- a/src/creatures/creature.cpp +++ b/src/creatures/creature.cpp @@ -29,7 +29,6 @@ double Creature::speedA = 857.36; double Creature::speedB = 261.29; double Creature::speedC = -4795.01; -extern CreatureEvents* g_creatureEvents; Creature::Creature() { @@ -282,13 +281,13 @@ void Creature::addEventWalk(bool firstStep) g_game().checkCreatureWalk(getID()); } - eventWalk = g_scheduler.addEvent(createSchedulerTask(static_cast(ticks), std::bind(&Game::checkCreatureWalk, &g_game(), getID()))); + eventWalk = g_scheduler().addEvent(createSchedulerTask(static_cast(ticks), std::bind(&Game::checkCreatureWalk, &g_game(), getID()))); } void Creature::stopEventWalk() { if (eventWalk != 0) { - g_scheduler.stopEvent(eventWalk); + g_scheduler().stopEvent(eventWalk); eventWalk = 0; } } @@ -606,7 +605,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos if (followCreature && (creature == this || creature == followCreature)) { if (hasFollowPath) { isUpdatingPath = true; - g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()))); } if (newPos.z != oldPos.z || !canSee(followCreature->getPosition())) { @@ -620,7 +619,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos } else { if (hasExtraSwing()) { //our target is moving lets see if we can get in hit - g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); } if (newTile->getZone() != oldTile->getZone()) { @@ -769,7 +768,7 @@ bool Creature::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreatur if (g_configManager().getBoolean(AUTOLOOT)) { int32_t pos = tile->getStackposOfItem(player, corpse); - g_dispatcher.addTask(createTask(std::bind(&Game::playerQuickLoot, &g_game(), mostDamageCreature->getID(), this->getPosition(), corpse->getClientID(), pos - 1, nullptr, false, true))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerQuickLoot, &g_game(), mostDamageCreature->getID(), this->getPosition(), corpse->getClientID(), pos - 1, nullptr, false, true))); } } } @@ -813,7 +812,7 @@ void Creature::changeHealth(int32_t healthChange, bool sendHealthChange/* = true g_game().addCreatureHealth(this); } if (health <= 0) { - g_dispatcher.addTask(createTask(std::bind(&Game::executeDeath, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::executeDeath, &g_game(), getID()))); } } @@ -1285,7 +1284,7 @@ void Creature::removeCondition(ConditionType_t conditionType, ConditionId_t cond if (!force && conditionType == CONDITION_PARALYZE) { int32_t walkDelay = getWalkDelay(); if (walkDelay > 0) { - g_scheduler.addEvent(createSchedulerTask(walkDelay, std::bind(&Game::forceRemoveCondition, &g_game(), getID(), conditionType, conditionId))); + g_scheduler().addEvent(createSchedulerTask(walkDelay, std::bind(&Game::forceRemoveCondition, &g_game(), getID(), conditionType, conditionId))); return; } } @@ -1468,7 +1467,7 @@ void Creature::setNormalCreatureLight() bool Creature::registerCreatureEvent(const std::string& name) { - CreatureEvent* event = g_creatureEvents->getEventByName(name); + CreatureEvent* event = g_creatureEvents().getEventByName(name); if (!event) { return false; } @@ -1490,7 +1489,7 @@ bool Creature::registerCreatureEvent(const std::string& name) bool Creature::unregisterCreatureEvent(const std::string& name) { - CreatureEvent* event = g_creatureEvents->getEventByName(name); + const CreatureEvent* event = g_creatureEvents().getEventByName(name); if (!event) { return false; } diff --git a/src/creatures/interactions/chat.cpp b/src/creatures/interactions/chat.cpp index c16c23cc93e..2af47734162 100644 --- a/src/creatures/interactions/chat.cpp +++ b/src/creatures/interactions/chat.cpp @@ -24,7 +24,6 @@ #include "utils/pugicast.h" #include "game/scheduling/scheduler.h" -extern Chat* g_chat; bool PrivateChatChannel::isInvited(uint32_t guid) const { @@ -99,7 +98,7 @@ bool ChatChannel::addUser(Player& player) if (id == CHANNEL_GUILD) { Guild* guild = player.getGuild(); if (guild && !guild->getMotd().empty()) { - g_scheduler.addEvent(createSchedulerTask(150, std::bind(&Game::sendGuildMotd, &g_game(), player.getID()))); + g_scheduler().addEvent(createSchedulerTask(150, std::bind(&Game::sendGuildMotd, &g_game(), player.getID()))); } } @@ -162,7 +161,7 @@ bool ChatChannel::executeCanJoinEvent(const Player& player) } //canJoin(player) - LuaScriptInterface* scriptInterface = g_chat->getScriptInterface(); + LuaScriptInterface* scriptInterface = g_chat().getScriptInterface(); if (!scriptInterface->reserveScriptEnv()) { SPDLOG_ERROR("[CanJoinChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested.", @@ -189,7 +188,7 @@ bool ChatChannel::executeOnJoinEvent(const Player& player) } //onJoin(player) - LuaScriptInterface* scriptInterface = g_chat->getScriptInterface(); + LuaScriptInterface* scriptInterface = g_chat().getScriptInterface(); if (!scriptInterface->reserveScriptEnv()) { SPDLOG_ERROR("[OnJoinChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested", @@ -216,7 +215,7 @@ bool ChatChannel::executeOnLeaveEvent(const Player& player) } //onLeave(player) - LuaScriptInterface* scriptInterface = g_chat->getScriptInterface(); + LuaScriptInterface* scriptInterface = g_chat().getScriptInterface(); if (!scriptInterface->reserveScriptEnv()) { SPDLOG_ERROR("[OnLeaveChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested.", @@ -243,7 +242,7 @@ bool ChatChannel::executeOnSpeakEvent(const Player& player, SpeakClasses& type, } //onSpeak(player, type, message) - LuaScriptInterface* scriptInterface = g_chat->getScriptInterface(); + LuaScriptInterface* scriptInterface = g_chat().getScriptInterface(); if (!scriptInterface->reserveScriptEnv()) { SPDLOG_ERROR("[OnSpeakChannelEvent::execute - Player {}, type {}] " "Call stack overflow. Too many lua script calls being nested.", diff --git a/src/creatures/interactions/chat.h b/src/creatures/interactions/chat.h index be5d73054b7..c9d60fd93aa 100644 --- a/src/creatures/interactions/chat.h +++ b/src/creatures/interactions/chat.h @@ -127,6 +127,13 @@ class Chat Chat(const Chat&) = delete; Chat& operator=(const Chat&) = delete; + static Chat& getInstance() { + // Guaranteed to be destroyed + static Chat instance; + // Instantiated on first use + return instance; + } + bool load(); ChatChannel* createChannel(const Player& player, uint16_t channelId); @@ -160,4 +167,6 @@ class Chat PrivateChatChannel dummyPrivate; }; +constexpr auto g_chat = &Chat::getInstance; + #endif // SRC_CREATURES_INTERACTIONS_CHAT_H_ diff --git a/src/creatures/monsters/monster.cpp b/src/creatures/monsters/monster.cpp index c9a38068388..62541f27b4a 100644 --- a/src/creatures/monsters/monster.cpp +++ b/src/creatures/monsters/monster.cpp @@ -26,8 +26,6 @@ #include "creatures/combat/spells.h" #include "lua/creature/events.h" -extern Monsters g_monsters; -extern Events* g_events; int32_t Monster::despawnRange; int32_t Monster::despawnRadius; @@ -36,7 +34,7 @@ uint32_t Monster::monsterAutoID = 0x40000000; Monster* Monster::createMonster(const std::string& name) { - MonsterType* mType = g_monsters.getMonsterType(name); + MonsterType* mType = g_monsters().getMonsterType(name); if (!mType) { return nullptr; } @@ -737,7 +735,7 @@ bool Monster::selectTarget(Creature* creature) if (isHostile() || isSummon()) { if (setAttackedCreature(creature) && !isSummon()) { - g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); } } return setFollowCreature(creature); @@ -2042,7 +2040,7 @@ void Monster::updateLookDirection() void Monster::dropLoot(Container* corpse, Creature*) { if (corpse && lootDrop) { - g_events->eventMonsterOnDropLoot(this, corpse); + g_events().eventMonsterOnDropLoot(this, corpse); } } diff --git a/src/creatures/monsters/monsters.cpp b/src/creatures/monsters/monsters.cpp index 4d94107e8a2..aee54a42392 100644 --- a/src/creatures/monsters/monsters.cpp +++ b/src/creatures/monsters/monsters.cpp @@ -28,8 +28,6 @@ #include "utils/pugicast.h" -extern Spells* g_spells; -extern Monsters g_monsters; spellBlock_t::~spellBlock_t() { @@ -165,7 +163,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co } } - if (auto spell = g_spells->getSpellByName(name)) { + if (auto spell = g_spells().getSpellByName(name)) { sb.spell = spell; return true; } @@ -184,7 +182,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co } std::unique_ptr combatSpellPtr(new CombatSpell(nullptr, needTarget, needDirection)); - if (!combatSpellPtr->loadScript("data/" + g_spells->getScriptBaseName() + "/scripts/" + scriptName)) { + if (!combatSpellPtr->loadScript("data/" + g_spells().getScriptBaseName() + "/scripts/" + scriptName)) { return false; } @@ -369,7 +367,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co } if ((attr = node.attribute("monster"))) { - MonsterType* mType = g_monsters.getMonsterType(attr.as_string()); + const MonsterType* mType = g_monsters().getMonsterType(attr.as_string()); if (mType) { ConditionOutfit* condition = static_cast(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); condition->setOutfit(mType->info.outfit); @@ -536,7 +534,7 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std sb.range = std::min((int) spell->range, Map::maxViewportX * 2); sb.minCombatValue = std::min(spell->minCombatValue, spell->maxCombatValue); sb.maxCombatValue = std::max(spell->minCombatValue, spell->maxCombatValue); - sb.spell = g_spells->getSpellByName(spell->name); + sb.spell = g_spells().getSpellByName(spell->name); if (sb.spell) { return true; @@ -546,7 +544,7 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std if (spell->isScripted) { std::unique_ptr combatSpellPtr(new CombatSpell(nullptr, spell->needTarget, spell->needDirection)); - if (!combatSpellPtr->loadScript("data/" + g_spells->getScriptBaseName() + "/scripts/" + spell->scriptName)) { + if (!combatSpellPtr->loadScript("data/" + g_spells().getScriptBaseName() + "/scripts/" + spell->scriptName)) { SPDLOG_ERROR("[Monsters::deserializeSpell] - Cannot find file: {}", spell->scriptName); return false; @@ -1472,7 +1470,7 @@ MonsterType* Monsters::getMonsterTypeByRaceId(uint16_t thisrace) { if (it == raceid_list.end()) { return nullptr; } - MonsterType* mtype = g_monsters.getMonsterType(it->second); + MonsterType* mtype = g_monsters().getMonsterType(it->second); return (mtype ? mtype : nullptr); } diff --git a/src/creatures/monsters/monsters.h b/src/creatures/monsters/monsters.h index 693b6554781..5842789e8fc 100644 --- a/src/creatures/monsters/monsters.h +++ b/src/creatures/monsters/monsters.h @@ -225,6 +225,13 @@ class Monsters Monsters(const Monsters&) = delete; Monsters& operator=(const Monsters&) = delete; + static Monsters& getInstance() { + // Guaranteed to be destroyed + static Monsters instance; + // Instantiated on first use + return instance; + } + bool loadFromXml(bool reloading = false); bool isLoaded() const { return loaded; @@ -254,4 +261,6 @@ class Monsters bool loaded = false; }; +constexpr auto g_monsters = &Monsters::getInstance; + #endif // SRC_CREATURES_MONSTERS_MONSTERS_H_ diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index 00021f81ca9..abad561e4ae 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -27,8 +27,6 @@ #include "utils/pugicast.h" #include "lua/creature/events.h" -extern Monsters g_monsters; -extern Events* g_events; static constexpr int32_t MONSTER_MINSPAWN_INTERVAL = 1000; // 1 second static constexpr int32_t MONSTER_MAXSPAWN_INTERVAL = 86400000; // 1 day @@ -159,7 +157,7 @@ bool SpawnsMonster::isInZone(const Position& centerPos, int32_t radius, const Po void SpawnMonster::startSpawnMonsterCheck() { if (checkSpawnMonsterEvent == 0) { - checkSpawnMonsterEvent = g_scheduler.addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this))); + checkSpawnMonsterEvent = g_scheduler().addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this))); } } @@ -211,7 +209,7 @@ bool SpawnMonster::spawnMonster(uint32_t spawnMonsterId, MonsterType* monsterTyp spawnedMonsterMap.insert(spawned_pair(spawnMonsterId, monster)); spawnMonsterMap[spawnMonsterId].lastSpawn = OTSYS_TIME(); - g_events->eventMonsterOnSpawn(monster, pos); + g_events().eventMonsterOnSpawn(monster, pos); return true; } @@ -263,7 +261,7 @@ void SpawnMonster::checkSpawnMonster() } if (spawnedMonsterMap.size() < spawnMonsterMap.size()) { - checkSpawnMonsterEvent = g_scheduler.addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this))); + checkSpawnMonsterEvent = g_scheduler().addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this))); } } @@ -273,7 +271,7 @@ void SpawnMonster::scheduleSpawn(uint32_t spawnMonsterId, spawnBlock_t& sb, uint spawnMonster(spawnMonsterId, sb.monsterType, sb.pos, sb.direction); } else { g_game().addMagicEffect(sb.pos, CONST_ME_TELEPORT); - g_scheduler.addEvent(createSchedulerTask(1400, std::bind(&SpawnMonster::scheduleSpawn, this, spawnMonsterId, sb, interval - NONBLOCKABLE_SPAWN_MONSTER_INTERVAL))); + g_scheduler().addEvent(createSchedulerTask(1400, std::bind(&SpawnMonster::scheduleSpawn, this, spawnMonsterId, sb, interval - NONBLOCKABLE_SPAWN_MONSTER_INTERVAL))); } } @@ -295,7 +293,7 @@ void SpawnMonster::cleanup() bool SpawnMonster::addMonster(const std::string& name, const Position& pos, Direction dir, uint32_t scheduleInterval) { - MonsterType* monsterType = g_monsters.getMonsterType(name); + MonsterType* monsterType = g_monsters().getMonsterType(name); if (!monsterType) { SPDLOG_ERROR("Can not find {}", name); return false; @@ -329,7 +327,7 @@ void SpawnMonster::removeMonster(Monster* monster) void SpawnMonster::stopEvent() { if (checkSpawnMonsterEvent != 0) { - g_scheduler.stopEvent(checkSpawnMonsterEvent); + g_scheduler().stopEvent(checkSpawnMonsterEvent); checkSpawnMonsterEvent = 0; } } diff --git a/src/creatures/npcs/npc.cpp b/src/creatures/npcs/npc.cpp index 2847db2c264..77bb1b95ce4 100644 --- a/src/creatures/npcs/npc.cpp +++ b/src/creatures/npcs/npc.cpp @@ -27,8 +27,6 @@ #include "creatures/combat/spells.h" #include "lua/creature/events.h" -extern Npcs g_npcs; -extern Events* g_events; int32_t Npc::despawnRange; int32_t Npc::despawnRadius; @@ -37,7 +35,7 @@ uint32_t Npc::npcAutoID = 0x80000000; Npc* Npc::createNpc(const std::string& name) { - NpcType* npcType = g_npcs.getNpcType(name); + NpcType* npcType = g_npcs().getNpcType(name); if (!npcType) { return nullptr; } @@ -71,7 +69,7 @@ Npc::~Npc() { void Npc::reset() const { - g_npcs.reset(); + g_npcs().reset(); // Close shop window from all npcs and reset the shopPlayerSet for (const auto& [npcId, npc] : g_game().getNpcs()) { npc->closeAllShopWindows(); diff --git a/src/creatures/npcs/npcs.cpp b/src/creatures/npcs/npcs.cpp index abc6feacbdc..a4ba05e0f8e 100644 --- a/src/creatures/npcs/npcs.cpp +++ b/src/creatures/npcs/npcs.cpp @@ -30,8 +30,6 @@ #include "utils/pugicast.h" -extern Spells* g_spells; -extern Npcs g_npcs; bool NpcType::canSpawn(const Position& pos) { diff --git a/src/creatures/npcs/npcs.h b/src/creatures/npcs/npcs.h index 151d3eeaddb..4a052ef78ac 100644 --- a/src/creatures/npcs/npcs.h +++ b/src/creatures/npcs/npcs.h @@ -105,6 +105,13 @@ class Npcs Npcs(const Npcs&) = delete; Npcs& operator=(const Npcs&) = delete; + static Npcs& getInstance() { + // Guaranteed to be destroyed + static Npcs instance; + // Instantiated on first use + return instance; + } + NpcType* getNpcType(const std::string& name, bool create = false); // Reset npcs informations on reload @@ -118,4 +125,6 @@ class Npcs std::map npcs; }; +constexpr auto g_npcs = &Npcs::getInstance; + #endif // SRC_CREATURES_NPCS_NPCS_H_ diff --git a/src/creatures/npcs/spawns/spawn_npc.cpp b/src/creatures/npcs/spawns/spawn_npc.cpp index 4fc9d841020..084f8011f18 100644 --- a/src/creatures/npcs/spawns/spawn_npc.cpp +++ b/src/creatures/npcs/spawns/spawn_npc.cpp @@ -27,8 +27,6 @@ #include "utils/pugicast.h" #include "lua/creature/events.h" -extern Npcs g_npcs; -extern Events* g_events; static constexpr int32_t MINSPAWN_INTERVAL = 1000; // 1 second static constexpr int32_t MAXSPAWN_INTERVAL = 86400000; // 1 day @@ -147,7 +145,7 @@ bool SpawnsNpc::isInZone(const Position& centerPos, int32_t radius, const Positi void SpawnNpc::startSpawnNpcCheck() { if (checkSpawnNpcEvent == 0) { - checkSpawnNpcEvent = g_scheduler.addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnNpc::checkSpawnNpc, this))); + checkSpawnNpcEvent = g_scheduler().addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnNpc::checkSpawnNpc, this))); } } @@ -199,7 +197,7 @@ bool SpawnNpc::spawnNpc(uint32_t spawnId, NpcType* npcType, const Position& pos, spawnedNpcMap.insert(spawned_pair(spawnId, npc)); spawnNpcMap[spawnId].lastSpawnNpc = OTSYS_TIME(); - g_events->eventNpcOnSpawn(npc, pos); + g_events().eventNpcOnSpawn(npc, pos); return true; } @@ -241,7 +239,7 @@ void SpawnNpc::checkSpawnNpc() } if (spawnedNpcMap.size() < spawnNpcMap.size()) { - checkSpawnNpcEvent = g_scheduler.addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnNpc::checkSpawnNpc, this))); + checkSpawnNpcEvent = g_scheduler().addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnNpc::checkSpawnNpc, this))); } } @@ -251,7 +249,7 @@ void SpawnNpc::scheduleSpawnNpc(uint32_t spawnId, spawnBlockNpc_t& sb, uint16_t spawnNpc(spawnId, sb.npcType, sb.pos, sb.direction); } else { g_game().addMagicEffect(sb.pos, CONST_ME_TELEPORT); - g_scheduler.addEvent(createSchedulerTask(1400, std::bind(&SpawnNpc::scheduleSpawnNpc, this, spawnId, sb, interval - NONBLOCKABLE_SPAWN_NPC_INTERVAL))); + g_scheduler().addEvent(createSchedulerTask(1400, std::bind(&SpawnNpc::scheduleSpawnNpc, this, spawnId, sb, interval - NONBLOCKABLE_SPAWN_NPC_INTERVAL))); } } @@ -273,7 +271,7 @@ void SpawnNpc::cleanup() bool SpawnNpc::addNpc(const std::string& name, const Position& pos, Direction dir, uint32_t scheduleInterval) { - NpcType* npcType = g_npcs.getNpcType(name); + NpcType* npcType = g_npcs().getNpcType(name); if (!npcType) { SPDLOG_ERROR("Can not find {}", name); return false; @@ -307,7 +305,7 @@ void SpawnNpc::removeNpc(Npc* npc) void SpawnNpc::stopEvent() { if (checkSpawnNpcEvent != 0) { - g_scheduler.stopEvent(checkSpawnNpcEvent); + g_scheduler().stopEvent(checkSpawnNpcEvent); checkSpawnNpcEvent = 0; } } diff --git a/src/creatures/players/account/account.cpp b/src/creatures/players/account/account.cpp index a320c8ad1ba..fa6a8a07b88 100644 --- a/src/creatures/players/account/account.cpp +++ b/src/creatures/players/account/account.cpp @@ -35,7 +35,7 @@ Account::Account() { premium_last_day_ = 0; account_type_ = ACCOUNT_TYPE_NORMAL; db_ = &Database::getInstance(); - db_tasks_ = &g_databaseTasks; + db_tasks_ = &g_databaseTasks(); } Account::Account(uint32_t id) { @@ -46,7 +46,7 @@ Account::Account(uint32_t id) { premium_last_day_ = 0; account_type_ = ACCOUNT_TYPE_NORMAL; db_ = &Database::getInstance(); - db_tasks_ = &g_databaseTasks; + db_tasks_ = &g_databaseTasks(); } Account::Account(const std::string &email) : email_(email) { @@ -56,7 +56,7 @@ Account::Account(const std::string &email) : email_(email) { premium_last_day_ = 0; account_type_ = ACCOUNT_TYPE_NORMAL; db_ = &Database::getInstance(); - db_tasks_ = &g_databaseTasks; + db_tasks_ = &g_databaseTasks(); } diff --git a/src/creatures/players/grouping/party.cpp b/src/creatures/players/grouping/party.cpp index 200c7c0e314..ed58f4a9176 100644 --- a/src/creatures/players/grouping/party.cpp +++ b/src/creatures/players/grouping/party.cpp @@ -23,7 +23,6 @@ #include "game/game.h" #include "lua/creature/events.h" -extern Events* g_events; Party::Party(Player* initLeader) : leader(initLeader) { @@ -32,7 +31,7 @@ Party::Party(Player* initLeader) : leader(initLeader) void Party::disband() { - if (!g_events->eventPartyOnDisband(this)) { + if (!g_events().eventPartyOnDisband(this)) { return; } @@ -86,7 +85,7 @@ bool Party::leaveParty(Player* player) return false; } - if (!g_events->eventPartyOnLeave(this, player)) { + if (!g_events().eventPartyOnLeave(this, player)) { return false; } @@ -183,7 +182,7 @@ bool Party::passPartyLeadership(Player* player) bool Party::joinParty(Player& player) { - if (!g_events->eventPartyOnJoin(this, &player)) { + if (!g_events().eventPartyOnJoin(this, &player)) { return false; } @@ -369,7 +368,7 @@ bool Party::setSharedExperience(Player* player, bool newSharedExpActive) void Party::shareExperience(uint64_t experience, Creature* source/* = nullptr*/) { uint64_t shareExperience = experience; - g_events->eventPartyOnShareExperience(this, shareExperience); + g_events().eventPartyOnShareExperience(this, shareExperience); for (Player* member : memberList) { member->onGainSharedExperience(shareExperience, source); } diff --git a/src/creatures/players/imbuements/imbuements.cpp b/src/creatures/players/imbuements/imbuements.cpp index cd1a2475f88..32afa9a0ca5 100644 --- a/src/creatures/players/imbuements/imbuements.cpp +++ b/src/creatures/players/imbuements/imbuements.cpp @@ -22,7 +22,6 @@ #include "creatures/players/imbuements/imbuements.h" #include "utils/pugicast.h" -extern Events* g_events; Imbuement* Imbuements::getImbuement(uint16_t id) { diff --git a/src/creatures/players/imbuements/imbuements.h b/src/creatures/players/imbuements/imbuements.h index e27410dc1da..a003f8731f4 100644 --- a/src/creatures/players/imbuements/imbuements.h +++ b/src/creatures/players/imbuements/imbuements.h @@ -53,9 +53,22 @@ struct CategoryImbuement { class Imbuements { public: + Imbuements() = default; + bool loadFromXml(bool reloading = false); bool reload(); + // non-copyable + Imbuements(const Imbuements&) = delete; + Imbuements& operator=(const Imbuements&) = delete; + + static Imbuements& getInstance() { + // Guaranteed to be destroyed + static Imbuements instance; + // Instantiated on first use + return instance; + } + Imbuement* getImbuement(uint16_t id); BaseImbuement* getBaseByID(uint16_t id); @@ -75,6 +88,8 @@ class Imbuements { uint32_t runningid = 0; }; +constexpr auto g_imbuements = &Imbuements::getInstance; + class Imbuement { public: diff --git a/src/creatures/players/management/ban.cpp b/src/creatures/players/management/ban.cpp index 7c563752776..4490748b102 100644 --- a/src/creatures/players/management/ban.cpp +++ b/src/creatures/players/management/ban.cpp @@ -75,11 +75,11 @@ bool IOBan::isAccountBanned(uint32_t accountId, BanInfo& banInfo) // Move the ban to history if it has expired query.str(std::string()); query << "INSERT INTO `account_ban_history` (`account_id`, `reason`, `banned_at`, `expired_at`, `banned_by`) VALUES (" << accountId << ',' << db.escapeString(result->getString("reason")) << ',' << result->getNumber("banned_at") << ',' << expiresAt << ',' << result->getNumber("banned_by") << ')'; - g_databaseTasks.addTask(query.str()); + g_databaseTasks().addTask(query.str()); query.str(std::string()); query << "DELETE FROM `account_bans` WHERE `account_id` = " << accountId; - g_databaseTasks.addTask(query.str()); + g_databaseTasks().addTask(query.str()); return false; } @@ -109,7 +109,7 @@ bool IOBan::isIpBanned(uint32_t clientIP, BanInfo& banInfo) if (expiresAt != 0 && time(nullptr) > expiresAt) { query.str(std::string()); query << "DELETE FROM `ip_bans` WHERE `ip` = " << clientIP; - g_databaseTasks.addTask(query.str()); + g_databaseTasks().addTask(query.str()); return false; } diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index aee95c049bc..f0a2a1f0c32 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -36,14 +36,6 @@ #include "items/weapons/weapons.h" #include "io/iobestiary.h" -extern Chat* g_chat; -extern Vocations g_vocations; -extern MoveEvents* g_moveEvents; -extern Weapons* g_weapons; -extern CreatureEvents* g_creatureEvents; -extern Events* g_events; -extern Imbuements* g_imbuements; -extern Monsters g_monsters; MuteCountMap Player::muteCountMap; @@ -92,7 +84,7 @@ Player::~Player() bool Player::setVocation(uint16_t vocId) { - Vocation* voc = g_vocations.getVocation(vocId); + Vocation* voc = g_vocations().getVocation(vocId); if (!voc) { return false; } @@ -494,7 +486,7 @@ void Player::updateInventoryImbuement(bool init /* = false */) // Time not decay on protection zone const Tile* playerTile = getTile(); - const CategoryImbuement *categoryImbuement = g_imbuements->getCategoryByID(imbuementInfo.imbuement->getCategory()); + const CategoryImbuement *categoryImbuement = g_imbuements().getCategoryByID(imbuementInfo.imbuement->getCategory()); if (categoryImbuement->agressive && playerTile && playerTile->hasFlag(TILESTATE_PROTECTIONZONE)) { continue; } @@ -539,7 +531,7 @@ void Player::addSkillAdvance(skills_t skill, uint64_t count) return; } - g_events->eventPlayerOnGainSkillTries(this, skill, count); + g_events().eventPlayerOnGainSkillTries(this, skill, count); if (count == 0) { return; } @@ -555,7 +547,7 @@ void Player::addSkillAdvance(skills_t skill, uint64_t count) ss << "You advanced to " << getSkillName(skill) << " level " << skills[skill].level << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); - g_creatureEvents->playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level); + g_creatureEvents().playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level); sendUpdateSkills = true; currReqTries = nextReqTries; @@ -753,8 +745,8 @@ void Player::addStorageValue(const uint32_t key, const int32_t value, const bool storageMap[key] = value; if (!isLogin) { - auto currentFrameTime = g_dispatcher.getDispatcherCycle(); - g_events->eventOnStorageUpdate(this, key, value, oldValue, currentFrameTime); + auto currentFrameTime = g_dispatcher().getDispatcherCycle(); + g_events().eventOnStorageUpdate(this, key, value, oldValue, currentFrameTime); } } else { storageMap.erase(key); @@ -1155,13 +1147,11 @@ void Player::sendPing() setAttackedCreature(nullptr); } - if (noPongTime >= 60000 && canLogout()) { - if (g_creatureEvents->playerLogout(this)) { - if (client) { - client->logout(true, true); - } else { - g_game().removeCreature(this, true); - } + if (noPongTime >= 60000 && canLogout() && g_creatureEvents().playerLogout(this)) { + if (client) { + client->logout(true, true); + } else { + g_game().removeCreature(this, true); } } } @@ -1255,7 +1245,7 @@ void Player::onApplyImbuement(Imbuement *imbuement, Item *item, uint8_t slot, bo } } - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuement->getBaseID()); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuement->getBaseID()); if (!baseImbuement) { return; @@ -1328,7 +1318,7 @@ void Player::onClearImbuement(Item* item, uint8_t slot) return; } - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuementInfo.imbuement->getBaseID()); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuementInfo.imbuement->getBaseID()); if (!baseImbuement) { return; } @@ -1509,7 +1499,7 @@ void Player::onCreatureAppear(Creature* creature, bool isLogin) Item* item = inventory[slot]; if (item) { item->startDecaying(); - g_moveEvents->onPlayerEquip(this, item, static_cast(slot), false); + g_moveEvents().onPlayerEquip(this, item, static_cast(slot), false); } } @@ -1596,7 +1586,7 @@ void Player::onChangeZone(ZoneType_t zone) g_game().updateCreatureWalkthrough(this); sendIcons(); - g_events->eventPlayerOnChangeZone(this, zone); + g_events().eventPlayerOnChangeZone(this, zone); } void Player::onAttackedCreatureChangeZone(ZoneType_t zone) @@ -1630,7 +1620,7 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout) if (isLogout) { loginPosition = getPosition(); SPDLOG_INFO("{} has logged out", getName()); - g_chat->removeUserFromAllChannels(*this); + g_chat().removeUserFromAllChannels(*this); clearPartyInvitations(); } @@ -1723,7 +1713,7 @@ void Player::onCreatureMove(Creature* creature, const Tile* newTile, const Posit if (hasFollowPath && (creature == followCreature || (creature == this && followCreature))) { isUpdatingPath = false; - g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()))); } if (creature != this) { @@ -1885,7 +1875,7 @@ void Player::checkTradeState(const Item* item) void Player::setNextWalkActionTask(SchedulerTask* task) { if (walkTaskEvent != 0) { - g_scheduler.stopEvent(walkTaskEvent); + g_scheduler().stopEvent(walkTaskEvent); walkTaskEvent = 0; } @@ -1896,12 +1886,12 @@ void Player::setNextWalkActionTask(SchedulerTask* task) void Player::setNextWalkTask(SchedulerTask* task) { if (nextStepEvent != 0) { - g_scheduler.stopEvent(nextStepEvent); + g_scheduler().stopEvent(nextStepEvent); nextStepEvent = 0; } if (task) { - nextStepEvent = g_scheduler.addEvent(task); + nextStepEvent = g_scheduler().addEvent(task); resetIdleTime(); } } @@ -1909,7 +1899,7 @@ void Player::setNextWalkTask(SchedulerTask* task) void Player::setNextActionTask(SchedulerTask* task, bool resetIdleTime /*= true */) { if (actionTaskEvent != 0) { - g_scheduler.stopEvent(actionTaskEvent); + g_scheduler().stopEvent(actionTaskEvent); actionTaskEvent = 0; } @@ -1918,7 +1908,7 @@ void Player::setNextActionTask(SchedulerTask* task, bool resetIdleTime /*= true } if (task) { - actionTaskEvent = g_scheduler.addEvent(task); + actionTaskEvent = g_scheduler().addEvent(task); if (resetIdleTime) { this->resetIdleTime(); } @@ -1928,26 +1918,26 @@ void Player::setNextActionTask(SchedulerTask* task, bool resetIdleTime /*= true void Player::setNextActionPushTask(SchedulerTask* task) { if (actionTaskEventPush != 0) { - g_scheduler.stopEvent(actionTaskEventPush); + g_scheduler().stopEvent(actionTaskEventPush); actionTaskEventPush = 0; } if (task) { - actionTaskEventPush = g_scheduler.addEvent(task); + actionTaskEventPush = g_scheduler().addEvent(task); } } void Player::setNextPotionActionTask(SchedulerTask* task) { if (actionPotionTaskEvent != 0) { - g_scheduler.stopEvent(actionPotionTaskEvent); + g_scheduler().stopEvent(actionPotionTaskEvent); actionPotionTaskEvent = 0; } cancelPush(); if (task) { - actionPotionTaskEvent = g_scheduler.addEvent(task); + actionPotionTaskEvent = g_scheduler().addEvent(task); //resetIdleTime(); } } @@ -1965,7 +1955,7 @@ uint32_t Player::getNextPotionActionTime() const void Player::cancelPush() { if (actionTaskEventPush != 0) { - g_scheduler.stopEvent(actionTaskEventPush); + g_scheduler().stopEvent(actionTaskEventPush); actionTaskEventPush = 0; inEventMovePush = false; } @@ -2079,7 +2069,7 @@ void Player::addManaSpent(uint64_t amount) return; } - g_events->eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, amount); + g_events().eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, amount); if (amount == 0) { return; } @@ -2095,7 +2085,7 @@ void Player::addManaSpent(uint64_t amount) ss << "You advanced to magic level " << magLevel << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); - g_creatureEvents->playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel); + g_creatureEvents().playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel); sendUpdateStats = true; currReqMana = nextReqMana; @@ -2136,7 +2126,7 @@ void Player::addExperience(Creature* source, uint64_t exp, bool sendText/* = fal return; } - g_events->eventPlayerOnGainExperience(this, source, exp, rawExp); + g_events().eventPlayerOnGainExperience(this, source, exp, rawExp); if (exp == 0) { return; } @@ -2169,7 +2159,7 @@ void Player::addExperience(Creature* source, uint64_t exp, bool sendText/* = fal ++level; // Player stats gain for vocations level <= 8 if (vocation->getId() != VOCATION_NONE && level <= 8) { - Vocation* noneVocation = g_vocations.getVocation(VOCATION_NONE); + const Vocation* noneVocation = g_vocations().getVocation(VOCATION_NONE); healthMax += noneVocation->getHPGain(); health += noneVocation->getHPGain(); manaMax += noneVocation->getManaGain(); @@ -2205,7 +2195,7 @@ void Player::addExperience(Creature* source, uint64_t exp, bool sendText/* = fal party->updateSharedExperience(); } - g_creatureEvents->playerAdvance(this, SKILL_LEVEL, prevLevel, level); + g_creatureEvents().playerAdvance(this, SKILL_LEVEL, prevLevel, level); std::ostringstream ss; ss << "You advanced from Level " << prevLevel << " to Level " << level << '.'; @@ -2227,7 +2217,7 @@ void Player::removeExperience(uint64_t exp, bool sendText/* = false*/) return; } - g_events->eventPlayerOnLoseExperience(this, exp); + g_events().eventPlayerOnLoseExperience(this, exp); if (exp == 0) { return; } @@ -2265,7 +2255,7 @@ void Player::removeExperience(uint64_t exp, bool sendText/* = false*/) --level; // Player stats loss for vocations level <= 8 if (vocation->getId() != VOCATION_NONE && level <= 8) { - Vocation* noneVocation = g_vocations.getVocation(VOCATION_NONE); + const Vocation* noneVocation = g_vocations().getVocation(VOCATION_NONE); healthMax = std::max(0, healthMax - noneVocation->getHPGain()); manaMax = std::max(0, manaMax - noneVocation->getManaGain()); capacity = std::max(0, capacity - noneVocation->getCapGain()); @@ -2522,7 +2512,7 @@ void Player::death(Creature* lastHitCreature) // Charm bless bestiary if (lastHitCreature && lastHitCreature->getMonster()) { if (charmRuneBless != 0) { - MonsterType* mType = g_monsters.getMonsterType(lastHitCreature->getName()); + const MonsterType* mType = g_monsters().getMonsterType(lastHitCreature->getName()); if (mType && mType->info.raceid == charmRuneBless) { deathLossPercent = (deathLossPercent * 90) / 100; } @@ -2548,7 +2538,7 @@ void Player::death(Creature* lastHitCreature) //Level loss uint64_t expLoss = static_cast(experience * deathLossPercent); - g_events->eventPlayerOnLoseExperience(this, expLoss); + g_events().eventPlayerOnLoseExperience(this, expLoss); sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead."); std::ostringstream lostExp; @@ -2847,7 +2837,7 @@ void Player::addList() void Player::removePlayer(bool displayEffect, bool forced /*= true*/) { - g_creatureEvents->playerLogout(this); + g_creatureEvents().playerLogout(this); if (client) { client->logout(displayEffect, forced); } else { @@ -3185,7 +3175,7 @@ ReturnValue Player::queryAdd(int32_t index, const Thing& thing, uint32_t count, return RETURNVALUE_NOTENOUGHCAPACITY; } - if (!g_moveEvents->onPlayerEquip(const_cast(this), const_cast(item), static_cast(index), true)) { + if (!g_moveEvents().onPlayerEquip(const_cast(this), const_cast(item), static_cast(index), true)) { return RETURNVALUE_CANNOTBEDRESSED; } } @@ -3528,9 +3518,9 @@ void Player::removeThing(Thing* thing, uint32_t count) } } -int32_t Player::getThingIndex(const Thing* thing) const +uint8_t Player::getThingIndex(const Thing* thing) const { - for (int i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { + for (uint8_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { if (inventory[i] == thing) { return i; } @@ -3814,7 +3804,7 @@ void Player::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_ { if (link == LINK_OWNER) { //calling movement scripts - g_moveEvents->onPlayerEquip(this, thing->getItem(), static_cast(index), false); + g_moveEvents().onPlayerEquip(this, thing->getItem(), static_cast(index), false); } bool requireListUpdate = true; @@ -3869,7 +3859,7 @@ void Player::postRemoveNotification(Thing* thing, const Cylinder* newParent, int { if (link == LINK_OWNER) { //calling movement scripts - g_moveEvents->onPlayerDeEquip(this, thing->getItem(), static_cast(index)); + g_moveEvents().onPlayerDeEquip(this, thing->getItem(), static_cast(index)); } bool requireListUpdate = true; @@ -3937,7 +3927,7 @@ bool Player::updateSaleShopList(const Item* item) if (!itemId || !item) return true; - g_dispatcher.addTask(createTask(std::bind(&Game::updatePlayerSaleItems, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updatePlayerSaleItems, &g_game(), getID()))); scheduledSaleUpdate = true; return true; } @@ -4009,7 +3999,7 @@ bool Player::setAttackedCreature(Creature* creature) } if (creature) { - g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); } return true; } @@ -4049,7 +4039,7 @@ void Player::doAttacking(uint32_t) bool result = false; Item* tool = getWeapon(); - const Weapon* weapon = g_weapons->getWeapon(tool); + const Weapon* weapon = g_weapons().getWeapon(tool); uint32_t delay = getAttackSpeed(); bool classicSpeed = g_configManager().getBoolean(CLASSIC_ATTACK_SPEED); @@ -4069,7 +4059,7 @@ void Player::doAttacking(uint32_t) if (!classicSpeed) { setNextActionTask(task, false); } else { - g_scheduler.addEvent(task); + g_scheduler().addEvent(task); } if (result) { @@ -4123,7 +4113,7 @@ void Player::onWalkAborted() void Player::onWalkComplete() { if (walkTask) { - walkTaskEvent = g_scheduler.addEvent(walkTask); + walkTaskEvent = g_scheduler().addEvent(walkTask); walkTask = nullptr; } } @@ -4335,7 +4325,7 @@ void Player::onIdleStatus() void Player::onPlacedCreature() { //scripting event - onLogin - if (!g_creatureEvents->playerLogin(this)) { + if (!g_creatureEvents().playerLogin(this)) { removePlayer(true); } @@ -4848,7 +4838,7 @@ void Player::checkSkullTicks(int64_t ticks) bool Player::isPromoted() const { - uint16_t promotedVocation = g_vocations.getPromotedVocation(vocation->getId()); + uint16_t promotedVocation = g_vocations().getPromotedVocation(vocation->getId()); return promotedVocation == VOCATION_NONE && vocation->getId() != promotedVocation; } @@ -5311,7 +5301,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) oldSkillValue = magLevel; oldPercentToNextLevel = static_cast(manaSpent * 100) / nextReqMana; - g_events->eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, tries); + g_events().eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, tries); uint32_t currMagLevel = magLevel; while ((manaSpent + tries) >= nextReqMana) { @@ -5320,7 +5310,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) magLevel++; manaSpent = 0; - g_creatureEvents->playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel); + g_creatureEvents().playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel); sendUpdate = true; currReqMana = nextReqMana; @@ -5365,7 +5355,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) oldSkillValue = skills[skill].level; oldPercentToNextLevel = static_cast(skills[skill].tries * 100) / nextReqTries; - g_events->eventPlayerOnGainSkillTries(this, skill, tries); + g_events().eventPlayerOnGainSkillTries(this, skill, tries); uint32_t currSkillLevel = skills[skill].level; while ((skills[skill].tries + tries) >= nextReqTries) { @@ -5375,7 +5365,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) skills[skill].tries = 0; skills[skill].percent = 0; - g_creatureEvents->playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level); + g_creatureEvents().playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level); sendUpdate = true; currReqTries = nextReqTries; @@ -5481,7 +5471,7 @@ uint16_t Player::getHelpers() const void Player::sendClosePrivate(uint16_t channelId) { if (channelId == CHANNEL_GUILD || channelId == CHANNEL_PARTY) { - g_chat->removeUserFromChannel(*this, channelId); + g_chat().removeUserFromChannel(*this, channelId); } if (client) { diff --git a/src/creatures/players/player.h b/src/creatures/players/player.h index d3df75297ad..87e2bd242cd 100644 --- a/src/creatures/players/player.h +++ b/src/creatures/players/player.h @@ -1931,7 +1931,7 @@ class Player final : public Creature, public Cylinder void removeThing(Thing* thing, uint32_t count) override; - int32_t getThingIndex(const Thing* thing) const override; + uint8_t getThingIndex(const Thing* thing) const override; size_t getFirstIndex() const override; size_t getLastIndex() const override; uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const override; diff --git a/src/creatures/players/vocations/vocation.cpp b/src/creatures/players/vocations/vocation.cpp index 92a951d1500..29f70733161 100644 --- a/src/creatures/players/vocations/vocation.cpp +++ b/src/creatures/players/vocations/vocation.cpp @@ -171,7 +171,7 @@ Vocation* Vocations::getVocation(uint16_t id) return &it->second; } -int32_t Vocations::getVocationId(const std::string& name) const +uint16_t Vocations::getVocationId(const std::string& name) const { for (const auto& it : vocationsMap) { if (strcasecmp(it.second.name.c_str(), name.c_str()) == 0) { diff --git a/src/creatures/players/vocations/vocation.h b/src/creatures/players/vocations/vocation.h index 420934aec5e..56752d9b323 100644 --- a/src/creatures/players/vocations/vocation.h +++ b/src/creatures/players/vocations/vocation.h @@ -99,9 +99,9 @@ class Vocation return fromVocation; } - bool getMagicShield() const { - return magicShield; - } + bool getMagicShield() const { + return magicShield; + } float meleeDamageMultiplier = 1.0f; float distDamageMultiplier = 1.0f; @@ -132,7 +132,7 @@ class Vocation uint32_t baseSpeed = 220; uint16_t id; - bool magicShield = false; + bool magicShield = false; uint32_t gainSoulTicks = 120000; @@ -146,15 +146,29 @@ class Vocation class Vocations { public: + Vocations() = default; + + Vocations(Vocations const&) = delete; + void operator=(Vocations const&) = delete; + + static Vocations& getInstance() { + // Guaranteed to be destroyed + static Vocations instance; + // Instantiated on first use + return instance; + } + bool loadFromXml(); Vocation* getVocation(uint16_t id); - const std::map& getVocations() const {return vocationsMap;} - int32_t getVocationId(const std::string& name) const; + const std::map& getVocations() const {return vocationsMap;} + uint16_t getVocationId(const std::string& name) const; uint16_t getPromotedVocation(uint16_t vocationId) const; private: std::map vocationsMap; }; +constexpr auto g_vocations = &Vocations::getInstance; + #endif // SRC_CREATURES_PLAYERS_VOCATIONS_VOCATION_H_ diff --git a/src/database/databasetasks.cpp b/src/database/databasetasks.cpp index 764961dfa00..5fe6a1980f2 100644 --- a/src/database/databasetasks.cpp +++ b/src/database/databasetasks.cpp @@ -22,7 +22,6 @@ #include "database/databasetasks.h" #include "game/scheduling/tasks.h" -extern Dispatcher g_dispatcher; DatabaseTasks::DatabaseTasks() { db_ = &Database::getInstance(); @@ -105,7 +104,7 @@ void DatabaseTasks::runTask(const DatabaseTask& task) } if (task.callback) { - g_dispatcher.addTask(createTask(std::bind(task.callback, result, success))); + g_dispatcher().addTask(createTask(std::bind(task.callback, result, success))); } } diff --git a/src/database/databasetasks.h b/src/database/databasetasks.h index 2c62d119af0..3468b57a69e 100644 --- a/src/database/databasetasks.h +++ b/src/database/databasetasks.h @@ -38,6 +38,18 @@ class DatabaseTasks : public ThreadHolder { public: DatabaseTasks(); + + // non-copyable + DatabaseTasks(DatabaseTasks const&) = delete; + void operator=(DatabaseTasks const&) = delete; + + static DatabaseTasks& getInstance() { + // Guaranteed to be destroyed + static DatabaseTasks instance; + // Instantiated on first use + return instance; + } + bool SetDatabaseInterface(Database *database); void start(); void startThread(); @@ -59,6 +71,6 @@ class DatabaseTasks : public ThreadHolder bool flushTasks = false; }; -extern DatabaseTasks g_databaseTasks; +constexpr auto g_databaseTasks = &DatabaseTasks::getInstance; #endif // SRC_DATABASE_DATABASETASKS_H_ diff --git a/src/game/game.cpp b/src/game/game.cpp index 5778e90fec0..f756acff612 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -47,24 +47,6 @@ #include "creatures/npcs/npc.h" #include "creatures/npcs/npcs.h" #include "server/network/webhook/webhook.h" - -extern Actions* g_actions; -extern Chat* g_chat; -extern TalkActions* g_talkActions; -extern Spells* g_spells; -extern Vocations g_vocations; -extern GlobalEvents* g_globalEvents; -extern CreatureEvents* g_creatureEvents; -extern Events* g_events; -extern Monsters g_monsters; -extern Npcs g_npcs; -extern MoveEvents* g_moveEvents; -extern Weapons* g_weapons; -extern Scripts* g_scripts; -extern Modules* g_modules; -extern Imbuements* g_imbuements; -extern LuaEnvironment g_luaEnvironment; - Game::Game() { offlineTrainingWindow.choices.emplace_back("Sword Fighting and Shielding", SKILL_SWORD); @@ -126,7 +108,7 @@ void Game::loadBoostedCreature() } } - MonsterType* monsterType = g_monsters.getMonsterTypeByRaceId(newrace); + const MonsterType* monsterType = g_monsters().getMonsterTypeByRaceId(newrace); query.str(std::string()); query << "UPDATE `boosted_creature` SET "; @@ -164,9 +146,9 @@ void Game::start(ServiceManager* manager) int minutes = tms->tm_min; lightHour = (minutes * LIGHT_DAY_LENGTH) / 60; - g_scheduler.addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL_MS, std::bind(&Game::checkLight, this))); - g_scheduler.addEvent(createSchedulerTask(EVENT_CREATURE_THINK_INTERVAL, std::bind(&Game::checkCreatures, this, 0))); - g_scheduler.addEvent(createSchedulerTask(EVENT_IMBUEMENT_INTERVAL, std::bind(&Game::checkImbuements, this))); + g_scheduler().addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL_MS, std::bind(&Game::checkLight, this))); + g_scheduler().addEvent(createSchedulerTask(EVENT_CREATURE_THINK_INTERVAL, std::bind(&Game::checkCreatures, this, 0))); + g_scheduler().addEvent(createSchedulerTask(EVENT_IMBUEMENT_INTERVAL, std::bind(&Game::checkImbuements, this))); } GameState_t Game::getGameState() const @@ -229,12 +211,10 @@ bool Game::loadScheduleEventFromXml() } } - if ((attr = schedNode.attribute("script"))) { - if (!(g_scripts->loadEventSchedulerScripts(attr.as_string()))) { - SPDLOG_WARN("Can not load the file '{}' on '/events/scripts/scheduler/'", - attr.as_string()); - return false; - } + if ((attr = schedNode.attribute("script")) && !(g_scripts().loadEventSchedulerScripts(attr.as_string()))) { + SPDLOG_WARN("Can not load the file '{}' on '/events/scripts/scheduler/'", + attr.as_string()); + return false; } for (auto schedENode : schedNode.children()) { @@ -283,7 +263,7 @@ void Game::setGameState(GameState_t newState) loadItemsPrice(); groups.load(); - g_chat->load(); + g_chat().load(); // Load monsters and npcs stored by the "loadFromXML" function map.spawnsMonster.startup(); @@ -306,12 +286,12 @@ void Game::setGameState(GameState_t newState) loadMotdNum(); loadPlayersRecord(); - g_globalEvents->startup(); + g_globalEvents().startup(); break; } case GAME_STATE_SHUTDOWN: { - g_globalEvents->execute(GLOBALEVENT_SHUTDOWN); + g_globalEvents().execute(GLOBALEVENT_SHUTDOWN); //kick all players that are still online auto it = players.begin(); @@ -323,12 +303,12 @@ void Game::setGameState(GameState_t newState) saveMotdNum(); saveGameState(); - g_dispatcher.addTask( + g_dispatcher().addTask( createTask(std::bind(&Game::shutdown, this))); - g_scheduler.stop(); - g_databaseTasks.stop(); - g_dispatcher.stop(); + g_scheduler().stop(); + g_databaseTasks().stop(); + g_dispatcher().stop(); break; } @@ -630,7 +610,7 @@ void Game::saveGameState() Map::save(); - g_databaseTasks.flush(); + g_databaseTasks().flush(); if (gameState == GAME_STATE_MAINTAIN) { setGameState(GAME_STATE_NORMAL); @@ -1248,7 +1228,7 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po //need to walk to the creature first before moving it std::forward_list listDir; if (player->getPathTo(movingCreatureOrigPos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(600, std::bind(&Game::playerMoveCreatureByID, this, @@ -1310,7 +1290,7 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po movingCreature->setLastPosition(movingCreature->getPosition()); } - if (!g_events->eventPlayerOnMoveCreature(player, movingCreature, movingCreaturePos, toPos)) { + if (!g_events().eventPlayerOnMoveCreature(player, movingCreature, movingCreaturePos, toPos)) { return; } @@ -1502,7 +1482,7 @@ void Game::playerMoveItem(Player* player, const Position& fromPos, //need to walk to the item first before using it std::forward_list listDir; if (player->getPathTo(item->getPosition(), listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, @@ -1563,7 +1543,7 @@ void Game::playerMoveItem(Player* player, const Position& fromPos, std::forward_list listDir; if (player->getPathTo(walkPos, listDir, 0, 0, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, @@ -1597,7 +1577,7 @@ void Game::playerMoveItem(Player* player, const Position& fromPos, return; } - if (!g_events->eventPlayerOnMoveItem(player, item, count, fromPos, toPos, fromCylinder, toCylinder)) { + if (!g_events().eventPlayerOnMoveItem(player, item, count, fromPos, toPos, fromCylinder, toCylinder)) { return; } @@ -1629,7 +1609,7 @@ void Game::playerMoveItem(Player* player, const Position& fromPos, } player->cancelPush(); - g_events->eventPlayerOnItemMoved(player, item, count, fromPos, toPos, fromCylinder, toCylinder); + g_events().eventPlayerOnItemMoved(player, item, count, fromPos, toPos, fromCylinder, toCylinder); } ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, @@ -2811,7 +2791,7 @@ void Game::playerCreatePrivateChannel(uint32_t playerId) return; } - ChatChannel* channel = g_chat->createChannel(*player, CHANNEL_PRIVATE); + ChatChannel* channel = g_chat().createChannel(*player, CHANNEL_PRIVATE); if (!channel || !channel->addUser(*player)) { return; } @@ -2826,7 +2806,7 @@ void Game::playerChannelInvite(uint32_t playerId, const std::string& name) return; } - PrivateChatChannel* channel = g_chat->getPrivateChannel(*player); + PrivateChatChannel* channel = g_chat().getPrivateChannel(*player); if (!channel) { return; } @@ -2850,7 +2830,7 @@ void Game::playerChannelExclude(uint32_t playerId, const std::string& name) return; } - PrivateChatChannel* channel = g_chat->getPrivateChannel(*player); + PrivateChatChannel* channel = g_chat().getPrivateChannel(*player); if (!channel) { return; } @@ -2884,7 +2864,7 @@ void Game::playerOpenChannel(uint32_t playerId, uint16_t channelId) return; } - ChatChannel* channel = g_chat->addUserToChannel(*player, channelId); + const ChatChannel* channel = g_chat().addUserToChannel(*player, channelId); if (!channel) { return; } @@ -2907,7 +2887,7 @@ void Game::playerCloseChannel(uint32_t playerId, uint16_t channelId) return; } - g_chat->removeUserFromChannel(*player, channelId); + g_chat().removeUserFromChannel(*player, channelId); } void Game::playerOpenPrivateChannel(uint32_t playerId, std::string& receiver) @@ -3014,9 +2994,9 @@ void Game::playerUseItemEx(uint32_t playerId, const Position& fromPos, uint8_t f } Position walkToPos = fromPos; - ReturnValue ret = g_actions->canUse(player, fromPos); + ReturnValue ret = g_actions().canUse(player, fromPos); if (ret == RETURNVALUE_NOERROR) { - ret = g_actions->canUse(player, toPos, item); + ret = g_actions().canUse(player, toPos, item); if (ret == RETURNVALUE_TOOFARAWAY) { walkToPos = toPos; } @@ -3051,7 +3031,7 @@ void Game::playerUseItemEx(uint32_t playerId, const Position& fromPos, uint8_t f std::forward_list listDir; if (player->getPathTo(walkToPos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerUseItemEx, this, @@ -3099,7 +3079,7 @@ void Game::playerUseItemEx(uint32_t playerId, const Position& fromPos, uint8_t f player->setNextActionTask(nullptr); } - g_actions->useItemEx(player, fromPos, toPos, toStackPos, item, isHotkey); + g_actions().useItemEx(player, fromPos, toPos, toStackPos, item, isHotkey); } void Game::playerUseItem(uint32_t playerId, const Position& pos, uint8_t stackPos, @@ -3135,12 +3115,12 @@ void Game::playerUseItem(uint32_t playerId, const Position& pos, uint8_t stackPo } } - ReturnValue ret = g_actions->canUse(player, pos); + ReturnValue ret = g_actions().canUse(player, pos); if (ret != RETURNVALUE_NOERROR) { if (ret == RETURNVALUE_TOOFARAWAY) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, @@ -3184,7 +3164,7 @@ void Game::playerUseItem(uint32_t playerId, const Position& pos, uint8_t stackPo player->resetIdleTime(); player->setNextActionTask(nullptr); - g_actions->useItem(player, pos, index, item, isHotkey); + g_actions().useItem(player, pos, index, item, isHotkey); } void Game::playerUseWithCreature(uint32_t playerId, const Position& fromPos, uint8_t fromStackPos, uint32_t creatureId, uint16_t spriteId) @@ -3232,9 +3212,9 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position& fromPos, uin } Position toPos = creature->getPosition(); Position walkToPos = fromPos; - ReturnValue ret = g_actions->canUse(player, fromPos); + ReturnValue ret = g_actions().canUse(player, fromPos); if (ret == RETURNVALUE_NOERROR) { - ret = g_actions->canUse(player, toPos, item); + ret = g_actions().canUse(player, toPos, item); if (ret == RETURNVALUE_TOOFARAWAY) { walkToPos = toPos; } @@ -3259,7 +3239,7 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position& fromPos, uin std::forward_list listDir; if (player->getPathTo(walkToPos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, @@ -3309,7 +3289,7 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position& fromPos, uin player->setNextActionTask(nullptr); } - g_actions->useItemEx(player, fromPos, creature->getPosition(), creature->getParent()->getThingIndex(creature), item, isHotkey, creature); + g_actions().useItemEx(player, fromPos, creature->getPosition(), creature->getParent()->getThingIndex(creature), item, isHotkey, creature); } void Game::playerCloseContainer(uint32_t playerId, uint8_t cid) @@ -3342,7 +3322,7 @@ void Game::playerMoveUpContainer(uint32_t playerId, uint8_t cid) return; } - if (!g_events->eventPlayerOnBrowseField(player, tile->getPosition())) { + if (!g_events().eventPlayerOnBrowseField(player, tile->getPosition())) { return; } @@ -3351,7 +3331,7 @@ void Game::playerMoveUpContainer(uint32_t playerId, uint8_t cid) parentContainer = new Container(tile); parentContainer->incrementReferenceCounter(); browseFields[tile] = parentContainer; - g_scheduler.addEvent(createSchedulerTask(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()))); + g_scheduler().addEvent(createSchedulerTask(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()))); } else { parentContainer = it->second; } @@ -3405,7 +3385,7 @@ void Game::playerRotateItem(uint32_t playerId, const Position& pos, uint8_t stac if (pos.x != 0xFFFF && !Position::areInRange<1, 1, 0>(pos, player->getPosition())) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerRotateItem, this, @@ -3444,7 +3424,7 @@ void Game::playerConfigureShowOffSocket(uint32_t playerId, const Position& pos, if (!Position::areInRange<1, 1, 0>(pos, player->getPosition())) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, false)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerBrowseField, this, playerId, pos)); @@ -3486,7 +3466,7 @@ void Game::playerSetShowOffSocket(uint32_t playerId, Outfit_t& outfit, const Pos if (!Position::areInRange<1, 1, 0>(pos, player->getPosition())) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, false)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerBrowseField, this, playerId, pos)); @@ -3581,7 +3561,7 @@ void Game::playerWrapableItem(uint32_t playerId, const Position& pos, uint8_t st if (pos.x != 0xFFFF && !Position::areInRange<1, 1, 0>(pos, player->getPosition())) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerWrapableItem, this, @@ -3727,7 +3707,7 @@ void Game::playerBrowseField(uint32_t playerId, const Position& pos) if (!Position::areInRange<1, 1>(playerPos, pos)) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerBrowseField, @@ -3744,7 +3724,7 @@ void Game::playerBrowseField(uint32_t playerId, const Position& pos) return; } - if (!g_events->eventPlayerOnBrowseField(player, pos)) { + if (!g_events().eventPlayerOnBrowseField(player, pos)) { return; } @@ -3755,7 +3735,7 @@ void Game::playerBrowseField(uint32_t playerId, const Position& pos) container = new Container(tile); container->incrementReferenceCounter(); browseFields[tile] = container; - g_scheduler.addEvent(createSchedulerTask(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()))); + g_scheduler().addEvent(createSchedulerTask(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()))); } else { container = it->second; } @@ -3965,7 +3945,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position& pos, uint8_t st if (!Position::areInRange<1, 1>(tradeItemPosition, playerPosition)) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerRequestTrade, this, @@ -4019,7 +3999,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position& pos, uint8_t st return; } - if (!g_events->eventPlayerOnTradeRequest(player, tradePartner, tradeItem)) { + if (!g_events().eventPlayerOnTradeRequest(player, tradePartner, tradeItem)) { return; } @@ -4086,7 +4066,7 @@ void Game::playerAcceptTrade(uint32_t playerId) Item* tradeItem1 = player->tradeItem; Item* tradeItem2 = tradePartner->tradeItem; - if (!g_events->eventPlayerOnTradeAccept(player, tradePartner, tradeItem1, tradeItem2)) { + if (!g_events().eventPlayerOnTradeAccept(player, tradePartner, tradeItem1, tradeItem2)) { internalCloseTrade(player); return; } @@ -4221,7 +4201,7 @@ void Game::playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, uint8_t Position::getDistanceX(playerPosition, tradeItemPosition), Position::getDistanceY(playerPosition, tradeItemPosition)); if (index == 0) { - g_events->eventPlayerOnLookInTrade(player, tradePartner, tradeItem, lookDistance); + g_events().eventPlayerOnLookInTrade(player, tradePartner, tradeItem, lookDistance); return; } @@ -4241,7 +4221,7 @@ void Game::playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, uint8_t } if (--index == 0) { - g_events->eventPlayerOnLookInTrade(player, tradePartner, item, lookDistance); + g_events().eventPlayerOnLookInTrade(player, tradePartner, item, lookDistance); return; } } @@ -4396,14 +4376,14 @@ void Game::playerLookInShop(uint32_t playerId, uint16_t spriteId, uint8_t count) return; } - int32_t subType; + uint8_t subType; if (it.isFluidContainer() || it.isSplash()) { subType = clientFluidToServer(count); } else { subType = count; } - if (!g_events->eventPlayerOnLookInShop(player, &it, subType)) { + if (!g_events().eventPlayerOnLookInShop(player, &it, subType)) { return; } @@ -4445,7 +4425,7 @@ void Game::playerLookAt(uint32_t playerId, const Position& pos, uint8_t stackPos } // Parse onLook from event player - g_events->eventPlayerOnLook(player, pos, thing, stackPos, lookDistance); + g_events().eventPlayerOnLook(player, pos, thing, stackPos, lookDistance); } void Game::playerLookInBattleList(uint32_t playerId, uint32_t creatureId) @@ -4480,7 +4460,7 @@ void Game::playerLookInBattleList(uint32_t playerId, uint32_t creatureId) lookDistance = -1; } - g_events->eventPlayerOnLookInBattleList(player, creature, lookDistance); + g_events().eventPlayerOnLookInBattleList(player, creature, lookDistance); } void Game::playerQuickLoot(uint32_t playerId, const Position& pos, uint16_t spriteId, uint8_t stackPos, Item* defaultItem, bool lootAllCorpses, bool autoLoot) @@ -4505,7 +4485,7 @@ void Game::playerQuickLoot(uint32_t playerId, const Position& pos, uint16_t spri //need to walk to the corpse first before looting it std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(0, std::bind( &Game::playerQuickLoot, this, player->getID(), pos, @@ -4603,7 +4583,7 @@ void Game::playerQuickLoot(uint32_t playerId, const Position& pos, uint16_t spri player->lastQuickLootNotification = OTSYS_TIME(); } else { if (corpse->isRewardCorpse()) { - g_actions->useItem(player, pos, 0, corpse, false); + g_actions().useItem(player, pos, 0, corpse, false); } else { if (!lootAllCorpses) { internalQuickLootCorpse(player, corpse); @@ -4839,7 +4819,7 @@ void Game::playerSetAttackedCreature(uint32_t playerId, uint32_t creatureId) } player->setAttackedCreature(attackCreature); - g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, this, player->getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, this, player->getID()))); } void Game::playerFollowCreature(uint32_t playerId, uint32_t creatureId) @@ -4850,7 +4830,7 @@ void Game::playerFollowCreature(uint32_t playerId, uint32_t creatureId) } player->setAttackedCreature(nullptr); - g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, this, player->getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, this, player->getID()))); player->setFollowCreature(getCreatureByID(creatureId)); } @@ -4927,7 +4907,7 @@ void Game::playerRequestEditVip(uint32_t playerId, uint32_t guid, const std::str player->editVIP(guid, description, icon, notify); } -void Game::playerApplyImbuement(uint32_t playerId, uint32_t imbuementid, uint8_t slot, bool protectionCharm) +void Game::playerApplyImbuement(uint32_t playerId, uint16_t imbuementid, uint8_t slot, bool protectionCharm) { Player* player = getPlayerByID(playerId); if (!player) { @@ -4938,7 +4918,7 @@ void Game::playerApplyImbuement(uint32_t playerId, uint32_t imbuementid, uint8_t return; } - Imbuement* imbuement = g_imbuements->getImbuement(imbuementid); + Imbuement* imbuement = g_imbuements().getImbuement(imbuementid); if (!imbuement) { return; } @@ -4998,7 +4978,7 @@ void Game::playerTurn(uint32_t playerId, Direction dir) return; } - if (!g_events->eventPlayerOnTurn(player, dir)) { + if (!g_events().eventPlayerOnTurn(player, dir)) { return; } @@ -5089,7 +5069,7 @@ void Game::playerShowQuestLog(uint32_t playerId) return; } - g_events->eventPlayerOnRequestQuestLog(player); + g_events().eventPlayerOnRequestQuestLog(player); } void Game::playerShowQuestLine(uint32_t playerId, uint16_t questId) @@ -5099,7 +5079,7 @@ void Game::playerShowQuestLine(uint32_t playerId, uint16_t questId) return; } - g_events->eventPlayerOnRequestQuestLine(player, questId); + g_events().eventPlayerOnRequestQuestLine(player, questId); } void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type, @@ -5154,7 +5134,7 @@ void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type, case TALKTYPE_CHANNEL_O: case TALKTYPE_CHANNEL_Y: case TALKTYPE_CHANNEL_R1: - g_chat->talkToChannel(*player, type, text, channelId); + g_chat().talkToChannel(*player, type, text, channelId); break; case TALKTYPE_PRIVATE_PN: @@ -5177,12 +5157,12 @@ bool Game::playerSaySpell(Player* player, SpeakClasses type, const std::string& } std::string words = text; - TalkActionResult_t result = g_talkActions->playerSaySpell(player, type, words); + TalkActionResult_t result = g_talkActions().playerSaySpell(player, type, words); if (result == TALKACTION_BREAK) { return true; } - result = g_spells->playerSaySpell(player, words); + result = g_spells().playerSaySpell(player, words); if (result == TALKACTION_BREAK) { if (!g_configManager().getBoolean(PUSH_WHEN_ATTACKING)) { player->cancelPush(); @@ -5363,7 +5343,7 @@ bool Game::internalCreatureSay(Creature* creature, SpeakClasses type, const std: for (Creature* spectator : spectators) { spectator->onCreatureSay(creature, type, text); if (creature != spectator) { - g_events->eventCreatureOnHear(spectator, creature, text, type); + g_events().eventCreatureOnHear(spectator, creature, text, type); } } return true; @@ -5417,7 +5397,7 @@ void Game::removeCreatureCheck(Creature* creature) void Game::checkCreatures(size_t index) { - g_scheduler.addEvent(createSchedulerTask(EVENT_CHECK_CREATURE_INTERVAL, std::bind(&Game::checkCreatures, this, (index + 1) % EVENT_CREATURECOUNT))); + g_scheduler().addEvent(createSchedulerTask(EVENT_CHECK_CREATURE_INTERVAL, std::bind(&Game::checkCreatures, this, (index + 1) % EVENT_CREATURECOUNT))); auto& checkCreatureList = checkCreatureLists[index]; size_t it = 0, end = checkCreatureList.size(); @@ -5461,7 +5441,7 @@ void Game::changeSpeed(Creature* creature, int32_t varSpeedDelta) void Game::internalCreatureChangeOutfit(Creature* creature, const Outfit_t& outfit) { - if (!g_events->eventCreatureOnChangeOutfit(creature, outfit)) { + if (!g_events().eventCreatureOnChangeOutfit(creature, outfit)) { return; } @@ -5868,7 +5848,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage message.position = targetPos; if (!isEvent) { - g_events->eventCreatureOnDrainHealth(target, attacker, damage.primary.type, damage.primary.value, damage.secondary.type, damage.secondary.value, message.primary.color, message.secondary.color); + g_events().eventCreatureOnDrainHealth(target, attacker, damage.primary.type, damage.primary.value, damage.secondary.type, damage.secondary.value, message.primary.color, message.secondary.color); } if (damage.origin != ORIGIN_NONE && attacker && damage.primary.type != COMBAT_HEALING) { damage.primary.value *= attacker->getBuff(BUFF_DAMAGEDEALT) / 100.; @@ -5892,7 +5872,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage if (!damage.extension && attacker && attacker->getMonster() && targetPlayer) { // Charm rune (target as player) - MonsterType* mType = g_monsters.getMonsterType(attacker->getName()); + MonsterType* mType = g_monsters().getMonsterType(attacker->getName()); if (mType) { IOBestiary g_bestiary; charmRune_t activeCharm = g_bestiary.getCharmFromTarget(targetPlayer, mType); @@ -6071,7 +6051,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage if (target && target->getMonster()) { uint16_t playerCharmRaceidVamp = attackerPlayer->parseRacebyCharm(CHARM_VAMP, false, 0); if (playerCharmRaceidVamp != 0) { - MonsterType* mType = g_monsters.getMonsterType(target->getName()); + const MonsterType* mType = g_monsters().getMonsterType(target->getName()); if (mType && playerCharmRaceidVamp == mType->info.raceid) { IOBestiary g_bestiary; Charm* lifec = g_bestiary.getBestiaryCharm(CHARM_VAMP); @@ -6100,7 +6080,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage if (target && target->getMonster()) { uint16_t playerCharmRaceidVoid = attackerPlayer->parseRacebyCharm(CHARM_VOID, false, 0); if (playerCharmRaceidVoid != 0) { - MonsterType* mType = g_monsters.getMonsterType(target->getName()); + const MonsterType* mType = g_monsters().getMonsterType(target->getName()); if (mType && playerCharmRaceidVoid == mType->info.raceid) { IOBestiary g_bestiary; Charm* voidc = g_bestiary.getBestiaryCharm(CHARM_VOID); @@ -6123,7 +6103,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage //Charm rune (attacker as player) if (!damage.extension && target && target->getMonster()) { - MonsterType* mType = g_monsters.getMonsterType(target->getName()); + MonsterType* mType = g_monsters().getMonsterType(target->getName()); if (mType) { IOBestiary g_bestiary; charmRune_t activeCharm = g_bestiary.getCharmFromTarget(attackerPlayer, mType); @@ -6392,7 +6372,7 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage& if (targetPlayer && attacker && attacker->getMonster()) { //Charm rune (target as player) - MonsterType* mType = g_monsters.getMonsterType(attacker->getName()); + MonsterType* mType = g_monsters().getMonsterType(attacker->getName()); if (mType) { IOBestiary g_bestiary; charmRune_t activeCharm = g_bestiary.getCharmFromTarget(targetPlayer, mType); @@ -6559,7 +6539,7 @@ void Game::addDistanceEffect(const SpectatorHashSet& spectators, const Position& void Game::checkImbuements() { - g_scheduler.addEvent(createSchedulerTask(EVENT_IMBUEMENT_INTERVAL, std::bind(&Game::checkImbuements, this))); + g_scheduler().addEvent(createSchedulerTask(EVENT_IMBUEMENT_INTERVAL, std::bind(&Game::checkImbuements, this))); std::vector toErase; @@ -6581,7 +6561,7 @@ void Game::checkImbuements() void Game::checkLight() { - g_scheduler.addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL_MS, std::bind(&Game::checkLight, this))); + g_scheduler().addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL_MS, std::bind(&Game::checkLight, this))); lightHour += lightHourDelta; @@ -6637,8 +6617,8 @@ void Game::checkLight() } if (currentLightState != lightState) { currentLightState = lightState; - for (auto& it : g_globalEvents->getEventMap(GLOBALEVENT_PERIODCHANGE)) { - it.second.executePeriodChange(lightState, lightInfo); + for (auto& [key, it] : g_globalEvents().getEventMap(GLOBALEVENT_PERIODCHANGE)) { + it.executePeriodChange(lightState, lightInfo); } } } @@ -6672,9 +6652,9 @@ void Game::shutdown() SPDLOG_INFO("Shutting down..."); - g_scheduler.shutdown(); - g_databaseTasks.shutdown(); - g_dispatcher.shutdown(); + g_scheduler().shutdown(); + g_databaseTasks().shutdown(); + g_dispatcher().shutdown(); map.spawnsMonster.clear(); map.spawnsNpc.clear(); raids.clear(); @@ -6889,8 +6869,8 @@ void Game::checkPlayersRecord() uint32_t previousRecord = playersRecord; playersRecord = playersOnline; - for (auto& it : g_globalEvents->getEventMap(GLOBALEVENT_RECORD)) { - it.second.executeRecord(playersRecord, previousRecord); + for (auto& [key, it] : g_globalEvents().getEventMap(GLOBALEVENT_RECORD)) { + it.executeRecord(playersRecord, previousRecord); } updatePlayersRecord(); } @@ -7140,7 +7120,7 @@ void Game::playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, C } while (result->next()); player->sendCyclopediaCharacterRecentDeaths(page, static_cast(pages), entries); }; - g_databaseTasks.addTask(std::move(query.str()), callback, true); + g_databaseTasks().addTask(query.str(), callback, true); player->addAsyncOngoingTask(PlayerAsyncTask_RecentDeaths); break; } @@ -7193,7 +7173,7 @@ void Game::playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, C } while (result->next()); player->sendCyclopediaCharacterRecentPvPKills(page, static_cast(pages), entries); }; - g_databaseTasks.addTask(std::move(query.str()), callback, true); + g_databaseTasks().addTask(query.str(), callback, true); player->addAsyncOngoingTask(PlayerAsyncTask_RecentPvPKills); break; } @@ -7239,7 +7219,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego if (vocation != 0xFFFFFFFF) { bool firstVocation = true; - const auto& vocationsMap = g_vocations.getVocations(); + const auto& vocationsMap = g_vocations().getVocations(); for (const auto& it : vocationsMap) { const Vocation& voc = it.second; if (voc.getFromVocation() == vocation) { @@ -7259,7 +7239,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego if (vocation != 0xFFFFFFFF) { bool firstVocation = true; - const auto& vocationsMap = g_vocations.getVocations(); + const auto& vocationsMap = g_vocations().getVocations(); for (const auto& it : vocationsMap) { const Vocation& voc = it.second; if (voc.getFromVocation() == vocation) { @@ -7297,7 +7277,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego characters.reserve(result->countResults()); do { uint8_t characterVocation; - Vocation* voc = g_vocations.getVocation(result->getNumber("vocation")); + const Vocation* voc = g_vocations().getVocation(result->getNumber("vocation")); if (voc) { characterVocation = voc->getClientId(); } else { @@ -7307,7 +7287,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego } while (result->next()); player->sendHighscores(characters, category, vocation, page, static_cast(pages)); }; - g_databaseTasks.addTask(std::move(query.str()), callback, true); + g_databaseTasks().addTask(query.str(), callback, true); player->addAsyncOngoingTask(PlayerAsyncTask_Highscore); } @@ -7327,7 +7307,7 @@ void Game::playerReportRuleViolationReport(uint32_t playerId, const std::string& return; } - g_events->eventPlayerOnReportRuleViolation(player, targetName, reportType, reportReason, comment, translation); + g_events().eventPlayerOnReportRuleViolation(player, targetName, reportType, reportReason, comment, translation); } void Game::playerReportBug(uint32_t playerId, const std::string& message, const Position& position, uint8_t category) @@ -7337,7 +7317,7 @@ void Game::playerReportBug(uint32_t playerId, const std::string& message, const return; } - g_events->eventPlayerOnReportBug(player, message, position, category); + g_events().eventPlayerOnReportBug(player, message, position, category); } void Game::playerDebugAssert(uint32_t playerId, const std::string& assertLine, const std::string& date, const std::string& description, const std::string& comment) @@ -8117,11 +8097,11 @@ void Game::playerBuyStoreOffer(uint32_t playerId, uint32_t offerId, // check if it's an NPC or Monster name. - if (g_monsters.getMonsterType(newName)) { + if (g_monsters().getMonsterType(newName)) { responseMessage = "Your new name cannot be a monster's name."; player -> sendStoreError(STORE_ERROR_PURCHASE, responseMessage); return; - } else if (g_npcs.getNpcType(newName)) { + } else if (g_npcs().getNpcType(newName)) { responseMessage = "Your new name cannot be an NPC's name."; player -> sendStoreError(STORE_ERROR_PURCHASE, responseMessage); return; @@ -8185,7 +8165,7 @@ void Game::playerBuyStoreOffer(uint32_t playerId, uint32_t offerId, return; } else if (offer -> type == PROMOTION) { if (player -> isPremium() && !player -> isPromoted()) { - uint16_t promotedId = g_vocations.getPromotedVocation(player -> getVocation() -> getId()); + uint16_t promotedId = g_vocations().getPromotedVocation(player -> getVocation() -> getId()); if (promotedId == VOCATION_NONE || promotedId == player -> getVocation() -> getId()) { player -> sendStoreError(STORE_ERROR_PURCHASE, "Your character cannot be promoted."); @@ -8613,44 +8593,44 @@ bool Game::reload(ReloadTypes_t reloadType) { switch (reloadType) { case RELOAD_TYPE_MONSTERS: { - g_scripts->loadScripts("monster", false, true); + g_scripts().loadScripts("monster", false, true); return true; } case RELOAD_TYPE_NPCS: { // Reset informations from npc interface g_npc().reset(); // Reload npc scripts - g_scripts->loadScripts("npc", false, true); + g_scripts().loadScripts("npc", false, true); // Reload npclib g_luaEnvironment.loadFile("data/npclib/load.lua"); return true; } - case RELOAD_TYPE_CHAT: return g_chat->load(); + case RELOAD_TYPE_CHAT: return g_chat().load(); case RELOAD_TYPE_CONFIG: return g_configManager().reload(); - case RELOAD_TYPE_EVENTS: return g_events->loadFromXml(); + case RELOAD_TYPE_EVENTS: return g_events().loadFromXml(); case RELOAD_TYPE_ITEMS: return Item::items.reload(); - case RELOAD_TYPE_MODULES: return g_modules->reload(); + case RELOAD_TYPE_MODULES: return g_modules().reload(); case RELOAD_TYPE_MOUNTS: return mounts.reload(); - case RELOAD_TYPE_IMBUEMENTS: return g_imbuements->reload(); + case RELOAD_TYPE_IMBUEMENTS: return g_imbuements().reload(); case RELOAD_TYPE_RAIDS: return raids.reload() && raids.startup(); case RELOAD_TYPE_SCRIPTS: { // commented out stuff is TODO, once we approach further in revscriptsys - g_actions->clear(true); - g_creatureEvents->clear(true); - g_moveEvents->clear(true); - g_talkActions->clear(true); - g_globalEvents->clear(true); - g_weapons->clear(true); - g_weapons->loadDefaults(); - g_spells->clear(true); + g_actions().clear(true); + g_creatureEvents().clear(true); + g_moveEvents().clear(true); + g_talkActions().clear(true); + g_globalEvents().clear(true); + g_weapons().clear(true); + g_weapons().loadDefaults(); + g_spells().clear(true); // Reset informations from npc interface g_npc().reset(); - g_scripts->loadScripts("scripts", false, true); + g_scripts().loadScripts("scripts", false, true); // lean up the monsters interface, ensuring that after reloading the scripts there is no use of any deallocated memory - g_scripts->loadScripts("monster", false, true); + g_scripts().loadScripts("monster", false, true); // Reload npc scripts - g_scripts->loadScripts("npc", false, true); + g_scripts().loadScripts("npc", false, true); // Reload npclib g_luaEnvironment.loadFile("data/npclib/load.lua"); return true; @@ -8661,18 +8641,18 @@ bool Game::reload(ReloadTypes_t reloadType) g_configManager().reload(); raids.reload() && raids.startup(); Item::items.reload(); - g_weapons->clear(true); - g_weapons->loadDefaults(); + g_weapons().clear(true); + g_weapons().loadDefaults(); mounts.reload(); - g_events->loadFromXml(); - g_chat->load(); - g_actions->clear(true); - g_creatureEvents->clear(true); - g_moveEvents->clear(true); - g_talkActions->clear(true); - g_globalEvents->clear(true); - g_spells->clear(true); - g_scripts->loadScripts("scripts", false, true); + g_events().loadFromXml(); + g_chat().load(); + g_actions().clear(true); + g_creatureEvents().clear(true); + g_moveEvents().clear(true); + g_talkActions().clear(true); + g_globalEvents().clear(true); + g_spells().clear(true); + g_scripts().loadScripts("scripts", false, true); } } return true; @@ -8680,7 +8660,7 @@ bool Game::reload(ReloadTypes_t reloadType) bool Game::itemidHasMoveevent(uint32_t itemid) { - return g_moveEvents->isRegistered(itemid); + return g_moveEvents().isRegistered(itemid); } bool Game::hasEffect(uint8_t effectId) { diff --git a/src/game/game.h b/src/game/game.h index 01f470d2f1f..b49a20f7df6 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -340,7 +340,7 @@ class Game void playerRequestAddVip(uint32_t playerId, const std::string& name); void playerRequestRemoveVip(uint32_t playerId, uint32_t guid); void playerRequestEditVip(uint32_t playerId, uint32_t guid, const std::string& description, uint32_t icon, bool notify); - void playerApplyImbuement(uint32_t playerId, uint32_t imbuementid, uint8_t slot, bool protectionCharm); + void playerApplyImbuement(uint32_t playerId, uint16_t imbuementid, uint8_t slot, bool protectionCharm); void playerClearImbuement(uint32_t playerid, uint8_t slot); void playerCloseImbuementWindow(uint32_t playerid); void playerTurn(uint32_t playerId, Direction dir); diff --git a/src/game/scheduling/scheduler.cpp b/src/game/scheduling/scheduler.cpp index 6d1467fb103..7687070dc5e 100644 --- a/src/game/scheduling/scheduler.cpp +++ b/src/game/scheduling/scheduler.cpp @@ -51,7 +51,7 @@ void Scheduler::threadMain() eventLockUnique.unlock(); task->setDontExpire(); - g_dispatcher.addTask(task, true); + g_dispatcher().addTask(task, true); } else { eventLockUnique.unlock(); } diff --git a/src/game/scheduling/scheduler.h b/src/game/scheduling/scheduler.h index 89ec6183c8b..52b7774d4b9 100644 --- a/src/game/scheduling/scheduler.h +++ b/src/game/scheduling/scheduler.h @@ -61,6 +61,18 @@ struct TaskComparator { class Scheduler : public ThreadHolder { public: + Scheduler() = default; + + Scheduler(Scheduler const&) = delete; + void operator=(Scheduler const&) = delete; + + static Scheduler& getInstance() { + // Guaranteed to be destroyed + static Scheduler instance; + // Instantiated on first use + return instance; + } + uint32_t addEvent(SchedulerTask* task); bool stopEvent(uint32_t eventId); @@ -78,6 +90,6 @@ class Scheduler : public ThreadHolder std::unordered_set eventIds; }; -extern Scheduler g_scheduler; +constexpr auto g_scheduler = &Scheduler::getInstance; #endif // SRC_GAME_SCHEDULING_SCHEDULER_H_ diff --git a/src/game/scheduling/tasks.h b/src/game/scheduling/tasks.h index da424e00560..0a62e9d4398 100644 --- a/src/game/scheduling/tasks.h +++ b/src/game/scheduling/tasks.h @@ -67,6 +67,18 @@ Task* createTask(uint32_t expiration, std::function f); class Dispatcher : public ThreadHolder { public: + Dispatcher() = default; + + Dispatcher(Dispatcher const&) = delete; + void operator=(Dispatcher const&) = delete; + + static Dispatcher& getInstance() { + // Guaranteed to be destroyed + static Dispatcher instance; + // Instantiated on first use + return instance; + } + void addTask(Task* task, bool push_front = false); void shutdown(); @@ -85,6 +97,6 @@ class Dispatcher : public ThreadHolder { uint64_t dispatcherCycle = 0; }; -extern Dispatcher g_dispatcher; +constexpr auto g_dispatcher = &Dispatcher::getInstance; #endif // SRC_GAME_SCHEDULING_TASKS_H_ diff --git a/src/io/iobestiary.cpp b/src/io/iobestiary.cpp index 782da99462b..5f3971d8d9e 100644 --- a/src/io/iobestiary.cpp +++ b/src/io/iobestiary.cpp @@ -26,7 +26,6 @@ #include "creatures/monsters/monsters.h" #include "creatures/players/player.h" -extern Monsters g_monsters; bool IOBestiary::parseCharmCombat(Charm* charm, Player* player, Creature* target, int32_t realDamage) { @@ -127,14 +126,14 @@ std::map IOBestiary::findRaceByName(const std::string &ra if (Onlystring) { for (auto it : best_list) { - MonsterType* tmpType = g_monsters.getMonsterType(it.second); + const MonsterType* tmpType = g_monsters().getMonsterType(it.second); if (tmpType && tmpType->info.bestiaryClass == race) { race_list.insert({it.first, it.second}); } } } else { for (auto itn : best_list) { - MonsterType* tmpType = g_monsters.getMonsterType(itn.second); + const MonsterType* tmpType = g_monsters().getMonsterType(itn.second); if (tmpType && tmpType->info.bestiaryRace == raceNumber) { race_list.insert({itn.first, itn.second}); } @@ -203,7 +202,7 @@ uint16_t IOBestiary::getBestiaryRaceUnlocked(Player* player, BestiaryType_t race std::map besty_l = g_game().getBestiaryList(); for (auto it : besty_l) { - MonsterType* mtype = g_monsters.getMonsterType(it.second); + const MonsterType* mtype = g_monsters().getMonsterType(it.second); if (mtype && mtype->info.bestiaryRace == race && player->getBestiaryKillCount(mtype->info.raceid) > 0) { count++; } @@ -427,7 +426,7 @@ std::list IOBestiary::getBestiaryFinished(Player* player) const for (auto nt : besty_l) { uint16_t raceid = nt.first; uint32_t thisKilled = player->getBestiaryKillCount(raceid); - MonsterType* mtype = g_monsters.getMonsterType(nt.second); + const MonsterType* mtype = g_monsters().getMonsterType(nt.second); if (mtype && thisKilled >= mtype->info.bestiaryToUnlock) { finishedMonsters.push_front(raceid); } diff --git a/src/io/iologindata.cpp b/src/io/iologindata.cpp index ef5901207f0..12302efe0cd 100644 --- a/src/io/iologindata.cpp +++ b/src/io/iologindata.cpp @@ -27,7 +27,6 @@ #include -extern Monsters g_monsters; bool IOLoginData::authenticateAccountPassword(const std::string& email, const std::string& password, account::Account *account) { if (account::ERROR_NO != account->LoadAccountDB(email)) { @@ -523,7 +522,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) uint16_t raceid_t; while (propBestStream.read(raceid_t)) { - MonsterType* tmp_tt = g_monsters.getMonsterTypeByRaceId(raceid_t); + MonsterType* tmp_tt = g_monsters().getMonsterTypeByRaceId(raceid_t); if (tmp_tt) { player->addBestiaryTrackerList(tmp_tt); } diff --git a/src/io/iomarket.cpp b/src/io/iomarket.cpp index 822beac17d7..d8b3b1782ec 100644 --- a/src/io/iomarket.cpp +++ b/src/io/iomarket.cpp @@ -193,14 +193,14 @@ void IOMarket::checkExpiredOffers() std::ostringstream query; query << "SELECT `id`, `amount`, `price`, `itemtype`, `player_id`, `sale` FROM `market_offers` WHERE `created` <= " << lastExpireDate; - g_databaseTasks.addTask(query.str(), IOMarket::processExpiredOffers, true); + g_databaseTasks().addTask(query.str(), IOMarket::processExpiredOffers, true); int32_t checkExpiredMarketOffersEachMinutes = g_configManager().getNumber(CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES); if (checkExpiredMarketOffersEachMinutes <= 0) { return; } - g_scheduler.addEvent(createSchedulerTask(checkExpiredMarketOffersEachMinutes * 60 * 1000, IOMarket::checkExpiredOffers)); + g_scheduler().addEvent(createSchedulerTask(checkExpiredMarketOffersEachMinutes * 60 * 1000, IOMarket::checkExpiredOffers)); } uint32_t IOMarket::getPlayerOfferCount(uint32_t playerId) @@ -273,7 +273,7 @@ void IOMarket::appendHistory(uint32_t playerId, MarketAction_t type, uint16_t it query << "INSERT INTO `market_history` (`player_id`, `sale`, `itemtype`, `amount`, `price`, `expires_at`, `inserted`, `state`) VALUES (" << playerId << ',' << type << ',' << itemId << ',' << amount << ',' << price << ',' << timestamp << ',' << time(nullptr) << ',' << state << ')'; - g_databaseTasks.addTask(query.str()); + g_databaseTasks().addTask(query.str()); } bool IOMarket::moveOfferToHistory(uint32_t offerId, MarketOfferState_t state) diff --git a/src/items/bed.cpp b/src/items/bed.cpp index 177f36f1a88..020f91b4b6d 100644 --- a/src/items/bed.cpp +++ b/src/items/bed.cpp @@ -162,7 +162,7 @@ bool BedItem::sleep(Player* player) g_game().addMagicEffect(player->getPosition(), CONST_ME_SLEEP); // logout player after he sees himself walk onto the bed and it change id - g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&ProtocolGame::logout, player->client, false, false))); + g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&ProtocolGame::logout, player->client, false, false))); // change self and partner's appearance updateAppearance(player); diff --git a/src/items/containers/container.cpp b/src/items/containers/container.cpp index 6b37b7a4ad8..5ea4cf108b0 100644 --- a/src/items/containers/container.cpp +++ b/src/items/containers/container.cpp @@ -682,9 +682,9 @@ void Container::removeThing(Thing* thing, uint32_t count) } } -int32_t Container::getThingIndex(const Thing* thing) const +uint8_t Container::getThingIndex(const Thing* thing) const { - int32_t index = 0; + uint8_t index = 0; for (Item* item : itemlist) { if (item == thing) { return index; @@ -792,17 +792,17 @@ void Container::internalAddThing(uint32_t, Thing* thing) void Container::startDecaying() { - g_decay.startDecay(this); + g_decay().startDecay(this); for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { - g_decay.startDecay(*it); + g_decay().startDecay(*it); } } void Container::stopDecaying() { - g_decay.stopDecay(this); + g_decay().stopDecay(this); for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { - g_decay.stopDecay(*it); + g_decay().stopDecay(*it); } } diff --git a/src/items/containers/container.h b/src/items/containers/container.h index 59e573dcd8c..eec9268ef1d 100644 --- a/src/items/containers/container.h +++ b/src/items/containers/container.h @@ -155,7 +155,7 @@ class Container : public Item, public Cylinder void removeThing(Thing* thing, uint32_t count) override final; - int32_t getThingIndex(const Thing* thing) const override final; + uint8_t getThingIndex(const Thing* thing) const override final; size_t getFirstIndex() const override final; size_t getLastIndex() const override final; uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const override final; diff --git a/src/items/cylinder.cpp b/src/items/cylinder.cpp index 0081a1e141c..f759a242597 100644 --- a/src/items/cylinder.cpp +++ b/src/items/cylinder.cpp @@ -23,7 +23,7 @@ VirtualCylinder* VirtualCylinder::virtualCylinder = new VirtualCylinder; -int32_t Cylinder::getThingIndex(const Thing*) const +uint8_t Cylinder::getThingIndex(const Thing*) const { return -1; } diff --git a/src/items/cylinder.h b/src/items/cylinder.h index 280a928477f..9fe81236dda 100644 --- a/src/items/cylinder.h +++ b/src/items/cylinder.h @@ -136,7 +136,7 @@ class Cylinder : virtual public Thing * \param thing the object to get the index value from * \returns the index of the object, returns -1 if not found */ - virtual int32_t getThingIndex(const Thing* thing) const; + virtual uint8_t getThingIndex(const Thing* thing) const; /** * Returns the first index diff --git a/src/items/decay/decay.cpp b/src/items/decay/decay.cpp index 70f6126413b..cdee82f1ab1 100644 --- a/src/items/decay/decay.cpp +++ b/src/items/decay/decay.cpp @@ -23,7 +23,6 @@ #include "game/game.h" #include "game/scheduling/scheduler.h" -Decay g_decay; void Decay::startDecay(Item* item) { @@ -41,7 +40,7 @@ void Decay::startDecay(Item* item) return; } - int64_t duration = item->getIntAttr(ITEM_ATTRIBUTE_DURATION); + const int64_t duration = item->getIntAttr(ITEM_ATTRIBUTE_DURATION); if (duration <= 0 && item->hasAttribute(ITEM_ATTRIBUTE_DURATION)) { internalDecayItem(item); return; @@ -52,13 +51,13 @@ void Decay::startDecay(Item* item) stopDecay(item); } - int64_t timestamp = OTSYS_TIME() + static_cast(duration); + int64_t timestamp = OTSYS_TIME() + duration; if (decayMap.empty()) { - eventId = g_scheduler.addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, duration), std::bind(&Decay::checkDecay, this))); + eventId = g_scheduler().addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, duration), std::bind(&Decay::checkDecay, this))); } else { if (timestamp < decayMap.begin()->first) { - g_scheduler.stopEvent(eventId); - eventId = g_scheduler.addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, duration), std::bind(&Decay::checkDecay, this))); + g_scheduler().stopEvent(eventId); + eventId = g_scheduler().addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, duration), std::bind(&Decay::checkDecay, this))); } } @@ -147,7 +146,7 @@ void Decay::checkDecay() } if (it != end) { - eventId = g_scheduler.addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, static_cast(it->first - timestamp)), std::bind(&Decay::checkDecay, this))); + eventId = g_scheduler().addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, static_cast(it->first - timestamp)), std::bind(&Decay::checkDecay, this))); } } diff --git a/src/items/decay/decay.h b/src/items/decay/decay.h index cdcbcd0ebc2..f0d7c88c9ce 100644 --- a/src/items/decay/decay.h +++ b/src/items/decay/decay.h @@ -25,17 +25,29 @@ class Decay { public: + Decay(Decay const&) = delete; + void operator=(Decay const&) = delete; + + static Decay& getInstance() { + // Guaranteed to be destroyed + static Decay instance; + // Instantiated on first use + return instance; + } + void startDecay(Item* item); void stopDecay(Item* item); private: + Decay() = default; + void checkDecay(); void internalDecayItem(Item* item); - uint64_t eventId {0}; + uint32_t eventId {0}; std::map> decayMap; }; -extern Decay g_decay; +constexpr auto g_decay = &Decay::getInstance; #endif // SRC_ITEMS_DECAY_DECAY_H_ diff --git a/src/items/item.cpp b/src/items/item.cpp index 6401907ca98..bdb6cfee6a9 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -37,9 +37,6 @@ #define IMBUEMENT_SLOT 500 -extern Spells* g_spells; -extern Vocations g_vocations; -extern Imbuements* g_imbuements; Items Item::items; @@ -94,7 +91,7 @@ bool Item::getImbuementInfo(uint8_t slot, ImbuementInfo *imbuementInfo) { const ItemAttributes::CustomAttribute* attribute = getCustomAttribute(IMBUEMENT_SLOT + slot); uint32_t info = attribute ? static_cast(attribute->getInt()) : 0; - imbuementInfo->imbuement = g_imbuements->getImbuement(info & 0xFF); + imbuementInfo->imbuement = g_imbuements().getImbuement(info & 0xFF); imbuementInfo->duration = info >> 8; return imbuementInfo->duration && imbuementInfo->imbuement; } @@ -115,13 +112,13 @@ void Item::addImbuement(uint8_t slot, uint16_t imbuementId, int32_t duration) } // Get imbuement by the id - const Imbuement *imbuement = g_imbuements->getImbuement(imbuementId); + const Imbuement *imbuement = g_imbuements().getImbuement(imbuementId); if (!imbuement) { return; } // Get category imbuement for acess category id - const CategoryImbuement* categoryImbuement = g_imbuements->getCategoryByID(imbuement->getCategory()); + const CategoryImbuement* categoryImbuement = g_imbuements().getCategoryByID(imbuement->getCategory()); if (!hasImbuementType(static_cast(categoryImbuement->id), imbuement->getBaseID())) { return; } @@ -140,7 +137,7 @@ bool Item::hasImbuementCategoryId(uint16_t categoryId) { for (uint8_t slotid = 0; slotid < getImbuementSlot(); slotid++) { ImbuementInfo imbuementInfo; if (getImbuementInfo(slotid, &imbuementInfo)) { - const CategoryImbuement* categoryImbuement = g_imbuements->getCategoryByID(imbuementInfo.imbuement->getCategory()); + const CategoryImbuement* categoryImbuement = g_imbuements().getCategoryByID(imbuementInfo.imbuement->getCategory()); if (categoryImbuement->id == categoryId) { return true; } @@ -1479,7 +1476,7 @@ std::string Item::parseImbuementDescription(const Item* item) continue; } - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuementInfo.imbuement->getBaseID()); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuementInfo.imbuement->getBaseID()); if (!baseImbuement) { continue; @@ -1513,7 +1510,7 @@ std::string Item::getDescription(const ItemType& it, int32_t lookDistance, if (it.isRune()) { if (it.runeLevel > 0 || it.runeMagLevel > 0) { - if (RuneSpell* rune = g_spells->getRuneSpell(it.id)) { + if (const RuneSpell* rune = g_spells().getRuneSpell(it.id)) { int32_t tmpSubType = subType; if (item) { tmpSubType = item->getSubType(); @@ -1528,7 +1525,7 @@ std::string Item::getDescription(const ItemType& it, int32_t lookDistance, showVocMap.reserve(vocMap.size() / 2); for (const auto& voc : vocMap) { if (voc.second) { - showVocMap.push_back(g_vocations.getVocation(voc.first)); + showVocMap.push_back(g_vocations().getVocation(voc.first)); } } @@ -2559,12 +2556,12 @@ ItemAttributes::Attribute& ItemAttributes::getAttr(ItemAttrTypes type) void Item::startDecaying() { - g_decay.startDecay(this); + g_decay().startDecay(this); } void Item::stopDecaying() { - g_decay.stopDecay(this); + g_decay().stopDecay(this); } bool Item::hasMarketAttributes() diff --git a/src/items/items.cpp b/src/items/items.cpp index 07332658a58..7f12c28e300 100644 --- a/src/items/items.cpp +++ b/src/items/items.cpp @@ -34,7 +34,6 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; #endif -extern Weapons* g_weapons; Items::Items(){} @@ -93,7 +92,7 @@ bool Items::reload() return false; } - g_weapons->loadDefaults(); + g_weapons().loadDefaults(); return true; } diff --git a/src/items/tile.cpp b/src/items/tile.cpp index 0d0a2b99e87..b55ce822eb3 100644 --- a/src/items/tile.cpp +++ b/src/items/tile.cpp @@ -34,7 +34,6 @@ #include "map/house/housetile.h" #include "io/iomap.h" -extern MoveEvents* g_moveEvents; StaticTile real_nullptr_tile(0xFFFF, 0xFFFF, 0xFF); Tile& Tile::nullptr_tile = real_nullptr_tile; @@ -1167,9 +1166,9 @@ void Tile::removeCreature(Creature* creature) removeThing(creature, 0); } -int32_t Tile::getThingIndex(const Thing* thing) const +uint8_t Tile::getThingIndex(const Thing* thing) const { - int32_t n = -1; + uint8_t n = -1; if (ground) { if (ground == thing) { return 0; @@ -1427,9 +1426,9 @@ void Tile::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t //calling movement scripts if (creature) { - g_moveEvents->onCreatureMove(creature, this, MOVE_EVENT_STEP_IN); + g_moveEvents().onCreatureMove(creature, this, MOVE_EVENT_STEP_IN); } else if (item) { - g_moveEvents->onItemMove(item, this, true); + g_moveEvents().onItemMove(item, this, true); } } @@ -1457,11 +1456,11 @@ void Tile::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32 //calling movement scripts Creature* creature = thing->getCreature(); if (creature) { - g_moveEvents->onCreatureMove(creature, this, MOVE_EVENT_STEP_OUT); + g_moveEvents().onCreatureMove(creature, this, MOVE_EVENT_STEP_OUT); } else { Item* item = thing->getItem(); if (item) { - g_moveEvents->onItemMove(item, this, false); + g_moveEvents().onItemMove(item, this, false); } } } diff --git a/src/items/tile.h b/src/items/tile.h index 63a9b2e0849..e903d262c1d 100644 --- a/src/items/tile.h +++ b/src/items/tile.h @@ -221,7 +221,7 @@ class Tile : public Cylinder void removeCreature(Creature* creature); - int32_t getThingIndex(const Thing* thing) const override final; + uint8_t getThingIndex(const Thing* thing) const override final; size_t getFirstIndex() const override final; size_t getLastIndex() const override final; uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const override final; diff --git a/src/items/weapons/weapons.cpp b/src/items/weapons/weapons.cpp index e2176237b02..c2b6fe6b9ed 100644 --- a/src/items/weapons/weapons.cpp +++ b/src/items/weapons/weapons.cpp @@ -25,9 +25,6 @@ #include "lua/creature/events.h" #include "items/weapons/weapons.h" -extern Vocations g_vocations; -extern Weapons* g_weapons; -extern Events* g_events; Weapons::Weapons() { @@ -217,10 +214,10 @@ bool Weapon::configureEvent(const pugi::xml_node& node) continue; } - int32_t vocationId = g_vocations.getVocationId(attr.as_string()); + uint16_t vocationId = g_vocations().getVocationId(attr.as_string()); if (vocationId != -1) { vocWeaponMap[vocationId] = true; - int32_t promotedVocation = g_vocations.getPromotedVocation(vocationId); + int32_t promotedVocation = g_vocations().getPromotedVocation(vocationId); if (promotedVocation != VOCATION_NONE) { vocWeaponMap[promotedVocation] = true; } @@ -702,7 +699,7 @@ bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) con const ItemType& it = Item::items[id]; if (it.weaponType == WEAPON_AMMO) { Item* mainWeaponItem = player->getWeapon(true); - const Weapon* mainWeapon = g_weapons->getWeapon(mainWeaponItem); + const Weapon* mainWeapon = g_weapons().getWeapon(mainWeaponItem); if (mainWeapon) { damageModifier = mainWeapon->playerWeaponCheck(player, target, mainWeaponItem->getShootRange()); } else { diff --git a/src/items/weapons/weapons.h b/src/items/weapons/weapons.h index c5c2d28a51a..fdfa70735b4 100644 --- a/src/items/weapons/weapons.h +++ b/src/items/weapons/weapons.h @@ -27,7 +27,6 @@ #include "utils/utils_definitions.hpp" #include "creatures/players/vocations/vocation.h" -extern Vocations g_vocations; class Weapon; class WeaponMelee; @@ -46,6 +45,13 @@ class Weapons final : public BaseEvents Weapons(const Weapons&) = delete; Weapons& operator=(const Weapons&) = delete; + static Weapons& getInstance() { + // Guaranteed to be destroyed + static Weapons instance; + // Instantiated on first use + return instance; + } + void loadDefaults(); const Weapon* getWeapon(const Item* item) const; @@ -66,6 +72,8 @@ class Weapons final : public BaseEvents LuaScriptInterface scriptInterface { "Weapon Interface" }; }; +constexpr auto g_weapons = &Weapons::getInstance; + class Weapon : public Event { public: @@ -181,7 +189,7 @@ class Weapon : public Event } void addVocWeaponMap(std::string vocName) { - int32_t vocationId = g_vocations.getVocationId(vocName); + int32_t vocationId = g_vocations().getVocationId(vocName); if (vocationId != -1) { vocWeaponMap[vocationId] = true; } diff --git a/src/lua/creature/actions.cpp b/src/lua/creature/actions.cpp index 907f3d8d019..981a2d9536e 100644 --- a/src/lua/creature/actions.cpp +++ b/src/lua/creature/actions.cpp @@ -27,8 +27,6 @@ #include "creatures/combat/spells.h" #include "items/containers/rewards/rewardchest.h" -extern Spells* g_spells; -extern Actions* g_actions; Actions::Actions() : scriptInterface("Action Interface") { @@ -404,7 +402,7 @@ Action* Actions::getAction(const Item* item) { } //rune items - return g_spells->getRuneSpell(item->getID()); + return g_spells().getRuneSpell(item->getID()); } ReturnValue Actions::internalUseItem(Player* player, const Position& pos, uint8_t index, Item* item, bool isHotkey) { @@ -638,10 +636,10 @@ std::string Action::getScriptEventName() const { ReturnValue Action::canExecuteAction(const Player* player, const Position& toPos) { if (!allowFarUse) { - return g_actions->canUse(player, toPos); + return g_actions().canUse(player, toPos); } - return g_actions->canUseFar(player, toPos, checkLineOfSight, checkFloor); + return g_actions().canUseFar(player, toPos, checkLineOfSight, checkFloor); } Thing* Action::getTarget(Player* player, Creature* targetCreature, diff --git a/src/lua/creature/actions.h b/src/lua/creature/actions.h index 58233cba034..5b677721b0a 100644 --- a/src/lua/creature/actions.h +++ b/src/lua/creature/actions.h @@ -141,6 +141,13 @@ class Actions final : public BaseEvents { Actions(const Actions&) = delete; Actions& operator=(const Actions&) = delete; + static Actions& getInstance() { + // Guaranteed to be destroyed + static Actions instance; + // Instantiated on first use + return instance; + } + bool useItem(Player* player, const Position& pos, uint8_t index, Item* item, bool isHotkey); bool useItemEx(Player* player, const Position& fromPos, const Position& toPos, uint8_t toStackPos, Item* item, bool isHotkey, Creature* creature = nullptr); @@ -235,4 +242,6 @@ class Actions final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_actions = &Actions::getInstance; + #endif // SRC_LUA_CREATURE_ACTIONS_H_ diff --git a/src/lua/creature/creatureevent.h b/src/lua/creature/creatureevent.h index 521df2da766..bc66cc1686f 100644 --- a/src/lua/creature/creatureevent.h +++ b/src/lua/creature/creatureevent.h @@ -86,6 +86,13 @@ class CreatureEvents final : public BaseEvents { CreatureEvents(const CreatureEvents&) = delete; CreatureEvents& operator=(const CreatureEvents&) = delete; + static CreatureEvents& getInstance() { + // Guaranteed to be destroyed + static CreatureEvents instance; + // Instantiated on first use + return instance; + } + // global events bool playerLogin(Player* player) const; bool playerLogout(Player* player) const; @@ -110,4 +117,6 @@ class CreatureEvents final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_creatureEvents = &CreatureEvents::getInstance; + #endif // SRC_LUA_CREATURE_CREATUREEVENT_H_ diff --git a/src/lua/creature/events.h b/src/lua/creature/events.h index d4283f71f90..5b908071755 100644 --- a/src/lua/creature/events.h +++ b/src/lua/creature/events.h @@ -77,10 +77,22 @@ class Events { }; public: + Events(); bool loadFromXml(); + // non-copyable + Events(Events const&) = delete; + void operator=(Events const&) = delete; + + static Events& getInstance() { + // Guaranteed to be destroyed + static Events instance; + // Instantiated on first use + return instance; + } + // Creature bool eventCreatureOnChangeOutfit(Creature* creature, const Outfit_t& outfit); ReturnValue eventCreatureOnAreaCombat(Creature* creature, Tile* tile, bool aggressive); @@ -130,4 +142,6 @@ class Events { EventsInfo info; }; +constexpr auto g_events = &Events::getInstance; + #endif // SRC_LUA_CREATURE_EVENTS_H_ diff --git a/src/lua/creature/movement.cpp b/src/lua/creature/movement.cpp index 202c517439c..7ef6bc29b67 100644 --- a/src/lua/creature/movement.cpp +++ b/src/lua/creature/movement.cpp @@ -27,9 +27,6 @@ #include "lua/creature/movement.h" #include "creatures/players/imbuements/imbuements.h" -extern Vocations g_vocations; -extern Events* g_events; -extern Imbuements* g_imbuements; MoveEvents::MoveEvents() : scriptInterface("MoveEvents Interface") { @@ -596,7 +593,7 @@ bool MoveEvent::configureEvent(const pugi::xml_node& node) { continue; } - int32_t vocationId = g_vocations.getVocationId(vocationNameAttribute.as_string()); + int32_t vocationId = g_vocations().getVocationId(vocationNameAttribute.as_string()); if (vocationId != -1) { vocEquipMap[vocationId] = true; if (vocationNode.attribute("showInDescription").as_bool(true)) { diff --git a/src/lua/creature/movement.h b/src/lua/creature/movement.h index 2b3dd5a755c..815c10fd787 100644 --- a/src/lua/creature/movement.h +++ b/src/lua/creature/movement.h @@ -26,7 +26,6 @@ #include "lua/functions/events/move_event_functions.hpp" #include "creatures/players/vocations/vocation.h" -extern Vocations g_vocations; class MoveEvent; using MoveEvent_ptr = std::unique_ptr; @@ -46,6 +45,13 @@ class MoveEvents final : public BaseEvents { MoveEvents(const MoveEvents&) = delete; MoveEvents& operator=(const MoveEvents&) = delete; + static MoveEvents& getInstance() { + // Guaranteed to be destroyed + static MoveEvents instance; + // Instantiated on first use + return instance; + } + uint32_t onCreatureMove(Creature* creature, const Tile* tile, MoveEvent_t eventType); uint32_t onPlayerEquip(Player* player, Item* item, Slots_t slot, bool isCheck); uint32_t onPlayerDeEquip(Player* player, Item* item, Slots_t slot); @@ -85,6 +91,8 @@ class MoveEvents final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_moveEvents = &MoveEvents::getInstance; + using StepFunction = std::function; using MoveFunction = std::function; using EquipFunction = std::function; @@ -136,7 +144,7 @@ class MoveEvent final : public Event { return vocEquipMap; } void addVocEquipMap(std::string vocName) { - int32_t vocationId = g_vocations.getVocationId(vocName); + int32_t vocationId = g_vocations().getVocationId(vocName); if (vocationId != -1) { vocEquipMap[vocationId] = true; } diff --git a/src/lua/creature/raids.cpp b/src/lua/creature/raids.cpp index aad71191b34..0e815095bfe 100644 --- a/src/lua/creature/raids.cpp +++ b/src/lua/creature/raids.cpp @@ -119,7 +119,7 @@ bool Raids::startup() { setLastRaidEnd(OTSYS_TIME()); - checkRaidsEvent = g_scheduler.addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this))); + checkRaidsEvent = g_scheduler().addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this))); started = true; return started; @@ -145,11 +145,11 @@ void Raids::checkRaids() { } } - checkRaidsEvent = g_scheduler.addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this))); + checkRaidsEvent = g_scheduler().addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this))); } void Raids::clear() { - g_scheduler.stopEvent(checkRaidsEvent); + g_scheduler().stopEvent(checkRaidsEvent); checkRaidsEvent = 0; for (Raid* raid : raidList) { @@ -234,7 +234,7 @@ void Raid::startRaid() { RaidEvent* raidEvent = getNextRaidEvent(); if (raidEvent) { state = RAIDSTATE_EXECUTING; - nextEventEvent = g_scheduler.addEvent(createSchedulerTask(raidEvent->getDelay(), std::bind(&Raid::executeRaidEvent, this, raidEvent))); + nextEventEvent = g_scheduler().addEvent(createSchedulerTask(raidEvent->getDelay(), std::bind(&Raid::executeRaidEvent, this, raidEvent))); } } @@ -245,7 +245,7 @@ void Raid::executeRaidEvent(RaidEvent* raidEvent) { if (newRaidEvent) { uint32_t ticks = static_cast(std::max(RAID_MINTICKS, newRaidEvent->getDelay() - raidEvent->getDelay())); - nextEventEvent = g_scheduler.addEvent(createSchedulerTask(ticks, std::bind(&Raid::executeRaidEvent, this, newRaidEvent))); + nextEventEvent = g_scheduler().addEvent(createSchedulerTask(ticks, std::bind(&Raid::executeRaidEvent, this, newRaidEvent))); } else { resetRaid(); } @@ -263,7 +263,7 @@ void Raid::resetRaid() { void Raid::stopEvents() { if (nextEventEvent != 0) { - g_scheduler.stopEvent(nextEventEvent); + g_scheduler().stopEvent(nextEventEvent); nextEventEvent = 0; } } diff --git a/src/lua/creature/talkaction.h b/src/lua/creature/talkaction.h index cebb49ab37d..79a62d38b60 100644 --- a/src/lua/creature/talkaction.h +++ b/src/lua/creature/talkaction.h @@ -72,6 +72,13 @@ class TalkActions final : public BaseEvents { TalkActions(const TalkActions&) = delete; TalkActions& operator=(const TalkActions&) = delete; + static TalkActions& getInstance() { + // Guaranteed to be destroyed + static TalkActions instance; + // Instantiated on first use + return instance; + } + TalkActionResult_t playerSaySpell(Player* player, SpeakClasses type, const std::string& words) const; bool registerLuaEvent(TalkAction* event); @@ -88,4 +95,6 @@ class TalkActions final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_talkActions = &TalkActions::getInstance; + #endif // SRC_LUA_CREATURE_TALKACTION_H_ diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index 7714ab76ea4..e4dc459a8e3 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -30,19 +30,17 @@ #include "lua/functions/creatures/npc/npc_type_functions.hpp" #include "lua/scripts/scripts.h" -extern Monsters g_monsters; -extern Scripts* g_scripts; // Game int GameFunctions::luaGameCreateMonsterType(lua_State* L) { // Game.createMonsterType(name) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("MonsterTypes can only be registered in the Scripts interface."); lua_pushnil(L); return 1; } - MonsterType* monsterType = g_monsters.getMonsterType(getString(L, 1)); + MonsterType* monsterType = g_monsters().getMonsterType(getString(L, 1)); if (monsterType) { monsterType->info.lootItems.clear(); monsterType->info.attackSpells.clear(); @@ -52,8 +50,8 @@ int GameFunctions::luaGameCreateMonsterType(lua_State* L) { } else if (isString(L, 1)) { monsterType = new MonsterType(); std::string name = getString(L, 1); - g_monsters.addMonsterType(name, monsterType); - monsterType = g_monsters.getMonsterType(getString(L, 1)); + g_monsters().addMonsterType(name, monsterType); + monsterType = g_monsters().getMonsterType(getString(L, 1)); monsterType->name = name; monsterType->nameDescription = "a " + name; pushUserdata(L, monsterType); @@ -66,7 +64,7 @@ int GameFunctions::luaGameCreateMonsterType(lua_State* L) { int GameFunctions::luaGameCreateNpcType(lua_State* L) { // Game.createNpcType(name) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("NpcType can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -189,7 +187,7 @@ int GameFunctions::luaGameGetPlayers(lua_State* L) { int GameFunctions::luaGameLoadMap(lua_State* L) { // Game.loadMap(path) const std::string& path = getString(L, 1); - g_dispatcher.addTask(createTask([path]() {g_game().loadMap(path);})); + g_dispatcher().addTask(createTask([path]() {g_game().loadMap(path); })); return 0; } @@ -213,7 +211,7 @@ int GameFunctions::luaGameGetNpcCount(lua_State* L) { int GameFunctions::luaGameGetMonsterTypes(lua_State* L) { // Game.getMonsterTypes() - auto& type = g_monsters.monsters; + auto& type = g_monsters().monsters; lua_createtable(L, type.size(), 0); for (auto& mType : type) { @@ -538,7 +536,7 @@ int GameFunctions::luaGameGetBestiaryCharm(lua_State* L) { int GameFunctions::luaGameCreateBestiaryCharm(lua_State* L) { // Game.createBestiaryCharm(id) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("Charm bestiary can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -556,7 +554,7 @@ int GameFunctions::luaGameCreateBestiaryCharm(lua_State* L) { int GameFunctions::luaGameCreateItemClassification(lua_State* L) { // Game.createItemClassification(id) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("Item classification can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -612,7 +610,7 @@ int GameFunctions::luaGameReload(lua_State* L) { if (reloadType == RELOAD_TYPE_GLOBAL) { pushBoolean(L, g_luaEnvironment.loadFile("data/global.lua") == 0); pushBoolean(L, g_luaEnvironment.loadFile("data/stages.lua") == 0); - pushBoolean(L, g_scripts->loadScripts("scripts/lib", true, true)); + pushBoolean(L, g_scripts().loadScripts("scripts/lib", true, true)); } else if (reloadType == RELOAD_TYPE_STAGES) { pushBoolean(L, g_luaEnvironment.loadFile("data/stages.lua") == 0); } else { diff --git a/src/lua/functions/core/game/game_functions.hpp b/src/lua/functions/core/game/game_functions.hpp index ebf1a4092bb..3f80c846220 100644 --- a/src/lua/functions/core/game/game_functions.hpp +++ b/src/lua/functions/core/game/game_functions.hpp @@ -24,9 +24,6 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/luascript.h" - -extern LuaEnvironment g_luaEnvironment; - class GameFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { diff --git a/src/lua/functions/core/game/global_functions.cpp b/src/lua/functions/core/game/global_functions.cpp index 25e82d7cff3..df88305a581 100644 --- a/src/lua/functions/core/game/global_functions.cpp +++ b/src/lua/functions/core/game/global_functions.cpp @@ -30,10 +30,6 @@ #include "server/network/protocol/protocolstatus.h" class Creature; - -extern Chat* g_chat; -extern LuaEnvironment g_luaEnvironment; - int GlobalFunctions::luaDoPlayerAddItem(lua_State* L) { // doPlayerAddItem(cid, itemid, count/subtype, canDropOnMap) // doPlayerAddItem(cid, itemid, count, canDropOnMap, subtype) @@ -657,7 +653,7 @@ int GlobalFunctions::luaAddEvent(lua_State* L) { eventDesc.scriptId = getScriptEnv()->getScriptId(); auto& lastTimerEventId = g_luaEnvironment.lastEventTimerId; - eventDesc.eventId = g_scheduler.addEvent(createSchedulerTask( + eventDesc.eventId = g_scheduler().addEvent(createSchedulerTask( delay, std::bind(&LuaEnvironment::executeTimerEvent, &g_luaEnvironment, lastTimerEventId) )); @@ -687,7 +683,7 @@ int GlobalFunctions::luaStopEvent(lua_State* L) { LuaTimerEventDesc timerEventDesc = std::move(it->second); timerEvents.erase(it); - g_scheduler.stopEvent(timerEventDesc.eventId); + g_scheduler().stopEvent(timerEventDesc.eventId); luaL_unref(globalState, LUA_REGISTRYINDEX, timerEventDesc.function); for (auto parameter : timerEventDesc.parameters) { @@ -750,8 +746,8 @@ int GlobalFunctions::luaGetWaypointPositionByName(lua_State* L) { int GlobalFunctions::luaSendChannelMessage(lua_State* L) { // sendChannelMessage(channelId, type, message) - uint32_t channelId = getNumber(L, 1); - ChatChannel* channel = g_chat->getChannelById(channelId); + uint16_t channelId = getNumber(L, 1); + const ChatChannel* channel = g_chat().getChannelById(channelId); if (!channel) { pushBoolean(L, false); return 1; @@ -767,7 +763,7 @@ int GlobalFunctions::luaSendChannelMessage(lua_State* L) { int GlobalFunctions::luaSendGuildChannelMessage(lua_State* L) { // sendGuildChannelMessage(guildId, type, message) uint32_t guildId = getNumber(L, 1); - ChatChannel* channel = g_chat->getGuildChannelById(guildId); + const ChatChannel* channel = g_chat().getGuildChannelById(guildId); if (!channel) { pushBoolean(L, false); return 1; diff --git a/src/lua/functions/core/libs/db_functions.cpp b/src/lua/functions/core/libs/db_functions.cpp index a1d6deae26b..1cccc81b03a 100644 --- a/src/lua/functions/core/libs/db_functions.cpp +++ b/src/lua/functions/core/libs/db_functions.cpp @@ -23,9 +23,6 @@ #include "database/databasetasks.h" #include "lua/functions/core/libs/db_functions.hpp" #include "lua/scripts/lua_environment.hpp" - -extern LuaEnvironment g_luaEnvironment; - int DBFunctions::luaDatabaseExecute(lua_State* L) { pushBoolean(L, Database::getInstance().executeQuery(getString(L, -1))); return 1; @@ -56,7 +53,7 @@ int DBFunctions::luaDatabaseAsyncExecute(lua_State* L) { luaL_unref(luaState, LUA_REGISTRYINDEX, ref); }; } - g_databaseTasks.addTask(getString(L, -1), callback); + g_databaseTasks().addTask(getString(L, -1), callback); return 0; } @@ -98,7 +95,7 @@ int DBFunctions::luaDatabaseAsyncStoreQuery(lua_State* L) { luaL_unref(luaState, LUA_REGISTRYINDEX, ref); }; } - g_databaseTasks.addTask(getString(L, -1), callback, true); + g_databaseTasks().addTask(getString(L, -1), callback, true); return 0; } diff --git a/src/lua/functions/core/network/network_message_functions.hpp b/src/lua/functions/core/network/network_message_functions.hpp index 1421d12d14a..131d28ae995 100644 --- a/src/lua/functions/core/network/network_message_functions.hpp +++ b/src/lua/functions/core/network/network_message_functions.hpp @@ -24,9 +24,6 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/luascript.h" - -extern LuaEnvironment g_luaEnvironment; - class NetworkMessageFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { diff --git a/src/lua/functions/creatures/combat/combat_functions.cpp b/src/lua/functions/creatures/combat/combat_functions.cpp index 254d27ac8e2..f14d893b97f 100644 --- a/src/lua/functions/creatures/combat/combat_functions.cpp +++ b/src/lua/functions/creatures/combat/combat_functions.cpp @@ -23,9 +23,6 @@ #include "game/game.h" #include "lua/functions/creatures/combat/combat_functions.hpp" #include "lua/scripts/lua_environment.hpp" - -extern LuaEnvironment g_luaEnvironment; - int CombatFunctions::luaCombatCreate(lua_State* L) { // Combat() pushUserdata(L, g_luaEnvironment.createCombatObject(getScriptEnv()->getScriptInterface())); diff --git a/src/lua/functions/creatures/combat/spell_functions.cpp b/src/lua/functions/creatures/combat/spell_functions.cpp index 43303b20d95..9838db0736b 100644 --- a/src/lua/functions/creatures/combat/spell_functions.cpp +++ b/src/lua/functions/creatures/combat/spell_functions.cpp @@ -23,8 +23,6 @@ #include "creatures/players/vocations/vocation.h" #include "lua/functions/creatures/combat/spell_functions.hpp" -extern Spells* g_spells; -extern Vocations g_vocations; int SpellFunctions::luaSpellCreate(lua_State* L) { // Spell(words, name or id) to get an existing spell @@ -40,7 +38,7 @@ int SpellFunctions::luaSpellCreate(lua_State* L) { if (isNumber(L, 2)) { int32_t id = getNumber(L, 2); - RuneSpell* rune = g_spells->getRuneSpell(id); + RuneSpell* rune = g_spells().getRuneSpell(id); if (rune) { pushUserdata(L, rune); @@ -51,19 +49,19 @@ int SpellFunctions::luaSpellCreate(lua_State* L) { spellType = static_cast(id); } else if (isString(L, 2)) { std::string arg = getString(L, 2); - InstantSpell* instant = g_spells->getInstantSpellByName(arg); + InstantSpell* instant = g_spells().getInstantSpellByName(arg); if (instant) { pushUserdata(L, instant); setMetatable(L, -1, "Spell"); return 1; } - instant = g_spells->getInstantSpell(arg); + instant = g_spells().getInstantSpell(arg); if (instant) { pushUserdata(L, instant); setMetatable(L, -1, "Spell"); return 1; } - RuneSpell* rune = g_spells->getRuneSpellByName(arg); + RuneSpell* rune = g_spells().getRuneSpellByName(arg); if (rune) { pushUserdata(L, rune); setMetatable(L, -1, "Spell"); @@ -141,7 +139,7 @@ int SpellFunctions::luaSpellRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_spells->registerInstantLuaEvent(instant)); + pushBoolean(L, g_spells().registerInstantLuaEvent(instant)); } else if (spell->spellType == SPELL_RUNE) { RuneSpell* rune = dynamic_cast(getUserdata(L, 1)); if (rune->getMagicLevel() != 0 || rune->getLevel() != 0) { @@ -159,7 +157,7 @@ int SpellFunctions::luaSpellRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_spells->registerRuneLuaEvent(rune)); + pushBoolean(L, g_spells().registerRuneLuaEvent(rune)); } return 1; } @@ -578,7 +576,7 @@ int SpellFunctions::luaSpellVocation(lua_State* L) { ++it; std::string s = std::to_string(it); char const *pchar = s.c_str(); - std::string name = g_vocations.getVocation(voc.first)->getVocName(); + std::string name = g_vocations().getVocation(voc.first)->getVocName(); setField(L, pchar, name); } setMetatable(L, -1, "Spell"); @@ -587,7 +585,7 @@ int SpellFunctions::luaSpellVocation(lua_State* L) { for (int i = 0; i < parameters; ++i) { if (getString(L, 2 + i).find(";") != std::string::npos) { std::vector vocList = explodeString(getString(L, 2 + i), ";"); - int32_t vocationId = g_vocations.getVocationId(vocList[0]); + int32_t vocationId = g_vocations().getVocationId(vocList[0]); if (vocList.size() > 0) { if (vocList[1] == "true") { spell->addVocMap(vocationId, true); @@ -596,7 +594,7 @@ int SpellFunctions::luaSpellVocation(lua_State* L) { } } } else { - int32_t vocationId = g_vocations.getVocationId(getString(L, 2 + i)); + int32_t vocationId = g_vocations().getVocationId(getString(L, 2 + i)); spell->addVocMap(vocationId, false); } } diff --git a/src/lua/functions/creatures/monster/loot_functions.cpp b/src/lua/functions/creatures/monster/loot_functions.cpp index 298577a1c58..c484f646978 100644 --- a/src/lua/functions/creatures/monster/loot_functions.cpp +++ b/src/lua/functions/creatures/monster/loot_functions.cpp @@ -22,7 +22,6 @@ #include "creatures/monsters/monsters.h" #include "lua/functions/creatures/monster/loot_functions.hpp" -extern Monsters g_monsters; int LootFunctions::luaCreateLoot(lua_State* L) { // Loot() will create a new loot item diff --git a/src/lua/functions/creatures/monster/monster_functions.cpp b/src/lua/functions/creatures/monster/monster_functions.cpp index c4256c2a7fb..8ea8aa6d7f5 100644 --- a/src/lua/functions/creatures/monster/monster_functions.cpp +++ b/src/lua/functions/creatures/monster/monster_functions.cpp @@ -27,7 +27,6 @@ #include "creatures/monsters/monsters.h" #include "lua/functions/creatures/monster/monster_functions.hpp" -extern Monsters g_monsters; int MonsterFunctions::luaMonsterCreate(lua_State* L) { // Monster(id or userdata) @@ -77,9 +76,9 @@ int MonsterFunctions::luaMonsterSetType(lua_State* L) { if (monster) { MonsterType* monsterType = nullptr; if (isNumber(L, 2)) { - monsterType = g_monsters.getMonsterTypeByRaceId(getNumber(L, 2)); + monsterType = g_monsters().getMonsterTypeByRaceId(getNumber(L, 2)); } else { - monsterType = g_monsters.getMonsterType(getString(L, 2)); + monsterType = g_monsters().getMonsterType(getString(L, 2)); } // Unregister creature events (current MonsterType) for (const std::string& scriptName : monster->mType->info.scripts) { diff --git a/src/lua/functions/creatures/monster/monster_type_functions.cpp b/src/lua/functions/creatures/monster/monster_type_functions.cpp index aaaa555c2dd..4e218ce03b0 100644 --- a/src/lua/functions/creatures/monster/monster_type_functions.cpp +++ b/src/lua/functions/creatures/monster/monster_type_functions.cpp @@ -25,8 +25,6 @@ #include "lua/functions/creatures/monster/monster_type_functions.hpp" #include "lua/scripts/scripts.h" -extern Monsters g_monsters; -extern Scripts* g_scripts; void MonsterTypeFunctions::createMonsterTypeLootLuaTable(lua_State* L, const std::vector& lootList) { lua_createtable(L, lootList.size(), 0); @@ -56,9 +54,9 @@ int MonsterTypeFunctions::luaMonsterTypeCreate(lua_State* L) { // MonsterType(name or raceid) MonsterType* monsterType = nullptr; if (isNumber(L, 2)) { - monsterType = g_monsters.getMonsterTypeByRaceId(getNumber(L, 2)); + monsterType = g_monsters().getMonsterTypeByRaceId(getNumber(L, 2)); } else { - monsterType = g_monsters.getMonsterType(getString(L, 2)); + monsterType = g_monsters().getMonsterType(getString(L, 2)); } if (monsterType) { @@ -774,7 +772,7 @@ int MonsterTypeFunctions::luaMonsterTypeAddAttack(lua_State* L) { MonsterSpell* spell = getUserdata(L, 2); if (spell) { spellBlock_t sb; - if (g_monsters.deserializeSpell(spell, sb, monsterType->name)) { + if (g_monsters().deserializeSpell(spell, sb, monsterType->name)) { monsterType->info.attackSpells.push_back(std::move(sb)); } else { SPDLOG_WARN("Monster: {}, cant load spell: {}", monsterType->name, @@ -826,7 +824,7 @@ int MonsterTypeFunctions::luaMonsterTypeAddDefense(lua_State* L) { MonsterSpell* spell = getUserdata(L, 2); if (spell) { spellBlock_t sb; - if (g_monsters.deserializeSpell(spell, sb, monsterType->name)) { + if (g_monsters().deserializeSpell(spell, sb, monsterType->name)) { monsterType->info.defenseSpells.push_back(std::move(sb)); } else { SPDLOG_WARN("Monster: {}, Cant load spell: {}", monsterType->name, @@ -998,7 +996,7 @@ int MonsterTypeFunctions::luaMonsterTypeEventOnCallback(lua_State* L) { // monsterType:onSay(callback) MonsterType* monsterType = getUserdata(L, 1); if (monsterType) { - if (monsterType->loadCallback(&g_scripts->getScriptInterface())) { + if (monsterType->loadCallback(&g_scripts().getScriptInterface())) { pushBoolean(L, true); return 1; } diff --git a/src/lua/functions/creatures/npc/npc_type_functions.cpp b/src/lua/functions/creatures/npc/npc_type_functions.cpp index af5eed3799e..46ee4a9972f 100644 --- a/src/lua/functions/creatures/npc/npc_type_functions.cpp +++ b/src/lua/functions/creatures/npc/npc_type_functions.cpp @@ -23,8 +23,6 @@ #include "lua/functions/creatures/npc/npc_type_functions.hpp" #include "lua/scripts/scripts.h" -extern Npcs g_npcs; -extern Scripts* g_scripts; void NpcTypeFunctions::createNpcTypeShopLuaTable(lua_State* L, const std::vector& shopVector) { lua_createtable(L, shopVector.size(), 0); @@ -49,7 +47,7 @@ void NpcTypeFunctions::createNpcTypeShopLuaTable(lua_State* L, const std::vector int NpcTypeFunctions::luaNpcTypeCreate(lua_State* L) { // NpcType(name) - NpcType* npcType = g_npcs.getNpcType(getString(L, 1), true); + NpcType* npcType = g_npcs().getNpcType(getString(L, 1), true); pushUserdata(L, npcType); setMetatable(L, -1, "NpcType"); return 1; @@ -290,7 +288,7 @@ int NpcTypeFunctions::luaNpcTypeEventOnCallback(lua_State* L) { // npcType:onCheckItem(callback) NpcType* npcType = getUserdata(L, 1); if (npcType) { - if (npcType->loadCallback(&g_scripts->getScriptInterface())) { + if (npcType->loadCallback(&g_scripts().getScriptInterface())) { pushBoolean(L, true); return 1; } diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index ca48ee86228..b5482c13b17 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -30,10 +30,6 @@ #include "items/item.h" #include "lua/functions/creatures/player/player_functions.hpp" -extern Chat* g_chat; -extern Monsters g_monsters; -extern Spells* g_spells; -extern Vocations g_vocations; int PlayerFunctions::luaPlayerSendInventory(lua_State* L) { // player:sendInventory() @@ -303,7 +299,7 @@ int PlayerFunctions::luaPlayeraddBestiaryKill(lua_State* L) { // player:addBestiaryKill(name[, amount = 1]) Player* player = getUserdata(L, 1); if (player) { - MonsterType* mtype = g_monsters.getMonsterType(getString(L, 2)); + MonsterType* mtype = g_monsters().getMonsterType(getString(L, 2)); if (mtype) { IOBestiary g_bestiary; g_bestiary.addBestiaryKill(player, mtype, getNumber(L, 3, 1)); @@ -324,7 +320,7 @@ int PlayerFunctions::luaPlayergetCharmMonsterType(lua_State* L) { charmRune_t charmid = getNumber(L, 2); uint16_t raceid = player->parseRacebyCharm(charmid, false, 0); if (raceid > 0) { - MonsterType* mtype = g_monsters.getMonsterTypeByRaceId(raceid); + MonsterType* mtype = g_monsters().getMonsterTypeByRaceId(raceid); if (mtype) { pushUserdata(L, mtype); setMetatable(L, -1, "MonsterType"); @@ -1124,9 +1120,9 @@ int PlayerFunctions::luaPlayerSetVocation(lua_State* L) { Vocation* vocation; if (isNumber(L, 2)) { - vocation = g_vocations.getVocation(getNumber(L, 2)); + vocation = g_vocations().getVocation(getNumber(L, 2)); } else if (isString(L, 2)) { - vocation = g_vocations.getVocation(g_vocations.getVocationId(getString(L, 2))); + vocation = g_vocations().getVocation(g_vocations().getVocationId(getString(L, 2))); } else if (isUserdata(L, 2)) { vocation = getUserdata(L, 2); } else { @@ -1917,7 +1913,7 @@ int PlayerFunctions::luaPlayerSendTextMessage(lua_State* L) { TextMessage message(getNumber(L, 2), getString(L, 3)); if (parameters == 4) { uint16_t channelId = getNumber(L, 4); - ChatChannel* channel = g_chat->getChannel(*player, channelId); + ChatChannel* channel = g_chat().getChannel(*player, channelId); if (!channel || !channel->hasUser(*player)) { pushBoolean(L, false); return 1; @@ -2437,7 +2433,7 @@ int PlayerFunctions::luaPlayerCanLearnSpell(lua_State* L) { } const std::string& spellName = getString(L, 2); - InstantSpell* spell = g_spells->getInstantSpellByName(spellName); + const InstantSpell* spell = g_spells().getInstantSpellByName(spellName); if (!spell) { reportErrorFunc("Spell \"" + spellName + "\" not found"); pushBoolean(L, false); @@ -3106,9 +3102,9 @@ int PlayerFunctions::luaPlayerGetInstantSpells(lua_State* L) { } std::vector spells; - for (auto& spell : g_spells->getInstantSpells()) { - if (spell.second.canCast(player)) { - spells.push_back(&spell.second); + for (auto& [key, spell] : g_spells().getInstantSpells()) { + if (spell.canCast(player)) { + spells.push_back(&spell); } } diff --git a/src/lua/functions/creatures/player/vocation_functions.cpp b/src/lua/functions/creatures/player/vocation_functions.cpp index 0f4a77aa4a7..0999bc267e2 100644 --- a/src/lua/functions/creatures/player/vocation_functions.cpp +++ b/src/lua/functions/creatures/player/vocation_functions.cpp @@ -22,18 +22,17 @@ #include "creatures/players/vocations/vocation.h" #include "lua/functions/creatures/player/vocation_functions.hpp" -extern Vocations g_vocations; int VocationFunctions::luaVocationCreate(lua_State* L) { // Vocation(id or name) - uint32_t id; + uint16_t vocationId; if (isNumber(L, 2)) { - id = getNumber(L, 2); + vocationId = getNumber(L, 2); } else { - id = g_vocations.getVocationId(getString(L, 2)); + vocationId = g_vocations().getVocationId(getString(L, 2)); } - Vocation* vocation = g_vocations.getVocation(id); + Vocation* vocation = g_vocations().getVocation(vocationId); if (vocation) { pushUserdata(L, vocation); setMetatable(L, -1, "Vocation"); @@ -269,7 +268,7 @@ int VocationFunctions::luaVocationGetDemotion(lua_State* L) { return 1; } - Vocation* demotedVocation = g_vocations.getVocation(fromId); + Vocation* demotedVocation = g_vocations().getVocation(fromId); if (demotedVocation && demotedVocation != vocation) { pushUserdata(L, demotedVocation); setMetatable(L, -1, "Vocation"); @@ -287,13 +286,13 @@ int VocationFunctions::luaVocationGetPromotion(lua_State* L) { return 1; } - uint16_t promotedId = g_vocations.getPromotedVocation(vocation->getId()); + uint16_t promotedId = g_vocations().getPromotedVocation(vocation->getId()); if (promotedId == VOCATION_NONE) { lua_pushnil(L); return 1; } - Vocation* promotedVocation = g_vocations.getVocation(promotedId); + Vocation* promotedVocation = g_vocations().getVocation(promotedId); if (promotedVocation && promotedVocation != vocation) { pushUserdata(L, promotedVocation); setMetatable(L, -1, "Vocation"); diff --git a/src/lua/functions/events/action_functions.cpp b/src/lua/functions/events/action_functions.cpp index 8c2b539e105..3893ab418a8 100644 --- a/src/lua/functions/events/action_functions.cpp +++ b/src/lua/functions/events/action_functions.cpp @@ -24,7 +24,6 @@ #include "game/game.h" #include "items/item.h" -extern Actions* g_actions; int ActionFunctions::luaCreateAction(lua_State* L) { // Action() @@ -65,7 +64,7 @@ int ActionFunctions::luaActionRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_actions->registerLuaEvent(action)); + pushBoolean(L, g_actions().registerLuaEvent(action)); pushBoolean(L, true); } else { reportErrorFunc(getErrorDesc(LUA_ERROR_ACTION_NOT_FOUND)); diff --git a/src/lua/functions/events/creature_event_functions.cpp b/src/lua/functions/events/creature_event_functions.cpp index fb9037fd4c5..e87e9dbc3b6 100644 --- a/src/lua/functions/events/creature_event_functions.cpp +++ b/src/lua/functions/events/creature_event_functions.cpp @@ -23,7 +23,6 @@ #include "lua/functions/events/creature_event_functions.hpp" #include "utils/tools.h" -extern CreatureEvents* g_creatureEvents; int CreatureEventFunctions::luaCreateCreatureEvent(lua_State* L) { // CreatureEvent(eventName) @@ -90,7 +89,7 @@ int CreatureEventFunctions::luaCreatureEventRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_creatureEvents->registerLuaEvent(creature)); + pushBoolean(L, g_creatureEvents().registerLuaEvent(creature)); } else { lua_pushnil(L); } diff --git a/src/lua/functions/events/global_event_functions.cpp b/src/lua/functions/events/global_event_functions.cpp index 3ed18df982f..ca99536ed89 100644 --- a/src/lua/functions/events/global_event_functions.cpp +++ b/src/lua/functions/events/global_event_functions.cpp @@ -24,12 +24,10 @@ #include "lua/scripts/scripts.h" #include "utils/tools.h" -extern GlobalEvents* g_globalEvents; -extern Scripts* g_scripts; int GlobalEventFunctions::luaCreateGlobalEvent(lua_State* L) { // GlobalEvent(eventName) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("GlobalEvents can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -82,7 +80,7 @@ int GlobalEventFunctions::luaGlobalEventRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_globalEvents->registerLuaEvent(globalevent)); + pushBoolean(L, g_globalEvents().registerLuaEvent(globalevent)); } else { lua_pushnil(L); } diff --git a/src/lua/functions/events/move_event_functions.cpp b/src/lua/functions/events/move_event_functions.cpp index 948edca10e0..fedd938eb11 100644 --- a/src/lua/functions/events/move_event_functions.cpp +++ b/src/lua/functions/events/move_event_functions.cpp @@ -23,7 +23,6 @@ #include "lua/creature/movement.h" #include "lua/functions/events/move_event_functions.hpp" -extern MoveEvents* g_moveEvents; int MoveEventFunctions::luaCreateMoveEvent(lua_State* L) { // MoveEvent() @@ -79,10 +78,10 @@ int MoveEventFunctions::luaMoveEventRegister(lua_State* L) { MoveEvent* moveevent = getUserdata(L, 1); if (moveevent) { if (!moveevent->isScripted()) { - pushBoolean(L, g_moveEvents->registerLuaFunction(moveevent)); + pushBoolean(L, g_moveEvents().registerLuaFunction(moveevent)); return 1; } - pushBoolean(L, g_moveEvents->registerLuaEvent(moveevent)); + pushBoolean(L, g_moveEvents().registerLuaEvent(moveevent)); moveevent->getItemIdRange().clear(); moveevent->getActionIdRange().clear(); moveevent->getUniqueIdRange().clear(); diff --git a/src/lua/functions/events/talk_action_functions.cpp b/src/lua/functions/events/talk_action_functions.cpp index ed8eb04c59a..9f7501529fd 100644 --- a/src/lua/functions/events/talk_action_functions.cpp +++ b/src/lua/functions/events/talk_action_functions.cpp @@ -22,7 +22,6 @@ #include "lua/creature/talkaction.h" #include "lua/functions/events/talk_action_functions.hpp" -extern TalkActions* g_talkActions; int TalkActionFunctions::luaCreateTalkAction(lua_State* L) { // TalkAction(words) @@ -63,7 +62,7 @@ int TalkActionFunctions::luaTalkActionRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_talkActions->registerLuaEvent(talk)); + pushBoolean(L, g_talkActions().registerLuaEvent(talk)); } else { lua_pushnil(L); } diff --git a/src/lua/functions/items/imbuement_functions.cpp b/src/lua/functions/items/imbuement_functions.cpp index d37e2f75d2f..676ba8e859d 100644 --- a/src/lua/functions/items/imbuement_functions.cpp +++ b/src/lua/functions/items/imbuement_functions.cpp @@ -28,14 +28,11 @@ #include "lua/scripts/scripts.h" #include "utils/tools.h" -extern Imbuements* g_imbuements; -extern Scripts* g_scripts; -extern Weapons* g_weapons; int ImbuementFunctions::luaCreateImbuement(lua_State* L) { // Imbuement(id) - uint32_t imbuementId = getNumber(L, 2); - Imbuement* imbuement = g_imbuements->getImbuement(imbuementId); + uint16_t imbuementId = getNumber(L, 2); + Imbuement* imbuement = g_imbuements().getImbuement(imbuementId); if (imbuement) { pushUserdata(L, imbuement); @@ -97,7 +94,7 @@ int ImbuementFunctions::luaImbuementGetBase(lua_State* L) { return 1; } - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuement->getBaseID()); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuement->getBaseID()); if (!baseImbuement) { lua_pushnil(L); @@ -122,8 +119,8 @@ int ImbuementFunctions::luaImbuementGetCategory(lua_State* L) { lua_pushnil(L); return 1; } - uint32_t categoryId = imbuement->getCategory(); - const CategoryImbuement* categoryImbuement = g_imbuements->getCategoryByID(categoryId); + uint16_t categoryId = imbuement->getCategory(); + const CategoryImbuement* categoryImbuement = g_imbuements().getCategoryByID(categoryId); if (categoryImbuement) { lua_createtable(L, 0, 2); diff --git a/src/lua/functions/items/item_functions.cpp b/src/lua/functions/items/item_functions.cpp index dbef827ff6f..1a1d40e090e 100644 --- a/src/lua/functions/items/item_functions.cpp +++ b/src/lua/functions/items/item_functions.cpp @@ -422,9 +422,9 @@ int ItemFunctions::luaItemSetAttribute(lua_State* L) { case ITEM_ATTRIBUTE_DECAYSTATE: { ItemDecayState_t decayState = getNumber(L, 3); if (decayState == DECAYING_FALSE || decayState == DECAYING_STOPPING) { - g_decay.stopDecay(item); + g_decay().stopDecay(item); } else { - g_decay.startDecay(item); + g_decay().startDecay(item); } pushBoolean(L, true); return 1; @@ -432,7 +432,7 @@ int ItemFunctions::luaItemSetAttribute(lua_State* L) { case ITEM_ATTRIBUTE_DURATION: { item->setDecaying(DECAYING_PENDING); item->setDuration(getNumber(L, 3)); - g_decay.startDecay(item); + g_decay().startDecay(item); pushBoolean(L, true); return 1; } diff --git a/src/lua/functions/items/weapon_functions.cpp b/src/lua/functions/items/weapon_functions.cpp index 009eccc66c2..10c63f3a76e 100644 --- a/src/lua/functions/items/weapon_functions.cpp +++ b/src/lua/functions/items/weapon_functions.cpp @@ -28,12 +28,10 @@ #include "lua/scripts/scripts.h" #include "utils/tools.h" -extern Scripts* g_scripts; -extern Weapons* g_weapons; int WeaponFunctions::luaCreateWeapon(lua_State* L) { // Weapon(type) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("Weapons can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -137,7 +135,7 @@ int WeaponFunctions::luaWeaponRegister(lua_State* L) { } weapon->configureWeapon(it); - pushBoolean(L, g_weapons->registerLuaEvent(weapon)); + pushBoolean(L, g_weapons().registerLuaEvent(weapon)); weapon = nullptr; // Releases weapon, removing the luascript reference } else { lua_pushnil(L); diff --git a/src/lua/functions/map/position_functions.hpp b/src/lua/functions/map/position_functions.hpp index b45154c5db5..34e46a1cc15 100644 --- a/src/lua/functions/map/position_functions.hpp +++ b/src/lua/functions/map/position_functions.hpp @@ -24,9 +24,6 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/luascript.h" - -extern LuaEnvironment g_luaEnvironment; - class PositionFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { diff --git a/src/lua/global/baseevents.cpp b/src/lua/global/baseevents.cpp index 64b40aad34f..1307e67fb9d 100644 --- a/src/lua/global/baseevents.cpp +++ b/src/lua/global/baseevents.cpp @@ -23,9 +23,6 @@ #include "lua/scripts/lua_environment.hpp" #include "utils/pugicast.h" #include "utils/tools.h" - -extern LuaEnvironment g_luaEnvironment; - bool BaseEvents::loadFromXml() { if (loaded) { SPDLOG_ERROR("[BaseEvents::loadFromXml] - It's already loaded."); diff --git a/src/lua/global/globalevent.cpp b/src/lua/global/globalevent.cpp index 2cbb58ee35d..f70335afa12 100644 --- a/src/lua/global/globalevent.cpp +++ b/src/lua/global/globalevent.cpp @@ -45,9 +45,9 @@ void GlobalEvents::clearMap(GlobalEventMap& map, bool fromLua) { } void GlobalEvents::clear(bool fromLua) { - g_scheduler.stopEvent(thinkEventId); + g_scheduler().stopEvent(thinkEventId); thinkEventId = 0; - g_scheduler.stopEvent(timerEventId); + g_scheduler().stopEvent(timerEventId); timerEventId = 0; clearMap(thinkMap, fromLua); @@ -70,7 +70,7 @@ bool GlobalEvents::registerEvent(Event_ptr event, const pugi::xml_node&) { auto result = timerMap.emplace(globalEvent->getName(), std::move(*globalEvent)); if (result.second) { if (timerEventId == 0) { - timerEventId = g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::timer, this))); + timerEventId = g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::timer, this))); } return true; } @@ -83,7 +83,7 @@ bool GlobalEvents::registerEvent(Event_ptr event, const pugi::xml_node&) { auto result = thinkMap.emplace(globalEvent->getName(), std::move(*globalEvent)); if (result.second) { if (thinkEventId == 0) { - thinkEventId = g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::think, this))); + thinkEventId = g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::think, this))); } return true; } @@ -100,7 +100,7 @@ bool GlobalEvents::registerLuaEvent(GlobalEvent* event) { auto result = timerMap.emplace(globalEvent->getName(), std::move(*globalEvent)); if (result.second) { if (timerEventId == 0) { - timerEventId = g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::timer, this))); + timerEventId = g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::timer, this))); } return true; } @@ -113,7 +113,7 @@ bool GlobalEvents::registerLuaEvent(GlobalEvent* event) { auto result = thinkMap.emplace(globalEvent->getName(), std::move(*globalEvent)); if (result.second) { if (thinkEventId == 0) { - thinkEventId = g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::think, this))); + thinkEventId = g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::think, this))); } return true; } @@ -162,7 +162,7 @@ void GlobalEvents::timer() { } if (nextScheduledTime != std::numeric_limits::max()) { - timerEventId = g_scheduler.addEvent(createSchedulerTask(std::max(1000, nextScheduledTime * 1000), + timerEventId = g_scheduler().addEvent(createSchedulerTask(std::max(1000, nextScheduledTime * 1000), std::bind(&GlobalEvents::timer, this))); } } @@ -196,7 +196,7 @@ void GlobalEvents::think() { } if (nextScheduledTime != std::numeric_limits::max()) { - thinkEventId = g_scheduler.addEvent(createSchedulerTask(nextScheduledTime, std::bind(&GlobalEvents::think, this))); + thinkEventId = g_scheduler().addEvent(createSchedulerTask(nextScheduledTime, std::bind(&GlobalEvents::think, this))); } } diff --git a/src/lua/global/globalevent.h b/src/lua/global/globalevent.h index 0bbbcb01d7c..0d0b41c07b9 100644 --- a/src/lua/global/globalevent.h +++ b/src/lua/global/globalevent.h @@ -36,6 +36,13 @@ class GlobalEvents final : public BaseEvents { GlobalEvents(const GlobalEvents&) = delete; GlobalEvents& operator=(const GlobalEvents&) = delete; + static GlobalEvents& getInstance() { + // Guaranteed to be destroyed + static GlobalEvents instance; + // Instantiated on first use + return instance; + } + void startup() const; void timer(); @@ -65,6 +72,8 @@ class GlobalEvents final : public BaseEvents { int32_t thinkEventId = 0, timerEventId = 0; }; +constexpr auto g_globalEvents = &GlobalEvents::getInstance; + class GlobalEvent final : public Event { public: explicit GlobalEvent(LuaScriptInterface* interface); diff --git a/src/lua/modules/modules.h b/src/lua/modules/modules.h index 4a4b85cafbd..10bc785350e 100644 --- a/src/lua/modules/modules.h +++ b/src/lua/modules/modules.h @@ -74,6 +74,13 @@ class Modules final : public BaseEvents { Modules(const Modules&) = delete; Modules& operator=(const Modules&) = delete; + static Modules& getInstance() { + // Guaranteed to be destroyed + static Modules instance; + // Instantiated on first use + return instance; + } + void executeOnRecvbyte(uint32_t playerId, NetworkMessage& msg, uint8_t byte) const; Module* getEventByRecvbyte(uint8_t recvbyte, bool force); @@ -90,4 +97,6 @@ class Modules final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_modules = &Modules::getInstance; + #endif // SRC_LUA_MODULES_MODULES_H_ diff --git a/src/lua/scripts/lua_environment.hpp b/src/lua/scripts/lua_environment.hpp index 2cc9f47225b..75e636747f5 100644 --- a/src/lua/scripts/lua_environment.hpp +++ b/src/lua/scripts/lua_environment.hpp @@ -82,4 +82,6 @@ class LuaEnvironment: public LuaScriptInterface { friend class CombatSpell; }; +inline LuaEnvironment g_luaEnvironment; + #endif // SRC_LUA_SCRIPTS_LUA_ENVIRONMENT_HPP_ diff --git a/src/lua/scripts/luascript.cpp b/src/lua/scripts/luascript.cpp index f7170242a9c..970c49607d8 100644 --- a/src/lua/scripts/luascript.cpp +++ b/src/lua/scripts/luascript.cpp @@ -27,7 +27,6 @@ ScriptEnvironment::DBResultMap ScriptEnvironment::tempResults; uint32_t ScriptEnvironment::lastResultId = 0; std::multimap ScriptEnvironment::tempItems; -LuaEnvironment g_luaEnvironment; ScriptEnvironment LuaFunctionsLoader::scriptEnv[16]; int32_t LuaFunctionsLoader::scriptEnvIndex = -1; diff --git a/src/lua/scripts/scripts.cpp b/src/lua/scripts/scripts.cpp index 52de60f12a8..305ac0abcad 100644 --- a/src/lua/scripts/scripts.cpp +++ b/src/lua/scripts/scripts.cpp @@ -34,21 +34,6 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/scripts.h" -Actions* g_actions = nullptr; -CreatureEvents* g_creatureEvents = nullptr; -Chat* g_chat = nullptr; -Events* g_events = nullptr; -GlobalEvents* g_globalEvents = nullptr; -Spells* g_spells = nullptr; -TalkActions* g_talkActions = nullptr; -MoveEvents* g_moveEvents = nullptr; -Weapons* g_weapons = nullptr; -Scripts* g_scripts = nullptr; -Modules* g_modules = nullptr; -Imbuements* g_imbuements = nullptr; - -extern LuaEnvironment g_luaEnvironment; - Scripts::Scripts() : scriptInterface("Scripts Interface") { scriptInterface.initState(); @@ -56,62 +41,6 @@ Scripts::Scripts() : Scripts::~Scripts() { scriptInterface.reInitState(); - - delete g_events; - delete g_weapons; - delete g_spells; - delete g_actions; - delete g_talkActions; - delete g_moveEvents; - delete g_chat; - delete g_creatureEvents; - delete g_globalEvents; - delete g_imbuements; -} - -bool Scripts::loadScriptSystems() { - g_chat = new Chat(); - - // XML loads disabled start - g_weapons = new Weapons(); - if (!g_weapons) { - return false; - } - - g_weapons->loadDefaults(); - - g_spells = new Spells(); - if (!g_spells) { - return false; - } - - g_actions = new Actions(); - if (!g_actions) { - return false; - } - - g_talkActions = new TalkActions(); - if (!g_talkActions) { - return false; - } - - g_moveEvents = new MoveEvents(); - if (!g_moveEvents) { - return false; - } - - g_creatureEvents = new CreatureEvents(); - if (!g_creatureEvents) { - return false; - } - - g_globalEvents = new GlobalEvents(); - if (!g_globalEvents) { - return false; - } - // XML loads disabled end - - return true; } bool Scripts::loadEventSchedulerScripts(const std::string& fileName) { diff --git a/src/lua/scripts/scripts.h b/src/lua/scripts/scripts.h index 070a165d3db..450744c4133 100644 --- a/src/lua/scripts/scripts.h +++ b/src/lua/scripts/scripts.h @@ -33,13 +33,14 @@ class Scripts { Scripts& operator=(const Scripts&) = delete; static Scripts& getInstance() { + // Guaranteed to be destroyed static Scripts instance; + // Instantiated on first use return instance; } bool loadEventSchedulerScripts(const std::string& fileName); bool loadScripts(std::string folderName, bool isLib, bool reload); - bool loadScriptSystems(); LuaScriptInterface& getScriptInterface() { return scriptInterface; } @@ -47,4 +48,6 @@ class Scripts { LuaScriptInterface scriptInterface; }; +constexpr auto g_scripts = &Scripts::getInstance; + #endif // SRC_LUA_SCRIPTS_SCRIPTS_H_ diff --git a/src/otserv.cpp b/src/otserv.cpp index aa36a43ff89..ae45fed37ef 100644 --- a/src/otserv.cpp +++ b/src/otserv.cpp @@ -31,6 +31,7 @@ #include "database/databasetasks.h" #include "game/game.h" #include "game/scheduling/scheduler.h" +#include "game/scheduling/tasks.h" #include "io/iomarket.h" #include "lua/creature/events.h" #include "lua/modules/modules.h" @@ -46,20 +47,6 @@ #include "gitmetadata.h" #endif -DatabaseTasks g_databaseTasks; -Dispatcher g_dispatcher; -Scheduler g_scheduler; - -extern Events* g_events; -extern Imbuements* g_imbuements; -extern LuaEnvironment g_luaEnvironment; -extern Modules* g_modules; -Monsters g_monsters; -Npcs g_npcs; -Vocations g_vocations; -extern Scripts* g_scripts; -RSA2 g_RSA; - std::mutex g_loaderLock; std::condition_variable g_loaderSignal; std::unique_lock g_loaderUniqueLock(g_loaderLock); @@ -96,13 +83,6 @@ void badAllocationHandler() { exit(-1); } -void initGlobalScopes() { - g_scripts = new Scripts(); - g_modules = new Modules(); - g_events = new Events(); - g_imbuements = new Imbuements(); -} - void modulesLoadHelper(bool loaded, std::string moduleName) { SPDLOG_INFO("Loading {}", moduleName); if (!loaded) { @@ -120,7 +100,7 @@ void loadModules() { // set RSA key try { - g_RSA.loadPEM("key.pem"); + g_RSA().loadPEM("key.pem"); } catch(const std::exception& e) { SPDLOG_ERROR(e.what()); startupErrorMessage(); @@ -142,7 +122,7 @@ void loadModules() { startupErrorMessage(); } - g_databaseTasks.start(); + g_databaseTasks().start(); DatabaseManager::updateDatabase(); if (g_configManager().getBoolean(OPTIMIZE_DATABASE) @@ -154,8 +134,6 @@ void loadModules() { "items.otb"); modulesLoadHelper(Item::items.loadFromXml(), "items.xml"); - modulesLoadHelper(Scripts::getInstance().loadScriptSystems(), - "script systems"); // Lua Env modulesLoadHelper((g_luaEnvironment.loadFile("data/global.lua") == 0), @@ -167,9 +145,9 @@ void loadModules() { modulesLoadHelper((g_luaEnvironment.loadFile("data/npclib/load.lua") == 0), "data/npclib/load.lua"); - modulesLoadHelper(g_scripts->loadScripts("scripts/lib", true, false), + modulesLoadHelper(g_scripts().loadScripts("scripts/lib", true, false), "data/scripts/libs"); - modulesLoadHelper(g_vocations.loadFromXml(), + modulesLoadHelper(g_vocations().loadFromXml(), "data/XML/vocations.xml"); modulesLoadHelper(g_game().loadScheduleEventFromXml(), "data/XML/events.xml"); @@ -177,18 +155,18 @@ void loadModules() { "data/XML/outfits.xml"); modulesLoadHelper(Familiars::getInstance().loadFromXml(), "data/XML/familiars.xml"); - modulesLoadHelper(g_imbuements->loadFromXml(), + modulesLoadHelper(g_imbuements().loadFromXml(), "data/XML/imbuements.xml"); - modulesLoadHelper(g_modules->loadFromXml(), + modulesLoadHelper(g_modules().loadFromXml(), "data/modules/modules.xml"); - modulesLoadHelper(g_events->loadFromXml(), + modulesLoadHelper(g_events().loadFromXml(), "data/events/events.xml"); - modulesLoadHelper(g_scripts->loadScripts("scripts", false, false), + modulesLoadHelper(g_scripts().loadScripts("scripts", false, false), "data/scripts"); - modulesLoadHelper(g_scripts->loadScripts("monster", false, false), + modulesLoadHelper(g_scripts().loadScripts("monster", false, false), "data/monster"); - modulesLoadHelper(g_scripts->loadScripts("npc", false, false), - "data/npc"); + modulesLoadHelper(g_scripts().loadScripts("npc", false, false), + "data/npclua"); g_game().loadBoostedCreature(); } @@ -209,10 +187,10 @@ int main(int argc, char* argv[]) { ServiceManager serviceManager; - g_dispatcher.start(); - g_scheduler.start(); + g_dispatcher().start(); + g_scheduler().start(); - g_dispatcher.addTask(createTask(std::bind(mainLoader, argc, argv, + g_dispatcher().addTask(createTask(std::bind(mainLoader, argc, argv, &serviceManager))); g_loaderSignal.wait(g_loaderUniqueLock); @@ -223,14 +201,14 @@ int main(int argc, char* argv[]) { serviceManager.run(); } else { SPDLOG_ERROR("No services running. The server is NOT online!"); - g_databaseTasks.shutdown(); - g_dispatcher.shutdown(); + g_databaseTasks().shutdown(); + g_dispatcher().shutdown(); exit(-1); } - g_scheduler.join(); - g_databaseTasks.join(); - g_dispatcher.join(); + g_scheduler().join(); + g_databaseTasks().join(); + g_dispatcher().join(); return 0; } #endif @@ -292,7 +270,6 @@ void mainLoader(int, char*[], ServiceManager* services) { } // Init and load modules - initGlobalScopes(); loadModules(); #ifdef _WIN32 diff --git a/src/security/rsa.cpp b/src/security/rsa.cpp index 493a36da415..4664de4cde5 100644 --- a/src/security/rsa.cpp +++ b/src/security/rsa.cpp @@ -29,13 +29,13 @@ static CryptoPP::AutoSeededRandomPool prng; -void RSA2::decrypt(char* msg) const +void RSA2::decrypt(uint8_t* msg) const { try { - CryptoPP::Integer m{reinterpret_cast(msg), 128}; + CryptoPP::Integer m{msg, 128}; auto c = pk.CalculateInverse(prng, m); - c.Encode(reinterpret_cast(msg), 128); + c.Encode(msg, 128); } catch (const CryptoPP::Exception &e) { diff --git a/src/security/rsa.h b/src/security/rsa.h index 0d95b4bb45e..c5e351ee824 100644 --- a/src/security/rsa.h +++ b/src/security/rsa.h @@ -33,11 +33,20 @@ class RSA2 RSA2(const RSA2&) = delete; RSA2& operator=(const RSA2&) = delete; + static RSA2& getInstance() { + // Guaranteed to be destroyed + static RSA2 instance; + // Instantiated on first use + return instance; + } + void loadPEM(const std::string& filename); - void decrypt(char* msg) const; + void decrypt(uint8_t* msg) const; private: CryptoPP::RSA::PrivateKey pk; }; +constexpr auto g_RSA = &RSA2::getInstance; + #endif // SRC_SECURITY_RSA_H_ diff --git a/src/server/network/connection/connection.cpp b/src/server/network/connection/connection.cpp index 76711cb1e42..3924ea2e6a5 100644 --- a/src/server/network/connection/connection.cpp +++ b/src/server/network/connection/connection.cpp @@ -69,7 +69,7 @@ void Connection::close(bool force) connectionState = CONNECTION_STATE_DISCONNECTED; if (protocol) { - g_dispatcher.addTask( + g_dispatcher().addTask( createTask(std::bind(&Protocol::release, protocol))); } @@ -103,7 +103,7 @@ Connection::~Connection() void Connection::accept(Protocol_ptr conProtocol) { this->protocol = conProtocol; - g_dispatcher.addTask(createTask(std::bind(&Protocol::onConnect, protocol))); + g_dispatcher().addTask(createTask(std::bind(&Protocol::onConnect, protocol))); connectionState = CONNECTION_STATE_CONNECTING_STAGE2; accept(); diff --git a/src/server/network/message/outputmessage.cpp b/src/server/network/message/outputmessage.cpp index b25c3160aed..d06a409c976 100644 --- a/src/server/network/message/outputmessage.cpp +++ b/src/server/network/message/outputmessage.cpp @@ -24,7 +24,6 @@ #include "utils/lockfree.h" #include "game/scheduling/scheduler.h" -extern Scheduler g_scheduler; const uint16_t OUTPUTMESSAGE_FREE_LIST_CAPACITY = 2048; const std::chrono::milliseconds OUTPUTMESSAGE_AUTOSEND_DELAY {10}; @@ -32,7 +31,7 @@ const std::chrono::milliseconds OUTPUTMESSAGE_AUTOSEND_DELAY {10}; void OutputMessagePool::scheduleSendAll() { auto functor = std::bind(&OutputMessagePool::sendAll, this); - g_scheduler.addEvent(createSchedulerTask(OUTPUTMESSAGE_AUTOSEND_DELAY.count(), functor)); + g_scheduler().addEvent(createSchedulerTask(OUTPUTMESSAGE_AUTOSEND_DELAY.count(), functor)); } void OutputMessagePool::sendAll() diff --git a/src/server/network/protocol/protocol.cpp b/src/server/network/protocol/protocol.cpp index bd15bb598e4..59112f18b5b 100644 --- a/src/server/network/protocol/protocol.cpp +++ b/src/server/network/protocol/protocol.cpp @@ -24,7 +24,6 @@ #include "security/rsa.h" #include "security/xtea.h" -extern RSA2 g_RSA; void Protocol::onSendMessage(const OutputMessage_ptr& msg) { @@ -99,7 +98,7 @@ bool Protocol::RSA_decrypt(NetworkMessage& msg) return false; } - g_RSA.decrypt(reinterpret_cast(msg.getBuffer()) + msg.getBufferPosition()); //does not break strict aliasing + g_RSA().decrypt(msg.getBuffer() + msg.getBufferPosition()); //does not break strict aliasing return msg.getByte() == 0; } diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 914be3456d0..7e08feb2aaf 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -39,25 +39,17 @@ #include "creatures/players/management/waitlist.h" #include "items/weapons/weapons.h" -extern Actions actions; -extern CreatureEvents *g_creatureEvents; -extern Vocations g_vocations; -extern Chat *g_chat; -extern Modules *g_modules; -extern Spells *g_spells; -extern Imbuements *g_imbuements; -extern Monsters g_monsters; template void ProtocolGame::addGameTask(Callable function, Args &&... args) { - g_dispatcher.addTask(createTask(std::bind(function, &g_game(), std::forward(args)...))); + g_dispatcher().addTask(createTask(std::bind(function, &g_game(), std::forward(args)...))); } template void ProtocolGame::addGameTaskTimed(uint32_t delay, Callable function, Args &&... args) { - g_dispatcher.addTask(createTask(delay, std::bind(function, &g_game(), std::forward(args)...))); + g_dispatcher().addTask(createTask(delay, std::bind(function, &g_game(), std::forward(args)...))); } void ProtocolGame::AddItem(NetworkMessage &msg, uint16_t id, uint8_t count) @@ -363,7 +355,7 @@ void ProtocolGame::login(const std::string &name, uint32_t accountId, OperatingS foundPlayer->disconnect(); foundPlayer->isConnecting = true; - eventConnect = g_scheduler.addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::connect, getThis(), foundPlayer->getID(), operatingSystem))); + eventConnect = g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::connect, getThis(), foundPlayer->getID(), operatingSystem))); } else { @@ -394,7 +386,7 @@ void ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem) player = foundPlayer; player->incrementReferenceCounter(); - g_chat->removeUserFromAllChannels(*player); + g_chat().removeUserFromAllChannels(*player); player->clearModalWindows(); player->setOperatingSystem(operatingSystem); player->isConnecting = false; @@ -426,7 +418,7 @@ void ProtocolGame::logout(bool displayEffect, bool forced) } } - if (removePlayer && !g_creatureEvents->playerLogout(player)) { + if (removePlayer && !g_creatureEvents().playerLogout(player)) { return; } @@ -553,7 +545,7 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg) return; } - g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::login, getThis(), characterName, accountId, operatingSystem))); + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::login, getThis(), characterName, accountId, operatingSystem))); } void ProtocolGame::onConnect() @@ -640,18 +632,18 @@ void ProtocolGame::parsePacket(NetworkMessage& msg) if (recvbyte != 0x1D && recvbyte != 0x1E) { // keep the connection alive - g_scheduler.addEvent(createSchedulerTask(500, std::bind(&ProtocolGame::sendPing, getThis()))); - g_scheduler.addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::sendPingBack, getThis()))); + g_scheduler().addEvent(createSchedulerTask(500, std::bind(&ProtocolGame::sendPing, getThis()))); + g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::sendPingBack, getThis()))); return; } } // Modules system if(player && recvbyte != 0xD3){ - g_dispatcher.addTask(createTask(std::bind(&Modules::executeOnRecvbyte, g_modules, player->getID(), msg, recvbyte))); + g_dispatcher().addTask(createTask(std::bind(&Modules::executeOnRecvbyte, &g_modules(), player->getID(), msg, recvbyte))); } - g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte))); + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte))); } void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyte) @@ -665,7 +657,7 @@ void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyt } switch (recvbyte) { - case 0x14: g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::logout, getThis(), true, false))); break; + case 0x14: g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::logout, getThis(), true, false))); break; case 0x1D: addGameTask(&Game::playerReceivePingBack, player->getID()); break; case 0x1E: addGameTask(&Game::playerReceivePing, player->getID()); break; case 0x2a: addBestiaryTrackerList(msg); break; @@ -743,8 +735,8 @@ void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyt case 0xCC: parseSeekInContainer(msg); break; case 0xCD: parseInspectionObject(msg); break; case 0xD2: addGameTask(&Game::playerRequestOutfit, player->getID()); break; - //g_dispatcher.addTask(createTask(std::bind(&Modules::executeOnRecvbyte, g_modules, player, msg, recvbyte))); - case 0xD3: g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::parseSetOutfit, getThis(), msg))); break; + //g_dispatcher().addTask(createTask(std::bind(&Modules::executeOnRecvbyte, g_modules, player, msg, recvbyte))); + case 0xD3: g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parseSetOutfit, getThis(), msg))); break; case 0xD4: parseToggleMount(msg); break; case 0xD5: parseApplyImbuement(msg); break; case 0xD6: parseClearImbuement(msg); break; @@ -1137,7 +1129,7 @@ void ProtocolGame::parseSetOutfit(NetworkMessage &msg) } uint16_t startBufferPosition = msg.getBufferPosition(); - Module *outfitModule = g_modules->getEventByRecvbyte(0xD3, false); + Module *outfitModule = g_modules().getEventByRecvbyte(0xD3, false); if (outfitModule) { outfitModule->executeOnRecvbyte(player, msg); @@ -1639,7 +1631,7 @@ void ProtocolGame::sendHighscores(const std::vector &charact msg.addString("(all)"); // All Vocations - hardcoded uint32_t selectedVocation = 0xFFFFFFFF; - const auto &vocationsMap = g_vocations.getVocations(); + const auto &vocationsMap = g_vocations().getVocations(); for (const auto &it : vocationsMap) { const Vocation &vocation = it.second; @@ -1771,7 +1763,7 @@ void ProtocolGame::parseBestiarysendRaces() uint16_t count = 0; for (auto rit : mtype_list) { - MonsterType *mtype = g_monsters.getMonsterType(rit.second); + const MonsterType *mtype = g_monsters().getMonsterType(rit.second); if (!mtype) { return; @@ -1811,7 +1803,7 @@ void ProtocolGame::parseBestiarysendMonsterData(NetworkMessage &msg) auto ait = mtype_list.find(raceId); if (ait != mtype_list.end()) { - MonsterType *mType = g_monsters.getMonsterType(ait->second); + MonsterType *mType = g_monsters().getMonsterType(ait->second); if (mType) { Class = mType->info.bestiaryClass; @@ -1945,7 +1937,7 @@ void ProtocolGame::addBestiaryTrackerList(NetworkMessage &msg) auto it = mtype_list.find(thisrace); if (it != mtype_list.end()) { - MonsterType *mtype = g_monsters.getMonsterType(it->second); + MonsterType *mtype = g_monsters().getMonsterType(it->second); if (mtype) { player->addBestiaryTrackerList(mtype); @@ -2456,7 +2448,7 @@ void ProtocolGame::parseBestiarysendCreatures(NetworkMessage &msg) { if (_it.first == raceid_) { - MonsterType *tmpType = g_monsters.getMonsterType(it_.second); + MonsterType *tmpType = g_monsters().getMonsterType(it_.second); if (!tmpType) { return; @@ -3516,7 +3508,7 @@ void ProtocolGame::sendBasicData() msg.addByte(1); // has reached Main (allow player to open Prey window) } - std::list spellsList = g_spells->getSpellsByVocation(player->getVocationId()); + std::list spellsList = g_spells().getSpellsByVocation(player->getVocationId()); msg.add(spellsList.size()); for (uint16_t sid : spellsList) { @@ -3694,7 +3686,7 @@ void ProtocolGame::sendChannelsDialog() NetworkMessage msg; msg.addByte(0xAB); - const ChannelList &list = g_chat->getChannelList(*player); + const ChannelList &list = g_chat().getChannelList(*player); msg.addByte(list.size()); for (ChatChannel *channel : list) { @@ -4160,7 +4152,7 @@ void ProtocolGame::updateCoinBalance() return; } - g_dispatcher.addTask( + g_dispatcher().addTask( createTask(std::bind([](uint32_t playerId) { Player* threadPlayer = g_game().getPlayerByID(playerId); if (threadPlayer) { @@ -6508,11 +6500,11 @@ void ProtocolGame::AddOutfit(NetworkMessage &msg, const Outfit_t &outfit, bool a } } -void ProtocolGame::addImbuementInfo(NetworkMessage &msg, uint32_t imbuementId) +void ProtocolGame::addImbuementInfo(NetworkMessage &msg, uint16_t imbuementId) const { - Imbuement *imbuement = g_imbuements->getImbuement(imbuementId); - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuement->getBaseID()); - CategoryImbuement *categoryImbuement = g_imbuements->getCategoryByID(imbuement->getCategory()); + Imbuement *imbuement = g_imbuements().getImbuement(imbuementId); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuement->getBaseID()); + const CategoryImbuement *categoryImbuement = g_imbuements().getCategoryByID(imbuement->getCategory()); msg.add(imbuementId); msg.addString(baseImbuement->name + " " + imbuement->getName()); @@ -6570,10 +6562,10 @@ void ProtocolGame::openImbuementWindow(Item *item) msg.addByte(0x01); addImbuementInfo(msg, imbuementInfo.imbuement->getID()); msg.add(imbuementInfo.duration); - msg.add(g_imbuements->getBaseByID(imbuementInfo.imbuement->getBaseID())->removeCost); + msg.add(g_imbuements().getBaseByID(imbuementInfo.imbuement->getBaseID())->removeCost); } - std::vector imbuements = g_imbuements->getImbuements(player, item); + std::vector imbuements = g_imbuements().getImbuements(player, item); std::unordered_map needItems; msg.add(imbuements.size()); diff --git a/src/server/network/protocol/protocolgame.h b/src/server/network/protocol/protocolgame.h index 8fa2e3257ee..b2f117ec61c 100644 --- a/src/server/network/protocol/protocolgame.h +++ b/src/server/network/protocol/protocolgame.h @@ -233,7 +233,7 @@ class ProtocolGame final : public Protocol void parseCoinTransfer(NetworkMessage &msg); // Imbuement info - void addImbuementInfo(NetworkMessage &msg, uint32_t imbuementId); + void addImbuementInfo(NetworkMessage &msg, uint16_t imbuementId) const; //Send functions void sendChannelMessage(const std::string &author, const std::string &text, SpeakClasses type, uint16_t channel); diff --git a/src/server/network/protocol/protocollogin.cpp b/src/server/network/protocol/protocollogin.cpp index 766a74abff4..2532289d8ee 100644 --- a/src/server/network/protocol/protocollogin.cpp +++ b/src/server/network/protocol/protocollogin.cpp @@ -187,5 +187,5 @@ void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) } auto thisPtr = std::static_pointer_cast(shared_from_this()); - g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::getCharacterList, thisPtr, email, password, version))); + g_dispatcher().addTask(createTask(std::bind(&ProtocolLogin::getCharacterList, thisPtr, email, password, version))); } diff --git a/src/server/network/protocol/protocolstatus.cpp b/src/server/network/protocol/protocolstatus.cpp index 1de279408c4..e8bf050ccda 100644 --- a/src/server/network/protocol/protocolstatus.cpp +++ b/src/server/network/protocol/protocolstatus.cpp @@ -49,7 +49,7 @@ void ProtocolStatus::onRecvFirstMessage(NetworkMessage& msg) //XML info protocol case 0xFF: { if (msg.getString(4) == "info") { - g_dispatcher.addTask(createTask(std::bind( + g_dispatcher().addTask(createTask(std::bind( &ProtocolStatus::sendStatusString, std::static_pointer_cast< ProtocolStatus>(shared_from_this())))); @@ -65,7 +65,7 @@ void ProtocolStatus::onRecvFirstMessage(NetworkMessage& msg) if (requestedInfo & REQUEST_PLAYER_STATUS_INFO) { characterName = msg.getString(); } - g_dispatcher.addTask(createTask(std::bind(&ProtocolStatus::sendInfo, std::static_pointer_cast(shared_from_this()), + g_dispatcher().addTask(createTask(std::bind(&ProtocolStatus::sendInfo, std::static_pointer_cast(shared_from_this()), requestedInfo, characterName))); return; } diff --git a/src/server/server.cpp b/src/server/server.cpp index a4de00f007a..7672bcc1fe0 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -124,7 +124,7 @@ void ServicePort::onAccept(Connection_ptr connection, const boost::system::error if (!pendingStart) { close(); pendingStart = true; - g_scheduler.addEvent(createSchedulerTask(15000, + g_scheduler().addEvent(createSchedulerTask(15000, std::bind(&ServicePort::openAcceptor, std::weak_ptr(shared_from_this()), serverPort))); @@ -187,7 +187,7 @@ void ServicePort::open(uint16_t port) SPDLOG_WARN("[ServicePort::open] - Error: {}", e.what()); pendingStart = true; - g_scheduler.addEvent(createSchedulerTask(15000, + g_scheduler().addEvent(createSchedulerTask(15000, std::bind(&ServicePort::openAcceptor, std::weak_ptr(shared_from_this()), port))); } } diff --git a/src/server/signals.cpp b/src/server/signals.cpp index da0cd7d5488..8f98a0bf77e 100644 --- a/src/server/signals.cpp +++ b/src/server/signals.cpp @@ -35,20 +35,6 @@ #include "lua/scripts/lua_environment.hpp" #include "server/signals.h" -extern Scheduler g_scheduler; -extern DatabaseTasks g_databaseTasks; -extern Dispatcher g_dispatcher; - -extern Actions* g_actions; -extern Monsters g_monsters; -extern TalkActions* g_talkActions; -extern Spells* g_spells; -extern CreatureEvents* g_creatureEvents; -extern GlobalEvents* g_globalEvents; -extern Events* g_events; -extern Chat* g_chat; -extern LuaEnvironment g_luaEnvironment; - using ErrorCode = boost::system::error_code; Signals::Signals(boost::asio::io_service& service) : @@ -89,25 +75,25 @@ void Signals::dispatchSignalHandler(int signal) { switch(signal) { case SIGINT: //Shuts the server down - g_dispatcher.addTask(createTask(sigintHandler)); + g_dispatcher().addTask(createTask(sigintHandler)); break; case SIGTERM: //Shuts the server down - g_dispatcher.addTask(createTask(sigtermHandler)); + g_dispatcher().addTask(createTask(sigtermHandler)); break; #ifndef _WIN32 case SIGHUP: //Reload config/data - g_dispatcher.addTask(createTask(sighupHandler)); + g_dispatcher().addTask(createTask(sighupHandler)); break; case SIGUSR1: //Saves game state - g_dispatcher.addTask(createTask(sigusr1Handler)); + g_dispatcher().addTask(createTask(sigusr1Handler)); break; #else case SIGBREAK: //Shuts the server down - g_dispatcher.addTask(createTask(sigbreakHandler)); + g_dispatcher().addTask(createTask(sigbreakHandler)); // hold the thread until other threads end - g_scheduler.join(); - g_databaseTasks.join(); - g_dispatcher.join(); + g_scheduler().join(); + g_databaseTasks().join(); + g_dispatcher().join(); break; #endif default: @@ -154,10 +140,10 @@ void Signals::sighupHandler() g_game().mounts.reload(); SPDLOG_INFO("Reloaded mounts"); - g_events->loadFromXml(); + g_events().loadFromXml(); SPDLOG_INFO("Reloaded events"); - g_chat->load(); + g_chat().load(); SPDLOG_INFO("Reloaded chatchannels"); g_luaEnvironment.loadFile("data/global.lua");