From ef72e29060101cb04ac876e959bb896f4a1dbf52 Mon Sep 17 00:00:00 2001 From: Matt Gomez Date: Thu, 28 Sep 2023 13:01:55 -0600 Subject: [PATCH] update to : https://github.com/opentibiabr/canary/commit/f7fe5d202cbbe1013d14f8662cc1b90c00ce5183 --- config.lua.dist | 9 +- schema.sql | 20 +- src/account/account.cpp | 6 +- src/canary_server.cpp | 77 +- src/config/config_definitions.hpp | 2 + src/config/configmanager.cpp | 4 + src/core.hpp | 2 +- src/creatures/combat/combat.cpp | 278 ++- src/creatures/combat/combat.hpp | 132 +- src/creatures/combat/condition.cpp | 306 ++-- src/creatures/combat/condition.hpp | 196 +- src/creatures/combat/spells.cpp | 87 +- src/creatures/combat/spells.hpp | 62 +- src/creatures/creature.cpp | 375 ++-- src/creatures/creature.hpp | 219 +-- src/creatures/interactions/chat.cpp | 136 +- src/creatures/interactions/chat.hpp | 44 +- src/creatures/monsters/monster.cpp | 423 +++-- src/creatures/monsters/monster.hpp | 124 +- src/creatures/monsters/monsters.cpp | 18 +- src/creatures/monsters/monsters.hpp | 2 +- .../monsters/spawns/spawn_monster.cpp | 23 +- .../monsters/spawns/spawn_monster.hpp | 4 +- src/creatures/npcs/npc.cpp | 131 +- src/creatures/npcs/npc.hpp | 64 +- src/creatures/npcs/npcs.cpp | 12 +- src/creatures/npcs/npcs.hpp | 8 +- src/creatures/npcs/spawns/spawn_npc.cpp | 39 +- src/creatures/npcs/spawns/spawn_npc.hpp | 14 +- src/creatures/players/grouping/guild.cpp | 9 +- src/creatures/players/grouping/guild.hpp | 11 +- src/creatures/players/grouping/party.cpp | 378 ++-- src/creatures/players/grouping/party.hpp | 92 +- .../players/grouping/team_finder.hpp | 2 + .../players/imbuements/imbuements.cpp | 2 +- .../players/imbuements/imbuements.hpp | 2 +- src/creatures/players/management/waitlist.cpp | 6 +- src/creatures/players/management/waitlist.hpp | 6 +- src/creatures/players/player.cpp | 1227 ++++++------- src/creatures/players/player.hpp | 479 +++-- src/creatures/players/wheel/player_wheel.cpp | 81 +- src/creatures/players/wheel/player_wheel.hpp | 9 +- src/database/database.cpp | 44 +- src/database/database.hpp | 2 + src/game/bank/bank.cpp | 46 +- src/game/bank/bank.hpp | 9 +- src/game/game.cpp | 1629 +++++++++-------- src/game/game.hpp | 325 ++-- src/game/movement/teleport.cpp | 36 +- src/game/movement/teleport.hpp | 31 +- src/game/scheduling/dispatcher.cpp | 8 +- src/game/scheduling/dispatcher.hpp | 4 +- src/game/scheduling/task.hpp | 12 + src/game/zones/zone.cpp | 48 +- src/game/zones/zone.hpp | 29 +- src/io/functions/iologindata_load_player.cpp | 126 +- src/io/functions/iologindata_load_player.hpp | 58 +- src/io/functions/iologindata_save_player.cpp | 58 +- src/io/functions/iologindata_save_player.hpp | 38 +- src/io/io_bosstiary.cpp | 9 +- src/io/io_bosstiary.hpp | 8 +- src/io/io_wheel.cpp | 90 +- src/io/io_wheel.hpp | 80 +- src/io/iobestiary.cpp | 36 +- src/io/iobestiary.hpp | 22 +- src/io/iologindata.cpp | 13 +- src/io/iologindata.hpp | 12 +- src/io/iomapserialize.cpp | 122 +- src/io/iomapserialize.hpp | 8 +- src/io/iomarket.cpp | 17 +- src/io/ioprey.cpp | 44 +- src/io/ioprey.hpp | 26 +- src/items/bed.cpp | 48 +- src/items/bed.hpp | 27 +- src/items/containers/container.cpp | 286 +-- src/items/containers/container.hpp | 109 +- src/items/containers/depot/depotchest.cpp | 25 +- src/items/containers/depot/depotchest.hpp | 14 +- src/items/containers/depot/depotlocker.cpp | 18 +- src/items/containers/depot/depotlocker.hpp | 17 +- src/items/containers/inbox/inbox.cpp | 25 +- src/items/containers/inbox/inbox.hpp | 14 +- src/items/containers/mailbox/mailbox.cpp | 45 +- src/items/containers/mailbox/mailbox.hpp | 35 +- src/items/containers/rewards/reward.cpp | 18 +- src/items/containers/rewards/reward.hpp | 19 +- src/items/containers/rewards/rewardchest.cpp | 20 +- src/items/containers/rewards/rewardchest.hpp | 15 +- src/items/cylinder.cpp | 10 +- src/items/cylinder.hpp | 60 +- src/items/decay/decay.cpp | 34 +- src/items/decay/decay.hpp | 9 +- src/items/functions/item/item_parse.cpp | 9 +- src/items/functions/item/item_parse.hpp | 2 +- src/items/item.cpp | 168 +- src/items/item.hpp | 133 +- src/items/items.cpp | 4 + src/items/items.hpp | 4 +- src/items/thing.cpp | 14 +- src/items/thing.hpp | 31 +- src/items/tile.cpp | 361 ++-- src/items/tile.hpp | 137 +- src/items/trashholder.cpp | 30 +- src/items/trashholder.hpp | 29 +- src/items/weapons/weapons.cpp | 64 +- src/items/weapons/weapons.hpp | 52 +- src/kv/kv.cpp | 12 +- src/kv/kv.hpp | 3 + src/kv/kv_sql.cpp | 28 +- src/kv/kv_sql.hpp | 8 +- src/kv/value_wrapper.hpp | 15 + src/lua/callbacks/creaturecallback.cpp | 14 +- src/lua/callbacks/creaturecallback.hpp | 12 +- src/lua/callbacks/event_callback.cpp | 90 +- src/lua/callbacks/event_callback.hpp | 82 +- src/lua/callbacks/events_callbacks.hpp | 18 +- src/lua/creature/actions.cpp | 48 +- src/lua/creature/actions.hpp | 26 +- src/lua/creature/creatureevent.cpp | 30 +- src/lua/creature/creatureevent.hpp | 30 +- src/lua/creature/events.cpp | 78 +- src/lua/creature/events.hpp | 70 +- src/lua/creature/movement.cpp | 156 +- src/lua/creature/movement.hpp | 54 +- src/lua/creature/raids.cpp | 15 +- src/lua/creature/talkaction.cpp | 6 +- src/lua/creature/talkaction.hpp | 6 +- .../functions/core/game/bank_functions.cpp | 16 +- .../functions/core/game/config_functions.cpp | 2 + .../functions/core/game/game_functions.cpp | 51 +- .../functions/core/game/global_functions.cpp | 68 +- src/lua/functions/core/game/lua_enums.cpp | 9 + src/lua/functions/core/game/lua_enums.hpp | 1 + .../core/game/modal_window_functions.cpp | 45 +- .../core/game/modal_window_functions.hpp | 5 +- .../functions/core/game/zone_functions.cpp | 6 +- .../network/network_message_functions.cpp | 59 +- .../network/network_message_functions.hpp | 6 +- .../creatures/combat/combat_functions.cpp | 29 +- .../creatures/combat/combat_functions.hpp | 2 +- .../creatures/combat/condition_functions.cpp | 31 +- .../creatures/combat/condition_functions.hpp | 2 +- .../creatures/combat/spell_functions.cpp | 34 +- .../creatures/combat/variant_functions.cpp | 2 +- .../creatures/creature_functions.cpp | 186 +- .../creatures/creature_functions.hpp | 2 +- .../creatures/monster/monster_functions.cpp | 106 +- .../creatures/monster/monster_functions.hpp | 2 +- .../monster/monster_type_functions.cpp | 4 +- .../functions/creatures/npc/npc_functions.cpp | 92 +- .../functions/creatures/npc/npc_functions.hpp | 2 +- .../creatures/npc/npc_type_functions.cpp | 66 +- .../creatures/npc/npc_type_functions.hpp | 2 +- .../creatures/npc/shop_functions.cpp | 48 +- .../creatures/npc/shop_functions.hpp | 6 +- .../creatures/player/guild_functions.cpp | 4 +- .../creatures/player/party_functions.cpp | 60 +- .../creatures/player/party_functions.hpp | 2 +- .../creatures/player/player_functions.cpp | 578 +++--- .../creatures/player/player_functions.hpp | 2 +- .../events/creature_event_functions.cpp | 2 +- .../events/global_event_functions.cpp | 10 +- .../functions/items/container_functions.cpp | 50 +- .../functions/items/container_functions.hpp | 2 +- .../functions/items/imbuement_functions.cpp | 2 +- src/lua/functions/items/item_functions.cpp | 140 +- src/lua/functions/items/item_functions.hpp | 4 +- src/lua/functions/lua_functions_loader.cpp | 42 +- src/lua/functions/lua_functions_loader.hpp | 18 +- src/lua/functions/map/house_functions.cpp | 158 +- src/lua/functions/map/house_functions.hpp | 12 +- src/lua/functions/map/position_functions.cpp | 10 +- src/lua/functions/map/teleport_functions.cpp | 6 +- src/lua/functions/map/teleport_functions.hpp | 2 +- src/lua/functions/map/tile_functions.cpp | 122 +- src/lua/functions/map/tile_functions.hpp | 2 +- src/lua/functions/map/town_functions.cpp | 11 +- src/lua/functions/map/town_functions.hpp | 2 +- src/lua/global/globalevent.cpp | 6 +- src/lua/global/shared_object.hpp | 2 + src/lua/modules/modules.cpp | 6 +- src/lua/modules/modules.hpp | 2 +- src/lua/scripts/lua_environment.cpp | 26 +- src/lua/scripts/lua_environment.hpp | 6 +- src/lua/scripts/luascript.cpp | 2 +- src/lua/scripts/script_environment.cpp | 31 +- src/lua/scripts/script_environment.hpp | 24 +- src/lua/scripts/scripts.cpp | 2 +- src/map/house/house.cpp | 308 ++-- src/map/house/house.hpp | 122 +- src/map/house/housetile.cpp | 46 +- src/map/house/housetile.hpp | 18 +- src/map/map.cpp | 112 +- src/map/map.hpp | 20 +- src/map/mapcache.cpp | 36 +- src/map/mapcache.hpp | 34 +- src/map/town.hpp | 19 +- src/map/utils/astarnodes.cpp | 12 +- src/map/utils/astarnodes.hpp | 2 +- src/map/utils/qtreenode.cpp | 4 +- src/map/utils/qtreenode.hpp | 8 +- src/server/network/protocol/protocol.cpp | 37 +- src/server/network/protocol/protocol.hpp | 1 + src/server/network/protocol/protocolgame.cpp | 385 ++-- src/server/network/protocol/protocolgame.hpp | 120 +- .../network/protocol/protocolstatus.cpp | 2 +- src/utils/tools.cpp | 5 + src/utils/tools.hpp | 1 + src/utils/utils_definitions.hpp | 14 + .../fixture/lib/logging/in_memory_logger.hpp | 104 +- tests/fixture/test_injection.hpp | 14 +- tests/unit/lib/di/soft_singleton_test.cpp | 40 +- tests/unit/lib/logging/in_memory_logger.hpp | 104 +- tests/unit/main.cpp | 2 +- tests/unit/security/rsa_test.cpp | 23 +- tests/unit/utils/position_functions_test.cpp | 52 +- tests/unit/utils/string_functions_test.cpp | 12 +- 217 files changed, 7533 insertions(+), 7154 deletions(-) diff --git a/config.lua.dist b/config.lua.dist index 50914c2b7..84a8dba26 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -230,7 +230,7 @@ maxAllowedOnADummy = 1 toggleSaveInterval = true saveIntervalType = "minute" toggleSaveIntervalCleanMap = true -saveIntervalTime = 15 +saveIntervalTime = 30 -- Imbuement toggleImbuementShrineStorage = false @@ -253,6 +253,11 @@ deathLosePercent = -1 -- Houses -- NOTE: set housePriceEachSQM to -1 to disable the ingame buy house functionality -- NOTE: set houseBuyLevel to 0 to disable the min level purchase functionality. +--[[ NOTE: The togglehouseTransferOnRestart setting controls whether house transfers/leave are true/false upon server restart. +• When set to true, the transfers will only occur during a server restart. +Setting this to false may pose risks; if a house is abandoned and contains a large number of items on the floor, those items will be transferred to the player's depot instantly. +• This could potentially freeze the server due to the heavy operation. It's advised to keep this setting enabled (true) to minimize risks. +]] -- Periods: daily/weekly/monthly/yearly/never -- Base: sqm,rent,sqm+rent housePriceRentMultiplier = 0.0 @@ -263,6 +268,7 @@ houseOwnedByAccount = false houseBuyLevel = 100 housePurchasedShowPrice = false onlyInvitedCanMoveHouseItems = true +togglehouseTransferOnRestart = true -- Item Usage timeBetweenActions = 200 @@ -327,6 +333,7 @@ resetSessionsOnStartup = false -- Misc. -- NOTE: experienceDisplayRates: set to false to ignore exp rate or true to include exp rate allowChangeOutfit = true +toggleMountInProtectionZone = false freePremium = false kickIdlePlayerAfterMinutes = 15 maxMessageBuffer = 4 diff --git a/schema.sql b/schema.sql index d4a69c8c8..b54d9e299 100644 --- a/schema.sql +++ b/schema.sql @@ -404,6 +404,7 @@ CREATE TABLE IF NOT EXISTS `guild_membership` ( CREATE TABLE IF NOT EXISTS `houses` ( `id` int(11) NOT NULL AUTO_INCREMENT, `owner` int(11) NOT NULL, + `new_owner` int(11) NOT NULL DEFAULT '-1', `paid` int(10) UNSIGNED NOT NULL DEFAULT '0', `warnings` int(11) NOT NULL DEFAULT '0', `name` varchar(255) NOT NULL, @@ -433,15 +434,18 @@ END DELIMITER ; -- Table structure `house_lists` + CREATE TABLE IF NOT EXISTS `house_lists` ( - `house_id` int(11) NOT NULL, - `listid` int(11) NOT NULL, - `list` text NOT NULL, - INDEX `house_id` (`house_id`), - CONSTRAINT `houses_list_house_fk` - FOREIGN KEY (`house_id`) REFERENCES `houses` (`id`) - ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; + `house_id` int NOT NULL, + `listid` int NOT NULL, + `version` int NOT NULL DEFAULT '0', + `list` text NOT NULL, + PRIMARY KEY (`house_id`, `listid`), + KEY `house_id_index` (`house_id`), + KEY `version` (`version`), + CONSTRAINT `houses_list_house_fk` FOREIGN KEY (`house_id`) REFERENCES `houses` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; + -- Table structure `ip_bans` CREATE TABLE IF NOT EXISTS `ip_bans` ( diff --git a/src/account/account.cpp b/src/account/account.cpp index 30b92b5c6..5c093f917 100644 --- a/src/account/account.cpp +++ b/src/account/account.cpp @@ -170,7 +170,7 @@ namespace account { } void Account::addPremiumDays(const int32_t &days) { - uint32_t timeLeft = static_cast((m_account.premiumLastDay - getTimeNow()) % 86400); + auto timeLeft = static_cast((m_account.premiumLastDay - getTimeNow()) % 86400); setPremiumDays(m_account.premiumRemainingDays + days); if (timeLeft > 0) { @@ -199,8 +199,8 @@ namespace account { time_t currentTime = getTimeNow(); - uint32_t daysLeft = static_cast((lastDay - currentTime) / 86400); - uint32_t timeLeft = static_cast((lastDay - currentTime) % 86400); + auto daysLeft = static_cast((lastDay - currentTime) / 86400); + auto timeLeft = static_cast((lastDay - currentTime) % 86400); m_account.premiumRemainingDays = daysLeft > 0 ? daysLeft : 0; diff --git a/src/canary_server.cpp b/src/canary_server.cpp index 1b49eb4e0..d9c9d7011 100644 --- a/src/canary_server.cpp +++ b/src/canary_server.cpp @@ -52,57 +52,60 @@ CanaryServer::CanaryServer( } int CanaryServer::run() { - g_dispatcher().addTask([this] { - try { - loadConfigLua(); + g_dispatcher().addTask( + [this] { + try { + loadConfigLua(); - logger.info("Server protocol: {}.{}{}", CLIENT_VERSION_UPPER, CLIENT_VERSION_LOWER, g_configManager().getBoolean(OLD_PROTOCOL) ? " and 10x allowed!" : ""); + logger.info("Server protocol: {}.{}{}", CLIENT_VERSION_UPPER, CLIENT_VERSION_LOWER, g_configManager().getBoolean(OLD_PROTOCOL) ? " and 10x allowed!" : ""); - rsa.start(); - initializeDatabase(); - loadModules(); - setWorldType(); - loadMaps(); + rsa.start(); + initializeDatabase(); + loadModules(); + setWorldType(); + loadMaps(); - logger.info("Initializing gamestate..."); - g_game().setGameState(GAME_STATE_INIT); + logger.info("Initializing gamestate..."); + g_game().setGameState(GAME_STATE_INIT); - setupHousesRent(); + setupHousesRent(); + g_game().transferHouseItemsToDepot(); - IOMarket::checkExpiredOffers(); - IOMarket::getInstance().updateStatistics(); + IOMarket::checkExpiredOffers(); + IOMarket::getInstance().updateStatistics(); - logger.info("Loaded all modules, server starting up..."); + logger.info("Loaded all modules, server starting up..."); #ifndef _WIN32 - if (getuid() == 0 || geteuid() == 0) { - logger.warn("{} has been executed as root user, " - "please consider running it as a normal user", - STATUS_SERVER_NAME); - } + if (getuid() == 0 || geteuid() == 0) { + logger.warn("{} has been executed as root user, " + "please consider running it as a normal user", + STATUS_SERVER_NAME); + } #endif - g_game().start(&serviceManager); - g_game().setGameState(GAME_STATE_NORMAL); + g_game().start(&serviceManager); + g_game().setGameState(GAME_STATE_NORMAL); - g_webhook().sendMessage("Server is now online", "Server has successfully started.", WEBHOOK_COLOR_ONLINE); + g_webhook().sendMessage("Server is now online", "Server has successfully started.", WEBHOOK_COLOR_ONLINE); - loaderDone = true; - loaderSignal.notify_all(); - } catch (FailedToInitializeCanary &err) { - loadFailed = true; - logger.error(err.what()); + loaderDone = true; + loaderSignal.notify_all(); + } catch (FailedToInitializeCanary &err) { + loadFailed = true; + logger.error(err.what()); - logger.error("The program will close after pressing the enter key..."); + logger.error("The program will close after pressing the enter key..."); - if (isatty(STDIN_FILENO)) { - getchar(); - } + if (isatty(STDIN_FILENO)) { + getchar(); + } - loaderSignal.notify_all(); - } - }, - "CanaryServer::run"); + loaderSignal.notify_all(); + } + }, + "CanaryServer::run" + ); loaderSignal.wait(loaderUniqueLock, [this] { return loaderDone || loadFailed; }); @@ -351,7 +354,7 @@ void CanaryServer::loadModules() { g_game().loadBoostedCreature(); g_ioBosstiary().loadBoostedBoss(); - g_ioprey().InitializeTaskHuntOptions(); + g_ioprey().initializeTaskHuntOptions(); } void CanaryServer::modulesLoadHelper(bool loaded, std::string moduleName) { diff --git a/src/config/config_definitions.hpp b/src/config/config_definitions.hpp index 98f72a90b..6a785280e 100644 --- a/src/config/config_definitions.hpp +++ b/src/config/config_definitions.hpp @@ -88,6 +88,8 @@ enum booleanConfig_t { VIP_STAY_ONLINE, REWARD_CHEST_COLLECT_ENABLED, + TOGGLE_MOUNT_IN_PZ, + TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART, LAST_BOOLEAN_CONFIG }; diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 6f04e5320..940ea29eb 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -389,6 +389,10 @@ bool ConfigManager::load() { boolean[REWARD_CHEST_COLLECT_ENABLED] = getGlobalBoolean(L, "rewardChestCollectEnabled", true); integer[REWARD_CHEST_MAX_COLLECT_ITEMS] = getGlobalNumber(L, "rewardChestMaxCollectItems", 200); + boolean[TOGGLE_MOUNT_IN_PZ] = getGlobalBoolean(L, "toggleMountInProtectionZone", false); + + boolean[TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART] = getGlobalBoolean(L, "togglehouseTransferOnRestart", false); + loaded = true; lua_close(L); return true; diff --git a/src/core.hpp b/src/core.hpp index b78c3c1d7..4670a43f9 100644 --- a/src/core.hpp +++ b/src/core.hpp @@ -11,7 +11,7 @@ static constexpr auto STATUS_SERVER_NAME = "OTX Server"; static constexpr auto STATUS_SERVER_VERSION = "6.2"; -static constexpr auto STATUS_SERVER_DEVELOPERS = "OpenTibiaBR Organization and data editor: Mattyx14"; +static constexpr auto STATUS_SERVER_DEVELOPERS = "Canary Base - OpenTibiaBR Organization and data editor: Mattyx14"; static constexpr auto AUTHENTICATOR_DIGITS = 6U; static constexpr auto AUTHENTICATOR_PERIOD = 30U; diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index 6b5b1a9ae..30b0208ad 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -19,7 +19,7 @@ #include "creatures/monsters/monsters.hpp" #include "items/weapons/weapons.hpp" -int32_t Combat::getLevelFormula(const Player* player, const std::shared_ptr wheelSpell, const CombatDamage &damage) const { +int32_t Combat::getLevelFormula(std::shared_ptr player, const std::shared_ptr wheelSpell, const CombatDamage &damage) const { if (!player) { return 0; } @@ -38,7 +38,7 @@ int32_t Combat::getLevelFormula(const Player* player, const std::shared_ptr creature, std::shared_ptr target) const { CombatDamage damage; damage.origin = params.origin; damage.primary.type = params.combatType; @@ -47,7 +47,7 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const damage.runeSpellName = runeSpellName; // Wheel of destiny std::shared_ptr wheelSpell = nullptr; - Player* attackerPlayer = creature ? creature->getPlayer() : nullptr; + std::shared_ptr attackerPlayer = creature ? creature->getPlayer() : nullptr; if (attackerPlayer) { wheelSpell = attackerPlayer->wheel()->getCombatDataSpell(damage); } @@ -61,7 +61,7 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const int32_t min, max; if (creature->getCombatValues(min, max)) { damage.primary.value = normal_random(min, max); - } else if (Player* player = creature->getPlayer()) { + } else if (std::shared_ptr player = creature->getPlayer()) { if (params.valueCallback) { params.valueCallback->getMinMaxValues(player, damage, params.useCharges); } else if (formulaType == COMBAT_FORMULA_LEVELMAGIC) { @@ -71,7 +71,7 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const static_cast(levelFormula * maxa + maxb) ); } else if (formulaType == COMBAT_FORMULA_SKILL) { - Item* tool = player->getWeapon(); + std::shared_ptr tool = player->getWeapon(); const Weapon* weapon = g_weapons().getWeapon(tool); if (weapon) { damage.primary.value = normal_random( @@ -99,7 +99,7 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const return damage; } -void Combat::getCombatArea(const Position ¢erPos, const Position &targetPos, const AreaCombat* area, std::forward_list &list) { +void Combat::getCombatArea(const Position ¢erPos, const Position &targetPos, const std::unique_ptr &area, std::forward_list> &list) { if (targetPos.z >= MAP_MAX_LAYERS) { return; } @@ -175,7 +175,7 @@ ConditionType_t Combat::DamageToConditionType(CombatType_t type) { } } -bool Combat::isPlayerCombat(const Creature* target) { +bool Combat::isPlayerCombat(std::shared_ptr target) { if (target->getPlayer()) { return true; } @@ -187,7 +187,7 @@ bool Combat::isPlayerCombat(const Creature* target) { return false; } -ReturnValue Combat::canTargetCreature(Player* player, Creature* target) { +ReturnValue Combat::canTargetCreature(std::shared_ptr player, std::shared_ptr target) { if (player == target) { return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER; } @@ -235,7 +235,7 @@ ReturnValue Combat::canTargetCreature(Player* player, Creature* target) { return Combat::canDoCombat(player, target, true); } -ReturnValue Combat::canDoCombat(Creature* caster, Tile* tile, bool aggressive) { +ReturnValue Combat::canDoCombat(std::shared_ptr caster, std::shared_ptr tile, bool aggressive) { if (tile->hasProperty(CONST_PROP_BLOCKPROJECTILE)) { return RETURNVALUE_NOTENOUGHROOM; } @@ -260,7 +260,7 @@ ReturnValue Combat::canDoCombat(Creature* caster, Tile* tile, bool aggressive) { return RETURNVALUE_FIRSTGOUPSTAIRS; } - if (const Player* player = caster->getPlayer()) { + if (std::shared_ptr player = caster->getPlayer()) { if (player->hasFlag(PlayerFlags_t::IgnoreProtectionZone)) { return RETURNVALUE_NOERROR; } @@ -270,11 +270,11 @@ ReturnValue Combat::canDoCombat(Creature* caster, Tile* tile, bool aggressive) { return g_events().eventCreatureOnAreaCombat(caster, tile, aggressive); } -bool Combat::isInPvpZone(const Creature* attacker, const Creature* target) { +bool Combat::isInPvpZone(std::shared_ptr attacker, std::shared_ptr target) { return attacker->getZoneType() == ZONE_PVP && target->getZoneType() == ZONE_PVP; } -bool Combat::isProtected(const Player* attacker, const Player* target) { +bool Combat::isProtected(std::shared_ptr attacker, std::shared_ptr target) { uint32_t protectionLevel = g_configManager().getNumber(PROTECTION_LEVEL); if (target->getLevel() < protectionLevel || attacker->getLevel() < protectionLevel) { return true; @@ -291,13 +291,13 @@ bool Combat::isProtected(const Player* attacker, const Player* target) { return false; } -ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target, bool aggressive) { +ReturnValue Combat::canDoCombat(std::shared_ptr attacker, std::shared_ptr target, bool aggressive) { if (!aggressive) { return RETURNVALUE_NOERROR; } if (target) { - const Tile* tile = target->getTile(); + std::shared_ptr tile = target->getTile(); if (tile->hasProperty(CONST_PROP_BLOCKPROJECTILE)) { return RETURNVALUE_NOTENOUGHROOM; } @@ -307,16 +307,16 @@ ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target, bool aggre } if (attacker) { - const Creature* attackerMaster = attacker->getMaster(); + const std::shared_ptr attackerMaster = attacker->getMaster(); auto targetPlayer = target ? target->getPlayer() : nullptr; if (targetPlayer) { if (targetPlayer->hasFlag(PlayerFlags_t::CannotBeAttacked)) { return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER; } - const Tile* targetPlayerTile = targetPlayer->getTile(); + const std::shared_ptr targetPlayerTile = targetPlayer->getTile(); - if (const Player* attackerPlayer = attacker->getPlayer()) { + if (const std::shared_ptr attackerPlayer = attacker->getPlayer()) { if (attackerPlayer->hasFlag(PlayerFlags_t::CannotAttackPlayer)) { return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER; } @@ -339,7 +339,7 @@ ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target, bool aggre } if (attackerMaster) { - if (const Player* masterAttackerPlayer = attackerMaster->getPlayer()) { + if (const std::shared_ptr masterAttackerPlayer = attackerMaster->getPlayer()) { if (masterAttackerPlayer->hasFlag(PlayerFlags_t::CannotAttackPlayer)) { return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER; } @@ -364,7 +364,7 @@ ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target, bool aggre return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE; } - if (const Player* attackerPlayer = attacker->getPlayer()) { + if (const std::shared_ptr attackerPlayer = attacker->getPlayer()) { if (attackerPlayer->hasFlag(PlayerFlags_t::CannotAttackMonster)) { return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE; } @@ -373,7 +373,7 @@ ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target, bool aggre return RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE; } } else if (attacker->getMonster()) { - const Creature* targetMaster = target->getMaster(); + const std::shared_ptr targetMaster = target->getMaster(); if ((!targetMaster || !targetMaster->getPlayer()) && attacker->getFaction() == FACTION_DEFAULT) { if (!attackerMaster || !attackerMaster->getPlayer()) { @@ -485,32 +485,32 @@ bool Combat::setParam(CombatParam_t param, uint32_t value) { bool Combat::setCallback(CallBackParam_t key) { switch (key) { case CALLBACK_PARAM_LEVELMAGICVALUE: { - params.valueCallback.reset(new ValueCallback(COMBAT_FORMULA_LEVELMAGIC)); + params.valueCallback = std::make_unique(COMBAT_FORMULA_LEVELMAGIC); return true; } case CALLBACK_PARAM_SKILLVALUE: { - params.valueCallback.reset(new ValueCallback(COMBAT_FORMULA_SKILL)); + params.valueCallback = std::make_unique(COMBAT_FORMULA_SKILL); return true; } case CALLBACK_PARAM_TARGETTILE: { - params.tileCallback.reset(new TileCallback()); + params.tileCallback = std::make_unique(); return true; } case CALLBACK_PARAM_TARGETCREATURE: { - params.targetCallback.reset(new TargetCallback()); + params.targetCallback = std::make_unique(); return true; } case CALLBACK_PARAM_CHAINVALUE: { - params.chainCallback.reset(new ChainCallback()); + params.chainCallback = std::make_unique(); return true; } case CALLBACK_PARAM_CHAINPICKER: { - params.chainPickerCallback.reset(new ChainPickerCallback()); + params.chainPickerCallback = std::make_unique(); return true; } } @@ -543,32 +543,32 @@ CallBack* Combat::getCallback(CallBackParam_t key) { return nullptr; } -void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage* data) { +void Combat::CombatHealthFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage* data) { assert(data); CombatDamage damage = *data; - Player* attackerPlayer = nullptr; + std::shared_ptr attackerPlayer = nullptr; if (caster) { attackerPlayer = caster->getPlayer(); } - Monster* targetMonster = nullptr; + std::shared_ptr targetMonster = nullptr; if (target) { targetMonster = target->getMonster(); } - Monster* attackerMonster = nullptr; + std::shared_ptr attackerMonster = nullptr; if (caster) { attackerMonster = caster->getMonster(); } - Player* targetPlayer = nullptr; + std::shared_ptr targetPlayer = nullptr; if (target) { targetPlayer = target->getPlayer(); } if (caster && attackerPlayer) { - Item* item = attackerPlayer->getWeapon(); + std::shared_ptr item = attackerPlayer->getWeapon(); damage = applyImbuementElementalDamage(attackerPlayer, item, damage); g_events().eventPlayerOnCombat(attackerPlayer, target, item, damage); @@ -588,7 +588,7 @@ void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatPa // Player attacking monster if (attackerPlayer && targetMonster) { - const PreySlot* slot = attackerPlayer->getPreyWithMonster(targetMonster->getRaceId()); + const std::unique_ptr &slot = attackerPlayer->getPreyWithMonster(targetMonster->getRaceId()); if (slot && slot->isOccupied() && slot->bonus == PreyBonus_Damage && slot->bonusTimeLeft > 0) { damage.primary.value += static_cast(std::ceil((damage.primary.value * slot->bonusPercentage) / 100)); damage.secondary.value += static_cast(std::ceil((damage.secondary.value * slot->bonusPercentage) / 100)); @@ -597,7 +597,7 @@ void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatPa // Monster attacking player if (attackerMonster && targetPlayer) { - const PreySlot* slot = targetPlayer->getPreyWithMonster(attackerMonster->getRaceId()); + const std::unique_ptr &slot = targetPlayer->getPreyWithMonster(attackerMonster->getRaceId()); if (slot && slot->isOccupied() && slot->bonus == PreyBonus_Defense && slot->bonusTimeLeft > 0) { damage.primary.value -= static_cast(std::ceil((damage.primary.value * slot->bonusPercentage) / 100)); damage.secondary.value -= static_cast(std::ceil((damage.secondary.value * slot->bonusPercentage) / 100)); @@ -610,7 +610,7 @@ void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatPa } } -CombatDamage Combat::applyImbuementElementalDamage(Player* attackerPlayer, Item* item, CombatDamage damage) { +CombatDamage Combat::applyImbuementElementalDamage(std::shared_ptr attackerPlayer, std::shared_ptr item, CombatDamage damage) { if (!item) { return damage; } @@ -648,7 +648,7 @@ CombatDamage Combat::applyImbuementElementalDamage(Player* attackerPlayer, Item* return damage; } -void Combat::CombatManaFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage* data) { +void Combat::CombatManaFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage* data) { assert(data); CombatDamage damage = *data; if (damage.primary.value < 0) { @@ -662,7 +662,7 @@ void Combat::CombatManaFunc(Creature* caster, Creature* target, const CombatPara } } -bool Combat::checkFearConditionAffected(Player* player) { +bool Combat::checkFearConditionAffected(std::shared_ptr player) { if (player->isImmuneFear()) { return false; } @@ -671,7 +671,7 @@ bool Combat::checkFearConditionAffected(Player* player) { return false; } - Party* party = player->getParty(); + auto party = player->getParty(); if (party) { auto affectedCount = (party->getMemberCount() + 5) / 5; g_logger().debug("[{}] Player is member of a party, {} members can be feared", __FUNCTION__, affectedCount); @@ -690,13 +690,13 @@ bool Combat::checkFearConditionAffected(Player* player) { return true; } -void Combat::CombatConditionFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage* data) { +void Combat::CombatConditionFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage* data) { if (params.origin == ORIGIN_MELEE && data && data->primary.value == 0 && data->secondary.value == 0) { return; } for (const auto &condition : params.conditionList) { - Player* player = nullptr; + std::shared_ptr player = nullptr; if (target) { player = target->getPlayer(); } @@ -729,7 +729,7 @@ void Combat::CombatConditionFunc(Creature* caster, Creature* target, const Comba } if (caster == target || target && !target->isImmune(condition->getType())) { - Condition* conditionCopy = condition->clone(); + auto conditionCopy = condition->clone(); if (caster) { conditionCopy->setParam(CONDITION_PARAM_OWNER, caster->getID()); conditionCopy->setPositionParam(CONDITION_PARAM_CASTER_POSITION, caster->getPosition()); @@ -743,18 +743,18 @@ void Combat::CombatConditionFunc(Creature* caster, Creature* target, const Comba } } -void Combat::CombatDispelFunc(Creature*, Creature* target, const CombatParams ¶ms, CombatDamage*) { +void Combat::CombatDispelFunc(std::shared_ptr, std::shared_ptr target, const CombatParams ¶ms, CombatDamage*) { if (target) { target->removeCombatCondition(params.dispelType); } } -void Combat::CombatNullFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage*) { +void Combat::CombatNullFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage*) { CombatConditionFunc(caster, target, params, nullptr); CombatDispelFunc(caster, target, params, nullptr); } -void Combat::combatTileEffects(const SpectatorHashSet &spectators, Creature* caster, Tile* tile, const CombatParams ¶ms) { +void Combat::combatTileEffects(const SpectatorHashSet &spectators, std::shared_ptr caster, std::shared_ptr tile, const CombatParams ¶ms) { if (params.itemId != 0) { uint16_t itemId = params.itemId; switch (itemId) { @@ -791,7 +791,7 @@ void Combat::combatTileEffects(const SpectatorHashSet &spectators, Creature* cas } if (caster) { - Player* casterPlayer; + std::shared_ptr casterPlayer; if (caster->isSummon()) { casterPlayer = caster->getMaster()->getPlayer(); } else { @@ -817,7 +817,7 @@ void Combat::combatTileEffects(const SpectatorHashSet &spectators, Creature* cas } } - Item* item = Item::CreateItem(itemId); + std::shared_ptr item = Item::CreateItem(itemId); if (caster) { item->setAttribute(ItemAttribute_t::OWNER, caster->getID()); } @@ -825,8 +825,6 @@ void Combat::combatTileEffects(const SpectatorHashSet &spectators, Creature* cas ReturnValue ret = g_game().internalAddItem(tile, item); if (ret == RETURNVALUE_NOERROR) { item->startDecaying(); - } else { - delete item; } } @@ -845,7 +843,7 @@ void Combat::combatTileEffects(const SpectatorHashSet &spectators, Creature* cas } } -void Combat::postCombatEffects(Creature* caster, const Position &origin, const Position &pos, const CombatParams ¶ms) { +void Combat::postCombatEffects(std::shared_ptr caster, const Position &origin, const Position &pos, const CombatParams ¶ms) { if (caster && params.distanceEffect != CONST_ANI_NONE) { addDistanceEffect(caster, origin, pos, params.distanceEffect); } @@ -857,13 +855,13 @@ void Combat::postCombatEffects(Creature* caster, const Position &origin, const P } } -void Combat::addDistanceEffect(Creature* caster, const Position &fromPos, const Position &toPos, uint16_t effect) { +void Combat::addDistanceEffect(std::shared_ptr caster, const Position &fromPos, const Position &toPos, uint16_t effect) { if (effect == CONST_ANI_WEAPONTYPE) { if (!caster) { return; } - Player* player = caster->getPlayer(); + std::shared_ptr player = caster->getPlayer(); if (!player) { return; } @@ -915,7 +913,7 @@ void Combat::doChainEffect(const Position &origin, const Position &dest, uint8_t } } -bool Combat::doCombatChain(Creature* caster, Creature* target, bool aggressive) const { +bool Combat::doCombatChain(std::shared_ptr caster, std::shared_ptr target, bool aggressive) const { if (!params.chainCallback) { return false; } @@ -946,7 +944,7 @@ bool Combat::doCombatChain(Creature* caster, Creature* target, bool aggressive) return true; } -bool Combat::doCombat(Creature* caster, Creature* target) const { +bool Combat::doCombat(std::shared_ptr caster, std::shared_ptr target) const { if (caster != nullptr && params.chainCallback) { return doCombatChain(caster, target, params.aggressive); } @@ -954,7 +952,7 @@ bool Combat::doCombat(Creature* caster, Creature* target) const { return doCombat(caster, target, caster != nullptr ? caster->getPosition() : Position()); } -bool Combat::doCombat(Creature* caster, Creature* target, const Position &origin) const { +bool Combat::doCombat(std::shared_ptr caster, std::shared_ptr target, const Position &origin) const { // target combat callback function if (params.combatType != COMBAT_NONE) { CombatDamage damage = getCombatDamage(caster, target); @@ -970,7 +968,7 @@ bool Combat::doCombat(Creature* caster, Creature* target, const Position &origin return true; } -bool Combat::doCombat(Creature* caster, const Position &position) const { +bool Combat::doCombat(std::shared_ptr caster, const Position &position) const { if (caster != nullptr && params.chainCallback) { return doCombatChain(caster, caster, params.aggressive); } @@ -979,20 +977,20 @@ bool Combat::doCombat(Creature* caster, const Position &position) const { if (params.combatType != COMBAT_NONE) { CombatDamage damage = getCombatDamage(caster, nullptr); if (damage.primary.type != COMBAT_MANADRAIN) { - doCombatHealth(caster, position, area.get(), damage, params); + doCombatHealth(caster, position, area, damage, params); } else { - doCombatMana(caster, position, area.get(), damage, params); + doCombatMana(caster, position, area, damage, params); } } else { auto origin = caster != nullptr ? caster->getPosition() : Position(); - CombatFunc(caster, origin, position, area.get(), params, CombatNullFunc, nullptr); + CombatFunc(caster, origin, position, area, params, CombatNullFunc, nullptr); } return true; } -void Combat::CombatFunc(Creature* caster, const Position &origin, const Position &pos, const AreaCombat* area, const CombatParams ¶ms, CombatFunction func, CombatDamage* data) { - std::forward_list tileList; +void Combat::CombatFunc(std::shared_ptr caster, const Position &origin, const Position &pos, const std::unique_ptr &area, const CombatParams ¶ms, CombatFunction func, CombatDamage* data) { + std::forward_list> tileList; if (caster) { getCombatArea(caster->getPosition(), pos, area, tileList); @@ -1005,7 +1003,7 @@ void Combat::CombatFunc(Creature* caster, const Position &origin, const Position uint32_t maxY = 0; // calculate the max viewable range - for (Tile* tile : tileList) { + for (std::shared_ptr tile : tileList) { const Position &tilePos = tile->getPosition(); uint32_t diff = Position::getDistanceX(tilePos, pos); @@ -1024,14 +1022,14 @@ void Combat::CombatFunc(Creature* caster, const Position &origin, const Position g_game().map.getSpectators(spectators, pos, true, true, rangeX, rangeX, rangeY, rangeY); int affected = 0; - for (Tile* tile : tileList) { + for (std::shared_ptr tile : tileList) { if (canDoCombat(caster, tile, params.aggressive) != RETURNVALUE_NOERROR) { continue; } if (CreatureVector* creatures = tile->getCreatures()) { - const Creature* topCreature = tile->getTopCreature(); - for (Creature* creature : *creatures) { + const std::shared_ptr topCreature = tile->getTopCreature(); + for (auto &creature : *creatures) { if (params.targetCasterOrTopMost) { if (caster && caster->getTile() == tile) { if (creature != caster) { @@ -1073,19 +1071,19 @@ void Combat::CombatFunc(Creature* caster, const Position &origin, const Position } // Wheel of destiny get beam affected total - Player* casterPlayer = caster ? caster->getPlayer() : nullptr; + std::shared_ptr casterPlayer = caster ? caster->getPlayer() : nullptr; uint8_t beamAffectedTotal = casterPlayer ? casterPlayer->wheel()->getBeamAffectedTotal(tmpDamage) : 0; uint8_t beamAffectedCurrent = 0; tmpDamage.affected = affected; - for (Tile* tile : tileList) { + for (std::shared_ptr tile : tileList) { if (canDoCombat(caster, tile, params.aggressive) != RETURNVALUE_NOERROR) { continue; } if (CreatureVector* creatures = tile->getCreatures()) { - const Creature* topCreature = tile->getTopCreature(); - for (Creature* creature : *creatures) { + const std::shared_ptr topCreature = tile->getTopCreature(); + for (auto &creature : *creatures) { if (params.targetCasterOrTopMost) { if (caster && caster->getTile() == tile) { if (creature != caster) { @@ -1123,11 +1121,11 @@ void Combat::CombatFunc(Creature* caster, const Position &origin, const Position postCombatEffects(caster, origin, pos, params); } -void Combat::doCombatHealth(Creature* caster, Creature* target, CombatDamage &damage, const CombatParams ¶ms) { +void Combat::doCombatHealth(std::shared_ptr caster, std::shared_ptr target, CombatDamage &damage, const CombatParams ¶ms) { doCombatHealth(caster, target, caster ? caster->getPosition() : Position(), damage, params); } -void Combat::doCombatHealth(Creature* caster, Creature* target, const Position &origin, CombatDamage &damage, const CombatParams ¶ms) { +void Combat::doCombatHealth(std::shared_ptr caster, std::shared_ptr target, const Position &origin, CombatDamage &damage, const CombatParams ¶ms) { bool canCombat = !params.aggressive || (caster != target && Combat::canDoCombat(caster, target, params.aggressive) == RETURNVALUE_NOERROR); if ((caster && target) && (caster == target || canCombat) @@ -1195,7 +1193,7 @@ void Combat::doCombatHealth(Creature* caster, Creature* target, const Position & } } -void Combat::doCombatHealth(Creature* caster, const Position &position, const AreaCombat* area, CombatDamage &damage, const CombatParams ¶ms) { +void Combat::doCombatHealth(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, CombatDamage &damage, const CombatParams ¶ms) { if (caster && caster->getPlayer()) { // Critical damage uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance; @@ -1217,15 +1215,15 @@ void Combat::doCombatHealth(Creature* caster, const Position &position, const Ar } } } - const auto &origin = caster ? caster->getPosition() : Position(); + const auto origin = caster ? caster->getPosition() : Position(); CombatFunc(caster, origin, position, area, params, CombatHealthFunc, &damage); } -void Combat::doCombatMana(Creature* caster, Creature* target, CombatDamage &damage, const CombatParams ¶ms) { +void Combat::doCombatMana(std::shared_ptr caster, std::shared_ptr target, CombatDamage &damage, const CombatParams ¶ms) { doCombatMana(caster, target, caster ? caster->getPosition() : Position(), damage, params); } -void Combat::doCombatMana(Creature* caster, Creature* target, const Position &origin, CombatDamage &damage, const CombatParams ¶ms) { +void Combat::doCombatMana(std::shared_ptr caster, std::shared_ptr target, const Position &origin, CombatDamage &damage, const CombatParams ¶ms) { bool canCombat = !params.aggressive || (caster != target && Combat::canDoCombat(caster, target, params.aggressive) == RETURNVALUE_NOERROR); if ((caster && target) && (caster == target || canCombat) @@ -1261,7 +1259,7 @@ void Combat::doCombatMana(Creature* caster, Creature* target, const Position &or } } -void Combat::doCombatMana(Creature* caster, const Position &position, const AreaCombat* area, CombatDamage &damage, const CombatParams ¶ms) { +void Combat::doCombatMana(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, CombatDamage &damage, const CombatParams ¶ms) { if (caster && caster->getPlayer()) { // Critical damage uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance; @@ -1271,16 +1269,16 @@ void Combat::doCombatMana(Creature* caster, const Position &position, const Area damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100; } } - const auto &origin = caster ? caster->getPosition() : Position(); + const auto origin = caster ? caster->getPosition() : Position(); CombatFunc(caster, origin, position, area, params, CombatManaFunc, &damage); } -void Combat::doCombatCondition(Creature* caster, const Position &position, const AreaCombat* area, const CombatParams ¶ms) { - const auto &origin = caster ? caster->getPosition() : Position(); +void Combat::doCombatCondition(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, const CombatParams ¶ms) { + const auto origin = caster ? caster->getPosition() : Position(); CombatFunc(caster, origin, position, area, params, CombatConditionFunc, nullptr); } -void Combat::doCombatCondition(Creature* caster, Creature* target, const CombatParams ¶ms) { +void Combat::doCombatCondition(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms) { bool canCombat = !params.aggressive || (caster != target && Combat::canDoCombat(caster, target, params.aggressive) == RETURNVALUE_NOERROR); if ((caster == target || canCombat) && params.impactEffect != CONST_ME_NONE) { g_game().addMagicEffect(target->getPosition(), params.impactEffect); @@ -1304,12 +1302,12 @@ void Combat::doCombatCondition(Creature* caster, Creature* target, const CombatP } } -void Combat::doCombatDispel(Creature* caster, const Position &position, const AreaCombat* area, const CombatParams ¶ms) { - const auto &origin = caster ? caster->getPosition() : Position(); +void Combat::doCombatDispel(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, const CombatParams ¶ms) { + const auto origin = caster ? caster->getPosition() : Position(); CombatFunc(caster, origin, position, area, params, CombatDispelFunc, nullptr); } -void Combat::doCombatDispel(Creature* caster, Creature* target, const CombatParams ¶ms) { +void Combat::doCombatDispel(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms) { bool canCombat = !params.aggressive || (caster != target && Combat::canDoCombat(caster, target, params.aggressive) == RETURNVALUE_NOERROR); if ((caster && target) && (caster == target || canCombat) @@ -1335,11 +1333,11 @@ void Combat::doCombatDispel(Creature* caster, Creature* target, const CombatPara } } -void Combat::doCombatDefault(Creature* caster, Creature* target, const CombatParams ¶ms) { +void Combat::doCombatDefault(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms) { doCombatDefault(caster, target, caster ? caster->getPosition() : Position(), params); } -void Combat::doCombatDefault(Creature* caster, Creature* target, const Position &origin, const CombatParams ¶ms) { +void Combat::doCombatDefault(std::shared_ptr caster, std::shared_ptr target, const Position &origin, const CombatParams ¶ms) { if (!params.aggressive || (caster != target && Combat::canDoCombat(caster, target, params.aggressive) == RETURNVALUE_NOERROR)) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, target->getPosition(), true, true); @@ -1377,13 +1375,13 @@ void Combat::setRuneSpellName(const std::string &value) { runeSpellName = value; } -std::vector>> Combat::pickChainTargets(Creature* caster, const CombatParams ¶ms, uint8_t chainDistance, uint8_t maxTargets, bool backtracking, bool aggressive, Creature* initialTarget /* = nullptr */) { +std::vector>> Combat::pickChainTargets(std::shared_ptr caster, const CombatParams ¶ms, uint8_t chainDistance, uint8_t maxTargets, bool backtracking, bool aggressive, std::shared_ptr initialTarget /* = nullptr */) { if (!caster) { return {}; } std::vector>> resultMap; - std::vector targets; + std::vector> targets; std::set visited; if (initialTarget && initialTarget != caster) { @@ -1397,14 +1395,14 @@ std::vector>> Combat::pickChainTargets const int maxBacktrackingAttempts = 10; // Can be adjusted as needed while (!targets.empty() && targets.size() <= maxTargets) { - Creature* currentTarget = targets.back(); + auto currentTarget = targets.back(); SpectatorHashSet spectators; g_game().map.getSpectators(spectators, currentTarget->getPosition(), false, false, chainDistance, chainDistance, chainDistance, chainDistance); g_logger().debug("Combat::pickChainTargets: currentTarget: {}, spectators: {}", currentTarget->getName(), spectators.size()); double closestDistance = std::numeric_limits::max(); - Creature* closestSpectator = nullptr; - for (Creature* spectator : spectators) { + std::shared_ptr closestSpectator = nullptr; + for (std::shared_ptr spectator : spectators) { if (!spectator || visited.contains(spectator->getID())) { continue; } @@ -1450,7 +1448,7 @@ std::vector>> Combat::pickChainTargets return resultMap; } -bool Combat::isValidChainTarget(Creature* caster, Creature* currentTarget, Creature* potentialTarget, const CombatParams ¶ms, bool aggressive) { +bool Combat::isValidChainTarget(std::shared_ptr caster, std::shared_ptr currentTarget, std::shared_ptr potentialTarget, const CombatParams ¶ms, bool aggressive) { bool canCombat = canDoCombat(caster, potentialTarget, aggressive) == RETURNVALUE_NOERROR; bool pick = params.chainPickerCallback ? params.chainPickerCallback->onChainCombat(caster, potentialTarget) : true; bool hasSight = g_game().isSightClear(currentTarget->getPosition(), potentialTarget->getPosition(), true); @@ -1459,7 +1457,7 @@ bool Combat::isValidChainTarget(Creature* caster, Creature* currentTarget, Creat //**********************************************************// -uint32_t ValueCallback::getMagicLevelSkill(const Player* player, const CombatDamage &damage) const { +uint32_t ValueCallback::getMagicLevelSkill(std::shared_ptr player, const CombatDamage &damage) const { if (!player) { return 0; } @@ -1479,7 +1477,7 @@ uint32_t ValueCallback::getMagicLevelSkill(const Player* player, const CombatDam return magicLevelSkill + player->getSpecializedMagicLevel(damage.primary.type, true); } -void ValueCallback::getMinMaxValues(Player* player, CombatDamage &damage, bool useCharges) const { +void ValueCallback::getMinMaxValues(std::shared_ptr player, CombatDamage &damage, bool useCharges) const { // onGetPlayerMinMaxValues(...) if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[ValueCallback::getMinMaxValues - Player {} formula {}] " @@ -1517,9 +1515,9 @@ void ValueCallback::getMinMaxValues(Player* player, CombatDamage &damage, bool u case COMBAT_FORMULA_SKILL: { // onGetPlayerMinMaxValues(player, attackSkill, attackValue, attackFactor) - Item* tool = player->getWeapon(); + std::shared_ptr tool = player->getWeapon(); const Weapon* weapon = g_weapons().getWeapon(tool); - Item* item = nullptr; + std::shared_ptr item = nullptr; if (weapon) { attackValue = tool->getAttack(); @@ -1598,7 +1596,7 @@ void ValueCallback::getMinMaxValues(Player* player, CombatDamage &damage, bool u //**********************************************************// -void TileCallback::onTileCombat(Creature* creature, Tile* tile) const { +void TileCallback::onTileCombat(std::shared_ptr creature, std::shared_ptr tile) const { // onTileCombat(creature, pos) if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[TileCallback::onTileCombat - Creature {} type {} on tile x: {} y: {} z: {}] " @@ -1629,7 +1627,7 @@ void TileCallback::onTileCombat(Creature* creature, Tile* tile) const { //**********************************************************// -void TargetCallback::onTargetCombat(Creature* creature, Creature* target) const { +void TargetCallback::onTargetCombat(std::shared_ptr creature, std::shared_ptr target) const { // onTargetCombat(creature, target) if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[TargetCallback::onTargetCombat - Creature {}] " @@ -1677,7 +1675,7 @@ void TargetCallback::onTargetCombat(Creature* creature, Creature* target) const //**********************************************************// -void ChainCallback::onChainCombat(Creature* creature, uint8_t &maxTargets, uint8_t &chainDistance, bool &backtracking) const { +void ChainCallback::onChainCombat(std::shared_ptr creature, uint8_t &maxTargets, uint8_t &chainDistance, bool &backtracking) const { // onChainCombat(creature) if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[ChainCallback::onTargetCombat - Creature {}] " @@ -1719,7 +1717,7 @@ void ChainCallback::onChainCombat(Creature* creature, uint8_t &maxTargets, uint8 scriptInterface->resetScriptEnv(); } -bool ChainPickerCallback::onChainCombat(Creature* creature, Creature* target) const { +bool ChainPickerCallback::onChainCombat(std::shared_ptr creature, std::shared_ptr target) const { // onChainCombat(creature, target) if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[ChainPickerCallback::onTargetCombat - Creature {}] " @@ -1772,21 +1770,18 @@ bool ChainPickerCallback::onChainCombat(Creature* creature, Creature* target) co //**********************************************************// void AreaCombat::clear() { - for (const auto &it : areas) { - delete it.second; - } areas.clear(); } AreaCombat::AreaCombat(const AreaCombat &rhs) { hasExtArea = rhs.hasExtArea; for (const auto &it : rhs.areas) { - areas[it.first] = new MatrixArea(*it.second); + areas[it.first] = it.second->clone(); } } -void AreaCombat::getList(const Position ¢erPos, const Position &targetPos, std::forward_list &list) const { - const MatrixArea* area = getArea(centerPos, targetPos); +void AreaCombat::getList(const Position ¢erPos, const Position &targetPos, std::forward_list> &list) const { + const std::unique_ptr &area = getArea(centerPos, targetPos); if (!area) { return; } @@ -1808,7 +1803,7 @@ void AreaCombat::getList(const Position ¢erPos, const Position &targetPos, s } } -void AreaCombat::copyArea(const MatrixArea* input, MatrixArea* output, MatrixOperation_t op) const { +void AreaCombat::copyArea(const std::unique_ptr &input, const std::unique_ptr &output, MatrixOperation_t op) const { uint32_t centerY, centerX; input->getCenter(centerY, centerX); @@ -1889,7 +1884,7 @@ void AreaCombat::copyArea(const MatrixArea* input, MatrixArea* output, MatrixOpe } } -MatrixArea* AreaCombat::createArea(const std::list &list, uint32_t rows) { +std::unique_ptr AreaCombat::createArea(const std::list &list, uint32_t rows) { uint32_t cols; if (rows == 0) { cols = 0; @@ -1897,7 +1892,7 @@ MatrixArea* AreaCombat::createArea(const std::list &list, uint32_t row cols = list.size() / rows; } - MatrixArea* area = new MatrixArea(rows, cols); + auto area = std::make_unique(rows, cols); uint32_t x = 0; uint32_t y = 0; @@ -1922,27 +1917,23 @@ MatrixArea* AreaCombat::createArea(const std::list &list, uint32_t row } void AreaCombat::setupArea(const std::list &list, uint32_t rows) { - MatrixArea* area = createArea(list, rows); + auto northArea = createArea(list, rows); - // NORTH - areas[DIRECTION_NORTH] = area; + const uint32_t maxOutput = std::max(northArea->getCols(), northArea->getRows()) * 2; - uint32_t maxOutput = std::max(area->getCols(), area->getRows()) * 2; + auto southArea = std::make_unique(maxOutput, maxOutput); + copyArea(northArea, southArea, MATRIXOPERATION_ROTATE180); - // SOUTH - MatrixArea* southArea = new MatrixArea(maxOutput, maxOutput); - copyArea(area, southArea, MATRIXOPERATION_ROTATE180); - areas[DIRECTION_SOUTH] = southArea; + auto eastArea = std::make_unique(maxOutput, maxOutput); + copyArea(northArea, eastArea, MATRIXOPERATION_ROTATE90); - // EAST - MatrixArea* eastArea = new MatrixArea(maxOutput, maxOutput); - copyArea(area, eastArea, MATRIXOPERATION_ROTATE90); - areas[DIRECTION_EAST] = eastArea; + auto westArea = std::make_unique(maxOutput, maxOutput); + copyArea(northArea, westArea, MATRIXOPERATION_ROTATE270); - // WEST - MatrixArea* westArea = new MatrixArea(maxOutput, maxOutput); - copyArea(area, westArea, MATRIXOPERATION_ROTATE270); - areas[DIRECTION_WEST] = westArea; + areas[DIRECTION_NORTH] = std::move(northArea); + areas[DIRECTION_SOUTH] = std::move(southArea); + areas[DIRECTION_EAST] = std::move(eastArea); + areas[DIRECTION_WEST] = std::move(westArea); } void AreaCombat::setupArea(int32_t length, int32_t spread) { @@ -2019,36 +2010,37 @@ void AreaCombat::setupExtArea(const std::list &list, uint32_t rows) { } hasExtArea = true; - MatrixArea* area = createArea(list, rows); // NORTH-WEST - areas[DIRECTION_NORTHWEST] = area; + auto nwArea = createArea(list, rows); - uint32_t maxOutput = std::max(area->getCols(), area->getRows()) * 2; + const uint32_t maxOutput = std::max(nwArea->getCols(), nwArea->getRows()) * 2; // NORTH-EAST - MatrixArea* neArea = new MatrixArea(maxOutput, maxOutput); - copyArea(area, neArea, MATRIXOPERATION_MIRROR); - areas[DIRECTION_NORTHEAST] = neArea; + auto neArea = std::make_unique(maxOutput, maxOutput); + copyArea(nwArea, neArea, MATRIXOPERATION_MIRROR); // SOUTH-WEST - MatrixArea* swArea = new MatrixArea(maxOutput, maxOutput); - copyArea(area, swArea, MATRIXOPERATION_FLIP); - areas[DIRECTION_SOUTHWEST] = swArea; + auto swArea = std::make_unique(maxOutput, maxOutput); + copyArea(nwArea, swArea, MATRIXOPERATION_FLIP); // SOUTH-EAST - MatrixArea* seArea = new MatrixArea(maxOutput, maxOutput); + auto seArea = std::make_unique(maxOutput, maxOutput); copyArea(swArea, seArea, MATRIXOPERATION_MIRROR); - areas[DIRECTION_SOUTHEAST] = seArea; + + areas[DIRECTION_NORTHWEST] = std::move(nwArea); + areas[DIRECTION_SOUTHWEST] = std::move(swArea); + areas[DIRECTION_NORTHEAST] = std::move(neArea); + areas[DIRECTION_SOUTHEAST] = std::move(seArea); } //**********************************************************// -void MagicField::onStepInField(Creature &creature) { +void MagicField::onStepInField(const std::shared_ptr &creature) { // remove magic walls/wild growth if (!isBlocking() && g_game().getWorldType() == WORLD_TYPE_NO_PVP && id == ITEM_MAGICWALL_SAFE || id == ITEM_WILDGROWTH_SAFE) { - if (!creature.isInGhostMode()) { - g_game().internalRemoveItem(this, 1); + if (!creature->isInGhostMode()) { + g_game().internalRemoveItem(static_self_cast(), 1); } return; @@ -2056,13 +2048,13 @@ void MagicField::onStepInField(Creature &creature) { const ItemType &it = items[getID()]; if (it.conditionDamage) { - Condition* conditionCopy = it.conditionDamage->clone(); + auto conditionCopy = it.conditionDamage->clone(); auto ownerId = getAttribute(ItemAttribute_t::OWNER); if (ownerId) { bool harmfulField = true; auto itemTile = getTile(); if (g_game().getWorldType() == WORLD_TYPE_NO_PVP || itemTile && itemTile->hasFlag(TILESTATE_NOPVPZONE)) { - Creature* owner = g_game().getCreatureByID(ownerId); + std::shared_ptr owner = g_game().getCreatureByID(ownerId); if (owner) { if (owner->getPlayer() || (owner->isSummon() && owner->getMaster()->getPlayer())) { harmfulField = false; @@ -2070,9 +2062,9 @@ void MagicField::onStepInField(Creature &creature) { } } - Player* targetPlayer = creature.getPlayer(); + std::shared_ptr targetPlayer = creature->getPlayer(); if (targetPlayer) { - const Player* attackerPlayer = g_game().getPlayerByID(ownerId); + const std::shared_ptr attackerPlayer = g_game().getPlayerByID(ownerId); if (attackerPlayer) { if (Combat::isProtected(attackerPlayer, targetPlayer)) { harmfulField = false; @@ -2080,11 +2072,11 @@ void MagicField::onStepInField(Creature &creature) { } } - if (!harmfulField || (OTSYS_TIME() - createTime <= 5000) || creature.hasBeenAttacked(ownerId)) { + if (!harmfulField || (OTSYS_TIME() - createTime <= 5000) || creature->hasBeenAttacked(ownerId)) { conditionCopy->setParam(CONDITION_PARAM_OWNER, ownerId); } } - creature.addCondition(conditionCopy); + creature->addCondition(conditionCopy); } } diff --git a/src/creatures/combat/combat.hpp b/src/creatures/combat/combat.hpp index 241d1c05f..56096b9fd 100644 --- a/src/creatures/combat/combat.hpp +++ b/src/creatures/combat/combat.hpp @@ -19,6 +19,9 @@ class Creature; class Item; class Spell; class Player; +class MatrixArea; + +static const std::unique_ptr &MatrixAreaNull {}; // for luascript callback class ValueCallback final : public CallBack { @@ -33,8 +36,8 @@ class ValueCallback final : public CallBack { * @param damage The combat damage information. * @return The magic level skill of the player. */ - uint32_t getMagicLevelSkill(const Player* player, const CombatDamage &damage) const; - void getMinMaxValues(Player* player, CombatDamage &damage, bool useCharges) const; + uint32_t getMagicLevelSkill(std::shared_ptr player, const CombatDamage &damage) const; + void getMinMaxValues(std::shared_ptr player, CombatDamage &damage, bool useCharges) const; private: formulaType_t type; @@ -42,7 +45,7 @@ class ValueCallback final : public CallBack { class TileCallback final : public CallBack { public: - void onTileCombat(Creature* creature, Tile* tile) const; + void onTileCombat(std::shared_ptr creature, std::shared_ptr tile) const; protected: formulaType_t type; @@ -50,7 +53,7 @@ class TileCallback final : public CallBack { class TargetCallback final : public CallBack { public: - void onTargetCombat(Creature* creature, Creature* target) const; + void onTargetCombat(std::shared_ptr creature, std::shared_ptr target) const; protected: formulaType_t type; @@ -58,16 +61,16 @@ class TargetCallback final : public CallBack { class ChainCallback final : public CallBack { public: - void onChainCombat(Creature* creature, uint8_t &chainTargets, uint8_t &chainDistance, bool &backtracking) const; + void onChainCombat(std::shared_ptr creature, uint8_t &chainTargets, uint8_t &chainDistance, bool &backtracking) const; }; class ChainPickerCallback final : public CallBack { public: - bool onChainCombat(Creature* creature, Creature* target) const; + bool onChainCombat(std::shared_ptr creature, std::shared_ptr target) const; }; struct CombatParams { - std::forward_list> conditionList; + std::forward_list> conditionList; std::unique_ptr valueCallback; std::unique_ptr tileCallback; @@ -96,7 +99,7 @@ struct CombatParams { uint8_t chainEffect = CONST_ME_NONE; }; -using CombatFunction = std::function; +using CombatFunction = std::function, std::shared_ptr, const CombatParams &, CombatDamage*)>; class MatrixArea { public: @@ -138,6 +141,10 @@ class MatrixArea { delete[] data_; } + std::unique_ptr clone() const { + return std::make_unique(*this); + } + // non-assignable MatrixArea &operator=(const MatrixArea &) = delete; @@ -197,7 +204,7 @@ class AreaCombat { // non-assignable AreaCombat &operator=(const AreaCombat &) = delete; - void getList(const Position ¢erPos, const Position &targetPos, std::forward_list &list) const; + void getList(const Position ¢erPos, const Position &targetPos, std::forward_list> &list) const; void setupArea(const std::list &list, uint32_t rows); void setupArea(int32_t length, int32_t spread); @@ -205,11 +212,15 @@ class AreaCombat { void setupExtArea(const std::list &list, uint32_t rows); void clear(); + std::unique_ptr clone() const { + return std::make_unique(*this); + } + private: - MatrixArea* createArea(const std::list &list, uint32_t rows); - void copyArea(const MatrixArea* input, MatrixArea* output, MatrixOperation_t op) const; + std::unique_ptr createArea(const std::list &list, uint32_t rows); + void copyArea(const std::unique_ptr &input, const std::unique_ptr &output, MatrixOperation_t op) const; - MatrixArea* getArea(const Position ¢erPos, const Position &targetPos) const { + const std::unique_ptr &getArea(const Position ¢erPos, const Position &targetPos) const { int32_t dx = Position::getOffsetX(targetPos, centerPos); int32_t dy = Position::getOffsetY(targetPos, centerPos); @@ -238,13 +249,13 @@ class AreaCombat { auto it = areas.find(dir); if (it == areas.end()) { - return nullptr; + return MatrixAreaNull; } return it->second; } - std::map areas; + std::map> areas; bool hasExtArea = false; }; @@ -256,51 +267,51 @@ class Combat { Combat(const Combat &) = delete; Combat &operator=(const Combat &) = delete; - static void doCombatHealth(Creature* caster, Creature* target, CombatDamage &damage, const CombatParams ¶ms); - static void doCombatHealth(Creature* caster, const Position &position, const AreaCombat* area, CombatDamage &damage, const CombatParams ¶ms); + static void doCombatHealth(std::shared_ptr caster, std::shared_ptr target, CombatDamage &damage, const CombatParams ¶ms); + static void doCombatHealth(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, CombatDamage &damage, const CombatParams ¶ms); - static void doCombatMana(Creature* caster, Creature* target, CombatDamage &damage, const CombatParams ¶ms); - static void doCombatMana(Creature* caster, const Position &position, const AreaCombat* area, CombatDamage &damage, const CombatParams ¶ms); + static void doCombatMana(std::shared_ptr caster, std::shared_ptr target, CombatDamage &damage, const CombatParams ¶ms); + static void doCombatMana(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, CombatDamage &damage, const CombatParams ¶ms); - static void doCombatCondition(Creature* caster, Creature* target, const CombatParams ¶ms); - static void doCombatCondition(Creature* caster, const Position &position, const AreaCombat* area, const CombatParams ¶ms); + static void doCombatCondition(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms); + static void doCombatCondition(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, const CombatParams ¶ms); - static void doCombatDispel(Creature* caster, Creature* target, const CombatParams ¶ms); - static void doCombatDispel(Creature* caster, const Position &position, const AreaCombat* area, const CombatParams ¶ms); + static void doCombatDispel(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms); + static void doCombatDispel(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, const CombatParams ¶ms); - static void getCombatArea(const Position ¢erPos, const Position &targetPos, const AreaCombat* area, std::forward_list &list); + static void getCombatArea(const Position ¢erPos, const Position &targetPos, const std::unique_ptr &area, std::forward_list> &list); - static bool isInPvpZone(const Creature* attacker, const Creature* target); - static bool isProtected(const Player* attacker, const Player* target); - static bool isPlayerCombat(const Creature* target); + static bool isInPvpZone(std::shared_ptr attacker, std::shared_ptr target); + static bool isProtected(std::shared_ptr attacker, std::shared_ptr target); + static bool isPlayerCombat(std::shared_ptr target); static CombatType_t ConditionToDamageType(ConditionType_t type); static ConditionType_t DamageToConditionType(CombatType_t type); - static ReturnValue canTargetCreature(Player* attacker, Creature* target); - static ReturnValue canDoCombat(Creature* caster, Tile* tile, bool aggressive); - static ReturnValue canDoCombat(Creature* attacker, Creature* target, bool aggressive); - static void postCombatEffects(Creature* caster, const Position &origin, const Position &pos, const CombatParams ¶ms); + static ReturnValue canTargetCreature(std::shared_ptr attacker, std::shared_ptr target); + static ReturnValue canDoCombat(std::shared_ptr caster, std::shared_ptr tile, bool aggressive); + static ReturnValue canDoCombat(std::shared_ptr attacker, std::shared_ptr target, bool aggressive); + static void postCombatEffects(std::shared_ptr caster, const Position &origin, const Position &pos, const CombatParams ¶ms); - static void addDistanceEffect(Creature* caster, const Position &fromPos, const Position &toPos, uint16_t effect); + static void addDistanceEffect(std::shared_ptr caster, const Position &fromPos, const Position &toPos, uint16_t effect); - bool doCombat(Creature* caster, Creature* target) const; - bool doCombat(Creature* caster, Creature* target, const Position &origin) const; - bool doCombat(Creature* caster, const Position &pos) const; + bool doCombat(std::shared_ptr caster, std::shared_ptr target) const; + bool doCombat(std::shared_ptr caster, std::shared_ptr target, const Position &origin) const; + bool doCombat(std::shared_ptr caster, const Position &pos) const; bool setCallback(CallBackParam_t key); CallBack* getCallback(CallBackParam_t key); bool setParam(CombatParam_t param, uint32_t value); - void setArea(AreaCombat* newArea) { - this->area.reset(newArea); + void setArea(std::unique_ptr &newArea) { + this->area = std::move(newArea); } bool hasArea() const { return area != nullptr; } - void addCondition(const Condition* condition) { + void addCondition(const std::shared_ptr condition) { params.conditionList.emplace_front(condition); } void setPlayerCombatValues(formulaType_t formulaType, double mina, double minb, double maxa, double maxb); - void postCombatEffects(Creature* caster, const Position &origin, const Position &pos) const { + void postCombatEffects(std::shared_ptr caster, const Position &origin, const Position &pos) const { postCombatEffects(caster, origin, pos, params); } @@ -324,20 +335,20 @@ class Combat { private: static void doChainEffect(const Position &origin, const Position &pos, uint8_t effect); - static std::vector>> pickChainTargets(Creature* caster, const CombatParams ¶ms, uint8_t chainDistance, uint8_t maxTargets, bool aggressive, bool backtracking, Creature* initialTarget = nullptr); - static bool isValidChainTarget(Creature* caster, Creature* currentTarget, Creature* potentialTarget, const CombatParams ¶ms, bool aggressive); + static std::vector>> pickChainTargets(std::shared_ptr caster, const CombatParams ¶ms, uint8_t chainDistance, uint8_t maxTargets, bool aggressive, bool backtracking, std::shared_ptr initialTarget = nullptr); + static bool isValidChainTarget(std::shared_ptr caster, std::shared_ptr currentTarget, std::shared_ptr potentialTarget, const CombatParams ¶ms, bool aggressive); - static void doCombatDefault(Creature* caster, Creature* target, const CombatParams ¶ms); + static void doCombatDefault(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms); - static void doCombatHealth(Creature* caster, Creature* target, const Position &origin, CombatDamage &damage, const CombatParams ¶ms); - static void doCombatMana(Creature* caster, Creature* target, const Position &origin, CombatDamage &damage, const CombatParams ¶ms); - static void doCombatDefault(Creature* caster, Creature* target, const Position &origin, const CombatParams ¶ms); + static void doCombatHealth(std::shared_ptr caster, std::shared_ptr target, const Position &origin, CombatDamage &damage, const CombatParams ¶ms); + static void doCombatMana(std::shared_ptr caster, std::shared_ptr target, const Position &origin, CombatDamage &damage, const CombatParams ¶ms); + static void doCombatDefault(std::shared_ptr caster, std::shared_ptr target, const Position &origin, const CombatParams ¶ms); - static void CombatFunc(Creature* caster, const Position &origin, const Position &pos, const AreaCombat* area, const CombatParams ¶ms, CombatFunction func, CombatDamage* data); + static void CombatFunc(std::shared_ptr caster, const Position &origin, const Position &pos, const std::unique_ptr &area, const CombatParams ¶ms, CombatFunction func, CombatDamage* data); - static void CombatHealthFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage* data); - static CombatDamage applyImbuementElementalDamage(Player* attackerPlayer, Item* item, CombatDamage damage); - static void CombatManaFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage* damage); + static void CombatHealthFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage* data); + static CombatDamage applyImbuementElementalDamage(std::shared_ptr attackerPlayer, std::shared_ptr item, CombatDamage damage); + static void CombatManaFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage* damage); /** * @brief Checks if a fear condition can be applied to a player. * @@ -352,12 +363,12 @@ class Combat { * @param player Pointer to the Player object to be checked. * @return true if the fear condition can be applied, false otherwise. */ - static bool checkFearConditionAffected(Player* player); - static void CombatConditionFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage* data); - static void CombatDispelFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage* data); - static void CombatNullFunc(Creature* caster, Creature* target, const CombatParams ¶ms, CombatDamage* data); + static bool checkFearConditionAffected(std::shared_ptr player); + static void CombatConditionFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage* data); + static void CombatDispelFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage* data); + static void CombatNullFunc(std::shared_ptr caster, std::shared_ptr target, const CombatParams ¶ms, CombatDamage* data); - static void combatTileEffects(const SpectatorHashSet &spectators, Creature* caster, Tile* tile, const CombatParams ¶ms); + static void combatTileEffects(const SpectatorHashSet &spectators, std::shared_ptr caster, std::shared_ptr tile, const CombatParams ¶ms); /** * @brief Calculate the level formula for combat. @@ -367,10 +378,10 @@ class Combat { * @param damage The combat damage. * @return The calculated level formula. */ - int32_t getLevelFormula(const Player* player, const std::shared_ptr wheelSpell, const CombatDamage &damage) const; - CombatDamage getCombatDamage(Creature* creature, Creature* target) const; + int32_t getLevelFormula(std::shared_ptr player, const std::shared_ptr wheelSpell, const CombatDamage &damage) const; + CombatDamage getCombatDamage(std::shared_ptr creature, std::shared_ptr target) const; - bool doCombatChain(Creature* caster, Creature* target, bool aggressive) const; + bool doCombatChain(std::shared_ptr caster, std::shared_ptr target, bool aggressive) const; // configureable CombatParams params; @@ -393,11 +404,8 @@ class MagicField final : public Item { explicit MagicField(uint16_t type) : Item(type), createTime(OTSYS_TIME()) { } - MagicField* getMagicField() override { - return this; - } - const MagicField* getMagicField() const override { - return this; + std::shared_ptr getMagicField() override { + return static_self_cast(); } bool isReplaceable() const { @@ -414,7 +422,7 @@ class MagicField final : public Item { } return 0; } - void onStepInField(Creature &creature); + void onStepInField(const std::shared_ptr &creature); private: int64_t createTime; diff --git a/src/creatures/combat/condition.cpp b/src/creatures/combat/condition.cpp index f7c1f4810..8b58e6ff0 100644 --- a/src/creatures/combat/condition.cpp +++ b/src/creatures/combat/condition.cpp @@ -166,7 +166,7 @@ void Condition::setTicks(int32_t newTicks) { endTime = ticks + OTSYS_TIME(); } -bool Condition::executeCondition(Creature* creature, int32_t interval) { +bool Condition::executeCondition(std::shared_ptr creature, int32_t interval) { if (ticks == -1) { return true; } @@ -184,7 +184,7 @@ bool Condition::executeCondition(Creature* creature, int32_t interval) { return true; } -Condition* Condition::createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, int32_t param /* = 0*/, bool buff /* = false*/, uint32_t subId /* = 0*/) { +std::shared_ptr Condition::createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, int32_t param /* = 0*/, bool buff /* = false*/, uint32_t subId /* = 0*/) { switch (type) { case CONDITION_POISON: case CONDITION_FIRE: @@ -194,41 +194,41 @@ Condition* Condition::createCondition(ConditionId_t id, ConditionType_t type, in case CONDITION_DAZZLED: case CONDITION_CURSED: case CONDITION_BLEEDING: - return new ConditionDamage(id, type, buff, subId); + return std::make_shared(id, type, buff, subId); case CONDITION_HASTE: case CONDITION_PARALYZE: - return new ConditionSpeed(id, type, ticks, buff, subId, param); + return std::make_shared(id, type, ticks, buff, subId, param); case CONDITION_INVISIBLE: - return new ConditionInvisible(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_OUTFIT: - return new ConditionOutfit(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_LIGHT: - return new ConditionLight(id, type, ticks, buff, subId, param & 0xFF, (param & 0xFF00) >> 8); + return std::make_shared(id, type, ticks, buff, subId, param & 0xFF, (param & 0xFF00) >> 8); case CONDITION_REGENERATION: - return new ConditionRegeneration(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_SOUL: - return new ConditionSoul(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_ATTRIBUTES: - return new ConditionAttributes(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_SPELLCOOLDOWN: - return new ConditionSpellCooldown(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_SPELLGROUPCOOLDOWN: - return new ConditionSpellGroupCooldown(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_MANASHIELD: - return new ConditionManaShield(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_FEARED: - return new ConditionFeared(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); case CONDITION_ROOTED: case CONDITION_INFIGHT: @@ -240,14 +240,14 @@ Condition* Condition::createCondition(ConditionId_t id, ConditionType_t type, in case CONDITION_CHANNELMUTEDTICKS: case CONDITION_YELLTICKS: case CONDITION_PACIFIED: - return new ConditionGeneric(id, type, ticks, buff, subId); + return std::make_shared(id, type, ticks, buff, subId); default: return nullptr; } } -Condition* Condition::createCondition(PropStream &propStream) { +std::shared_ptr Condition::createCondition(PropStream &propStream) { uint8_t attr; if (!propStream.read(attr) || attr != CONDITIONATTR_TYPE) { return nullptr; @@ -297,7 +297,7 @@ Condition* Condition::createCondition(PropStream &propStream) { return createCondition(static_cast(id), static_cast(type), ticks, 0, buff != 0, subId); } -bool Condition::startCondition(Creature*) { +bool Condition::startCondition(std::shared_ptr) { if (ticks > 0) { endTime = ticks + OTSYS_TIME(); } @@ -332,7 +332,7 @@ uint32_t Condition::getIcons() const { return isBuff ? ICON_PARTY_BUFF : 0; } -bool Condition::updateCondition(const Condition* addCondition) { +bool Condition::updateCondition(const std::shared_ptr addCondition) { if (conditionType != addCondition->getType()) { return false; } @@ -352,19 +352,19 @@ bool Condition::updateCondition(const Condition* addCondition) { * ConditionGeneric */ -bool ConditionGeneric::startCondition(Creature* creature) { +bool ConditionGeneric::startCondition(std::shared_ptr creature) { return Condition::startCondition(creature); } -bool ConditionGeneric::executeCondition(Creature* creature, int32_t interval) { +bool ConditionGeneric::executeCondition(std::shared_ptr creature, int32_t interval) { return Condition::executeCondition(creature, interval); } -void ConditionGeneric::endCondition(Creature*) { +void ConditionGeneric::endCondition(std::shared_ptr) { // } -void ConditionGeneric::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionGeneric::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { if (updateCondition(addCondition)) { setTicks(addCondition->getTicks()); @@ -401,7 +401,7 @@ uint32_t ConditionGeneric::getIcons() const { * ConditionAttributes */ -void ConditionAttributes::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionAttributes::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { if (!creature) { return; } @@ -409,24 +409,24 @@ void ConditionAttributes::addCondition(Creature* creature, const Condition* addC if (updateCondition(addCondition)) { setTicks(addCondition->getTicks()); - const ConditionAttributes &conditionAttrs = static_cast(*addCondition); + const std::shared_ptr &conditionAttrs = addCondition->static_self_cast(); // Remove the old condition endCondition(creature); // Apply the new one - memcpy(skills, conditionAttrs.skills, sizeof(skills)); - memcpy(skillsPercent, conditionAttrs.skillsPercent, sizeof(skillsPercent)); - memcpy(stats, conditionAttrs.stats, sizeof(stats)); - memcpy(statsPercent, conditionAttrs.statsPercent, sizeof(statsPercent)); - memcpy(buffs, conditionAttrs.buffs, sizeof(buffs)); - memcpy(buffsPercent, conditionAttrs.buffsPercent, sizeof(buffsPercent)); + memcpy(skills, conditionAttrs->skills, sizeof(skills)); + memcpy(skillsPercent, conditionAttrs->skillsPercent, sizeof(skillsPercent)); + memcpy(stats, conditionAttrs->stats, sizeof(stats)); + memcpy(statsPercent, conditionAttrs->statsPercent, sizeof(statsPercent)); + memcpy(buffs, conditionAttrs->buffs, sizeof(buffs)); + memcpy(buffsPercent, conditionAttrs->buffsPercent, sizeof(buffsPercent)); // Using std::array can only increment to the new instead of use memcpy - absorbs = conditionAttrs.absorbs; - absorbsPercent = conditionAttrs.absorbsPercent; - increases = conditionAttrs.increases; - increasesPercent = conditionAttrs.increasesPercent; - charmChanceModifier = conditionAttrs.charmChanceModifier; + absorbs = conditionAttrs->absorbs; + absorbsPercent = conditionAttrs->absorbsPercent; + increases = conditionAttrs->increases; + increasesPercent = conditionAttrs->increasesPercent; + charmChanceModifier = conditionAttrs->charmChanceModifier; updatePercentBuffs(creature); updateBuffs(creature); @@ -435,9 +435,9 @@ void ConditionAttributes::addCondition(Creature* creature, const Condition* addC updatePercentIncreases(creature); updateIncreases(creature); updateCharmChanceModifier(creature); - disableDefense = conditionAttrs.disableDefense; + disableDefense = conditionAttrs->disableDefense; - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { updatePercentSkills(player); updateSkills(player); updatePercentStats(player); @@ -527,7 +527,7 @@ void ConditionAttributes::serialize(PropWriteStream &propWriteStream) { propWriteStream.write(charmChanceModifier); } -bool ConditionAttributes::startCondition(Creature* creature) { +bool ConditionAttributes::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } @@ -541,7 +541,7 @@ bool ConditionAttributes::startCondition(Creature* creature) { updatePercentIncreases(creature); updateIncreases(creature); updateCharmChanceModifier(creature); - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { updatePercentSkills(player); updateSkills(player); updatePercentStats(player); @@ -551,7 +551,7 @@ bool ConditionAttributes::startCondition(Creature* creature) { return true; } -void ConditionAttributes::updatePercentStats(Player* player) { +void ConditionAttributes::updatePercentStats(std::shared_ptr player) { for (int32_t i = STAT_FIRST; i <= STAT_LAST; ++i) { if (statsPercent[i] == 0) { continue; @@ -577,7 +577,7 @@ void ConditionAttributes::updatePercentStats(Player* player) { } } -void ConditionAttributes::updateStats(Player* player) { +void ConditionAttributes::updateStats(std::shared_ptr player) { bool needUpdate = false; for (int32_t i = STAT_FIRST; i <= STAT_LAST; ++i) { @@ -593,7 +593,7 @@ void ConditionAttributes::updateStats(Player* player) { } } -void ConditionAttributes::updatePercentSkills(Player* player) { +void ConditionAttributes::updatePercentSkills(std::shared_ptr player) { for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { skills_t skill = static_cast(i); if (skillsPercent[skill] == 0) { @@ -605,7 +605,7 @@ void ConditionAttributes::updatePercentSkills(Player* player) { } } -void ConditionAttributes::updateSkills(Player* player) { +void ConditionAttributes::updateSkills(std::shared_ptr player) { bool needUpdateSkills = false; for (int32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { @@ -620,7 +620,7 @@ void ConditionAttributes::updateSkills(Player* player) { } } -void ConditionAttributes::updatePercentAbsorbs(const Creature* creature) { +void ConditionAttributes::updatePercentAbsorbs(std::shared_ptr creature) { for (uint8_t i = 0; i < COMBAT_COUNT; i++) { auto value = getAbsorbPercentByIndex(i); if (value == 0) { @@ -630,7 +630,7 @@ void ConditionAttributes::updatePercentAbsorbs(const Creature* creature) { } } -void ConditionAttributes::updateAbsorbs(Creature* creature) const { +void ConditionAttributes::updateAbsorbs(std::shared_ptr creature) const { for (uint8_t i = 0; i < COMBAT_COUNT; i++) { auto value = getAbsorbByIndex(i); if (value == 0) { @@ -641,7 +641,7 @@ void ConditionAttributes::updateAbsorbs(Creature* creature) const { } } -void ConditionAttributes::updatePercentIncreases(const Creature* creature) { +void ConditionAttributes::updatePercentIncreases(std::shared_ptr creature) { for (uint8_t i = 0; i < COMBAT_COUNT; i++) { auto increasePercentValue = getIncreasePercentById(i); if (increasePercentValue == 0) { @@ -651,7 +651,7 @@ void ConditionAttributes::updatePercentIncreases(const Creature* creature) { } } -void ConditionAttributes::updateIncreases(Creature* creature) const { +void ConditionAttributes::updateIncreases(std::shared_ptr creature) const { for (uint8_t i = 0; i < COMBAT_COUNT; i++) { auto increaseValue = getIncreaseByIndex(i); if (increaseValue == 0) { @@ -661,11 +661,11 @@ void ConditionAttributes::updateIncreases(Creature* creature) const { } } -void ConditionAttributes::updateCharmChanceModifier(Creature* creature) const { +void ConditionAttributes::updateCharmChanceModifier(std::shared_ptr creature) const { creature->setCharmChanceModifier(creature->getCharmChanceModifier() + charmChanceModifier); } -void ConditionAttributes::updatePercentBuffs(Creature* creature) { +void ConditionAttributes::updatePercentBuffs(std::shared_ptr creature) { for (int32_t i = BUFF_FIRST; i <= BUFF_LAST; ++i) { if (buffsPercent[i] == 0) { continue; @@ -676,7 +676,7 @@ void ConditionAttributes::updatePercentBuffs(Creature* creature) { } } -void ConditionAttributes::updateBuffs(Creature* creature) { +void ConditionAttributes::updateBuffs(std::shared_ptr creature) { bool needUpdate = false; for (int32_t i = BUFF_FIRST; i <= BUFF_LAST; ++i) { if (buffs[i]) { @@ -689,12 +689,12 @@ void ConditionAttributes::updateBuffs(Creature* creature) { } } -bool ConditionAttributes::executeCondition(Creature* creature, int32_t interval) { +bool ConditionAttributes::executeCondition(std::shared_ptr creature, int32_t interval) { return ConditionGeneric::executeCondition(creature, interval); } -void ConditionAttributes::endCondition(Creature* creature) { - Player* player = creature->getPlayer(); +void ConditionAttributes::endCondition(std::shared_ptr creature) { + std::shared_ptr player = creature->getPlayer(); if (player) { bool needUpdate = false; @@ -1096,37 +1096,37 @@ void ConditionAttributes::setIncreasePercent(uint8_t index, int32_t value) { * ConditionRegeneration */ -bool ConditionRegeneration::startCondition(Creature* creature) { +bool ConditionRegeneration::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { player->sendStats(); } return true; } -void ConditionRegeneration::endCondition(Creature* creature) { - if (Player* player = creature->getPlayer()) { +void ConditionRegeneration::endCondition(std::shared_ptr creature) { + if (std::shared_ptr player = creature->getPlayer()) { player->sendStats(); } } -void ConditionRegeneration::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionRegeneration::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { if (updateCondition(addCondition)) { setTicks(addCondition->getTicks()); - const ConditionRegeneration &conditionRegen = static_cast(*addCondition); + const std::shared_ptr &conditionRegen = addCondition->static_self_cast(); - healthTicks = conditionRegen.healthTicks; - manaTicks = conditionRegen.manaTicks; + healthTicks = conditionRegen->healthTicks; + manaTicks = conditionRegen->manaTicks; - healthGain = conditionRegen.healthGain; - manaGain = conditionRegen.manaGain; + healthGain = conditionRegen->healthGain; + manaGain = conditionRegen->manaGain; } - if (Player* player = creature->getPlayer()) { + if (auto player = creature->getPlayer()) { player->sendStats(); } } @@ -1160,10 +1160,10 @@ void ConditionRegeneration::serialize(PropWriteStream &propWriteStream) { propWriteStream.write(manaGain); } -bool ConditionRegeneration::executeCondition(Creature* creature, int32_t interval) { +bool ConditionRegeneration::executeCondition(std::shared_ptr creature, int32_t interval) { internalHealthTicks += interval; internalManaTicks += interval; - Player* player = creature->getPlayer(); + auto player = creature->getPlayer(); int32_t PlayerdailyStreak = 0; if (player) { PlayerdailyStreak = player->getStorageValue(STORAGEVALUE_DAILYREWARD); @@ -1196,7 +1196,7 @@ bool ConditionRegeneration::executeCondition(Creature* creature, int32_t interva if (!spectators.empty()) { message.type = MESSAGE_HEALED_OTHERS; message.text = player->getName() + " was healed for " + healString; - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { spectator->getPlayer()->sendTextMessage(message); } } @@ -1244,8 +1244,8 @@ bool ConditionRegeneration::setParam(ConditionParam_t param, int32_t value) { } } -uint32_t ConditionRegeneration::getHealthTicks(Creature* creature) const { - const Player* player = creature->getPlayer(); +uint32_t ConditionRegeneration::getHealthTicks(std::shared_ptr creature) const { + std::shared_ptr player = creature->getPlayer(); if (player != nullptr && isBuff) { return healthTicks / g_configManager().getFloat(RATE_SPELL_COOLDOWN); @@ -1254,8 +1254,8 @@ uint32_t ConditionRegeneration::getHealthTicks(Creature* creature) const { return healthTicks; } -uint32_t ConditionRegeneration::getManaTicks(Creature* creature) const { - const Player* player = creature->getPlayer(); +uint32_t ConditionRegeneration::getManaTicks(std::shared_ptr creature) const { + std::shared_ptr player = creature->getPlayer(); if (player != nullptr && isBuff) { return manaTicks / g_configManager().getFloat(RATE_SPELL_COOLDOWN); @@ -1268,7 +1268,7 @@ uint32_t ConditionRegeneration::getManaTicks(Creature* creature) const { * ConditionManaShield */ -bool ConditionManaShield::startCondition(Creature* creature) { +bool ConditionManaShield::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } @@ -1276,32 +1276,32 @@ bool ConditionManaShield::startCondition(Creature* creature) { creature->setManaShield(manaShield); creature->setMaxManaShield(manaShield); - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { player->sendStats(); } return true; } -void ConditionManaShield::endCondition(Creature* creature) { +void ConditionManaShield::endCondition(std::shared_ptr creature) { creature->setManaShield(0); creature->setMaxManaShield(0); - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { player->sendStats(); } } -void ConditionManaShield::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionManaShield::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { endCondition(creature); setTicks(addCondition->getTicks()); - const ConditionManaShield &conditionManaShield = static_cast(*addCondition); + const std::shared_ptr &conditionManaShield = addCondition->static_self_cast(); - manaShield = conditionManaShield.manaShield; + manaShield = conditionManaShield->manaShield; creature->setManaShield(manaShield); creature->setMaxManaShield(manaShield); - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { player->sendStats(); } } @@ -1346,14 +1346,14 @@ uint32_t ConditionManaShield::getIcons() const { * ConditionSoul */ -void ConditionSoul::addCondition(Creature*, const Condition* addCondition) { +void ConditionSoul::addCondition(std::shared_ptr, const std::shared_ptr addCondition) { if (updateCondition(addCondition)) { setTicks(addCondition->getTicks()); - const ConditionSoul &conditionSoul = static_cast(*addCondition); + const std::shared_ptr &conditionSoul = addCondition->static_self_cast(); - soulTicks = conditionSoul.soulTicks; - soulGain = conditionSoul.soulGain; + soulTicks = conditionSoul->soulTicks; + soulGain = conditionSoul->soulGain; } } @@ -1376,10 +1376,10 @@ void ConditionSoul::serialize(PropWriteStream &propWriteStream) { propWriteStream.write(soulTicks); } -bool ConditionSoul::executeCondition(Creature* creature, int32_t interval) { +bool ConditionSoul::executeCondition(std::shared_ptr creature, int32_t interval) { internalSoulTicks += interval; - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { if (player->getZoneType() != ZONE_PROTECTION) { if (internalSoulTicks >= soulTicks) { internalSoulTicks = 0; @@ -1501,17 +1501,17 @@ void ConditionDamage::serialize(PropWriteStream &propWriteStream) { } } -bool ConditionDamage::updateCondition(const Condition* addCondition) { - const ConditionDamage &conditionDamage = static_cast(*addCondition); - if (conditionDamage.doForceUpdate()) { +bool ConditionDamage::updateCondition(const std::shared_ptr addCondition) { + const std::shared_ptr &conditionDamage = addCondition->static_self_cast(); + if (conditionDamage->doForceUpdate()) { return true; } - if (ticks == -1 && conditionDamage.ticks > 0) { + if (ticks == -1 && conditionDamage->ticks > 0) { return false; } - return conditionDamage.getTotalDamage() > getTotalDamage(); + return conditionDamage->getTotalDamage() > getTotalDamage(); } bool ConditionDamage::addDamage(int32_t rounds, int32_t time, int32_t value) { @@ -1571,7 +1571,7 @@ bool ConditionDamage::init() { return !damageList.empty(); } -bool ConditionDamage::startCondition(Creature* creature) { +bool ConditionDamage::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } @@ -1589,7 +1589,7 @@ bool ConditionDamage::startCondition(Creature* creature) { return true; } -bool ConditionDamage::executeCondition(Creature* creature, int32_t interval) { +bool ConditionDamage::executeCondition(std::shared_ptr creature, int32_t interval) { if (periodDamage != 0) { periodDamageTick += interval; @@ -1643,7 +1643,7 @@ bool ConditionDamage::getNextDamage(int32_t &damage) { return false; } -bool ConditionDamage::doDamage(Creature* creature, int32_t healthChange) { +bool ConditionDamage::doDamage(std::shared_ptr creature, int32_t healthChange) { if (creature->isSuppress(getType())) { return true; } @@ -1653,7 +1653,7 @@ bool ConditionDamage::doDamage(Creature* creature, int32_t healthChange) { damage.primary.value = healthChange; damage.primary.type = Combat::ConditionToDamageType(conditionType); - Creature* attacker = g_game().getCreatureByID(owner); + std::shared_ptr attacker = g_game().getCreatureByID(owner); if (field && creature->getPlayer() && attacker && attacker->getPlayer()) { damage.primary.value = static_cast(std::round(damage.primary.value / 2.)); } @@ -1676,11 +1676,11 @@ bool ConditionDamage::doDamage(Creature* creature, int32_t healthChange) { return g_game().combatChangeHealth(attacker, creature, damage); } -void ConditionDamage::endCondition(Creature*) { +void ConditionDamage::endCondition(std::shared_ptr) { // } -void ConditionDamage::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionDamage::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { if (addCondition->getType() != conditionType) { return; } @@ -1689,15 +1689,15 @@ void ConditionDamage::addCondition(Creature* creature, const Condition* addCondi return; } - const ConditionDamage &conditionDamage = static_cast(*addCondition); + const std::shared_ptr &conditionDamage = addCondition->static_self_cast(); setTicks(addCondition->getTicks()); - owner = conditionDamage.owner; - maxDamage = conditionDamage.maxDamage; - minDamage = conditionDamage.minDamage; - startDamage = conditionDamage.startDamage; - tickInterval = conditionDamage.tickInterval; - periodDamage = conditionDamage.periodDamage; + owner = conditionDamage->owner; + maxDamage = conditionDamage->maxDamage; + minDamage = conditionDamage->minDamage; + startDamage = conditionDamage->startDamage; + tickInterval = conditionDamage->tickInterval; + periodDamage = conditionDamage->periodDamage; int32_t nextTimeLeft = tickInterval; if (!damageList.empty()) { @@ -1707,7 +1707,7 @@ void ConditionDamage::addCondition(Creature* creature, const Condition* addCondi damageList.clear(); } - damageList = conditionDamage.damageList; + damageList = conditionDamage->damageList; if (init()) { if (!damageList.empty()) { @@ -1801,7 +1801,7 @@ void ConditionDamage::generateDamageList(int32_t amount, int32_t start, std::lis /** * ConditionFeared */ -bool ConditionFeared::isStuck(Creature* creature, Position pos) const { +bool ConditionFeared::isStuck(std::shared_ptr creature, Position pos) const { for (Direction dir : m_directionsVector) { if (canWalkTo(creature, pos, dir)) { return false; @@ -1811,7 +1811,7 @@ bool ConditionFeared::isStuck(Creature* creature, Position pos) const { return true; } -bool ConditionFeared::getRandomDirection(Creature* creature, Position pos) { +bool ConditionFeared::getRandomDirection(std::shared_ptr creature, Position pos) { static std::vector directions { DIRECTION_NORTH, DIRECTION_NORTHEAST, @@ -1834,16 +1834,16 @@ bool ConditionFeared::getRandomDirection(Creature* creature, Position pos) { return false; } -bool ConditionFeared::canWalkTo(const Creature* creature, Position pos, Direction moveDirection) const { +bool ConditionFeared::canWalkTo(std::shared_ptr creature, Position pos, Direction moveDirection) const { pos = getNextPosition(moveDirection, pos); if (!creature) { g_logger().error("[{}] creature is nullptr", __FUNCTION__); return false; } - const Tile* tile = g_game().map.getTile(pos); - if (tile && tile->getTopVisibleCreature(creature) == nullptr && tile->queryAdd(0, *creature, 1, FLAG_PATHFINDING) == RETURNVALUE_NOERROR) { - const MagicField* field = tile->getFieldItem(); + auto tile = g_game().map.getTile(pos); + if (tile && tile->getTopVisibleCreature(creature) == nullptr && tile->queryAdd(0, creature, 1, FLAG_PATHFINDING) == RETURNVALUE_NOERROR) { + std::shared_ptr field = tile->getFieldItem(); if (field && !field->isBlocking() && field->getDamage() != 0) { return false; } @@ -1853,7 +1853,7 @@ bool ConditionFeared::canWalkTo(const Creature* creature, Position pos, Directio return false; } -bool ConditionFeared::getFleeDirection(Creature* creature) { +bool ConditionFeared::getFleeDirection(std::shared_ptr creature) { Position creaturePos = creature->getPosition(); int_fast32_t offx = Position::getOffsetX(creaturePos, fleeingFromPos); @@ -1929,7 +1929,7 @@ bool ConditionFeared::getFleeDirection(Creature* creature) { return false; } -bool ConditionFeared::getFleePath(Creature* creature, const Position &pos, std::forward_list &dirList) { +bool ConditionFeared::getFleePath(std::shared_ptr creature, const Position &pos, std::forward_list &dirList) { const std::vector walkSize { 15, 9, 3, 1 }; bool found = false; std::ptrdiff_t found_size = 0; @@ -2021,14 +2021,14 @@ bool ConditionFeared::setPositionParam(ConditionParam_t param, const Position &p return false; } -bool ConditionFeared::startCondition(Creature* creature) { +bool ConditionFeared::startCondition(std::shared_ptr creature) { g_logger().debug("[ConditionFeared::executeCondition] Condition started for {}", creature->getName()); getFleeDirection(creature); g_logger().debug("[ConditionFeared::executeCondition] Flee from {}", fleeingFromPos.toString()); return Condition::startCondition(creature); } -bool ConditionFeared::executeCondition(Creature* creature, int32_t interval) { +bool ConditionFeared::executeCondition(std::shared_ptr creature, int32_t interval) { Position currentPos = creature->getPosition(); std::forward_list listDir; @@ -2048,18 +2048,18 @@ bool ConditionFeared::executeCondition(Creature* creature, int32_t interval) { return Condition::executeCondition(creature, interval); } -void ConditionFeared::endCondition(Creature* creature) { +void ConditionFeared::endCondition(std::shared_ptr creature) { creature->stopEventWalk(); /* * After a player is feared there's a 10 seconds before he can feared again. */ - Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player) { player->setImmuneFear(); } } -void ConditionFeared::addCondition(Creature*, const Condition* addCondition) { +void ConditionFeared::addCondition(std::shared_ptr, const std::shared_ptr addCondition) { if (updateCondition(addCondition)) { setTicks(addCondition->getTicks()); } @@ -2139,7 +2139,7 @@ void ConditionSpeed::serialize(PropWriteStream &propWriteStream) { propWriteStream.write(maxb); } -bool ConditionSpeed::startCondition(Creature* creature) { +bool ConditionSpeed::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } @@ -2154,15 +2154,15 @@ bool ConditionSpeed::startCondition(Creature* creature) { return true; } -bool ConditionSpeed::executeCondition(Creature* creature, int32_t interval) { +bool ConditionSpeed::executeCondition(std::shared_ptr creature, int32_t interval) { return Condition::executeCondition(creature, interval); } -void ConditionSpeed::endCondition(Creature* creature) { +void ConditionSpeed::endCondition(std::shared_ptr creature) { g_game().changeSpeed(creature, -speedDelta); } -void ConditionSpeed::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionSpeed::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { if (conditionType != addCondition->getType()) { return; } @@ -2173,13 +2173,13 @@ void ConditionSpeed::addCondition(Creature* creature, const Condition* addCondit setTicks(addCondition->getTicks()); - const ConditionSpeed &conditionSpeed = static_cast(*addCondition); + const std::shared_ptr &conditionSpeed = addCondition->static_self_cast(); int32_t oldSpeedDelta = speedDelta; - speedDelta = conditionSpeed.speedDelta; - mina = conditionSpeed.mina; - maxa = conditionSpeed.maxa; - minb = conditionSpeed.minb; - maxb = conditionSpeed.maxb; + speedDelta = conditionSpeed->speedDelta; + mina = conditionSpeed->mina; + maxa = conditionSpeed->maxa; + minb = conditionSpeed->minb; + maxb = conditionSpeed->maxb; if (speedDelta == 0) { int32_t min; @@ -2215,7 +2215,7 @@ uint32_t ConditionSpeed::getIcons() const { * ConditionInvisible */ -bool ConditionInvisible::startCondition(Creature* creature) { +bool ConditionInvisible::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } @@ -2224,7 +2224,7 @@ bool ConditionInvisible::startCondition(Creature* creature) { return true; } -void ConditionInvisible::endCondition(Creature* creature) { +void ConditionInvisible::endCondition(std::shared_ptr creature) { if (!creature->isInvisible()) { g_game().internalCreatureChangeVisible(creature, true); } @@ -2256,7 +2256,7 @@ void ConditionOutfit::serialize(PropWriteStream &propWriteStream) { propWriteStream.write(outfit); } -bool ConditionOutfit::startCondition(Creature* creature) { +bool ConditionOutfit::startCondition(std::shared_ptr creature) { if (g_configManager().getBoolean(WARN_UNSAFE_SCRIPTS) && outfit.lookType != 0 && !g_game().isLookTypeRegistered(outfit.lookType)) { g_logger().warn("[ConditionOutfit::startCondition] An unregistered creature looktype type with id '{}' was blocked to prevent client crash.", outfit.lookType); return false; @@ -2280,15 +2280,15 @@ bool ConditionOutfit::startCondition(Creature* creature) { return true; } -bool ConditionOutfit::executeCondition(Creature* creature, int32_t interval) { +bool ConditionOutfit::executeCondition(std::shared_ptr creature, int32_t interval) { return Condition::executeCondition(creature, interval); } -void ConditionOutfit::endCondition(Creature* creature) { +void ConditionOutfit::endCondition(std::shared_ptr creature) { g_game().internalCreatureChangeOutfit(creature, creature->getDefaultOutfit()); } -void ConditionOutfit::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionOutfit::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { if (g_configManager().getBoolean(WARN_UNSAFE_SCRIPTS) && outfit.lookType != 0 && !g_game().isLookTypeRegistered(outfit.lookType)) { g_logger().warn("[ConditionOutfit::addCondition] An unregistered creature looktype type with id '{}' was blocked to prevent client crash.", outfit.lookType); return; @@ -2297,17 +2297,17 @@ void ConditionOutfit::addCondition(Creature* creature, const Condition* addCondi if (updateCondition(addCondition)) { setTicks(addCondition->getTicks()); - const ConditionOutfit &conditionOutfit = static_cast(*addCondition); - if (!conditionOutfit.monsterName.empty() && conditionOutfit.monsterName.compare(monsterName) != 0) { - const auto monsterType = g_monsters().getMonsterType(conditionOutfit.monsterName); + const std::shared_ptr &conditionOutfit = addCondition->static_self_cast(); + if (!conditionOutfit->monsterName.empty() && conditionOutfit->monsterName.compare(monsterName) != 0) { + const auto monsterType = g_monsters().getMonsterType(conditionOutfit->monsterName); if (monsterType) { setOutfit(monsterType->info.outfit); } else { g_logger().error("[ConditionOutfit::addCondition] - Monster {} does not exist", monsterName); return; } - } else if (conditionOutfit.outfit.lookType != 0 || conditionOutfit.outfit.lookTypeEx != 0) { - setOutfit(conditionOutfit.outfit); + } else if (conditionOutfit->outfit.lookType != 0 || conditionOutfit->outfit.lookTypeEx != 0) { + setOutfit(conditionOutfit->outfit); } g_game().internalCreatureChangeOutfit(creature, outfit); @@ -2318,7 +2318,7 @@ void ConditionOutfit::addCondition(Creature* creature, const Condition* addCondi * ConditionLight */ -bool ConditionLight::startCondition(Creature* creature) { +bool ConditionLight::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } @@ -2330,7 +2330,7 @@ bool ConditionLight::startCondition(Creature* creature) { return true; } -bool ConditionLight::executeCondition(Creature* creature, int32_t interval) { +bool ConditionLight::executeCondition(std::shared_ptr creature, int32_t interval) { internalLightTicks += interval; if (internalLightTicks >= lightChangeInterval) { @@ -2347,18 +2347,18 @@ bool ConditionLight::executeCondition(Creature* creature, int32_t interval) { return Condition::executeCondition(creature, interval); } -void ConditionLight::endCondition(Creature* creature) { +void ConditionLight::endCondition(std::shared_ptr creature) { creature->setNormalCreatureLight(); g_game().changeLight(creature); } -void ConditionLight::addCondition(Creature* creature, const Condition* condition) { +void ConditionLight::addCondition(std::shared_ptr creature, const std::shared_ptr condition) { if (updateCondition(condition)) { setTicks(condition->getTicks()); - const ConditionLight &conditionLight = static_cast(*condition); - lightInfo.level = conditionLight.lightInfo.level; - lightInfo.color = conditionLight.lightInfo.color; + const std::shared_ptr &conditionLight = condition->static_self_cast(); + lightInfo.level = conditionLight->lightInfo.level; + lightInfo.color = conditionLight->lightInfo.color; lightChangeInterval = ticks / lightInfo.level; internalLightTicks = 0; creature->setCreatureLight(lightInfo); @@ -2434,12 +2434,12 @@ void ConditionLight::serialize(PropWriteStream &propWriteStream) { * ConditionSpellCooldown */ -void ConditionSpellCooldown::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionSpellCooldown::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { if (updateCondition(addCondition)) { setTicks(addCondition->getTicks()); if (subId != 0 && ticks > 0) { - Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player) { player->sendSpellCooldown(subId, ticks); } @@ -2447,13 +2447,13 @@ void ConditionSpellCooldown::addCondition(Creature* creature, const Condition* a } } -bool ConditionSpellCooldown::startCondition(Creature* creature) { +bool ConditionSpellCooldown::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } if (subId != 0 && ticks > 0) { - Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player) { player->sendSpellCooldown(subId, ticks); } @@ -2465,12 +2465,12 @@ bool ConditionSpellCooldown::startCondition(Creature* creature) { * ConditionSpellGroupCooldown */ -void ConditionSpellGroupCooldown::addCondition(Creature* creature, const Condition* addCondition) { +void ConditionSpellGroupCooldown::addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) { if (updateCondition(addCondition)) { setTicks(addCondition->getTicks()); if (subId != 0 && ticks > 0) { - Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player) { player->sendSpellGroupCooldown(static_cast(subId), ticks); } @@ -2478,13 +2478,13 @@ void ConditionSpellGroupCooldown::addCondition(Creature* creature, const Conditi } } -bool ConditionSpellGroupCooldown::startCondition(Creature* creature) { +bool ConditionSpellGroupCooldown::startCondition(std::shared_ptr creature) { if (!Condition::startCondition(creature)) { return false; } if (subId != 0 && ticks > 0) { - Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player) { player->sendSpellGroupCooldown(static_cast(subId), ticks); } diff --git a/src/creatures/combat/condition.hpp b/src/creatures/combat/condition.hpp index 2d1f08a9b..f8228e074 100644 --- a/src/creatures/combat/condition.hpp +++ b/src/creatures/combat/condition.hpp @@ -16,7 +16,7 @@ class Player; class PropStream; class PropWriteStream; -class Condition { +class Condition : public SharedObject { public: Condition() = default; Condition(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff = false, uint32_t initSubId = 0) : @@ -24,10 +24,10 @@ class Condition { subId(initSubId), ticks(initTicks), conditionType(initType), id(initId), isBuff(initBuff) { } virtual ~Condition() = default; - virtual bool startCondition(Creature* creature); - virtual bool executeCondition(Creature* creature, int32_t interval); - virtual void endCondition(Creature* creature) = 0; - virtual void addCondition(Creature* creature, const Condition* condition) = 0; + virtual bool startCondition(std::shared_ptr creature); + virtual bool executeCondition(std::shared_ptr creature, int32_t interval); + virtual void endCondition(std::shared_ptr creature) = 0; + virtual void addCondition(std::shared_ptr creature, const std::shared_ptr condition) = 0; virtual uint32_t getIcons() const; ConditionId_t getId() const { return id; @@ -36,7 +36,7 @@ class Condition { return subId; } - virtual Condition* clone() const = 0; + virtual std::shared_ptr clone() const = 0; ConditionType_t getType() const { return conditionType; @@ -49,8 +49,8 @@ class Condition { } void setTicks(int32_t newTicks); - static Condition* createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, int32_t param = 0, bool buff = false, uint32_t subId = 0); - static Condition* createCondition(PropStream &propStream); + static std::shared_ptr createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, int32_t param = 0, bool buff = false, uint32_t subId = 0); + static std::shared_ptr createCondition(PropStream &propStream); virtual bool setParam(ConditionParam_t param, int32_t value); virtual bool setPositionParam(ConditionParam_t param, const Position &pos); @@ -72,7 +72,7 @@ class Condition { ConditionId_t id; bool isBuff; - virtual bool updateCondition(const Condition* addCondition); + virtual bool updateCondition(const std::shared_ptr addCondition); private: SoundEffect_t tickSound = SoundEffect_t::SILENCE; @@ -87,14 +87,14 @@ class ConditionGeneric : public Condition { ConditionGeneric(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff = false, uint32_t initSubId = 0) : Condition(initId, initType, initTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) override; - bool executeCondition(Creature* creature, int32_t interval) override; - void endCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* condition) override; + bool startCondition(std::shared_ptr creature) override; + bool executeCondition(std::shared_ptr creature, int32_t interval) override; + void endCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr condition) override; uint32_t getIcons() const override; - ConditionGeneric* clone() const override { - return new ConditionGeneric(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } }; @@ -103,15 +103,15 @@ class ConditionAttributes final : public ConditionGeneric { ConditionAttributes(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff = false, uint32_t initSubId = 0) : ConditionGeneric(initId, initType, initTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) final; - bool executeCondition(Creature* creature, int32_t interval) final; - void endCondition(Creature* creature) final; - void addCondition(Creature* creature, const Condition* condition) final; + bool startCondition(std::shared_ptr creature) final; + bool executeCondition(std::shared_ptr creature, int32_t interval) final; + void endCondition(std::shared_ptr creature) final; + void addCondition(std::shared_ptr creature, const std::shared_ptr condition) final; bool setParam(ConditionParam_t param, int32_t value) final; - ConditionAttributes* clone() const final { - return new ConditionAttributes(*this); + std::shared_ptr clone() const final { + return std::make_shared(*this); } // serialization @@ -150,19 +150,19 @@ class ConditionAttributes final : public ConditionGeneric { bool disableDefense = false; - void updatePercentStats(Player* player); - void updateStats(Player* player); - void updatePercentSkills(Player* player); - void updateSkills(Player* player); - void updateBuffs(Creature* creature); + void updatePercentStats(std::shared_ptr player); + void updateStats(std::shared_ptr player); + void updatePercentSkills(std::shared_ptr player); + void updateSkills(std::shared_ptr player); + void updateBuffs(std::shared_ptr creature); // 12.72 mechanics - void updatePercentAbsorbs(const Creature* creature); - void updateAbsorbs(Creature* creature) const; - void updatePercentIncreases(const Creature* creature); - void updateIncreases(Creature* creature) const; - void updateCharmChanceModifier(Creature* creature) const; - void updatePercentBuffs(Creature* creature); + void updatePercentAbsorbs(std::shared_ptr creature); + void updateAbsorbs(std::shared_ptr creature) const; + void updatePercentIncreases(std::shared_ptr creature); + void updateIncreases(std::shared_ptr creature) const; + void updateCharmChanceModifier(std::shared_ptr creature) const; + void updatePercentBuffs(std::shared_ptr creature); }; class ConditionRegeneration final : public ConditionGeneric { @@ -170,18 +170,18 @@ class ConditionRegeneration final : public ConditionGeneric { ConditionRegeneration(ConditionId_t initId, ConditionType_t initType, int32_t iniTicks, bool initBuff = false, uint32_t initSubId = 0) : ConditionGeneric(initId, initType, iniTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) override; - void endCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* addCondition) override; - bool executeCondition(Creature* creature, int32_t interval) override; + bool startCondition(std::shared_ptr creature) override; + void endCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) override; + bool executeCondition(std::shared_ptr creature, int32_t interval) override; bool setParam(ConditionParam_t param, int32_t value) override; - uint32_t getHealthTicks(Creature* creature) const; - uint32_t getManaTicks(Creature* creature) const; + uint32_t getHealthTicks(std::shared_ptr creature) const; + uint32_t getManaTicks(std::shared_ptr creature) const; - ConditionRegeneration* clone() const override { - return new ConditionRegeneration(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } // serialization @@ -203,15 +203,15 @@ class ConditionManaShield final : public Condition { ConditionManaShield(ConditionId_t initId, ConditionType_t initType, int32_t iniTicks, bool initBuff = false, uint32_t initSubId = 0) : Condition(initId, initType, iniTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) override; - void endCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* addCondition) override; + bool startCondition(std::shared_ptr creature) override; + void endCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) override; uint32_t getIcons() const override; bool setParam(ConditionParam_t param, int32_t value) override; - ConditionManaShield* clone() const override { - return new ConditionManaShield(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } // serialization @@ -227,13 +227,13 @@ class ConditionSoul final : public ConditionGeneric { ConditionSoul(ConditionId_t initId, ConditionType_t initType, int32_t iniTicks, bool initBuff = false, uint32_t initSubId = 0) : ConditionGeneric(initId, initType, iniTicks, initBuff, initSubId) { } - void addCondition(Creature* creature, const Condition* addCondition) override; - bool executeCondition(Creature* creature, int32_t interval) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) override; + bool executeCondition(std::shared_ptr creature, int32_t interval) override; bool setParam(ConditionParam_t param, int32_t value) override; - ConditionSoul* clone() const override { - return new ConditionSoul(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } // serialization @@ -251,11 +251,11 @@ class ConditionInvisible final : public ConditionGeneric { ConditionInvisible(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff = false, uint32_t initSubId = 0) : ConditionGeneric(initId, initType, initTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) override; - void endCondition(Creature* creature) override; + bool startCondition(std::shared_ptr creature) override; + void endCondition(std::shared_ptr creature) override; - ConditionInvisible* clone() const override { - return new ConditionInvisible(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } }; @@ -267,14 +267,14 @@ class ConditionDamage final : public Condition { static void generateDamageList(int32_t amount, int32_t start, std::list &list); - bool startCondition(Creature* creature) override; - bool executeCondition(Creature* creature, int32_t interval) override; - void endCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* condition) override; + bool startCondition(std::shared_ptr creature) override; + bool executeCondition(std::shared_ptr creature, int32_t interval) override; + void endCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr condition) override; uint32_t getIcons() const override; - ConditionDamage* clone() const override { - return new ConditionDamage(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } bool setParam(ConditionParam_t param, int32_t value) override; @@ -307,9 +307,9 @@ class ConditionDamage final : public Condition { std::list damageList; bool getNextDamage(int32_t &damage); - bool doDamage(Creature* creature, int32_t healthChange); + bool doDamage(std::shared_ptr creature, int32_t healthChange); - bool updateCondition(const Condition* addCondition) override; + bool updateCondition(const std::shared_ptr addCondition) override; }; class ConditionFeared final : public Condition { @@ -318,24 +318,24 @@ class ConditionFeared final : public Condition { ConditionFeared(ConditionId_t intiId, ConditionType_t initType, int32_t initTicks, bool initBuff, uint32_t initSubId) : Condition(intiId, initType, initTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) override; - bool executeCondition(Creature* creature, int32_t interval) override; - void endCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* condition) override; + bool startCondition(std::shared_ptr creature) override; + bool executeCondition(std::shared_ptr creature, int32_t interval) override; + void endCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr condition) override; uint32_t getIcons() const override; - ConditionFeared* clone() const override { - return new ConditionFeared(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } bool setPositionParam(ConditionParam_t param, const Position &pos) override; private: - bool canWalkTo(const Creature* creature, Position pos, Direction moveDirection) const; - bool getFleeDirection(Creature* creature); - bool getFleePath(Creature* creature, const Position &pos, std::forward_list &dirList); - bool getRandomDirection(Creature* creature, Position pos); - bool isStuck(Creature* creature, Position pos) const; + bool canWalkTo(std::shared_ptr creature, Position pos, Direction moveDirection) const; + bool getFleeDirection(std::shared_ptr creature); + bool getFleePath(std::shared_ptr creature, const Position &pos, std::forward_list &dirList); + bool getRandomDirection(std::shared_ptr creature, Position pos); + bool isStuck(std::shared_ptr creature, Position pos) const; std::vector m_directionsVector { DIRECTION_NORTH, @@ -357,14 +357,14 @@ class ConditionSpeed final : public Condition { ConditionSpeed(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff, uint32_t initSubId, int32_t initChangeSpeed) : Condition(initId, initType, initTicks, initBuff, initSubId), speedDelta(initChangeSpeed) { } - bool startCondition(Creature* creature) override; - bool executeCondition(Creature* creature, int32_t interval) override; - void endCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* condition) override; + bool startCondition(std::shared_ptr creature) override; + bool executeCondition(std::shared_ptr creature, int32_t interval) override; + void endCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr condition) override; uint32_t getIcons() const override; - ConditionSpeed* clone() const override { - return new ConditionSpeed(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } bool setParam(ConditionParam_t param, int32_t value) override; @@ -392,13 +392,13 @@ class ConditionOutfit final : public Condition { ConditionOutfit(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff = false, uint32_t initSubId = 0) : Condition(initId, initType, initTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) override; - bool executeCondition(Creature* creature, int32_t interval) override; - void endCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* condition) override; + bool startCondition(std::shared_ptr creature) override; + bool executeCondition(std::shared_ptr creature, int32_t interval) override; + void endCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr condition) override; - ConditionOutfit* clone() const override { - return new ConditionOutfit(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } void setOutfit(const Outfit_t &outfit); @@ -418,13 +418,13 @@ class ConditionLight final : public Condition { ConditionLight(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff, uint32_t initSubId, uint8_t initLightlevel, uint8_t initLightcolor) : Condition(initId, initType, initTicks, initBuff, initSubId), lightInfo(initLightlevel, initLightcolor) { } - bool startCondition(Creature* creature) override; - bool executeCondition(Creature* creature, int32_t interval) override; - void endCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* addCondition) override; + bool startCondition(std::shared_ptr creature) override; + bool executeCondition(std::shared_ptr creature, int32_t interval) override; + void endCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr addCondition) override; - ConditionLight* clone() const override { - return new ConditionLight(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } bool setParam(ConditionParam_t param, int32_t value) override; @@ -444,11 +444,11 @@ class ConditionSpellCooldown final : public ConditionGeneric { ConditionSpellCooldown(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff = false, uint32_t initSubId = 0) : ConditionGeneric(initId, initType, initTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* condition) override; + bool startCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr condition) override; - ConditionSpellCooldown* clone() const override { - return new ConditionSpellCooldown(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } }; @@ -457,10 +457,10 @@ class ConditionSpellGroupCooldown final : public ConditionGeneric { ConditionSpellGroupCooldown(ConditionId_t initId, ConditionType_t initType, int32_t initTicks, bool initBuff = false, uint32_t initSubId = 0) : ConditionGeneric(initId, initType, initTicks, initBuff, initSubId) { } - bool startCondition(Creature* creature) override; - void addCondition(Creature* creature, const Condition* condition) override; + bool startCondition(std::shared_ptr creature) override; + void addCondition(std::shared_ptr creature, const std::shared_ptr condition) override; - ConditionSpellGroupCooldown* clone() const override { - return new ConditionSpellGroupCooldown(*this); + std::shared_ptr clone() const override { + return std::make_shared(*this); } }; diff --git a/src/creatures/combat/spells.cpp b/src/creatures/combat/spells.cpp index ae2dad648..d0f4d260d 100644 --- a/src/creatures/combat/spells.cpp +++ b/src/creatures/combat/spells.cpp @@ -19,7 +19,7 @@ Spells::Spells() = default; Spells::~Spells() = default; -TalkActionResult_t Spells::playerSaySpell(Player* player, std::string &words) { +TalkActionResult_t Spells::playerSaySpell(std::shared_ptr player, std::string &words) { std::string str_words = words; if (player->hasCondition(CONDITION_FEARED)) { @@ -232,24 +232,24 @@ std::shared_ptr Spells::getInstantSpellByName(const std::string &n return nullptr; } -Position Spells::getCasterPosition(Creature* creature, Direction dir) { +Position Spells::getCasterPosition(std::shared_ptr creature, Direction dir) { return getNextPosition(dir, creature->getPosition()); } CombatSpell::CombatSpell(const std::shared_ptr newCombat, bool newNeedTarget, bool newNeedDirection) : Script(&g_spells().getScriptInterface()), - combat(newCombat), + m_combat(newCombat), needDirection(newNeedDirection), needTarget(newNeedTarget) { // Empty } bool CombatSpell::loadScriptCombat() { - combat = g_luaEnvironment().getCombatObject(g_luaEnvironment().lastCombatId); - return combat != nullptr; + m_combat = g_luaEnvironment().getCombatObject(g_luaEnvironment().lastCombatId); + return m_combat != nullptr; } -bool CombatSpell::castSpell(Creature* creature) { +bool CombatSpell::castSpell(std::shared_ptr creature) { if (isLoadedCallback()) { LuaVariant var; var.type = VARIANT_POSITION; @@ -270,6 +270,11 @@ bool CombatSpell::castSpell(Creature* creature) { pos = creature->getPosition(); } + auto combat = getCombat(); + if (!combat) { + return false; + } + if (soundCastEffect != SoundEffect_t::SILENCE) { combat->setParam(COMBAT_PARAM_CASTSOUND, static_cast(soundCastEffect)); } @@ -282,10 +287,14 @@ bool CombatSpell::castSpell(Creature* creature) { return true; } -bool CombatSpell::castSpell(Creature* creature, Creature* target) { +bool CombatSpell::castSpell(std::shared_ptr creature, std::shared_ptr target) { + auto combat = getCombat(); + if (!combat) { + return false; + } + if (isLoadedCallback()) { LuaVariant var; - if (combat->hasArea()) { var.type = VARIANT_POSITION; @@ -324,7 +333,7 @@ bool CombatSpell::castSpell(Creature* creature, Creature* target) { return true; } -bool CombatSpell::executeCastSpell(Creature* creature, const LuaVariant &var) const { +bool CombatSpell::executeCastSpell(std::shared_ptr creature, const LuaVariant &var) const { // onCastSpell(creature, var) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CombatSpell::executeCastSpell - Creature {}] " @@ -348,7 +357,7 @@ bool CombatSpell::executeCastSpell(Creature* creature, const LuaVariant &var) co return getScriptInterface()->callFunction(2); } -bool Spell::playerSpellCheck(Player* player) const { +bool Spell::playerSpellCheck(std::shared_ptr player) const { if (player->hasFlag(PlayerFlags_t::CannotUseSpells)) { return false; } @@ -452,7 +461,7 @@ bool Spell::playerSpellCheck(Player* player) const { return true; } -bool Spell::playerInstantSpellCheck(Player* player, const Position &toPos) const { +bool Spell::playerInstantSpellCheck(std::shared_ptr player, const Position &toPos) const { if (toPos.x == 0xFFFF) { return true; } @@ -492,7 +501,7 @@ bool Spell::playerInstantSpellCheck(Player* player, const Position &toPos) const return true; } -bool Spell::playerRuneSpellCheck(Player* player, const Position &toPos) { +bool Spell::playerRuneSpellCheck(std::shared_ptr player, const Position &toPos) { if (!playerSpellCheck(player)) { return false; } @@ -512,7 +521,7 @@ bool Spell::playerRuneSpellCheck(Player* player, const Position &toPos) { return false; } - Tile* tile = g_game().map.getTile(toPos); + std::shared_ptr tile = g_game().map.getTile(toPos); if (!tile) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); g_game().addMagicEffect(player->getPosition(), CONST_ME_POFF); @@ -532,7 +541,7 @@ bool Spell::playerRuneSpellCheck(Player* player, const Position &toPos) { return false; } - const Creature* topVisibleCreature = tile->getBottomVisibleCreature(player); + const std::shared_ptr topVisibleCreature = tile->getBottomVisibleCreature(player); if (blockingCreature && topVisibleCreature) { player->sendCancelMessage(RETURNVALUE_NOTENOUGHROOM); g_game().addMagicEffect(player->getPosition(), CONST_ME_POFF); @@ -550,7 +559,7 @@ bool Spell::playerRuneSpellCheck(Player* player, const Position &toPos) { } if (aggressive && needTarget && topVisibleCreature && player->hasSecureMode()) { - const Player* targetPlayer = topVisibleCreature->getPlayer(); + const std::shared_ptr targetPlayer = topVisibleCreature->getPlayer(); if (targetPlayer && targetPlayer != player && player->getSkullClient(targetPlayer) == SKULL_NONE && !Combat::isInPvpZone(player, targetPlayer)) { player->sendCancelMessage(RETURNVALUE_TURNSECUREMODETOATTACKUNMARKEDPLAYERS); g_game().addMagicEffect(player->getPosition(), CONST_ME_POFF); @@ -597,7 +606,7 @@ void Spell::setWheelOfDestinyBoost(WheelSpellBoost_t boost, WheelSpellGrade_t gr } } -void Spell::applyCooldownConditions(Player* player) const { +void Spell::applyCooldownConditions(std::shared_ptr player) const { WheelSpellGrade_t spellGrade = player->wheel()->getSpellUpgrade(getName()); bool isUpgraded = getWheelOfDestinyUpgraded() && static_cast(spellGrade) > 0; auto rate_cooldown = (int32_t)g_configManager().getFloat(RATE_SPELL_COOLDOWN); @@ -607,7 +616,7 @@ void Spell::applyCooldownConditions(Player* player) const { spellCooldown -= getWheelOfDestinyBoost(WheelSpellBoost_t::COOLDOWN, spellGrade); } if (spellCooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLCOOLDOWN, spellCooldown / rate_cooldown, 0, false, spellId); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLCOOLDOWN, spellCooldown / rate_cooldown, 0, false, spellId); player->addCondition(condition); } } @@ -618,7 +627,7 @@ void Spell::applyCooldownConditions(Player* player) const { spellGroupCooldown -= getWheelOfDestinyBoost(WheelSpellBoost_t::GROUP_COOLDOWN, spellGrade); } if (spellGroupCooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, spellGroupCooldown / rate_cooldown, 0, false, group); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, spellGroupCooldown / rate_cooldown, 0, false, group); player->addCondition(condition); } } @@ -629,13 +638,13 @@ void Spell::applyCooldownConditions(Player* player) const { spellSecondaryGroupCooldown -= getWheelOfDestinyBoost(WheelSpellBoost_t::SECONDARY_GROUP_COOLDOWN, spellGrade); } if (spellSecondaryGroupCooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, spellSecondaryGroupCooldown / rate_cooldown, 0, false, secondaryGroup); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, spellSecondaryGroupCooldown / rate_cooldown, 0, false, secondaryGroup); player->addCondition(condition); } } } -void Spell::postCastSpell(Player* player, bool finishedCast /*= true*/, bool payCost /*= true*/) const { +void Spell::postCastSpell(std::shared_ptr player, bool finishedCast /*= true*/, bool payCost /*= true*/) const { if (finishedCast) { if (!player->hasFlag(PlayerFlags_t::HasNoExhaustion)) { applyCooldownConditions(player); @@ -655,7 +664,7 @@ void Spell::postCastSpell(Player* player, bool finishedCast /*= true*/, bool pay } } -void Spell::postCastSpell(Player* player, uint32_t manaCost, uint32_t soulCost) { +void Spell::postCastSpell(std::shared_ptr player, uint32_t manaCost, uint32_t soulCost) { if (manaCost > 0) { player->addManaSpent(manaCost); player->changeMana(-static_cast(manaCost)); @@ -668,7 +677,7 @@ void Spell::postCastSpell(Player* player, uint32_t manaCost, uint32_t soulCost) } } -uint32_t Spell::getManaCost(const Player* player) const { +uint32_t Spell::getManaCost(std::shared_ptr player) const { if (mana != 0) { WheelSpellGrade_t spellGrade = player->wheel()->getSpellUpgrade(getName()); if (getWheelOfDestinyUpgraded() && static_cast(spellGrade) > 0) { @@ -698,20 +707,20 @@ uint32_t Spell::getManaCost(const Player* player) const { return 0; } -bool InstantSpell::playerCastInstant(Player* player, std::string ¶m) { +bool InstantSpell::playerCastInstant(std::shared_ptr player, std::string ¶m) { if (!playerSpellCheck(player)) { return false; } LuaVariant var; var.instantName = getName(); - Player* playerTarget = nullptr; + std::shared_ptr playerTarget = nullptr; if (selfTarget) { var.type = VARIANT_NUMBER; var.number = player->getID(); } else if (needTarget || casterTargetOrDirection) { - Creature* target = nullptr; + std::shared_ptr target = nullptr; bool useDirection = false; if (hasParam) { @@ -819,7 +828,7 @@ bool InstantSpell::playerCastInstant(Player* player, std::string ¶m) { return result; } -bool InstantSpell::canThrowSpell(const Creature* creature, const Creature* target) const { +bool InstantSpell::canThrowSpell(std::shared_ptr creature, std::shared_ptr target) const { const Position &fromPos = creature->getPosition(); const Position &toPos = target->getPosition(); if (fromPos.z != toPos.z || (range == -1 && !g_game().canThrowObjectTo(fromPos, toPos, checkLineOfSight)) || (range != -1 && !g_game().canThrowObjectTo(fromPos, toPos, checkLineOfSight, range, range))) { @@ -828,12 +837,12 @@ bool InstantSpell::canThrowSpell(const Creature* creature, const Creature* targe return true; } -bool InstantSpell::castSpell(Creature* creature) { +bool InstantSpell::castSpell(std::shared_ptr creature) { LuaVariant var; var.instantName = getName(); if (casterTargetOrDirection) { - Creature* target = creature->getAttackedCreature(); + std::shared_ptr target = creature->getAttackedCreature(); if (target && target->getHealth() > 0) { if (!canThrowSpell(creature, target)) { return false; @@ -857,7 +866,7 @@ bool InstantSpell::castSpell(Creature* creature) { return executeCastSpell(creature, var); } -bool InstantSpell::castSpell(Creature* creature, Creature* target) { +bool InstantSpell::castSpell(std::shared_ptr creature, std::shared_ptr target) { if (needTarget) { LuaVariant var; var.type = VARIANT_NUMBER; @@ -868,7 +877,7 @@ bool InstantSpell::castSpell(Creature* creature, Creature* target) { } } -bool InstantSpell::executeCastSpell(Creature* creature, const LuaVariant &var) const { +bool InstantSpell::executeCastSpell(std::shared_ptr creature, const LuaVariant &var) const { // onCastSpell(creature, var) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[InstantSpell::executeCastSpell - Creature {} words {}] " @@ -892,7 +901,7 @@ bool InstantSpell::executeCastSpell(Creature* creature, const LuaVariant &var) c return getScriptInterface()->callFunction(2); } -bool InstantSpell::canCast(const Player* player) const { +bool InstantSpell::canCast(std::shared_ptr player) const { if (player->hasFlag(PlayerFlags_t::CannotUseSpells)) { return false; } @@ -914,7 +923,7 @@ bool InstantSpell::canCast(const Player* player) const { return false; } -ReturnValue RuneSpell::canExecuteAction(const Player* player, const Position &toPos) { +ReturnValue RuneSpell::canExecuteAction(std::shared_ptr player, const Position &toPos) { if (player->hasFlag(PlayerFlags_t::CannotUseSpells)) { return RETURNVALUE_CANNOTUSETHISOBJECT; } @@ -935,7 +944,7 @@ ReturnValue RuneSpell::canExecuteAction(const Player* player, const Position &to return RETURNVALUE_NOERROR; } -bool RuneSpell::executeUse(Player* player, Item* item, const Position &, Thing* target, const Position &toPosition, bool isHotkey) { +bool RuneSpell::executeUse(std::shared_ptr player, std::shared_ptr item, const Position &, std::shared_ptr target, const Position &toPosition, bool isHotkey) { if (!playerRuneSpellCheck(player, toPosition)) { return false; } @@ -952,9 +961,9 @@ bool RuneSpell::executeUse(Player* player, Item* item, const Position &, Thing* var.type = VARIANT_NUMBER; if (target == nullptr) { - const Tile* toTile = g_game().map.getTile(toPosition); + std::shared_ptr toTile = g_game().map.getTile(toPosition); if (toTile) { - const Creature* visibleCreature = toTile->getBottomVisibleCreature(player); + std::shared_ptr visibleCreature = toTile->getBottomVisibleCreature(player); if (visibleCreature) { var.number = visibleCreature->getID(); } @@ -986,7 +995,7 @@ bool RuneSpell::executeUse(Player* player, Item* item, const Position &, Thing* return true; } -bool RuneSpell::castSpell(Creature* creature) { +bool RuneSpell::castSpell(std::shared_ptr creature) { LuaVariant var; var.type = VARIANT_NUMBER; var.number = creature->getID(); @@ -994,7 +1003,7 @@ bool RuneSpell::castSpell(Creature* creature) { return internalCastSpell(creature, var, false); } -bool RuneSpell::castSpell(Creature* creature, Creature* target) { +bool RuneSpell::castSpell(std::shared_ptr creature, std::shared_ptr target) { LuaVariant var; var.type = VARIANT_NUMBER; var.number = target->getID(); @@ -1002,7 +1011,7 @@ bool RuneSpell::castSpell(Creature* creature, Creature* target) { return internalCastSpell(creature, var, false); } -bool RuneSpell::internalCastSpell(Creature* creature, const LuaVariant &var, bool isHotkey) { +bool RuneSpell::internalCastSpell(std::shared_ptr creature, const LuaVariant &var, bool isHotkey) { bool result; if (isLoadedCallback()) { result = executeCastSpell(creature, var, isHotkey); @@ -1012,7 +1021,7 @@ bool RuneSpell::internalCastSpell(Creature* creature, const LuaVariant &var, boo return result; } -bool RuneSpell::executeCastSpell(Creature* creature, const LuaVariant &var, bool isHotkey) const { +bool RuneSpell::executeCastSpell(std::shared_ptr creature, const LuaVariant &var, bool isHotkey) const { // onCastSpell(creature, var, isHotkey) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[RuneSpell::executeCastSpell - Creature {} runeId {}] " diff --git a/src/creatures/combat/spells.hpp b/src/creatures/combat/spells.hpp index 10c3295f3..f95f8aa40 100644 --- a/src/creatures/combat/spells.hpp +++ b/src/creatures/combat/spells.hpp @@ -44,9 +44,9 @@ class Spells final : public Scripts { std::shared_ptr getInstantSpellById(uint16_t spellId); - TalkActionResult_t playerSaySpell(Player* player, std::string &words); + TalkActionResult_t playerSaySpell(std::shared_ptr player, std::string &words); - static Position getCasterPosition(Creature* creature, Direction dir); + static Position getCasterPosition(std::shared_ptr creature, Direction dir); std::list getSpellsByVocation(uint16_t vocationId); @@ -73,15 +73,15 @@ class Spells final : public Scripts { constexpr auto g_spells = Spells::getInstance; -using RuneSpellFunction = std::function spell, Player* player, const Position &posTo)>; +using RuneSpellFunction = std::function spell, std::shared_ptr player, const Position &posTo)>; class BaseSpell { public: constexpr BaseSpell() = default; virtual ~BaseSpell() = default; - virtual bool castSpell(Creature* creature) = 0; - virtual bool castSpell(Creature* creature, Creature* target) = 0; + virtual bool castSpell(std::shared_ptr creature) = 0; + virtual bool castSpell(std::shared_ptr creature, std::shared_ptr target) = 0; SoundEffect_t soundImpactEffect = SoundEffect_t::SILENCE; SoundEffect_t soundCastEffect = SoundEffect_t::SPELL_OR_RUNE; @@ -96,15 +96,15 @@ class CombatSpell final : public Script, public BaseSpell, public std::enable_sh CombatSpell(const CombatSpell &) = delete; CombatSpell &operator=(const CombatSpell &) = delete; - bool castSpell(Creature* creature) override; - bool castSpell(Creature* creature, Creature* target) override; + bool castSpell(std::shared_ptr creature) override; + bool castSpell(std::shared_ptr creature, std::shared_ptr target) override; // Scripting spell - bool executeCastSpell(Creature* creature, const LuaVariant &var) const; + bool executeCastSpell(std::shared_ptr creature, const LuaVariant &var) const; bool loadScriptCombat(); - std::shared_ptr getCombat() { - return combat; + std::shared_ptr getCombat() const { + return m_combat; } private: @@ -112,7 +112,7 @@ class CombatSpell final : public Script, public BaseSpell, public std::enable_sh return "onCastSpell"; } - std::shared_ptr combat; + std::shared_ptr m_combat; bool needDirection; bool needTarget; @@ -135,14 +135,14 @@ class Spell : public BaseSpell { spellId = id; } - void postCastSpell(Player* player, bool finishedCast = true, bool payCost = true) const; - static void postCastSpell(Player* player, uint32_t manaCost, uint32_t soulCost); + void postCastSpell(std::shared_ptr player, bool finishedCast = true, bool payCost = true) const; + static void postCastSpell(std::shared_ptr player, uint32_t manaCost, uint32_t soulCost); [[nodiscard]] virtual bool isInstant() const = 0; [[nodiscard]] bool isLearnable() const { return learnable; } - uint32_t getManaCost(const Player* player) const; + uint32_t getManaCost(std::shared_ptr player) const; [[nodiscard]] uint32_t getSoulCost() const { return soul; } @@ -338,10 +338,10 @@ class Spell : public BaseSpell { } protected: - void applyCooldownConditions(Player* player) const; - bool playerSpellCheck(Player* player) const; - bool playerInstantSpellCheck(Player* player, const Position &toPos) const; - bool playerRuneSpellCheck(Player* player, const Position &toPos); + void applyCooldownConditions(std::shared_ptr player) const; + bool playerSpellCheck(std::shared_ptr player) const; + bool playerInstantSpellCheck(std::shared_ptr player, const Position &toPos) const; + bool playerRuneSpellCheck(std::shared_ptr player, const Position &toPos); VocSpellMap vocSpellMap; @@ -388,13 +388,13 @@ class InstantSpell final : public Script, public Spell { public: using Script::Script; - virtual bool playerCastInstant(Player* player, std::string ¶m); + virtual bool playerCastInstant(std::shared_ptr player, std::string ¶m); - bool castSpell(Creature* creature) override; - bool castSpell(Creature* creature, Creature* target) override; + bool castSpell(std::shared_ptr creature) override; + bool castSpell(std::shared_ptr creature, std::shared_ptr target) override; // Scripting spell - bool executeCastSpell(Creature* creature, const LuaVariant &var) const; + bool executeCastSpell(std::shared_ptr creature, const LuaVariant &var) const; [[nodiscard]] bool isInstant() const override { return true; @@ -429,8 +429,8 @@ class InstantSpell final : public Script, public Spell { void setBlockWalls(bool w) { checkLineOfSight = w; } - bool canCast(const Player* player) const; - bool canThrowSpell(const Creature* creature, const Creature* target) const; + bool canCast(std::shared_ptr player) const; + bool canThrowSpell(std::shared_ptr creature, std::shared_ptr target) const; private: [[nodiscard]] std::string getScriptTypeName() const override { @@ -448,21 +448,21 @@ class RuneSpell final : public Action, public Spell { public: using Action::Action; - ReturnValue canExecuteAction(const Player* player, const Position &toPos) override; + ReturnValue canExecuteAction(std::shared_ptr player, const Position &toPos) override; bool hasOwnErrorHandler() override { return true; } - Thing* getTarget(Player*, Creature* targetCreature, const Position &, uint8_t) const override { + std::shared_ptr getTarget(std::shared_ptr, std::shared_ptr targetCreature, const Position &, uint8_t) const override { return targetCreature; } - bool executeUse(Player* player, Item* item, const Position &fromPosition, Thing* target, const Position &toPosition, bool isHotkey) override; + bool executeUse(std::shared_ptr player, std::shared_ptr item, const Position &fromPosition, std::shared_ptr target, const Position &toPosition, bool isHotkey) override; - bool castSpell(Creature* creature) override; - bool castSpell(Creature* creature, Creature* target) override; + bool castSpell(std::shared_ptr creature) override; + bool castSpell(std::shared_ptr creature, std::shared_ptr target) override; // Scripting spell - bool executeCastSpell(Creature* creature, const LuaVariant &var, bool isHotkey) const; + bool executeCastSpell(std::shared_ptr creature, const LuaVariant &var, bool isHotkey) const; [[nodiscard]] bool isInstant() const override { return false; @@ -488,7 +488,7 @@ class RuneSpell final : public Action, public Spell { return "onCastSpell"; } - bool internalCastSpell(Creature* creature, const LuaVariant &var, bool isHotkey); + bool internalCastSpell(std::shared_ptr creature, const LuaVariant &var, bool isHotkey); uint16_t runeId = 0; uint32_t charges = 0; diff --git a/src/creatures/creature.cpp b/src/creatures/creature.cpp index 78d7720bf..5c01bb4e5 100644 --- a/src/creatures/creature.cpp +++ b/src/creatures/creature.cpp @@ -26,15 +26,10 @@ Creature::Creature() { } Creature::~Creature() { - for (Creature* summon : summons) { + for (const auto &summon : m_summons) { summon->setAttackedCreature(nullptr); summon->removeMaster(); } - - for (Condition* condition : conditions) { - condition->endCondition(this); - delete condition; - } } bool Creature::canSee(const Position &myPos, const Position &pos, int32_t viewRangeX, int32_t viewRangeY) { @@ -57,11 +52,11 @@ bool Creature::canSee(const Position &myPos, const Position &pos, int32_t viewRa && (pos.getY() >= myPos.getY() - viewRangeY + offsetz) && (pos.getY() <= myPos.getY() + viewRangeY + offsetz); } -bool Creature::canSee(const Position &pos) const { +bool Creature::canSee(const Position &pos) { return canSee(getPosition(), pos, MAP_MAX_VIEW_PORT_X, MAP_MAX_VIEW_PORT_Y); } -bool Creature::canSeeCreature(const Creature* creature) const { +bool Creature::canSeeCreature(std::shared_ptr creature) const { if (!canSeeInvisibility() && creature->isInvisible()) { return false; } @@ -70,7 +65,7 @@ bool Creature::canSeeCreature(const Creature* creature) const { void Creature::setSkull(Skulls_t newSkull) { skull = newSkull; - g_game().updateCreatureSkull(this); + g_game().updateCreatureSkull(static_self_cast()); } int64_t Creature::getTimeSinceLastMove() const { @@ -80,7 +75,7 @@ int64_t Creature::getTimeSinceLastMove() const { return std::numeric_limits::max(); } -int32_t Creature::getWalkDelay(Direction dir) const { +int32_t Creature::getWalkDelay(Direction dir) { if (lastStep == 0) { return 0; } @@ -90,7 +85,7 @@ int32_t Creature::getWalkDelay(Direction dir) const { return stepDuration - (ct - lastStep); } -int32_t Creature::getWalkDelay() const { +int32_t Creature::getWalkDelay() { // Used for auto-walking if (lastStep == 0) { return 0; @@ -112,10 +107,13 @@ void Creature::onThink(uint32_t interval) { updateMapCache(); } + auto followCreature = getFollowCreature(); + auto master = getMaster(); if (followCreature && master != followCreature && !canSeeCreature(followCreature)) { onCreatureDisappear(followCreature, false); } + auto attackedCreature = getAttackedCreature(); if (attackedCreature && master != attackedCreature && !canSeeCreature(attackedCreature)) { onCreatureDisappear(attackedCreature, false); } @@ -143,11 +141,12 @@ void Creature::onThink(uint32_t interval) { // scripting event - onThink const CreatureEventList &thinkEvents = getCreatureEvents(CREATURE_EVENT_THINK); for (const auto creatureEventPtr : thinkEvents) { - creatureEventPtr->executeOnThink(this, interval); + creatureEventPtr->executeOnThink(static_self_cast(), interval); } } void Creature::onAttacking(uint32_t interval) { + auto attackedCreature = getAttackedCreature(); if (!attackedCreature) { return; } @@ -172,9 +171,9 @@ void Creature::onCreatureWalk() { Direction dir; uint32_t flags = FLAG_IGNOREFIELDDAMAGE; if (getNextStep(dir, flags)) { - ReturnValue ret = g_game().internalMoveCreature(this, dir, flags); + ReturnValue ret = g_game().internalMoveCreature(static_self_cast(), dir, flags); if (ret != RETURNVALUE_NOERROR) { - if (Player* player = getPlayer()) { + if (std::shared_ptr player = getPlayer()) { player->sendCancelMessage(ret); player->sendCancelWalk(); } @@ -209,7 +208,7 @@ void Creature::onWalk(Direction &dir) { if (r < DIRECTION_DIAGONAL_MASK) { dir = static_cast(r); } - g_game().internalCreatureSay(this, TALKTYPE_MONSTER_SAY, "Hicks!", false); + g_game().internalCreatureSay(static_self_cast(), TALKTYPE_MONSTER_SAY, "Hicks!", false); } } } @@ -274,7 +273,7 @@ void Creature::stopEventWalk() { } void Creature::updateMapCache() { - Tile* newTile; + std::shared_ptr newTile; const Position &myPos = getPosition(); Position pos(0, 0, myPos.z); @@ -288,13 +287,13 @@ void Creature::updateMapCache() { } } -void Creature::updateTileCache(const Tile* newTile, int32_t dx, int32_t dy) { +void Creature::updateTileCache(std::shared_ptr newTile, int32_t dx, int32_t dy) { if (std::abs(dx) <= maxWalkCacheWidth && std::abs(dy) <= maxWalkCacheHeight) { - localMapCache[maxWalkCacheHeight + dy][maxWalkCacheWidth + dx] = newTile && newTile->queryAdd(0, *this, 1, FLAG_PATHFINDING | FLAG_IGNOREFIELDDAMAGE) == RETURNVALUE_NOERROR; + localMapCache[maxWalkCacheHeight + dy][maxWalkCacheWidth + dx] = newTile && newTile->queryAdd(0, getCreature(), 1, FLAG_PATHFINDING | FLAG_IGNOREFIELDDAMAGE) == RETURNVALUE_NOERROR; } } -void Creature::updateTileCache(const Tile* upTile, const Position &pos) { +void Creature::updateTileCache(std::shared_ptr upTile, const Position &pos) { const Position &myPos = getPosition(); if (pos.z == myPos.z) { int32_t dx = Position::getOffsetX(pos, myPos); @@ -303,7 +302,7 @@ void Creature::updateTileCache(const Tile* upTile, const Position &pos) { } } -int32_t Creature::getWalkCache(const Position &pos) const { +int32_t Creature::getWalkCache(const Position &pos) { if (!useCacheMap()) { return 2; } @@ -333,13 +332,13 @@ int32_t Creature::getWalkCache(const Position &pos) const { return 2; } -void Creature::onAddTileItem(const Tile* tileItem, const Position &pos) { +void Creature::onAddTileItem(std::shared_ptr tileItem, const Position &pos) { if (isMapLoaded && pos.z == getPosition().z) { updateTileCache(tileItem, pos); } } -void Creature::onUpdateTileItem(const Tile* updateTile, const Position &pos, const Item*, const ItemType &oldType, const Item*, const ItemType &newType) { +void Creature::onUpdateTileItem(std::shared_ptr updateTile, const Position &pos, std::shared_ptr, const ItemType &oldType, std::shared_ptr, const ItemType &newType) { if (!isMapLoaded) { return; } @@ -351,7 +350,7 @@ void Creature::onUpdateTileItem(const Tile* updateTile, const Position &pos, con } } -void Creature::onRemoveTileItem(const Tile* updateTile, const Position &pos, const ItemType &iType, const Item*) { +void Creature::onRemoveTileItem(std::shared_ptr updateTile, const Position &pos, const ItemType &iType, std::shared_ptr) { if (!isMapLoaded) { return; } @@ -363,8 +362,8 @@ void Creature::onRemoveTileItem(const Tile* updateTile, const Position &pos, con } } -void Creature::onCreatureAppear(Creature* creature, bool isLogin) { - if (creature == this) { +void Creature::onCreatureAppear(std::shared_ptr creature, bool isLogin) { + if (creature == getCreature()) { if (useCacheMap()) { isMapLoaded = true; updateMapCache(); @@ -380,9 +379,9 @@ void Creature::onCreatureAppear(Creature* creature, bool isLogin) { } } -void Creature::onRemoveCreature(Creature* creature, bool) { +void Creature::onRemoveCreature(std::shared_ptr creature, bool) { onCreatureDisappear(creature, true); - if (creature != this && isMapLoaded) { + if (creature != getCreature() && isMapLoaded) { if (creature->getPosition().z == getPosition().z) { updateTileCache(creature->getTile(), creature->getPosition()); } @@ -395,19 +394,20 @@ void Creature::onRemoveCreature(Creature* creature, bool) { } } -void Creature::onCreatureDisappear(const Creature* creature, bool isLogout) { - if (attackedCreature == creature) { +void Creature::onCreatureDisappear(std::shared_ptr creature, bool isLogout) { + if (getAttackedCreature() == creature) { setAttackedCreature(nullptr); onAttackedCreatureDisappear(isLogout); } - if (followCreature == creature) { + if (getFollowCreature() == creature) { setFollowCreature(nullptr); onFollowCreatureDisappear(isLogout); } } void Creature::onChangeZone(ZoneType_t zone) { + auto attackedCreature = getAttackedCreature(); if (attackedCreature && zone == ZONE_PROTECTION) { onCreatureDisappear(attackedCreature, false); } @@ -415,20 +415,20 @@ void Creature::onChangeZone(ZoneType_t zone) { void Creature::onAttackedCreatureChangeZone(ZoneType_t zone) { if (zone == ZONE_PROTECTION) { - onCreatureDisappear(attackedCreature, false); + auto attackedCreature = getAttackedCreature(); + if (attackedCreature) { + onCreatureDisappear(attackedCreature, false); + } } } -void Creature::checkSummonMove(const Position &newPos, bool teleportSummon) const { +void Creature::checkSummonMove(const Position &newPos, bool teleportSummon) { if (hasSummons()) { - std::vector despawnMonsterList; - for (Creature* creature : getSummons()) { - if (!creature) { - continue; - } - - const Position &pos = creature->getPosition(); - const Monster* monster = creature->getMonster(); + std::vector> despawnMonsterList; + for (const auto &summon : getSummons()) { + const Position &pos = summon->getPosition(); + std::shared_ptr monster = summon->getMonster(); + auto tile = getTile(); bool protectionZoneCheck = tile ? tile->hasFlag(TILESTATE_PROTECTIONZONE) : false; // Check if any of our summons is out of range (+/- 0 floors or 15 tiles away) bool checkSummonDist = Position::getDistanceZ(newPos, pos) > 0 || (std::max(Position::getDistanceX(newPos, pos), Position::getDistanceY(newPos, pos)) > 15); @@ -436,27 +436,27 @@ void Creature::checkSummonMove(const Position &newPos, bool teleportSummon) cons bool checkRemoveDist = Position::getDistanceZ(newPos, pos) > 2 || (std::max(Position::getDistanceX(newPos, pos), Position::getDistanceY(newPos, pos)) > 30); if (monster && monster->isFamiliar() && checkSummonDist || teleportSummon && !protectionZoneCheck && checkSummonDist) { - auto creatureMaster = creature->getMaster(); + auto creatureMaster = summon->getMaster(); if (!creatureMaster) { continue; } - if (Tile* masterTile = creatureMaster->getTile()) { + if (std::shared_ptr masterTile = creatureMaster->getTile()) { if (masterTile->hasFlag(TILESTATE_TELEPORT)) { g_logger().warn("[{}] cannot teleport summon, position has teleport. {}", __FUNCTION__, creatureMaster->getPosition().toString()); } else { - g_game().internalTeleport(creature, creatureMaster->getPosition(), true); + g_game().internalTeleport(summon, creatureMaster->getPosition(), true); continue; } } } if (monster && monster->isSummon() && !monster->isFamiliar() && !teleportSummon && checkRemoveDist) { - despawnMonsterList.push_back(creature); + despawnMonsterList.push_back(summon); } } - for (Creature* despawnCreature : despawnMonsterList) { + for (std::shared_ptr despawnCreature : despawnMonsterList) { if (!despawnMonsterList.empty()) { g_game().removeCreature(despawnCreature, true); } @@ -464,8 +464,8 @@ void Creature::checkSummonMove(const Position &newPos, bool teleportSummon) cons } } -void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Position &newPos, const Tile* oldTile, const Position &oldPos, bool teleport) { - if (creature == this) { +void Creature::onCreatureMove(std::shared_ptr creature, std::shared_ptr newTile, const Position &newPos, std::shared_ptr oldTile, const Position &oldPos, bool teleport) { + if (creature == getCreature()) { lastStep = OTSYS_TIME(); lastStepCost = 1; @@ -487,7 +487,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos handleLostSummon(configTeleportSummons); } - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { if (player->isExerciseTraining()) { player->setTraining(false); } @@ -512,7 +512,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos // update 0 for (int32_t x = -maxWalkCacheWidth; x <= maxWalkCacheWidth; ++x) { - const Tile* cacheTile = g_game().map.getTile(static_cast(myPos.getX() + x), static_cast(myPos.getY() - maxWalkCacheHeight), myPos.z); + std::shared_ptr cacheTile = g_game().map.getTile(static_cast(myPos.getX() + x), static_cast(myPos.getY() - maxWalkCacheHeight), myPos.z); updateTileCache(cacheTile, x, -maxWalkCacheHeight); } } else if (oldPos.y < newPos.y) { // south @@ -523,7 +523,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos // update mapWalkHeight - 1 for (int32_t x = -maxWalkCacheWidth; x <= maxWalkCacheWidth; ++x) { - const Tile* cacheTile = g_game().map.getTile(static_cast(myPos.getX() + x), static_cast(myPos.getY() + maxWalkCacheHeight), myPos.z); + std::shared_ptr cacheTile = g_game().map.getTile(static_cast(myPos.getX() + x), static_cast(myPos.getY() + maxWalkCacheHeight), myPos.z); updateTileCache(cacheTile, x, maxWalkCacheHeight); } } @@ -548,7 +548,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos // update mapWalkWidth - 1 for (int32_t y = -maxWalkCacheHeight; y <= maxWalkCacheHeight; ++y) { - const Tile* cacheTile = g_game().map.getTile(myPos.x + maxWalkCacheWidth, static_cast(myPos.y + y), myPos.z); + std::shared_ptr cacheTile = g_game().map.getTile(myPos.x + maxWalkCacheWidth, static_cast(myPos.y + y), myPos.z); updateTileCache(cacheTile, maxWalkCacheWidth, y); } } else if (oldPos.x > newPos.x) { // west @@ -571,7 +571,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos // update 0 for (int32_t y = -maxWalkCacheHeight; y <= maxWalkCacheHeight; ++y) { - const Tile* cacheTile = g_game().map.getTile(myPos.x - maxWalkCacheWidth, static_cast(myPos.y + y), myPos.z); + std::shared_ptr cacheTile = g_game().map.getTile(myPos.x - maxWalkCacheWidth, static_cast(myPos.y + y), myPos.z); updateTileCache(cacheTile, -maxWalkCacheWidth, y); } } @@ -593,7 +593,8 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos } } - if (followCreature && (creature == this || creature == followCreature)) { + auto followCreature = getFollowCreature(); + if (followCreature && (creature == getCreature() || creature == followCreature)) { if (hasFollowPath) { isUpdatingPath = true; g_dispatcher().addTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()), "Game::updateCreatureWalk"); @@ -604,7 +605,8 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos } } - if (creature == attackedCreature || (creature == this && attackedCreature)) { + auto attackedCreature = getAttackedCreature(); + if (attackedCreature && (creature == attackedCreature || creature == getCreature())) { if (newPos.z != oldPos.z || !canSee(attackedCreature->getPosition())) { onCreatureDisappear(attackedCreature, false); } else { @@ -623,35 +625,35 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos void Creature::onDeath() { bool lastHitUnjustified = false; bool mostDamageUnjustified = false; - Creature* lastHitCreature = g_game().getCreatureByID(lastHitCreatureId); - Creature* lastHitCreatureMaster; + std::shared_ptr lastHitCreature = g_game().getCreatureByID(lastHitCreatureId); + std::shared_ptr lastHitCreatureMaster; if (lastHitCreature) { - lastHitUnjustified = lastHitCreature->onKilledCreature(this, true); + lastHitUnjustified = lastHitCreature->onKilledCreature(static_self_cast(), true); lastHitCreatureMaster = lastHitCreature->getMaster(); } else { lastHitCreatureMaster = nullptr; } - Creature* mostDamageCreature = nullptr; + std::shared_ptr mostDamageCreature = nullptr; const int64_t timeNow = OTSYS_TIME(); const uint32_t inFightTicks = g_configManager().getNumber(PZ_LOCKED); int32_t mostDamage = 0; - std::map experienceMap; + std::map, uint64_t> experienceMap; for (const auto &it : damageMap) { - if (Creature* attacker = g_game().getCreatureByID(it.first)) { + if (auto attacker = g_game().getCreatureByID(it.first)) { CountBlock_t cb = it.second; if ((cb.total > mostDamage && (timeNow - cb.ticks <= inFightTicks))) { mostDamage = cb.total; mostDamageCreature = attacker; } - if (attacker != this) { + if (attacker != getCreature()) { uint64_t gainExp = getGainedExperience(attacker); - if (Player* attackerPlayer = attacker->getPlayer()) { + if (auto attackerPlayer = attacker->getPlayer()) { attackerPlayer->removeAttacked(getPlayer()); - Party* party = attackerPlayer->getParty(); + auto party = attackerPlayer->getParty(); if (party && party->getLeader() && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) { attacker = party->getLeader(); mostDamageCreature = attacker; @@ -669,14 +671,14 @@ void Creature::onDeath() { } for (const auto &it : experienceMap) { - it.first->onGainExperience(it.second, this); + it.first->onGainExperience(it.second, getCreature()); } if (mostDamageCreature) { if (mostDamageCreature != lastHitCreature && mostDamageCreature != lastHitCreatureMaster) { - Creature* mostDamageCreatureMaster = mostDamageCreature->getMaster(); + auto mostDamageCreatureMaster = mostDamageCreature->getMaster(); if (lastHitCreature != mostDamageCreatureMaster && (lastHitCreatureMaster == nullptr || mostDamageCreatureMaster != lastHitCreatureMaster)) { - mostDamageUnjustified = mostDamageCreature->onKilledCreature(this, false); + mostDamageUnjustified = mostDamageCreature->onKilledCreature(static_self_cast(), false); } } } @@ -685,27 +687,27 @@ void Creature::onDeath() { death(lastHitCreature); if (droppedCorpse && !getPlayer()) { - g_game().removeCreature(this, false); + g_game().removeCreature(static_self_cast(), false); } - if (master) { + if (getMaster()) { removeMaster(); } } -bool Creature::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified) { +bool Creature::dropCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified) { if (!lootDrop && getMonster()) { - if (master) { + if (getMaster()) { // Scripting event onDeath const CreatureEventList &deathEvents = getCreatureEvents(CREATURE_EVENT_DEATH); for (const auto deathEventPtr : deathEvents) { - deathEventPtr->executeOnDeath(this, nullptr, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified); + deathEventPtr->executeOnDeath(static_self_cast(), nullptr, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified); } } g_game().addMagicEffect(getPosition(), CONST_ME_POFF); } else { - Item* splash; + std::shared_ptr splash; switch (getRace()) { case RACE_VENOM: splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_SLIME); @@ -724,27 +726,30 @@ bool Creature::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreatur break; } - Tile* tile = getTile(); + std::shared_ptr tile = getTile(); if (tile && splash) { g_game().internalAddItem(tile, splash, INDEX_WHEREEVER, FLAG_NOLIMIT); splash->startDecaying(); } - Item* corpse = getCorpse(lastHitCreature, mostDamageCreature); + std::shared_ptr corpse = getCorpse(lastHitCreature, mostDamageCreature); if (tile && corpse) { g_game().internalAddItem(tile, corpse, INDEX_WHEREEVER, FLAG_NOLIMIT); dropLoot(corpse->getContainer(), lastHitCreature); corpse->startDecaying(); bool corpses = corpse->isRewardCorpse() || (corpse->getID() == ITEM_MALE_CORPSE || corpse->getID() == ITEM_FEMALE_CORPSE); if (corpse->getContainer() && mostDamageCreature && mostDamageCreature->getPlayer() && !corpses) { - Player* player = mostDamageCreature->getPlayer(); - std::ostringstream lootMessage; - lootMessage << "Loot of " << getNameDescription() << ": " << corpse->getContainer()->getContentDescription(player->getProtocolVersion() < 1200); - auto suffix = corpse->getContainer()->getAttribute(ItemAttribute_t::LOOTMESSAGE_SUFFIX); - if (!suffix.empty()) { - lootMessage << suffix; + const auto player = mostDamageCreature->getPlayer(); + auto monster = getMonster(); + if (monster && !monster->isRewardBoss()) { + std::ostringstream lootMessage; + lootMessage << "Loot of " << getNameDescription() << ": " << corpse->getContainer()->getContentDescription(player->getProtocolVersion() < 1200); + auto suffix = corpse->getContainer()->getAttribute(ItemAttribute_t::LOOTMESSAGE_SUFFIX); + if (!suffix.empty()) { + lootMessage << suffix; + } + player->sendLootMessage(lootMessage.str()); } - player->sendLootMessage(lootMessage.str()); if (player->checkAutoLoot()) { int32_t pos = tile->getStackposOfItem(player, corpse); @@ -759,7 +764,7 @@ bool Creature::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreatur // Scripting event onDeath for (const auto deathEventPtr : getCreatureEvents(CREATURE_EVENT_DEATH)) { if (deathEventPtr) { - deathEventPtr->executeOnDeath(this, corpse, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified); + deathEventPtr->executeOnDeath(static_self_cast(), corpse, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified); } } } @@ -775,7 +780,7 @@ bool Creature::hasBeenAttacked(uint32_t attackerId) { return (OTSYS_TIME() - it->second.ticks) <= g_configManager().getNumber(PZ_LOCKED); } -Item* Creature::getCorpse(Creature*, Creature*) { +std::shared_ptr Creature::getCorpse(std::shared_ptr, std::shared_ptr) { if (getLookCorpse() != 0) { return Item::CreateItem(getLookCorpse()); } @@ -792,7 +797,7 @@ void Creature::changeHealth(int32_t healthChange, bool sendHealthChange /* = tru } if (sendHealthChange && oldHealth != health) { - g_game().addCreatureHealth(this); + g_game().addCreatureHealth(static_self_cast()); } if (health <= 0) { g_dispatcher().addTask(std::bind(&Game::executeDeath, &g_game(), getID()), "Game::executeDeath"); @@ -807,22 +812,22 @@ void Creature::changeMana(int32_t manaChange) { } } -void Creature::gainHealth(Creature* healer, int32_t healthGain) { +void Creature::gainHealth(std::shared_ptr healer, int32_t healthGain) { changeHealth(healthGain); if (healer) { - healer->onTargetCreatureGainHealth(this, healthGain); + healer->onTargetCreatureGainHealth(static_self_cast(), healthGain); } } -void Creature::drainHealth(Creature* attacker, int32_t damage) { +void Creature::drainHealth(std::shared_ptr attacker, int32_t damage) { changeHealth(-damage, false); if (attacker) { - attacker->onAttackedCreatureDrainHealth(this, damage); + attacker->onAttackedCreatureDrainHealth(static_self_cast(), damage); } } -void Creature::drainMana(Creature* attacker, int32_t manaLoss) { +void Creature::drainMana(std::shared_ptr attacker, int32_t manaLoss) { onAttacked(); changeMana(-manaLoss); @@ -845,7 +850,7 @@ void Creature::mitigateDamage(const CombatType_t &combatType, BlockType_t &block } } -void Creature::applyAbsorbDamageModifications(const Creature* attacker, int32_t &damage, CombatType_t combatType) const { +void Creature::applyAbsorbDamageModifications(std::shared_ptr attacker, int32_t &damage, CombatType_t combatType) const { if (combatType != COMBAT_HEALING && damage != 0) { int32_t value = getAbsorbPercent(combatType); if (value != 0) { @@ -865,7 +870,7 @@ void Creature::applyAbsorbDamageModifications(const Creature* attacker, int32_t } } -BlockType_t Creature::blockHit(Creature* attacker, CombatType_t combatType, int32_t &damage, bool checkDefense /* = false */, bool checkArmor /* = false */, bool /* field = false */) { +BlockType_t Creature::blockHit(std::shared_ptr attacker, CombatType_t combatType, int32_t &damage, bool checkDefense /* = false */, bool checkArmor /* = false */, bool /* field = false */) { BlockType_t blockType = BLOCK_NONE; // Apply skills 12.72 absorbs damage @@ -912,7 +917,7 @@ BlockType_t Creature::blockHit(Creature* attacker, CombatType_t combatType, int3 } if (attacker) { - attacker->onAttackedCreature(this); + attacker->onAttackedCreature(static_self_cast()); attacker->onAttackedCreatureBlockHit(blockType); } @@ -922,33 +927,34 @@ BlockType_t Creature::blockHit(Creature* attacker, CombatType_t combatType, int3 return blockType; } -bool Creature::setAttackedCreature(Creature* creature) { +bool Creature::setAttackedCreature(std::shared_ptr creature) { if (creature) { auto monster = getMonster(); + auto tile = getTile(); if (monster && monster->isFamiliar() && tile && tile->hasFlag(TILESTATE_PROTECTIONZONE)) { return false; } const Position &creaturePos = creature->getPosition(); if (creaturePos.z != getPosition().z || !canSee(creaturePos)) { - attackedCreature = nullptr; + m_attackedCreature.reset(); return false; } - attackedCreature = creature; - onAttackedCreature(attackedCreature); - attackedCreature->onAttacked(); + m_attackedCreature = creature; + onAttackedCreature(creature); + creature->onAttacked(); } else { - attackedCreature = nullptr; + m_attackedCreature.reset(); } - for (Creature* summon : summons) { + for (const auto &summon : m_summons) { summon->setAttackedCreature(creature); } return true; } -void Creature::getPathSearchParams(const Creature*, FindPathParams &fpp) const { +void Creature::getPathSearchParams(std::shared_ptr, FindPathParams &fpp) { fpp.fullPathSearch = !hasFollowPath; fpp.clearSight = true; fpp.maxSearchDist = 12; @@ -957,6 +963,7 @@ void Creature::getPathSearchParams(const Creature*, FindPathParams &fpp) const { } void Creature::goToFollowCreature() { + auto followCreature = getFollowCreature(); if (followCreature) { if (isSummon() && !getMonster()->isFamiliar() && !canFollowMaster()) { hasFollowPath = false; @@ -965,7 +972,7 @@ void Creature::goToFollowCreature() { FindPathParams fpp; getPathSearchParams(followCreature, fpp); - Monster* monster = getMonster(); + std::shared_ptr monster = getMonster(); if (monster && !monster->getMaster() && (monster->isFleeing() || fpp.maxTargetDist > 1)) { Direction dir = DIRECTION_NONE; @@ -1006,25 +1013,29 @@ void Creature::goToFollowCreature() { onFollowCreatureComplete(followCreature); } -bool Creature::canFollowMaster() const { +bool Creature::canFollowMaster() { + auto master = getMaster(); + if (!master) { + return false; + } auto tile = master->getTile(); return tile && !tile->hasFlag(TILESTATE_PROTECTIONZONE) && (canSeeInvisibility() || !master->isInvisible()); } -bool Creature::setFollowCreature(Creature* creature) { +bool Creature::setFollowCreature(std::shared_ptr creature) { if (creature) { - if (followCreature == creature) { + if (getFollowCreature() == creature) { return true; } if (hasCondition(CONDITION_FEARED)) { - followCreature = nullptr; + m_followCreature.reset(); return false; } const Position &creaturePos = creature->getPosition(); if (creaturePos.z != getPosition().z || !canSee(creaturePos)) { - followCreature = nullptr; + m_followCreature.reset(); return false; } @@ -1035,18 +1046,18 @@ bool Creature::setFollowCreature(Creature* creature) { hasFollowPath = false; forceUpdateFollowPath = false; - followCreature = creature; + m_followCreature = creature; isUpdatingPath = true; } else { isUpdatingPath = false; - followCreature = nullptr; + m_followCreature.reset(); } onFollowCreature(creature); return true; } -double Creature::getDamageRatio(Creature* attacker) const { +double Creature::getDamageRatio(std::shared_ptr attacker) const { uint32_t totalDamage = 0; uint32_t attackerDamage = 0; @@ -1065,11 +1076,11 @@ double Creature::getDamageRatio(Creature* attacker) const { return (static_cast(attackerDamage) / totalDamage); } -uint64_t Creature::getGainedExperience(Creature* attacker) const { +uint64_t Creature::getGainedExperience(std::shared_ptr attacker) const { return std::floor(getDamageRatio(attacker) * getLostExperience()); } -void Creature::addDamagePoints(Creature* attacker, int32_t damagePoints) { +void Creature::addDamagePoints(std::shared_ptr attacker, int32_t damagePoints) { if (damagePoints <= 0) { return; } @@ -1107,7 +1118,8 @@ void Creature::onEndCondition(ConditionType_t) { } void Creature::onTickCondition(ConditionType_t type, bool &bRemove) { - const MagicField* field = tile ? tile->getFieldItem() : nullptr; + auto tile = getTile(); + std::shared_ptr field = tile ? tile->getFieldItem() : nullptr; if (!field) { return; } @@ -1142,7 +1154,7 @@ void Creature::onTickCondition(ConditionType_t type, bool &bRemove) { } } -void Creature::onCombatRemoveCondition(Condition* condition) { +void Creature::onCombatRemoveCondition(std::shared_ptr condition) { removeCondition(condition); } @@ -1150,18 +1162,19 @@ void Creature::onAttacked() { // } -void Creature::onAttackedCreatureDrainHealth(Creature* target, int32_t points) { - target->addDamagePoints(this, points); +void Creature::onAttackedCreatureDrainHealth(std::shared_ptr target, int32_t points) { + target->addDamagePoints(static_self_cast(), points); } -void Creature::onAttackedCreatureKilled(Creature* target) { - if (target != this) { - uint64_t gainExp = target->getGainedExperience(this); +void Creature::onAttackedCreatureKilled(std::shared_ptr target) { + if (target != getCreature()) { + uint64_t gainExp = target->getGainedExperience(static_self_cast()); onGainExperience(gainExp, target); } } -bool Creature::onKilledCreature(Creature* target, bool lastHit) { +bool Creature::onKilledCreature(std::shared_ptr target, bool lastHit) { + auto master = getMaster(); if (master) { master->onKilledCreature(target, lastHit); } @@ -1169,17 +1182,18 @@ bool Creature::onKilledCreature(Creature* target, bool lastHit) { // scripting event - onKill const CreatureEventList &killEvents = getCreatureEvents(CREATURE_EVENT_KILL); for (const auto killEventPtr : killEvents) { - killEventPtr->executeOnKill(this, target, lastHit); + killEventPtr->executeOnKill(static_self_cast(), target, lastHit); } return false; } -void Creature::onGainExperience(uint64_t gainExp, Creature* target) { +void Creature::onGainExperience(uint64_t gainExp, std::shared_ptr target) { + auto master = getMaster(); if (gainExp == 0 || !master) { return; } - Monster* m = getMonster(); + std::shared_ptr m = getMonster(); if (!m->isFamiliar()) { gainExp /= 2; } @@ -1198,68 +1212,63 @@ void Creature::onGainExperience(uint64_t gainExp, Creature* target) { message.primary.color = TEXTCOLOR_WHITE_EXP; message.primary.value = gainExp; - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { spectator->getPlayer()->sendTextMessage(message); } } } -bool Creature::setMaster(Creature* newMaster, bool reloadCreature /* = false*/) { +bool Creature::setMaster(std::shared_ptr newMaster, bool reloadCreature /* = false*/) { // Persists if this creature has ever been a summon this->summoned = true; + auto oldMaster = getMaster(); - if (!newMaster && !master) { + if (!newMaster && !oldMaster) { return false; } + const auto &self = getCreature(); // Reloading summon icon/knownCreature and reset informations (follow/dropLoot/skillLoss) if (reloadCreature) { setFollowCreature(nullptr); setDropLoot(false); setSkillLoss(false); - g_game().reloadCreature(this); + g_game().reloadCreature(self); } if (newMaster) { - incrementReferenceCounter(); - newMaster->summons.push_back(this); + newMaster->m_summons.insert(self); } - Creature* oldMaster = master; - master = newMaster; + m_master = newMaster; if (oldMaster) { - auto summon = std::find(oldMaster->summons.begin(), oldMaster->summons.end(), this); - if (summon != oldMaster->summons.end()) { - oldMaster->summons.erase(summon); - decrementReferenceCounter(); - } + oldMaster->m_summons.erase(self); } return true; } -bool Creature::addCondition(Condition* condition) { +bool Creature::addCondition(std::shared_ptr condition) { if (condition == nullptr) { return false; } - Condition* prevCond = getCondition(condition->getType(), condition->getId(), condition->getSubId()); + std::shared_ptr prevCond = getCondition(condition->getType(), condition->getId(), condition->getSubId()); if (prevCond) { - prevCond->addCondition(this, condition); - delete condition; + prevCond->addCondition(getCreature(), condition); + return true; } - if (condition->startCondition(this)) { + if (condition->startCondition(getCreature())) { conditions.push_back(condition); onAddCondition(condition->getType()); return true; } - delete condition; return false; } -bool Creature::addCombatCondition(Condition* condition) { +bool Creature::addCombatCondition(std::shared_ptr condition) { // Caution: condition variable could be deleted after the call to addCondition ConditionType_t type = condition->getType(); @@ -1274,7 +1283,7 @@ bool Creature::addCombatCondition(Condition* condition) { void Creature::removeCondition(ConditionType_t type) { auto it = conditions.begin(), end = conditions.end(); while (it != end) { - Condition* condition = *it; + std::shared_ptr condition = *it; if (condition->getType() != type) { ++it; continue; @@ -1282,8 +1291,7 @@ void Creature::removeCondition(ConditionType_t type) { it = conditions.erase(it); - condition->endCondition(this); - delete condition; + condition->endCondition(getCreature()); onEndCondition(type); } @@ -1292,7 +1300,7 @@ void Creature::removeCondition(ConditionType_t type) { void Creature::removeCondition(ConditionType_t conditionType, ConditionId_t conditionId, bool force /* = false*/) { auto it = conditions.begin(), end = conditions.end(); while (it != end) { - Condition* condition = *it; + std::shared_ptr condition = *it; if (condition->getType() != conditionType || condition->getId() != conditionId) { ++it; continue; @@ -1312,27 +1320,26 @@ void Creature::removeCondition(ConditionType_t conditionType, ConditionId_t cond it = conditions.erase(it); - condition->endCondition(this); - delete condition; + condition->endCondition(getCreature()); onEndCondition(conditionType); } } void Creature::removeCombatCondition(ConditionType_t type) { - std::vector removeConditions; - for (Condition* condition : conditions) { + std::vector> removeConditions; + for (const auto &condition : conditions) { if (condition->getType() == type) { removeConditions.push_back(condition); } } - for (Condition* condition : removeConditions) { + for (const auto &condition : removeConditions) { onCombatRemoveCondition(condition); } } -void Creature::removeCondition(Condition* condition) { +void Creature::removeCondition(std::shared_ptr condition) { auto it = std::find(conditions.begin(), conditions.end(), condition); if (it == conditions.end()) { return; @@ -1340,13 +1347,12 @@ void Creature::removeCondition(Condition* condition) { conditions.erase(it); - condition->endCondition(this); + condition->endCondition(getCreature()); onEndCondition(condition->getType()); - delete condition; } -Condition* Creature::getCondition(ConditionType_t type) const { - for (Condition* condition : conditions) { +std::shared_ptr Creature::getCondition(ConditionType_t type) const { + for (const auto &condition : conditions) { if (condition->getType() == type) { return condition; } @@ -1354,8 +1360,8 @@ Condition* Creature::getCondition(ConditionType_t type) const { return nullptr; } -Condition* Creature::getCondition(ConditionType_t type, ConditionId_t conditionId, uint32_t subId /* = 0*/) const { - for (Condition* condition : conditions) { +std::shared_ptr Creature::getCondition(ConditionType_t type, ConditionId_t conditionId, uint32_t subId /* = 0*/) const { + for (const auto &condition : conditions) { if (condition->getType() == type && condition->getId() == conditionId && condition->getSubId() == subId) { return condition; } @@ -1363,9 +1369,9 @@ Condition* Creature::getCondition(ConditionType_t type, ConditionId_t conditionI return nullptr; } -std::vector Creature::getConditionsByType(ConditionType_t type) const { - std::vector conditionsVec; - for (Condition* condition : conditions) { +std::vector> Creature::getConditionsByType(ConditionType_t type) const { + std::vector> conditionsVec; + for (const auto &condition : conditions) { if (condition->getType() == type) { conditionsVec.push_back(condition); } @@ -1376,14 +1382,13 @@ std::vector Creature::getConditionsByType(ConditionType_t type) cons void Creature::executeConditions(uint32_t interval) { auto it = conditions.begin(), end = conditions.end(); while (it != end) { - Condition* condition = *it; - if (!condition->executeCondition(this, interval)) { + std::shared_ptr condition = *it; + if (!condition->executeCondition(getCreature(), interval)) { ConditionType_t type = condition->getType(); it = conditions.erase(it); - condition->endCondition(this); - delete condition; + condition->endCondition(getCreature()); onEndCondition(type); } else { @@ -1398,7 +1403,7 @@ bool Creature::hasCondition(ConditionType_t type, uint32_t subId /* = 0*/) const } int64_t timeNow = OTSYS_TIME(); - for (Condition* condition : conditions) { + for (const auto &condition : conditions) { if (condition->getType() != type || condition->getSubId() != subId) { continue; } @@ -1410,7 +1415,7 @@ bool Creature::hasCondition(ConditionType_t type, uint32_t subId /* = 0*/) const return false; } -int64_t Creature::getStepDuration(Direction dir) const { +int64_t Creature::getStepDuration(Direction dir) { int64_t stepDuration = getStepDuration(); if ((dir & DIRECTION_DIAGONAL_MASK) != 0) { stepDuration *= 3; @@ -1418,7 +1423,7 @@ int64_t Creature::getStepDuration(Direction dir) const { return stepDuration; } -int64_t Creature::getStepDuration() const { +int64_t Creature::getStepDuration() { if (isRemoved()) { return 0; } @@ -1428,8 +1433,9 @@ int64_t Creature::getStepDuration() const { calculatedStepSpeed = (stepSpeed > -Creature::speedB) ? calculatedStepSpeed : 1; uint32_t groundSpeed = 150; + auto tile = getTile(); if (tile && tile->getGround()) { - Item* ground = tile->getGround(); + std::shared_ptr ground = tile->getGround(); const ItemType &it = Item::items[ground->getID()]; groundSpeed = it.speed > 0 ? it.speed : groundSpeed; } @@ -1437,7 +1443,7 @@ int64_t Creature::getStepDuration() const { double duration = std::floor(1000 * groundSpeed / calculatedStepSpeed); int64_t stepDuration = std::ceil(duration / 50) * 50; - const Monster* monster = getMonster(); + std::shared_ptr monster = getMonster(); if (monster && monster->isTargetNearby() && !monster->isFleeing() && !monster->getMaster()) { stepDuration *= 2; } @@ -1445,7 +1451,7 @@ int64_t Creature::getStepDuration() const { return stepDuration; } -int64_t Creature::getEventStepTicks(bool onlyDelay) const { +int64_t Creature::getEventStepTicks(bool onlyDelay) { int64_t ret = getWalkDelay(); if (ret <= 0) { int64_t stepDuration = getStepDuration(); @@ -1633,17 +1639,17 @@ bool FrozenPathingConditionCall::operator()(const Position &startPos, const Posi } bool Creature::isInvisible() const { - return std::find_if(conditions.begin(), conditions.end(), [](const Condition* condition) { + return std::find_if(conditions.begin(), conditions.end(), [](const std::shared_ptr condition) { return condition->getType() == CONDITION_INVISIBLE; }) != conditions.end(); } -bool Creature::getPathTo(const Position &targetPos, std::forward_list &dirList, const FindPathParams &fpp) const { - return g_game().map.getPathMatching(*this, dirList, FrozenPathingConditionCall(targetPos), fpp); +bool Creature::getPathTo(const Position &targetPos, std::forward_list &dirList, const FindPathParams &fpp) { + return g_game().map.getPathMatching(getCreature(), dirList, FrozenPathingConditionCall(targetPos), fpp); } -bool Creature::getPathTo(const Position &targetPos, std::forward_list &dirList, int32_t minTargetDist, int32_t maxTargetDist, bool fullPathSearch /*= true*/, bool clearSight /*= true*/, int32_t maxSearchDist /*= 7*/) const { +bool Creature::getPathTo(const Position &targetPos, std::forward_list &dirList, int32_t minTargetDist, int32_t maxTargetDist, bool fullPathSearch /*= true*/, bool clearSight /*= true*/, int32_t maxSearchDist /*= 7*/) { FindPathParams fpp; fpp.fullPathSearch = fullPathSearch; fpp.maxSearchDist = maxSearchDist; @@ -1653,7 +1659,7 @@ bool Creature::getPathTo(const Position &targetPos, std::forward_list return getPathTo(targetPos, dirList, fpp); } -void Creature::turnToCreature(Creature* creature) { +void Creature::turnToCreature(std::shared_ptr creature) { const Position &creaturePos = creature->getPosition(); const auto dx = Position::getOffsetX(position, creaturePos); const auto dy = Position::getOffsetY(position, creaturePos); @@ -1679,10 +1685,10 @@ void Creature::turnToCreature(Creature* creature) { dir = DIRECTION_SOUTH; } } - g_game().internalCreatureTurn(this, dir); + g_game().internalCreatureTurn(static_self_cast(), dir); } -bool Creature::isLostSummon() const { +bool Creature::isLostSummon() { if (!isSummon()) { return false; } @@ -1692,9 +1698,9 @@ bool Creature::isLostSummon() const { void Creature::handleLostSummon(bool teleportSummons) { if (teleportSummons) { - g_game().internalTeleport(this, getMaster()->getPosition(), true); + g_game().internalTeleport(static_self_cast(), getMaster()->getPosition(), true); } else { - g_game().removeCreature(this, true); + g_game().removeCreature(static_self_cast(), true); } g_game().addMagicEffect(getPosition(), CONST_ME_POFF); } @@ -1788,21 +1794,22 @@ const phmap::parallel_flat_hash_set> Creature::getZones() return Zone::getZones(getPosition()); } -void Creature::iconChanged() const { +void Creature::iconChanged() { + auto tile = getTile(); if (!tile) { return; } SpectatorHashSet spectators; g_game().map.getSpectators(spectators, tile->getPosition(), true); - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { if (!spectator) { continue; } - Player* player = spectator->getPlayer(); + auto player = spectator->getPlayer(); if (player) { - player->sendCreatureIcon(this); + player->sendCreatureIcon(getCreature()); } } } diff --git a/src/creatures/creature.hpp b/src/creatures/creature.hpp index 3349ddb83..b6a8df61a 100644 --- a/src/creatures/creature.hpp +++ b/src/creatures/creature.hpp @@ -17,7 +17,7 @@ #include "game/movement/position.hpp" #include "items/tile.hpp" -using ConditionList = std::list; +using ConditionList = std::list>; using CreatureEventList = std::list>; class Map; @@ -51,7 +51,7 @@ class FrozenPathingConditionCall { // Defines the Base class for all creatures and base functions which // every creature has -class Creature : virtual public Thing { +class Creature : virtual public Thing, public SharedObject { protected: Creature(); @@ -64,28 +64,16 @@ class Creature : virtual public Thing { Creature(const Creature &) = delete; Creature &operator=(const Creature &) = delete; - Creature* getCreature() override final { - return this; + std::shared_ptr getCreature() override final { + return static_self_cast(); } - const Creature* getCreature() const override final { - return this; - } - virtual Player* getPlayer() { - return nullptr; - } - virtual const Player* getPlayer() const { - return nullptr; - } - virtual Npc* getNpc() { - return nullptr; - } - virtual const Npc* getNpc() const { + virtual std::shared_ptr getPlayer() { return nullptr; } - virtual Monster* getMonster() { + virtual std::shared_ptr getNpc() { return nullptr; } - virtual const Monster* getMonster() const { + virtual std::shared_ptr getMonster() { return nullptr; } @@ -107,8 +95,8 @@ class Creature : virtual public Thing { virtual void removeList() = 0; virtual void addList() = 0; - virtual bool canSee(const Position &pos) const; - virtual bool canSeeCreature(const Creature* creature) const; + virtual bool canSee(const Position &pos); + virtual bool canSeeCreature(std::shared_ptr creature) const; virtual RaceType_t getRace() const { return RACE_NONE; @@ -116,7 +104,7 @@ class Creature : virtual public Thing { virtual Skulls_t getSkull() const { return skull; } - virtual Skulls_t getSkullClient(const Creature* creature) const { + virtual Skulls_t getSkullClient(std::shared_ptr creature) { return creature->getSkull(); } void setSkull(Skulls_t newSkull); @@ -144,10 +132,10 @@ class Creature : virtual public Thing { int32_t getThrowRange() const override final { return 1; } - bool isPushable() const override { + bool isPushable() override { return getWalkDelay() <= 0; } - bool isRemoved() const override final { + bool isRemoved() override final { return isInternalRemoved; } virtual bool canSeeInvisibility() const { @@ -159,13 +147,13 @@ class Creature : virtual public Thing { int32_t getWalkSize(); - int32_t getWalkDelay(Direction dir) const; - int32_t getWalkDelay() const; + int32_t getWalkDelay(Direction dir); + int32_t getWalkDelay(); int64_t getTimeSinceLastMove() const; - int64_t getEventStepTicks(bool onlyDelay = false) const; - int64_t getStepDuration(Direction dir) const; - int64_t getStepDuration() const; + int64_t getEventStepTicks(bool onlyDelay = false); + int64_t getStepDuration(Direction dir); + int64_t getStepDuration(); virtual uint16_t getStepSpeed() const { return getSpeed(); } @@ -255,7 +243,7 @@ class Creature : virtual public Thing { iconChanged(); } - void iconChanged() const; + void iconChanged(); const Outfit_t getCurrentOutfit() const { return currentOutfit; @@ -267,9 +255,9 @@ class Creature : virtual public Thing { return defaultOutfit; } bool isInvisible() const; - ZoneType_t getZoneType() const { + ZoneType_t getZoneType() { if (getTile()) { - return tile->getZoneType(); + return getTile()->getZoneType(); } return ZONE_NORMAL; @@ -289,20 +277,20 @@ class Creature : virtual public Thing { virtual void onWalkComplete() { } // follow functions - Creature* getFollowCreature() const { - return followCreature; + std::shared_ptr getFollowCreature() const { + return m_followCreature.lock(); } - virtual bool setFollowCreature(Creature* creature); + virtual bool setFollowCreature(std::shared_ptr creature); // follow events - virtual void onFollowCreature(const Creature*) { } - virtual void onFollowCreatureComplete(const Creature*) { } + virtual void onFollowCreature(std::shared_ptr) { } + virtual void onFollowCreatureComplete(std::shared_ptr) { } // combat functions - Creature* getAttackedCreature() { - return attackedCreature; + std::shared_ptr getAttackedCreature() { + return m_attackedCreature.lock(); } - virtual bool setAttackedCreature(Creature* creature); + virtual bool setAttackedCreature(std::shared_ptr creature); /** * @brief Mitigates damage inflicted on a creature. @@ -317,21 +305,20 @@ class Creature : virtual public Thing { * @param damage Reference to the amount of damage inflicted, which will be reduced by the creature's mitigation factor. */ void mitigateDamage(const CombatType_t &combatType, BlockType_t &blockType, int32_t &damage) const; - virtual BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t &damage, bool checkDefense = false, bool checkArmor = false, bool field = false); + virtual BlockType_t blockHit(std::shared_ptr attacker, CombatType_t combatType, int32_t &damage, bool checkDefense = false, bool checkArmor = false, bool field = false); - void applyAbsorbDamageModifications(const Creature* attacker, int32_t &damage, CombatType_t combatType) const; + void applyAbsorbDamageModifications(std::shared_ptr attacker, int32_t &damage, CombatType_t combatType) const; - bool setMaster(Creature* newMaster, bool reloadCreature = false); + bool setMaster(std::shared_ptr newMaster, bool reloadCreature = false); void removeMaster() { - if (master) { - master = nullptr; - decrementReferenceCounter(); + if (getMaster()) { + m_master.reset(); } } bool isSummon() const { - return master != nullptr; + return !m_master.expired(); } /** @@ -340,12 +327,12 @@ class Creature : virtual public Thing { bool hasBeenSummoned() const { return summoned; } - Creature* getMaster() const { - return master; + std::shared_ptr getMaster() const { + return m_master.lock(); } - const std::list &getSummons() const { - return summons; + const phmap::flat_hash_set> &getSummons() const { + return m_summons; } virtual int32_t getArmor() const { @@ -368,15 +355,15 @@ class Creature : virtual public Thing { return SPEECHBUBBLE_NONE; } - bool addCondition(Condition* condition); - bool addCombatCondition(Condition* condition); + bool addCondition(std::shared_ptr condition); + bool addCombatCondition(std::shared_ptr condition); void removeCondition(ConditionType_t conditionType, ConditionId_t conditionId, bool force = false); void removeCondition(ConditionType_t type); - void removeCondition(Condition* condition); + void removeCondition(std::shared_ptr condition); void removeCombatCondition(ConditionType_t type); - Condition* getCondition(ConditionType_t type) const; - Condition* getCondition(ConditionType_t type, ConditionId_t conditionId, uint32_t subId = 0) const; - std::vector getConditionsByType(ConditionType_t type) const; + std::shared_ptr getCondition(ConditionType_t type) const; + std::shared_ptr getCondition(ConditionType_t type, ConditionId_t conditionId, uint32_t subId = 0) const; + std::vector> getConditionsByType(ConditionType_t type) const; void executeConditions(uint32_t interval); bool hasCondition(ConditionType_t type, uint32_t subId = 0) const; @@ -400,17 +387,17 @@ class Creature : virtual public Thing { virtual void changeHealth(int32_t healthChange, bool sendHealthChange = true); virtual void changeMana(int32_t manaChange); - void gainHealth(Creature* attacker, int32_t healthGain); - virtual void drainHealth(Creature* attacker, int32_t damage); - virtual void drainMana(Creature* attacker, int32_t manaLoss); + void gainHealth(std::shared_ptr attacker, int32_t healthGain); + virtual void drainHealth(std::shared_ptr attacker, int32_t damage); + virtual void drainMana(std::shared_ptr attacker, int32_t manaLoss); - virtual bool challengeCreature(Creature*, int targetChangeCooldown) { + virtual bool challengeCreature(std::shared_ptr, int targetChangeCooldown) { return false; } void onDeath(); - virtual uint64_t getGainedExperience(Creature* attacker) const; - void addDamagePoints(Creature* attacker, int32_t damagePoints); + virtual uint64_t getGainedExperience(std::shared_ptr attacker) const; + void addDamagePoints(std::shared_ptr attacker, int32_t damagePoints); bool hasBeenAttacked(uint32_t attackerId); // combat event functions @@ -418,14 +405,14 @@ class Creature : virtual public Thing { virtual void onAddCombatCondition(ConditionType_t type); virtual void onEndCondition(ConditionType_t type); void onTickCondition(ConditionType_t type, bool &bRemove); - virtual void onCombatRemoveCondition(Condition* condition); - virtual void onAttackedCreature(Creature*) { } + virtual void onCombatRemoveCondition(std::shared_ptr condition); + virtual void onAttackedCreature(std::shared_ptr) { } virtual void onAttacked(); - virtual void onAttackedCreatureDrainHealth(Creature* target, int32_t points); - virtual void onTargetCreatureGainHealth(Creature*, int32_t) { } - void onAttackedCreatureKilled(Creature* target); - virtual bool onKilledCreature(Creature* target, bool lastHit = true); - virtual void onGainExperience(uint64_t gainExp, Creature* target); + virtual void onAttackedCreatureDrainHealth(std::shared_ptr target, int32_t points); + virtual void onTargetCreatureGainHealth(std::shared_ptr, int32_t) { } + void onAttackedCreatureKilled(std::shared_ptr target); + virtual bool onKilledCreature(std::shared_ptr target, bool lastHit = true); + virtual void onGainExperience(uint64_t gainExp, std::shared_ptr target); virtual void onAttackedCreatureBlockHit(BlockType_t) { } virtual void onBlockHit() { } virtual void onChangeZone(ZoneType_t zone); @@ -441,14 +428,14 @@ class Creature : virtual public Thing { virtual void onCreatureWalk(); virtual bool getNextStep(Direction &dir, uint32_t &flags); - virtual void turnToCreature(Creature* creature); + virtual void turnToCreature(std::shared_ptr creature); - void onAddTileItem(const Tile* tile, const Position &pos); - virtual void onUpdateTileItem(const Tile* tile, const Position &pos, const Item* oldItem, const ItemType &oldType, const Item* newItem, const ItemType &newType); - virtual void onRemoveTileItem(const Tile* tile, const Position &pos, const ItemType &iType, const Item* item); + void onAddTileItem(std::shared_ptr tile, const Position &pos); + virtual void onUpdateTileItem(std::shared_ptr tile, const Position &pos, std::shared_ptr oldItem, const ItemType &oldType, std::shared_ptr newItem, const ItemType &newType); + virtual void onRemoveTileItem(std::shared_ptr tile, const Position &pos, const ItemType &iType, std::shared_ptr item); - virtual void onCreatureAppear(Creature* creature, bool isLogin); - virtual void onRemoveCreature(Creature* creature, bool isLogout); + virtual void onCreatureAppear(std::shared_ptr creature, bool isLogin); + virtual void onRemoveCreature(std::shared_ptr creature, bool isLogout); /** * @brief Check if the summon can move/spawn and if the familiar can teleport to the master @@ -458,13 +445,13 @@ class Creature : virtual public Thing { * @return true * @return false */ - void checkSummonMove(const Position &newPos, bool teleportSummon = false) const; - virtual void onCreatureMove(Creature* creature, const Tile* newTile, const Position &newPos, const Tile* oldTile, const Position &oldPos, bool teleport); + void checkSummonMove(const Position &newPos, bool teleportSummon = false); + virtual void onCreatureMove(std::shared_ptr creature, std::shared_ptr newTile, const Position &newPos, std::shared_ptr oldTile, const Position &oldPos, bool teleport); virtual void onAttackedCreatureDisappear(bool) { } virtual void onFollowCreatureDisappear(bool) { } - virtual void onCreatureSay(Creature*, SpeakClasses, const std::string &) { } + virtual void onCreatureSay(std::shared_ptr, SpeakClasses, const std::string &) { } virtual void onPlacedCreature() { } @@ -473,7 +460,7 @@ class Creature : virtual public Thing { } size_t getSummonCount() const { - return summons.size(); + return m_summons.size(); } /** @@ -483,7 +470,7 @@ class Creature : virtual public Thing { * @return false = empty */ bool hasSummons() const { - if (!summons.empty()) { + if (!m_summons.empty()) { return true; } return false; @@ -503,26 +490,27 @@ class Creature : virtual public Thing { bool registerCreatureEvent(const std::string &name); bool unregisterCreatureEvent(const std::string &name); - Cylinder* getParent() const override final { - return tile; + std::shared_ptr getParent() override final { + return getTile(); } - void setParent(Cylinder* cylinder) override final { - tile = static_cast(cylinder); - position = tile->getPosition(); + void setParent(std::weak_ptr cylinder) override final { + auto lockedCylinder = cylinder.lock(); + if (lockedCylinder) { + auto newParent = lockedCylinder->getTile(); + position = newParent->getPosition(); + m_tile = newParent; + } } - const Position &getPosition() const override final { + const Position &getPosition() override final { return position; } - Tile* getTile() override final { - return tile; - } - const Tile* getTile() const override final { - return tile; + std::shared_ptr getTile() override final { + return m_tile.lock(); } - int32_t getWalkCache(const Position &pos) const; + int32_t getWalkCache(const Position &pos); const Position &getLastPosition() const { return lastPosition; @@ -533,19 +521,11 @@ class Creature : virtual public Thing { static bool canSee(const Position &myPos, const Position &pos, int32_t viewRangeX, int32_t viewRangeY); - double getDamageRatio(Creature* attacker) const; + double getDamageRatio(std::shared_ptr attacker) const; - bool getPathTo(const Position &targetPos, std::forward_list &dirList, const FindPathParams &fpp) const; - bool getPathTo(const Position &targetPos, std::forward_list &dirList, int32_t minTargetDist, int32_t maxTargetDist, bool fullPathSearch = true, bool clearSight = true, int32_t maxSearchDist = 7) const; + bool getPathTo(const Position &targetPos, std::forward_list &dirList, const FindPathParams &fpp); + bool getPathTo(const Position &targetPos, std::forward_list &dirList, int32_t minTargetDist, int32_t maxTargetDist, bool fullPathSearch = true, bool clearSight = true, int32_t maxSearchDist = 7); - void incrementReferenceCounter() { - ++referenceCounter; - } - void decrementReferenceCounter() { - if (--referenceCounter == 0) { - delete this; - } - } struct CountBlock_t { int32_t total; int64_t ticks; @@ -675,16 +655,16 @@ class Creature : virtual public Thing { CountMap damageMap; - std::list summons; + phmap::flat_hash_set> m_summons; CreatureEventList eventsList; ConditionList conditions; std::forward_list listWalkDir; - Tile* tile = nullptr; - Creature* attackedCreature = nullptr; - Creature* master = nullptr; - Creature* followCreature = nullptr; + std::weak_ptr m_tile; + std::weak_ptr m_attackedCreature; + std::weak_ptr m_master; + std::weak_ptr m_followCreature; /** * We need to persist if this creature is summon or not because when we @@ -697,7 +677,6 @@ class Creature : virtual public Thing { bool summoned = false; uint64_t lastStep = 0; - uint32_t referenceCounter = 0; uint32_t id = 0; uint32_t scriptEventsBitField = 0; uint32_t eventWalk = 0; @@ -761,9 +740,9 @@ class Creature : virtual public Thing { CreatureEventList getCreatureEvents(CreatureEventType_t type); void updateMapCache(); - void updateTileCache(const Tile* tile, int32_t dx, int32_t dy); - void updateTileCache(const Tile* tile, const Position &pos); - void onCreatureDisappear(const Creature* creature, bool isLogout); + void updateTileCache(std::shared_ptr tile, int32_t dx, int32_t dy); + void updateTileCache(std::shared_ptr tile, const Position &pos); + void onCreatureDisappear(std::shared_ptr creature, bool isLogout); virtual void doAttacking(uint32_t) { } virtual bool hasExtraSwing() { return false; @@ -772,21 +751,21 @@ class Creature : virtual public Thing { virtual uint64_t getLostExperience() const { return 0; } - virtual void dropLoot(Container*, Creature*) { } + virtual void dropLoot(std::shared_ptr, std::shared_ptr) { } virtual uint16_t getLookCorpse() const { return 0; } - virtual void getPathSearchParams(const Creature* creature, FindPathParams &fpp) const; - virtual void death(Creature*) { } - virtual bool dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified); - virtual Item* getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature); + virtual void getPathSearchParams(std::shared_ptr creature, FindPathParams &fpp); + virtual void death(std::shared_ptr) { } + virtual bool dropCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified); + virtual std::shared_ptr getCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature); friend class Game; friend class Map; friend class CreatureFunctions; private: - bool canFollowMaster() const; - bool isLostSummon() const; + bool canFollowMaster(); + bool isLostSummon(); void handleLostSummon(bool teleportSummons); }; diff --git a/src/creatures/interactions/chat.cpp b/src/creatures/interactions/chat.cpp index 1e6dab2d7..d58da4607 100644 --- a/src/creatures/interactions/chat.cpp +++ b/src/creatures/interactions/chat.cpp @@ -25,40 +25,40 @@ bool PrivateChatChannel::removeInvite(uint32_t guid) { return invites.erase(guid) != 0; } -void PrivateChatChannel::invitePlayer(const Player &player, Player &invitePlayer) { - auto result = invites.emplace(invitePlayer.getGUID(), &invitePlayer); +void PrivateChatChannel::invitePlayer(const std::shared_ptr &player, const std::shared_ptr &invitePlayer) { + auto result = invites.emplace(invitePlayer->getGUID(), invitePlayer); if (!result.second) { return; } std::ostringstream ss; - ss << player.getName() << " invites you to " << player.getPossessivePronoun() << " private chat channel."; - invitePlayer.sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); + ss << player->getName() << " invites you to " << player->getPossessivePronoun() << " private chat channel."; + invitePlayer->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); ss.str(std::string()); - ss << invitePlayer.getName() << " has been invited."; - player.sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); + ss << invitePlayer->getName() << " has been invited."; + player->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); for (const auto &it : users) { - it.second->sendChannelEvent(id, invitePlayer.getName(), CHANNELEVENT_INVITE); + it.second->sendChannelEvent(id, invitePlayer->getName(), CHANNELEVENT_INVITE); } } -void PrivateChatChannel::excludePlayer(const Player &player, Player &excludePlayer) { - if (!removeInvite(excludePlayer.getGUID())) { +void PrivateChatChannel::excludePlayer(const std::shared_ptr &player, const std::shared_ptr &excludePlayer) { + if (!removeInvite(excludePlayer->getGUID())) { return; } removeUser(excludePlayer); std::ostringstream ss; - ss << excludePlayer.getName() << " has been excluded."; - player.sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); + ss << excludePlayer->getName() << " has been excluded."; + player->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); - excludePlayer.sendClosePrivate(id); + excludePlayer->sendClosePrivate(id); for (const auto &it : users) { - it.second->sendChannelEvent(id, excludePlayer.getName(), CHANNELEVENT_EXCLUDE); + it.second->sendChannelEvent(id, excludePlayer->getName(), CHANNELEVENT_EXCLUDE); } } @@ -68,8 +68,8 @@ void PrivateChatChannel::closeChannel() const { } } -bool ChatChannel::addUser(Player &player) { - if (users.find(player.getID()) != users.end()) { +bool ChatChannel::addUser(const std::shared_ptr &player) { + if (users.find(player->getID()) != users.end()) { return false; } @@ -79,24 +79,24 @@ bool ChatChannel::addUser(Player &player) { // TODO: Move to script when guild channels can be scripted if (id == CHANNEL_GUILD) { - const auto guild = player.getGuild(); + const auto guild = player->getGuild(); if (guild && !guild->getMotd().empty()) { - g_scheduler().addEvent(150, std::bind(&Game::sendGuildMotd, &g_game(), player.getID()), "Game::sendGuildMotd"); + g_scheduler().addEvent(150, std::bind(&Game::sendGuildMotd, &g_game(), player->getID()), "Game::sendGuildMotd"); } } if (!publicChannel) { for (const auto &it : users) { - it.second->sendChannelEvent(id, player.getName(), CHANNELEVENT_JOIN); + it.second->sendChannelEvent(id, player->getName(), CHANNELEVENT_JOIN); } } - users[player.getID()] = &player; + users[player->getID()] = player; return true; } -bool ChatChannel::removeUser(const Player &player) { - auto iter = users.find(player.getID()); +bool ChatChannel::removeUser(const std::shared_ptr &player) { + auto iter = users.find(player->getID()); if (iter == users.end()) { return false; } @@ -105,7 +105,7 @@ bool ChatChannel::removeUser(const Player &player) { if (!publicChannel) { for (const auto &it : users) { - it.second->sendChannelEvent(id, player.getName(), CHANNELEVENT_LEAVE); + it.second->sendChannelEvent(id, player->getName(), CHANNELEVENT_LEAVE); } } @@ -113,8 +113,8 @@ bool ChatChannel::removeUser(const Player &player) { return true; } -bool ChatChannel::hasUser(const Player &player) { - return users.find(player.getID()) != users.end(); +bool ChatChannel::hasUser(const std::shared_ptr &player) { + return users.find(player->getID()) != users.end(); } void ChatChannel::sendToAll(const std::string &message, SpeakClasses type) const { @@ -123,18 +123,18 @@ void ChatChannel::sendToAll(const std::string &message, SpeakClasses type) const } } -bool ChatChannel::talk(const Player &fromPlayer, SpeakClasses type, const std::string &text) { - if (users.find(fromPlayer.getID()) == users.end()) { +bool ChatChannel::talk(const std::shared_ptr &fromPlayer, SpeakClasses type, const std::string &text) { + if (users.find(fromPlayer->getID()) == users.end()) { return false; } for (const auto &it : users) { - it.second->sendToChannel(&fromPlayer, type, text, id); + it.second->sendToChannel(fromPlayer, type, text, id); } return true; } -bool ChatChannel::executeCanJoinEvent(const Player &player) { +bool ChatChannel::executeCanJoinEvent(const std::shared_ptr &player) { if (canJoinEvent == -1) { return true; } @@ -144,7 +144,7 @@ bool ChatChannel::executeCanJoinEvent(const Player &player) { if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[CanJoinChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested.", - player.getName(), getName()); + player->getName(), getName()); return false; } @@ -154,13 +154,13 @@ bool ChatChannel::executeCanJoinEvent(const Player &player) { lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(canJoinEvent); - LuaScriptInterface::pushUserdata(L, &player); + LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); return scriptInterface->callFunction(1); } -bool ChatChannel::executeOnJoinEvent(const Player &player) { +bool ChatChannel::executeOnJoinEvent(const std::shared_ptr &player) { if (onJoinEvent == -1) { return true; } @@ -170,7 +170,7 @@ bool ChatChannel::executeOnJoinEvent(const Player &player) { if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[OnJoinChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested", - player.getName(), getName()); + player->getName(), getName()); return false; } @@ -180,13 +180,13 @@ bool ChatChannel::executeOnJoinEvent(const Player &player) { lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(onJoinEvent); - LuaScriptInterface::pushUserdata(L, &player); + LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); return scriptInterface->callFunction(1); } -bool ChatChannel::executeOnLeaveEvent(const Player &player) { +bool ChatChannel::executeOnLeaveEvent(const std::shared_ptr &player) { if (onLeaveEvent == -1) { return true; } @@ -196,7 +196,7 @@ bool ChatChannel::executeOnLeaveEvent(const Player &player) { if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[OnLeaveChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested.", - player.getName(), getName()); + player->getName(), getName()); return false; } @@ -206,13 +206,13 @@ bool ChatChannel::executeOnLeaveEvent(const Player &player) { lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(onLeaveEvent); - LuaScriptInterface::pushUserdata(L, &player); + LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); return scriptInterface->callFunction(1); } -bool ChatChannel::executeOnSpeakEvent(const Player &player, SpeakClasses &type, const std::string &message) { +bool ChatChannel::executeOnSpeakEvent(const std::shared_ptr &player, SpeakClasses &type, const std::string &message) { if (onSpeakEvent == -1) { return true; } @@ -222,7 +222,7 @@ bool ChatChannel::executeOnSpeakEvent(const Player &player, SpeakClasses &type, if (!scriptInterface->reserveScriptEnv()) { g_logger().error("[OnSpeakChannelEvent::execute - Player {}, type {}] " "Call stack overflow. Too many lua script calls being nested.", - player.getName(), fmt::underlying(type)); + player->getName(), fmt::underlying(type)); return false; } @@ -232,7 +232,7 @@ bool ChatChannel::executeOnSpeakEvent(const Player &player, SpeakClasses &type, lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(onSpeakEvent); - LuaScriptInterface::pushUserdata(L, &player); + LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); lua_pushnumber(L, type); @@ -301,7 +301,7 @@ bool Chat::load() { UsersMap tempUserMap = std::move(channel.users); for (const auto &pair : tempUserMap) { - channel.addUser(*pair.second); + channel.addUser(pair.second); } continue; } @@ -325,14 +325,14 @@ bool Chat::load() { return true; } -ChatChannel* Chat::createChannel(const Player &player, uint16_t channelId) { +ChatChannel* Chat::createChannel(const std::shared_ptr &player, uint16_t channelId) { if (getChannel(player, channelId) != nullptr) { return nullptr; } switch (channelId) { case CHANNEL_GUILD: { - const auto guild = player.getGuild(); + const auto guild = player->getGuild(); if (guild != nullptr) { auto ret = guildChannels.emplace(std::make_pair(guild->getId(), ChatChannel(channelId, guild->getName()))); return &ret.first->second; @@ -341,7 +341,7 @@ ChatChannel* Chat::createChannel(const Player &player, uint16_t channelId) { } case CHANNEL_PARTY: { - Party* party = player.getParty(); + auto party = player->getParty(); if (party != nullptr) { auto ret = partyChannels.emplace(std::make_pair(party, ChatChannel(channelId, "Party"))); return &ret.first->second; @@ -351,16 +351,16 @@ ChatChannel* Chat::createChannel(const Player &player, uint16_t channelId) { case CHANNEL_PRIVATE: { // only 1 private channel for each premium player - if (!player.isPremium() || (getPrivateChannel(player) != nullptr)) { + if (!player->isPremium() || (getPrivateChannel(player) != nullptr)) { return nullptr; } // find a free private channel slot for (uint16_t i = 100; i < 10000; ++i) { - auto ret = privateChannels.emplace(std::make_pair(i, PrivateChatChannel(i, player.getName() + "'s Channel"))); + auto ret = privateChannels.emplace(std::make_pair(i, PrivateChatChannel(i, player->getName() + "'s Channel"))); if (ret.second) { // second is a bool that indicates that a new channel has been placed in the map auto &newChannel = (*ret.first).second; - newChannel.setOwner(player.getGUID()); + newChannel.setOwner(player->getGUID()); return &newChannel; } } @@ -373,10 +373,10 @@ ChatChannel* Chat::createChannel(const Player &player, uint16_t channelId) { return nullptr; } -bool Chat::deleteChannel(const Player &player, uint16_t channelId) { +bool Chat::deleteChannel(const std::shared_ptr &player, uint16_t channelId) { switch (channelId) { case CHANNEL_GUILD: { - const auto guild = player.getGuild(); + const auto guild = player->getGuild(); if (guild == nullptr) { return false; } @@ -391,7 +391,7 @@ bool Chat::deleteChannel(const Player &player, uint16_t channelId) { } case CHANNEL_PARTY: { - Party* party = player.getParty(); + auto party = player->getParty(); if (party == nullptr) { return false; } @@ -420,7 +420,7 @@ bool Chat::deleteChannel(const Player &player, uint16_t channelId) { return true; } -ChatChannel* Chat::addUserToChannel(Player &player, uint16_t channelId) { +ChatChannel* Chat::addUserToChannel(const std::shared_ptr &player, uint16_t channelId) { ChatChannel* channel = getChannel(player, channelId); if ((channel != nullptr) && channel->addUser(player)) { return channel; @@ -428,19 +428,19 @@ ChatChannel* Chat::addUserToChannel(Player &player, uint16_t channelId) { return nullptr; } -bool Chat::removeUserFromChannel(const Player &player, uint16_t channelId) { +bool Chat::removeUserFromChannel(const std::shared_ptr &player, uint16_t channelId) { ChatChannel* channel = getChannel(player, channelId); if ((channel == nullptr) || !channel->removeUser(player)) { return false; } - if (channel->getOwner() == player.getGUID()) { + if (channel->getOwner() == player->getGUID()) { deleteChannel(player, channelId); } return true; } -void Chat::removeUserFromAllChannels(const Player &player) { +void Chat::removeUserFromAllChannels(const std::shared_ptr &player) { for (auto &it : normalChannels) { it.second.removeUser(player); } @@ -456,9 +456,9 @@ void Chat::removeUserFromAllChannels(const Player &player) { auto it = privateChannels.begin(); while (it != privateChannels.end()) { PrivateChatChannel* channel = &it->second; - channel->removeInvite(player.getGUID()); + channel->removeInvite(player->getGUID()); channel->removeUser(player); - if (channel->getOwner() == player.getGUID()) { + if (channel->getOwner() == player->getGUID()) { channel->closeChannel(); it = privateChannels.erase(it); } else { @@ -467,14 +467,14 @@ void Chat::removeUserFromAllChannels(const Player &player) { } } -bool Chat::talkToChannel(const Player &player, SpeakClasses type, const std::string &text, uint16_t channelId) { +bool Chat::talkToChannel(const std::shared_ptr &player, SpeakClasses type, const std::string &text, uint16_t channelId) { ChatChannel* channel = getChannel(player, channelId); if (channel == nullptr) { return false; } if (channelId == CHANNEL_GUILD) { - GuildRank_ptr rank = player.getGuildRank(); + GuildRank_ptr rank = player->getGuildRank(); if (rank && rank->level > 1) { type = TALKTYPE_CHANNEL_O; } else if (type != TALKTYPE_CHANNEL_Y) { @@ -491,9 +491,9 @@ bool Chat::talkToChannel(const Player &player, SpeakClasses type, const std::str return channel->talk(player, type, text); } -ChannelList Chat::getChannelList(const Player &player) { +ChannelList Chat::getChannelList(const std::shared_ptr &player) { ChannelList list; - if (player.getGuild()) { + if (player->getGuild()) { ChatChannel* channel = getChannel(player, CHANNEL_GUILD); if (channel) { list.push_back(channel); @@ -505,7 +505,7 @@ ChannelList Chat::getChannelList(const Player &player) { } } - if (player.getParty()) { + if (player->getParty()) { ChatChannel* channel = getChannel(player, CHANNEL_PARTY); if (channel) { list.push_back(channel); @@ -527,7 +527,7 @@ ChannelList Chat::getChannelList(const Player &player) { bool hasPrivate = false; for (auto &it : privateChannels) { if (PrivateChatChannel* channel = &it.second) { - uint32_t guid = player.getGUID(); + uint32_t guid = player->getGUID(); if (channel->isInvited(guid)) { list.push_back(channel); } @@ -538,16 +538,16 @@ ChannelList Chat::getChannelList(const Player &player) { } } - if (!hasPrivate && player.isPremium()) { + if (!hasPrivate && player->isPremium()) { list.push_front(&dummyPrivate); } return list; } -ChatChannel* Chat::getChannel(const Player &player, uint16_t channelId) { +ChatChannel* Chat::getChannel(const std::shared_ptr &player, uint16_t channelId) { switch (channelId) { case CHANNEL_GUILD: { - const auto guild = player.getGuild(); + const auto guild = player->getGuild(); if (guild != nullptr) { auto it = guildChannels.find(guild->getId()); if (it != guildChannels.end()) { @@ -558,7 +558,7 @@ ChatChannel* Chat::getChannel(const Player &player, uint16_t channelId) { } case CHANNEL_PARTY: { - Party* party = player.getParty(); + auto party = player->getParty(); if (party != nullptr) { auto it = partyChannels.find(party); if (it != partyChannels.end()) { @@ -579,7 +579,7 @@ ChatChannel* Chat::getChannel(const Player &player, uint16_t channelId) { } auto it2 = privateChannels.find(channelId); - if (it2 != privateChannels.end() && it2->second.isInvited(player.getGUID())) { + if (it2 != privateChannels.end() && it2->second.isInvited(player->getGUID())) { return &it2->second; } break; @@ -604,9 +604,9 @@ ChatChannel* Chat::getChannelById(uint16_t channelId) { return &it->second; } -PrivateChatChannel* Chat::getPrivateChannel(const Player &player) { +PrivateChatChannel* Chat::getPrivateChannel(const std::shared_ptr &player) { for (auto &it : privateChannels) { - if (it.second.getOwner() == player.getGUID()) { + if (it.second.getOwner() == player->getGUID()) { return &it.second; } } diff --git a/src/creatures/interactions/chat.hpp b/src/creatures/interactions/chat.hpp index dad87d879..31d2a612e 100644 --- a/src/creatures/interactions/chat.hpp +++ b/src/creatures/interactions/chat.hpp @@ -16,8 +16,8 @@ class Party; class Player; -using UsersMap = std::map; -using InvitedMap = std::map; +using UsersMap = std::map>; +using InvitedMap = std::map>; class ChatChannel { public: @@ -28,11 +28,11 @@ class ChatChannel { virtual ~ChatChannel() = default; - bool addUser(Player &player); - bool removeUser(const Player &player); - bool hasUser(const Player &player); + bool addUser(const std::shared_ptr &player); + bool removeUser(const std::shared_ptr &player); + bool hasUser(const std::shared_ptr &player); - bool talk(const Player &fromPlayer, SpeakClasses type, const std::string &text); + bool talk(const std::shared_ptr &fromPlayer, SpeakClasses type, const std::string &text); void sendToAll(const std::string &message, SpeakClasses type) const; const std::string &getName() const { @@ -56,10 +56,10 @@ class ChatChannel { return publicChannel; } - bool executeOnJoinEvent(const Player &player); - bool executeCanJoinEvent(const Player &player); - bool executeOnLeaveEvent(const Player &player); - bool executeOnSpeakEvent(const Player &player, SpeakClasses &type, const std::string &message); + bool executeOnJoinEvent(const std::shared_ptr &player); + bool executeCanJoinEvent(const std::shared_ptr &player); + bool executeOnLeaveEvent(const std::shared_ptr &player); + bool executeOnSpeakEvent(const std::shared_ptr &player, SpeakClasses &type, const std::string &message); protected: UsersMap users; @@ -91,8 +91,8 @@ class PrivateChatChannel final : public ChatChannel { bool isInvited(uint32_t guid) const; - void invitePlayer(const Player &player, Player &invitePlayer); - void excludePlayer(const Player &player, Player &excludePlayer); + void invitePlayer(const std::shared_ptr &player, const std::shared_ptr &invitePlayer); + void excludePlayer(const std::shared_ptr &player, const std::shared_ptr &excludePlayer); bool removeInvite(uint32_t guid); @@ -123,21 +123,21 @@ class Chat { bool load(); - ChatChannel* createChannel(const Player &player, uint16_t channelId); - bool deleteChannel(const Player &player, uint16_t channelId); + ChatChannel* createChannel(const std::shared_ptr &player, uint16_t channelId); + bool deleteChannel(const std::shared_ptr &player, uint16_t channelId); - ChatChannel* addUserToChannel(Player &player, uint16_t channelId); - bool removeUserFromChannel(const Player &player, uint16_t channelId); - void removeUserFromAllChannels(const Player &player); + ChatChannel* addUserToChannel(const std::shared_ptr &player, uint16_t channelId); + bool removeUserFromChannel(const std::shared_ptr &player, uint16_t channelId); + void removeUserFromAllChannels(const std::shared_ptr &player); - bool talkToChannel(const Player &player, SpeakClasses type, const std::string &text, uint16_t channelId); + bool talkToChannel(const std::shared_ptr &player, SpeakClasses type, const std::string &text, uint16_t channelId); - ChannelList getChannelList(const Player &player); + ChannelList getChannelList(const std::shared_ptr &player); - ChatChannel* getChannel(const Player &player, uint16_t channelId); + ChatChannel* getChannel(const std::shared_ptr &player, uint16_t channelId); ChatChannel* getChannelById(uint16_t channelId); ChatChannel* getGuildChannelById(uint32_t guildId); - PrivateChatChannel* getPrivateChannel(const Player &player); + PrivateChatChannel* getPrivateChannel(const std::shared_ptr &player); LuaScriptInterface* getScriptInterface() { return &scriptInterface; @@ -146,7 +146,7 @@ class Chat { private: std::map normalChannels; std::map privateChannels; - std::map partyChannels; + std::map, ChatChannel> partyChannels; std::map guildChannels; LuaScriptInterface scriptInterface; diff --git a/src/creatures/monsters/monster.cpp b/src/creatures/monsters/monster.cpp index 43d41567b..1948c2458 100644 --- a/src/creatures/monsters/monster.cpp +++ b/src/creatures/monsters/monster.cpp @@ -23,12 +23,12 @@ int32_t Monster::despawnRadius; uint32_t Monster::monsterAutoID = 0x50000001; -Monster* Monster::createMonster(const std::string &name) { +std::shared_ptr Monster::createMonster(const std::string &name) { const auto mType = g_monsters().getMonsterType(name); if (!mType) { return nullptr; } - return new Monster(mType); + return std::make_shared(mType); } Monster::Monster(const std::shared_ptr mType) : @@ -56,17 +56,12 @@ Monster::Monster(const std::shared_ptr mType) : } } -Monster::~Monster() { - clearTargetList(); - clearFriendList(); -} - void Monster::addList() { - g_game().addMonster(this); + g_game().addMonster(static_self_cast()); } void Monster::removeList() { - g_game().removeMonster(this); + g_game().removeMonster(static_self_cast()); } bool Monster::canWalkOnFieldType(CombatType_t combatType) const { @@ -104,7 +99,7 @@ void Monster::onAttackedCreatureDisappear(bool) { extraMeleeAttack = true; } -void Monster::onCreatureAppear(Creature* creature, bool isLogin) { +void Monster::onCreatureAppear(std::shared_ptr creature, bool isLogin) { Creature::onCreatureAppear(creature, isLogin); if (mType->info.creatureAppearEvent != -1) { @@ -123,7 +118,7 @@ void Monster::onCreatureAppear(Creature* creature, bool isLogin) { lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.creatureAppearEvent); - LuaScriptInterface::pushUserdata(L, this); + LuaScriptInterface::pushUserdata(L, getMonster()); LuaScriptInterface::setMetatable(L, -1, "Monster"); LuaScriptInterface::pushUserdata(L, creature); @@ -134,7 +129,7 @@ void Monster::onCreatureAppear(Creature* creature, bool isLogin) { } } - if (creature == this) { + if (creature.get() == this) { updateTargetList(); updateIdleStatus(); } else { @@ -142,7 +137,7 @@ void Monster::onCreatureAppear(Creature* creature, bool isLogin) { } } -void Monster::onRemoveCreature(Creature* creature, bool isLogout) { +void Monster::onRemoveCreature(std::shared_ptr creature, bool isLogout) { Creature::onRemoveCreature(creature, isLogout); if (mType->info.creatureDisappearEvent != -1) { @@ -161,7 +156,7 @@ void Monster::onRemoveCreature(Creature* creature, bool isLogout) { lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.creatureDisappearEvent); - LuaScriptInterface::pushUserdata(L, this); + LuaScriptInterface::pushUserdata(L, getMonster()); LuaScriptInterface::setMetatable(L, -1, "Monster"); LuaScriptInterface::pushUserdata(L, creature); @@ -172,7 +167,7 @@ void Monster::onRemoveCreature(Creature* creature, bool isLogout) { } } - if (creature == this) { + if (creature.get() == this) { if (spawnMonster) { spawnMonster->startSpawnMonsterCheck(); } @@ -183,7 +178,7 @@ void Monster::onRemoveCreature(Creature* creature, bool isLogout) { } } -void Monster::onCreatureMove(Creature* creature, const Tile* newTile, const Position &newPos, const Tile* oldTile, const Position &oldPos, bool teleport) { +void Monster::onCreatureMove(std::shared_ptr creature, std::shared_ptr newTile, const Position &newPos, std::shared_ptr oldTile, const Position &oldPos, bool teleport) { Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport); if (mType->info.creatureMoveEvent != -1) { @@ -202,7 +197,7 @@ void Monster::onCreatureMove(Creature* creature, const Tile* newTile, const Posi lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.creatureMoveEvent); - LuaScriptInterface::pushUserdata(L, this); + LuaScriptInterface::pushUserdata(L, getMonster()); LuaScriptInterface::setMetatable(L, -1, "Monster"); LuaScriptInterface::pushUserdata(L, creature); @@ -216,7 +211,7 @@ void Monster::onCreatureMove(Creature* creature, const Tile* newTile, const Posi } } - if (creature == this) { + if (creature.get() == this) { updateTargetList(); updateIdleStatus(); } else { @@ -232,6 +227,7 @@ void Monster::onCreatureMove(Creature* creature, const Tile* newTile, const Posi updateIdleStatus(); if (!isSummon()) { + auto followCreature = getFollowCreature(); if (followCreature) { const Position &followPosition = followCreature->getPosition(); const Position &pos = getPosition(); @@ -242,9 +238,9 @@ void Monster::onCreatureMove(Creature* creature, const Tile* newTile, const Posi Direction dir = getDirectionTo(pos, followPosition); const Position &checkPosition = getNextPosition(dir, pos); - const Tile* nextTile = g_game().map.getTile(checkPosition); + auto nextTile = g_game().map.getTile(checkPosition); if (nextTile) { - Creature* topCreature = nextTile->getTopCreature(); + auto topCreature = nextTile->getTopCreature(); if (topCreature && followCreature != topCreature && isOpponent(topCreature)) { selectTarget(topCreature); } @@ -258,7 +254,7 @@ void Monster::onCreatureMove(Creature* creature, const Tile* newTile, const Posi } } -void Monster::onCreatureSay(Creature* creature, SpeakClasses type, const std::string &text) { +void Monster::onCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text) { Creature::onCreatureSay(creature, type, text); if (mType->info.creatureSayEvent != -1) { @@ -277,7 +273,7 @@ void Monster::onCreatureSay(Creature* creature, SpeakClasses type, const std::st lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.creatureSayEvent); - LuaScriptInterface::pushUserdata(L, this); + LuaScriptInterface::pushUserdata(L, getMonster()); LuaScriptInterface::setMetatable(L, -1, "Monster"); LuaScriptInterface::pushUserdata(L, creature); @@ -290,71 +286,64 @@ void Monster::onCreatureSay(Creature* creature, SpeakClasses type, const std::st } } -void Monster::addFriend(Creature* creature) { - assert(creature != this); - auto result = friendList.insert(creature); - if (result.second) { - creature->incrementReferenceCounter(); - } +void Monster::addFriend(std::shared_ptr creature) { + assert(creature.get() != this); + friendList.try_emplace(creature->getID(), creature); } -void Monster::removeFriend(Creature* creature) { - auto it = friendList.find(creature); - if (it != friendList.end()) { - creature->decrementReferenceCounter(); - friendList.erase(it); - } +void Monster::removeFriend(std::shared_ptr creature) { + friendList.erase(creature->getID()); } -void Monster::addTarget(Creature* creature, bool pushFront /* = false*/) { - assert(creature != this); - if (std::find(targetList.begin(), targetList.end(), creature) == targetList.end()) { - creature->incrementReferenceCounter(); +void Monster::addTarget(std::shared_ptr creature, bool pushFront /* = false*/) { + assert(creature.get() != this); + auto cid = creature->getID(); + targetListMap.try_emplace(cid, creature); + if (std::find(targetIDList.begin(), targetIDList.end(), cid) == targetIDList.end()) { if (pushFront) { - targetList.push_front(creature); + targetIDList.push_front(cid); } else { - targetList.push_back(creature); + targetIDList.push_back(cid); } - if (!master && getFaction() != FACTION_DEFAULT && creature->getPlayer()) { + if (!getMaster() && getFaction() != FACTION_DEFAULT && creature->getPlayer()) { totalPlayersOnScreen++; } } } -void Monster::removeTarget(Creature* creature) { +void Monster::removeTarget(std::shared_ptr creature) { if (!creature) { return; } - auto it = std::find(targetList.begin(), targetList.end(), creature); - if (it != targetList.end()) { - if (!master && getFaction() != FACTION_DEFAULT && creature->getPlayer()) { + auto it = std::find(targetIDList.begin(), targetIDList.end(), creature->getID()); + if (it != targetIDList.end()) { + if (!getMaster() && getFaction() != FACTION_DEFAULT && creature->getPlayer()) { totalPlayersOnScreen--; } - creature->decrementReferenceCounter(); - targetList.erase(it); + targetIDList.erase(it); + targetListMap.erase(creature->getID()); } } void Monster::updateTargetList() { auto friendIterator = friendList.begin(); while (friendIterator != friendList.end()) { - Creature* creature = *friendIterator; - if (creature->getHealth() <= 0 || !canSee(creature->getPosition())) { - creature->decrementReferenceCounter(); + auto creature = (*friendIterator).second.lock(); + if (!creature || creature->getHealth() <= 0 || !canSee(creature->getPosition())) { friendIterator = friendList.erase(friendIterator); } else { ++friendIterator; } } - auto targetIterator = targetList.begin(); - while (targetIterator != targetList.end()) { - Creature* creature = *targetIterator; - if (creature->getHealth() <= 0 || !canSee(creature->getPosition())) { - creature->decrementReferenceCounter(); - targetIterator = targetList.erase(targetIterator); + auto targetIterator = targetIDList.begin(); + while (targetIterator != targetIDList.end()) { + auto creature = targetListMap[*targetIterator].lock(); + if (!creature || creature->getHealth() <= 0 || !canSee(creature->getPosition())) { + targetIterator = targetIDList.erase(targetIterator); + targetListMap.erase(*targetIterator); } else { ++targetIterator; } @@ -363,7 +352,7 @@ void Monster::updateTargetList() { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, position, true); spectators.erase(this); - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { if (canSee(spectator->getPosition())) { onCreatureFound(spectator); } @@ -371,20 +360,15 @@ void Monster::updateTargetList() { } void Monster::clearTargetList() { - for (Creature* creature : targetList) { - creature->decrementReferenceCounter(); - } - targetList.clear(); + targetIDList.clear(); + targetListMap.clear(); } void Monster::clearFriendList() { - for (Creature* creature : friendList) { - creature->decrementReferenceCounter(); - } friendList.clear(); } -void Monster::onCreatureFound(Creature* creature, bool pushFront /* = false*/) { +void Monster::onCreatureFound(std::shared_ptr creature, bool pushFront /* = false*/) { if (isFriend(creature)) { addFriend(creature); } @@ -396,19 +380,19 @@ void Monster::onCreatureFound(Creature* creature, bool pushFront /* = false*/) { updateIdleStatus(); } -void Monster::onCreatureEnter(Creature* creature) { +void Monster::onCreatureEnter(std::shared_ptr creature) { onCreatureFound(creature, true); } -bool Monster::isFriend(const Creature* creature) const { +bool Monster::isFriend(std::shared_ptr creature) const { if (isSummon() && getMaster()->getPlayer()) { - const Player* masterPlayer = getMaster()->getPlayer(); - const Player* tmpPlayer = nullptr; + std::shared_ptr masterPlayer = getMaster()->getPlayer(); + std::shared_ptr tmpPlayer = nullptr; if (creature->getPlayer()) { tmpPlayer = creature->getPlayer(); } else { - const Creature* creatureMaster = creature->getMaster(); + std::shared_ptr creatureMaster = creature->getMaster(); if (creatureMaster && creatureMaster->getPlayer()) { tmpPlayer = creatureMaster->getPlayer(); @@ -425,7 +409,7 @@ bool Monster::isFriend(const Creature* creature) const { return false; } -bool Monster::isOpponent(const Creature* creature) const { +bool Monster::isOpponent(std::shared_ptr creature) const { if (isSummon() && getMaster()->getPlayer()) { if (creature != getMaster()) { return true; @@ -444,7 +428,7 @@ bool Monster::isOpponent(const Creature* creature) const { return false; } -void Monster::onCreatureLeave(Creature* creature) { +void Monster::onCreatureLeave(std::shared_ptr creature) { // update friendList if (isFriend(creature)) { removeFriend(creature); @@ -453,7 +437,7 @@ void Monster::onCreatureLeave(Creature* creature) { // update targetList if (isOpponent(creature)) { removeTarget(creature); - if (targetList.empty()) { + if (targetIDList.empty()) { updateIdleStatus(); } } @@ -480,12 +464,13 @@ bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAUL } } - std::list resultList; + std::list> resultList; const Position &myPos = getPosition(); - for (Creature* creature : targetList) { - if (isTarget(creature)) { - if ((this->targetDistance == 1) || canUseAttack(myPos, creature)) { + for (auto cid : targetIDList) { + auto creature = targetListMap[cid].lock(); + if (creature && isTarget(creature)) { + if ((static_self_cast()->targetDistance == 1) || canUseAttack(myPos, creature)) { resultList.push_back(creature); } } @@ -495,7 +480,7 @@ bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAUL return false; } - Creature* getTarget = nullptr; + std::shared_ptr getTarget = nullptr; switch (searchType) { case TARGETSEARCH_NEAREST: { @@ -519,7 +504,7 @@ bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAUL } } else { int32_t minRange = std::numeric_limits::max(); - for (Creature* creature : targetList) { + for (auto creature : getTargetList()) { if (!isTarget(creature)) { continue; } @@ -567,7 +552,7 @@ bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAUL if (++it != resultList.end()) { int32_t mostDamage = 0; do { - const auto &dmg = damageMap.find((*it)->getID()); + const auto dmg = damageMap.find((*it)->getID()); if (dmg != damageMap.end()) { if (dmg->second.total > mostDamage) { mostDamage = dmg->second.total; @@ -594,7 +579,7 @@ bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAUL } // lets just pick the first target in the list - for (Creature* target : targetList) { + for (auto target : getTargetList()) { if (selectTarget(target)) { return true; } @@ -602,25 +587,29 @@ bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAUL return false; } -void Monster::onFollowCreatureComplete(const Creature* creature) { - if (creature) { - auto it = std::find(targetList.begin(), targetList.end(), creature); - if (it != targetList.end()) { - Creature* target = (*it); - targetList.erase(it); +void Monster::onFollowCreatureComplete(std::shared_ptr creature) { + if (!creature) { + return; + } + auto it = std::find(targetIDList.begin(), targetIDList.end(), creature->getID()); + if (it != targetIDList.end()) { + auto target = targetListMap[*it].lock(); + if (!target) { + return; + } + targetIDList.erase(it); - if (hasFollowPath) { - targetList.push_front(target); - } else if (!isSummon()) { - targetList.push_back(target); - } else { - target->decrementReferenceCounter(); - } + if (hasFollowPath) { + targetIDList.push_front(target->getID()); + } else if (!isSummon()) { + targetIDList.push_back(target->getID()); + } else { + targetListMap.erase(target->getID()); } } } -BlockType_t Monster::blockHit(Creature* attacker, CombatType_t combatType, int32_t &damage, bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool /* field = false */) { +BlockType_t Monster::blockHit(std::shared_ptr attacker, CombatType_t combatType, int32_t &damage, bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool /* field = false */) { BlockType_t blockType = Creature::blockHit(attacker, combatType, damage, checkDefense, checkArmor); if (damage != 0) { @@ -631,7 +620,7 @@ BlockType_t Monster::blockHit(Creature* attacker, CombatType_t combatType, int32 } // Wheel of destiny - Player* player = attacker ? attacker->getPlayer() : nullptr; + std::shared_ptr player = attacker ? attacker->getPlayer() : nullptr; if (player && player->wheel()->getInstant("Ballistic Mastery")) { elementMod -= player->wheel()->checkElementSensitiveReduction(combatType); } @@ -648,7 +637,7 @@ BlockType_t Monster::blockHit(Creature* attacker, CombatType_t combatType, int32 return blockType; } -bool Monster::isTarget(const Creature* creature) const { +bool Monster::isTarget(std::shared_ptr creature) { if (creature->isRemoved() || !creature->isAttackable() || creature->getZoneType() == ZONE_PROTECTION || !canSeeCreature(creature)) { return false; } @@ -663,13 +652,13 @@ bool Monster::isTarget(const Creature* creature) const { return true; } -bool Monster::selectTarget(Creature* creature) { +bool Monster::selectTarget(std::shared_ptr creature) { if (!isTarget(creature)) { return false; } - auto it = std::find(targetList.begin(), targetList.end(), creature); - if (it == targetList.end()) { + auto it = std::find(targetIDList.begin(), targetIDList.end(), creature->getID()); + if (it == targetIDList.end()) { // Target not found in our target list. return false; } @@ -690,22 +679,23 @@ void Monster::setIdle(bool idle) { isIdle = idle; if (!isIdle) { - g_game().addCreatureCheck(this); + g_game().addCreatureCheck(static_self_cast()); } else { onIdleStatus(); clearTargetList(); clearFriendList(); - Game::removeCreatureCheck(this); + Game::removeCreatureCheck(static_self_cast()); } } void Monster::updateIdleStatus() { bool idle = false; + auto master = getMaster(); if (conditions.empty()) { - if (!isSummon() && targetList.empty()) { + if (!isSummon() && targetIDList.empty()) { idle = true; - } else if ((!isSummon() && totalPlayersOnScreen == 0 || isSummon() && master->getMonster() && master->getMonster()->totalPlayersOnScreen == 0) && getFaction() != FACTION_DEFAULT) { + } else if (master && (!isSummon() && totalPlayersOnScreen == 0 || isSummon() && master->getMonster() && master->getMonster()->totalPlayersOnScreen == 0) && getFaction() != FACTION_DEFAULT) { idle = true; } } @@ -747,7 +737,7 @@ void Monster::onThink(uint32_t interval) { lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.thinkEvent); - LuaScriptInterface::pushUserdata(L, this); + LuaScriptInterface::pushUserdata(L, getMonster()); LuaScriptInterface::setMetatable(L, -1, "Monster"); lua_pushnumber(L, interval); @@ -762,16 +752,16 @@ void Monster::onThink(uint32_t interval) { if (challengeMeleeDuration <= 0) { challengeMeleeDuration = 0; targetDistance = mType->info.targetDistance; - g_game().updateCreatureIcon(this); + g_game().updateCreatureIcon(static_self_cast()); } } if (!mType->canSpawn(position)) { - g_game().removeCreature(this); + g_game().removeCreature(static_self_cast()); } if (!isInSpawnRange(position)) { - g_game().internalTeleport(this, masterPos); + g_game().internalTeleport(static_self_cast(), masterPos); setIdle(true); } else { updateIdleStatus(); @@ -779,6 +769,8 @@ void Monster::onThink(uint32_t interval) { if (!isIdle) { addEventWalk(); + auto attackedCreature = getAttackedCreature(); + auto followCreature = getFollowCreature(); if (isSummon()) { if (!attackedCreature) { if (getMaster() && getMaster()->getAttackedCreature()) { @@ -788,13 +780,13 @@ void Monster::onThink(uint32_t interval) { // Our master has not ordered us to attack anything, lets follow him around instead. setFollowCreature(getMaster()); } - } else if (attackedCreature == this) { + } else if (attackedCreature.get() == this) { setFollowCreature(nullptr); } else if (followCreature != attackedCreature) { // This happens just after a master orders an attack, so lets follow it aswell. setFollowCreature(attackedCreature); } - } else if (!targetList.empty()) { + } else if (!targetIDList.empty()) { if (!followCreature || !hasFollowPath) { searchTarget(TARGETSEARCH_NEAREST); } else if (isFleeing()) { @@ -813,7 +805,8 @@ void Monster::onThink(uint32_t interval) { } void Monster::doAttacking(uint32_t interval) { - if (!attackedCreature || (isSummon() && attackedCreature == this)) { + auto attackedCreature = getAttackedCreature(); + if (!attackedCreature || (isSummon() && attackedCreature.get() == this)) { return; } @@ -833,10 +826,6 @@ void Monster::doAttacking(uint32_t interval) { for (const spellBlock_t &spellBlock : mType->info.attackSpells) { bool inRange = false; - if (attackedCreature == nullptr) { - break; - } - if (spellBlock.spell == nullptr || spellBlock.isMelee && isFleeing()) { continue; } @@ -867,7 +856,7 @@ void Monster::doAttacking(uint32_t interval) { continue; } - spellBlock.spell->castSpell(this, attackedCreature); + spellBlock.spell->castSpell(getMonster(), attackedCreature); if (spellBlock.isMelee) { extraMeleeAttack = false; @@ -890,7 +879,7 @@ void Monster::doAttacking(uint32_t interval) { } } -bool Monster::canUseAttack(const Position &pos, const Creature* target) const { +bool Monster::canUseAttack(const Position &pos, std::shared_ptr target) const { if (isHostile()) { const Position &targetPos = target->getPosition(); uint32_t distance = std::max(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos)); @@ -1003,18 +992,18 @@ void Monster::onThinkDefense(uint32_t interval) { if ((spellBlock.chance >= static_cast(uniform_random(1, 100)))) { minCombatValue = spellBlock.minCombatValue; maxCombatValue = spellBlock.maxCombatValue; - spellBlock.spell->castSpell(this, this); + spellBlock.spell->castSpell(getMonster(), getMonster()); } } - if (!isSummon() && summons.size() < mType->info.maxSummons && hasFollowPath) { + if (!isSummon() && m_summons.size() < mType->info.maxSummons && hasFollowPath) { for (const summonBlock_t &summonBlock : mType->info.summons) { if (summonBlock.speed > defenseTicks) { resetTicks = false; continue; } - if (summons.size() >= mType->info.maxSummons) { + if (m_summons.size() >= mType->info.maxSummons) { continue; } @@ -1024,8 +1013,8 @@ void Monster::onThinkDefense(uint32_t interval) { } uint32_t summonCount = 0; - for (Creature* summon : summons) { - if (summon->getName() == summonBlock.name) { + for (const auto &summon : m_summons) { + if (summon && summon->getName() == summonBlock.name) { ++summonCount; } } @@ -1038,15 +1027,13 @@ void Monster::onThinkDefense(uint32_t interval) { continue; } - Monster* summon = Monster::createMonster(summonBlock.name); + std::shared_ptr summon = Monster::createMonster(summonBlock.name); if (summon) { if (g_game().placeCreature(summon, getPosition(), false, summonBlock.force)) { - summon->setMaster(this, true); + summon->setMaster(static_self_cast(), true); g_game().addMagicEffect(getPosition(), CONST_ME_MAGIC_BLUE); g_game().addMagicEffect(summon->getPosition(), CONST_ME_TELEPORT); - g_game().sendSingleSoundEffect(summon->getPosition(), SoundEffect_t::MONSTER_SPELL_SUMMON, this); - } else { - delete summon; + g_game().sendSingleSoundEffect(summon->getPosition(), SoundEffect_t::MONSTER_SPELL_SUMMON, getMonster()); } } } @@ -1071,9 +1058,9 @@ void Monster::onThinkYell(uint32_t interval) { const voiceBlock_t &vb = mType->info.voiceVector[index]; if (vb.yellText) { - g_game().internalCreatureSay(this, TALKTYPE_MONSTER_YELL, vb.text, false); + g_game().internalCreatureSay(static_self_cast(), TALKTYPE_MONSTER_YELL, vb.text, false); } else { - g_game().internalCreatureSay(this, TALKTYPE_MONSTER_SAY, vb.text, false); + g_game().internalCreatureSay(static_self_cast(), TALKTYPE_MONSTER_SAY, vb.text, false); } } } @@ -1090,16 +1077,16 @@ void Monster::onThinkSound(uint32_t interval) { if (!mType->info.soundVector.empty() && (mType->info.soundChance >= static_cast(uniform_random(1, 100)))) { int64_t index = uniform_random(0, static_cast(mType->info.soundVector.size() - 1)); - g_game().sendSingleSoundEffect(this->getPosition(), mType->info.soundVector[index], this); + g_game().sendSingleSoundEffect(static_self_cast()->getPosition(), mType->info.soundVector[index], getMonster()); } } } -bool Monster::pushItem(Item* item, const Direction &nextDirection) { +bool Monster::pushItem(std::shared_ptr item, const Direction &nextDirection) { const Position ¢erPos = item->getPosition(); for (const auto &[x, y] : getPushItemLocationOptions(nextDirection)) { Position tryPos(centerPos.x + x, centerPos.y + y, centerPos.z); - Tile* tile = g_game().map.getTile(tryPos); + std::shared_ptr tile = g_game().map.getTile(tryPos); if (tile && g_game().canThrowObjectTo(centerPos, tryPos) && g_game().internalMoveItem(item->getParent(), tile, INDEX_WHEREEVER, item, item->getItemCount(), nullptr) == RETURNVALUE_NOERROR) { return true; } @@ -1107,7 +1094,7 @@ bool Monster::pushItem(Item* item, const Direction &nextDirection) { return false; } -void Monster::pushItems(Tile* tile, const Direction &nextDirection) { +void Monster::pushItems(std::shared_ptr tile, const Direction &nextDirection) { // We can not use iterators here since we can push the item to another tile // which will invalidate the iterator. // start from the end to minimize the amount of traffic @@ -1119,7 +1106,7 @@ void Monster::pushItems(Tile* tile, const Direction &nextDirection) { uint32_t removeCount = 0; auto it = items->begin(); while (it != items->end()) { - Item* item = *it; + std::shared_ptr item = *it; if (item && item->hasProperty(CONST_PROP_MOVEABLE) && (item->hasProperty(CONST_PROP_BLOCKPATH) || item->hasProperty(CONST_PROP_BLOCKSOLID)) && item->getAttribute(ItemAttribute_t::ACTIONID) != IMMOVABLE_ACTION_ID) { if (moveCount < 20 && pushItem(item, nextDirection)) { ++moveCount; @@ -1135,7 +1122,7 @@ void Monster::pushItems(Tile* tile, const Direction &nextDirection) { } } -bool Monster::pushCreature(Creature* creature) { +bool Monster::pushCreature(std::shared_ptr creature) { static std::vector dirList { DIRECTION_NORTH, DIRECTION_WEST, DIRECTION_EAST, @@ -1145,7 +1132,7 @@ bool Monster::pushCreature(Creature* creature) { for (Direction dir : dirList) { const Position &tryPos = Spells::getCasterPosition(creature, dir); - const Tile* toTile = g_game().map.getTile(tryPos); + const auto toTile = g_game().map.getTile(tryPos); if (toTile && !toTile->hasFlag(TILESTATE_BLOCKPATH) && g_game().internalMoveCreature(creature, dir) == RETURNVALUE_NOERROR) { return true; } @@ -1153,15 +1140,15 @@ bool Monster::pushCreature(Creature* creature) { return false; } -void Monster::pushCreatures(Tile* tile) { +void Monster::pushCreatures(std::shared_ptr tile) { // We can not use iterators here since we can push a creature to another tile // which will invalidate the iterator. if (CreatureVector* creatures = tile->getCreatures()) { uint32_t removeCount = 0; - Monster* lastPushedMonster = nullptr; + std::shared_ptr lastPushedMonster = nullptr; for (size_t i = 0; i < creatures->size();) { - Monster* monster = creatures->at(i)->getMonster(); + std::shared_ptr monster = creatures->at(i)->getMonster(); if (monster && monster->isPushable()) { if (monster != lastPushedMonster && Monster::pushCreature(monster)) { lastPushedMonster = monster; @@ -1191,7 +1178,7 @@ bool Monster::getNextStep(Direction &nextDirection, uint32_t &flags) { bool result = false; - if (followCreature && hasFollowPath) { + if (getFollowCreature() && hasFollowPath) { doFollowCreature(flags, nextDirection, result); } else { doRandomStep(nextDirection, result); @@ -1199,7 +1186,7 @@ bool Monster::getNextStep(Direction &nextDirection, uint32_t &flags) { if (result && (canPushItems() || canPushCreatures())) { const Position &pos = getNextPosition(nextDirection, getPosition()); - Tile* posTile = g_game().map.getTile(pos); + auto posTile = g_game().map.getTile(pos); if (posTile) { if (canPushItems()) { Monster::pushItems(posTile, nextDirection); @@ -1232,6 +1219,8 @@ void Monster::doFollowCreature(uint32_t &flags, Direction &nextDirection, bool & updateMapCache(); } // target dancing + auto attackedCreature = getAttackedCreature(); + auto followCreature = getFollowCreature(); if (attackedCreature && attackedCreature == followCreature) { if (isFleeing()) { result = getDanceStep(getPosition(), nextDirection, false, false); @@ -1242,7 +1231,7 @@ void Monster::doFollowCreature(uint32_t &flags, Direction &nextDirection, bool & } } -bool Monster::getRandomStep(const Position &creaturePos, Direction &moveDirection) const { +bool Monster::getRandomStep(const Position &creaturePos, Direction &moveDirection) { static std::vector dirList { DIRECTION_NORTH, DIRECTION_WEST, DIRECTION_EAST, @@ -1260,9 +1249,11 @@ bool Monster::getRandomStep(const Position &creaturePos, Direction &moveDirectio } bool Monster::getDanceStep(const Position &creaturePos, Direction &moveDirection, bool keepAttack /*= true*/, bool keepDistance /*= true*/) { + auto attackedCreature = getAttackedCreature(); + if (!attackedCreature) { + return false; + } bool canDoAttackNow = canUseAttack(creaturePos, attackedCreature); - - assert(attackedCreature != nullptr); const Position ¢erPos = attackedCreature->getPosition(); int_fast32_t offset_x = Position::getOffsetX(creaturePos, centerPos); @@ -1279,7 +1270,6 @@ bool Monster::getDanceStep(const Position &creaturePos, Direction &moveDirection } std::vector dirList; - if (!keepDistance || offset_y >= 0) { uint32_t tmpDist = std::max(distance_x, std::abs((creaturePos.getY() - 1) - centerPos.getY())); if (tmpDist == centerToDist && canWalkTo(creaturePos, DIRECTION_NORTH)) { @@ -1840,50 +1830,53 @@ bool Monster::getDistanceStep(const Position &targetPos, Direction &moveDirectio return true; } -bool Monster::canWalkTo(Position pos, Direction moveDirection) const { +bool Monster::canWalkTo(Position pos, Direction moveDirection) { pos = getNextPosition(moveDirection, pos); if (isInSpawnRange(pos)) { if (getWalkCache(pos) == 0) { return false; } - const Tile* tile = g_game().map.getTile(pos); - if (tile && tile->getTopVisibleCreature(this) == nullptr && tile->queryAdd(0, *this, 1, FLAG_PATHFINDING | FLAG_IGNOREFIELDDAMAGE) == RETURNVALUE_NOERROR) { + const auto tile = g_game().map.getTile(pos); + if (tile && tile->getTopVisibleCreature(getMonster()) == nullptr && tile->queryAdd(0, getMonster(), 1, FLAG_PATHFINDING | FLAG_IGNOREFIELDDAMAGE) == RETURNVALUE_NOERROR) { return true; } } return false; } -void Monster::death(Creature*) { +void Monster::death(std::shared_ptr) { if (monsterForgeClassification > ForgeClassifications_t::FORGE_NORMAL_MONSTER) { g_game().removeForgeMonster(getID(), monsterForgeClassification, true); } setAttackedCreature(nullptr); - for (Creature* summon : summons) { + for (const auto &summon : m_summons) { + if (!summon) { + continue; + } summon->changeHealth(-summon->getHealth()); summon->removeMaster(); } - summons.clear(); + m_summons.clear(); clearTargetList(); clearFriendList(); onIdleStatus(); if (mType) { - g_game().sendSingleSoundEffect(this->getPosition(), mType->info.deathSound, this); + g_game().sendSingleSoundEffect(static_self_cast()->getPosition(), mType->info.deathSound, getMonster()); } } -Item* Monster::getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature) { - Item* corpse = Creature::getCorpse(lastHitCreature, mostDamageCreature); +std::shared_ptr Monster::getCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature) { + std::shared_ptr corpse = Creature::getCorpse(lastHitCreature, mostDamageCreature); if (corpse) { if (mostDamageCreature) { if (mostDamageCreature->getPlayer()) { corpse->setAttribute(ItemAttribute_t::CORPSEOWNER, mostDamageCreature->getID()); } else { - const Creature* mostDamageCreatureMaster = mostDamageCreature->getMaster(); + std::shared_ptr mostDamageCreatureMaster = mostDamageCreature->getMaster(); if (mostDamageCreatureMaster && mostDamageCreatureMaster->getPlayer()) { corpse->setAttribute(ItemAttribute_t::CORPSEOWNER, mostDamageCreatureMaster->getID()); } @@ -1936,62 +1929,64 @@ bool Monster::getCombatValues(int32_t &min, int32_t &max) { void Monster::updateLookDirection() { Direction newDir = getDirection(); + auto attackedCreature = getAttackedCreature(); + if (!attackedCreature) { + return; + } + + const Position &pos = getPosition(); + const Position &attackedCreaturePos = attackedCreature->getPosition(); + int_fast32_t offsetx = Position::getOffsetX(attackedCreaturePos, pos); + int_fast32_t offsety = Position::getOffsetY(attackedCreaturePos, pos); - if (attackedCreature) { - const Position &pos = getPosition(); - const Position &attackedCreaturePos = attackedCreature->getPosition(); - int_fast32_t offsetx = Position::getOffsetX(attackedCreaturePos, pos); - int_fast32_t offsety = Position::getOffsetY(attackedCreaturePos, pos); - - int32_t dx = std::abs(offsetx); - int32_t dy = std::abs(offsety); - if (dx > dy) { - // look EAST/WEST - if (offsetx < 0) { + int32_t dx = std::abs(offsetx); + int32_t dy = std::abs(offsety); + if (dx > dy) { + // look EAST/WEST + if (offsetx < 0) { + newDir = DIRECTION_WEST; + } else { + newDir = DIRECTION_EAST; + } + } else if (dx < dy) { + // look NORTH/SOUTH + if (offsety < 0) { + newDir = DIRECTION_NORTH; + } else { + newDir = DIRECTION_SOUTH; + } + } else { + Direction dir = getDirection(); + if (offsetx < 0 && offsety < 0) { + if (dir == DIRECTION_SOUTH) { newDir = DIRECTION_WEST; - } else { - newDir = DIRECTION_EAST; - } - } else if (dx < dy) { - // look NORTH/SOUTH - if (offsety < 0) { + } else if (dir == DIRECTION_EAST) { newDir = DIRECTION_NORTH; - } else { + } + } else if (offsetx < 0 && offsety > 0) { + if (dir == DIRECTION_NORTH) { + newDir = DIRECTION_WEST; + } else if (dir == DIRECTION_EAST) { newDir = DIRECTION_SOUTH; } + } else if (offsetx > 0 && offsety < 0) { + if (dir == DIRECTION_SOUTH) { + newDir = DIRECTION_EAST; + } else if (dir == DIRECTION_WEST) { + newDir = DIRECTION_NORTH; + } } else { - Direction dir = getDirection(); - if (offsetx < 0 && offsety < 0) { - if (dir == DIRECTION_SOUTH) { - newDir = DIRECTION_WEST; - } else if (dir == DIRECTION_EAST) { - newDir = DIRECTION_NORTH; - } - } else if (offsetx < 0 && offsety > 0) { - if (dir == DIRECTION_NORTH) { - newDir = DIRECTION_WEST; - } else if (dir == DIRECTION_EAST) { - newDir = DIRECTION_SOUTH; - } - } else if (offsetx > 0 && offsety < 0) { - if (dir == DIRECTION_SOUTH) { - newDir = DIRECTION_EAST; - } else if (dir == DIRECTION_WEST) { - newDir = DIRECTION_NORTH; - } - } else { - if (dir == DIRECTION_NORTH) { - newDir = DIRECTION_EAST; - } else if (dir == DIRECTION_WEST) { - newDir = DIRECTION_SOUTH; - } + if (dir == DIRECTION_NORTH) { + newDir = DIRECTION_EAST; + } else if (dir == DIRECTION_WEST) { + newDir = DIRECTION_SOUTH; } } } - g_game().internalCreatureTurn(this, newDir); + g_game().internalCreatureTurn(getMonster(), newDir); } -void Monster::dropLoot(Container* corpse, Creature*) { +void Monster::dropLoot(std::shared_ptr corpse, std::shared_ptr) { if (corpse && lootDrop) { // Only fiendish drops sliver if (ForgeClassifications_t classification = getMonsterForgeClassification(); @@ -2002,14 +1997,14 @@ void Monster::dropLoot(Container* corpse, Creature*) { auto sliverCount = static_cast(uniform_random(minSlivers, maxSlivers)); - Item* sliver = Item::CreateItem(ITEM_FORGE_SLIVER, sliverCount); + std::shared_ptr sliver = Item::CreateItem(ITEM_FORGE_SLIVER, sliverCount); if (g_game().internalAddItem(corpse, sliver) != RETURNVALUE_NOERROR) { corpse->internalAddThing(sliver); } } if (!this->isRewardBoss() && g_configManager().getNumber(RATE_LOOT) > 0) { - g_callbacks().executeCallback(EventCallback_t::monsterOnDropLoot, &EventCallback::monsterOnDropLoot, this, corpse); - g_callbacks().executeCallback(EventCallback_t::monsterPostDropLoot, &EventCallback::monsterPostDropLoot, this, corpse); + g_callbacks().executeCallback(EventCallback_t::monsterOnDropLoot, &EventCallback::monsterOnDropLoot, getMonster(), corpse); + g_callbacks().executeCallback(EventCallback_t::monsterPostDropLoot, &EventCallback::monsterPostDropLoot, getMonster(), corpse); } } } @@ -2018,7 +2013,7 @@ void Monster::setNormalCreatureLight() { internalLight = mType->info.light; } -void Monster::drainHealth(Creature* attacker, int32_t damage) { +void Monster::drainHealth(std::shared_ptr attacker, int32_t damage) { Creature::drainHealth(attacker, damage); if (damage > 0 && randomStepping) { @@ -2034,7 +2029,7 @@ void Monster::drainHealth(Creature* attacker, int32_t damage) { void Monster::changeHealth(int32_t healthChange, bool sendHealthChange /* = true*/) { if (mType && !mType->info.soundVector.empty() && mType->info.soundChance >= static_cast(uniform_random(1, 100))) { auto index = uniform_random(0, mType->info.soundVector.size() - 1); - g_game().sendSingleSoundEffect(this->getPosition(), mType->info.soundVector[index], this); + g_game().sendSingleSoundEffect(static_self_cast()->getPosition(), mType->info.soundVector[index], getMonster()); } // In case a player with ignore flag set attacks the monster @@ -2042,7 +2037,7 @@ void Monster::changeHealth(int32_t healthChange, bool sendHealthChange /* = true Creature::changeHealth(healthChange, sendHealthChange); } -bool Monster::challengeCreature(Creature* creature, int targetChangeCooldown) { +bool Monster::challengeCreature(std::shared_ptr creature, int targetChangeCooldown) { if (isSummon()) { return false; } @@ -2052,7 +2047,7 @@ bool Monster::challengeCreature(Creature* creature, int targetChangeCooldown) { challengeFocusDuration = targetChangeCooldown; targetChangeTicks = 0; // Wheel of destiny - Player* player = creature ? creature->getPlayer() : nullptr; + std::shared_ptr player = creature ? creature->getPlayer() : nullptr; if (player && !player->isRemoved()) { player->wheel()->healIfBattleHealingActive(); } @@ -2074,7 +2069,7 @@ bool Monster::changeTargetDistance(int32_t distance, uint32_t duration /* = 1200 targetDistance = distance; if (shouldUpdate) { - g_game().updateCreatureIcon(this); + g_game().updateCreatureIcon(static_self_cast()); } return true; } @@ -2087,7 +2082,7 @@ bool Monster::isImmune(CombatType_t combatType) const { return mType->info.m_damageImmunities[combatTypeToIndex(combatType)]; } -void Monster::getPathSearchParams(const Creature* creature, FindPathParams &fpp) const { +void Monster::getPathSearchParams(std::shared_ptr creature, FindPathParams &fpp) { Creature::getPathSearchParams(creature, fpp); fpp.minTargetDist = 1; @@ -2123,12 +2118,12 @@ void Monster::configureForgeSystem() { if (monsterForgeClassification == ForgeClassifications_t::FORGE_FIENDISH_MONSTER) { setForgeStack(15); setIcon("forge", CreatureIcon(CreatureIconModifications_t::Fiendish, 0 /* don't show stacks on fiends */)); - g_game().updateCreatureIcon(this); + g_game().updateCreatureIcon(static_self_cast()); } else if (monsterForgeClassification == ForgeClassifications_t::FORGE_INFLUENCED_MONSTER) { auto stack = static_cast(normal_random(1, 5)); setForgeStack(stack); setIcon("forge", CreatureIcon(CreatureIconModifications_t::Influenced, stack)); - g_game().updateCreatureIcon(this); + g_game().updateCreatureIcon(static_self_cast()); } // Change health based in stacks @@ -2142,7 +2137,7 @@ void Monster::configureForgeSystem() { const std::string &Eventname = "ForgeSystemMonster"; registerCreatureEvent(Eventname); - g_game().sendUpdateCreature(this); + g_game().sendUpdateCreature(static_self_cast()); } void Monster::clearFiendishStatus() { @@ -2154,8 +2149,8 @@ void Monster::clearFiendishStatus() { healthMax = mType->info.healthMax * mType->getHealthMultiplier(); removeIcon("forge"); - g_game().updateCreatureIcon(this); - g_game().sendUpdateCreature(this); + g_game().updateCreatureIcon(static_self_cast()); + g_game().sendUpdateCreature(static_self_cast()); } bool Monster::canDropLoot() const { diff --git a/src/creatures/monsters/monster.hpp b/src/creatures/monsters/monster.hpp index a479b494a..5f589af0e 100644 --- a/src/creatures/monsters/monster.hpp +++ b/src/creatures/monsters/monster.hpp @@ -17,27 +17,26 @@ class Creature; class Game; class Spawn; -using CreatureHashSet = phmap::flat_hash_set; -using CreatureList = std::list; +using CreatureHashSet = phmap::flat_hash_set>; +using CreatureList = std::list>; + +using CreatureWeakHashMap = phmap::flat_hash_map>; +using CreatureIDList = std::list; class Monster final : public Creature { public: - static Monster* createMonster(const std::string &name); + static std::shared_ptr createMonster(const std::string &name); static int32_t despawnRange; static int32_t despawnRadius; explicit Monster(const std::shared_ptr mType); - ~Monster(); // non-copyable Monster(const Monster &) = delete; Monster &operator=(const Monster &) = delete; - Monster* getMonster() override { - return this; - } - const Monster* getMonster() const override { - return this; + std::shared_ptr getMonster() override { + return static_self_cast(); } void setID() override { @@ -59,7 +58,7 @@ class Monster final : public Creature { const std::string &getNameDescription() const override { return mType->nameDescription; } - std::string getDescription(int32_t) const override { + std::string getDescription(int32_t) override { return strDescription + '.'; } @@ -88,20 +87,22 @@ class Monster final : public Creature { } Faction_t getFaction() const override { - if (master) { - return master->getFaction(); + auto master = getMaster(); + if (getMaster()) { + return getMaster()->getFaction(); } return mType->info.faction; } bool isEnemyFaction(Faction_t faction) const { + auto master = getMaster(); if (master && master->getMonster()) { return master->getMonster()->isEnemyFaction(faction); } return mType->info.enemyFactions.empty() ? false : mType->info.enemyFactions.find(faction) != mType->info.enemyFactions.end(); } - bool isPushable() const override { + bool isPushable() override { return mType->info.pushable && baseSpeed != 0; } bool isAttackable() const override { @@ -141,19 +142,19 @@ class Monster final : public Creature { bool canWalkOnFieldType(CombatType_t combatType) const; void onAttackedCreatureDisappear(bool isLogout) override; - void onCreatureAppear(Creature* creature, bool isLogin) override; - void onRemoveCreature(Creature* creature, bool isLogout) override; - void onCreatureMove(Creature* creature, const Tile* newTile, const Position &newPos, const Tile* oldTile, const Position &oldPos, bool teleport) override; - void onCreatureSay(Creature* creature, SpeakClasses type, const std::string &text) override; + void onCreatureAppear(std::shared_ptr creature, bool isLogin) override; + void onRemoveCreature(std::shared_ptr creature, bool isLogout) override; + void onCreatureMove(std::shared_ptr creature, std::shared_ptr newTile, const Position &newPos, std::shared_ptr oldTile, const Position &oldPos, bool teleport) override; + void onCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text) override; - void drainHealth(Creature* attacker, int32_t damage) override; + void drainHealth(std::shared_ptr attacker, int32_t damage) override; void changeHealth(int32_t healthChange, bool sendHealthChange = true) override; bool getNextStep(Direction &direction, uint32_t &flags) override; - void onFollowCreatureComplete(const Creature* creature) override; + void onFollowCreatureComplete(std::shared_ptr creature) override; void onThink(uint32_t interval) override; - bool challengeCreature(Creature* creature, int targetChangeCooldown) override; + bool challengeCreature(std::shared_ptr creature, int targetChangeCooldown) override; bool changeTargetDistance(int32_t distance, uint32_t duration = 12000); bool isChallenged() const { @@ -184,16 +185,36 @@ class Monster final : public Creature { } bool searchTarget(TargetSearchType_t searchType = TARGETSEARCH_DEFAULT); - bool selectTarget(Creature* creature); - - const CreatureList &getTargetList() const { - return targetList; - } - const CreatureHashSet &getFriendList() const { - return friendList; + bool selectTarget(std::shared_ptr creature); + + CreatureList getTargetList() { + std::list> list; + for (auto it = targetIDList.begin(); it != targetIDList.end();) { + auto cid = *it; + if (auto targetCreature = targetListMap[cid].lock()) { + list.push_back(targetCreature); + ++it; + } else { + it = targetIDList.erase(it); + targetListMap.erase(cid); + } + } + return list; + } + CreatureHashSet getFriendList() { + CreatureHashSet set; + for (auto it = friendList.begin(); it != friendList.end();) { + if (auto friendCreature = it->second.lock()) { + set.insert(friendCreature); + ++it; + } else { + it = friendList.erase(it); + } + } + return set; } - bool isTarget(const Creature* creature) const; + bool isTarget(std::shared_ptr creature); bool isFleeing() const { return !isSummon() && getHealth() <= runAwayHealth && challengeFocusDuration <= 0 && challengeMeleeDuration <= 0; } @@ -252,7 +273,7 @@ class Monster final : public Creature { void clearTargetList(); void clearFriendList(); - BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t &damage, bool checkDefense = false, bool checkArmor = false, bool field = false) override; + BlockType_t blockHit(std::shared_ptr attacker, CombatType_t combatType, int32_t &damage, bool checkDefense = false, bool checkArmor = false, bool field = false) override; static uint32_t monsterAutoID; @@ -305,8 +326,9 @@ class Monster final : public Creature { bool isImmune(CombatType_t combatType) const override; private: - CreatureHashSet friendList; - CreatureList targetList; + CreatureWeakHashMap friendList; + CreatureIDList targetIDList; + CreatureWeakHashMap targetListMap; time_t timeToChangeFiendish = 0; @@ -350,19 +372,19 @@ class Monster final : public Creature { bool hazardDodge = false; bool hazardDamageBoost = false; - void onCreatureEnter(Creature* creature); - void onCreatureLeave(Creature* creature); - void onCreatureFound(Creature* creature, bool pushFront = false); + void onCreatureEnter(std::shared_ptr creature); + void onCreatureLeave(std::shared_ptr creature); + void onCreatureFound(std::shared_ptr creature, bool pushFront = false); void updateLookDirection(); - void addFriend(Creature* creature); - void removeFriend(Creature* creature); - void addTarget(Creature* creature, bool pushFront = false); - void removeTarget(Creature* creature); + void addFriend(std::shared_ptr creature); + void removeFriend(std::shared_ptr creature); + void addTarget(std::shared_ptr creature, bool pushFront = false); + void removeTarget(std::shared_ptr creature); - void death(Creature* lastHitCreature) override; - Item* getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature) override; + void death(std::shared_ptr lastHitCreature) override; + std::shared_ptr getCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature) override; void setIdle(bool idle); void updateIdleStatus(); @@ -373,25 +395,25 @@ class Monster final : public Creature { void onAddCondition(ConditionType_t type) override; void onEndCondition(ConditionType_t type) override; - bool canUseAttack(const Position &pos, const Creature* target) const; + bool canUseAttack(const Position &pos, std::shared_ptr target) const; bool canUseSpell(const Position &pos, const Position &targetPos, const spellBlock_t &sb, uint32_t interval, bool &inRange, bool &resetTicks); - bool getRandomStep(const Position &creaturePos, Direction &direction) const; + bool getRandomStep(const Position &creaturePos, Direction &direction); bool getDanceStep(const Position &creaturePos, Direction &direction, bool keepAttack = true, bool keepDistance = true); bool isInSpawnRange(const Position &pos) const; - bool canWalkTo(Position pos, Direction direction) const; + bool canWalkTo(Position pos, Direction direction); - static bool pushItem(Item* item, const Direction &nextDirection); - static void pushItems(Tile* tile, const Direction &nextDirection); - static bool pushCreature(Creature* creature); - static void pushCreatures(Tile* tile); + static bool pushItem(std::shared_ptr item, const Direction &nextDirection); + static void pushItems(std::shared_ptr tile, const Direction &nextDirection); + static bool pushCreature(std::shared_ptr creature); + static void pushCreatures(std::shared_ptr tile); void onThinkTarget(uint32_t interval); void onThinkYell(uint32_t interval); void onThinkDefense(uint32_t interval); void onThinkSound(uint32_t interval); - bool isFriend(const Creature* creature) const; - bool isOpponent(const Creature* creature) const; + bool isFriend(std::shared_ptr creature) const; + bool isOpponent(std::shared_ptr creature) const; uint64_t getLostExperience() const override { return skillLoss ? mType->info.experience : 0; @@ -399,8 +421,8 @@ class Monster final : public Creature { uint16_t getLookCorpse() const override { return mType->info.lookcorpse; } - void dropLoot(Container* corpse, Creature* lastHitCreature) override; - void getPathSearchParams(const Creature* creature, FindPathParams &fpp) const override; + void dropLoot(std::shared_ptr corpse, std::shared_ptr lastHitCreature) override; + void getPathSearchParams(std::shared_ptr creature, FindPathParams &fpp) override; bool useCacheMap() const override { return !randomStepping; } diff --git a/src/creatures/monsters/monsters.cpp b/src/creatures/monsters/monsters.cpp index 6bba74225..eb74178c0 100644 --- a/src/creatures/monsters/monsters.cpp +++ b/src/creatures/monsters/monsters.cpp @@ -42,8 +42,8 @@ bool MonsterType::canSpawn(const Position &pos) { return canSpawn; } -ConditionDamage* Monsters::getDamageCondition(ConditionType_t conditionType, int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval) { - ConditionDamage* condition = static_cast(Condition::createCondition(CONDITIONID_COMBAT, conditionType, 0, 0)); +std::shared_ptr Monsters::getDamageCondition(ConditionType_t conditionType, int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval) { + std::shared_ptr condition = Condition::createCondition(CONDITIONID_COMBAT, conditionType, 0, 0)->static_self_cast(); condition->setParam(CONDITION_PARAM_TICKINTERVAL, tickInterval); condition->setParam(CONDITION_PARAM_MINVALUE, minDamage); condition->setParam(CONDITION_PARAM_MAXVALUE, maxDamage); @@ -83,7 +83,7 @@ bool Monsters::deserializeSpell(const std::shared_ptr spell, spell if (spell->length > 0) { spell->spread = std::max(0, spell->spread); - AreaCombat* area = new AreaCombat(); + auto area = std::make_unique(); area->setupArea(spell->length, spell->spread); combatPtr->setArea(area); @@ -91,7 +91,7 @@ bool Monsters::deserializeSpell(const std::shared_ptr spell, spell } if (spell->radius > 0) { - AreaCombat* area = new AreaCombat(); + auto area = std::make_unique(); area->setupArea(spell->radius); combatPtr->setArea(area); } @@ -143,7 +143,7 @@ bool Monsters::deserializeSpell(const std::shared_ptr spell, spell conditionType = CONDITION_PARALYZE; } - ConditionSpeed* condition = static_cast(Condition::createCondition(CONDITIONID_COMBAT, conditionType, duration, 0)); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_COMBAT, conditionType, duration, 0)->static_self_cast(); condition->setFormulaVars(speedChange / 1000.0, 0, speedChange / 1000.0, 0); combatPtr->addCondition(condition); } else if (spellName == "outfit") { @@ -153,7 +153,7 @@ bool Monsters::deserializeSpell(const std::shared_ptr spell, spell duration = spell->duration; } - ConditionOutfit* condition = static_cast(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)->static_self_cast(); if (spell->outfitMonster != "") { condition->setLazyMonsterOutfit(spell->outfitMonster); @@ -177,7 +177,7 @@ bool Monsters::deserializeSpell(const std::shared_ptr spell, spell duration = spell->duration; } - Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0); combatPtr->setParam(COMBAT_PARAM_AGGRESSIVE, 0); combatPtr->addCondition(condition); } else if (spellName == "drunk") { @@ -187,7 +187,7 @@ bool Monsters::deserializeSpell(const std::shared_ptr spell, spell duration = spell->duration; } - Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, 0); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, 0); combatPtr->addCondition(condition); } else if (spellName == "soulwars fear" || spellName == "fear") { int32_t duration = 6000; @@ -247,7 +247,7 @@ bool Monsters::deserializeSpell(const std::shared_ptr spell, spell maxDamage = minDamage; } - Condition* condition = getDamageCondition(spell->conditionType, maxDamage, minDamage, startDamage, tickInterval); + std::shared_ptr condition = getDamageCondition(spell->conditionType, maxDamage, minDamage, startDamage, tickInterval); combatPtr->addCondition(condition); } diff --git a/src/creatures/monsters/monsters.hpp b/src/creatures/monsters/monsters.hpp index ceea9d44a..a13792fd2 100644 --- a/src/creatures/monsters/monsters.hpp +++ b/src/creatures/monsters/monsters.hpp @@ -272,7 +272,7 @@ class Monsters { std::map> monsters; private: - ConditionDamage* getDamageCondition(ConditionType_t conditionType, int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval); + std::shared_ptr getDamageCondition(ConditionType_t conditionType, int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval); }; constexpr auto g_monsters = Monsters::getInstance; diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index 83793f7a1..045038e6e 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -149,16 +149,15 @@ void SpawnMonster::startSpawnMonsterCheck() { SpawnMonster::~SpawnMonster() { for (const auto &it : spawnedMonsterMap) { - Monster* monster = it.second; + std::shared_ptr monster = it.second; monster->setSpawnMonster(nullptr); - monster->decrementReferenceCounter(); } } bool SpawnMonster::findPlayer(const Position &pos) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, pos, false, true); - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { if (!spectator->getPlayer()->hasFlag(PlayerFlags_t::IgnoredByMonsters)) { return true; } @@ -171,23 +170,21 @@ bool SpawnMonster::isInSpawnMonsterZone(const Position &pos) { } bool SpawnMonster::spawnMonster(uint32_t spawnMonsterId, const std::shared_ptr monsterType, const Position &pos, Direction dir, bool startup /*= false*/) { - std::unique_ptr monster_ptr(new Monster(monsterType)); + auto monster = std::make_shared(monsterType); if (startup) { // No need to send out events to the surrounding since there is no one out there to listen! - if (!g_game().internalPlaceCreature(monster_ptr.get(), pos, true)) { + if (!g_game().internalPlaceCreature(monster, pos, true)) { return false; } } else { - if (!g_game().placeCreature(monster_ptr.get(), pos, false, true)) { + if (!g_game().placeCreature(monster, pos, false, true)) { return false; } } - Monster* monster = monster_ptr.release(); monster->setDirection(dir); monster->setSpawnMonster(this); monster->setMasterPos(pos); - monster->incrementReferenceCounter(); spawnedMonsterMap.insert(spawned_pair(spawnMonsterId, monster)); spawnMonsterMap[spawnMonsterId].lastSpawn = OTSYS_TIME(); @@ -242,7 +239,7 @@ void SpawnMonster::checkSpawnMonster() { } if (spawnedMonsterMap.size() < spawnMonsterMap.size()) { - checkSpawnMonsterEvent = g_scheduler().addEvent(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this), __FUNCTION__); + checkSpawnMonsterEvent = g_scheduler().addEvent(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this), "SpawnMonster::checkSpawnMonster"); } } @@ -251,7 +248,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(1400, std::bind(&SpawnMonster::scheduleSpawn, this, spawnMonsterId, sb, interval - NONBLOCKABLE_SPAWN_MONSTER_INTERVAL), __FUNCTION__); + g_scheduler().addEvent(1400, std::bind(&SpawnMonster::scheduleSpawn, this, spawnMonsterId, sb, interval - NONBLOCKABLE_SPAWN_MONSTER_INTERVAL), "SpawnMonster::scheduleSpawn"); } } @@ -259,10 +256,9 @@ void SpawnMonster::cleanup() { auto it = spawnedMonsterMap.begin(); while (it != spawnedMonsterMap.end()) { uint32_t spawnMonsterId = it->first; - Monster* monster = it->second; + std::shared_ptr monster = it->second; if (monster->isRemoved()) { spawnMonsterMap[spawnMonsterId].lastSpawn = OTSYS_TIME(); - monster->decrementReferenceCounter(); it = spawnedMonsterMap.erase(it); } else { ++it; @@ -291,10 +287,9 @@ bool SpawnMonster::addMonster(const std::string &name, const Position &pos, Dire return true; } -void SpawnMonster::removeMonster(Monster* monster) { +void SpawnMonster::removeMonster(std::shared_ptr monster) { for (auto it = spawnedMonsterMap.begin(), end = spawnedMonsterMap.end(); it != end; ++it) { if (it->second == monster) { - monster->decrementReferenceCounter(); spawnedMonsterMap.erase(it); break; } diff --git a/src/creatures/monsters/spawns/spawn_monster.hpp b/src/creatures/monsters/spawns/spawn_monster.hpp index 17ad00a9a..3c361f956 100644 --- a/src/creatures/monsters/spawns/spawn_monster.hpp +++ b/src/creatures/monsters/spawns/spawn_monster.hpp @@ -34,7 +34,7 @@ class SpawnMonster { SpawnMonster &operator=(const SpawnMonster &) = delete; bool addMonster(const std::string &name, const Position &pos, Direction dir, uint32_t interval); - void removeMonster(Monster* monster); + void removeMonster(std::shared_ptr monster); uint32_t getInterval() const { return interval; @@ -49,7 +49,7 @@ class SpawnMonster { private: // map of the spawned creatures - using SpawnedMap = std::multimap; + using SpawnedMap = std::multimap>; using spawned_pair = SpawnedMap::value_type; SpawnedMap spawnedMonsterMap; diff --git a/src/creatures/npcs/npc.cpp b/src/creatures/npcs/npc.cpp index 9d95a2e91..ab9ca5795 100644 --- a/src/creatures/npcs/npc.cpp +++ b/src/creatures/npcs/npc.cpp @@ -22,15 +22,15 @@ int32_t Npc::despawnRadius; uint32_t Npc::npcAutoID = 0x80000000; -Npc* Npc::createNpc(const std::string &name) { - NpcType* npcType = g_npcs().getNpcType(name); +std::shared_ptr Npc::createNpc(const std::string &name) { + const auto &npcType = g_npcs().getNpcType(name); if (!npcType) { return nullptr; } - return new Npc(npcType); + return std::make_shared(npcType); } -Npc::Npc(NpcType* npcType) : +Npc::Npc(const std::shared_ptr &npcType) : Creature(), strDescription(npcType->nameDescription), npcType(npcType) { @@ -55,21 +55,21 @@ Npc::~Npc() { } void Npc::addList() { - g_game().addNpc(this); + g_game().addNpc(static_self_cast()); } void Npc::removeList() { - g_game().removeNpc(this); + g_game().removeNpc(static_self_cast()); } -bool Npc::canInteract(const Position &pos, uint32_t range /* = 4 */) const { +bool Npc::canInteract(const Position &pos, uint32_t range /* = 4 */) { if (pos.z != getPosition().z) { return false; } return Creature::canSee(getPosition(), pos, range, range); } -void Npc::onCreatureAppear(Creature* creature, bool isLogin) { +void Npc::onCreatureAppear(std::shared_ptr creature, bool isLogin) { Creature::onCreatureAppear(creature, isLogin); if (auto player = creature->getPlayer()) { @@ -77,9 +77,9 @@ void Npc::onCreatureAppear(Creature* creature, bool isLogin) { } // onCreatureAppear(self, creature) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.creatureAppearEvent)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushCreature(creature); } @@ -88,13 +88,13 @@ void Npc::onCreatureAppear(Creature* creature, bool isLogin) { } } -void Npc::onRemoveCreature(Creature* creature, bool isLogout) { +void Npc::onRemoveCreature(std::shared_ptr creature, bool isLogout) { Creature::onRemoveCreature(creature, isLogout); // onCreatureDisappear(self, creature) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.creatureDisappearEvent)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushCreature(creature); } @@ -110,16 +110,16 @@ void Npc::onRemoveCreature(Creature* creature, bool isLogout) { spawnNpc->startSpawnNpcCheck(); } - shopPlayerSet.clear(); + shopPlayerMap.clear(); } -void Npc::onCreatureMove(Creature* creature, const Tile* newTile, const Position &newPos, const Tile* oldTile, const Position &oldPos, bool teleport) { +void Npc::onCreatureMove(std::shared_ptr creature, std::shared_ptr newTile, const Position &newPos, std::shared_ptr oldTile, const Position &oldPos, bool teleport) { Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport); // onCreatureMove(self, creature, oldPosition, newPosition) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.creatureMoveEvent)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushCreature(creature); callback.pushPosition(oldPos); callback.pushPosition(newPos); @@ -129,7 +129,7 @@ void Npc::onCreatureMove(Creature* creature, const Tile* newTile, const Position return; } - if (creature == this && !canInteract(oldPos)) { + if (creature == getNpc() && !canInteract(oldPos)) { resetPlayerInteractions(); closeAllShopWindows(); } @@ -141,13 +141,13 @@ void Npc::onCreatureMove(Creature* creature, const Tile* newTile, const Position void Npc::manageIdle() { if (creatureCheck && playerSpectators.empty()) { - Game::removeCreatureCheck(this); + Game::removeCreatureCheck(static_self_cast()); } else if (!creatureCheck) { - g_game().addCreatureCheck(this); + g_game().addCreatureCheck(static_self_cast()); } } -void Npc::onPlayerAppear(Player* player) { +void Npc::onPlayerAppear(std::shared_ptr player) { if (player->hasFlag(PlayerFlags_t::IgnoredByNpcs) || playerSpectators.contains(player)) { return; } @@ -155,7 +155,7 @@ void Npc::onPlayerAppear(Player* player) { manageIdle(); } -void Npc::onPlayerDisappear(Player* player) { +void Npc::onPlayerDisappear(std::shared_ptr player) { removePlayerInteraction(player); if (!player->hasFlag(PlayerFlags_t::IgnoredByNpcs) && playerSpectators.contains(player)) { playerSpectators.erase(player); @@ -163,7 +163,7 @@ void Npc::onPlayerDisappear(Player* player) { } } -void Npc::onCreatureSay(Creature* creature, SpeakClasses type, const std::string &text) { +void Npc::onCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text) { Creature::onCreatureSay(creature, type, text); if (!creature->getPlayer()) { @@ -171,9 +171,9 @@ void Npc::onCreatureSay(Creature* creature, SpeakClasses type, const std::string } // onCreatureSay(self, creature, type, message) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.creatureSayEvent)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushCreature(creature); callback.pushNumber(type); callback.pushString(text); @@ -195,7 +195,7 @@ void Npc::onThinkSound(uint32_t interval) { if (!npcType->info.soundVector.empty() && (npcType->info.soundChance >= static_cast(uniform_random(1, 100)))) { auto index = uniform_random(0, npcType->info.soundVector.size() - 1); - g_game().sendSingleSoundEffect(this->getPosition(), npcType->info.soundVector[index], this); + g_game().sendSingleSoundEffect(static_self_cast()->getPosition(), npcType->info.soundVector[index], getNpc()); } } } @@ -204,9 +204,9 @@ void Npc::onThink(uint32_t interval) { Creature::onThink(interval); // onThink(self, interval) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.thinkEvent)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushNumber(interval); } @@ -215,11 +215,11 @@ void Npc::onThink(uint32_t interval) { } if (!npcType->canSpawn(position)) { - g_game().removeCreature(this); + g_game().removeCreature(static_self_cast()); } if (!isInSpawnRange(position)) { - g_game().internalTeleport(this, masterPos); + g_game().internalTeleport(static_self_cast(), masterPos); resetPlayerInteractions(); closeAllShopWindows(); } @@ -231,7 +231,7 @@ void Npc::onThink(uint32_t interval) { } } -void Npc::onPlayerBuyItem(Player* player, uint16_t itemId, uint8_t subType, uint16_t amount, bool ignore, bool inBackpacks) { +void Npc::onPlayerBuyItem(std::shared_ptr player, uint16_t itemId, uint8_t subType, uint16_t amount, bool ignore, bool inBackpacks) { if (player == nullptr) { g_logger().error("[Npc::onPlayerBuyItem] - Player is nullptr"); return; @@ -246,7 +246,7 @@ void Npc::onPlayerBuyItem(Player* player, uint16_t itemId, uint8_t subType, uint uint32_t shoppingBagPrice = 20; uint32_t shoppingBagSlots = 20; const ItemType &itemType = Item::items[itemId]; - if (const Tile* tile = ignore ? player->getTile() : nullptr; tile) { + if (std::shared_ptr tile = ignore ? player->getTile() : nullptr; tile) { double slotsNedeed = 0; if (itemType.stackable) { slotsNedeed = inBackpacks ? std::ceil(std::ceil(static_cast(amount) / 100) / shoppingBagSlots) : std::ceil(static_cast(amount) / 100); @@ -287,9 +287,9 @@ void Npc::onPlayerBuyItem(Player* player, uint16_t itemId, uint8_t subType, uint } // npc:onBuyItem(player, itemId, subType, amount, ignore, inBackpacks, totalCost) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.playerBuyEvent)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushCreature(player); callback.pushNumber(itemId); callback.pushNumber(subType); @@ -304,13 +304,13 @@ void Npc::onPlayerBuyItem(Player* player, uint16_t itemId, uint8_t subType, uint } } -void Npc::onPlayerSellItem(Player* player, uint16_t itemId, uint8_t subType, uint16_t amount, bool ignore) { +void Npc::onPlayerSellItem(std::shared_ptr player, uint16_t itemId, uint8_t subType, uint16_t amount, bool ignore) { uint64_t totalPrice = 0; onPlayerSellItem(player, itemId, subType, amount, ignore, totalPrice); } void Npc::onPlayerSellAllLoot(uint32_t playerId, uint16_t itemId, bool ignore, uint64_t totalPrice) { - Player* player = g_game().getPlayerByID(playerId); + std::shared_ptr player = g_game().getPlayerByID(playerId); if (!player) { return; } @@ -359,7 +359,7 @@ void Npc::onPlayerSellAllLoot(uint32_t playerId, uint16_t itemId, bool ignore, u } } -void Npc::onPlayerSellItem(Player* player, uint16_t itemId, uint8_t subType, uint16_t amount, bool ignore, uint64_t &totalPrice, Cylinder* parent /*= nullptr*/) { +void Npc::onPlayerSellItem(std::shared_ptr player, uint16_t itemId, uint8_t subType, uint16_t amount, bool ignore, uint64_t &totalPrice, std::shared_ptr parent /*= nullptr*/) { if (!player) { return; } @@ -417,16 +417,16 @@ void Npc::onPlayerSellItem(Player* player, uint16_t itemId, uint8_t subType, uin g_game().addMoney(player, totalCost); } } else { - Item* newItem = Item::CreateItem(getCurrency(), totalCost); + std::shared_ptr newItem = Item::CreateItem(getCurrency(), totalCost); if (newItem) { g_game().internalPlayerAddItem(player, newItem, true); } } // npc:onSellItem(player, itemId, subType, amount, ignore, itemName, totalCost) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.playerSellEvent)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushCreature(player); callback.pushNumber(itemType.id); callback.pushNumber(subType); @@ -441,16 +441,16 @@ void Npc::onPlayerSellItem(Player* player, uint16_t itemId, uint8_t subType, uin } } -void Npc::onPlayerCheckItem(Player* player, uint16_t itemId, uint8_t subType) { +void Npc::onPlayerCheckItem(std::shared_ptr player, uint16_t itemId, uint8_t subType) { if (!player) { return; } const ItemType &itemType = Item::items[itemId]; // onPlayerCheckItem(self, player, itemId, subType) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.playerLookEvent)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushCreature(player); callback.pushNumber(itemId); callback.pushNumber(subType); @@ -461,16 +461,16 @@ void Npc::onPlayerCheckItem(Player* player, uint16_t itemId, uint8_t subType) { } } -void Npc::onPlayerCloseChannel(Creature* creature) { - Player* player = creature->getPlayer(); +void Npc::onPlayerCloseChannel(std::shared_ptr creature) { + std::shared_ptr player = creature->getPlayer(); if (!player) { return; } // onPlayerCloseChannel(npc, player) - CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, this); + CreatureCallback callback = CreatureCallback(npcType->info.scriptInterface, getNpc()); if (callback.startScriptInterface(npcType->info.playerCloseChannel)) { - callback.pushSpecificCreature(this); + callback.pushSpecificCreature(static_self_cast()); callback.pushCreature(player); } @@ -495,9 +495,9 @@ void Npc::onThinkYell(uint32_t interval) { const voiceBlock_t &vb = npcType->info.voiceVector[index]; if (vb.yellText) { - g_game().internalCreatureSay(this, TALKTYPE_YELL, vb.text, false); + g_game().internalCreatureSay(static_self_cast(), TALKTYPE_YELL, vb.text, false); } else { - g_game().internalCreatureSay(this, TALKTYPE_SAY, vb.text, false); + g_game().internalCreatureSay(static_self_cast(), TALKTYPE_SAY, vb.text, false); } } } @@ -573,7 +573,7 @@ bool Npc::isInSpawnRange(const Position &pos) const { } void Npc::setPlayerInteraction(uint32_t playerId, uint16_t topicId /*= 0*/) { - Creature* creature = g_game().getCreatureByID(playerId); + std::shared_ptr creature = g_game().getCreatureByID(playerId); if (!creature) { return; } @@ -583,7 +583,7 @@ void Npc::setPlayerInteraction(uint32_t playerId, uint16_t topicId /*= 0*/) { playerInteractions[playerId] = topicId; } -void Npc::removePlayerInteraction(Player* player) { +void Npc::removePlayerInteraction(std::shared_ptr player) { if (playerInteractions.contains(player->getID())) { playerInteractions.erase(player->getID()); player->closeShopWindow(true); @@ -594,7 +594,7 @@ void Npc::resetPlayerInteractions() { playerInteractions.clear(); } -bool Npc::canWalkTo(const Position &fromPos, Direction dir) const { +bool Npc::canWalkTo(const Position &fromPos, Direction dir) { if (npcType->info.walkRadius == 0) { return false; } @@ -604,8 +604,8 @@ bool Npc::canWalkTo(const Position &fromPos, Direction dir) const { return false; } - const Tile* toTile = g_game().map.getTile(toPos); - if (!toTile || toTile->queryAdd(0, *this, 1, 0) != RETURNVALUE_NOERROR) { + std::shared_ptr toTile = g_game().map.getTile(toPos); + if (!toTile || toTile->queryAdd(0, getNpc(), 1, 0) != RETURNVALUE_NOERROR) { return false; } @@ -624,7 +624,7 @@ bool Npc::getNextStep(Direction &nextDirection, uint32_t &flags) { return Creature::getNextStep(nextDirection, flags); } -bool Npc::getRandomStep(Direction &moveDirection) const { +bool Npc::getRandomStep(Direction &moveDirection) { static std::vector directionvector { Direction::DIRECTION_NORTH, Direction::DIRECTION_WEST, @@ -643,26 +643,31 @@ bool Npc::getRandomStep(Direction &moveDirection) const { return false; } -void Npc::addShopPlayer(Player* player) { - shopPlayerSet.insert(player); +void Npc::addShopPlayer(const std::shared_ptr &player) { + if (!player) { + return; + } + shopPlayerMap.try_emplace(player->getID(), player); } -void Npc::removeShopPlayer(Player* player) { - if (player) { - shopPlayerSet.erase(player); +void Npc::removeShopPlayer(const std::shared_ptr &player) { + if (!player) { + return; } + shopPlayerMap.erase(player->getID()); } void Npc::closeAllShopWindows() { - for (auto shopPlayer : shopPlayerSet) { + for (auto &[_, playerPtr] : shopPlayerMap) { + auto shopPlayer = playerPtr.lock(); if (shopPlayer) { shopPlayer->closeShopWindow(); } } - shopPlayerSet.clear(); + shopPlayerMap.clear(); } -void Npc::handlePlayerMove(Player* player, const Position &newPos) { +void Npc::handlePlayerMove(std::shared_ptr player, const Position &newPos) { if (!canInteract(newPos)) { removePlayerInteraction(player); } diff --git a/src/creatures/npcs/npc.hpp b/src/creatures/npcs/npc.hpp index e0c8c7286..45941706f 100644 --- a/src/creatures/npcs/npc.hpp +++ b/src/creatures/npcs/npc.hpp @@ -10,6 +10,7 @@ #pragma once #include "creatures/npcs/npcs.hpp" +#include "creatures/players/player.hpp" #include "declarations.hpp" #include "items/tile.hpp" #include "lib/di/container.hpp" @@ -20,27 +21,24 @@ class SpawnNpc; class Npc final : public Creature { public: - static Npc* createNpc(const std::string &name); + static std::shared_ptr createNpc(const std::string &name); static int32_t despawnRange; static int32_t despawnRadius; - explicit Npc(NpcType* npcType); + explicit Npc(const std::shared_ptr &npcType); Npc() = default; ~Npc(); // Singleton - ensures we don't accidentally copy it Npc(const Npc &) = delete; - void operator=(const Npc &) = delete; + void operator=(const std::shared_ptr &) = delete; static Npc &getInstance() { return inject(); } - Npc* getNpc() override { - return this; - } - const Npc* getNpc() const override { - return this; + std::shared_ptr getNpc() override { + return static_self_cast(); } void setID() override { @@ -62,7 +60,7 @@ class Npc final : public Creature { const std::string &getNameDescription() const override { return npcType->nameDescription; } - std::string getDescription(int32_t) const override { + std::string getDescription(int32_t) override { return strDescription + '.'; } @@ -99,7 +97,7 @@ class Npc final : public Creature { return npcType->info.shopItemVector; } - bool isPushable() const override { + bool isPushable() override { return npcType->info.pushable; } @@ -107,19 +105,19 @@ class Npc final : public Creature { return false; } - bool canInteract(const Position &pos, uint32_t range = 4) const; + bool canInteract(const Position &pos, uint32_t range = 4); bool canSeeInvisibility() const override { return true; } RespawnType getRespawnType() const { return npcType->info.respawnType; } - void setSpawnNpc(SpawnNpc* newSpawn) { - this->spawnNpc = newSpawn; + void setSpawnNpc(const std::shared_ptr &newSpawn) { + spawnNpc = newSpawn; } void setPlayerInteraction(uint32_t playerId, uint16_t topicId = 0); - void removePlayerInteraction(Player* player); + void removePlayerInteraction(std::shared_ptr player); void resetPlayerInteractions(); bool isInteractingWithPlayer(uint32_t playerId) { @@ -137,29 +135,29 @@ class Npc final : public Creature { return it->second == topicId; } - void onCreatureAppear(Creature* creature, bool isLogin) override; - void onRemoveCreature(Creature* creature, bool isLogout) override; - void onCreatureMove(Creature* creature, const Tile* newTile, const Position &newPos, const Tile* oldTile, const Position &oldPos, bool teleport) override; - void onCreatureSay(Creature* creature, SpeakClasses type, const std::string &text) override; + void onCreatureAppear(std::shared_ptr creature, bool isLogin) override; + void onRemoveCreature(std::shared_ptr creature, bool isLogout) override; + void onCreatureMove(std::shared_ptr creature, std::shared_ptr newTile, const Position &newPos, std::shared_ptr oldTile, const Position &oldPos, bool teleport) override; + void onCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text) override; void onThink(uint32_t interval) override; - void onPlayerBuyItem(Player* player, uint16_t itemid, uint8_t count, uint16_t amount, bool ignore, bool inBackpacks); + void onPlayerBuyItem(std::shared_ptr player, uint16_t itemid, uint8_t count, uint16_t amount, bool ignore, bool inBackpacks); void onPlayerSellAllLoot(uint32_t playerId, uint16_t itemid, bool ignore, uint64_t totalPrice); - void onPlayerSellItem(Player* player, uint16_t itemid, uint8_t count, uint16_t amount, bool ignore); - void onPlayerSellItem(Player* player, uint16_t itemid, uint8_t count, uint16_t amount, bool ignore, uint64_t &totalPrice, Cylinder* parent = nullptr); - void onPlayerCheckItem(Player* player, uint16_t itemid, uint8_t count); - void onPlayerCloseChannel(Creature* creature); + void onPlayerSellItem(std::shared_ptr player, uint16_t itemid, uint8_t count, uint16_t amount, bool ignore); + void onPlayerSellItem(std::shared_ptr player, uint16_t itemid, uint8_t count, uint16_t amount, bool ignore, uint64_t &totalPrice, std::shared_ptr parent = nullptr); + void onPlayerCheckItem(std::shared_ptr player, uint16_t itemid, uint8_t count); + void onPlayerCloseChannel(std::shared_ptr creature); void onPlacedCreature() override; - bool canWalkTo(const Position &fromPos, Direction dir) const; + bool canWalkTo(const Position &fromPos, Direction dir); bool getNextStep(Direction &nextDirection, uint32_t &flags) override; - bool getRandomStep(Direction &moveDirection) const; + bool getRandomStep(Direction &moveDirection); void setNormalCreatureLight() override { internalLight = npcType->info.light; } - void addShopPlayer(Player* player); - void removeShopPlayer(Player* player); + void addShopPlayer(const std::shared_ptr &player); + void removeShopPlayer(const std::shared_ptr &player); void closeAllShopWindows(); static uint32_t npcAutoID; @@ -177,10 +175,10 @@ class Npc final : public Creature { std::map playerInteractions; - std::set shopPlayerSet; + phmap::flat_hash_map> shopPlayerMap; - NpcType* npcType; - SpawnNpc* spawnNpc = nullptr; + std::shared_ptr npcType; + std::shared_ptr spawnNpc; uint8_t speechBubble; @@ -196,10 +194,10 @@ class Npc final : public Creature { friend class LuaScriptInterface; friend class Map; - void onPlayerAppear(Player* player); - void onPlayerDisappear(Player* player); + void onPlayerAppear(std::shared_ptr player); + void onPlayerDisappear(std::shared_ptr player); void manageIdle(); - void handlePlayerMove(Player* player, const Position &newPos); + void handlePlayerMove(std::shared_ptr player, const Position &newPos); void loadPlayerSpectators(); }; diff --git a/src/creatures/npcs/npcs.cpp b/src/creatures/npcs/npcs.cpp index d3c1fff7a..432b0adbe 100644 --- a/src/creatures/npcs/npcs.cpp +++ b/src/creatures/npcs/npcs.cpp @@ -73,7 +73,7 @@ bool NpcType::loadCallback(LuaScriptInterface* scriptInterface) { return true; } -void NpcType::loadShop(NpcType* npcType, ShopBlock shopBlock) { +void NpcType::loadShop(const std::shared_ptr &npcType, ShopBlock shopBlock) { ItemType &iType = Item::items.getItemType(shopBlock.itemId); // Registering item prices globaly. @@ -134,7 +134,7 @@ bool Npcs::reload() { return false; } -NpcType* Npcs::getNpcType(const std::string &name, bool create /* = false*/) { +std::shared_ptr Npcs::getNpcType(const std::string &name, bool create /* = false*/) { std::string key = asLowerCaseString(name); auto it = npcs.find(key); @@ -142,11 +142,5 @@ NpcType* Npcs::getNpcType(const std::string &name, bool create /* = false*/) { return it->second; } - if (!create) { - return nullptr; - } - - npcs[key] = new NpcType(name); - - return npcs[key]; + return create ? npcs[key] = std::make_shared(name) : nullptr; } diff --git a/src/creatures/npcs/npcs.hpp b/src/creatures/npcs/npcs.hpp index 4b8f59186..d836e6e92 100644 --- a/src/creatures/npcs/npcs.hpp +++ b/src/creatures/npcs/npcs.hpp @@ -23,7 +23,7 @@ class Shop { ShopBlock shopBlock; }; -class NpcType { +class NpcType : public SharedObject { struct NpcInfo { LuaScriptInterface* scriptInterface; @@ -86,7 +86,7 @@ class NpcType { std::string nameDescription; NpcInfo info; - void loadShop(NpcType* npcType, ShopBlock shopBlock); + void loadShop(const std::shared_ptr &npcType, ShopBlock shopBlock); bool loadCallback(LuaScriptInterface* scriptInterface); bool canSpawn(const Position &pos); @@ -103,7 +103,7 @@ class Npcs { return inject(); } - NpcType* getNpcType(const std::string &name, bool create = false); + std::shared_ptr getNpcType(const std::string &name, bool create = false); // Reset npcs informations on reload bool load(bool loadLibs = true, bool loadNpcs = true, bool reloading = false) const; @@ -111,7 +111,7 @@ class Npcs { private: std::unique_ptr scriptInterface; - std::map npcs; + std::map> npcs; }; constexpr auto g_npcs = Npcs::getInstance; diff --git a/src/creatures/npcs/spawns/spawn_npc.cpp b/src/creatures/npcs/spawns/spawn_npc.cpp index 20ae9ba91..c7605f36c 100644 --- a/src/creatures/npcs/spawns/spawn_npc.cpp +++ b/src/creatures/npcs/spawns/spawn_npc.cpp @@ -56,8 +56,7 @@ bool SpawnsNpc::loadFromXml(const std::string &fileNpcName) { continue; } - spawnNpcList.emplace_front(centerPos, radius); - SpawnNpc &spawnNpc = spawnNpcList.front(); + const auto &spawnNpc = spawnNpcList.emplace_front(std::make_shared(centerPos, radius)); for (auto childNode : spawnNode.children()) { if (strcasecmp(childNode.name(), "npc") == 0) { @@ -84,7 +83,7 @@ bool SpawnsNpc::loadFromXml(const std::string &fileNpcName) { ); int64_t interval = pugi::cast(childNode.attribute("spawntime").value()) * 1000; if (interval >= MINSPAWN_INTERVAL && interval <= MAXSPAWN_INTERVAL) { - spawnNpc.addNpc(nameAttribute.as_string(), pos, dir, static_cast(interval)); + spawnNpc->addNpc(nameAttribute.as_string(), pos, dir, static_cast(interval)); } else { if (interval <= MINSPAWN_INTERVAL) { g_logger().warn("[SpawnsNpc::loadFromXml] - {} {} spawntime can not be less than {} seconds", nameAttribute.as_string(), pos.toString(), MINSPAWN_INTERVAL / 1000); @@ -103,16 +102,16 @@ void SpawnsNpc::startup() { return; } - for (SpawnNpc &spawnNpc : spawnNpcList) { - spawnNpc.startup(); + for (const auto &spawnNpc : spawnNpcList) { + spawnNpc->startup(); } setStarted(true); } void SpawnsNpc::clear() { - for (SpawnNpc &spawnNpc : spawnNpcList) { - spawnNpc.stopEvent(); + for (const auto &spawnNpc : spawnNpcList) { + spawnNpc->stopEvent(); } spawnNpcList.clear(); @@ -137,16 +136,14 @@ void SpawnNpc::startSpawnNpcCheck() { SpawnNpc::~SpawnNpc() { for (const auto &it : spawnedNpcMap) { - Npc* npc = it.second; - npc->setSpawnNpc(nullptr); - npc->decrementReferenceCounter(); + it.second->setSpawnNpc(nullptr); } } bool SpawnNpc::findPlayer(const Position &pos) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, pos, false, true); - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { if (!spectator->getPlayer()->hasFlag(PlayerFlags_t::IgnoredByNpcs)) { return true; } @@ -158,24 +155,22 @@ bool SpawnNpc::isInSpawnNpcZone(const Position &pos) { return SpawnsNpc::isInZone(centerPos, radius, pos); } -bool SpawnNpc::spawnNpc(uint32_t spawnId, NpcType* npcType, const Position &pos, Direction dir, bool startup /*= false*/) { - std::unique_ptr npc_ptr(new Npc(npcType)); +bool SpawnNpc::spawnNpc(uint32_t spawnId, const std::shared_ptr &npcType, const Position &pos, Direction dir, bool startup /*= false*/) { + auto npc = std::make_shared(npcType); if (startup) { // No need to send out events to the surrounding since there is no one out there to listen! - if (!g_game().internalPlaceCreature(npc_ptr.get(), pos, true, false)) { + if (!g_game().internalPlaceCreature(npc, pos, true, false)) { return false; } } else { - if (!g_game().placeCreature(npc_ptr.get(), pos, false, true)) { + if (!g_game().placeCreature(npc, pos, false, true)) { return false; } } - Npc* npc = npc_ptr.release(); npc->setDirection(dir); - npc->setSpawnNpc(this); + npc->setSpawnNpc(static_self_cast()); npc->setMasterPos(pos); - npc->incrementReferenceCounter(); spawnedNpcMap.insert(spawned_pair(spawnId, npc)); spawnNpcMap[spawnId].lastSpawnNpc = OTSYS_TIME(); @@ -238,10 +233,9 @@ void SpawnNpc::cleanup() { auto it = spawnedNpcMap.begin(); while (it != spawnedNpcMap.end()) { uint32_t spawnId = it->first; - Npc* npc = it->second; + auto npc = it->second; if (npc->isRemoved()) { spawnNpcMap[spawnId].lastSpawnNpc = OTSYS_TIME(); - npc->decrementReferenceCounter(); it = spawnedNpcMap.erase(it); } else { ++it; @@ -250,7 +244,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); + const auto &npcType = g_npcs().getNpcType(name); if (!npcType) { g_logger().error("Can not find {}", name); return false; @@ -270,10 +264,9 @@ bool SpawnNpc::addNpc(const std::string &name, const Position &pos, Direction di return true; } -void SpawnNpc::removeNpc(Npc* npc) { +void SpawnNpc::removeNpc(std::shared_ptr npc) { for (auto it = spawnedNpcMap.begin(), end = spawnedNpcMap.end(); it != end; ++it) { if (it->second == npc) { - npc->decrementReferenceCounter(); spawnedNpcMap.erase(it); break; } diff --git a/src/creatures/npcs/spawns/spawn_npc.hpp b/src/creatures/npcs/spawns/spawn_npc.hpp index 697cdf928..dccc1a75e 100644 --- a/src/creatures/npcs/spawns/spawn_npc.hpp +++ b/src/creatures/npcs/spawns/spawn_npc.hpp @@ -17,13 +17,13 @@ class NpcType; struct spawnBlockNpc_t { Position pos; - NpcType* npcType; + std::shared_ptr npcType; int64_t lastSpawnNpc; uint32_t interval; Direction direction; }; -class SpawnNpc { +class SpawnNpc : public SharedObject { public: SpawnNpc(Position initPos, int32_t initRadius) : centerPos(std::move(initPos)), radius(initRadius) { } @@ -34,7 +34,7 @@ class SpawnNpc { SpawnNpc &operator=(const SpawnNpc &) = delete; bool addNpc(const std::string &name, const Position &pos, Direction dir, uint32_t interval); - void removeNpc(Npc* npc); + void removeNpc(std::shared_ptr npc); uint32_t getInterval() const { return interval; @@ -49,7 +49,7 @@ class SpawnNpc { private: // map of the spawned npcs - using SpawnedNpcMap = std::multimap; + using SpawnedNpcMap = std::multimap>; using spawned_pair = SpawnedNpcMap::value_type; SpawnedNpcMap spawnedNpcMap; @@ -63,7 +63,7 @@ class SpawnNpc { uint32_t checkSpawnNpcEvent = 0; static bool findPlayer(const Position &pos); - bool spawnNpc(uint32_t spawnId, NpcType* npcType, const Position &pos, Direction dir, bool startup = false); + bool spawnNpc(uint32_t spawnId, const std::shared_ptr &npcType, const Position &pos, Direction dir, bool startup = false); void checkSpawnNpc(); void scheduleSpawnNpc(uint32_t spawnId, spawnBlockNpc_t &sb, uint16_t interval); }; @@ -94,12 +94,12 @@ class SpawnsNpc { return fileName = setName; } - std::forward_list &getSpawnNpcList() { + std::forward_list> &getSpawnNpcList() { return spawnNpcList; } private: - std::forward_list spawnNpcList; + std::forward_list> spawnNpcList; std::string fileName; bool loaded = false; bool started = false; diff --git a/src/creatures/players/grouping/guild.cpp b/src/creatures/players/grouping/guild.cpp index 995f4936b..14b59b8e9 100644 --- a/src/creatures/players/grouping/guild.cpp +++ b/src/creatures/players/grouping/guild.cpp @@ -12,16 +12,17 @@ #include "creatures/players/grouping/guild.hpp" #include "game/game.hpp" -void Guild::addMember(Player* player) { +void Guild::addMember(const std::shared_ptr &player) { membersOnline.push_back(player); - for (Player* member : membersOnline) { + for (auto member : getMembersOnline()) { g_game().updatePlayerHelpers(member); } } -void Guild::removeMember(Player* player) { +void Guild::removeMember(const std::shared_ptr &player) { + // loop over to udpate all members and delete the player from the list membersOnline.remove(player); - for (Player* member : membersOnline) { + for (const auto &member : membersOnline) { g_game().updatePlayerHelpers(member); } diff --git a/src/creatures/players/grouping/guild.hpp b/src/creatures/players/grouping/guild.hpp index 497d83635..ee16c469c 100644 --- a/src/creatures/players/grouping/guild.hpp +++ b/src/creatures/players/grouping/guild.hpp @@ -29,8 +29,8 @@ class Guild : public Bankable { Guild(uint32_t initId, std::string initName) : name(std::move(initName)), id(initId) { } - void addMember(Player* player); - void removeMember(Player* player); + void addMember(const std::shared_ptr &player); + void removeMember(const std::shared_ptr &player); bool isGuild() { return true; @@ -48,9 +48,12 @@ class Guild : public Bankable { const std::string &getName() const { return name; } - const std::list &getMembersOnline() const { + std::list> getMembersOnline() const { return membersOnline; } + uint32_t getMemberCountOnline() const { + return membersOnline.size(); + } uint32_t getMemberCount() const { return memberCount; } @@ -81,7 +84,7 @@ class Guild : public Bankable { } private: - std::list membersOnline; + std::list> membersOnline; std::vector ranks; std::string name; uint64_t bankBalance = 0; diff --git a/src/creatures/players/grouping/party.cpp b/src/creatures/players/grouping/party.cpp index 55dc1a678..57cfab4da 100644 --- a/src/creatures/players/grouping/party.cpp +++ b/src/creatures/players/grouping/party.cpp @@ -15,25 +15,30 @@ #include "lua/callbacks/event_callback.hpp" #include "lua/callbacks/events_callbacks.hpp" -Party::Party(Player* initLeader) : - leader(initLeader) { - leader->setParty(this); +std::shared_ptr Party::create(std::shared_ptr leader) { + auto party = std::make_shared(); + party->m_leader = leader; + leader->setParty(party); if (g_configManager().getBoolean(PARTY_AUTO_SHARE_EXPERIENCE)) { - setSharedExperience(initLeader, true); + party->setSharedExperience(leader, true); } + return party; } void Party::disband() { - if (!g_events().eventPartyOnDisband(this)) { + if (!g_events().eventPartyOnDisband(getParty())) { return; } - if (!g_callbacks().checkCallback(EventCallback_t::partyOnDisband, &EventCallback::partyOnDisband, this)) { + if (!g_callbacks().checkCallback(EventCallback_t::partyOnDisband, &EventCallback::partyOnDisband, getParty())) { return; } - Player* currentLeader = leader; - leader = nullptr; + auto currentLeader = getLeader(); + if (!currentLeader) { + return; + } + m_leader.reset(); currentLeader->setParty(nullptr); currentLeader->sendClosePrivate(CHANNEL_PARTY); @@ -42,22 +47,23 @@ void Party::disband() { currentLeader->sendCreatureSkull(currentLeader); currentLeader->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, "Your party has been disbanded."); - for (Player* invitee : inviteList) { - invitee->removePartyInvitation(this); + for (auto invitee : getInvitees()) { + invitee->removePartyInvitation(getParty()); currentLeader->sendCreatureShield(invitee); } inviteList.clear(); - for (Player* member : memberList) { + auto members = getMembers(); + for (auto member : members) { member->setParty(nullptr); member->sendClosePrivate(CHANNEL_PARTY); member->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, "Your party has been disbanded."); } - for (Player* member : memberList) { + for (auto member : members) { g_game().updatePlayerShield(member); - for (Player* otherMember : memberList) { + for (auto otherMember : members) { otherMember->sendCreatureSkull(member); } @@ -66,28 +72,28 @@ void Party::disband() { g_game().updatePlayerHelpers(member); } memberList.clear(); - - for (PartyAnalyzer* analyzer : membersData) { - delete analyzer; - } membersData.clear(); - delete this; } -bool Party::leaveParty(Player* player) { +bool Party::leaveParty(std::shared_ptr player) { if (!player) { return false; } - if (player->getParty() != this && leader != player) { + auto leader = getLeader(); + if (!leader) { + return false; + } + + if (player->getParty().get() != this && leader != player) { return false; } - if (!g_events().eventPartyOnLeave(this, player)) { + if (!g_events().eventPartyOnLeave(getParty(), player)) { return false; } - if (!g_callbacks().checkCallback(EventCallback_t::partyOnLeave, &EventCallback::partyOnLeave, this, player)) { + if (!g_callbacks().checkCallback(EventCallback_t::partyOnLeave, &EventCallback::partyOnLeave, getParty(), player)) { return false; } @@ -97,7 +103,18 @@ bool Party::leaveParty(Player* player) { if (memberList.size() == 1 && inviteList.empty()) { missingLeader = true; } else { - passPartyLeadership(memberList.front()); + auto newLeader = memberList.front(); + while (!newLeader) { + memberList.erase(memberList.begin()); + if (memberList.empty()) { + missingLeader = true; + break; + } + newLeader = memberList.front(); + } + if (newLeader) { + passPartyLeadership(newLeader); + } } } else { missingLeader = true; @@ -115,7 +132,7 @@ bool Party::leaveParty(Player* player) { g_game().updatePlayerShield(player); g_game().updatePlayerHelpers(player); - for (Player* member : memberList) { + for (auto member : getMembers()) { member->sendCreatureSkull(player); player->sendPlayerPartyIcons(member); member->sendPartyCreatureUpdate(player); @@ -144,8 +161,9 @@ bool Party::leaveParty(Player* player) { return true; } -bool Party::passPartyLeadership(Player* player) { - if (!player || leader == player || player->getParty() != this) { +bool Party::passPartyLeadership(std::shared_ptr player) { + auto leader = getLeader(); + if (!leader || !player || leader == player || player->getParty().get() != this) { return false; } @@ -159,20 +177,20 @@ bool Party::passPartyLeadership(Player* player) { ss << player->getName() << " is now the leader of the party."; broadcastPartyMessage(MESSAGE_PARTY_MANAGEMENT, ss.str(), true); - Player* oldLeader = leader; - leader = player; + auto oldLeader = leader; + m_leader = player; memberList.insert(memberList.begin(), oldLeader); updateSharedExperience(); updateTrackerAnalyzer(); - for (Player* member : memberList) { + for (auto member : getMembers()) { member->sendPartyCreatureShield(oldLeader); member->sendPartyCreatureShield(leader); } - for (Player* invitee : inviteList) { + for (auto invitee : getInvitees()) { invitee->sendCreatureShield(oldLeader); invitee->sendCreatureShield(leader); } @@ -184,16 +202,21 @@ bool Party::passPartyLeadership(Player* player) { return true; } -bool Party::joinParty(Player &player) { - if (!g_events().eventPartyOnJoin(this, &player)) { +bool Party::joinParty(const std::shared_ptr &player) { + auto leader = getLeader(); + if (!leader) { + return false; + } + + if (!g_events().eventPartyOnJoin(getParty(), player)) { return false; } - if (!g_callbacks().checkCallback(EventCallback_t::partyOnJoin, &EventCallback::partyOnJoin, this, &player)) { + if (!g_callbacks().checkCallback(EventCallback_t::partyOnJoin, &EventCallback::partyOnJoin, getParty(), player)) { return false; } - auto it = std::find(inviteList.begin(), inviteList.end(), &player); + auto it = std::find(inviteList.begin(), inviteList.end(), player); if (it == inviteList.end()) { return false; } @@ -201,58 +224,63 @@ bool Party::joinParty(Player &player) { inviteList.erase(it); std::ostringstream ss; - ss << player.getName() << " has joined the party."; + ss << player->getName() << " has joined the party."; broadcastPartyMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); - player.setParty(this); + player->setParty(getParty()); - g_game().updatePlayerShield(&player); + g_game().updatePlayerShield(player); - for (Player* member : memberList) { - member->sendCreatureSkull(&player); - player.sendPlayerPartyIcons(member); + for (auto member : getMembers()) { + member->sendCreatureSkull(player); + player->sendPlayerPartyIcons(member); } - player.sendCreatureSkull(&player); - leader->sendCreatureSkull(&player); - player.sendPlayerPartyIcons(leader); + player->sendCreatureSkull(player); + leader->sendCreatureSkull(player); + player->sendPlayerPartyIcons(leader); - memberList.push_back(&player); + memberList.push_back(player); - g_game().updatePlayerHelpers(&player); + g_game().updatePlayerHelpers(player); - updatePlayerStatus(&player); + updatePlayerStatus(player); - player.removePartyInvitation(this); + player->removePartyInvitation(getParty()); updateSharedExperience(); const std::string &leaderName = leader->getName(); ss.str(std::string()); ss << "You have joined " << leaderName << "'" << (leaderName.back() == 's' ? "" : "s") << " party. Open the party channel to communicate with your companions."; - player.sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); + player->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); updateTrackerAnalyzer(); return true; } -bool Party::removeInvite(Player &player, bool removeFromPlayer /* = true*/) { - auto it = std::find(inviteList.begin(), inviteList.end(), &player); +bool Party::removeInvite(const std::shared_ptr &player, bool removeFromPlayer /* = true*/) { + auto leader = getLeader(); + if (!leader) { + return false; + } + + auto it = std::find(inviteList.begin(), inviteList.end(), player); if (it == inviteList.end()) { return false; } inviteList.erase(it); - leader->sendCreatureShield(&player); - player.sendCreatureShield(leader); + leader->sendCreatureShield(player); + player->sendCreatureShield(leader); if (removeFromPlayer) { - player.removePartyInvitation(this); + player->removePartyInvitation(getParty()); } if (empty()) { disband(); } else { - for (Player* member : memberList) { + for (auto member : getMembers()) { g_game().updatePlayerHelpers(member); } @@ -262,25 +290,35 @@ bool Party::removeInvite(Player &player, bool removeFromPlayer /* = true*/) { return true; } -void Party::revokeInvitation(Player &player) { +void Party::revokeInvitation(const std::shared_ptr &player) { + auto leader = getLeader(); + if (!leader) { + return; + } + std::ostringstream ss; ss << leader->getName() << " has revoked " << leader->getPossessivePronoun() << " invitation."; - player.sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); + player->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); ss.str(std::string()); - ss << "Invitation for " << player.getName() << " has been revoked."; + ss << "Invitation for " << player->getName() << " has been revoked."; leader->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); removeInvite(player); } -bool Party::invitePlayer(Player &player) { - if (isPlayerInvited(&player)) { +bool Party::invitePlayer(const std::shared_ptr &player) { + auto leader = getLeader(); + if (!leader) { + return false; + } + + if (isPlayerInvited(player)) { return false; } std::ostringstream ss; - ss << player.getName() << " has been invited to join the party (Share range: " << getMinLevel() << "-" << getMaxLevel() << ")."; + ss << player->getName() << " has been invited to join the party (Share range: " << getMinLevel() << "-" << getMaxLevel() << ")."; if (empty()) { ss << " Open the party channel to communicate with your members."; @@ -290,32 +328,37 @@ bool Party::invitePlayer(Player &player) { leader->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); - inviteList.push_back(&player); + inviteList.push_back(player); - for (Player* member : memberList) { + for (auto member : getMembers()) { g_game().updatePlayerHelpers(member); } g_game().updatePlayerHelpers(leader); - leader->sendCreatureShield(&player); - player.sendCreatureShield(leader); + leader->sendCreatureShield(player); + player->sendCreatureShield(leader); - player.addPartyInvitation(this); + player->addPartyInvitation(getParty()); ss.str(std::string()); ss << leader->getName() << " has invited you to " << leader->getPossessivePronoun() << " party (Share range: " << getMinLevel() << "-" << getMaxLevel() << ")."; - player.sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); + player->sendTextMessage(MESSAGE_PARTY_MANAGEMENT, ss.str()); return true; } -bool Party::isPlayerInvited(const Player* player) const { +bool Party::isPlayerInvited(const std::shared_ptr &player) const { return std::find(inviteList.begin(), inviteList.end(), player) != inviteList.end(); } void Party::updateAllPartyIcons() { - for (Player* member : memberList) { - for (Player* otherMember : memberList) { + auto leader = getLeader(); + if (!leader) { + return; + } + auto members = getMembers(); + for (auto member : members) { + for (auto otherMember : members) { member->sendPartyCreatureShield(otherMember); } @@ -327,14 +370,18 @@ void Party::updateAllPartyIcons() { } void Party::broadcastPartyMessage(MessageClasses msgClass, const std::string &msg, bool sendToInvitations /*= false*/) { - for (Player* member : memberList) { + auto leader = getLeader(); + if (!leader) { + return; + } + for (auto member : getMembers()) { member->sendTextMessage(msgClass, msg); } leader->sendTextMessage(msgClass, msg); if (sendToInvitations) { - for (Player* invitee : inviteList) { + for (auto invitee : getInvitees()) { invitee->sendTextMessage(msgClass, msg); } } @@ -367,7 +414,8 @@ const char* Party::getSharedExpReturnMessage(SharedExpStatus_t value) { } } -bool Party::setSharedExperience(Player* player, bool newSharedExpActive, bool silent /*= false*/) { +bool Party::setSharedExperience(std::shared_ptr player, bool newSharedExpActive, bool silent /*= false*/) { + auto leader = getLeader(); if (!player || leader != player) { return false; } @@ -394,22 +442,31 @@ bool Party::setSharedExperience(Player* player, bool newSharedExpActive, bool si return true; } -void Party::shareExperience(uint64_t experience, Creature* target /* = nullptr*/) { +void Party::shareExperience(uint64_t experience, std::shared_ptr target /* = nullptr*/) { + auto leader = getLeader(); + if (!leader) { + return; + } + uint64_t shareExperience = experience; - g_events().eventPartyOnShareExperience(this, shareExperience); - g_callbacks().executeCallback(EventCallback_t::partyOnShareExperience, &EventCallback::partyOnShareExperience, this, shareExperience); + g_events().eventPartyOnShareExperience(getParty(), shareExperience); + g_callbacks().executeCallback(EventCallback_t::partyOnShareExperience, &EventCallback::partyOnShareExperience, getParty(), shareExperience); - for (Player* member : memberList) { + for (auto member : getMembers()) { member->onGainSharedExperience(shareExperience, target); } leader->onGainSharedExperience(shareExperience, target); } -bool Party::canUseSharedExperience(const Player* player) const { +bool Party::canUseSharedExperience(std::shared_ptr player) { return getMemberSharedExperienceStatus(player) == SHAREDEXP_OK; } -SharedExpStatus_t Party::getMemberSharedExperienceStatus(const Player* player) const { +SharedExpStatus_t Party::getMemberSharedExperienceStatus(std::shared_ptr player) { + auto leader = getLeader(); + if (!leader) { + return SHAREDEXP_EMPTYPARTY; + } if (memberList.empty()) { return SHAREDEXP_EMPTYPARTY; } @@ -432,9 +489,14 @@ SharedExpStatus_t Party::getMemberSharedExperienceStatus(const Player* player) c return SHAREDEXP_OK; } -uint32_t Party::getHighestLevel() const { +uint32_t Party::getHighestLevel() { + auto leader = getLeader(); + if (!leader) { + return 0; + } + uint32_t highestLevel = leader->getLevel(); - for (Player* member : memberList) { + for (auto member : getMembers()) { if (member->getLevel() > highestLevel) { highestLevel = member->getLevel(); } @@ -442,13 +504,17 @@ uint32_t Party::getHighestLevel() const { return highestLevel; } -uint32_t Party::getMinLevel() const { +uint32_t Party::getMinLevel() { return static_cast(std::ceil((static_cast(getHighestLevel()) * 2) / 3)); } -uint32_t Party::getLowestLevel() const { +uint32_t Party::getLowestLevel() { + auto leader = getLeader(); + if (!leader) { + return 0; + } uint32_t lowestLevel = leader->getLevel(); - for (Player* member : memberList) { + for (auto member : getMembers()) { if (member->getLevel() < lowestLevel) { lowestLevel = member->getLevel(); } @@ -456,11 +522,11 @@ uint32_t Party::getLowestLevel() const { return lowestLevel; } -uint32_t Party::getMaxLevel() const { +uint32_t Party::getMaxLevel() { return static_cast(std::floor((static_cast(getLowestLevel()) * 3) / 2)); } -bool Party::isPlayerActive(const Player* player) const { +bool Party::isPlayerActive(std::shared_ptr player) { auto it = ticksMap.find(player->getID()); if (it == ticksMap.end()) { return false; @@ -471,12 +537,16 @@ bool Party::isPlayerActive(const Player* player) const { } SharedExpStatus_t Party::getSharedExperienceStatus() { + auto leader = getLeader(); + if (!leader) { + return SHAREDEXP_EMPTYPARTY; + } SharedExpStatus_t leaderStatus = getMemberSharedExperienceStatus(leader); if (leaderStatus != SHAREDEXP_OK) { return leaderStatus; } - for (Player* member : memberList) { + for (auto member : getMembers()) { SharedExpStatus_t memberStatus = getMemberSharedExperienceStatus(member); if (memberStatus != SHAREDEXP_OK) { return memberStatus; @@ -485,14 +555,14 @@ SharedExpStatus_t Party::getSharedExperienceStatus() { return SHAREDEXP_OK; } -void Party::updatePlayerTicks(Player* player, uint32_t points) { +void Party::updatePlayerTicks(std::shared_ptr player, uint32_t points) { if (points != 0 && !player->hasFlag(PlayerFlags_t::NotGainInFight)) { ticksMap[player->getID()] = OTSYS_TIME(); updateSharedExperience(); } } -void Party::clearPlayerPoints(Player* player) { +void Party::clearPlayerPoints(std::shared_ptr player) { auto it = ticksMap.find(player->getID()); if (it != ticksMap.end()) { ticksMap.erase(it); @@ -501,21 +571,26 @@ void Party::clearPlayerPoints(Player* player) { } bool Party::canOpenCorpse(uint32_t ownerId) const { - if (const Player* player = g_game().getPlayerByID(ownerId)) { - return leader->getID() == ownerId || player->getParty() == this; + auto leader = getLeader(); + if (!leader) { + return false; + } + + if (std::shared_ptr player = g_game().getPlayerByID(ownerId)) { + return leader->getID() == ownerId || player->getParty().get() == this; } return false; } -void Party::showPlayerStatus(Player* player, Player* member, bool showStatus) { +void Party::showPlayerStatus(std::shared_ptr player, std::shared_ptr member, bool showStatus) { player->sendPartyCreatureShowStatus(member, showStatus); member->sendPartyCreatureShowStatus(player, showStatus); if (showStatus) { - for (Creature* summon : member->getSummons()) { + for (const auto &summon : member->getSummons()) { player->sendPartyCreatureShowStatus(summon, showStatus); player->sendPartyCreatureHealth(summon, std::ceil((static_cast(summon->getHealth()) / std::max(summon->getMaxHealth(), 1)) * 100)); } - for (Creature* summon : player->getSummons()) { + for (const auto &summon : player->getSummons()) { member->sendPartyCreatureShowStatus(summon, showStatus); member->sendPartyCreatureHealth(summon, std::ceil((static_cast(summon->getHealth()) / std::max(summon->getMaxHealth(), 1)) * 100)); } @@ -524,18 +599,23 @@ void Party::showPlayerStatus(Player* player, Player* member, bool showStatus) { player->sendPartyPlayerMana(member, std::ceil((static_cast(member->getMana()) / std::max(member->getMaxMana(), 1)) * 100)); member->sendPartyPlayerMana(player, std::ceil((static_cast(player->getMana()) / std::max(player->getMaxMana(), 1)) * 100)); } else { - for (Creature* summon : player->getSummons()) { + for (const auto &summon : player->getSummons()) { member->sendPartyCreatureShowStatus(summon, showStatus); } - for (Creature* summon : member->getSummons()) { + for (const auto &summon : member->getSummons()) { player->sendPartyCreatureShowStatus(summon, showStatus); } } } -void Party::updatePlayerStatus(Player* player) { +void Party::updatePlayerStatus(std::shared_ptr player) { + auto leader = getLeader(); + if (!leader) { + return; + } + int32_t maxDistance = g_configManager().getNumber(PARTY_LIST_MAX_DISTANCE); - for (Player* member : memberList) { + for (auto member : getMembers()) { bool condition = (maxDistance == 0 || (Position::getDistanceX(player->getPosition(), member->getPosition()) <= maxDistance && Position::getDistanceY(player->getPosition(), member->getPosition()) <= maxDistance)); if (condition) { showPlayerStatus(player, member, true); @@ -551,10 +631,15 @@ void Party::updatePlayerStatus(Player* player) { } } -void Party::updatePlayerStatus(Player* player, const Position &oldPos, const Position &newPos) { +void Party::updatePlayerStatus(std::shared_ptr player, const Position &oldPos, const Position &newPos) { + auto leader = getLeader(); + if (!leader) { + return; + } + int32_t maxDistance = g_configManager().getNumber(PARTY_LIST_MAX_DISTANCE); if (maxDistance != 0) { - for (Player* member : memberList) { + for (auto member : getMembers()) { bool condition1 = (Position::getDistanceX(oldPos, member->getPosition()) <= maxDistance && Position::getDistanceY(oldPos, member->getPosition()) <= maxDistance); bool condition2 = (Position::getDistanceX(newPos, member->getPosition()) <= maxDistance && Position::getDistanceY(newPos, member->getPosition()) <= maxDistance); if (condition1 && !condition2) { @@ -574,23 +659,36 @@ void Party::updatePlayerStatus(Player* player, const Position &oldPos, const Pos } } -void Party::updatePlayerHealth(const Player* player, const Creature* target, uint8_t healthPercent) { +void Party::updatePlayerHealth(std::shared_ptr player, std::shared_ptr target, uint8_t healthPercent) { + auto leader = getLeader(); + if (!leader) { + return; + } + int32_t maxDistance = g_configManager().getNumber(PARTY_LIST_MAX_DISTANCE); - for (Player* member : memberList) { - bool condition = (maxDistance == 0 || (Position::getDistanceX(player->getPosition(), member->getPosition()) <= maxDistance && Position::getDistanceY(player->getPosition(), member->getPosition()) <= maxDistance)); + auto playerPosition = player->getPosition(); + auto leaderPosition = leader->getPosition(); + for (auto member : getMembers()) { + auto memberPosition = member->getPosition(); + bool condition = (maxDistance == 0 || (Position::getDistanceX(playerPosition, memberPosition) <= maxDistance && Position::getDistanceY(playerPosition, memberPosition) <= maxDistance)); if (condition) { member->sendPartyCreatureHealth(target, healthPercent); } } - bool condition = (maxDistance == 0 || (Position::getDistanceX(player->getPosition(), leader->getPosition()) <= maxDistance && Position::getDistanceY(player->getPosition(), leader->getPosition()) <= maxDistance)); + bool condition = (maxDistance == 0 || (Position::getDistanceX(playerPosition, leaderPosition) <= maxDistance && Position::getDistanceY(playerPosition, leaderPosition) <= maxDistance)); if (condition) { leader->sendPartyCreatureHealth(target, healthPercent); } } -void Party::updatePlayerMana(const Player* player, uint8_t manaPercent) { +void Party::updatePlayerMana(std::shared_ptr player, uint8_t manaPercent) { + auto leader = getLeader(); + if (!leader) { + return; + } + int32_t maxDistance = g_configManager().getNumber(PARTY_LIST_MAX_DISTANCE); - for (Player* member : memberList) { + for (auto member : getMembers()) { bool condition = (maxDistance == 0 || (Position::getDistanceX(player->getPosition(), member->getPosition()) <= maxDistance && Position::getDistanceY(player->getPosition(), member->getPosition()) <= maxDistance)); if (condition) { member->sendPartyPlayerMana(player, manaPercent); @@ -602,9 +700,14 @@ void Party::updatePlayerMana(const Player* player, uint8_t manaPercent) { } } -void Party::updatePlayerVocation(const Player* player) { +void Party::updatePlayerVocation(std::shared_ptr player) { + auto leader = getLeader(); + if (!leader) { + return; + } + int32_t maxDistance = g_configManager().getNumber(PARTY_LIST_MAX_DISTANCE); - for (Player* member : memberList) { + for (auto member : getMembers()) { bool condition = (maxDistance == 0 || (Position::getDistanceX(player->getPosition(), member->getPosition()) <= maxDistance && Position::getDistanceY(player->getPosition(), member->getPosition()) <= maxDistance)); if (condition) { member->sendPartyPlayerVocation(player); @@ -616,20 +719,28 @@ void Party::updatePlayerVocation(const Player* player) { } } -void Party::updateTrackerAnalyzer() const { - for (const Player* member : memberList) { - member->updatePartyTrackerAnalyzer(); +void Party::updateTrackerAnalyzer() { + auto leader = getLeader(); + if (!leader) { + return; } - if (leader) { - leader->updatePartyTrackerAnalyzer(); + for (auto member : getMembers()) { + member->updatePartyTrackerAnalyzer(); } + + leader->updatePartyTrackerAnalyzer(); } -void Party::addPlayerLoot(const Player* player, const Item* item) { - PartyAnalyzer* playerAnalyzer = getPlayerPartyAnalyzerStruct(player->getID()); +void Party::addPlayerLoot(std::shared_ptr player, std::shared_ptr item) { + auto leader = getLeader(); + if (!leader) { + return; + } + + auto playerAnalyzer = getPlayerPartyAnalyzerStruct(player->getID()); if (!playerAnalyzer) { - playerAnalyzer = new PartyAnalyzer(player->getID(), player->getName()); + playerAnalyzer = std::make_shared(player->getID(), player->getName()); membersData.push_back(playerAnalyzer); } @@ -649,10 +760,15 @@ void Party::addPlayerLoot(const Player* player, const Item* item) { updateTrackerAnalyzer(); } -void Party::addPlayerSupply(const Player* player, const Item* item) { - PartyAnalyzer* playerAnalyzer = getPlayerPartyAnalyzerStruct(player->getID()); +void Party::addPlayerSupply(std::shared_ptr player, std::shared_ptr item) { + auto leader = getLeader(); + if (!leader) { + return; + } + + std::shared_ptr playerAnalyzer = getPlayerPartyAnalyzerStruct(player->getID()); if (!playerAnalyzer) { - playerAnalyzer = new PartyAnalyzer(player->getID(), player->getName()); + playerAnalyzer = std::make_shared(player->getID(), player->getName()); membersData.push_back(playerAnalyzer); } @@ -671,10 +787,10 @@ void Party::addPlayerSupply(const Player* player, const Item* item) { updateTrackerAnalyzer(); } -void Party::addPlayerDamage(const Player* player, uint64_t amount) { - PartyAnalyzer* playerAnalyzer = getPlayerPartyAnalyzerStruct(player->getID()); +void Party::addPlayerDamage(std::shared_ptr player, uint64_t amount) { + auto playerAnalyzer = getPlayerPartyAnalyzerStruct(player->getID()); if (!playerAnalyzer) { - playerAnalyzer = new PartyAnalyzer(player->getID(), player->getName()); + playerAnalyzer = std::make_shared(player->getID(), player->getName()); membersData.push_back(playerAnalyzer); } @@ -682,10 +798,10 @@ void Party::addPlayerDamage(const Player* player, uint64_t amount) { updateTrackerAnalyzer(); } -void Party::addPlayerHealing(const Player* player, uint64_t amount) { - PartyAnalyzer* playerAnalyzer = getPlayerPartyAnalyzerStruct(player->getID()); +void Party::addPlayerHealing(std::shared_ptr player, uint64_t amount) { + auto playerAnalyzer = getPlayerPartyAnalyzerStruct(player->getID()); if (!playerAnalyzer) { - playerAnalyzer = new PartyAnalyzer(player->getID(), player->getName()); + playerAnalyzer = std::make_shared(player->getID(), player->getName()); membersData.push_back(playerAnalyzer); } @@ -694,7 +810,8 @@ void Party::addPlayerHealing(const Player* player, uint64_t amount) { } void Party::switchAnalyzerPriceType() { - if (leader == nullptr) { + auto leader = getLeader(); + if (!leader) { return; } @@ -705,16 +822,17 @@ void Party::switchAnalyzerPriceType() { void Party::resetAnalyzer() { trackerTime = time(nullptr); - for (PartyAnalyzer* analyzer : membersData) { - delete analyzer; - } - membersData.clear(); updateTrackerAnalyzer(); } void Party::reloadPrices() { - for (PartyAnalyzer* analyzer : membersData) { + auto leader = getLeader(); + if (!leader) { + return; + } + + for (const auto &analyzer : membersData) { if (priceType == MARKET_PRICE) { analyzer->lootPrice = g_game().getItemMarketPrice(analyzer->lootMap, false); analyzer->supplyPrice = g_game().getItemMarketPrice(analyzer->supplyMap, true); diff --git a/src/creatures/players/grouping/party.hpp b/src/creatures/players/grouping/party.hpp index c89a6eb65..e7bc2c2fc 100644 --- a/src/creatures/players/grouping/party.hpp +++ b/src/creatures/players/grouping/party.hpp @@ -24,19 +24,21 @@ enum SharedExpStatus_t : uint8_t { class Player; class Party; -using PlayerVector = std::vector; - -class Party { +class Party : public SharedObject { public: - explicit Party(Player* leader); + static std::shared_ptr create(std::shared_ptr leader); + + std::shared_ptr getParty() { + return static_self_cast(); + } - Player* getLeader() const { - return leader; + std::shared_ptr getLeader() const { + return m_leader.lock(); } - PlayerVector &getMembers() { + std::vector> getMembers() { return memberList; } - const PlayerVector &getInvitees() const { + std::vector> getInvitees() { return inviteList; } size_t getMemberCount() const { @@ -47,15 +49,15 @@ class Party { } void disband(); - bool invitePlayer(Player &player); - bool joinParty(Player &player); - void revokeInvitation(Player &player); - bool passPartyLeadership(Player* player); - bool leaveParty(Player* player); + bool invitePlayer(const std::shared_ptr &player); + bool joinParty(const std::shared_ptr &player); + void revokeInvitation(const std::shared_ptr &player); + bool passPartyLeadership(std::shared_ptr player); + bool leaveParty(std::shared_ptr player); - bool removeInvite(Player &player, bool removeFromPlayer = true); + bool removeInvite(const std::shared_ptr &player, bool removeFromPlayer = true); - bool isPlayerInvited(const Player* player) const; + bool isPlayerInvited(const std::shared_ptr &player) const; void updateAllPartyIcons(); void broadcastPartyMessage(MessageClasses msgClass, const std::string &msg, bool sendToInvitations = false); bool empty() const { @@ -63,39 +65,39 @@ class Party { } bool canOpenCorpse(uint32_t ownerId) const; - void shareExperience(uint64_t experience, Creature* target = nullptr); - bool setSharedExperience(Player* player, bool sharedExpActive, bool silent = false); + void shareExperience(uint64_t experience, std::shared_ptr target = nullptr); + bool setSharedExperience(std::shared_ptr player, bool sharedExpActive, bool silent = false); bool isSharedExperienceActive() const { return sharedExpActive; } bool isSharedExperienceEnabled() const { return sharedExpEnabled; } - bool canUseSharedExperience(const Player* player) const; - SharedExpStatus_t getMemberSharedExperienceStatus(const Player* player) const; + bool canUseSharedExperience(std::shared_ptr player); + SharedExpStatus_t getMemberSharedExperienceStatus(std::shared_ptr player); void updateSharedExperience(); - void updatePlayerTicks(Player* player, uint32_t points); - void clearPlayerPoints(Player* player); - - void showPlayerStatus(Player* player, Player* member, bool showStatus); - void updatePlayerStatus(Player* player); - void updatePlayerStatus(Player* player, const Position &oldPos, const Position &newPos); - void updatePlayerHealth(const Player* player, const Creature* target, uint8_t healthPercent); - void updatePlayerMana(const Player* player, uint8_t manaPercent); - void updatePlayerVocation(const Player* player); - - void updateTrackerAnalyzer() const; - void addPlayerLoot(const Player* player, const Item* item); - void addPlayerSupply(const Player* player, const Item* item); - void addPlayerDamage(const Player* player, uint64_t amount); - void addPlayerHealing(const Player* player, uint64_t amount); + void updatePlayerTicks(std::shared_ptr player, uint32_t points); + void clearPlayerPoints(std::shared_ptr player); + + void showPlayerStatus(std::shared_ptr player, std::shared_ptr member, bool showStatus); + void updatePlayerStatus(std::shared_ptr player); + void updatePlayerStatus(std::shared_ptr player, const Position &oldPos, const Position &newPos); + void updatePlayerHealth(std::shared_ptr player, std::shared_ptr target, uint8_t healthPercent); + void updatePlayerMana(std::shared_ptr player, uint8_t manaPercent); + void updatePlayerVocation(std::shared_ptr player); + + void updateTrackerAnalyzer(); + void addPlayerLoot(std::shared_ptr player, std::shared_ptr item); + void addPlayerSupply(std::shared_ptr player, std::shared_ptr item); + void addPlayerDamage(std::shared_ptr player, uint64_t amount); + void addPlayerHealing(std::shared_ptr player, uint64_t amount); void switchAnalyzerPriceType(); void resetAnalyzer(); void reloadPrices(); - PartyAnalyzer* getPlayerPartyAnalyzerStruct(uint32_t playerId) const { - if (auto it = std::find_if(membersData.begin(), membersData.end(), [playerId](const PartyAnalyzer* preyIt) { + std::shared_ptr getPlayerPartyAnalyzerStruct(uint32_t playerId) const { + if (auto it = std::find_if(membersData.begin(), membersData.end(), [playerId](const std::shared_ptr preyIt) { return preyIt->id == playerId; }); it != membersData.end()) { @@ -113,23 +115,23 @@ class Party { // Party analyzer time_t trackerTime = time(nullptr); PartyAnalyzer_t priceType = MARKET_PRICE; - std::vector membersData; + std::vector> membersData; private: const char* getSharedExpReturnMessage(SharedExpStatus_t value); - bool isPlayerActive(const Player* player) const; + bool isPlayerActive(std::shared_ptr player); SharedExpStatus_t getSharedExperienceStatus(); - uint32_t getHighestLevel() const; - uint32_t getLowestLevel() const; - uint32_t getMinLevel() const; - uint32_t getMaxLevel() const; + uint32_t getHighestLevel(); + uint32_t getLowestLevel(); + uint32_t getMinLevel(); + uint32_t getMaxLevel(); std::map ticksMap; - PlayerVector memberList; - PlayerVector inviteList; + std::vector> memberList; + std::vector> inviteList; - Player* leader; + std::weak_ptr m_leader; bool sharedExpActive = false; bool sharedExpEnabled = false; diff --git a/src/creatures/players/grouping/team_finder.hpp b/src/creatures/players/grouping/team_finder.hpp index b0c779306..609ce0f67 100644 --- a/src/creatures/players/grouping/team_finder.hpp +++ b/src/creatures/players/grouping/team_finder.hpp @@ -51,3 +51,5 @@ class TeamFinder { // list: player:getGuid(), player status std::map membersMap = {}; }; + +static const std::unique_ptr &TeamFinderNull {}; diff --git a/src/creatures/players/imbuements/imbuements.cpp b/src/creatures/players/imbuements/imbuements.cpp index 664e2bd09..2d27d15bb 100644 --- a/src/creatures/players/imbuements/imbuements.cpp +++ b/src/creatures/players/imbuements/imbuements.cpp @@ -336,7 +336,7 @@ CategoryImbuement* Imbuements::getCategoryByID(uint16_t id) { return categoryImbuements != categoriesImbuement.end() ? &*categoryImbuements : nullptr; } -std::vector Imbuements::getImbuements(const Player* player, Item* item) { +std::vector Imbuements::getImbuements(std::shared_ptr player, std::shared_ptr item) { std::vector imbuements; for (auto &[key, value] : imbuementMap) { diff --git a/src/creatures/players/imbuements/imbuements.hpp b/src/creatures/players/imbuements/imbuements.hpp index 828dfd67b..69c5219a0 100644 --- a/src/creatures/players/imbuements/imbuements.hpp +++ b/src/creatures/players/imbuements/imbuements.hpp @@ -60,7 +60,7 @@ class Imbuements { BaseImbuement* getBaseByID(uint16_t id); CategoryImbuement* getCategoryByID(uint16_t id); - std::vector getImbuements(const Player* player, Item* item); + std::vector getImbuements(std::shared_ptr player, std::shared_ptr item); protected: friend class Imbuement; diff --git a/src/creatures/players/management/waitlist.cpp b/src/creatures/players/management/waitlist.cpp index f5179daf0..ff1ad2b00 100644 --- a/src/creatures/players/management/waitlist.cpp +++ b/src/creatures/players/management/waitlist.cpp @@ -59,7 +59,7 @@ std::size_t WaitingList::getTime(std::size_t slot) { } } -bool WaitingList::clientLogin(const Player* player) { +bool WaitingList::clientLogin(std::shared_ptr player) { if (player->hasFlag(PlayerFlags_t::CanAlwaysLogin) || player->getAccountType() >= account::ACCOUNT_TYPE_GAMEMASTER) { return true; } @@ -85,7 +85,7 @@ bool WaitingList::clientLogin(const Player* player) { return false; } -void WaitingList::addPlayerToList(const Player* player) { +void WaitingList::addPlayerToList(std::shared_ptr player) { auto it = info->playerReferences.find(player->getGUID()); if (it != info->playerReferences.end()) { std::size_t slot; @@ -111,7 +111,7 @@ void WaitingList::addPlayerToList(const Player* player) { } } -std::size_t WaitingList::getClientSlot(const Player* player) { +std::size_t WaitingList::getClientSlot(std::shared_ptr player) { auto it = info->playerReferences.find(player->getGUID()); if (it == info->playerReferences.end()) { return 0; diff --git a/src/creatures/players/management/waitlist.hpp b/src/creatures/players/management/waitlist.hpp index 2203a1ebb..28b65c7ca 100644 --- a/src/creatures/players/management/waitlist.hpp +++ b/src/creatures/players/management/waitlist.hpp @@ -34,13 +34,13 @@ class WaitingList { public: WaitingList(); static WaitingList &getInstance(); - bool clientLogin(const Player* player); - std::size_t getClientSlot(const Player* player); + bool clientLogin(std::shared_ptr player); + std::size_t getClientSlot(std::shared_ptr player); static std::size_t getTime(std::size_t slot); private: void cleanupList(WaitList &list); std::size_t getTimeout(std::size_t slot); - void addPlayerToList(const Player* player); + void addPlayerToList(std::shared_ptr player); std::unique_ptr info; }; diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index b018a9d5e..305fe6ee8 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -37,49 +37,25 @@ Player::Player(ProtocolGame_ptr p) : Creature(), lastPing(OTSYS_TIME()), lastPong(lastPing), - inbox(new Inbox(ITEM_INBOX)), + inbox(std::make_shared(ITEM_INBOX)), client(std::move(p)) { - inbox->incrementReferenceCounter(); m_wheelPlayer = std::make_unique(*this); } Player::~Player() { - for (Item* item : inventory) { + for (std::shared_ptr item : inventory) { if (item) { - item->setParent(nullptr); + item->resetParent(); item->stopDecaying(); - item->decrementReferenceCounter(); } } for (const auto &it : depotLockerMap) { it.second->removeInbox(inbox); it.second->stopDecaying(); - it.second->decrementReferenceCounter(); - } - - for (const auto &it : rewardMap) { - it.second->decrementReferenceCounter(); - } - - for (const auto &it : quickLootContainers) { - it.second->decrementReferenceCounter(); - } - - for (PreySlot* slot : preys) { - if (slot) { - delete slot; - } - } - - for (TaskHuntingSlot* slot : taskHunting) { - if (slot) { - delete slot; - } } inbox->stopDecaying(); - inbox->decrementReferenceCounter(); setWriteItem(nullptr); setEditHouse(nullptr); @@ -94,11 +70,11 @@ bool Player::setVocation(uint16_t vocId) { vocation = voc; updateRegeneration(); - g_game().addPlayerVocation(this); + g_game().addPlayerVocation(static_self_cast()); return true; } -bool Player::isPushable() const { +bool Player::isPushable() { if (hasFlag(PlayerFlags_t::CannotBePushed)) { return false; } @@ -128,7 +104,7 @@ void Player::setID() { } } -std::string Player::getDescription(int32_t lookDistance) const { +std::string Player::getDescription(int32_t lookDistance) { std::ostringstream s; std::string subjectPronoun = getSubjectPronoun(); capitalizeWords(subjectPronoun); @@ -230,7 +206,7 @@ std::string Player::getDescription(int32_t lookDistance) const { return s.str(); } -Item* Player::getInventoryItem(Slots_t slot) const { +std::shared_ptr Player::getInventoryItem(Slots_t slot) const { if (slot < CONST_SLOT_FIRST || slot > CONST_SLOT_LAST) { return nullptr; } @@ -251,8 +227,8 @@ void Player::removeConditionSuppressions() { m_conditionSuppressions.reset(); } -Item* Player::getWeapon(Slots_t slot, bool ignoreAmmo) const { - Item* item = inventory[slot]; +std::shared_ptr Player::getWeapon(Slots_t slot, bool ignoreAmmo) const { + std::shared_ptr item = inventory[slot]; if (!item) { return nullptr; } @@ -273,23 +249,23 @@ Item* Player::getWeapon(Slots_t slot, bool ignoreAmmo) const { } bool Player::hasQuiverEquipped() const { - Item* quiver = inventory[CONST_SLOT_RIGHT]; + std::shared_ptr quiver = inventory[CONST_SLOT_RIGHT]; return quiver && quiver->isQuiver() && quiver->getContainer(); } bool Player::hasWeaponDistanceEquipped() const { - const Item* item = inventory[CONST_SLOT_LEFT]; + std::shared_ptr item = inventory[CONST_SLOT_LEFT]; return item && item->getWeaponType() == WEAPON_DISTANCE; } -Item* Player::getQuiverAmmoOfType(const ItemType &it) const { +std::shared_ptr Player::getQuiverAmmoOfType(const ItemType &it) const { if (!hasQuiverEquipped()) { return nullptr; } - Item* quiver = inventory[CONST_SLOT_RIGHT]; - for (const Container* container = quiver->getContainer(); - Item * ammoItem : container->getItemList()) { + std::shared_ptr quiver = inventory[CONST_SLOT_RIGHT]; + for (std::shared_ptr container = quiver->getContainer(); + auto ammoItem : container->getItemList()) { if (ammoItem->getAmmoType() == it.ammoType) { if (level >= Item::items[ammoItem->getID()].minReqLevel) { return ammoItem; @@ -299,8 +275,8 @@ Item* Player::getQuiverAmmoOfType(const ItemType &it) const { return nullptr; } -Item* Player::getWeapon(bool ignoreAmmo /* = false*/) const { - Item* item = getWeapon(CONST_SLOT_LEFT, ignoreAmmo); +std::shared_ptr Player::getWeapon(bool ignoreAmmo /* = false*/) const { + std::shared_ptr item = getWeapon(CONST_SLOT_LEFT, ignoreAmmo); if (item) { return item; } @@ -313,14 +289,14 @@ Item* Player::getWeapon(bool ignoreAmmo /* = false*/) const { } WeaponType_t Player::getWeaponType() const { - Item* item = getWeapon(); + std::shared_ptr item = getWeapon(); if (!item) { return WEAPON_NONE; } return item->getWeaponType(); } -int32_t Player::getWeaponSkill(const Item* item) const { +int32_t Player::getWeaponSkill(std::shared_ptr item) const { if (!item) { return getSkillLevel(SKILL_FIST); } @@ -363,7 +339,7 @@ int32_t Player::getArmor() const { static const Slots_t armorSlots[] = { CONST_SLOT_HEAD, CONST_SLOT_NECKLACE, CONST_SLOT_ARMOR, CONST_SLOT_LEGS, CONST_SLOT_FEET, CONST_SLOT_RING }; for (Slots_t slot : armorSlots) { - Item* inventoryItem = inventory[slot]; + std::shared_ptr inventoryItem = inventory[slot]; if (inventoryItem) { armor += inventoryItem->getArmor(); } @@ -371,12 +347,12 @@ int32_t Player::getArmor() const { return static_cast(armor * vocation->armorMultiplier); } -void Player::getShieldAndWeapon(const Item*&shield, const Item*&weapon) const { +void Player::getShieldAndWeapon(std::shared_ptr &shield, std::shared_ptr &weapon) const { shield = nullptr; weapon = nullptr; for (uint32_t slot = CONST_SLOT_RIGHT; slot <= CONST_SLOT_LEFT; slot++) { - Item* item = inventory[slot]; + std::shared_ptr item = inventory[slot]; if (!item) { continue; } @@ -407,8 +383,8 @@ float Player::getMitigation() const { int32_t Player::getDefense() const { int32_t defenseSkill = getSkillLevel(SKILL_FIST); int32_t defenseValue = 7; - const Item* weapon; - const Item* shield; + std::shared_ptr weapon; + std::shared_ptr shield; try { getShieldAndWeapon(shield, weapon); } catch (const std::exception &e) { @@ -469,9 +445,9 @@ float Player::getDefenseFactor() const { } } -uint32_t Player::getClientIcons() const { +uint32_t Player::getClientIcons() { uint32_t icons = 0; - for (Condition* condition : conditions) { + for (const auto &condition : conditions) { if (!isSuppress(condition->getType())) { icons |= condition->getIcons(); } @@ -481,6 +457,7 @@ uint32_t Player::getClientIcons() const { icons |= ICON_REDSWORDS; } + auto tile = getTile(); if (tile && tile->hasFlag(TILESTATE_PROTECTIONZONE)) { icons |= ICON_PIGEON; client->sendRestingStatus(1); @@ -563,7 +540,7 @@ void Player::updateInventoryWeight() { inventoryWeight = 0; for (int i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { - const Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (item) { inventoryWeight += item->getWeight(); } @@ -572,7 +549,7 @@ void Player::updateInventoryWeight() { void Player::updateInventoryImbuement() { // Get the tile the player is currently on - const Tile* playerTile = getTile(); + std::shared_ptr playerTile = getTile(); // Check if the player is in a protection zone bool isInProtectionZone = playerTile && playerTile->hasFlag(TILESTATE_PROTECTIONZONE); // Check if the player is in fight mode @@ -580,7 +557,7 @@ void Player::updateInventoryImbuement() { bool nonAggressiveFightOnly = g_configManager().getBoolean(TOGGLE_IMBUEMENT_NON_AGGRESSIVE_FIGHT_ONLY); // Iterate through all items in the player's inventory - for (auto item : getAllInventoryItems()) { + for (auto [key, item] : getAllSlotItems()) { // Iterate through all imbuement slots on the item for (uint8_t slotid = 0; slotid < item->getImbuementSlot(); slotid++) { @@ -603,7 +580,7 @@ void Player::updateInventoryImbuement() { continue; } // If the item is not in the backpack slot and it's not a agressive imbuement, ignore it. - if (categoryImbuement && !categoryImbuement->agressive && parent && parent != this) { + if (categoryImbuement && !categoryImbuement->agressive && parent && parent != getPlayer()) { continue; } @@ -629,10 +606,24 @@ void Player::updateInventoryImbuement() { } } +phmap::flat_hash_map> Player::getAllSlotItems() const { + phmap::flat_hash_map> itemMap; + for (uint8_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { + std::shared_ptr item = inventory[i]; + if (!item) { + continue; + } + + itemMap[i] = item; + } + + return itemMap; +} + void Player::setTraining(bool value) { for (const auto &[key, player] : g_game().getPlayers()) { if (!this->isInGhostMode() || player->isAccessPlayer()) { - player->notifyStatusChange(this, value ? VIPSTATUS_TRAINING : VIPSTATUS_ONLINE, false); + player->notifyStatusChange(static_self_cast(), value ? VIPSTATUS_TRAINING : VIPSTATUS_ONLINE, false); } } this->statusVipList = VIPSTATUS_TRAINING; @@ -674,8 +665,8 @@ void Player::addSkillAdvance(skills_t skill, uint64_t count) { return; } - g_events().eventPlayerOnGainSkillTries(this, skill, count); - g_callbacks().executeCallback(EventCallback_t::playerOnGainSkillTries, &EventCallback::playerOnGainSkillTries, this, skill, count); + g_events().eventPlayerOnGainSkillTries(static_self_cast(), skill, count); + g_callbacks().executeCallback(EventCallback_t::playerOnGainSkillTries, &EventCallback::playerOnGainSkillTries, getPlayer(), skill, count); if (count == 0) { return; } @@ -691,7 +682,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(static_self_cast(), skill, (skills[skill].level - 1), skills[skill].level); sendUpdateSkills = true; currReqTries = nextReqTries; @@ -730,7 +721,7 @@ void Player::setVarStats(stats_t stat, int32_t modifier) { if (getHealth() > getMaxHealth()) { Creature::changeHealth(getMaxHealth() - getHealth()); } else { - g_game().addCreatureHealth(this); + g_game().addCreatureHealth(static_self_cast()); } break; } @@ -739,7 +730,7 @@ void Player::setVarStats(stats_t stat, int32_t modifier) { if (getMana() > getMaxMana()) { Creature::changeMana(getMaxMana() - getMana()); } else { - g_game().addPlayerMana(this); + g_game().addPlayerMana(static_self_cast()); } break; } @@ -763,7 +754,7 @@ int32_t Player::getDefaultStats(stats_t stat) const { } } -void Player::addContainer(uint8_t cid, Container* container) { +void Player::addContainer(uint8_t cid, std::shared_ptr container) { if (cid > 0xF) { return; } @@ -772,16 +763,11 @@ void Player::addContainer(uint8_t cid, Container* container) { return; } - if (container->getID() == ITEM_BROWSEFIELD) { - container->incrementReferenceCounter(); - } - auto it = openContainers.find(cid); if (it != openContainers.end()) { OpenContainer &openContainer = it->second; - Container* oldContainer = openContainer.container; + auto oldContainer = openContainer.container; if (oldContainer->getID() == ITEM_BROWSEFIELD) { - oldContainer->decrementReferenceCounter(); } openContainer.container = container; @@ -801,11 +787,10 @@ void Player::closeContainer(uint8_t cid) { } OpenContainer openContainer = it->second; - Container* container = openContainer.container; + std::shared_ptr container = openContainer.container; openContainers.erase(it); if (container && container->getID() == ITEM_BROWSEFIELD) { - container->decrementReferenceCounter(); } } @@ -817,7 +802,7 @@ void Player::setContainerIndex(uint8_t cid, uint16_t index) { it->second.index = index; } -Container* Player::getContainerByID(uint8_t cid) { +std::shared_ptr Player::getContainerByID(uint8_t cid) { auto it = openContainers.find(cid); if (it == openContainers.end()) { return nullptr; @@ -825,7 +810,7 @@ Container* Player::getContainerByID(uint8_t cid) { return it->second.container; } -int8_t Player::getContainerID(const Container* container) const { +int8_t Player::getContainerID(std::shared_ptr container) const { for (const auto &it : openContainers) { if (it.second.container == container) { return it.first; @@ -880,8 +865,8 @@ void Player::addStorageValue(const uint32_t key, const int32_t value, const bool if (!isLogin) { auto currentFrameTime = g_dispatcher().getDispatcherCycle(); - g_events().eventOnStorageUpdate(this, key, value, getStorageValue(key), currentFrameTime); - g_callbacks().executeCallback(EventCallback_t::playerOnStorageUpdate, &EventCallback::playerOnStorageUpdate, this, key, value, getStorageValue(key), currentFrameTime); + g_events().eventOnStorageUpdate(static_self_cast(), key, value, getStorageValue(key), currentFrameTime); + g_callbacks().executeCallback(EventCallback_t::playerOnStorageUpdate, &EventCallback::playerOnStorageUpdate, getPlayer(), key, value, getStorageValue(key), currentFrameTime); } } else { storageMap.erase(key); @@ -919,15 +904,15 @@ void Player::addStorageValueByName(const std::string &storageName, const int32_t addStorageValue(key, value, isLogin); } -bool Player::canSee(const Position &pos) const { +bool Player::canSee(const Position &pos) { if (!client) { return false; } return client->canSee(pos); } -bool Player::canSeeCreature(const Creature* creature) const { - if (creature == this) { +bool Player::canSeeCreature(std::shared_ptr creature) const { + if (creature.get() == this) { return true; } @@ -941,14 +926,14 @@ bool Player::canSeeCreature(const Creature* creature) const { return true; } -bool Player::canWalkthrough(const Creature* creature) const { +bool Player::canWalkthrough(std::shared_ptr creature) { if (group->access || creature->isInGhostMode()) { return true; } - const Player* player = creature->getPlayer(); - const Monster* monster = creature->getMonster(); - const Npc* npc = creature->getNpc(); + std::shared_ptr player = creature->getPlayer(); + std::shared_ptr monster = creature->getMonster(); + std::shared_ptr npc = creature->getNpc(); if (monster) { if (!monster->isFamiliar()) { return false; @@ -957,17 +942,17 @@ bool Player::canWalkthrough(const Creature* creature) const { } if (player) { - const Tile* playerTile = player->getTile(); + std::shared_ptr playerTile = player->getTile(); if (!playerTile || (!playerTile->hasFlag(TILESTATE_NOPVPZONE) && !playerTile->hasFlag(TILESTATE_PROTECTIONZONE) && player->getLevel() > static_cast(g_configManager().getNumber(PROTECTION_LEVEL)) && g_game().getWorldType() != WORLD_TYPE_NO_PVP)) { return false; } - const Item* playerTileGround = playerTile->getGround(); + std::shared_ptr playerTileGround = playerTile->getGround(); if (!playerTileGround || !playerTileGround->hasWalkStack()) { return false; } - Player* thisPlayer = const_cast(this); + std::shared_ptr thisPlayer = getPlayer(); if ((OTSYS_TIME() - lastWalkthroughAttempt) > 2000) { thisPlayer->setLastWalkthroughAttempt(OTSYS_TIME()); return false; @@ -981,20 +966,20 @@ bool Player::canWalkthrough(const Creature* creature) const { thisPlayer->setLastWalkthroughPosition(creature->getPosition()); return true; } else if (npc) { - const Tile* tile = npc->getTile(); - const HouseTile* houseTile = dynamic_cast(tile); + std::shared_ptr tile = npc->getTile(); + std::shared_ptr houseTile = std::dynamic_pointer_cast(tile); return (houseTile != nullptr); } return false; } -bool Player::canWalkthroughEx(const Creature* creature) const { +bool Player::canWalkthroughEx(std::shared_ptr creature) { if (group->access) { return true; } - const Monster* monster = creature->getMonster(); + std::shared_ptr monster = creature->getMonster(); if (monster) { if (!monster->isFamiliar()) { return false; @@ -1002,28 +987,28 @@ bool Player::canWalkthroughEx(const Creature* creature) const { return true; } - const Player* player = creature->getPlayer(); - const Npc* npc = creature->getNpc(); + std::shared_ptr player = creature->getPlayer(); + std::shared_ptr npc = creature->getNpc(); if (player) { - const Tile* playerTile = player->getTile(); + std::shared_ptr playerTile = player->getTile(); return playerTile && (playerTile->hasFlag(TILESTATE_NOPVPZONE) || playerTile->hasFlag(TILESTATE_PROTECTIONZONE) || player->getLevel() <= static_cast(g_configManager().getNumber(PROTECTION_LEVEL)) || g_game().getWorldType() == WORLD_TYPE_NO_PVP); } else if (npc) { - const Tile* tile = npc->getTile(); - const HouseTile* houseTile = dynamic_cast(tile); + std::shared_ptr tile = npc->getTile(); + std::shared_ptr houseTile = std::dynamic_pointer_cast(tile); return (houseTile != nullptr); } else { return false; } } -void Player::onReceiveMail() const { +void Player::onReceiveMail() { if (isNearDepotBox()) { sendTextMessage(MESSAGE_EVENT_ADVANCE, "New mail has arrived."); } } -Container* Player::setLootContainer(ObjectCategory_t category, Container* container, bool loading /* = false*/) { - Container* previousContainer = nullptr; +std::shared_ptr Player::setLootContainer(ObjectCategory_t category, std::shared_ptr container, bool loading /* = false*/) { + std::shared_ptr previousContainer = nullptr; if (auto it = quickLootContainers.find(category); it != quickLootContainers.end() && !loading) { previousContainer = (*it).second; @@ -1035,14 +1020,12 @@ Container* Player::setLootContainer(ObjectCategory_t category, Container* contai previousContainer->setAttribute(ItemAttribute_t::QUICKLOOTCONTAINER, flags); } - previousContainer->decrementReferenceCounter(); quickLootContainers.erase(it); } if (container) { previousContainer = container; quickLootContainers[category] = container; - container->incrementReferenceCounter(); if (!loading) { auto flags = container->getAttribute(ItemAttribute_t::QUICKLOOTCONTAINER); auto sendAttribute = flags | 1 << category; @@ -1054,7 +1037,7 @@ Container* Player::setLootContainer(ObjectCategory_t category, Container* contai return nullptr; } -Container* Player::getLootContainer(ObjectCategory_t category) const { +std::shared_ptr Player::getLootContainer(ObjectCategory_t category) const { if (category != OBJECTCATEGORY_DEFAULT && !isPremium()) { category = OBJECTCATEGORY_DEFAULT; } @@ -1072,12 +1055,12 @@ Container* Player::getLootContainer(ObjectCategory_t category) const { return nullptr; } -void Player::checkLootContainers(const Item* item) { +void Player::checkLootContainers(std::shared_ptr item) { if (!item) { return; } - const Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (!container) { return; } @@ -1086,10 +1069,10 @@ void Player::checkLootContainers(const Item* item) { auto it = quickLootContainers.begin(); while (it != quickLootContainers.end()) { - Container* lootContainer = (*it).second; + std::shared_ptr lootContainer = (*it).second; bool remove = false; - if (item->getHoldingPlayer() != this && (item == lootContainer || container->isHoldingItem(lootContainer))) { + if (item->getHoldingPlayer() != getPlayer() && (item == lootContainer || container->isHoldingItem(lootContainer))) { remove = true; } @@ -1097,7 +1080,6 @@ void Player::checkLootContainers(const Item* item) { shouldSend = true; it = quickLootContainers.erase(it); lootContainer->removeAttribute(ItemAttribute_t::QUICKLOOTCONTAINER); - lootContainer->decrementReferenceCounter(); } else { ++it; } @@ -1108,21 +1090,21 @@ void Player::checkLootContainers(const Item* item) { } } -void Player::sendLootStats(Item* item, uint8_t count) const { +void Player::sendLootStats(std::shared_ptr item, uint8_t count) { if (client) { client->sendLootStats(item, count); } if (party) { - party->addPlayerLoot(this, item); + party->addPlayerLoot(getPlayer(), item); } } -bool Player::isNearDepotBox() const { +bool Player::isNearDepotBox() { const Position &pos = getPosition(); for (int32_t cx = -1; cx <= 1; ++cx) { for (int32_t cy = -1; cy <= 1; ++cy) { - const Tile* posTile = g_game().map.getTile(static_cast(pos.x + cx), static_cast(pos.y + cy), pos.z); + std::shared_ptr posTile = g_game().map.getTile(static_cast(pos.x + cx), static_cast(pos.y + cy), pos.z); if (!posTile) { continue; } @@ -1135,7 +1117,7 @@ bool Player::isNearDepotBox() const { return false; } -DepotChest* Player::getDepotChest(uint32_t depotId, bool autoCreate) { +std::shared_ptr Player::getDepotChest(uint32_t depotId, bool autoCreate) { auto it = depotChests.find(depotId); if (it != depotChests.end()) { return it->second; @@ -1145,28 +1127,27 @@ DepotChest* Player::getDepotChest(uint32_t depotId, bool autoCreate) { return nullptr; } - DepotChest* depotChest; + std::shared_ptr depotChest; if (depotId > 0 && depotId < 18) { - depotChest = new DepotChest(ITEM_DEPOT_NULL + depotId); + depotChest = std::make_shared(ITEM_DEPOT_NULL + depotId); } else if (depotId == 18) { - depotChest = new DepotChest(ITEM_DEPOT_XVIII); + depotChest = std::make_shared(ITEM_DEPOT_XVIII); } else if (depotId == 19) { - depotChest = new DepotChest(ITEM_DEPOT_XIX); + depotChest = std::make_shared(ITEM_DEPOT_XIX); } else { - depotChest = new DepotChest(ITEM_DEPOT_XX); + depotChest = std::make_shared(ITEM_DEPOT_XX); } - depotChest->incrementReferenceCounter(); depotChests[depotId] = depotChest; return depotChest; } -DepotLocker* Player::getDepotLocker(uint32_t depotId) { +std::shared_ptr Player::getDepotLocker(uint32_t depotId) { auto it = depotLockerMap.find(depotId); if (it != depotLockerMap.end()) { inbox->setParent(it->second); for (uint32_t i = g_configManager().getNumber(DEPOT_BOXES); i > 0; i--) { - if (DepotChest* depotBox = getDepotChest(i, false)) { + if (std::shared_ptr depotBox = getDepotChest(i, false)) { depotBox->setParent(it->second->getItemByIndex(0)->getContainer()); } } @@ -1176,16 +1157,16 @@ DepotLocker* Player::getDepotLocker(uint32_t depotId) { // We need to make room for supply stash on 12+ protocol versions and remove it for 10x. bool createSupplyStash = !client->oldProtocol; - DepotLocker* depotLocker = new DepotLocker(ITEM_LOCKER, createSupplyStash ? 4 : 3); + std::shared_ptr depotLocker = std::make_shared(ITEM_LOCKER, createSupplyStash ? 4 : 3); depotLocker->setDepotId(depotId); depotLocker->internalAddThing(Item::CreateItem(ITEM_MARKET)); depotLocker->internalAddThing(inbox); if (createSupplyStash) { depotLocker->internalAddThing(Item::CreateItem(ITEM_SUPPLY_STASH)); } - Container* depotChest = Item::CreateItemAsContainer(ITEM_DEPOT, static_cast(g_configManager().getNumber(DEPOT_BOXES))); + std::shared_ptr depotChest = Item::CreateItemAsContainer(ITEM_DEPOT, static_cast(g_configManager().getNumber(DEPOT_BOXES))); for (uint32_t i = g_configManager().getNumber(DEPOT_BOXES); i > 0; i--) { - DepotChest* depotBox = getDepotChest(i, true); + std::shared_ptr depotBox = getDepotChest(i, true); depotChest->internalAddThing(depotBox); depotBox->setParent(depotChest); } @@ -1194,16 +1175,16 @@ DepotLocker* Player::getDepotLocker(uint32_t depotId) { return depotLocker; } -RewardChest* Player::getRewardChest() { +std::shared_ptr Player::getRewardChest() { if (rewardChest != nullptr) { return rewardChest; } - rewardChest = new RewardChest(ITEM_REWARD_CHEST); + rewardChest = std::make_shared(ITEM_REWARD_CHEST); return rewardChest; } -Reward* Player::getReward(const uint64_t rewardId, const bool autoCreate) { +std::shared_ptr Player::getReward(const uint64_t rewardId, const bool autoCreate) { auto it = rewardMap.find(rewardId); if (it != rewardMap.end()) { return it->second; @@ -1212,8 +1193,7 @@ Reward* Player::getReward(const uint64_t rewardId, const bool autoCreate) { return nullptr; } - auto reward = new Reward(); - reward->incrementReferenceCounter(); + auto reward = std::make_shared(); reward->setAttribute(ItemAttribute_t::DATE, rewardId); rewardMap[rewardId] = reward; g_game().internalAddItem(getRewardChest(), reward, INDEX_WHEREEVER, FLAG_NOLIMIT); @@ -1232,8 +1212,8 @@ void Player::getRewardList(std::vector &rewards) const { } } -std::vector Player::getRewardsFromContainer(const Container* container) const { - std::vector rewardItemsVector; +std::vector> Player::getRewardsFromContainer(std::shared_ptr container) const { + std::vector> rewardItemsVector; if (container) { for (auto item : container->getItems(false)) { if (item->getID() == ITEM_REWARD_CONTAINER) { @@ -1259,13 +1239,13 @@ void Player::sendStats() { } } -void Player::updateSupplyTracker(const Item* item) const { +void Player::updateSupplyTracker(std::shared_ptr item) { if (client) { client->sendUpdateSupplyTracker(item); } if (party) { - party->addPlayerSupply(this, item); + party->addPlayerSupply(getPlayer(), item); } } @@ -1289,67 +1269,55 @@ void Player::sendPing() { } int64_t noPongTime = timeNow - lastPong; + auto attackedCreature = getAttackedCreature(); if ((hasLostConnection || noPongTime >= 7000) && attackedCreature && attackedCreature->getPlayer()) { setAttackedCreature(nullptr); } - if (noPongTime >= 60000 && canLogout() && g_creatureEvents().playerLogout(this)) { + if (noPongTime >= 60000 && canLogout() && g_creatureEvents().playerLogout(static_self_cast())) { if (client) { client->logout(true, true); } else { - g_game().removeCreature(this, true); + g_game().removeCreature(static_self_cast(), true); } } } -Item* Player::getWriteItem(uint32_t &retWindowTextId, uint16_t &retMaxWriteLen) { +std::shared_ptr Player::getWriteItem(uint32_t &retWindowTextId, uint16_t &retMaxWriteLen) { retWindowTextId = this->windowTextId; retMaxWriteLen = this->maxWriteLen; return writeItem; } -void Player::setImbuingItem(Item* item) { - if (imbuingItem) { - imbuingItem->decrementReferenceCounter(); - } - - if (item) { - item->incrementReferenceCounter(); - } - +void Player::setImbuingItem(std::shared_ptr item) { imbuingItem = item; } -void Player::setWriteItem(Item* item, uint16_t maxWriteLength /*= 0*/) { +void Player::setWriteItem(std::shared_ptr item, uint16_t maxWriteLength /*= 0*/) { windowTextId++; - if (writeItem) { - writeItem->decrementReferenceCounter(); - } - if (item) { writeItem = item; this->maxWriteLen = maxWriteLength; - writeItem->incrementReferenceCounter(); } else { writeItem = nullptr; this->maxWriteLen = 0; } } -House* Player::getEditHouse(uint32_t &retWindowTextId, uint32_t &retListId) { +std::shared_ptr Player::getEditHouse(uint32_t &retWindowTextId, uint32_t &retListId) { retWindowTextId = this->windowTextId; retListId = this->editListId; return editHouse; } -void Player::setEditHouse(House* house, uint32_t listId /*= 0*/) { +void Player::setEditHouse(std::shared_ptr house, uint32_t listId /*= 0*/) { windowTextId++; editHouse = house; editListId = listId; } -void Player::sendHouseWindow(House* house, uint32_t listId) const { +void Player::sendHouseWindow(std::shared_ptr house, uint32_t listId) const { if (!client) { return; } @@ -1360,7 +1328,7 @@ void Player::sendHouseWindow(House* house, uint32_t listId) const { } } -void Player::onApplyImbuement(Imbuement* imbuement, Item* item, uint8_t slot, bool protectionCharm) { +void Player::onApplyImbuement(Imbuement* imbuement, std::shared_ptr item, uint8_t slot, bool protectionCharm) { if (!imbuement || !item) { return; } @@ -1372,10 +1340,10 @@ void Player::onApplyImbuement(Imbuement* imbuement, Item* item, uint8_t slot, bo return; } - const auto &items = imbuement->getItems(); + const auto items = imbuement->getItems(); for (auto &[key, value] : items) { const ItemType &itemType = Item::items[key]; - if (this->getItemTypeCount(key) + this->getStashItemCount(itemType.id) < value) { + if (static_self_cast()->getItemTypeCount(key) + this->getStashItemCount(itemType.id) < value) { this->sendImbuementResult("You don't have all necessary items."); return; } @@ -1389,7 +1357,7 @@ void Player::onApplyImbuement(Imbuement* imbuement, Item* item, uint8_t slot, bo uint32_t price = baseImbuement->price; price += protectionCharm ? baseImbuement->protectionPrice : 0; - if (!g_game().removeMoney(this, price, 0, true)) { + if (!g_game().removeMoney(static_self_cast(), price, 0, true)) { std::string message = fmt::format("You don't have {} gold coins.", price); g_logger().error("[Player::onApplyImbuement] - An error occurred while player with name {} try to apply imbuement, player do not have money", this->getName()); @@ -1426,7 +1394,7 @@ void Player::onApplyImbuement(Imbuement* imbuement, Item* item, uint8_t slot, bo } // Update imbuement stats item if the item is equipped - if (item->getParent() == this) { + if (item->getParent() == getPlayer()) { addItemImbuementStats(imbuement); } @@ -1434,7 +1402,7 @@ void Player::onApplyImbuement(Imbuement* imbuement, Item* item, uint8_t slot, bo openImbuementWindow(item); } -void Player::onClearImbuement(Item* item, uint8_t slot) { +void Player::onClearImbuement(std::shared_ptr item, uint8_t slot) { if (!item) { return; } @@ -1451,7 +1419,7 @@ void Player::onClearImbuement(Item* item, uint8_t slot) { return; } - if (!g_game().removeMoney(this, baseImbuement->removeCost, 0, true)) { + if (!g_game().removeMoney(static_self_cast(), baseImbuement->removeCost, 0, true)) { std::string message = fmt::format("You don't have {} gold coins.", baseImbuement->removeCost); g_logger().error("[Player::onClearImbuement] - An error occurred while player with name {} try to apply imbuement, player do not have money", this->getName()); @@ -1460,7 +1428,7 @@ void Player::onClearImbuement(Item* item, uint8_t slot) { return; } - if (item->getParent() == this) { + if (item->getParent() == getPlayer()) { removeItemImbuementStats(imbuementInfo.imbuement); } @@ -1468,7 +1436,7 @@ void Player::onClearImbuement(Item* item, uint8_t slot) { this->openImbuementWindow(item); } -void Player::openImbuementWindow(Item* item) { +void Player::openImbuementWindow(std::shared_ptr item) { if (!client || !item) { return; } @@ -1479,7 +1447,7 @@ void Player::openImbuementWindow(Item* item) { } auto itemParent = item->getTopParent(); - if (itemParent && itemParent != this) { + if (itemParent && itemParent != getPlayer()) { this->sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have to pick up the item to imbue it."); return; } @@ -1487,6 +1455,12 @@ void Player::openImbuementWindow(Item* item) { client->openImbuementWindow(item); } +void Player::sendSaleItemList(const std::map &inventoryMap) const { + if (client && shopOwner) { + client->sendSaleItemList(shopOwner->getShopItemVector(), inventoryMap); + } +} + void Player::sendMarketEnter(uint32_t depotId) { if (!client || this->getLastDepotId() == -1 || !depotId) { return; @@ -1496,7 +1470,7 @@ void Player::sendMarketEnter(uint32_t depotId) { } // container -void Player::sendAddContainerItem(const Container* container, const Item* item) { +void Player::sendAddContainerItem(std::shared_ptr container, std::shared_ptr item) { if (!client) { return; } @@ -1528,7 +1502,7 @@ void Player::sendAddContainerItem(const Container* container, const Item* item) } } -void Player::sendUpdateContainerItem(const Container* container, uint16_t slot, const Item* newItem) { +void Player::sendUpdateContainerItem(std::shared_ptr container, uint16_t slot, std::shared_ptr newItem) { if (!client) { return; } @@ -1552,7 +1526,7 @@ void Player::sendUpdateContainerItem(const Container* container, uint16_t slot, } } -void Player::sendRemoveContainerItem(const Container* container, uint16_t slot) { +void Player::sendRemoveContainerItem(std::shared_ptr container, uint16_t slot) { if (!client) { return; } @@ -1577,7 +1551,7 @@ void Player::sendRemoveContainerItem(const Container* container, uint16_t slot) } } -void Player::onUpdateTileItem(const Tile* updateTile, const Position &pos, const Item* oldItem, const ItemType &oldType, const Item* newItem, const ItemType &newType) { +void Player::onUpdateTileItem(std::shared_ptr updateTile, const Position &pos, std::shared_ptr oldItem, const ItemType &oldType, std::shared_ptr newItem, const ItemType &newType) { Creature::onUpdateTileItem(updateTile, pos, oldItem, oldType, newItem, newType); if (oldItem != newItem) { @@ -1586,21 +1560,21 @@ void Player::onUpdateTileItem(const Tile* updateTile, const Position &pos, const if (tradeState != TRADE_TRANSFER) { if (tradeItem && oldItem == tradeItem) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(getPlayer()); } } } -void Player::onRemoveTileItem(const Tile* fromTile, const Position &pos, const ItemType &iType, const Item* item) { +void Player::onRemoveTileItem(std::shared_ptr fromTile, const Position &pos, const ItemType &iType, std::shared_ptr item) { Creature::onRemoveTileItem(fromTile, pos, iType, item); if (tradeState != TRADE_TRANSFER) { checkTradeState(item); if (tradeItem) { - const Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && container->isHoldingItem(tradeItem)) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(static_self_cast()); } } } @@ -1608,35 +1582,35 @@ void Player::onRemoveTileItem(const Tile* fromTile, const Position &pos, const I checkLootContainers(item); } -void Player::onCreatureAppear(Creature* creature, bool isLogin) { +void Player::onCreatureAppear(std::shared_ptr creature, bool isLogin) { Creature::onCreatureAppear(creature, isLogin); - if (isLogin && creature == this) { + if (isLogin && creature == getPlayer()) { for (int32_t slot = CONST_SLOT_FIRST; slot <= CONST_SLOT_LAST; ++slot) { - Item* item = inventory[slot]; + std::shared_ptr item = inventory[slot]; if (item) { item->startDecaying(); - g_moveEvents().onPlayerEquip(*this, *item, static_cast(slot), false); + g_moveEvents().onPlayerEquip(getPlayer(), item, static_cast(slot), false); } } - for (Condition* condition : storedConditionList) { + for (const auto &condition : storedConditionList) { addCondition(condition); } storedConditionList.clear(); updateRegeneration(); - BedItem* bed = g_game().getBedBySleeper(guid); + std::shared_ptr bed = g_game().getBedBySleeper(guid); if (bed) { - bed->wakeUp(this); + bed->wakeUp(static_self_cast()); } auto version = client->oldProtocol ? getProtocolVersion() : CLIENT_VERSION; g_logger().info("{} has logged in. (Protocol: {})", name, version); if (guild) { - guild->addMember(this); + guild->addMember(static_self_cast()); } int32_t offlineTime; @@ -1647,16 +1621,13 @@ void Player::onCreatureAppear(Creature* creature, bool isLogin) { offlineTime = 0; } - for (Condition* condition : getMuteConditions()) { + for (std::shared_ptr condition : getMuteConditions()) { condition->setTicks(condition->getTicks() - (offlineTime * 1000)); if (condition->getTicks() <= 0) { removeCondition(condition); } } - // Reload bestiary tracker - refreshBestiaryMonsterTracker(); - g_game().checkPlayersRecord(); IOLoginData::updateOnlineStatus(guid, true); if (getLevel() < g_configManager().getNumber(ADVENTURERSBLESSING_LEVEL)) { @@ -1688,14 +1659,14 @@ void Player::onFollowCreatureDisappear(bool isLogout) { void Player::onChangeZone(ZoneType_t zone) { if (zone == ZONE_PROTECTION) { - if (attackedCreature && !hasFlag(PlayerFlags_t::IgnoreProtectionZone)) { + if (getAttackedCreature() && !hasFlag(PlayerFlags_t::IgnoreProtectionZone)) { setAttackedCreature(nullptr); onAttackedCreatureDisappear(false); } - if (!group->access && isMounted()) { + if (!g_configManager().getBoolean(TOGGLE_MOUNT_IN_PZ) && !group->access && isMounted()) { dismount(); - g_game().internalCreatureChangeOutfit(this, defaultOutfit); + g_game().internalCreatureChangeOutfit(getPlayer(), defaultOutfit); wasMounted = true; } } else { @@ -1708,14 +1679,18 @@ void Player::onChangeZone(ZoneType_t zone) { updateImbuementTrackerStats(); wheel()->onThink(true); wheel()->sendGiftOfLifeCooldown(); - g_game().updateCreatureWalkthrough(this); + g_game().updateCreatureWalkthrough(static_self_cast()); sendIcons(); - g_events().eventPlayerOnChangeZone(this, zone); + g_events().eventPlayerOnChangeZone(static_self_cast(), zone); - g_callbacks().executeCallback(EventCallback_t::playerOnChangeZone, &EventCallback::playerOnChangeZone, this, zone); + g_callbacks().executeCallback(EventCallback_t::playerOnChangeZone, &EventCallback::playerOnChangeZone, getPlayer(), zone); } void Player::onAttackedCreatureChangeZone(ZoneType_t zone) { + auto attackedCreature = getAttackedCreature(); + if (!attackedCreature) { + return; + } if (zone == ZONE_PROTECTION) { if (!hasFlag(PlayerFlags_t::IgnoreProtectionZone)) { setAttackedCreature(nullptr); @@ -1737,23 +1712,23 @@ void Player::onAttackedCreatureChangeZone(ZoneType_t zone) { } } -void Player::onRemoveCreature(Creature* creature, bool isLogout) { +void Player::onRemoveCreature(std::shared_ptr creature, bool isLogout) { Creature::onRemoveCreature(creature, isLogout); - if (creature == this) { + if (creature == getPlayer()) { if (isLogout) { if (party) { - party->leaveParty(this); + party->leaveParty(static_self_cast()); } if (guild) { - guild->removeMember(this); + guild->removeMember(static_self_cast()); } - g_game().removePlayerUniqueLogin(this); + g_game().removePlayerUniqueLogin(static_self_cast()); loginPosition = getPosition(); lastLogout = time(nullptr); g_logger().info("{} has logged out", getName()); - g_chat().removeUserFromAllChannels(*this); + g_chat().removeUserFromAllChannels(getPlayer()); clearPartyInvitations(); IOLoginData::updateOnlineStatus(guid, false); } @@ -1763,13 +1738,13 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout) { } if (tradePartner) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(static_self_cast()); } closeShopWindow(); for (uint32_t tries = 0; tries < 3; ++tries) { - if (IOLoginData::savePlayer(this)) { + if (IOLoginData::savePlayer(static_self_cast())) { break; } } @@ -1781,14 +1756,14 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout) { } } -bool Player::openShopWindow(Npc* npc) { +bool Player::openShopWindow(std::shared_ptr npc) { if (!npc) { g_logger().error("[Player::openShopWindow] - Npc is wrong or nullptr"); return false; } setShopOwner(npc); - npc->addShopPlayer(this); + npc->addShopPlayer(static_self_cast()); sendShop(npc); std::map inventoryMap; @@ -1801,7 +1776,7 @@ bool Player::closeShopWindow(bool sendCloseShopWindow /*= true*/) { return false; } - shopOwner->removeShopPlayer(this); + shopOwner->removeShopPlayer(static_self_cast()); setShopOwner(nullptr); if (sendCloseShopWindow) { @@ -1815,9 +1790,9 @@ void Player::onWalk(Direction &dir) { if (hasCondition(CONDITION_FEARED)) { Position pos = getNextPosition(dir, getPosition()); - const Tile* tile = g_game().map.getTile(pos); + std::shared_ptr tile = g_game().map.getTile(pos); if (tile) { - const MagicField* field = tile->getFieldItem(); + std::shared_ptr field = tile->getFieldItem(); if (field && !field->isBlocking() && field->getDamage() != 0) { setNextActionTask(nullptr); setNextAction(OTSYS_TIME() + getStepDuration(dir)); @@ -1831,26 +1806,27 @@ void Player::onWalk(Direction &dir) { setNextAction(OTSYS_TIME() + getStepDuration(dir)); } -void Player::onCreatureMove(Creature* creature, const Tile* newTile, const Position &newPos, const Tile* oldTile, const Position &oldPos, bool teleport) { +void Player::onCreatureMove(std::shared_ptr creature, std::shared_ptr newTile, const Position &newPos, std::shared_ptr oldTile, const Position &oldPos, bool teleport) { Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport); - if (hasFollowPath && (creature == followCreature || (creature == this && followCreature))) { + auto followCreature = getFollowCreature(); + if (hasFollowPath && (creature == followCreature || (creature.get() == this && followCreature))) { isUpdatingPath = false; g_dispatcher().addTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()), "Game::updateCreatureWalk"); } - if (creature != this) { + if (creature != getPlayer()) { return; } if (tradeState != TRADE_TRANSFER) { // check if we should close trade if (tradeItem && !Position::areInRange<1, 1, 0>(tradeItem->getPosition(), getPosition())) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(getPlayer()); } if (tradePartner && !Position::areInRange<2, 2, 0>(tradePartner->getPosition(), getPosition())) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(static_self_cast()); } } @@ -1873,13 +1849,13 @@ void Player::onCreatureMove(Creature* creature, const Tile* newTile, const Posit if (party) { party->updateSharedExperience(); - party->updatePlayerStatus(this, oldPos, newPos); + party->updatePlayerStatus(static_self_cast(), oldPos, newPos); } if (teleport || oldPos.z != newPos.z) { int32_t ticks = g_configManager().getNumber(STAIRHOP_DELAY); if (ticks > 0) { - if (Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_PACIFIED, ticks, 0)) { + if (std::shared_ptr condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_PACIFIED, ticks, 0)) { addCondition(condition); } } @@ -1887,11 +1863,11 @@ void Player::onCreatureMove(Creature* creature, const Tile* newTile, const Posit } // container -void Player::onAddContainerItem(const Item* item) { +void Player::onAddContainerItem(std::shared_ptr item) { checkTradeState(item); } -void Player::onUpdateContainerItem(const Container* container, const Item* oldItem, const Item* newItem) { +void Player::onUpdateContainerItem(std::shared_ptr container, std::shared_ptr oldItem, std::shared_ptr newItem) { if (oldItem != newItem) { onRemoveContainerItem(container, oldItem); } @@ -1901,13 +1877,13 @@ void Player::onUpdateContainerItem(const Container* container, const Item* oldIt } } -void Player::onRemoveContainerItem(const Container* container, const Item* item) { +void Player::onRemoveContainerItem(std::shared_ptr container, std::shared_ptr item) { if (tradeState != TRADE_TRANSFER) { checkTradeState(item); if (tradeItem) { if (tradeItem->getParent() != container && container->isHoldingItem(tradeItem)) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(static_self_cast()); } } } @@ -1915,7 +1891,7 @@ void Player::onRemoveContainerItem(const Container* container, const Item* item) checkLootContainers(item); } -void Player::onCloseContainer(const Container* container) { +void Player::onCloseContainer(std::shared_ptr container) { if (!client) { return; } @@ -1927,7 +1903,7 @@ void Player::onCloseContainer(const Container* container) { } } -void Player::onSendContainer(const Container* container) { +void Player::onSendContainer(std::shared_ptr container) { if (!client || !container) { return; } @@ -1942,7 +1918,7 @@ void Player::onSendContainer(const Container* container) { } // inventory -void Player::onUpdateInventoryItem(Item* oldItem, Item* newItem) { +void Player::onUpdateInventoryItem(std::shared_ptr oldItem, std::shared_ptr newItem) { if (oldItem != newItem) { onRemoveInventoryItem(oldItem); } @@ -1952,14 +1928,14 @@ void Player::onUpdateInventoryItem(Item* oldItem, Item* newItem) { } } -void Player::onRemoveInventoryItem(Item* item) { +void Player::onRemoveInventoryItem(std::shared_ptr item) { if (tradeState != TRADE_TRANSFER) { checkTradeState(item); if (tradeItem) { - const Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && container->isHoldingItem(tradeItem)) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(static_self_cast()); } } } @@ -1967,22 +1943,22 @@ void Player::onRemoveInventoryItem(Item* item) { checkLootContainers(item); } -void Player::checkTradeState(const Item* item) { +void Player::checkTradeState(std::shared_ptr item) { if (!tradeItem || tradeState == TRADE_TRANSFER) { return; } if (tradeItem == item) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(static_self_cast()); } else { - const Container* container = dynamic_cast(item->getParent()); + std::shared_ptr container = std::dynamic_pointer_cast(item->getParent()); while (container) { if (container == tradeItem) { - g_game().internalCloseTrade(this); + g_game().internalCloseTrade(static_self_cast()); break; } - container = dynamic_cast(container->getParent()); + container = std::dynamic_pointer_cast(container->getParent()); } } } @@ -2113,7 +2089,7 @@ uint32_t Player::isMuted() const { } int32_t muteTicks = 0; - for (Condition* condition : conditions) { + for (std::shared_ptr condition : conditions) { if (condition->getType() == CONDITION_MUTED && condition->getTicks() > muteTicks) { muteTicks = condition->getTicks(); } @@ -2143,7 +2119,7 @@ void Player::removeMessageBuffer() { uint32_t muteTime = 5 * muteCount * muteCount; muteCountMap[guid] = muteCount + 1; - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_MUTED, muteTime * 1000, 0); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_MUTED, muteTime * 1000, 0); addCondition(condition); std::ostringstream ss; @@ -2153,16 +2129,16 @@ void Player::removeMessageBuffer() { } } -void Player::drainHealth(Creature* attacker, int32_t damage) { +void Player::drainHealth(std::shared_ptr attacker, int32_t damage) { if (PLAYER_SOUND_HEALTH_CHANGE >= static_cast(uniform_random(1, 100))) { - g_game().sendSingleSoundEffect(this->getPosition(), sex == PLAYERSEX_FEMALE ? SoundEffect_t::HUMAN_FEMALE_BARK : SoundEffect_t::HUMAN_MALE_BARK, this); + g_game().sendSingleSoundEffect(static_self_cast()->getPosition(), sex == PLAYERSEX_FEMALE ? SoundEffect_t::HUMAN_FEMALE_BARK : SoundEffect_t::HUMAN_MALE_BARK, getPlayer()); } Creature::drainHealth(attacker, damage); sendStats(); } -void Player::drainMana(Creature* attacker, int32_t manaLoss) { +void Player::drainMana(std::shared_ptr attacker, int32_t manaLoss) { Creature::drainMana(attacker, manaLoss); sendStats(); } @@ -2179,8 +2155,8 @@ void Player::addManaSpent(uint64_t amount) { return; } - g_events().eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, amount); - g_callbacks().executeCallback(EventCallback_t::playerOnGainSkillTries, &EventCallback::playerOnGainSkillTries, this, SKILL_MAGLEVEL, amount); + g_events().eventPlayerOnGainSkillTries(static_self_cast(), SKILL_MAGLEVEL, amount); + g_callbacks().executeCallback(EventCallback_t::playerOnGainSkillTries, &EventCallback::playerOnGainSkillTries, getPlayer(), SKILL_MAGLEVEL, amount); if (amount == 0) { return; } @@ -2196,7 +2172,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(static_self_cast(), SKILL_MAGLEVEL, magLevel - 1, magLevel); sendUpdateStats = true; currReqMana = nextReqMana; @@ -2225,7 +2201,7 @@ void Player::addManaSpent(uint64_t amount) { } } -void Player::addExperience(Creature* target, uint64_t exp, bool sendText /* = false*/) { +void Player::addExperience(std::shared_ptr target, uint64_t exp, bool sendText /* = false*/) { uint64_t currLevelExp = Player::getExpForLevel(level); uint64_t nextLevelExp = Player::getExpForLevel(level + 1); uint64_t rawExp = exp; @@ -2236,15 +2212,15 @@ void Player::addExperience(Creature* target, uint64_t exp, bool sendText /* = fa return; } - g_callbacks().executeCallback(EventCallback_t::playerOnGainExperience, &EventCallback::playerOnGainExperience, this, target, exp, rawExp); + g_callbacks().executeCallback(EventCallback_t::playerOnGainExperience, &EventCallback::playerOnGainExperience, getPlayer(), target, exp, rawExp); - g_events().eventPlayerOnGainExperience(this, target, exp, rawExp); + g_events().eventPlayerOnGainExperience(static_self_cast(), target, exp, rawExp); if (exp == 0) { return; } // Hazard system experience - const Monster* monster = target && target->getMonster() ? target->getMonster() : nullptr; + std::shared_ptr monster = target && target->getMonster() ? target->getMonster() : nullptr; bool handleHazardExperience = monster && monster->getHazard() && getHazardSystemPoints() > 0; if (handleHazardExperience) { exp += (exp * (1.75 * getHazardSystemPoints() * g_configManager().getNumber(HAZARD_EXP_BONUS_MULTIPLIER))) / 100.; @@ -2269,11 +2245,11 @@ void Player::addExperience(Creature* target, uint64_t exp, bool sendText /* = fa SpectatorHashSet spectators; g_game().map.getSpectators(spectators, position, false, true); - spectators.erase(this); + spectators.erase(static_self_cast()); if (!spectators.empty()) { message.type = MESSAGE_EXPERIENCE_OTHERS; message.text = getName() + " gained " + expString; - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { spectator->getPlayer()->sendTextMessage(message); } } @@ -2312,15 +2288,15 @@ void Player::addExperience(Creature* target, uint64_t exp, bool sendText /* = fa updateBaseSpeed(); setBaseSpeed(getBaseSpeed()); - g_game().changeSpeed(this, 0); - g_game().addCreatureHealth(this); - g_game().addPlayerMana(this); + g_game().changeSpeed(static_self_cast(), 0); + g_game().addCreatureHealth(static_self_cast()); + g_game().addPlayerMana(static_self_cast()); if (party) { party->updateSharedExperience(); } - g_creatureEvents().playerAdvance(this, SKILL_LEVEL, prevLevel, level); + g_creatureEvents().playerAdvance(static_self_cast(), SKILL_LEVEL, prevLevel, level); std::ostringstream ss; ss << "You advanced from Level " << prevLevel << " to Level " << level << '.'; @@ -2341,8 +2317,8 @@ void Player::removeExperience(uint64_t exp, bool sendText /* = false*/) { return; } - g_events().eventPlayerOnLoseExperience(this, exp); - g_callbacks().executeCallback(EventCallback_t::playerOnLoseExperience, &EventCallback::playerOnLoseExperience, this, exp); + g_events().eventPlayerOnLoseExperience(static_self_cast(), exp); + g_callbacks().executeCallback(EventCallback_t::playerOnLoseExperience, &EventCallback::playerOnLoseExperience, getPlayer(), exp); if (exp == 0) { return; } @@ -2363,11 +2339,11 @@ void Player::removeExperience(uint64_t exp, bool sendText /* = false*/) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, position, false, true); - spectators.erase(this); + spectators.erase(static_self_cast()); if (!spectators.empty()) { message.type = MESSAGE_EXPERIENCE_OTHERS; message.text = getName() + " lost " + expString; - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { spectator->getPlayer()->sendTextMessage(message); } } @@ -2399,9 +2375,9 @@ void Player::removeExperience(uint64_t exp, bool sendText /* = false*/) { updateBaseSpeed(); setBaseSpeed(getBaseSpeed()); - g_game().changeSpeed(this, 0); - g_game().addCreatureHealth(this); - g_game().addPlayerMana(this); + g_game().changeSpeed(static_self_cast(), 0); + g_game().addCreatureHealth(static_self_cast()); + g_game().addPlayerMana(static_self_cast()); if (party) { party->updateSharedExperience(); @@ -2475,7 +2451,7 @@ void Player::onAttackedCreatureBlockHit(BlockType_t blockType) { } bool Player::hasShield() const { - Item* item = inventory[CONST_SLOT_LEFT]; + std::shared_ptr item = inventory[CONST_SLOT_LEFT]; if (item && item->getWeaponType() == WEAPON_SHIELD) { return true; } @@ -2487,7 +2463,7 @@ bool Player::hasShield() const { return false; } -BlockType_t Player::blockHit(Creature* attacker, CombatType_t combatType, int32_t &damage, bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool field /* = false*/) { +BlockType_t Player::blockHit(std::shared_ptr attacker, CombatType_t combatType, int32_t &damage, bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool field /* = false*/) { BlockType_t blockType = Creature::blockHit(attacker, combatType, damage, checkDefense, checkArmor, field); if (attacker) { sendCreatureSquare(attacker, SQ_COLOR_BLACK); @@ -2503,7 +2479,7 @@ BlockType_t Player::blockHit(Creature* attacker, CombatType_t combatType, int32_ continue; } - Item* item = inventory[slot]; + std::shared_ptr item = inventory[slot]; if (!item) { continue; } @@ -2564,10 +2540,10 @@ uint32_t Player::getIP() const { return 0; } -void Player::death(Creature* lastHitCreature) { +void Player::death(std::shared_ptr lastHitCreature) { loginPosition = town->getTemplePosition(); - g_game().sendSingleSoundEffect(this->getPosition(), sex == PLAYERSEX_FEMALE ? SoundEffect_t::HUMAN_FEMALE_DEATH : SoundEffect_t::HUMAN_MALE_DEATH, this); + g_game().sendSingleSoundEffect(static_self_cast()->getPosition(), sex == PLAYERSEX_FEMALE ? SoundEffect_t::HUMAN_FEMALE_DEATH : SoundEffect_t::HUMAN_MALE_DEATH, getPlayer()); if (skillLoss) { uint8_t unfairFightReduction = 100; int playerDmg = 0; @@ -2577,7 +2553,7 @@ void Player::death(Creature* lastHitCreature) { for (const auto &it : damageMap) { CountBlock_t cb = it.second; if ((OTSYS_TIME() - cb.ticks) <= inFightTicks) { - const Player* damageDealer = g_game().getPlayerByID(it.first); + std::shared_ptr damageDealer = g_game().getPlayerByID(it.first); if (damageDealer) { playerDmg += cb.total; sumLevels += damageDealer->getLevel(); @@ -2637,8 +2613,8 @@ void Player::death(Creature* lastHitCreature) { // Level loss uint64_t expLoss = static_cast(experience * deathLossPercent); - g_events().eventPlayerOnLoseExperience(this, expLoss); - g_callbacks().executeCallback(EventCallback_t::playerOnLoseExperience, &EventCallback::playerOnLoseExperience, this, expLoss); + g_events().eventPlayerOnLoseExperience(static_self_cast(), expLoss); + g_callbacks().executeCallback(EventCallback_t::playerOnLoseExperience, &EventCallback::playerOnLoseExperience, getPlayer(), expLoss); sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead."); std::ostringstream lostExp; @@ -2745,14 +2721,13 @@ void Player::death(Creature* lastHitCreature) { auto it = conditions.begin(), end = conditions.end(); while (it != end) { - Condition* condition = *it; + std::shared_ptr condition = *it; // isSupress block to delete spells conditions (ensures that the player cannot, for example, reset the cooldown time of the familiar and summon several) if (condition->isPersistent() && condition->isRemovableOnDeath()) { it = conditions.erase(it); - condition->endCondition(this); + condition->endCondition(static_self_cast()); onEndCondition(condition->getType()); - delete condition; } else { ++it; } @@ -2762,22 +2737,21 @@ void Player::death(Creature* lastHitCreature) { auto it = conditions.begin(), end = conditions.end(); while (it != end) { - Condition* condition = *it; + std::shared_ptr condition = *it; if (condition->isPersistent()) { it = conditions.erase(it); - condition->endCondition(this); + condition->endCondition(static_self_cast()); onEndCondition(condition->getType()); - delete condition; } else { ++it; } } health = healthMax; - g_game().internalTeleport(this, getTemplePosition(), true); - g_game().addCreatureHealth(this); - g_game().addPlayerMana(this); + g_game().internalTeleport(static_self_cast(), getTemplePosition(), true); + g_game().addCreatureHealth(static_self_cast()); + g_game().addPlayerMana(static_self_cast()); onThink(EVENT_CREATURE_THINK_INTERVAL); onIdleStatus(); sendStats(); @@ -2791,27 +2765,27 @@ bool Player::spawn() { const Position &pos = getLoginPosition(); - if (!g_game().map.placeCreature(pos, this, false, true)) { + if (!g_game().map.placeCreature(pos, getPlayer(), false, true)) { return false; } SpectatorHashSet spectators; g_game().map.getSpectators(spectators, position, true); - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { if (!spectator) { continue; } - if (Player* tmpPlayer = spectator->getPlayer()) { - tmpPlayer->sendCreatureAppear(this, pos, true); + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { + tmpPlayer->sendCreatureAppear(static_self_cast(), pos, true); } - spectator->onCreatureAppear(this, false); + spectator->onCreatureAppear(static_self_cast(), false); } - getParent()->postAddNotification(this, nullptr, 0); - g_game().addCreatureCheck(this); - g_game().addPlayer(this); + getParent()->postAddNotification(static_self_cast(), nullptr, 0); + g_game().addCreatureCheck(static_self_cast()); + g_game().addPlayer(static_self_cast()); return true; } @@ -2824,14 +2798,14 @@ void Player::despawn() { stopEventWalk(); onWalkAborted(); closeAllExternalContainers(); - g_game().playerSetAttackedCreature(this->getID(), 0); - g_game().playerFollowCreature(this->getID(), 0); + g_game().playerSetAttackedCreature(static_self_cast()->getID(), 0); + g_game().playerFollowCreature(static_self_cast()->getID(), 0); // remove check - Game::removeCreatureCheck(this); + Game::removeCreatureCheck(static_self_cast()); // remove from map - Tile* tile = getTile(); + std::shared_ptr tile = getTile(); if (!tile) { return; } @@ -2841,36 +2815,36 @@ void Player::despawn() { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, tile->getPosition(), true); size_t i = 0; - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { if (!spectator) { continue; } - if (const Player* player = spectator->getPlayer()) { - oldStackPosVector.push_back(player->canSeeCreature(this) ? tile->getStackposOfCreature(player, this) : -1); + if (const auto player = spectator->getPlayer()) { + oldStackPosVector.push_back(player->canSeeCreature(static_self_cast()) ? tile->getStackposOfCreature(player, getPlayer()) : -1); } - if (Player* player = spectator->getPlayer()) { + if (auto player = spectator->getPlayer()) { player->sendRemoveTileThing(tile->getPosition(), oldStackPosVector[i++]); } - spectator->onRemoveCreature(this, false); + spectator->onRemoveCreature(static_self_cast(), false); } - tile->removeCreature(this); + tile->removeCreature(static_self_cast()); - getParent()->postRemoveNotification(this, nullptr, 0); + getParent()->postRemoveNotification(static_self_cast(), nullptr, 0); - g_game().removePlayer(this); + g_game().removePlayer(static_self_cast()); // show player as pending for (const auto &[key, player] : g_game().getPlayers()) { - player->notifyStatusChange(this, VIPSTATUS_PENDING, false); + player->notifyStatusChange(static_self_cast(), VIPSTATUS_PENDING, false); } setDead(true); } -bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified) { +bool Player::dropCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified) { if (getZoneType() != ZONE_PVP || !Player::lastHitIsPlayer(lastHitCreature)) { return Creature::dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified); } @@ -2879,8 +2853,8 @@ bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, return false; } -Item* Player::getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature) { - Item* corpse = Creature::getCorpse(lastHitCreature, mostDamageCreature); +std::shared_ptr Player::getCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature) { + std::shared_ptr corpse = Creature::getCorpse(lastHitCreature, mostDamageCreature); if (corpse && corpse->getContainer()) { std::ostringstream ss; if (lastHitCreature) { @@ -2910,36 +2884,36 @@ void Player::addInFightTicks(bool pzlock /*= false*/) { updateImbuementTrackerStats(); - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_configManager().getNumber(PZ_LOCKED), 0); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_configManager().getNumber(PZ_LOCKED), 0); addCondition(condition); } void Player::removeList() { - g_game().removePlayer(this); + g_game().removePlayer(static_self_cast()); for (const auto &[key, player] : g_game().getPlayers()) { - player->notifyStatusChange(this, VIPSTATUS_OFFLINE); + player->notifyStatusChange(static_self_cast(), VIPSTATUS_OFFLINE); } } void Player::addList() { for (const auto &[key, player] : g_game().getPlayers()) { - player->notifyStatusChange(this, this->statusVipList); + player->notifyStatusChange(static_self_cast(), this->statusVipList); } - g_game().addPlayer(this); + g_game().addPlayer(static_self_cast()); } void Player::removePlayer(bool displayEffect, bool forced /*= true*/) { - g_creatureEvents().playerLogout(this); + g_creatureEvents().playerLogout(static_self_cast()); if (client) { client->logout(displayEffect, forced); } else { - g_game().removeCreature(this); + g_game().removeCreature(static_self_cast()); } } -void Player::notifyStatusChange(Player* loginPlayer, VipStatus_t status, bool message) { +void Player::notifyStatusChange(std::shared_ptr loginPlayer, VipStatus_t status, bool message) { if (!client) { return; } @@ -3017,17 +2991,17 @@ bool Player::editVIP(uint32_t vipGuid, const std::string &description, uint32_t } // close container and its child containers -void Player::autoCloseContainers(const Container* container) { +void Player::autoCloseContainers(std::shared_ptr container) { std::vector closeList; for (const auto &it : openContainers) { - Container* tmpContainer = it.second.container; + std::shared_ptr tmpContainer = it.second.container; while (tmpContainer) { if (tmpContainer->isRemoved() || tmpContainer == container) { closeList.push_back(it.first); break; } - tmpContainer = dynamic_cast(tmpContainer->getParent()); + tmpContainer = std::dynamic_pointer_cast(tmpContainer->getParent()); } } @@ -3039,12 +3013,12 @@ void Player::autoCloseContainers(const Container* container) { } } -bool Player::hasCapacity(const Item* item, uint32_t count) const { +bool Player::hasCapacity(std::shared_ptr item, uint32_t count) const { if (hasFlag(PlayerFlags_t::CannotPickupItem)) { return false; } - if (hasFlag(PlayerFlags_t::HasInfiniteCapacity) || item->getTopParent() == this) { + if (hasFlag(PlayerFlags_t::HasInfiniteCapacity) || item->getTopParent().get() == this) { return true; } @@ -3055,8 +3029,8 @@ bool Player::hasCapacity(const Item* item, uint32_t count) const { return itemWeight <= getFreeCapacity(); } -ReturnValue Player::queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature*) const { - const Item* item = thing.getItem(); +ReturnValue Player::queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr) { + std::shared_ptr item = thing->getItem(); if (item == nullptr) { g_logger().error("[Player::queryAdd] - Item is nullptr"); return RETURNVALUE_NOTPOSSIBLE; @@ -3121,7 +3095,7 @@ ReturnValue Player::queryAdd(int32_t index, const Thing &thing, uint32_t count, if (item->getWeaponType() != WEAPON_SHIELD && !item->isQuiver()) { ret = RETURNVALUE_CANNOTBEDRESSED; } else { - const Item* leftItem = inventory[CONST_SLOT_LEFT]; + std::shared_ptr leftItem = inventory[CONST_SLOT_LEFT]; if (leftItem) { if ((leftItem->getSlotPosition() | slotPosition) & SLOTP_TWO_HAND) { if (item->isQuiver() && leftItem->getWeaponType() == WEAPON_DISTANCE) { @@ -3143,7 +3117,7 @@ ReturnValue Player::queryAdd(int32_t index, const Thing &thing, uint32_t count, ret = RETURNVALUE_NOERROR; } } else if (inventory[CONST_SLOT_LEFT]) { - const Item* leftItem = inventory[CONST_SLOT_LEFT]; + std::shared_ptr leftItem = inventory[CONST_SLOT_LEFT]; WeaponType_t type = item->getWeaponType(), leftType = leftItem->getWeaponType(); if (leftItem->getSlotPosition() & SLOTP_TWO_HAND) { @@ -3184,7 +3158,7 @@ ReturnValue Player::queryAdd(int32_t index, const Thing &thing, uint32_t count, ret = RETURNVALUE_NOERROR; } } else if (inventory[CONST_SLOT_RIGHT]) { - const Item* rightItem = inventory[CONST_SLOT_RIGHT]; + std::shared_ptr rightItem = inventory[CONST_SLOT_RIGHT]; WeaponType_t type = item->getWeaponType(), rightType = rightItem->getWeaponType(); if (rightItem->getSlotPosition() & SLOTP_TWO_HAND) { @@ -3244,7 +3218,7 @@ ReturnValue Player::queryAdd(int32_t index, const Thing &thing, uint32_t count, if (ret == RETURNVALUE_NOERROR || ret == RETURNVALUE_NOTENOUGHROOM) { // need an exchange with source? - const Item* inventoryItem = getInventoryItem(static_cast(index)); + std::shared_ptr inventoryItem = getInventoryItem(static_cast(index)); if (inventoryItem && (!inventoryItem->isStackable() || inventoryItem->getID() != item->getID())) { return RETURNVALUE_NEEDEXCHANGE; } @@ -3254,7 +3228,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(getPlayer(), item, static_cast(index), true)) { return RETURNVALUE_CANNOTBEDRESSED; } } @@ -3262,8 +3236,8 @@ ReturnValue Player::queryAdd(int32_t index, const Thing &thing, uint32_t count, return ret; } -ReturnValue Player::queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const { - const Item* item = thing.getItem(); +ReturnValue Player::queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) { + auto item = thing->getItem(); if (item == nullptr) { maxQueryCount = 0; return RETURNVALUE_NOTPOSSIBLE; @@ -3272,29 +3246,29 @@ ReturnValue Player::queryMaxCount(int32_t index, const Thing &thing, uint32_t co if (index == INDEX_WHEREEVER) { uint32_t n = 0; for (int32_t slotIndex = CONST_SLOT_FIRST; slotIndex <= CONST_SLOT_LAST; ++slotIndex) { - Item* inventoryItem = inventory[slotIndex]; + std::shared_ptr inventoryItem = inventory[slotIndex]; if (inventoryItem) { - if (Container* subContainer = inventoryItem->getContainer()) { + if (std::shared_ptr subContainer = inventoryItem->getContainer()) { uint32_t queryCount = 0; - subContainer->queryMaxCount(INDEX_WHEREEVER, *item, item->getItemCount(), queryCount, flags); + subContainer->queryMaxCount(INDEX_WHEREEVER, item, item->getItemCount(), queryCount, flags); n += queryCount; // iterate through all items, including sub-containers (deep search) for (ContainerIterator it = subContainer->iterator(); it.hasNext(); it.advance()) { - if (Container* tmpContainer = (*it)->getContainer()) { + if (std::shared_ptr tmpContainer = (*it)->getContainer()) { queryCount = 0; - tmpContainer->queryMaxCount(INDEX_WHEREEVER, *item, item->getItemCount(), queryCount, flags); + tmpContainer->queryMaxCount(INDEX_WHEREEVER, item, item->getItemCount(), queryCount, flags); n += queryCount; } } } else if (inventoryItem->isStackable() && item->equals(inventoryItem) && inventoryItem->getItemCount() < inventoryItem->getStackSize()) { uint32_t remainder = (inventoryItem->getStackSize() - inventoryItem->getItemCount()); - if (queryAdd(slotIndex, *item, remainder, flags) == RETURNVALUE_NOERROR) { + if (queryAdd(slotIndex, item, remainder, flags) == RETURNVALUE_NOERROR) { n += remainder; } } - } else if (queryAdd(slotIndex, *item, item->getItemCount(), flags) == RETURNVALUE_NOERROR) { // empty slot + } else if (queryAdd(slotIndex, item, item->getItemCount(), flags) == RETURNVALUE_NOERROR) { // empty slot if (item->isStackable()) { n += item->getStackSize(); } else { @@ -3305,9 +3279,9 @@ ReturnValue Player::queryMaxCount(int32_t index, const Thing &thing, uint32_t co maxQueryCount = n; } else { - const Item* destItem = nullptr; + std::shared_ptr destItem = nullptr; - const Thing* destThing = getThing(index); + std::shared_ptr destThing = getThing(index); if (destThing) { destItem = destThing->getItem(); } @@ -3318,7 +3292,7 @@ ReturnValue Player::queryMaxCount(int32_t index, const Thing &thing, uint32_t co } else { maxQueryCount = 0; } - } else if (queryAdd(index, *item, count, flags) == RETURNVALUE_NOERROR) { // empty slot + } else if (queryAdd(index, item, count, flags) == RETURNVALUE_NOERROR) { // empty slot if (item->isStackable()) { maxQueryCount = item->getStackSize(); } else { @@ -3336,13 +3310,13 @@ ReturnValue Player::queryMaxCount(int32_t index, const Thing &thing, uint32_t co } } -ReturnValue Player::queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* /*= nullptr*/) const { - int32_t index = getThingIndex(&thing); +ReturnValue Player::queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr /*= nullptr*/) { + int32_t index = getThingIndex(thing); if (index == -1) { return RETURNVALUE_NOTPOSSIBLE; } - const Item* item = thing.getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return RETURNVALUE_NOTPOSSIBLE; } @@ -3358,22 +3332,22 @@ ReturnValue Player::queryRemove(const Thing &thing, uint32_t count, uint32_t fla return RETURNVALUE_NOERROR; } -Cylinder* Player::queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) { +std::shared_ptr Player::queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) { if (index == 0 /*drop to capacity window*/ || index == INDEX_WHEREEVER) { *destItem = nullptr; - const Item* item = thing.getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { - return this; + return getPlayer(); } bool autoStack = !((flags & FLAG_IGNOREAUTOSTACK) == FLAG_IGNOREAUTOSTACK); bool isStackable = item->isStackable(); - std::vector containers; + std::vector> containers; for (uint32_t slotIndex = CONST_SLOT_FIRST; slotIndex <= CONST_SLOT_AMMO; ++slotIndex) { - Item* inventoryItem = inventory[slotIndex]; + std::shared_ptr inventoryItem = inventory[slotIndex]; if (inventoryItem) { if (inventoryItem == tradeItem) { continue; @@ -3385,35 +3359,35 @@ Cylinder* Player::queryDestination(int32_t &index, const Thing &thing, Item** de if (autoStack && isStackable) { // try find an already existing item to stack with - if (queryAdd(slotIndex, *item, item->getItemCount(), 0) == RETURNVALUE_NOERROR) { + if (queryAdd(slotIndex, item, item->getItemCount(), 0) == RETURNVALUE_NOERROR) { if (inventoryItem->equals(item) && inventoryItem->getItemCount() < inventoryItem->getStackSize()) { index = slotIndex; *destItem = inventoryItem; - return this; + return getPlayer(); } } - if (Container* subContainer = inventoryItem->getContainer()) { + if (std::shared_ptr subContainer = inventoryItem->getContainer()) { containers.push_back(subContainer); } - } else if (Container* subContainer = inventoryItem->getContainer()) { + } else if (std::shared_ptr subContainer = inventoryItem->getContainer()) { containers.push_back(subContainer); } - } else if (queryAdd(slotIndex, *item, item->getItemCount(), flags) == RETURNVALUE_NOERROR) { // empty slot + } else if (queryAdd(slotIndex, item, item->getItemCount(), flags) == RETURNVALUE_NOERROR) { // empty slot index = slotIndex; *destItem = nullptr; - return this; + return getPlayer(); } } size_t i = 0; while (i < containers.size()) { - Container* tmpContainer = containers[i++]; + std::shared_ptr tmpContainer = containers[i++]; if (!autoStack || !isStackable) { // we need to find first empty container as fast as we can for non-stackable items uint32_t n = tmpContainer->capacity() - tmpContainer->size(); while (n) { - if (tmpContainer->queryAdd(tmpContainer->capacity() - n, *item, item->getItemCount(), flags) == RETURNVALUE_NOERROR) { + if (tmpContainer->queryAdd(tmpContainer->capacity() - n, item, item->getItemCount(), flags) == RETURNVALUE_NOERROR) { index = tmpContainer->capacity() - n; *destItem = nullptr; return tmpContainer; @@ -3422,8 +3396,8 @@ Cylinder* Player::queryDestination(int32_t &index, const Thing &thing, Item** de n--; } - for (Item* tmpContainerItem : tmpContainer->getItemList()) { - if (Container* subContainer = tmpContainerItem->getContainer()) { + for (std::shared_ptr tmpContainerItem : tmpContainer->getItemList()) { + if (std::shared_ptr subContainer = tmpContainerItem->getContainer()) { containers.push_back(subContainer); } } @@ -3433,7 +3407,7 @@ Cylinder* Player::queryDestination(int32_t &index, const Thing &thing, Item** de uint32_t n = 0; - for (Item* tmpItem : tmpContainer->getItemList()) { + for (std::shared_ptr tmpItem : tmpContainer->getItemList()) { if (tmpItem == tradeItem) { continue; } @@ -3449,46 +3423,46 @@ Cylinder* Player::queryDestination(int32_t &index, const Thing &thing, Item** de return tmpContainer; } - if (Container* subContainer = tmpItem->getContainer()) { + if (std::shared_ptr subContainer = tmpItem->getContainer()) { containers.push_back(subContainer); } n++; } - if (n < tmpContainer->capacity() && tmpContainer->queryAdd(n, *item, item->getItemCount(), flags) == RETURNVALUE_NOERROR) { + if (n < tmpContainer->capacity() && tmpContainer->queryAdd(n, item, item->getItemCount(), flags) == RETURNVALUE_NOERROR) { index = n; *destItem = nullptr; return tmpContainer; } } - return this; + return getPlayer(); } - Thing* destThing = getThing(index); + std::shared_ptr destThing = getThing(index); if (destThing) { *destItem = destThing->getItem(); } - const Item* item = thing.getItem(); + std::shared_ptr item = thing->getItem(); bool movingAmmoToQuiver = item && *destItem && (*destItem)->isQuiver() && item->isAmmo(); // force shield any slot right to player cylinder if (index == CONST_SLOT_RIGHT && !movingAmmoToQuiver) { - return this; + return getPlayer(); } - Cylinder* subCylinder = dynamic_cast(destThing); + std::shared_ptr subCylinder = std::dynamic_pointer_cast(destThing); if (subCylinder) { index = INDEX_WHEREEVER; *destItem = nullptr; return subCylinder; } else { - return this; + return getPlayer(); } } -void Player::addThing(int32_t index, Thing* thing) { +void Player::addThing(int32_t index, std::shared_ptr thing) { if (!thing) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -3497,25 +3471,25 @@ void Player::addThing(int32_t index, Thing* thing) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - item->setParent(this); + item->setParent(static_self_cast()); inventory[index] = item; // send to client sendInventoryItem(static_cast(index), item); } -void Player::updateThing(Thing* thing, uint16_t itemId, uint32_t count) { +void Player::updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) { int32_t index = getThingIndex(thing); if (index == -1) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -3530,17 +3504,17 @@ void Player::updateThing(Thing* thing, uint16_t itemId, uint32_t count) { onUpdateInventoryItem(item, item); } -void Player::replaceThing(uint32_t index, Thing* thing) { +void Player::replaceThing(uint32_t index, std::shared_ptr thing) { if (index > CONST_SLOT_LAST) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* oldItem = getInventoryItem(static_cast(index)); + std::shared_ptr oldItem = getInventoryItem(static_cast(index)); if (!oldItem) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -3551,13 +3525,13 @@ void Player::replaceThing(uint32_t index, Thing* thing) { // event methods onUpdateInventoryItem(oldItem, item); - item->setParent(this); + item->setParent(static_self_cast()); inventory[index] = item; } -void Player::removeThing(Thing* thing, uint32_t count) { - Item* item = thing->getItem(); +void Player::removeThing(std::shared_ptr thing, uint32_t count) { + std::shared_ptr item = thing->getItem(); if (!item) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -3575,7 +3549,7 @@ void Player::removeThing(Thing* thing, uint32_t count) { // event methods onRemoveInventoryItem(item); - item->setParent(nullptr); + item->resetParent(); inventory[index] = nullptr; } else { uint8_t newCount = static_cast(std::max(0, item->getItemCount() - count)); @@ -3594,12 +3568,12 @@ void Player::removeThing(Thing* thing, uint32_t count) { // event methods onRemoveInventoryItem(item); - item->setParent(nullptr); + item->resetParent(); inventory[index] = nullptr; } } -int32_t Player::getThingIndex(const Thing* thing) const { +int32_t Player::getThingIndex(std::shared_ptr thing) const { for (uint8_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { if (inventory[i] == thing) { return i; @@ -3619,7 +3593,7 @@ size_t Player::getLastIndex() const { uint32_t Player::getItemTypeCount(uint16_t itemId, int32_t subType /*= -1*/) const { uint32_t count = 0; for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) { - Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (!item) { continue; } @@ -3628,7 +3602,7 @@ uint32_t Player::getItemTypeCount(uint16_t itemId, int32_t subType /*= -1*/) con count += Item::countByType(item, subType); } - if (Container* container = item->getContainer()) { + if (std::shared_ptr container = item->getContainer()) { for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) { if ((*it)->getID() == itemId) { count += Item::countByType(*it, subType); @@ -3654,7 +3628,7 @@ void Player::stashContainer(StashContainerList itemDict) { } if (getStashSize(stashItemDict) > g_configManager().getNumber(STASH_ITEMS)) { - sendCancelMessage("You don't have capacity in the Supply Stash to stow all this item."); + sendCancelMessage("You don't have capacity in the Supply Stash to stow all this item->"); return; } @@ -3695,11 +3669,11 @@ bool Player::removeItemOfType(uint16_t itemId, uint32_t amount, int32_t subType, return true; } - std::vector itemList; + std::vector> itemList; uint32_t count = 0; for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) { - Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (!item) { continue; } @@ -3717,9 +3691,9 @@ bool Player::removeItemOfType(uint16_t itemId, uint32_t amount, int32_t subType, g_game().internalRemoveItems(std::move(itemList), amount, Item::items[itemId].stackable); return true; } - } else if (Container* container = item->getContainer()) { + } else if (std::shared_ptr container = item->getContainer()) { for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) { - Item* containerItem = *it; + std::shared_ptr containerItem = *it; if (containerItem->getID() == itemId) { uint32_t itemCount = Item::countByType(containerItem, subType); if (itemCount == 0) { @@ -3747,7 +3721,7 @@ bool Player::removeItemOfType(uint16_t itemId, uint32_t amount, int32_t subType, bool Player::hasItemCountById(uint16_t itemId, uint32_t itemAmount, bool checkStash) const { uint32_t newCount = 0; // Check items from inventory - for (const auto* item : getAllInventoryItems()) { + for (const auto item : getAllInventoryItems()) { if (!item || item->getID() != itemId) { continue; } @@ -3778,7 +3752,7 @@ bool Player::removeItemCountById(uint16_t itemId, uint32_t itemAmount, bool remo uint32_t amountToRemove = itemAmount; // Check items from inventory - for (auto* item : getAllInventoryItems()) { + for (auto item : getAllInventoryItems()) { if (!item || item->getID() != itemId) { continue; } @@ -3805,13 +3779,13 @@ bool Player::removeItemCountById(uint16_t itemId, uint32_t itemAmount, bool remo ItemsTierCountList Player::getInventoryItemsId() const { ItemsTierCountList itemMap; for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) { - Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (!item) { continue; } (itemMap[item->getID()])[item->getTier()] += Item::countByType(item, -1); - if (Container* container = item->getContainer()) { + if (std::shared_ptr container = item->getContainer()) { for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) { auto containerItem = *it; (itemMap[containerItem->getID()])[containerItem->getTier()] += Item::countByType(containerItem, -1); @@ -3821,10 +3795,10 @@ ItemsTierCountList Player::getInventoryItemsId() const { return itemMap; } -std::vector Player::getInventoryItemsFromId(uint16_t itemId, bool ignore /*= true*/) const { - std::vector itemVector; +std::vector> Player::getInventoryItemsFromId(uint16_t itemId, bool ignore /*= true*/) const { + std::vector> itemVector; for (int i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { - Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (!item) { continue; } @@ -3833,7 +3807,7 @@ std::vector Player::getInventoryItemsFromId(uint16_t itemId, bool ignore itemVector.push_back(item); } - if (Container* container = item->getContainer()) { + if (std::shared_ptr container = item->getContainer()) { for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) { auto containerItem = *it; if (containerItem->getID() == itemId) { @@ -3862,14 +3836,14 @@ std::array Player::getFinalDamageReduction() const { void Player::calculateDamageReductionFromEquipedItems(std::array &combatReductionArray) const { for (uint8_t slot = CONST_SLOT_FIRST; slot <= CONST_SLOT_LAST; ++slot) { - Item* item = inventory[slot]; + std::shared_ptr item = inventory[slot]; if (item) { calculateDamageReductionFromItem(combatReductionArray, item); } } } -void Player::calculateDamageReductionFromItem(std::array &combatReductionArray, Item* item) const { +void Player::calculateDamageReductionFromItem(std::array &combatReductionArray, std::shared_ptr item) const { for (uint16_t combatTypeIndex = 0; combatTypeIndex < COMBAT_COUNT; combatTypeIndex++) { updateDamageReductionFromItemImbuement(combatReductionArray, item, combatTypeIndex); updateDamageReductionFromItemAbility(combatReductionArray, item, combatTypeIndex); @@ -3877,7 +3851,7 @@ void Player::calculateDamageReductionFromItem(std::array } void Player::updateDamageReductionFromItemImbuement( - std::array &combatReductionArray, Item* item, uint16_t combatTypeIndex + std::array &combatReductionArray, std::shared_ptr item, uint16_t combatTypeIndex ) const { for (uint8_t imbueSlotId = 0; imbueSlotId < item->getImbuementSlot(); imbueSlotId++) { ImbuementInfo imbuementInfo; @@ -3891,7 +3865,7 @@ void Player::updateDamageReductionFromItemImbuement( } void Player::updateDamageReductionFromItemAbility( - std::array &combatReductionArray, const Item* item, uint16_t combatTypeIndex + std::array &combatReductionArray, std::shared_ptr item, uint16_t combatTypeIndex ) const { if (!item) { return; @@ -3910,10 +3884,10 @@ double_t Player::calculateDamageReduction(double_t currentTotal, int16_t resista return (100 - currentTotal) / 100.0 * resistance + currentTotal; } -std::vector Player::getAllInventoryItems(bool ignoreEquiped /*= false*/, bool ignoreItemWithTier /* false*/) const { - std::vector itemVector; +std::vector> Player::getAllInventoryItems(bool ignoreEquiped /*= false*/, bool ignoreItemWithTier /* false*/) const { + std::vector> itemVector; for (int i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { - Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (!item) { continue; } @@ -3922,7 +3896,7 @@ std::vector Player::getAllInventoryItems(bool ignoreEquiped /*= false*/, if (!ignoreEquiped) { itemVector.push_back(item); } - if (Container* container = item->getContainer()) { + if (std::shared_ptr container = item->getContainer()) { for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) { if (ignoreItemWithTier && (*it)->getTier() > 0) { continue; @@ -3936,7 +3910,7 @@ std::vector Player::getAllInventoryItems(bool ignoreEquiped /*= false*/, return itemVector; } -std::vector Player::getEquippedItems() const { +std::vector> Player::getEquippedItems() const { std::vector valid_slots { CONST_SLOT_HEAD, CONST_SLOT_NECKLACE, @@ -3949,9 +3923,9 @@ std::vector Player::getEquippedItems() const { CONST_SLOT_RING, }; - std::vector valid_items; + std::vector> valid_items; for (const auto &slot : valid_slots) { - Item* item = inventory[slot]; + std::shared_ptr item = inventory[slot]; if (!item) { continue; } @@ -3990,7 +3964,7 @@ void Player::getAllItemTypeCountAndSubtype(std::map &countMa } } -Item* Player::getForgeItemFromId(uint16_t itemId, uint8_t tier) { +std::shared_ptr Player::getForgeItemFromId(uint16_t itemId, uint8_t tier) { for (auto item : getAllInventoryItems(true)) { if (item->hasImbuements()) { continue; @@ -4004,32 +3978,32 @@ Item* Player::getForgeItemFromId(uint16_t itemId, uint8_t tier) { return nullptr; } -Thing* Player::getThing(size_t index) const { +std::shared_ptr Player::getThing(size_t index) const { if (index >= CONST_SLOT_FIRST && index <= CONST_SLOT_LAST) { return inventory[index]; } return nullptr; } -void Player::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link /*= LINK_OWNER*/) { +void Player::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link /*= LINK_OWNER*/) { if (link == LINK_OWNER) { // calling movement scripts - g_moveEvents().onPlayerEquip(*this, *thing->getItem(), static_cast(index), false); + g_moveEvents().onPlayerEquip(getPlayer(), thing->getItem(), static_cast(index), false); } bool requireListUpdate = true; if (link == LINK_OWNER || link == LINK_TOPPARENT) { - const Item* i = (oldParent ? oldParent->getItem() : nullptr); + std::shared_ptr i = (oldParent ? oldParent->getItem() : nullptr); // Check if we owned the old container too, so we don't need to do anything, // as the list was updated in postRemoveNotification assert(i ? i->getContainer() != nullptr : true); if (i) { - requireListUpdate = i->getContainer()->getHoldingPlayer() != this; + requireListUpdate = i->getContainer()->getHoldingPlayer() != getPlayer(); } else { - requireListUpdate = oldParent != this; + requireListUpdate = oldParent != getPlayer(); } updateInventoryWeight(); @@ -4038,21 +4012,21 @@ void Player::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_ sendStats(); } - if (const Item* item = thing->getItem()) { - if (const Container* container = item->getContainer()) { + if (std::shared_ptr item = thing->getItem()) { + if (std::shared_ptr container = item->getContainer()) { onSendContainer(container); } if (shopOwner && !scheduledSaleUpdate && requireListUpdate) { updateSaleShopList(item); } - } else if (const Creature* creature = thing->getCreature()) { - if (creature == this) { + } else if (std::shared_ptr creature = thing->getCreature()) { + if (creature == getPlayer()) { // check containers - std::vector containers; + std::vector> containers; for (const auto &it : openContainers) { - Container* container = it.second.container; + std::shared_ptr container = it.second.container; if (container == nullptr) { continue; } @@ -4062,32 +4036,32 @@ void Player::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_ } } - for (const Container* container : containers) { + for (std::shared_ptr container : containers) { autoCloseContainers(container); } } } } -void Player::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link /*= LINK_OWNER*/) { +void Player::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link /*= LINK_OWNER*/) { if (link == LINK_OWNER) { // calling movement scripts - g_moveEvents().onPlayerDeEquip(*this, *thing->getItem(), static_cast(index)); + g_moveEvents().onPlayerDeEquip(getPlayer(), thing->getItem(), static_cast(index)); } bool requireListUpdate = true; if (link == LINK_OWNER || link == LINK_TOPPARENT) { - const Item* i = (newParent ? newParent->getItem() : nullptr); + std::shared_ptr i = (newParent ? newParent->getItem() : nullptr); // Check if we owned the old container too, so we don't need to do anything, // as the list was updated in postRemoveNotification assert(i ? i->getContainer() != nullptr : true); if (i) { - requireListUpdate = i->getContainer()->getHoldingPlayer() != this; + requireListUpdate = i->getContainer()->getHoldingPlayer() != getPlayer(); } else { - requireListUpdate = newParent != this; + requireListUpdate = newParent != getPlayer(); } updateInventoryWeight(); @@ -4096,16 +4070,16 @@ void Player::postRemoveNotification(Thing* thing, const Cylinder* newParent, int sendStats(); } - if (const Item* item = thing->getItem()) { - if (const Container* container = item->getContainer()) { + if (std::shared_ptr item = thing->getItem()) { + if (std::shared_ptr container = item->getContainer()) { checkLootContainers(container); if (container->isRemoved() || !Position::areInRange<1, 1, 0>(getPosition(), container->getPosition())) { autoCloseContainers(container); - } else if (container->getTopParent() == this) { + } else if (container->getTopParent() == getPlayer()) { onSendContainer(container); - } else if (const Container* topContainer = dynamic_cast(container->getTopParent())) { - if (const DepotChest* depotChest = dynamic_cast(topContainer)) { + } else if (std::shared_ptr topContainer = std::dynamic_pointer_cast(container->getTopParent())) { + if (std::shared_ptr depotChest = std::dynamic_pointer_cast(topContainer)) { bool isOwner = false; for (const auto &it : depotChests) { @@ -4139,7 +4113,7 @@ void Player::postRemoveNotification(Thing* thing, const Cylinder* newParent, int } // i will keep this function so it can be reviewed -bool Player::updateSaleShopList(const Item* item) { +bool Player::updateSaleShopList(std::shared_ptr item) { uint16_t itemId = item->getID(); if (!itemId || !item) { return true; @@ -4162,16 +4136,16 @@ bool Player::hasShopItemForSale(uint16_t itemId, uint8_t subType) const { }); } -void Player::internalAddThing(Thing* thing) { +void Player::internalAddThing(std::shared_ptr thing) { internalAddThing(0, thing); } -void Player::internalAddThing(uint32_t index, Thing* thing) { +void Player::internalAddThing(uint32_t index, std::shared_ptr thing) { if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { return; } @@ -4183,11 +4157,11 @@ void Player::internalAddThing(uint32_t index, Thing* thing) { } inventory[index] = item; - item->setParent(this); + item->setParent(static_self_cast()); } } -bool Player::setFollowCreature(Creature* creature) { +bool Player::setFollowCreature(std::shared_ptr creature) { if (!Creature::setFollowCreature(creature)) { setFollowCreature(nullptr); setAttackedCreature(nullptr); @@ -4200,15 +4174,15 @@ bool Player::setFollowCreature(Creature* creature) { return true; } -bool Player::setAttackedCreature(Creature* creature) { +bool Player::setAttackedCreature(std::shared_ptr creature) { if (!Creature::setAttackedCreature(creature)) { sendCancelTarget(); return false; } + auto followCreature = getFollowCreature(); if (chaseMode && creature) { if (followCreature != creature) { - // chase opponent setFollowCreature(creature); } } else if (followCreature) { @@ -4229,13 +4203,13 @@ void Player::goToFollowCreature() { Creature::goToFollowCreature(); - if (followCreature && !hasFollowPath) { + if (getFollowCreature() && !hasFollowPath) { lastFailedFollow = OTSYS_TIME(); } } } -void Player::getPathSearchParams(const Creature* creature, FindPathParams &fpp) const { +void Player::getPathSearchParams(std::shared_ptr creature, FindPathParams &fpp) { Creature::getPathSearchParams(creature, fpp); fpp.fullPathSearch = true; } @@ -4249,26 +4223,31 @@ void Player::doAttacking(uint32_t) { return; } + auto attackedCreature = getAttackedCreature(); + if (!attackedCreature) { + return; + } + if ((OTSYS_TIME() - lastAttack) >= getAttackSpeed()) { bool result = false; - Item* tool = getWeapon(); + std::shared_ptr tool = getWeapon(); const Weapon* weapon = g_weapons().getWeapon(tool); uint32_t delay = getAttackSpeed(); bool classicSpeed = g_configManager().getBoolean(CLASSIC_ATTACK_SPEED); if (weapon) { if (!weapon->interruptSwing()) { - result = weapon->useWeapon(this, tool, attackedCreature); + result = weapon->useWeapon(static_self_cast(), tool, attackedCreature); } else if (!classicSpeed && !canDoAction()) { delay = getNextActionTime(); } else { - result = weapon->useWeapon(this, tool, attackedCreature); + result = weapon->useWeapon(static_self_cast(), tool, attackedCreature); } } else if (hasWeaponDistanceEquipped()) { return; } else { - result = Weapon::useFist(this, attackedCreature); + result = Weapon::useFist(static_self_cast(), attackedCreature); } std::shared_ptr task = createPlayerTask(std::max(SCHEDULER_MINTICKS, delay), std::bind(&Game::checkCreatureAttack, &g_game(), getID()), "Game::checkCreatureAttack"); @@ -4284,17 +4263,17 @@ void Player::doAttacking(uint32_t) { } } -uint64_t Player::getGainedExperience(Creature* attacker) const { +uint64_t Player::getGainedExperience(std::shared_ptr attacker) const { if (g_configManager().getBoolean(EXPERIENCE_FROM_PLAYERS)) { - Player* attackerPlayer = attacker->getPlayer(); - if (attackerPlayer && attackerPlayer != this && skillLoss && std::abs(static_cast(attackerPlayer->getLevel() - level)) <= g_configManager().getNumber(EXP_FROM_PLAYERS_LEVEL_RANGE)) { + auto attackerPlayer = attacker->getPlayer(); + if (attackerPlayer && attackerPlayer.get() != this && skillLoss && std::abs(static_cast(attackerPlayer->getLevel() - level)) <= g_configManager().getNumber(EXP_FROM_PLAYERS_LEVEL_RANGE)) { return std::max(0, std::floor(getLostExperience() * getDamageRatio(attacker) * 0.75)); } } return 0; } -void Player::onFollowCreature(const Creature* creature) { +void Player::onFollowCreature(std::shared_ptr creature) { if (!creature) { stopWalk(); } @@ -4303,6 +4282,8 @@ void Player::onFollowCreature(const Creature* creature) { void Player::setChaseMode(bool mode) { bool prevChaseMode = chaseMode; chaseMode = mode; + auto attackedCreature = getAttackedCreature(); + auto followCreature = getFollowCreature(); if (prevChaseMode != chaseMode) { if (chaseMode) { @@ -4331,8 +4312,8 @@ void Player::onWalkComplete() { */ g_logger().debug("[Player::onWalkComplete] Executing feared conditions as players completed it's walk."); - Condition* f = getCondition(CONDITION_FEARED); - f->executeCondition(this, 0); + std::shared_ptr f = getCondition(CONDITION_FEARED); + f->executeCondition(static_self_cast(), 0); } if (walkTask) { @@ -4356,7 +4337,7 @@ void Player::updateItemsLight(bool internal /*=false*/) { LightInfo maxLight; for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { - Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (item) { LightInfo curLight = item->getLightInfo(); @@ -4370,7 +4351,7 @@ void Player::updateItemsLight(bool internal /*=false*/) { itemsLight = maxLight; if (!internal) { - g_game().changeLight(this); + g_game().changeLight(static_self_cast()); } } } @@ -4456,12 +4437,12 @@ void Player::onEndCondition(ConditionType_t type) { sendIcons(); } -void Player::onCombatRemoveCondition(Condition* condition) { +void Player::onCombatRemoveCondition(std::shared_ptr condition) { // Creature::onCombatRemoveCondition(condition); if (condition->getId() > 0) { // Means the condition is from an item, id == slot if (g_game().getWorldType() == WORLD_TYPE_PVP_ENFORCED) { - Item* item = getInventoryItem(static_cast(condition->getId())); + std::shared_ptr item = getInventoryItem(static_cast(condition->getId())); if (item) { // 25% chance to destroy the item if (25 >= uniform_random(1, 100)) { @@ -4484,14 +4465,14 @@ void Player::onCombatRemoveCondition(Condition* condition) { } } -void Player::onAttackedCreature(Creature* target) { +void Player::onAttackedCreature(std::shared_ptr target) { Creature::onAttackedCreature(target); if (target->getZoneType() == ZONE_PVP) { return; } - if (target == this) { + if (target == getPlayer()) { addInFightTicks(); return; } @@ -4500,7 +4481,7 @@ void Player::onAttackedCreature(Creature* target) { return; } - Player* targetPlayer = target->getPlayer(); + auto targetPlayer = target->getPlayer(); if (targetPlayer && !isPartner(targetPlayer) && !isGuildMate(targetPlayer)) { if (!pzLocked && g_game().getWorldType() == WORLD_TYPE_PVP_ENFORCED) { pzLocked = true; @@ -4509,22 +4490,22 @@ void Player::onAttackedCreature(Creature* target) { if (getSkull() == SKULL_NONE && getSkullClient(targetPlayer) == SKULL_YELLOW) { addAttacked(targetPlayer); - targetPlayer->sendCreatureSkull(this); - } else if (!targetPlayer->hasAttacked(this)) { + targetPlayer->sendCreatureSkull(static_self_cast()); + } else if (!targetPlayer->hasAttacked(static_self_cast())) { if (!pzLocked) { pzLocked = true; sendIcons(); } - if (!Combat::isInPvpZone(this, targetPlayer) && !isInWar(targetPlayer)) { + if (!Combat::isInPvpZone(static_self_cast(), targetPlayer) && !isInWar(targetPlayer)) { addAttacked(targetPlayer); - if (targetPlayer->getSkull() == SKULL_NONE && getSkull() == SKULL_NONE && !targetPlayer->hasKilled(this)) { + if (targetPlayer->getSkull() == SKULL_NONE && getSkull() == SKULL_NONE && !targetPlayer->hasKilled(static_self_cast())) { setSkull(SKULL_WHITE); } if (getSkull() == SKULL_NONE) { - targetPlayer->sendCreatureSkull(this); + targetPlayer->sendCreatureSkull(static_self_cast()); } } } @@ -4543,52 +4524,52 @@ void Player::onIdleStatus() { Creature::onIdleStatus(); if (party) { - party->clearPlayerPoints(this); + party->clearPlayerPoints(static_self_cast()); } } void Player::onPlacedCreature() { // scripting event - onLogin - if (!g_creatureEvents().playerLogin(this)) { + if (!g_creatureEvents().playerLogin(static_self_cast())) { removePlayer(true); } sendUnjustifiedPoints(); } -void Player::onAttackedCreatureDrainHealth(Creature* target, int32_t points) { +void Player::onAttackedCreatureDrainHealth(std::shared_ptr target, int32_t points) { Creature::onAttackedCreatureDrainHealth(target, points); if (target) { if (party && !Combat::isPlayerCombat(target)) { - Monster* tmpMonster = target->getMonster(); + auto tmpMonster = target->getMonster(); if (tmpMonster && tmpMonster->isHostile()) { // We have fulfilled a requirement for shared experience - party->updatePlayerTicks(this, points); + party->updatePlayerTicks(static_self_cast(), points); } } } } -void Player::onTargetCreatureGainHealth(Creature* target, int32_t points) { +void Player::onTargetCreatureGainHealth(std::shared_ptr target, int32_t points) { if (target && party) { - Player* tmpPlayer = nullptr; + std::shared_ptr tmpPlayer = nullptr; - if (isPartner(tmpPlayer) && (tmpPlayer != this)) { + if (isPartner(tmpPlayer) && (tmpPlayer != getPlayer())) { tmpPlayer = target->getPlayer(); - } else if (Creature* targetMaster = target->getMaster()) { - if (Player* targetMasterPlayer = targetMaster->getPlayer()) { + } else if (std::shared_ptr targetMaster = target->getMaster()) { + if (std::shared_ptr targetMasterPlayer = targetMaster->getPlayer()) { tmpPlayer = targetMasterPlayer; } } if (isPartner(tmpPlayer)) { - party->updatePlayerTicks(this, points); + party->updatePlayerTicks(static_self_cast(), points); } } } -bool Player::onKilledCreature(Creature* target, bool lastHit /* = true*/) { +bool Player::onKilledCreature(std::shared_ptr target, bool lastHit /* = true*/) { bool unjustified = false; if (hasFlag(PlayerFlags_t::NotGenerateLoot)) { @@ -4597,13 +4578,13 @@ bool Player::onKilledCreature(Creature* target, bool lastHit /* = true*/) { Creature::onKilledCreature(target, lastHit); - if (Player* targetPlayer = target->getPlayer()) { + if (auto targetPlayer = target->getPlayer()) { if (targetPlayer && targetPlayer->getZoneType() == ZONE_PVP) { targetPlayer->setDropLoot(false); targetPlayer->setSkillLoss(false); } else if (!hasFlag(PlayerFlags_t::NotGainInFight) && !isPartner(targetPlayer)) { - if (!Combat::isInPvpZone(this, targetPlayer) && hasAttacked(targetPlayer) && !targetPlayer->hasAttacked(this) && !isGuildMate(targetPlayer) && targetPlayer != this) { - if (targetPlayer->hasKilled(this)) { + if (!Combat::isInPvpZone(getPlayer(), targetPlayer) && hasAttacked(targetPlayer) && !targetPlayer->hasAttacked(getPlayer()) && !isGuildMate(targetPlayer) && targetPlayer != getPlayer()) { + if (targetPlayer->hasKilled(getPlayer())) { for (auto &kill : targetPlayer->unjustifiedKills) { if (kill.target == getGUID() && kill.unavenged) { kill.unavenged = false; @@ -4619,12 +4600,12 @@ bool Player::onKilledCreature(Creature* target, bool lastHit /* = true*/) { if (lastHit && hasCondition(CONDITION_INFIGHT)) { pzLocked = true; - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_configManager().getNumber(WHITE_SKULL_TIME), 0); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_configManager().getNumber(WHITE_SKULL_TIME), 0); addCondition(condition); } } } - } else if (const Monster* monster = target->getMonster()) { + } else if (std::shared_ptr monster = target->getMonster()) { // Access to the monster's map damage to check if the player attacked it for (auto [playerId, damage] : monster->getDamageMap()) { auto damagePlayer = g_game().getPlayerByID(playerId); @@ -4635,16 +4616,16 @@ bool Player::onKilledCreature(Creature* target, bool lastHit /* = true*/) { // If the player is not in a party and sharing exp active and enabled // And it's not the player killing the creature, then we ignore everything else auto damageParty = damagePlayer->getParty(); - if (this->getID() != damagePlayer->getID() && (!damageParty || !damageParty->isSharedExperienceActive() || !damageParty->isSharedExperienceEnabled())) { + if (static_self_cast()->getID() != damagePlayer->getID() && (!damageParty || !damageParty->isSharedExperienceActive() || !damageParty->isSharedExperienceEnabled())) { continue; } - TaskHuntingSlot* taskSlot = damagePlayer->getTaskHuntingWithCreature(monster->getRaceId()); + const auto &taskSlot = damagePlayer->getTaskHuntingWithCreature(monster->getRaceId()); if (!taskSlot || monster->isSummon()) { continue; } - if (const TaskHuntingOption* option = g_ioprey().GetTaskRewardOption(taskSlot)) { + if (const auto &option = g_ioprey().getTaskRewardOption(taskSlot)) { taskSlot->currentKills += 1; if ((taskSlot->upgrade && taskSlot->currentKills >= option->secondKills) || (!taskSlot->upgrade && taskSlot->currentKills >= option->firstKills)) { taskSlot->state = PreyTaskDataState_Completed; @@ -4659,7 +4640,7 @@ bool Player::onKilledCreature(Creature* target, bool lastHit /* = true*/) { return unjustified; } -void Player::gainExperience(uint64_t gainExp, Creature* target) { +void Player::gainExperience(uint64_t gainExp, std::shared_ptr target) { if (hasFlag(PlayerFlags_t::NotGainExperience) || gainExp == 0 || staminaMinutes == 0) { return; } @@ -4667,7 +4648,7 @@ void Player::gainExperience(uint64_t gainExp, Creature* target) { addExperience(target, gainExp, true); } -void Player::onGainExperience(uint64_t gainExp, Creature* target) { +void Player::onGainExperience(uint64_t gainExp, std::shared_ptr target) { if (hasFlag(PlayerFlags_t::NotGainExperience)) { return; } @@ -4682,7 +4663,7 @@ void Player::onGainExperience(uint64_t gainExp, Creature* target) { gainExperience(gainExp, target); } -void Player::onGainSharedExperience(uint64_t gainExp, Creature* target) { +void Player::onGainSharedExperience(uint64_t gainExp, std::shared_ptr target) { gainExperience(gainExp, target); } @@ -4705,7 +4686,7 @@ bool Player::isAttackable() const { return !hasFlag(PlayerFlags_t::CannotBeAttacked); } -bool Player::lastHitIsPlayer(Creature* lastHitCreature) { +bool Player::lastHitIsPlayer(std::shared_ptr lastHitCreature) { if (!lastHitCreature) { return false; } @@ -4714,7 +4695,7 @@ bool Player::lastHitIsPlayer(Creature* lastHitCreature) { return true; } - Creature* lastHitMaster = lastHitCreature->getMaster(); + std::shared_ptr lastHitMaster = lastHitCreature->getMaster(); return lastHitMaster && lastHitMaster->getPlayer(); } @@ -4727,7 +4708,7 @@ void Player::changeMana(int32_t manaChange) { if (!hasFlag(PlayerFlags_t::HasInfiniteMana)) { Creature::changeMana(manaChange); } - g_game().addPlayerMana(this); + g_game().addPlayerMana(static_self_cast()); sendStats(); } @@ -4950,14 +4931,14 @@ Skulls_t Player::getSkull() const { return skull; } -Skulls_t Player::getSkullClient(const Creature* creature) const { +Skulls_t Player::getSkullClient(std::shared_ptr creature) { if (!creature || g_game().getWorldType() != WORLD_TYPE_PVP) { return SKULL_NONE; } - const Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player && player->getSkull() == SKULL_NONE) { - if (player == this) { + if (player.get() == this) { for (const auto &kill : unjustifiedKills) { if (kill.unavenged && (time(nullptr) - kill.time) < g_configManager().getNumber(ORANGE_SKULL_DURATION) * 24 * 60 * 60) { return SKULL_ORANGE; @@ -4965,11 +4946,11 @@ Skulls_t Player::getSkullClient(const Creature* creature) const { } } - if (player->hasKilled(this)) { + if (player->hasKilled(getPlayer())) { return SKULL_ORANGE; } - if (player->hasAttacked(this)) { + if (player->hasAttacked(getPlayer())) { return SKULL_YELLOW; } @@ -4980,7 +4961,7 @@ Skulls_t Player::getSkullClient(const Creature* creature) const { return Creature::getSkullClient(creature); } -bool Player::hasKilled(const Player* player) const { +bool Player::hasKilled(std::shared_ptr player) const { for (const auto &kill : unjustifiedKills) { if (kill.target == player->getGUID() && (time(nullptr) - kill.time) < g_configManager().getNumber(ORANGE_SKULL_DURATION) * 24 * 60 * 60 && kill.unavenged) { return true; @@ -4990,7 +4971,7 @@ bool Player::hasKilled(const Player* player) const { return false; } -bool Player::hasAttacked(const Player* attacked) const { +bool Player::hasAttacked(std::shared_ptr attacked) const { if (hasFlag(PlayerFlags_t::NotGainInFight) || !attacked) { return false; } @@ -4998,16 +4979,16 @@ bool Player::hasAttacked(const Player* attacked) const { return attackedSet.find(attacked->guid) != attackedSet.end(); } -void Player::addAttacked(const Player* attacked) { - if (hasFlag(PlayerFlags_t::NotGainInFight) || !attacked || attacked == this) { +void Player::addAttacked(std::shared_ptr attacked) { + if (hasFlag(PlayerFlags_t::NotGainInFight) || !attacked || attacked == getPlayer()) { return; } attackedSet.insert(attacked->guid); } -void Player::removeAttacked(const Player* attacked) { - if (!attacked || attacked == this) { +void Player::removeAttacked(std::shared_ptr attacked) { + if (!attacked || attacked == getPlayer()) { return; } @@ -5021,8 +5002,8 @@ void Player::clearAttacked() { attackedSet.clear(); } -void Player::addUnjustifiedDead(const Player* attacked) { - if (hasFlag(PlayerFlags_t::NotGainInFight) || attacked == this || g_game().getWorldType() == WORLD_TYPE_PVP_ENFORCED) { +void Player::addUnjustifiedDead(std::shared_ptr attacked) { + if (hasFlag(PlayerFlags_t::NotGainInFight) || attacked == getPlayer() || g_game().getWorldType() == WORLD_TYPE_PVP_ENFORCED) { return; } @@ -5143,7 +5124,7 @@ bool Player::hasLearnedInstantSpell(const std::string &spellName) const { return false; } -bool Player::isInWar(const Player* player) const { +bool Player::isInWar(std::shared_ptr player) const { if (!player || !guild) { return false; } @@ -5422,7 +5403,7 @@ void Player::setTransferableTibiaCoins(int32_t v) { coinTransferableBalance = v; } -PartyShields_t Player::getPartyShield(const Player* player) const { +PartyShields_t Player::getPartyShield(std::shared_ptr player) { if (!player) { return SHIELD_NONE; } @@ -5465,7 +5446,7 @@ PartyShields_t Player::getPartyShield(const Player* player) const { } } - if (player->isInviting(this)) { + if (player->isInviting(getPlayer())) { return SHIELD_WHITEYELLOW; } @@ -5476,33 +5457,33 @@ PartyShields_t Player::getPartyShield(const Player* player) const { return SHIELD_NONE; } -bool Player::isInviting(const Player* player) const { - if (!player || !party || party->getLeader() != this) { +bool Player::isInviting(std::shared_ptr player) const { + if (!player || !party || party->getLeader().get() != this) { return false; } return party->isPlayerInvited(player); } -bool Player::isPartner(const Player* player) const { - if (!player || !party || player == this) { +bool Player::isPartner(std::shared_ptr player) const { + if (!player || !party || player.get() == this) { return false; } return party == player->party; } -bool Player::isGuildMate(const Player* player) const { +bool Player::isGuildMate(std::shared_ptr player) const { if (!player || !guild) { return false; } return guild == player->guild; } -void Player::sendPlayerPartyIcons(Player* player) { +void Player::sendPlayerPartyIcons(std::shared_ptr player) { sendPartyCreatureShield(player); sendPartyCreatureSkull(player); } -bool Player::addPartyInvitation(Party* newParty) { +bool Player::addPartyInvitation(std::shared_ptr newParty) { auto it = std::find(invitePartyList.begin(), invitePartyList.end(), newParty); if (it != invitePartyList.end()) { return false; @@ -5512,18 +5493,18 @@ bool Player::addPartyInvitation(Party* newParty) { return true; } -void Player::removePartyInvitation(Party* remParty) { +void Player::removePartyInvitation(std::shared_ptr remParty) { invitePartyList.remove(remParty); } void Player::clearPartyInvitations() { - for (Party* invitingParty : invitePartyList) { - invitingParty->removeInvite(*this, false); + for (const auto &invitingParty : invitePartyList) { + invitingParty->removeInvite(getPlayer(), false); } invitePartyList.clear(); } -GuildEmblems_t Player::getGuildEmblem(const Player* player) const { +GuildEmblems_t Player::getGuildEmblem(std::shared_ptr player) const { if (!player) { return GUILDEMBLEM_NONE; } @@ -5631,7 +5612,8 @@ bool Player::toggleMount(bool mount) { return false; } - if (!group->access && tile->hasFlag(TILESTATE_PROTECTIONZONE)) { + auto tile = getTile(); + if (!g_configManager().getBoolean(TOGGLE_MOUNT_IN_PZ) && !group->access && tile && tile->hasFlag(TILESTATE_PROTECTIONZONE)) { sendCancelMessage(RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE); return false; } @@ -5676,7 +5658,7 @@ bool Player::toggleMount(bool mount) { setCurrentMount(currentMount->id); if (currentMount->speed != 0) { - g_game().changeSpeed(this, currentMount->speed); + g_game().changeSpeed(static_self_cast(), currentMount->speed); } } else { if (!isMounted()) { @@ -5686,7 +5668,7 @@ bool Player::toggleMount(bool mount) { dismount(); } - g_game().internalCreatureChangeOutfit(this, defaultOutfit); + g_game().internalCreatureChangeOutfit(static_self_cast(), defaultOutfit); lastToggleMount = OTSYS_TIME(); return true; } @@ -5729,7 +5711,7 @@ bool Player::untameMount(uint8_t mountId) { if (getCurrentMount() == mountId) { if (isMounted()) { dismount(); - g_game().internalCreatureChangeOutfit(this, defaultOutfit); + g_game().internalCreatureChangeOutfit(static_self_cast(), defaultOutfit); } setCurrentMount(0); @@ -5760,7 +5742,7 @@ bool Player::hasMount(const std::shared_ptr mount) const { void Player::dismount() { const auto mount = g_game().mounts.getMountByID(getCurrentMount()); if (mount && mount->speed > 0) { - g_game().changeSpeed(this, -mount->speed); + g_game().changeSpeed(static_self_cast(), -mount->speed); } defaultOutfit.lookMount = 0; @@ -5786,8 +5768,8 @@ 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_callbacks().executeCallback(EventCallback_t::playerOnGainSkillTries, &EventCallback::playerOnGainSkillTries, this, SKILL_MAGLEVEL, tries); + g_events().eventPlayerOnGainSkillTries(static_self_cast(), SKILL_MAGLEVEL, tries); + g_callbacks().executeCallback(EventCallback_t::playerOnGainSkillTries, &EventCallback::playerOnGainSkillTries, getPlayer(), SKILL_MAGLEVEL, tries); uint32_t currMagLevel = magLevel; while ((manaSpent + tries) >= nextReqMana) { @@ -5796,7 +5778,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(static_self_cast(), SKILL_MAGLEVEL, magLevel - 1, magLevel); sendUpdate = true; currReqMana = nextReqMana; @@ -5841,8 +5823,8 @@ 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_callbacks().executeCallback(EventCallback_t::playerOnGainSkillTries, &EventCallback::playerOnGainSkillTries, this, skill, tries); + g_events().eventPlayerOnGainSkillTries(static_self_cast(), skill, tries); + g_callbacks().executeCallback(EventCallback_t::playerOnGainSkillTries, &EventCallback::playerOnGainSkillTries, getPlayer(), skill, tries); uint32_t currSkillLevel = skills[skill].level; while ((skills[skill].tries + tries) >= nextReqTries) { @@ -5852,7 +5834,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(static_self_cast(), skill, (skills[skill].level - 1), skills[skill].level); sendUpdate = true; currReqTries = nextReqTries; @@ -5934,22 +5916,22 @@ uint16_t Player::getHelpers() const { uint16_t helpers; if (guild && party) { - phmap::flat_hash_set helperSet; + phmap::flat_hash_set> helperSet; const auto guildMembers = guild->getMembersOnline(); helperSet.insert(guildMembers.begin(), guildMembers.end()); - const auto &partyMembers = party->getMembers(); + const auto partyMembers = party->getMembers(); helperSet.insert(partyMembers.begin(), partyMembers.end()); - const auto &partyInvitees = party->getInvitees(); + const auto partyInvitees = party->getInvitees(); helperSet.insert(partyInvitees.begin(), partyInvitees.end()); helperSet.insert(party->getLeader()); helpers = helperSet.size(); } else if (guild) { - helpers = guild->getMembersOnline().size(); + helpers = guild->getMemberCountOnline(); } else if (party) { helpers = party->getMemberCount() + party->getInvitationCount() + 1; } else { @@ -5961,7 +5943,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(getPlayer(), channelId); } if (client) { @@ -5970,16 +5952,16 @@ void Player::sendClosePrivate(uint16_t channelId) { } uint64_t Player::getMoney() const { - std::vector containers; + std::vector> containers; uint64_t moneyCount = 0; for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { - Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (!item) { continue; } - const Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container) { containers.push_back(container); } else { @@ -5989,9 +5971,9 @@ uint64_t Player::getMoney() const { size_t i = 0; while (i < containers.size()) { - const Container* container = containers[i++]; - for (const Item* item : container->getItemList()) { - const Container* tmpContainer = item->getContainer(); + std::shared_ptr container = containers[i++]; + for (std::shared_ptr item : container->getItemList()) { + std::shared_ptr tmpContainer = item->getContainer(); if (tmpContainer) { containers.push_back(tmpContainer); } else { @@ -6007,7 +5989,7 @@ std::pair Player::getForgeSliversAndCores() const { uint64_t coreCount = 0; // Check items from inventory - for (const auto* item : getAllInventoryItems()) { + for (const auto item : getAllInventoryItems()) { if (!item) { continue; } @@ -6048,9 +6030,9 @@ size_t Player::getMaxDepotItems() const { return g_configManager().getNumber(FREE_DEPOT_LIMIT); } -std::forward_list Player::getMuteConditions() const { - std::forward_list muteConditions; - for (Condition* condition : conditions) { +std::forward_list> Player::getMuteConditions() const { + std::forward_list> muteConditions; + for (std::shared_ptr condition : conditions) { if (condition->getTicks() <= 0) { continue; } @@ -6071,7 +6053,7 @@ void Player::setGuild(const std::shared_ptr newGuild) { } if (guild) { - guild->removeMember(this); + guild->removeMember(static_self_cast()); guild = nullptr; } @@ -6086,7 +6068,7 @@ void Player::setGuild(const std::shared_ptr newGuild) { guild = newGuild; guildRank = rank; - newGuild->addMember(this); + newGuild->addMember(static_self_cast()); } } @@ -6095,7 +6077,7 @@ void Player::updateRegeneration() { return; } - Condition* condition = getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT); + std::shared_ptr condition = getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT); if (condition) { condition->setParam(CONDITION_PARAM_HEALTHGAIN, vocation->getHealthGainAmount()); condition->setParam(CONDITION_PARAM_HEALTHTICKS, vocation->getHealthGainTicks()); @@ -6134,12 +6116,12 @@ uint64_t Player::getItemCustomPrice(uint16_t itemId, bool buyPrice /* = false*/) } uint16_t Player::getFreeBackpackSlots() const { - Thing* thing = getThing(CONST_SLOT_BACKPACK); + std::shared_ptr thing = getThing(CONST_SLOT_BACKPACK); if (!thing) { return 0; } - Container* backpack = thing->getContainer(); + std::shared_ptr backpack = thing->getContainer(); if (!backpack) { return 0; } @@ -6169,7 +6151,7 @@ void Player::addItemImbuementStats(const Imbuement* imbuement) { // Add imbuement speed if (imbuement->speed != 0) { - g_game().changeSpeed(this, imbuement->speed); + g_game().changeSpeed(static_self_cast(), imbuement->speed); } // Add imbuement capacity @@ -6208,7 +6190,7 @@ void Player::removeItemImbuementStats(const Imbuement* imbuement) { // Remove imbuement speed if (imbuement->speed != 0) { - g_game().changeSpeed(this, -imbuement->speed); + g_game().changeSpeed(static_self_cast(), -imbuement->speed); } // Remove imbuement capacity @@ -6235,10 +6217,10 @@ bool Player::addItemFromStash(uint16_t itemId, uint32_t itemCount) { while (itemCount > 0) { auto addValue = itemCount > stackCount ? stackCount : itemCount; itemCount -= addValue; - Item* newItem = Item::CreateItem(itemId, addValue); + std::shared_ptr newItem = Item::CreateItem(itemId, addValue); - if (!g_game().tryRetrieveStashItems(this, newItem)) { - g_game().internalPlayerAddItem(this, newItem, true); + if (!g_game().tryRetrieveStashItems(static_self_cast(), newItem)) { + g_game().internalPlayerAddItem(static_self_cast(), newItem, true); } } @@ -6250,21 +6232,21 @@ bool Player::addItemFromStash(uint16_t itemId, uint32_t itemCount) { return true; } -void sendStowItems(Item &item, Item &stowItem, StashContainerList &itemDict) { - if (stowItem.getID() == item.getID()) { - itemDict.push_back(std::pair(&stowItem, stowItem.getItemCount())); +void sendStowItems(const std::shared_ptr &item, const std::shared_ptr &stowItem, StashContainerList &itemDict) { + if (stowItem->getID() == item->getID()) { + itemDict.push_back(std::pair, uint32_t>(stowItem, stowItem->getItemCount())); } - if (auto container = stowItem.getContainer()) { + if (auto container = stowItem->getContainer()) { for (auto stowable_it : container->getStowableItems()) { - if ((stowable_it.first)->getID() == item.getID()) { + if ((stowable_it.first)->getID() == item->getID()) { itemDict.push_back(stowable_it); } } } } -void Player::stowItem(Item* item, uint32_t count, bool allItems) { +void Player::stowItem(std::shared_ptr item, uint32_t count, bool allItems) { if (!item || !item->isItemStorable()) { sendCancelMessage("This item cannot be stowed here."); return; @@ -6275,19 +6257,19 @@ void Player::stowItem(Item* item, uint32_t count, bool allItems) { if (!item->isInsideDepot(true)) { // Stow "all items" from player backpack if (auto backpack = getInventoryItem(CONST_SLOT_BACKPACK)) { - sendStowItems(*item, *backpack, itemDict); + sendStowItems(item, backpack, itemDict); } // Stow "all items" from loot pouch auto itemParent = item->getParent(); auto lootPouch = itemParent->getItem(); if (itemParent && lootPouch && lootPouch->getID() == ITEM_GOLD_POUCH) { - sendStowItems(*item, *lootPouch, itemDict); + sendStowItems(item, lootPouch, itemDict); } } // Stow locker items - DepotLocker* depotLocker = getDepotLocker(getLastDepotId()); + std::shared_ptr depotLocker = getDepotLocker(getLastDepotId()); auto [itemVector, itemMap] = requestLockerItems(depotLocker); for (auto lockerItem : itemVector) { if (lockerItem == nullptr) { @@ -6295,12 +6277,12 @@ void Player::stowItem(Item* item, uint32_t count, bool allItems) { } if (item->isInsideDepot(true)) { - sendStowItems(*item, *lockerItem, itemDict); + sendStowItems(item, lockerItem, itemDict); } } } else if (item->getContainer()) { itemDict = item->getContainer()->getStowableItems(); - for (Item* containerItem : item->getContainer()->getItems(true)) { + for (std::shared_ptr containerItem : item->getContainer()->getItems(true)) { uint32_t depotChest = g_configManager().getNumber(DEPOTCHEST); bool validDepot = depotChest > 0 && depotChest < 21; if (g_configManager().getBoolean(STASH_MOVING) && containerItem && !containerItem->isStackable() && validDepot) { @@ -6310,7 +6292,7 @@ void Player::stowItem(Item* item, uint32_t count, bool allItems) { } } } else { - itemDict.push_back(std::pair(item, count)); + itemDict.push_back(std::pair, uint32_t>(item, count)); } if (itemDict.size() == 0) { @@ -6322,22 +6304,22 @@ void Player::stowItem(Item* item, uint32_t count, bool allItems) { } void Player::openPlayerContainers() { - std::vector> openContainersList; + std::vector>> openContainersList; for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) { - Item* item = inventory[i]; + std::shared_ptr item = inventory[i]; if (!item) { continue; } - Container* itemContainer = item->getContainer(); + std::shared_ptr itemContainer = item->getContainer(); if (itemContainer) { auto cid = item->getAttribute(ItemAttribute_t::OPENCONTAINER); if (cid > 0) { openContainersList.emplace_back(std::make_pair(cid, itemContainer)); } for (ContainerIterator it = itemContainer->iterator(); it.hasNext(); it.advance()) { - Container* subContainer = (*it)->getContainer(); + std::shared_ptr subContainer = (*it)->getContainer(); if (subContainer) { auto subcid = (*it)->getAttribute(ItemAttribute_t::OPENCONTAINER); if (subcid > 0) { @@ -6348,7 +6330,7 @@ void Player::openPlayerContainers() { } } - std::sort(openContainersList.begin(), openContainersList.end(), [](const std::pair &left, const std::pair &right) { + std::sort(openContainersList.begin(), openContainersList.end(), [](const std::pair> &left, const std::pair> &right) { return left.first < right.first; }); @@ -6373,22 +6355,16 @@ void Player::initializePrey() { slot->reloadMonsterGrid(getPreyBlackList(), getLevel()); } - if (!setPreySlotClass(std::move(slot))) { - slot.reset(); - } + setPreySlotClass(slot); } } } void Player::removePreySlotById(PreySlot_t slotid) { - auto it = std::remove_if(preys.begin(), preys.end(), [slotid](const PreySlot* preyIt) { + auto it = std::remove_if(preys.begin(), preys.end(), [slotid](const std::unique_ptr &preyIt) { return preyIt->id == slotid; }); - for (auto i = it; i != preys.end(); ++i) { - delete *i; - } - preys.erase(it, preys.end()); } @@ -6407,14 +6383,12 @@ void Player::initializeTaskHunting() { slot->reloadMonsterGrid(getTaskHuntingBlackList(), getLevel()); } - if (!setTaskHuntingSlotClass(std::move(slot))) { - slot.reset(); - } + setTaskHuntingSlotClass(slot); } } if (client && g_configManager().getBoolean(TASK_HUNTING_ENABLED) && !client->oldProtocol) { - client->writeToOutputBuffer(g_ioprey().GetTaskHuntingBaseDate()); + client->writeToOutputBuffer(g_ioprey().getTaskHuntingBaseDate()); } } @@ -6513,13 +6487,13 @@ void Player::clearCooldowns() { void Player::requestDepotItems() { ItemsTierCountList itemMap; uint16_t count = 0; - const DepotLocker* depotLocker = getDepotLocker(getLastDepotId()); + std::shared_ptr depotLocker = getDepotLocker(getLastDepotId()); if (!depotLocker) { return; } - for (Item* locker : depotLocker->getItemList()) { - const Container* c = locker->getContainer(); + for (std::shared_ptr locker : depotLocker->getItemList()) { + std::shared_ptr c = locker->getContainer(); if (!c || c->empty()) { continue; } @@ -6579,19 +6553,19 @@ void Player::requestDepotSearchItem(uint16_t itemId, uint8_t tier) { stashCount = getStashItemCount(itemId); } - const DepotLocker* depotLocker = getDepotLocker(getLastDepotId()); + std::shared_ptr depotLocker = getDepotLocker(getLastDepotId()); if (!depotLocker) { return; } - for (Item* locker : depotLocker->getItemList()) { - const Container* c = locker->getContainer(); + for (std::shared_ptr locker : depotLocker->getItemList()) { + std::shared_ptr c = locker->getContainer(); if (!c || c->empty()) { continue; } for (ContainerIterator it = c->iterator(); it.hasNext(); it.advance()) { - Item* item = *it; + std::shared_ptr item = *it; if (!item || item->getID() != itemId || item->getTier() != tier) { continue; } @@ -6615,14 +6589,14 @@ void Player::requestDepotSearchItem(uint16_t itemId, uint8_t tier) { } void Player::retrieveAllItemsFromDepotSearch(uint16_t itemId, uint8_t tier, bool isDepot) { - const DepotLocker* depotLocker = getDepotLocker(getLastDepotId()); + std::shared_ptr depotLocker = getDepotLocker(getLastDepotId()); if (!depotLocker) { return; } - std::vector itemsVector; - for (Item* locker : depotLocker->getItemList()) { - const Container* c = locker->getContainer(); + std::vector> itemsVector; + for (std::shared_ptr locker : depotLocker->getItemList()) { + std::shared_ptr c = locker->getContainer(); if (!c || c->empty() || // Retrieve from inbox. (c->isInbox() && isDepot) || @@ -6632,7 +6606,7 @@ void Player::retrieveAllItemsFromDepotSearch(uint16_t itemId, uint8_t tier, bool } for (ContainerIterator it = c->iterator(); it.hasNext(); it.advance()) { - Item* item = *it; + std::shared_ptr item = *it; if (!item) { continue; } @@ -6644,14 +6618,14 @@ void Player::retrieveAllItemsFromDepotSearch(uint16_t itemId, uint8_t tier, bool } ReturnValue ret = RETURNVALUE_NOERROR; - for (Item* item : itemsVector) { + for (std::shared_ptr item : itemsVector) { // First lets try to retrieve the item to the stash retrieve container. - if (g_game().tryRetrieveStashItems(this, item)) { + if (g_game().tryRetrieveStashItems(static_self_cast(), item)) { continue; } // If the retrieve fails to move the item to the stash retrieve container, let's add the item anywhere. - if (ret = g_game().internalMoveItem(item->getParent(), this, INDEX_WHEREEVER, item, item->getItemCount(), nullptr); ret == RETURNVALUE_NOERROR) { + if (ret = g_game().internalMoveItem(item->getParent(), getPlayer(), INDEX_WHEREEVER, item, item->getItemCount(), nullptr); ret == RETURNVALUE_NOERROR) { continue; } @@ -6668,37 +6642,37 @@ void Player::openContainerFromDepotSearch(const Position &pos) { return; } - const Item* item = getItemFromDepotSearch(depotSearchOnItem.first, pos); + std::shared_ptr item = getItemFromDepotSearch(depotSearchOnItem.first, pos); if (!item) { sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - Container* container = item->getParent() ? item->getParent()->getContainer() : nullptr; + std::shared_ptr container = item->getParent() ? item->getParent()->getContainer() : nullptr; if (!container) { sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - g_actions().useItem(this, pos, 0, container, false); + g_actions().useItem(static_self_cast(), pos, 0, container, false); } -Item* Player::getItemFromDepotSearch(uint16_t itemId, const Position &pos) { - const DepotLocker* depotLocker = getDepotLocker(getLastDepotId()); +std::shared_ptr Player::getItemFromDepotSearch(uint16_t itemId, const Position &pos) { + std::shared_ptr depotLocker = getDepotLocker(getLastDepotId()); if (!depotLocker) { return nullptr; } uint8_t index = 0; - for (Item* locker : depotLocker->getItemList()) { - const Container* c = locker->getContainer(); + for (std::shared_ptr locker : depotLocker->getItemList()) { + std::shared_ptr c = locker->getContainer(); if (!c || c->empty() || (c->isInbox() && pos.y != 0x21) || // From inbox. (!c->isInbox() && pos.y != 0x20)) { // From depot. continue; } for (ContainerIterator it = c->iterator(); it.hasNext(); it.advance()) { - Item* item = *it; + std::shared_ptr item = *it; if (!item || item->getID() != itemId || item->getTier() != depotSearchOnItem.second) { continue; } @@ -6713,23 +6687,23 @@ Item* Player::getItemFromDepotSearch(uint16_t itemId, const Position &pos) { return nullptr; } -std::pair, std::map>> Player::requestLockerItems(DepotLocker* depotLocker, bool sendToClient /*= false*/, uint8_t tier /*= 0*/) const { +std::pair>, std::map>> Player::requestLockerItems(std::shared_ptr depotLocker, bool sendToClient /*= false*/, uint8_t tier /*= 0*/) const { if (depotLocker == nullptr) { g_logger().error("{} - Depot locker is nullptr", __FUNCTION__); return {}; } std::map> lockerItems; - std::vector itemVector; - std::vector containers { depotLocker }; + std::vector> itemVector; + std::vector> containers { depotLocker }; size_t size = 0; do { - const Container* container = containers[size]; + std::shared_ptr container = containers[size]; size++; - for (Item* item : container->getItemList()) { - Container* lockerContainers = item->getContainer(); + for (std::shared_ptr item : container->getItemList()) { + std::shared_ptr lockerContainers = item->getContainer(); if (lockerContainers && !lockerContainers->empty()) { containers.push_back(lockerContainers); continue; @@ -6777,9 +6751,9 @@ std::pair, std::map>> P return std::make_pair(itemVector, lockerItems); } -std::pair, uint16_t> Player::getLockerItemsAndCountById(DepotLocker &depotLocker, uint8_t tier, uint16_t itemId) { - std::vector lockerItems; - auto [itemVector, itemMap] = requestLockerItems(&depotLocker, false, tier); +std::pair>, uint16_t> Player::getLockerItemsAndCountById(const std::shared_ptr &depotLocker, uint8_t tier, uint16_t itemId) { + std::vector> lockerItems; + auto [itemVector, itemMap] = requestLockerItems(depotLocker, false, tier); uint16_t totalCount = 0; for (auto item : itemVector) { if (!item || item->getID() != itemId) { @@ -6827,30 +6801,30 @@ bool Player::saySpell( int32_t valueEmote = 0; // Send to client - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (std::shared_ptr spectator : spectators) { + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { valueEmote = tmpPlayer->getStorageValue(STORAGEVALUE_EMOTE); - if (!ghostMode || tmpPlayer->canSeeCreature(this)) { + if (!ghostMode || tmpPlayer->canSeeCreature(static_self_cast())) { if (valueEmote == 1) { - tmpPlayer->sendCreatureSay(this, TALKTYPE_MONSTER_SAY, text, pos); + tmpPlayer->sendCreatureSay(static_self_cast(), TALKTYPE_MONSTER_SAY, text, pos); } else { - tmpPlayer->sendCreatureSay(this, TALKTYPE_SPELL_USE, text, pos); + tmpPlayer->sendCreatureSay(static_self_cast(), TALKTYPE_SPELL_USE, text, pos); } } } } // Execute lua event method - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { auto tmpPlayer = spectator->getPlayer(); if (!tmpPlayer) { continue; } - tmpPlayer->onCreatureSay(this, type, text); - if (this != tmpPlayer) { - g_events().eventCreatureOnHear(tmpPlayer, this, text, type); - g_callbacks().executeCallback(EventCallback_t::creatureOnHear, &EventCallback::creatureOnHear, tmpPlayer, this, text, type); + tmpPlayer->onCreatureSay(static_self_cast(), type, text); + if (static_self_cast() != tmpPlayer) { + g_events().eventCreatureOnHear(tmpPlayer, getPlayer(), text, type); + g_callbacks().executeCallback(EventCallback_t::creatureOnHear, &EventCallback::creatureOnHear, tmpPlayer, getPlayer(), text, type); } } return true; @@ -6904,7 +6878,7 @@ void Player::forgeFuseItems(uint16_t itemId, uint8_t tier, bool success, bool re return; } - Item* firstForgedItem = Item::CreateItem(itemId, 1); + std::shared_ptr firstForgedItem = Item::CreateItem(itemId, 1); if (!firstForgedItem) { g_logger().error("[Log 3] Player with name {} failed to fuse item with id {}", getName(), itemId); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); @@ -6919,7 +6893,7 @@ void Player::forgeFuseItems(uint16_t itemId, uint8_t tier, bool success, bool re return; } - Item* secondForgedItem = Item::CreateItem(itemId, 1); + std::shared_ptr secondForgedItem = Item::CreateItem(itemId, 1); if (!secondForgedItem) { g_logger().error("[Log 4] Player with name {} failed to fuse item with id {}", getName(), itemId); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); @@ -6966,7 +6940,7 @@ void Player::forgeFuseItems(uint16_t itemId, uint8_t tier, bool success, bool re } break; } - if (!g_game().removeMoney(this, cost, 0, true)) { + if (!g_game().removeMoney(static_self_cast(), cost, 0, true)) { g_logger().error("[{}] Failed to remove {} gold from player with name {}", __FUNCTION__, cost, getName()); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); return; @@ -7039,7 +7013,7 @@ void Player::forgeFuseItems(uint16_t itemId, uint8_t tier, bool success, bool re } break; } - if (!g_game().removeMoney(this, cost, 0, true)) { + if (!g_game().removeMoney(static_self_cast(), cost, 0, true)) { g_logger().error("[{}] Failed to remove {} gold from player with name {}", __FUNCTION__, cost, getName()); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); return; @@ -7047,7 +7021,7 @@ void Player::forgeFuseItems(uint16_t itemId, uint8_t tier, bool success, bool re history.cost = cost; } - returnValue = g_game().internalAddItem(this, exaltationContainer, INDEX_WHEREEVER); + returnValue = g_game().internalAddItem(static_self_cast(), exaltationContainer, INDEX_WHEREEVER); if (returnValue != RETURNVALUE_NOERROR) { g_logger().error("Failed to add exaltation chest to player with name {}", fmt::underlying(ITEM_EXALTATION_CHEST), getName()); sendCancelMessage(getReturnMessage(returnValue)); @@ -7110,7 +7084,7 @@ void Player::forgeTransferItemTier(uint16_t donorItemId, uint8_t tier, uint16_t return; } - Item* newDonorItem = Item::CreateItem(donorItemId, 1); + std::shared_ptr newDonorItem = Item::CreateItem(donorItemId, 1); if (!newDonorItem) { g_logger().error("[Log 4] Player with name {} failed to transfer item with id {}", getName(), donorItemId); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); @@ -7124,7 +7098,7 @@ void Player::forgeTransferItemTier(uint16_t donorItemId, uint8_t tier, uint16_t return; } - Item* newReceiveItem = Item::CreateItem(receiveItemId, 1); + std::shared_ptr newReceiveItem = Item::CreateItem(receiveItemId, 1); if (!newReceiveItem) { g_logger().error("[Log 6] Player with name {} failed to fuse item with id {}", getName(), receiveItemId); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); @@ -7169,14 +7143,14 @@ void Player::forgeTransferItemTier(uint16_t donorItemId, uint8_t tier, uint16_t return; } - if (!g_game().removeMoney(this, cost, 0, true)) { + if (!g_game().removeMoney(static_self_cast(), cost, 0, true)) { g_logger().error("[{}] Failed to remove {} gold from player with name {}", __FUNCTION__, cost, getName()); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); return; } history.cost = cost; - returnValue = g_game().internalAddItem(this, exaltationContainer, INDEX_WHEREEVER); + returnValue = g_game().internalAddItem(static_self_cast(), exaltationContainer, INDEX_WHEREEVER); if (returnValue != RETURNVALUE_NOERROR) { g_logger().error("[Log 10] Failed to add forge item {} from player with name {}", fmt::underlying(ITEM_EXALTATION_CHEST), getName()); sendCancelMessage(getReturnMessage(returnValue)); @@ -7209,8 +7183,8 @@ void Player::forgeResourceConversion(uint8_t action) { } auto itemCount = static_cast(g_configManager().getNumber(FORGE_SLIVER_AMOUNT)); - Item* item = Item::CreateItem(ITEM_FORGE_SLIVER, itemCount); - returnValue = g_game().internalPlayerAddItem(this, item); + std::shared_ptr item = Item::CreateItem(ITEM_FORGE_SLIVER, itemCount); + returnValue = g_game().internalPlayerAddItem(static_self_cast(), item); if (returnValue != RETURNVALUE_NOERROR) { g_logger().error("Failed to add {} slivers to player with name {}", itemCount, getName()); sendCancelMessage(getReturnMessage(returnValue)); @@ -7235,9 +7209,9 @@ void Player::forgeResourceConversion(uint8_t action) { return; } - if (Item* item = Item::CreateItem(ITEM_FORGE_CORE, 1); + if (std::shared_ptr item = Item::CreateItem(ITEM_FORGE_CORE, 1); item) { - returnValue = g_game().internalPlayerAddItem(this, item); + returnValue = g_game().internalPlayerAddItem(static_self_cast(), item); } if (returnValue != RETURNVALUE_NOERROR) { g_logger().error("Failed to add one core to player with name {}", getName()); @@ -7414,15 +7388,12 @@ void Player::registerForgeHistoryDescription(ForgeHistory history) { ); } else if (history.actionType == ForgeConversion_t::FORGE_ACTION_DUSTTOSLIVERS) { detailsResponse << fmt::format("Converted {:d} dust to {:d} slivers.", history.cost, history.gained); - } else if (history.actionType == ForgeConversion_t::FORGE_ACTION_SLIVERSTOCORES) { history.actionType = ForgeConversion_t::FORGE_ACTION_DUSTTOSLIVERS; detailsResponse << fmt::format("Converted {:d} slivers to {:d} exalted core.", history.cost, history.gained); - } else if (history.actionType == ForgeConversion_t::FORGE_ACTION_INCREASELIMIT) { history.actionType = ForgeConversion_t::FORGE_ACTION_DUSTTOSLIVERS; detailsResponse << fmt::format("Spent {:d} dust to increase the dust limit to {:d}.", history.cost, history.gained + 1); - } else { detailsResponse << "(unknown)"; } @@ -7437,26 +7408,26 @@ void Player::closeAllExternalContainers() { return; } - std::vector containerToClose; + std::vector> containerToClose; for (const auto &it : openContainers) { - Container* container = it.second.container; + std::shared_ptr container = it.second.container; if (!container) { continue; } - if (container->getHoldingPlayer() != this) { + if (container->getHoldingPlayer() != getPlayer()) { containerToClose.push_back(container); } } - for (Container* container : containerToClose) { + for (std::shared_ptr container : containerToClose) { autoCloseContainers(container); } } SoundEffect_t Player::getHitSoundEffect() const { // Distance sound effects - const Item* tool = getWeapon(); + std::shared_ptr tool = getWeapon(); if (tool == nullptr) { return SoundEffect_t::SILENCE; } @@ -7498,7 +7469,7 @@ SoundEffect_t Player::getHitSoundEffect() const { } SoundEffect_t Player::getAttackSoundEffect() const { - const Item* tool = getWeapon(); + std::shared_ptr tool = getWeapon(); if (tool == nullptr) { return SoundEffect_t::HUMAN_CLOSE_ATK_FIST; } @@ -7575,7 +7546,7 @@ void Player::setHazardSystemPoints(int32_t count) { } } -void Player::parseAttackRecvHazardSystem(CombatDamage &damage, const Monster* monster) { +void Player::parseAttackRecvHazardSystem(CombatDamage &damage, std::shared_ptr monster) { if (!monster || !monster->getHazard()) { return; } @@ -7634,7 +7605,7 @@ void Player::parseAttackRecvHazardSystem(CombatDamage &damage, const Monster* mo } } -void Player::parseAttackDealtHazardSystem(CombatDamage &damage, const Monster* monster) { +void Player::parseAttackDealtHazardSystem(CombatDamage &damage, std::shared_ptr monster) { if (!g_configManager().getBoolean(TOGGLE_HAZARDSYSTEM)) { return; } @@ -7696,7 +7667,9 @@ void Player::sendLootMessage(const std::string &message) const { return; } - party->getLeader()->sendTextMessage(MESSAGE_LOOT, message); + if (auto partyLeader = party->getLeader()) { + partyLeader->sendTextMessage(MESSAGE_LOOT, message); + } for (const auto partyMember : party->getMembers()) { if (partyMember) { partyMember->sendTextMessage(MESSAGE_LOOT, message); @@ -7704,7 +7677,7 @@ void Player::sendLootMessage(const std::string &message) const { } } -Container* Player::getLootPouch() const { +std::shared_ptr Player::getLootPouch() { // Allow players with CM access or higher have the loot pouch anywhere auto parentItem = getParent() ? getParent()->getItem() : nullptr; if (isPlayerGroup() && parentItem && parentItem->getID() != ITEM_STORE_INBOX) { diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index 34bda5485..a70df45b3 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -81,7 +81,7 @@ struct ForgeHistory { }; struct OpenContainer { - Container* container; + std::shared_ptr container; uint16_t index; }; @@ -100,11 +100,8 @@ class Player final : public Creature, public Cylinder, public Bankable { Player(const Player &) = delete; Player &operator=(const Player &) = delete; - Player* getPlayer() override { - return this; - } - const Player* getPlayer() const override { - return this; + std::shared_ptr getPlayer() override { + return static_self_cast(); } static std::shared_ptr createPlayerTask(uint32_t delay, std::function f, std::string context); @@ -135,7 +132,7 @@ class Player final : public Creature, public Cylinder, public Bankable { const std::string &getNameDescription() const override { return name; } - std::string getDescription(int32_t lookDistance) const override; + std::string getDescription(int32_t lookDistance) override; CreatureType_t getType() const override { return CREATURETYPE_PLAYER; @@ -260,7 +257,7 @@ class Player final : public Creature, public Cylinder, public Bankable { guildRank = newGuildRank; } - bool isGuildMate(const Player* player) const; + bool isGuildMate(std::shared_ptr player) const; [[nodiscard]] const std::string &getGuildNick() const { return guildNick; @@ -269,7 +266,7 @@ class Player final : public Creature, public Cylinder, public Bankable { guildNick = nick; } - bool isInWar(const Player* player) const; + bool isInWar(std::shared_ptr player) const; bool isInWarList(uint32_t guild_id) const; void setLastWalkthroughAttempt(int64_t walkthroughAttempt) { @@ -279,11 +276,11 @@ class Player final : public Creature, public Cylinder, public Bankable { lastWalkthroughPosition = walkthroughPosition; } - Inbox* getInbox() const { + std::shared_ptr getInbox() const { return inbox; } - uint32_t getClientIcons() const; + uint32_t getClientIcons(); const GuildWarVector &getGuildWarVector() const { return guildWarVector; @@ -303,8 +300,8 @@ class Player final : public Creature, public Cylinder, public Bankable { } } - void refreshBestiaryMonsterTracker() const { - refreshCyclopediaMonsterTracker(getCyclopediaMonsterTrackerSet(false), false); + void refreshCyclopediaMonsterTracker(bool isBoss = false) const { + refreshCyclopediaMonsterTracker(getCyclopediaMonsterTrackerSet(isBoss), isBoss); } void refreshCyclopediaMonsterTracker(const phmap::parallel_flat_hash_set> &trackerList, bool isBoss) const { @@ -338,10 +335,10 @@ class Player final : public Creature, public Cylinder, public Bankable { return secureMode; } - void setParty(Party* newParty) { + void setParty(std::shared_ptr newParty) { this->party = newParty; } - Party* getParty() const { + std::shared_ptr getParty() const { return party; } @@ -386,17 +383,17 @@ class Player final : public Creature, public Cylinder, public Bankable { int32_t getReflectFlat(CombatType_t combat, bool useCharges = false) const override; - PartyShields_t getPartyShield(const Player* player) const; - bool isInviting(const Player* player) const; - bool isPartner(const Player* player) const; - void sendPlayerPartyIcons(Player* player); - bool addPartyInvitation(Party* party); - void removePartyInvitation(Party* party); + PartyShields_t getPartyShield(std::shared_ptr player); + bool isInviting(std::shared_ptr player) const; + bool isPartner(std::shared_ptr player) const; + void sendPlayerPartyIcons(std::shared_ptr player); + bool addPartyInvitation(std::shared_ptr party); + void removePartyInvitation(std::shared_ptr party); void clearPartyInvitations(); void sendUnjustifiedPoints(); - GuildEmblems_t getGuildEmblem(const Player* player) const; + GuildEmblems_t getGuildEmblem(std::shared_ptr player) const; uint64_t getSpentMana() const { return manaSpent; @@ -414,17 +411,17 @@ class Player final : public Creature, public Cylinder, public Bankable { group->flags[static_cast(flag)] = false; } - BedItem* getBedItem() { + std::shared_ptr getBedItem() { return bedItem; } - void setBedItem(BedItem* b) { + void setBedItem(std::shared_ptr b) { bedItem = b; } bool hasImbuingItem() { return imbuingItem != nullptr; } - void setImbuingItem(Item* item); + void setImbuingItem(std::shared_ptr item); void addBlessing(uint8_t index, uint8_t count) { if (blessings[index - 1] == 255) { @@ -458,12 +455,12 @@ class Player final : public Creature, public Cylinder, public Bankable { } uint32_t getIP() const; - void addContainer(uint8_t cid, Container* container); + void addContainer(uint8_t cid, std::shared_ptr container); void closeContainer(uint8_t cid); void setContainerIndex(uint8_t cid, uint16_t index); - Container* getContainerByID(uint8_t cid); - int8_t getContainerID(const Container* container) const; + std::shared_ptr getContainerByID(uint8_t cid); + int8_t getContainerID(std::shared_ptr container) const; uint16_t getContainerIndex(uint8_t cid) const; bool canOpenCorpse(uint32_t ownerId) const; @@ -494,7 +491,6 @@ class Player final : public Creature, public Cylinder, public Bankable { return inMarket; } void setSpecialMenuAvailable(bool supplyStashBool, bool marketMenuBool, bool depotSearchBool) { - // Closing depot search when player have special container disabled and it's still open. if (isDepotSearchOpen() && !depotSearchBool && depotSearch) { depotSearchOnItem = { 0, 0 }; @@ -638,10 +634,10 @@ class Player final : public Creature, public Cylinder, public Bankable { const Position &getTemplePosition() const { return town->getTemplePosition(); } - Town* getTown() const { + std::shared_ptr getTown() const { return town; } - void setTown(Town* newTown) { + void setTown(const std::shared_ptr &newTown) { this->town = newTown; } @@ -649,7 +645,7 @@ class Player final : public Creature, public Cylinder, public Bankable { bool hasModalWindowOpen(uint32_t modalWindowId) const; void onModalWindowHandled(uint32_t modalWindowId); - bool isPushable() const override; + bool isPushable() override; uint32_t isMuted() const; void addMessageBuffer(); void removeMessageBuffer(); @@ -722,7 +718,7 @@ class Player final : public Creature, public Cylinder, public Bankable { int32_t getMaxHealth() const override; uint32_t getMaxMana() const override; - Item* getInventoryItem(Slots_t slot) const; + std::shared_ptr getInventoryItem(Slots_t slot) const; bool isItemAbilityEnabled(Slots_t slot) const { return inventoryAbilities[slot]; @@ -741,26 +737,26 @@ class Player final : public Creature, public Cylinder, public Bankable { void addConditionSuppressions(const std::array &addCondition); void removeConditionSuppressions(); - Reward* getReward(const uint64_t rewardId, const bool autoCreate); + std::shared_ptr getReward(const uint64_t rewardId, const bool autoCreate); void removeReward(uint64_t rewardId); void getRewardList(std::vector &rewards) const; - RewardChest* getRewardChest(); + std::shared_ptr getRewardChest(); - std::vector getRewardsFromContainer(const Container* container) const; + std::vector> getRewardsFromContainer(std::shared_ptr container) const; - DepotChest* getDepotChest(uint32_t depotId, bool autoCreate); - DepotLocker* getDepotLocker(uint32_t depotId); - void onReceiveMail() const; - bool isNearDepotBox() const; + std::shared_ptr getDepotChest(uint32_t depotId, bool autoCreate); + std::shared_ptr getDepotLocker(uint32_t depotId); + void onReceiveMail(); + bool isNearDepotBox(); - Container* setLootContainer(ObjectCategory_t category, Container* container, bool loading = false); - Container* getLootContainer(ObjectCategory_t category) const; + std::shared_ptr setLootContainer(ObjectCategory_t category, std::shared_ptr container, bool loading = false); + std::shared_ptr getLootContainer(ObjectCategory_t category) const; - bool canSee(const Position &pos) const override; - bool canSeeCreature(const Creature* creature) const override; + bool canSee(const Position &pos) override; + bool canSeeCreature(std::shared_ptr creature) const override; - bool canWalkthrough(const Creature* creature) const; - bool canWalkthroughEx(const Creature* creature) const; + bool canWalkthrough(std::shared_ptr creature); + bool canWalkthroughEx(std::shared_ptr creature); RaceType_t getRace() const override { return RACE_BLOOD; @@ -776,32 +772,32 @@ class Player final : public Creature, public Cylinder, public Bankable { TradeState_t getTradeState() const { return tradeState; } - Item* getTradeItem() { + std::shared_ptr getTradeItem() { return tradeItem; } // shop functions - void setShopOwner(Npc* owner) { + void setShopOwner(std::shared_ptr owner) { shopOwner = owner; } - Npc* getShopOwner() const { + std::shared_ptr getShopOwner() const { return shopOwner; } // V.I.P. functions - void notifyStatusChange(Player* player, VipStatus_t status, bool message = true); + void notifyStatusChange(std::shared_ptr player, VipStatus_t status, bool message = true); bool removeVIP(uint32_t vipGuid); bool addVIP(uint32_t vipGuid, const std::string &vipName, VipStatus_t status); bool addVIPInternal(uint32_t vipGuid); bool editVIP(uint32_t vipGuid, const std::string &description, uint32_t icon, bool notify); // follow functions - bool setFollowCreature(Creature* creature) override; + bool setFollowCreature(std::shared_ptr creature) override; void goToFollowCreature() override; // follow events - void onFollowCreature(const Creature* creature) override; + void onFollowCreature(std::shared_ptr creature) override; // walk events void onWalk(Direction &dir) override; @@ -809,9 +805,9 @@ class Player final : public Creature, public Cylinder, public Bankable { void onWalkComplete() override; void stopWalk(); - bool openShopWindow(Npc* npc); + bool openShopWindow(std::shared_ptr npc); bool closeShopWindow(bool sendCloseShopWindow = true); - bool updateSaleShopList(const Item* item); + bool updateSaleShopList(std::shared_ptr item); bool hasShopItemForSale(uint16_t itemId, uint8_t subType) const; void setChaseMode(bool mode); @@ -830,16 +826,16 @@ class Player final : public Creature, public Cylinder, public Bankable { faction = factionId; } // combat functions - bool setAttackedCreature(Creature* creature) override; + bool setAttackedCreature(std::shared_ptr creature) override; bool isImmune(CombatType_t type) const override; bool isImmune(ConditionType_t type) const override; bool hasShield() const; bool isAttackable() const override; - static bool lastHitIsPlayer(Creature* lastHitCreature); + static bool lastHitIsPlayer(std::shared_ptr lastHitCreature); // stash functions bool addItemFromStash(uint16_t itemId, uint32_t itemCount); - void stowItem(Item* item, uint32_t count, bool allItems); + void stowItem(std::shared_ptr item, uint32_t count, bool allItems); void changeHealth(int32_t healthChange, bool sendHealthChange = true) override; void changeMana(int32_t manaChange) override; @@ -848,7 +844,7 @@ class Player final : public Creature, public Cylinder, public Bankable { bool isPzLocked() const { return pzLocked; } - BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t &damage, bool checkDefense = false, bool checkArmor = false, bool field = false) override; + BlockType_t blockHit(std::shared_ptr attacker, CombatType_t combatType, int32_t &damage, bool checkDefense = false, bool checkArmor = false, bool field = false) override; void doAttacking(uint32_t interval) override; bool hasExtraSwing() override { return lastAttack > 0 && ((OTSYS_TIME() - lastAttack) >= getAttackSpeed()); @@ -870,14 +866,14 @@ class Player final : public Creature, public Cylinder, public Bankable { return lastAttackBlockType; } - Item* getWeapon(Slots_t slot, bool ignoreAmmo) const; - Item* getWeapon(bool ignoreAmmo = false) const; + std::shared_ptr getWeapon(Slots_t slot, bool ignoreAmmo) const; + std::shared_ptr getWeapon(bool ignoreAmmo = false) const; WeaponType_t getWeaponType() const; - int32_t getWeaponSkill(const Item* item) const; - void getShieldAndWeapon(const Item*&shield, const Item*&weapon) const; + int32_t getWeaponSkill(std::shared_ptr item) const; + void getShieldAndWeapon(std::shared_ptr &shield, std::shared_ptr &weapon) const; - void drainHealth(Creature* attacker, int32_t damage) override; - void drainMana(Creature* attacker, int32_t manaLoss) override; + void drainHealth(std::shared_ptr attacker, int32_t damage) override; + void drainMana(std::shared_ptr attacker, int32_t manaLoss) override; void addManaSpent(uint64_t amount); void addSkillAdvance(skills_t skill, uint64_t count); @@ -890,20 +886,20 @@ class Player final : public Creature, public Cylinder, public Bankable { void addInFightTicks(bool pzlock = false); - uint64_t getGainedExperience(Creature* attacker) const override; + uint64_t getGainedExperience(std::shared_ptr attacker) const override; // combat event functions void onAddCondition(ConditionType_t type) override; void onAddCombatCondition(ConditionType_t type) override; void onEndCondition(ConditionType_t type) override; - void onCombatRemoveCondition(Condition* condition) override; - void onAttackedCreature(Creature* target) override; + void onCombatRemoveCondition(std::shared_ptr condition) override; + void onAttackedCreature(std::shared_ptr target) override; void onAttacked() override; - void onAttackedCreatureDrainHealth(Creature* target, int32_t points) override; - void onTargetCreatureGainHealth(Creature* target, int32_t points) override; - bool onKilledCreature(Creature* target, bool lastHit = true) override; - void onGainExperience(uint64_t gainExp, Creature* target) override; - void onGainSharedExperience(uint64_t gainExp, Creature* target); + void onAttackedCreatureDrainHealth(std::shared_ptr target, int32_t points) override; + void onTargetCreatureGainHealth(std::shared_ptr target, int32_t points) override; + bool onKilledCreature(std::shared_ptr target, bool lastHit = true) override; + void onGainExperience(uint64_t gainExp, std::shared_ptr target) override; + void onGainSharedExperience(uint64_t gainExp, std::shared_ptr target); void onAttackedCreatureBlockHit(BlockType_t blockType) override; void onBlockHit() override; void onChangeZone(ZoneType_t zone) override; @@ -914,7 +910,7 @@ class Player final : public Creature, public Cylinder, public Bankable { LightInfo getCreatureLight() const override; Skulls_t getSkull() const override; - Skulls_t getSkullClient(const Creature* creature) const override; + Skulls_t getSkullClient(std::shared_ptr creature) override; int64_t getSkullTicks() const { return skullTicks; } @@ -922,17 +918,17 @@ class Player final : public Creature, public Cylinder, public Bankable { skullTicks = ticks; } - bool hasAttacked(const Player* attacked) const; - void addAttacked(const Player* attacked); - void removeAttacked(const Player* attacked); + bool hasAttacked(std::shared_ptr attacked) const; + void addAttacked(std::shared_ptr attacked); + void removeAttacked(std::shared_ptr attacked); void clearAttacked(); - void addUnjustifiedDead(const Player* attacked); - void sendCreatureEmblem(const Creature* creature) const { + void addUnjustifiedDead(std::shared_ptr attacked); + void sendCreatureEmblem(std::shared_ptr creature) const { if (client) { client->sendCreatureEmblem(creature); } } - void sendCreatureSkull(const Creature* creature) const { + void sendCreatureSkull(std::shared_ptr creature) const { if (client) { client->sendCreatureSkull(creature); } @@ -955,24 +951,24 @@ class Player final : public Creature, public Cylinder, public Bankable { bool canLogout(); - bool hasKilled(const Player* player) const; + bool hasKilled(std::shared_ptr player) const; size_t getMaxVIPEntries() const; size_t getMaxDepotItems() const; // tile // send methods - void sendAddTileItem(const Tile* itemTile, const Position &pos, const Item* item) { + void sendAddTileItem(std::shared_ptr itemTile, const Position &pos, std::shared_ptr item) { if (client) { - int32_t stackpos = itemTile->getStackposOfItem(this, item); + int32_t stackpos = itemTile->getStackposOfItem(static_self_cast(), item); if (stackpos != -1) { client->sendAddTileItem(pos, stackpos, item); } } } - void sendUpdateTileItem(const Tile* updateTile, const Position &pos, const Item* item) { + void sendUpdateTileItem(std::shared_ptr updateTile, const Position &pos, std::shared_ptr item) { if (client) { - int32_t stackpos = updateTile->getStackposOfItem(this, item); + int32_t stackpos = updateTile->getStackposOfItem(static_self_cast(), item); if (stackpos != -1) { client->sendUpdateTileItem(pos, stackpos, item); } @@ -983,7 +979,7 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendRemoveTileThing(pos, stackpos); } } - void sendUpdateTile(const Tile* updateTile, const Position &pos) { + void sendUpdateTile(std::shared_ptr updateTile, const Position &pos) { if (client) { client->sendUpdateTile(updateTile, pos); } @@ -999,7 +995,7 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendChannelEvent(channelId, playerName, channelEvent); } } - void sendCreatureAppear(const Creature* creature, const Position &pos, bool isLogin) { + void sendCreatureAppear(std::shared_ptr creature, const Position &pos, bool isLogin) { if (!creature) { return; } @@ -1010,15 +1006,15 @@ class Player final : public Creature, public Cylinder, public Bankable { } if (client) { - client->sendAddCreature(creature, pos, tile->getStackposOfCreature(this, creature), isLogin); + client->sendAddCreature(creature, pos, tile->getStackposOfCreature(static_self_cast(), creature), isLogin); } } - void sendCreatureMove(const Creature* creature, const Position &newPos, int32_t newStackPos, const Position &oldPos, int32_t oldStackPos, bool teleport) { + void sendCreatureMove(std::shared_ptr creature, const Position &newPos, int32_t newStackPos, const Position &oldPos, int32_t oldStackPos, bool teleport) { if (client) { client->sendMoveCreature(creature, newPos, newStackPos, oldPos, oldStackPos, teleport); } } - void sendCreatureTurn(const Creature* creature) { + void sendCreatureTurn(std::shared_ptr creature) { if (!creature) { return; } @@ -1029,38 +1025,38 @@ class Player final : public Creature, public Cylinder, public Bankable { } if (client && canSeeCreature(creature)) { - int32_t stackpos = tile->getStackposOfCreature(this, creature); + int32_t stackpos = tile->getStackposOfCreature(static_self_cast(), creature); if (stackpos != -1) { client->sendCreatureTurn(creature, stackpos); } } } - void sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string &text, const Position* pos = nullptr) { + void sendCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text, const Position* pos = nullptr) { if (client) { client->sendCreatureSay(creature, type, text, pos); } } - void sendCreatureReload(const Creature* creature) { + void sendCreatureReload(std::shared_ptr creature) { if (client) { client->reloadCreature(creature); } } - void sendPrivateMessage(const Player* speaker, SpeakClasses type, const std::string &text) { + void sendPrivateMessage(std::shared_ptr speaker, SpeakClasses type, const std::string &text) { if (client) { client->sendPrivateMessage(speaker, type, text); } } - void sendCreatureSquare(const Creature* creature, SquareColor_t color) { + void sendCreatureSquare(std::shared_ptr creature, SquareColor_t color) { if (client) { client->sendCreatureSquare(creature, color); } } - void sendCreatureChangeOutfit(const Creature* creature, const Outfit_t &outfit) { + void sendCreatureChangeOutfit(std::shared_ptr creature, const Outfit_t &outfit) { if (client) { client->sendCreatureOutfit(creature, outfit); } } - void sendCreatureChangeVisible(const Creature* creature, bool visible) { + void sendCreatureChangeVisible(std::shared_ptr creature, bool visible) { if (!client || !creature) { return; } @@ -1079,7 +1075,7 @@ class Player final : public Creature, public Cylinder, public Bankable { if (!tile) { return; } - int32_t stackpos = tile->getStackposOfCreature(this, creature); + int32_t stackpos = tile->getStackposOfCreature(static_self_cast(), creature); if (stackpos == -1) { return; } @@ -1091,32 +1087,32 @@ class Player final : public Creature, public Cylinder, public Bankable { } } } - void sendCreatureLight(const Creature* creature) { + void sendCreatureLight(std::shared_ptr creature) { if (client) { client->sendCreatureLight(creature); } } - void sendCreatureIcon(const Creature* creature) { + void sendCreatureIcon(std::shared_ptr creature) { if (client && !client->oldProtocol) { client->sendCreatureIcon(creature); } } - void sendUpdateCreature(const Creature* creature) const { + void sendUpdateCreature(std::shared_ptr creature) const { if (client) { client->sendUpdateCreature(creature); } } - void sendCreatureWalkthrough(const Creature* creature, bool walkthrough) { + void sendCreatureWalkthrough(std::shared_ptr creature, bool walkthrough) { if (client) { client->sendCreatureWalkthrough(creature, walkthrough); } } - void sendCreatureShield(const Creature* creature) { + void sendCreatureShield(std::shared_ptr creature) { if (client) { client->sendCreatureShield(creature); } } - void sendCreatureType(const Creature* creature, uint8_t creatureType) { + void sendCreatureType(std::shared_ptr creature, uint8_t creatureType) { if (client) { client->sendCreatureType(creature, creatureType); } @@ -1136,7 +1132,7 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendUseItemCooldown(time); } } - void reloadCreature(const Creature* creature) { + void reloadCreature(std::shared_ptr creature) { if (client) { client->reloadCreature(creature); } @@ -1145,10 +1141,10 @@ class Player final : public Creature, public Cylinder, public Bankable { // container void closeAllExternalContainers(); - void sendAddContainerItem(const Container* container, const Item* item); - void sendUpdateContainerItem(const Container* container, uint16_t slot, const Item* newItem); - void sendRemoveContainerItem(const Container* container, uint16_t slot); - void sendContainer(uint8_t cid, const Container* container, bool hasParent, uint16_t firstIndex) { + void sendAddContainerItem(std::shared_ptr container, std::shared_ptr item); + void sendUpdateContainerItem(std::shared_ptr container, uint16_t slot, std::shared_ptr newItem); + void sendRemoveContainerItem(std::shared_ptr container, uint16_t slot); + void sendContainer(uint8_t cid, std::shared_ptr container, bool hasParent, uint16_t firstIndex) { if (client) { client->sendContainer(cid, container, hasParent, firstIndex); } @@ -1175,7 +1171,7 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendCoinBalance(); } } - void sendInventoryItem(Slots_t slot, const Item* item) { + void sendInventoryItem(Slots_t slot, std::shared_ptr item) { if (client) { client->sendInventoryItem(slot, item); } @@ -1211,28 +1207,28 @@ class Player final : public Creature, public Cylinder, public Bankable { SoundEffect_t getHitSoundEffect() const; // event methods - void onUpdateTileItem(const Tile* tile, const Position &pos, const Item* oldItem, const ItemType &oldType, const Item* newItem, const ItemType &newType) override; - void onRemoveTileItem(const Tile* tile, const Position &pos, const ItemType &iType, const Item* item) override; + void onUpdateTileItem(std::shared_ptr tile, const Position &pos, std::shared_ptr oldItem, const ItemType &oldType, std::shared_ptr newItem, const ItemType &newType) override; + void onRemoveTileItem(std::shared_ptr tile, const Position &pos, const ItemType &iType, std::shared_ptr item) override; - void onCreatureAppear(Creature* creature, bool isLogin) override; - void onRemoveCreature(Creature* creature, bool isLogout) override; - void onCreatureMove(Creature* creature, const Tile* newTile, const Position &newPos, const Tile* oldTile, const Position &oldPos, bool teleport) override; + void onCreatureAppear(std::shared_ptr creature, bool isLogin) override; + void onRemoveCreature(std::shared_ptr creature, bool isLogout) override; + void onCreatureMove(std::shared_ptr creature, std::shared_ptr newTile, const Position &newPos, std::shared_ptr oldTile, const Position &oldPos, bool teleport) override; void onAttackedCreatureDisappear(bool isLogout) override; void onFollowCreatureDisappear(bool isLogout) override; // container - void onAddContainerItem(const Item* item); - void onUpdateContainerItem(const Container* container, const Item* oldItem, const Item* newItem); - void onRemoveContainerItem(const Container* container, const Item* item); + void onAddContainerItem(std::shared_ptr item); + void onUpdateContainerItem(std::shared_ptr container, std::shared_ptr oldItem, std::shared_ptr newItem); + void onRemoveContainerItem(std::shared_ptr container, std::shared_ptr item); - void onCloseContainer(const Container* container); - void onSendContainer(const Container* container); - void autoCloseContainers(const Container* container); + void onCloseContainer(std::shared_ptr container); + void onSendContainer(std::shared_ptr container); + void autoCloseContainers(std::shared_ptr container); // inventory - void onUpdateInventoryItem(Item* oldItem, Item* newItem); - void onRemoveInventoryItem(Item* item); + void onUpdateInventoryItem(std::shared_ptr oldItem, std::shared_ptr newItem); + void onRemoveInventoryItem(std::shared_ptr item); void sendCancelMessage(const std::string &msg) const { if (client) { @@ -1250,52 +1246,52 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendCancelWalk(); } } - void sendChangeSpeed(const Creature* creature, uint16_t newSpeed) const { + void sendChangeSpeed(std::shared_ptr creature, uint16_t newSpeed) const { if (client) { client->sendChangeSpeed(creature, newSpeed); } } - void sendCreatureHealth(const Creature* creature) const { + void sendCreatureHealth(std::shared_ptr creature) const { if (client) { client->sendCreatureHealth(creature); } } - void sendPartyCreatureUpdate(const Creature* creature) const { + void sendPartyCreatureUpdate(std::shared_ptr creature) const { if (client) { client->sendPartyCreatureUpdate(creature); } } - void sendPartyCreatureShield(const Creature* creature) const { + void sendPartyCreatureShield(std::shared_ptr creature) const { if (client) { client->sendPartyCreatureShield(creature); } } - void sendPartyCreatureSkull(const Creature* creature) const { + void sendPartyCreatureSkull(std::shared_ptr creature) const { if (client) { client->sendPartyCreatureSkull(creature); } } - void sendPartyCreatureHealth(const Creature* creature, uint8_t healthPercent) const { + void sendPartyCreatureHealth(std::shared_ptr creature, uint8_t healthPercent) const { if (client) { client->sendPartyCreatureHealth(creature, healthPercent); } } - void sendPartyPlayerMana(const Player* player, uint8_t manaPercent) const { + void sendPartyPlayerMana(std::shared_ptr player, uint8_t manaPercent) const { if (client) { client->sendPartyPlayerMana(player, manaPercent); } } - void sendPartyCreatureShowStatus(const Creature* creature, bool showStatus) const { + void sendPartyCreatureShowStatus(std::shared_ptr creature, bool showStatus) const { if (client) { client->sendPartyCreatureShowStatus(creature, showStatus); } } - void sendPartyPlayerVocation(const Player* player) const { + void sendPartyPlayerVocation(std::shared_ptr player) const { if (client) { client->sendPartyPlayerVocation(player); } } - void sendPlayerVocation(const Player* player) const { + void sendPlayerVocation(std::shared_ptr player) const { if (client) { client->sendPlayerVocation(player); } @@ -1305,14 +1301,14 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendDistanceShoot(from, to, type); } } - void sendHouseWindow(House* house, uint32_t listId) const; + void sendHouseWindow(std::shared_ptr house, uint32_t listId) const; void sendCreatePrivateChannel(uint16_t channelId, const std::string &channelName) { if (client) { client->sendCreatePrivateChannel(channelId, channelName); } } void sendClosePrivate(uint16_t channelId); - void sendIcons() const { + void sendIcons() { if (client) { client->sendIcons(getClientIcons()); } @@ -1374,26 +1370,22 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendReLoginWindow(unfairFightReduction); } } - void sendTextWindow(Item* item, uint16_t maxlen, bool canWrite) const { + void sendTextWindow(std::shared_ptr item, uint16_t maxlen, bool canWrite) const { if (client) { client->sendTextWindow(windowTextId, item, maxlen, canWrite); } } - void sendToChannel(const Creature* creature, SpeakClasses type, const std::string &text, uint16_t channelId) const { + void sendToChannel(std::shared_ptr creature, SpeakClasses type, const std::string &text, uint16_t channelId) const { if (client) { client->sendToChannel(creature, type, text, channelId); } } - void sendShop(Npc* npc) const { + void sendShop(std::shared_ptr npc) const { if (client) { client->sendShop(npc); } } - void sendSaleItemList(const std::map &inventoryMap) const { - if (client && shopOwner) { - client->sendSaleItemList(shopOwner->getShopItemVector(), inventoryMap); - } - } + void sendSaleItemList(const std::map &inventoryMap) const; void sendCloseShop() const { if (client) { client->sendCloseShop(); @@ -1436,7 +1428,7 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendMarketCancelOffer(offer); } } - void sendTradeItemRequest(const std::string &traderName, const Item* item, bool ack) const { + void sendTradeItemRequest(const std::string &traderName, std::shared_ptr item, bool ack) const { if (client) { client->sendTradeItemRequest(traderName, item, ack); } @@ -1477,9 +1469,9 @@ class Player final : public Creature, public Cylinder, public Bankable { } } // Imbuements - void onApplyImbuement(Imbuement* imbuement, Item* item, uint8_t slot, bool protectionCharm); - void onClearImbuement(Item* item, uint8_t slot); - void openImbuementWindow(Item* item); + void onApplyImbuement(Imbuement* imbuement, std::shared_ptr item, uint8_t slot, bool protectionCharm); + void onClearImbuement(std::shared_ptr item, uint8_t slot); + void openImbuementWindow(std::shared_ptr item); void sendImbuementResult(const std::string message) { if (client) { client->sendImbuementResult(message); @@ -1490,7 +1482,7 @@ class Player final : public Creature, public Cylinder, public Bankable { client->closeImbuementWindow(); } } - void sendPodiumWindow(const Item* podium, const Position &position, uint16_t itemId, uint8_t stackpos) { + void sendPodiumWindow(std::shared_ptr podium, const Position &position, uint16_t itemId, uint8_t stackpos) { if (client) { client->sendPodiumWindow(podium, position, itemId, stackpos); } @@ -1516,7 +1508,7 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendAddMarker(pos, markType, desc); } } - void sendItemInspection(uint16_t itemId, uint8_t itemCount, const Item* item, bool cyclopedia) { + void sendItemInspection(uint16_t itemId, uint8_t itemCount, std::shared_ptr item, bool cyclopedia) { if (client) { client->sendItemInspection(itemId, itemCount, item, cyclopedia); } @@ -1637,8 +1629,8 @@ class Player final : public Creature, public Cylinder, public Bankable { void onThink(uint32_t interval) override; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; void setNextAction(int64_t time) { if (time > nextAction) { @@ -1674,11 +1666,11 @@ class Player final : public Creature, public Cylinder, public Bankable { uint32_t getNextActionTime() const; uint32_t getNextPotionActionTime() const; - Item* getWriteItem(uint32_t &windowTextId, uint16_t &maxWriteLen); - void setWriteItem(Item* item, uint16_t maxWriteLen = 0); + std::shared_ptr getWriteItem(uint32_t &windowTextId, uint16_t &maxWriteLen); + void setWriteItem(std::shared_ptr item, uint16_t maxWriteLen = 0); - House* getEditHouse(uint32_t &windowTextId, uint32_t &listId); - void setEditHouse(House* house, uint32_t listId = 0); + std::shared_ptr getEditHouse(uint32_t &windowTextId, uint32_t &listId); + void setEditHouse(std::shared_ptr house, uint32_t listId = 0); void learnInstantSpell(const std::string &spellName); void forgetInstantSpell(const std::string &spellName); @@ -1770,7 +1762,7 @@ class Player final : public Creature, public Cylinder, public Bankable { bool isUIExhausted(uint32_t exhaustionTime = 250) const; void updateUIExhausted(); - bool isQuickLootListedItem(const Item* item) const { + bool isQuickLootListedItem(std::shared_ptr item) const { if (!item) { return false; } @@ -1779,7 +1771,7 @@ class Player final : public Creature, public Cylinder, public Bankable { return it != quickLootListItemIds.end(); } - bool updateKillTracker(Container* corpse, const std::string &playerName, const Outfit_t creatureOutfit) const { + bool updateKillTracker(std::shared_ptr corpse, const std::string &playerName, const Outfit_t creatureOutfit) const { if (client) { client->sendKillTrackerUpdate(corpse, playerName, creatureOutfit); return true; @@ -1794,8 +1786,8 @@ class Player final : public Creature, public Cylinder, public Bankable { } } - void sendLootStats(Item* item, uint8_t count) const; - void updateSupplyTracker(const Item* item) const; + void sendLootStats(std::shared_ptr item, uint8_t count); + void updateSupplyTracker(std::shared_ptr item); void updateImpactTracker(CombatType_t type, int32_t amount) const; void updateInputAnalyzer(CombatType_t type, int32_t amount, std::string target) { @@ -2049,7 +2041,7 @@ class Player final : public Creature, public Cylinder, public Bankable { void sendPreyData() const { if (client) { - for (const PreySlot* slot : preys) { + for (const std::unique_ptr &slot : preys) { client->sendPreyData(slot); } @@ -2057,7 +2049,7 @@ class Player final : public Creature, public Cylinder, public Bankable { } } - void sendPreyTimeLeft(const PreySlot* slot) const { + void sendPreyTimeLeft(const std::unique_ptr &slot) const { if (g_configManager().getBoolean(PREY_ENABLED) && client) { client->sendPreyTimeLeft(slot); } @@ -2070,23 +2062,23 @@ class Player final : public Creature, public Cylinder, public Bankable { } } - PreySlot* getPreySlotById(PreySlot_t slotid) { - if (auto it = std::find_if(preys.begin(), preys.end(), [slotid](const PreySlot* preyIt) { + const std::unique_ptr &getPreySlotById(PreySlot_t slotid) { + if (auto it = std::find_if(preys.begin(), preys.end(), [slotid](const std::unique_ptr &preyIt) { return preyIt->id == slotid; }); it != preys.end()) { return *it; } - return nullptr; + return PreySlotNull; } - bool setPreySlotClass(std::unique_ptr slot) { + bool setPreySlotClass(std::unique_ptr &slot) { if (getPreySlotById(slot->id)) { return false; } - preys.emplace_back(slot.release()); + preys.emplace_back(std::move(slot)); return true; } @@ -2119,7 +2111,7 @@ class Player final : public Creature, public Cylinder, public Bankable { std::vector getPreyBlackList() const { std::vector rt; - for (const PreySlot* slot : preys) { + for (const std::unique_ptr &slot : preys) { if (slot) { if (slot->isOccupied()) { rt.push_back(slot->selectedRaceId); @@ -2133,31 +2125,31 @@ class Player final : public Creature, public Cylinder, public Bankable { return rt; } - PreySlot* getPreyWithMonster(uint16_t raceId) const { + const std::unique_ptr &getPreyWithMonster(uint16_t raceId) const { if (!g_configManager().getBoolean(PREY_ENABLED)) { - return nullptr; + return PreySlotNull; } - if (auto it = std::find_if(preys.begin(), preys.end(), [raceId](const PreySlot* it) { + if (auto it = std::find_if(preys.begin(), preys.end(), [raceId](const std::unique_ptr &it) { return it->selectedRaceId == raceId; }); it != preys.end()) { return *it; } - return nullptr; + return PreySlotNull; } // Task hunting system void initializeTaskHunting(); bool isCreatureUnlockedOnTaskHunting(const std::shared_ptr mtype) const; - bool setTaskHuntingSlotClass(std::unique_ptr slot) { + bool setTaskHuntingSlotClass(std::unique_ptr &slot) { if (getTaskHuntingSlotById(slot->id)) { return false; } - taskHunting.emplace_back(slot.release()); + taskHunting.emplace_back(std::move(slot)); return true; } @@ -2168,21 +2160,21 @@ class Player final : public Creature, public Cylinder, public Bankable { } } - TaskHuntingSlot* getTaskHuntingSlotById(PreySlot_t slotid) { - if (auto it = std::find_if(taskHunting.begin(), taskHunting.end(), [slotid](const TaskHuntingSlot* itTask) { + const std::unique_ptr &getTaskHuntingSlotById(PreySlot_t slotid) { + if (auto it = std::find_if(taskHunting.begin(), taskHunting.end(), [slotid](const std::unique_ptr &itTask) { return itTask->id == slotid; }); it != taskHunting.end()) { return *it; } - return nullptr; + return TaskHuntingSlotNull; } std::vector getTaskHuntingBlackList() const { std::vector rt; - std::for_each(taskHunting.begin(), taskHunting.end(), [&rt](const TaskHuntingSlot* slot) { + std::for_each(taskHunting.begin(), taskHunting.end(), [&rt](const std::unique_ptr &slot) { if (slot->isOccupied()) { rt.push_back(slot->selectedRaceId); } else { @@ -2198,7 +2190,7 @@ class Player final : public Creature, public Cylinder, public Bankable { void sendTaskHuntingData() const { if (client) { client->sendResourcesBalance(getMoney(), getBankBalance(), getPreyCards(), getTaskHuntingPoints()); - for (const TaskHuntingSlot* slot : taskHunting) { + for (const std::unique_ptr &slot : taskHunting) { if (slot) { client->sendTaskHuntingData(slot); } @@ -2233,19 +2225,19 @@ class Player final : public Creature, public Cylinder, public Bankable { return getLevel() * g_configManager().getNumber(TASK_HUNTING_REROLL_PRICE_LEVEL); } - TaskHuntingSlot* getTaskHuntingWithCreature(uint16_t raceId) const { + const std::unique_ptr &getTaskHuntingWithCreature(uint16_t raceId) const { if (!g_configManager().getBoolean(TASK_HUNTING_ENABLED)) { - return nullptr; + return TaskHuntingSlotNull; } - if (auto it = std::find_if(taskHunting.begin(), taskHunting.end(), [raceId](const TaskHuntingSlot* itTask) { + if (auto it = std::find_if(taskHunting.begin(), taskHunting.end(), [raceId](const std::unique_ptr &itTask) { return itTask->selectedRaceId == raceId; }); it != taskHunting.end()) { return *it; } - return nullptr; + return TaskHuntingSlotNull; } uint32_t getLoyaltyPoints() const { @@ -2271,9 +2263,9 @@ class Player final : public Creature, public Cylinder, public Bankable { void requestDepotSearchItem(uint16_t itemId, uint8_t tier); void retrieveAllItemsFromDepotSearch(uint16_t itemId, uint8_t tier, bool isDepot); void openContainerFromDepotSearch(const Position &pos); - Item* getItemFromDepotSearch(uint16_t itemId, const Position &pos); + std::shared_ptr getItemFromDepotSearch(uint16_t itemId, const Position &pos); - std::pair, std::map>> requestLockerItems(DepotLocker* depotLocker, bool sendToClient = false, uint8_t tier = 0) const; + std::pair>, std::map>> requestLockerItems(std::shared_ptr depotLocker, bool sendToClient = false, uint8_t tier = 0) const; /** This function returns a pair of an array of items and a 16-bit integer from a DepotLocker instance, a 8-bit byte and a 16-bit integer. @@ -2283,8 +2275,8 @@ class Player final : public Creature, public Cylinder, public Bankable { @return A pair of an array of items and a 16-bit integer, where the array of items is filled with all items from the locker with the specified id and the 16-bit integer is the total items found. */ - std::pair, uint16_t> getLockerItemsAndCountById( - DepotLocker &depotLocker, + std::pair>, uint16_t> getLockerItemsAndCountById( + const std::shared_ptr &depotLocker, uint8_t tier, uint16_t itemId ); @@ -2428,7 +2420,7 @@ class Player final : public Creature, public Cylinder, public Bankable { return bossRemoveTimes; } - void sendMonsterPodiumWindow(const Item* podium, const Position &position, uint16_t itemId, uint8_t stackpos) const { + void sendMonsterPodiumWindow(std::shared_ptr podium, const Position &position, uint16_t itemId, uint8_t stackpos) const { if (client) { client->sendMonsterPodiumWindow(podium, position, itemId, stackpos); } @@ -2440,7 +2432,7 @@ class Player final : public Creature, public Cylinder, public Bankable { } } - void sendInventoryImbuements(const std::map items) const { + void sendInventoryImbuements(const std::map> items) const { if (client) { client->sendInventoryImbuements(items); } @@ -2450,8 +2442,8 @@ class Player final : public Creature, public Cylinder, public Bankable { * Hazard system ******************************************************************************/ // Parser - void parseAttackRecvHazardSystem(CombatDamage &damage, const Monster* monster); - void parseAttackDealtHazardSystem(CombatDamage &damage, const Monster* monster); + void parseAttackRecvHazardSystem(CombatDamage &damage, std::shared_ptr monster); + void parseAttackDealtHazardSystem(CombatDamage &damage, std::shared_ptr monster); // Points increase: void setHazardSystemPoints(int32_t amount); // Points get: @@ -2487,17 +2479,20 @@ class Player final : public Creature, public Cylinder, public Bankable { } // Get specific inventory item from itemid - std::vector getInventoryItemsFromId(uint16_t itemId, bool ignore = true) const; + std::vector> getInventoryItemsFromId(uint16_t itemId, bool ignore = true) const; // This get all player inventory items - std::vector getAllInventoryItems(bool ignoreEquiped = false, bool ignoreItemWithTier = false) const; + std::vector> getAllInventoryItems(bool ignoreEquiped = false, bool ignoreItemWithTier = false) const; + + // This get all players slot items + phmap::flat_hash_map> getAllSlotItems() const; /** - * @brief Get the equipped items of the player. + * @brief Get the equipped items of the player-> * @details This function returns a vector containing the items currently equipped by the player * @return A vector of pointers to the equipped items. */ - std::vector getEquippedItems() const; + std::vector> getEquippedItems() const; // Player wheel methods interface std::unique_ptr &wheel(); @@ -2505,21 +2500,21 @@ class Player final : public Creature, public Cylinder, public Bankable { void sendLootMessage(const std::string &message) const; - Container* getLootPouch() const; + std::shared_ptr getLootPouch(); private: static uint32_t playerFirstID; static uint32_t playerLastID; - std::forward_list getMuteConditions() const; + std::forward_list> getMuteConditions() const; - void checkTradeState(const Item* item); - bool hasCapacity(const Item* item, uint32_t count) const; + void checkTradeState(std::shared_ptr item); + bool hasCapacity(std::shared_ptr item, uint32_t count) const; - void checkLootContainers(const Item* item); + void checkLootContainers(std::shared_ptr item); - void gainExperience(uint64_t exp, Creature* target); - void addExperience(Creature* target, uint64_t exp, bool sendText = false); + void gainExperience(uint64_t exp, std::shared_ptr target); + void addExperience(std::shared_ptr target, uint64_t exp, bool sendText = false); void removeExperience(uint64_t exp, bool sendText = false); void updateInventoryWeight(); @@ -2535,27 +2530,27 @@ class Player final : public Creature, public Cylinder, public Bankable { void setNextActionPushTask(std::shared_ptr task); void setNextPotionActionTask(std::shared_ptr task); - void death(Creature* lastHitCreature) override; + void death(std::shared_ptr lastHitCreature) override; bool spawn(); void despawn(); - bool dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified) override; - Item* getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature) override; + bool dropCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified) override; + std::shared_ptr getCorpse(std::shared_ptr lastHitCreature, std::shared_ptr mostDamageCreature) override; // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - ReturnValue queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const override; - ReturnValue queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - Cylinder* queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + ReturnValue queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) override; + ReturnValue queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + std::shared_ptr queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) override; - void addThing(Thing*) override { } - void addThing(int32_t index, Thing* thing) override; + void addThing(std::shared_ptr) override { } + void addThing(int32_t index, std::shared_ptr thing) override; - void updateThing(Thing* thing, uint16_t itemId, uint32_t count) override; - void replaceThing(uint32_t index, Thing* thing) override; + void updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) override; + void replaceThing(uint32_t index, std::shared_ptr thing) override; - void removeThing(Thing* thing, uint32_t count) override; + void removeThing(std::shared_ptr thing, uint32_t count) override; - int32_t getThingIndex(const Thing* thing) const override; + int32_t getThingIndex(std::shared_ptr 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; @@ -2567,19 +2562,19 @@ class Player final : public Creature, public Cylinder, public Bankable { // Function from player class with correct type sizes (uint16_t) std::map &getAllSaleItemIdAndCount(std::map &countMap) const; void getAllItemTypeCountAndSubtype(std::map &countMap) const; - Item* getForgeItemFromId(uint16_t itemId, uint8_t tier); - Thing* getThing(size_t index) const override; + std::shared_ptr getForgeItemFromId(uint16_t itemId, uint8_t tier); + std::shared_ptr getThing(size_t index) const override; - void internalAddThing(Thing* thing) override; - void internalAddThing(uint32_t index, Thing* thing) override; + void internalAddThing(std::shared_ptr thing) override; + void internalAddThing(uint32_t index, std::shared_ptr thing) override; phmap::flat_hash_set attackedSet; phmap::flat_hash_set VIPList; std::map openContainers; - std::map depotLockerMap; - std::map depotChests; + std::map> depotLockerMap; + std::map> depotChests; std::map moduleDelayMap; std::map storageMap; std::map itemPriceMap; @@ -2590,9 +2585,9 @@ class Player final : public Creature, public Cylinder, public Bankable { { SKILL_CRITICAL_HIT_CHANCE, g_configManager().getNumber(CRITICALCHANCE) } }; - std::map rewardMap; + std::map> rewardMap; - std::map quickLootContainers; + std::map> quickLootContainers; std::vector forgeHistoryVector; std::vector quickLootListItemIds; @@ -2600,16 +2595,16 @@ class Player final : public Creature, public Cylinder, public Bankable { std::vector outfits; std::vector familiars; - std::vector preys; - std::vector taskHunting; + std::vector> preys; + std::vector> taskHunting; GuildWarVector guildWarVector; - std::forward_list invitePartyList; + std::forward_list> invitePartyList; std::forward_list modalWindows; std::forward_list learnedInstantSpellList; // TODO: This variable is only temporarily used when logging in, get rid of it somehow. - std::forward_list storedConditionList; + std::forward_list> storedConditionList; phmap::parallel_flat_hash_set> m_bestiaryMonsterTracker; phmap::parallel_flat_hash_set> m_bosstiaryMonsterTracker; @@ -2654,24 +2649,24 @@ class Player final : public Creature, public Cylinder, public Bankable { std::vector unjustifiedKills; - BedItem* bedItem = nullptr; + std::shared_ptr bedItem = nullptr; std::shared_ptr guild = nullptr; GuildRank_ptr guildRank; Group* group = nullptr; - Inbox* inbox; - Item* imbuingItem = nullptr; - Item* tradeItem = nullptr; - Item* inventory[CONST_SLOT_LAST + 1] = {}; - Item* writeItem = nullptr; - House* editHouse = nullptr; - Npc* shopOwner = nullptr; - Party* party = nullptr; - Player* tradePartner = nullptr; + std::shared_ptr inbox; + std::shared_ptr imbuingItem = nullptr; + std::shared_ptr tradeItem = nullptr; + std::shared_ptr inventory[CONST_SLOT_LAST + 1] = {}; + std::shared_ptr writeItem = nullptr; + std::shared_ptr editHouse = nullptr; + std::shared_ptr shopOwner = nullptr; + std::shared_ptr party = nullptr; + std::shared_ptr tradePartner = nullptr; ProtocolGame_ptr client; std::shared_ptr walkTask; - Town* town = nullptr; + std::shared_ptr town; Vocation* vocation = nullptr; - RewardChest* rewardChest = nullptr; + std::shared_ptr rewardChest = nullptr; uint32_t inventoryWeight = 0; uint32_t capacity = 40000; @@ -2853,7 +2848,7 @@ class Player final : public Creature, public Cylinder, public Bankable { void addConditionSuppression(const std::array &addConditions); uint16_t getLookCorpse() const override; - void getPathSearchParams(const Creature* creature, FindPathParams &fpp) const override; + void getPathSearchParams(std::shared_ptr creature, FindPathParams &fpp) override; void setDead(bool isDead) { dead = isDead; @@ -2890,12 +2885,12 @@ class Player final : public Creature, public Cylinder, public Bankable { bool hasWeaponDistanceEquipped() const; - Item* getQuiverAmmoOfType(const ItemType &it) const; + std::shared_ptr getQuiverAmmoOfType(const ItemType &it) const; std::array getFinalDamageReduction() const; void calculateDamageReductionFromEquipedItems(std::array &combatReductionMap) const; - void calculateDamageReductionFromItem(std::array &combatReductionMap, Item* item) const; - void updateDamageReductionFromItemImbuement(std::array &combatReductionMap, Item* item, uint16_t combatTypeIndex) const; - void updateDamageReductionFromItemAbility(std::array &combatReductionMap, const Item* item, uint16_t combatTypeIndex) const; + void calculateDamageReductionFromItem(std::array &combatReductionMap, std::shared_ptr item) const; + void updateDamageReductionFromItemImbuement(std::array &combatReductionMap, std::shared_ptr item, uint16_t combatTypeIndex) const; + void updateDamageReductionFromItemAbility(std::array &combatReductionMap, std::shared_ptr item, uint16_t combatTypeIndex) const; double_t calculateDamageReduction(double_t currentTotal, int16_t resistance) const; }; diff --git a/src/creatures/players/wheel/player_wheel.cpp b/src/creatures/players/wheel/player_wheel.cpp index 06a25f4d7..6890f7b4e 100644 --- a/src/creatures/players/wheel/player_wheel.cpp +++ b/src/creatures/players/wheel/player_wheel.cpp @@ -883,7 +883,7 @@ bool PlayerWheel::saveDBPlayerSlotPointsOnLogout() const { DBInsert insertWheelData("INSERT INTO `player_wheeldata` (`player_id`, `slot`) VALUES "); insertWheelData.upsert({ "slot" }); PropWriteStream stream; - const auto &wheelSlots = getSlots(); + const auto wheelSlots = getSlots(); for (uint8_t i = 1; i < wheelSlots.size(); ++i) { auto value = wheelSlots[i]; if (value == 0) { @@ -935,7 +935,7 @@ uint16_t PlayerWheel::getWheelPoints(bool includeExtraPoints /* = true*/) const auto totalPoints = std::max(0u, (level - m_minLevelToStartCountPoints)) * m_pointsPerLevel; if (includeExtraPoints) { - const auto &extraPoints = getExtraPoints(); + const auto extraPoints = getExtraPoints(); totalPoints += extraPoints; } @@ -1074,7 +1074,7 @@ void PlayerWheel::reloadPlayerData() { m_player.sendStats(); m_player.sendBasicData(); sendGiftOfLifeCooldown(); - g_game().reloadCreature(&m_player); + g_game().reloadCreature(m_player.getPlayer()); } void PlayerWheel::registerPlayerBonusData() { @@ -1216,7 +1216,7 @@ void PlayerWheel::registerPlayerBonusData() { if (m_player.getHealth() > m_player.getMaxHealth()) { m_player.health = std::min(m_player.getMaxHealth(), m_player.healthMax); - g_game().addCreatureHealth(&m_player); + g_game().addCreatureHealth(m_player.getPlayer()); } if (m_player.getMana() > m_player.getMaxMana()) { @@ -1374,8 +1374,8 @@ void PlayerWheel::printPlayerWheelMethodsBonusData(const PlayerWheelMethodsBonus } void PlayerWheel::loadDedicationAndConvictionPerks() { - using VocationBonusFunction = std::function; - auto &wheelFunctions = g_game().getIOWheel()->getWheelMapFunctions(); + using VocationBonusFunction = std::function &, uint16_t, uint8_t, PlayerWheelMethodsBonusData &)>; + auto wheelFunctions = g_game().getIOWheel()->getWheelMapFunctions(); auto vocationCipId = getPlayerVocationEnum(); if (vocationCipId < VOCATION_KNIGHT_CIP || vocationCipId > VOCATION_DRUID_CIP) { return; @@ -1392,7 +1392,7 @@ void PlayerWheel::loadDedicationAndConvictionPerks() { if (internalData == nullptr) { g_logger().warn("[{}] 'internalData' cannot be null on slot type: {}, for player: {}", __FUNCTION__, i, m_player.getName()); } else { - internalData(m_player, points, vocationCipId, m_playerBonusData); + internalData(m_player.getPlayer(), points, vocationCipId, m_playerBonusData); } } } @@ -1612,13 +1612,13 @@ bool PlayerWheel::checkBattleInstinct() { m_player.getPosition().y + offsetY, m_player.getPosition().z ); - const Tile* tile = g_game().map.getTile(playerPositionOffSet); + std::shared_ptr tile = g_game().map.getTile(playerPositionOffSet); if (!tile) { continue; } - const Creature* creature = tile->getTopVisibleCreature(&m_player); - if (!creature || creature == &m_player || (creature->getMaster() && creature->getMaster()->getPlayer() == &m_player)) { + std::shared_ptr creature = tile->getTopVisibleCreature(m_player.getPlayer()); + if (!creature || creature == m_player.getPlayer() || (creature->getMaster() && creature->getMaster()->getPlayer() == m_player.getPlayer())) { continue; } @@ -1660,13 +1660,13 @@ bool PlayerWheel::checkPositionalTatics() { m_player.getPosition().y + offsetY, m_player.getPosition().z ); - const Tile* tile = g_game().map.getTile(playerPositionOffSet); + std::shared_ptr tile = g_game().map.getTile(playerPositionOffSet); if (!tile) { continue; } - const Creature* creature = tile->getTopVisibleCreature(&m_player); - if (!creature || creature == &m_player || !creature->getMonster() || (creature->getMaster() && creature->getMaster()->getPlayer())) { + std::shared_ptr creature = tile->getTopVisibleCreature(m_player.getPlayer()); + if (!creature || creature == m_player.getPlayer() || !creature->getMonster() || (creature->getMaster() && creature->getMaster()->getPlayer())) { continue; } @@ -1707,7 +1707,7 @@ bool PlayerWheel::checkBallisticMastery() { uint16_t newHolyBonus = 2; // 2% uint16_t newPhysicalBonus = 2; // 2% - const Item* item = m_player.getWeapon(); + std::shared_ptr item = m_player.getWeapon(); if (item && item->getAmmoType() == AMMO_BOLT) { if (getMajorStat(WheelMajor_t::CRITICAL_DMG) != newCritical) { setMajorStat(WheelMajor_t::CRITICAL_DMG, newCritical); @@ -1748,7 +1748,7 @@ bool PlayerWheel::checkCombatMastery() { bool updateClient = false; uint8_t stage = getStage(WheelStage_t::COMBAT_MASTERY); - const Item* item = m_player.getWeapon(); + std::shared_ptr item = m_player.getWeapon(); if (item && item->getSlotPosition() & SLOTP_TWO_HAND) { int32_t criticalSkill = 0; if (stage >= 3) { @@ -1793,9 +1793,26 @@ bool PlayerWheel::checkDivineEmpowerment() { bool updateClient = false; setOnThinkTimer(WheelOnThink_t::DIVINE_EMPOWERMENT, OTSYS_TIME() + 2000); - const Tile* tile = m_player.getTile(); - if (tile && tile->getItemTypeCount(ITEM_DIVINE_EMPOWERMENT) > 0) { - int32_t damageBonus = 0; + const auto tile = m_player.getTile(); + if (!tile) { + return updateClient; + } + + const auto items = tile->getItemList(); + if (!items) { + return updateClient; + } + + int32_t damageBonus = 0; + bool isOwner = false; + for (const auto &item : *items) { + if (item->getID() == ITEM_DIVINE_EMPOWERMENT && item->getAttribute(ItemAttribute_t::OWNER) == m_player.getID()) { + isOwner = true; + break; + } + } + + if (isOwner) { uint8_t stage = getStage(WheelStage_t::DIVINE_EMPOWERMENT); if (stage >= 3) { damageBonus = 12; @@ -1821,7 +1838,7 @@ void PlayerWheel::checkGiftOfLife() { giftDamage.primary.type = COMBAT_HEALING; m_player.sendTextMessage(MESSAGE_EVENT_ADVANCE, "That was close! Fortunately, your were saved by the Gift of Life."); g_game().addMagicEffect(m_player.getPosition(), CONST_ME_WATER_DROP); - g_game().combatChangeHealth(&m_player, &m_player, giftDamage); + g_game().combatChangeHealth(m_player.getPlayer(), m_player.getPlayer(), giftDamage); // Condition cooldown reduction uint16_t reductionTimer = 60000; reduceAllSpellsCooldownTimer(reductionTimer); @@ -1831,8 +1848,8 @@ void PlayerWheel::checkGiftOfLife() { sendGiftOfLifeCooldown(); } -int32_t PlayerWheel::checkBlessingGroveHealingByTarget(const Creature* target) const { - if (!target || target == &m_player) { +int32_t PlayerWheel::checkBlessingGroveHealingByTarget(std::shared_ptr target) const { + if (!target || target == m_player.getPlayer()) { return 0; } @@ -1860,8 +1877,8 @@ int32_t PlayerWheel::checkBlessingGroveHealingByTarget(const Creature* target) c return healingBonus; } -int32_t PlayerWheel::checkTwinBurstByTarget(const Creature* target) const { - if (!target || target == &m_player) { +int32_t PlayerWheel::checkTwinBurstByTarget(std::shared_ptr target) const { + if (!target || target == m_player.getPlayer()) { return 0; } @@ -1881,8 +1898,8 @@ int32_t PlayerWheel::checkTwinBurstByTarget(const Creature* target) const { return damageBonus; } -int32_t PlayerWheel::checkExecutionersThrow(const Creature* target) const { - if (!target || target == &m_player) { +int32_t PlayerWheel::checkExecutionersThrow(std::shared_ptr target) const { + if (!target || target == m_player.getPlayer()) { return 0; } @@ -1916,7 +1933,7 @@ int32_t PlayerWheel::checkBeamMasteryDamage() const { return damageBoost; } -int32_t PlayerWheel::checkDrainBodyLeech(const Creature* target, skills_t skill) const { +int32_t PlayerWheel::checkDrainBodyLeech(std::shared_ptr target, skills_t skill) const { if (!target || !target->getMonster() || target->getWheelOfDestinyDrainBodyDebuff() == 0) { return 0; } @@ -2036,7 +2053,7 @@ void PlayerWheel::onThink(bool force /* = false*/) { } m_player.sendSkills(); m_player.sendStats(); - g_game().reloadCreature(&m_player); + g_game().reloadCreature(m_player.getPlayer()); } return; } @@ -2071,10 +2088,10 @@ void PlayerWheel::onThink(bool force /* = false*/) { } void PlayerWheel::reduceAllSpellsCooldownTimer(int32_t value) { - for (Condition* condition : m_player.getConditionsByType(CONDITION_SPELLCOOLDOWN)) { + for (const auto &condition : m_player.getConditionsByType(CONDITION_SPELLCOOLDOWN)) { if (condition->getTicks() <= value) { m_player.sendSpellCooldown(condition->getSubId(), 0); - condition->endCondition(&m_player); + condition->endCondition(m_player.getPlayer()); } else { condition->setTicks(condition->getTicks() - value); m_player.sendSpellCooldown(condition->getSubId(), condition->getTicks()); @@ -2612,7 +2629,7 @@ void PlayerWheel::healIfBattleHealingActive() const { CombatDamage damage; damage.primary.value = checkBattleHealingAmount(); damage.primary.type = COMBAT_HEALING; - g_game().combatChangeHealth(&m_player, &m_player, damage); + g_game().combatChangeHealth(m_player.getPlayer(), m_player.getPlayer(), damage); } } @@ -2628,8 +2645,8 @@ void PlayerWheel::adjustDamageBasedOnResistanceAndSkill(int32_t &damage, CombatT float PlayerWheel::calculateMitigation() const { int32_t skill = m_player.getSkillLevel(SKILL_SHIELD); int32_t defenseValue = 0; - const Item* weapon = m_player.inventory[CONST_SLOT_LEFT]; - const Item* shield = m_player.inventory[CONST_SLOT_RIGHT]; + std::shared_ptr weapon = m_player.inventory[CONST_SLOT_LEFT]; + std::shared_ptr shield = m_player.inventory[CONST_SLOT_RIGHT]; float fightFactor = 1.0f; float shieldFactor = 1.0f; diff --git a/src/creatures/players/wheel/player_wheel.hpp b/src/creatures/players/wheel/player_wheel.hpp index bf3441839..70e55ff28 100644 --- a/src/creatures/players/wheel/player_wheel.hpp +++ b/src/creatures/players/wheel/player_wheel.hpp @@ -158,12 +158,13 @@ class PlayerWheel { bool checkBallisticMastery(); bool checkCombatMastery(); bool checkDivineEmpowerment(); - int32_t checkDrainBodyLeech(const Creature* target, skills_t skill) const; + int32_t checkDrainBodyLeech(std::shared_ptr target, skills_t skill) const; int32_t checkBeamMasteryDamage() const; int32_t checkBattleHealingAmount() const; - int32_t checkBlessingGroveHealingByTarget(const Creature* target) const; - int32_t checkTwinBurstByTarget(const Creature* target) const; - int32_t checkExecutionersThrow(const Creature* target) const; + int32_t checkBlessingGroveHealingByTarget(std::shared_ptr target) const; + int32_t checkTwinBurstByTarget(std::shared_ptr target) const; + int32_t checkExecutionersThrow(std::shared_ptr target) const; + int32_t checkDivineGrenade(std::shared_ptr target) const; int32_t checkAvatarSkill(WheelAvatarSkill_t skill) const; int32_t checkFocusMasteryDamage(); int32_t checkElementSensitiveReduction(CombatType_t type) const; diff --git a/src/database/database.cpp b/src/database/database.cpp index a2a6969b7..4f6eaf918 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -119,6 +119,8 @@ bool Database::executeQuery(const std::string_view &query) { return false; } + g_logger().trace("Executing Query: {}", query); + std::scoped_lock lock { databaseLock }; bool success = retryQuery(query, 10); @@ -132,6 +134,7 @@ DBResult_ptr Database::storeQuery(const std::string_view &query) { g_logger().error("Database not initialized!"); return nullptr; } + g_logger().trace("Storing Query: {}", query); std::scoped_lock lock { databaseLock }; @@ -312,17 +315,46 @@ bool DBInsert::execute() { return true; } - std::ostringstream query; - query << this->query << " " << values; + std::string baseQuery = this->query; + std::string upsertQuery; if (!upsertColumns.empty()) { - query << " ON DUPLICATE KEY UPDATE "; + std::ostringstream upsertStream; + upsertStream << " ON DUPLICATE KEY UPDATE "; for (size_t i = 0; i < upsertColumns.size(); ++i) { - query << "`" << upsertColumns[i] << "` = VALUES(`" << upsertColumns[i] << "`)"; + upsertStream << "`" << upsertColumns[i] << "` = VALUES(`" << upsertColumns[i] << "`)"; if (i < upsertColumns.size() - 1) { - query << ", "; + upsertStream << ", "; + } + } + upsertQuery = upsertStream.str(); + } + + std::string currentBatch = values; + while (!currentBatch.empty()) { + size_t cutPos = Database::MAX_QUERY_SIZE - baseQuery.size() - upsertQuery.size(); + if (cutPos < currentBatch.size()) { + cutPos = currentBatch.rfind("),(", cutPos); + if (cutPos == std::string::npos) { + return false; } + cutPos += 2; + } else { + cutPos = currentBatch.size(); + } + + std::string batchValues = currentBatch.substr(0, cutPos); + if (batchValues.back() == ',') { + batchValues.pop_back(); + } + currentBatch = currentBatch.substr(cutPos); + + std::ostringstream query; + query << baseQuery << " " << batchValues << upsertQuery; + if (!Database::getInstance().executeQuery(query.str())) { + return false; } } - return Database::getInstance().executeQuery(query.str()); + + return true; } diff --git a/src/database/database.hpp b/src/database/database.hpp index f471a227c..9158ae708 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -17,6 +17,8 @@ using DBResult_ptr = std::shared_ptr; class Database { public: + static const size_t MAX_QUERY_SIZE = 8 * 1024 * 1024; // 8 Mb -- half the default MySQL max_allowed_packet size + Database() = default; ~Database(); diff --git a/src/game/bank/bank.cpp b/src/game/bank/bank.cpp index 3acc788d0..bab052b8a 100644 --- a/src/game/bank/bank.cpp +++ b/src/game/bank/bank.cpp @@ -15,17 +15,18 @@ #include "io/iologindata.hpp" Bank::Bank(const std::shared_ptr bankable) : - bankable(bankable) { + m_bankable(bankable) { } Bank::~Bank() { + auto bankable = getBankable(); if (bankable == nullptr || bankable->isOnline()) { return; } - Player* player = bankable->getPlayer(); + std::shared_ptr player = bankable->getPlayer(); if (player && !player->isOnline()) { IOLoginData::savePlayer(player); - delete player; + return; } if (bankable->isGuild()) { @@ -48,7 +49,8 @@ bool Bank::debit(uint64_t amount) { } bool Bank::balance(uint64_t amount) const { - if (bankable == nullptr) { + auto bankable = getBankable(); + if (!bankable) { return 0; } bankable->setBankBalance(amount); @@ -56,7 +58,8 @@ bool Bank::balance(uint64_t amount) const { } uint64_t Bank::balance() { - if (bankable == nullptr) { + auto bankable = getBankable(); + if (!bankable) { return 0; } return bankable->getBankBalance(); @@ -78,29 +81,38 @@ const std::set deniedNames = { const uint32_t minTownId = 3; bool Bank::transferTo(const std::shared_ptr destination, uint64_t amount) { - if (destination == nullptr) { + if (!destination) { + g_logger().error("Bank::transferTo: destination is nullptr"); + return false; + } + auto bankable = getBankable(); + if (!bankable) { + g_logger().error("Bank::transferTo: bankable is nullptr"); return false; } - if (destination->bankable->getPlayer() != nullptr) { + auto destinationBankable = destination->getBankable(); + if (!destinationBankable) { + g_logger().error("Bank::transferTo: destinationBankable is nullptr"); + return false; + } + if (destinationBankable->getPlayer() != nullptr) { auto player = bankable->getPlayer(); auto name = asLowerCaseString(player->getName()); replaceString(name, " ", ""); if (deniedNames.contains(name)) { + g_logger().warn("Bank::transferTo: denied name: {}", name); return false; } if (player->getTown()->getID() < minTownId) { + g_logger().warn("Bank::transferTo: denied town: {}", player->getTown()->getID()); return false; } } - if (!hasBalance(amount)) { - return false; - } - return debit(amount) && destination->credit(amount); } -bool Bank::withdraw(Player* player, uint64_t amount) { +bool Bank::withdraw(std::shared_ptr player, uint64_t amount) { if (!debit(amount)) { return false; } @@ -109,6 +121,10 @@ bool Bank::withdraw(Player* player, uint64_t amount) { } bool Bank::deposit(const std::shared_ptr destination) { + auto bankable = getBankable(); + if (!bankable) { + return false; + } if (bankable->getPlayer() == nullptr) { return false; } @@ -117,7 +133,11 @@ bool Bank::deposit(const std::shared_ptr destination) { } bool Bank::deposit(const std::shared_ptr destination, uint64_t amount) { - if (destination == nullptr) { + if (!destination) { + return false; + } + auto bankable = getBankable(); + if (!bankable) { return false; } if (!g_game().removeMoney(bankable->getPlayer(), amount)) { diff --git a/src/game/bank/bank.hpp b/src/game/bank/bank.hpp index d4ae9edf1..f4ebbb7be 100644 --- a/src/game/bank/bank.hpp +++ b/src/game/bank/bank.hpp @@ -17,7 +17,7 @@ class Bankable { virtual void setBankBalance(uint64_t amount) = 0; [[nodiscard]] virtual uint64_t getBankBalance() const = 0; virtual ~Bankable() = default; - virtual Player* getPlayer() { + virtual std::shared_ptr getPlayer() { return nullptr; } virtual bool isGuild() { @@ -43,10 +43,13 @@ class Bank : public SharedObject { uint64_t balance(); bool hasBalance(uint64_t amount); bool transferTo(const std::shared_ptr destination, uint64_t amount); - bool withdraw(Player* player, uint64_t amount); + bool withdraw(std::shared_ptr player, uint64_t amount); bool deposit(const std::shared_ptr destination); bool deposit(const std::shared_ptr destination, uint64_t amount); private: - std::shared_ptr bankable; + std::shared_ptr getBankable() const { + return m_bankable; + } + std::shared_ptr m_bankable; }; diff --git a/src/game/game.cpp b/src/game/game.cpp index db498e7d8..6db6a0687 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -49,7 +49,7 @@ #include "kv/kv.hpp" namespace InternalGame { - void sendBlockEffect(BlockType_t blockType, CombatType_t combatType, const Position &targetPos, Creature* source) { + void sendBlockEffect(BlockType_t blockType, CombatType_t combatType, const Position &targetPos, std::shared_ptr source) { if (blockType == BLOCK_DEFENSE) { g_game().addMagicEffect(targetPos, CONST_ME_POFF); } else if (blockType == BLOCK_ARMOR) { @@ -91,7 +91,7 @@ namespace InternalGame { } } - bool playerCanUseItemOnHouseTile(Player* player, Item* item) { + bool playerCanUseItemOnHouseTile(std::shared_ptr player, std::shared_ptr item) { if (!player || !item) { return false; } @@ -101,8 +101,8 @@ namespace InternalGame { return false; } - if (HouseTile* houseTile = dynamic_cast(itemTile)) { - House* house = houseTile->getHouse(); + if (std::shared_ptr houseTile = std::dynamic_pointer_cast(itemTile)) { + const auto &house = houseTile->getHouse(); if (!house || !house->isInvited(player)) { return false; } @@ -124,7 +124,7 @@ namespace InternalGame { return true; } - bool playerCanUseItemWithOnHouseTile(Player* player, Item* item, const Position &toPos, int toStackPos, int toItemId) { + bool playerCanUseItemWithOnHouseTile(std::shared_ptr player, std::shared_ptr item, const Position &toPos, int toStackPos, int toItemId) { if (!player || !item) { return false; } @@ -135,9 +135,9 @@ namespace InternalGame { } if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) { - if (HouseTile* houseTile = dynamic_cast(itemTile)) { - House* house = houseTile->getHouse(); - Thing* targetThing = g_game().internalGetThing(player, toPos, toStackPos, toItemId, STACKPOS_FIND_THING); + if (std::shared_ptr houseTile = std::dynamic_pointer_cast(itemTile)) { + const auto &house = houseTile->getHouse(); + std::shared_ptr targetThing = g_game().internalGetThing(player, toPos, toStackPos, toItemId, STACKPOS_FIND_THING); auto targetItem = targetThing ? targetThing->getItem() : nullptr; uint16_t targetId = targetItem ? targetItem->getID() : 0; auto invitedCheckUseWith = house && item->getRealParent() && item->getRealParent() != player && (!house->isInvited(player) || house->getHouseAccessLevel(player) == HOUSE_GUEST); @@ -152,7 +152,7 @@ namespace InternalGame { } template - T getCustomAttributeValue(const Item* item, const std::string &attributeName) { + T getCustomAttributeValue(std::shared_ptr item, const std::string &attributeName) { static_assert(std::is_integral::value, "T must be an integral type"); auto attribute = item->getCustomAttribute(attributeName); @@ -205,7 +205,7 @@ void Game::resetNpcs() const { void Game::loadBoostedCreature() { auto &db = Database::getInstance(); - const auto &result = db.storeQuery("SELECT * FROM `boosted_creature`"); + const auto result = db.storeQuery("SELECT * FROM `boosted_creature`"); if (!result) { g_logger().warn("[Game::loadBoostedCreature] - " "Failed to detect boosted creature database. (CODE 01)"); @@ -222,7 +222,7 @@ void Game::loadBoostedCreature() { } const uint16_t oldRace = result->getNumber("raceid"); - const auto &monsterlist = getBestiaryList(); + const auto monsterlist = getBestiaryList(); struct MonsterRace { uint16_t raceId { 0 }; @@ -245,14 +245,14 @@ void Game::loadBoostedCreature() { if (selectedMonster.raceId == 0) { g_logger().warn("[Game::loadBoostedCreature] - " - "It was not possible to generate a new boosted creature."); + "It was not possible to generate a new boosted creature->"); return; } const auto monsterType = g_monsters().getMonsterType(selectedMonster.name); if (!monsterType) { g_logger().warn("[Game::loadBoostedCreature] - " - "It was not possible to generate a new boosted creature. Monster '" + "It was not possible to generate a new boosted creature-> Monster '" + selectedMonster.name + "' not found."); return; } @@ -297,6 +297,12 @@ void Game::start(ServiceManager* manager) { g_scheduler().addEvent(EVENT_MS, std::bind_front(&Game::updateForgeableMonsters, this), "Game::updateForgeableMonsters"); g_scheduler().addEvent(EVENT_MS + 1000, std::bind_front(&Game::createFiendishMonsters, this), "Game::createFiendishMonsters"); g_scheduler().addEvent(EVENT_MS + 1000, std::bind_front(&Game::createInfluencedMonsters, this), "Game::createInfluencedMonsters"); + + static const std::function &LUA_GC = [] { + g_scheduler().addEvent(EVENT_LUA_GARBAGE_COLLECTION, LUA_GC, "Calling GC"); + g_luaEnvironment().collectGarbage(); + }; + LUA_GC(); } GameState_t Game::getGameState() const { @@ -460,7 +466,7 @@ void Game::loadCustomMaps(const std::filesystem::path &customMapPath) { int customMapIndex = 0; for (const auto &entry : fs::directory_iterator(customMapPath)) { - const auto &realPath = entry.path(); + const auto realPath = entry.path(); if (realPath.extension() != ".otbm") { continue; @@ -499,7 +505,7 @@ void Game::loadMap(const std::string &path, const Position &pos) { map.loadMap(path, false, false, false, false, pos); } -Cylinder* Game::internalGetCylinder(Player* player, const Position &pos) { +std::shared_ptr Game::internalGetCylinder(std::shared_ptr player, const Position &pos) { if (pos.x != 0xFFFF) { return map.getTile(pos); } @@ -514,21 +520,21 @@ Cylinder* Game::internalGetCylinder(Player* player, const Position &pos) { return player; } -Thing* Game::internalGetThing(Player* player, const Position &pos, int32_t index, uint32_t itemId, StackPosType_t type) { +std::shared_ptr Game::internalGetThing(std::shared_ptr player, const Position &pos, int32_t index, uint32_t itemId, StackPosType_t type) { if (pos.x != 0xFFFF) { - Tile* tile = map.getTile(pos); + std::shared_ptr tile = map.getTile(pos); if (!tile) { return nullptr; } - Thing* thing; + std::shared_ptr thing; switch (type) { case STACKPOS_LOOK: { return tile->getTopVisibleThing(player); } case STACKPOS_MOVE: { - Item* item = tile->getTopDownItem(); + std::shared_ptr item = tile->getTopDownItem(); if (item && item->isMoveable()) { thing = item; } else { @@ -595,13 +601,13 @@ Thing* Game::internalGetThing(Player* player, const Position &pos, int32_t index if (pos.y & 0x40) { uint8_t fromCid = pos.y & 0x0F; - Container* parentContainer = player->getContainerByID(fromCid); + std::shared_ptr parentContainer = player->getContainerByID(fromCid); if (!parentContainer) { return nullptr; } if (parentContainer->getID() == ITEM_BROWSEFIELD) { - Tile* tile = parentContainer->getTile(); + std::shared_ptr tile = parentContainer->getTile(); if (tile && tile->hasFlag(TILESTATE_SUPPORTS_HANGABLE)) { if (tile->hasProperty(CONST_PROP_ISVERTICAL)) { if (player->getPosition().x + 1 == tile->getPosition().x) { @@ -653,18 +659,18 @@ Thing* Game::internalGetThing(Player* player, const Position &pos, int32_t index return player->getInventoryItem(slot); } -void Game::internalGetPosition(Item* item, Position &pos, uint8_t &stackpos) { +void Game::internalGetPosition(std::shared_ptr item, Position &pos, uint8_t &stackpos) { pos.x = 0; pos.y = 0; pos.z = 0; stackpos = 0; - Cylinder* topParent = item->getTopParent(); + std::shared_ptr topParent = item->getTopParent(); if (topParent) { - if (Player* player = dynamic_cast(topParent)) { + if (std::shared_ptr player = std::dynamic_pointer_cast(topParent)) { pos.x = 0xFFFF; - Container* container = dynamic_cast(item->getParent()); + std::shared_ptr container = std::dynamic_pointer_cast(item->getParent()); if (container) { pos.y = static_cast(0x40) | static_cast(player->getContainerID(container)); pos.z = container->getThingIndex(item); @@ -673,14 +679,14 @@ void Game::internalGetPosition(Item* item, Position &pos, uint8_t &stackpos) { pos.y = player->getThingIndex(item); stackpos = pos.y; } - } else if (Tile* tile = topParent->getTile()) { + } else if (std::shared_ptr tile = topParent->getTile()) { pos = tile->getPosition(); stackpos = tile->getThingIndex(item); } } } -Creature* Game::getCreatureByID(uint32_t id) { +std::shared_ptr Game::getCreatureByID(uint32_t id) { if (id >= Player::getFirstID() && id <= Player::getLastID()) { return getPlayerByID(id); } else if (id <= Monster::monsterAutoID) { @@ -693,7 +699,7 @@ Creature* Game::getCreatureByID(uint32_t id) { return nullptr; } -Monster* Game::getMonsterByID(uint32_t id) { +std::shared_ptr Game::getMonsterByID(uint32_t id) { if (id == 0) { return nullptr; } @@ -705,7 +711,7 @@ Monster* Game::getMonsterByID(uint32_t id) { return it->second; } -Npc* Game::getNpcByID(uint32_t id) { +std::shared_ptr Game::getNpcByID(uint32_t id) { if (id == 0) { return nullptr; } @@ -717,7 +723,7 @@ Npc* Game::getNpcByID(uint32_t id) { return it->second; } -Player* Game::getPlayerByID(uint32_t id, bool loadTmp /* = false */) { +std::shared_ptr Game::getPlayerByID(uint32_t id, bool loadTmp /* = false */) { auto playerMap = players.find(id); if (playerMap != players.end()) { return playerMap->second; @@ -726,14 +732,14 @@ Player* Game::getPlayerByID(uint32_t id, bool loadTmp /* = false */) { if (!loadTmp) { return nullptr; } - Player* tmpPlayer(nullptr); + std::shared_ptr tmpPlayer(nullptr); if (!IOLoginData::loadPlayerById(tmpPlayer, id)) { return nullptr; } return tmpPlayer; } -Creature* Game::getCreatureByName(const std::string &s) { +std::shared_ptr Game::getCreatureByName(const std::string &s) { if (s.empty()) { return nullptr; } @@ -742,7 +748,7 @@ Creature* Game::getCreatureByName(const std::string &s) { auto m_it = mappedPlayerNames.find(lowerCaseName); if (m_it != mappedPlayerNames.end()) { - return m_it->second; + return m_it->second.lock(); } for (const auto &it : npcs) { @@ -759,7 +765,7 @@ Creature* Game::getCreatureByName(const std::string &s) { return nullptr; } -Npc* Game::getNpcByName(const std::string &s) { +std::shared_ptr Game::getNpcByName(const std::string &s) { if (s.empty()) { return nullptr; } @@ -773,28 +779,28 @@ Npc* Game::getNpcByName(const std::string &s) { return nullptr; } -Player* Game::getPlayerByName(const std::string &s, bool loadTmp /* = false */) { +std::shared_ptr Game::getPlayerByName(const std::string &s, bool loadTmp /* = false */) { if (s.empty()) { return nullptr; } auto it = mappedPlayerNames.find(asLowerCaseString(s)); - if (it == mappedPlayerNames.end()) { + if (it == mappedPlayerNames.end() || it->second.expired()) { if (!loadTmp) { return nullptr; } - Player* tmpPlayer = new Player(nullptr); + std::shared_ptr tmpPlayer = std::make_shared(nullptr); if (!IOLoginData::loadPlayerByName(tmpPlayer, s)) { - delete tmpPlayer; + g_logger().error("Failed to load player {} from database", s); return nullptr; } tmpPlayer->setOnline(false); return tmpPlayer; } - return it->second; + return it->second.lock(); } -Player* Game::getPlayerByGUID(const uint32_t &guid) { +std::shared_ptr Game::getPlayerByGUID(const uint32_t &guid) { if (guid == 0) { return nullptr; } @@ -806,7 +812,7 @@ Player* Game::getPlayerByGUID(const uint32_t &guid) { return nullptr; } -ReturnValue Game::getPlayerByNameWildcard(const std::string &s, Player*&player) { +ReturnValue Game::getPlayerByNameWildcard(const std::string &s, std::shared_ptr &player) { size_t strlen = s.length(); if (strlen == 0 || strlen > 20) { return RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE; @@ -832,7 +838,7 @@ ReturnValue Game::getPlayerByNameWildcard(const std::string &s, Player*&player) return RETURNVALUE_NOERROR; } -Player* Game::getPlayerByAccount(uint32_t acc) { +std::shared_ptr Game::getPlayerByAccount(uint32_t acc) { for (const auto &it : players) { if (it.second->getAccountId() == acc) { return it.second; @@ -841,7 +847,7 @@ Player* Game::getPlayerByAccount(uint32_t acc) { return nullptr; } -bool Game::internalPlaceCreature(Creature* creature, const Position &pos, bool extendedPos /*=false*/, bool forced /*= false*/, bool creatureCheck /*= false*/) { +bool Game::internalPlaceCreature(std::shared_ptr creature, const Position &pos, bool extendedPos /*=false*/, bool forced /*= false*/, bool creatureCheck /*= false*/) { if (creature->getParent() != nullptr) { return false; } @@ -854,7 +860,6 @@ bool Game::internalPlaceCreature(Creature* creature, const Position &pos, bool e return false; } - creature->incrementReferenceCounter(); creature->setID(); creature->addList(); @@ -866,7 +871,7 @@ bool Game::internalPlaceCreature(Creature* creature, const Position &pos, bool e return true; } -bool Game::placeCreature(Creature* creature, const Position &pos, bool extendedPos /*=false*/, bool forced /*= false*/) { +bool Game::placeCreature(std::shared_ptr creature, const Position &pos, bool extendedPos /*=false*/, bool forced /*= false*/) { if (!internalPlaceCreature(creature, pos, extendedPos, forced)) { return false; } @@ -874,8 +879,8 @@ bool Game::placeCreature(Creature* creature, const Position &pos, bool extendedP bool hasPlayerSpectators = false; SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true); - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (std::shared_ptr spectator : spectators) { + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendCreatureAppear(creature, creature->getPosition(), true); hasPlayerSpectators = true; } @@ -891,19 +896,19 @@ bool Game::placeCreature(Creature* creature, const Position &pos, bool extendedP return true; } -bool Game::removeCreature(Creature* creature, bool isLogout /* = true*/) { +bool Game::removeCreature(std::shared_ptr creature, bool isLogout /* = true*/) { if (creature->isRemoved()) { return false; } - Tile* tile = creature->getTile(); + std::shared_ptr tile = creature->getTile(); std::vector oldStackPosVector; SpectatorHashSet spectators; map.getSpectators(spectators, tile->getPosition(), true); - for (Creature* spectator : spectators) { - if (Player* player = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto player = spectator->getPlayer()) { oldStackPosVector.push_back(player->canSeeCreature(creature) ? tile->getStackposOfCreature(player, creature) : -1); } } @@ -912,16 +917,16 @@ bool Game::removeCreature(Creature* creature, bool isLogout /* = true*/) { const Position &tilePosition = tile->getPosition(); - // send to client + // Send to client size_t i = 0; - for (Creature* spectator : spectators) { - if (Player* player = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto player = spectator->getPlayer()) { player->sendRemoveTileThing(tilePosition, oldStackPosVector[i++]); } } // event method - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { spectator->onRemoveCreature(creature, isLogout); } @@ -934,11 +939,10 @@ bool Game::removeCreature(Creature* creature, bool isLogout /* = true*/) { creature->removeList(); creature->setRemoved(); - ReleaseCreature(creature); removeCreatureCheck(creature); - for (Creature* summon : creature->summons) { + for (const auto &summon : creature->m_summons) { summon->setSkillLoss(false); removeCreature(summon); } @@ -954,7 +958,7 @@ bool Game::removeCreature(Creature* creature, bool isLogout /* = true*/) { } void Game::executeDeath(uint32_t creatureId) { - Creature* creature = getCreatureByID(creatureId); + std::shared_ptr creature = getCreatureByID(creatureId); if (creature && !creature->isRemoved()) { creature->onDeath(); afterCreatureZoneChange(creature, creature->getZones(), {}); @@ -962,7 +966,7 @@ void Game::executeDeath(uint32_t creatureId) { } void Game::playerTeleport(uint32_t playerId, const Position &newPosition) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->hasFlag(PlayerFlags_t::CanMapClickTeleport)) { return; } @@ -973,14 +977,14 @@ void Game::playerTeleport(uint32_t playerId, const Position &newPosition) { } } -void Game::playerInspectItem(Player* player, const Position &pos) { - Thing* thing = internalGetThing(player, pos, 0, 0, STACKPOS_TOPDOWN_ITEM); +void Game::playerInspectItem(std::shared_ptr player, const Position &pos) { + std::shared_ptr thing = internalGetThing(player, pos, 0, 0, STACKPOS_TOPDOWN_ITEM); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -989,7 +993,7 @@ void Game::playerInspectItem(Player* player, const Position &pos) { player->sendItemInspection(item->getID(), static_cast(item->getItemCount()), item, false); } -void Game::playerInspectItem(Player* player, uint16_t itemId, uint8_t itemCount, bool cyclopedia) { +void Game::playerInspectItem(std::shared_ptr player, uint16_t itemId, uint8_t itemCount, bool cyclopedia) { player->sendItemInspection(itemId, itemCount, nullptr, cyclopedia); } @@ -1043,7 +1047,7 @@ FILELOADER_ERRORS Game::loadAppearanceProtobuf(const std::string &file) { } void Game::playerMoveThing(uint32_t playerId, const Position &fromPos, uint16_t itemId, uint8_t fromStackPos, const Position &toPos, uint8_t count) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -1070,14 +1074,14 @@ void Game::playerMoveThing(uint32_t playerId, const Position &fromPos, uint16_t fromIndex = fromStackPos; } - Thing* thing = internalGetThing(player, fromPos, fromIndex, itemId, STACKPOS_MOVE); + std::shared_ptr thing = internalGetThing(player, fromPos, fromIndex, itemId, STACKPOS_MOVE); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - if (Creature* movingCreature = thing->getCreature()) { - Tile* tile = map.getTile(toPos); + if (std::shared_ptr movingCreature = thing->getCreature()) { + std::shared_ptr tile = map.getTile(toPos); if (!tile) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -1094,7 +1098,7 @@ void Game::playerMoveThing(uint32_t playerId, const Position &fromPos, uint16_t playerMoveCreature(player, movingCreature, movingCreature->getPosition(), tile); } } else if (thing->getItem()) { - Cylinder* toCylinder = internalGetCylinder(player, toPos); + std::shared_ptr toCylinder = internalGetCylinder(player, toPos); if (!toCylinder) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -1105,17 +1109,17 @@ void Game::playerMoveThing(uint32_t playerId, const Position &fromPos, uint16_t } void Game::playerMoveCreatureByID(uint32_t playerId, uint32_t movingCreatureId, const Position &movingCreatureOrigPos, const Position &toPos) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Creature* movingCreature = getCreatureByID(movingCreatureId); + std::shared_ptr movingCreature = getCreatureByID(movingCreatureId); if (!movingCreature) { return; } - Tile* toTile = map.getTile(toPos); + std::shared_ptr toTile = map.getTile(toPos); if (!toTile) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -1124,7 +1128,7 @@ void Game::playerMoveCreatureByID(uint32_t playerId, uint32_t movingCreatureId, playerMoveCreature(player, movingCreature, movingCreatureOrigPos, toTile); } -void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Position &movingCreatureOrigPos, Tile* toTile) { +void Game::playerMoveCreature(std::shared_ptr player, std::shared_ptr movingCreature, const Position &movingCreatureOrigPos, std::shared_ptr toTile) { if (!player->canDoAction()) { uint32_t delay = 600; std::shared_ptr task = createPlayerTask(delay, std::bind(&Game::playerMoveCreatureByID, this, player->getID(), movingCreature->getID(), movingCreatureOrigPos, toTile->getPosition()), "Game::playerMoveCreatureByID"); @@ -1152,7 +1156,7 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po } player->pushEvent(false); - const Monster* monster = movingCreature->getMonster(); + std::shared_ptr monster = movingCreature->getMonster(); bool isFamiliar = false; if (monster) { isFamiliar = monster->isFamiliar(); @@ -1180,7 +1184,7 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po return; } else { if (CreatureVector* tileCreatures = toTile->getCreatures()) { - for (Creature* tileCreature : *tileCreatures) { + for (auto &tileCreature : *tileCreatures) { if (!tileCreature->isInGhostMode()) { player->sendCancelMessage(RETURNVALUE_NOTENOUGHROOM); return; @@ -1188,7 +1192,7 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po } } - Npc* movingNpc = movingCreature->getNpc(); + auto movingNpc = movingCreature->getNpc(); if (movingNpc && movingNpc->canInteract(toPos)) { player->sendCancelMessage(RETURNVALUE_NOTENOUGHROOM); return; @@ -1206,14 +1210,14 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po return; } - ReturnValue ret = internalMoveCreature(*movingCreature, *toTile); + ReturnValue ret = internalMoveCreature(movingCreature, toTile); if (ret != RETURNVALUE_NOERROR) { player->sendCancelMessage(ret); } player->setLastPosition(player->getPosition()); } -ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags /*= 0*/) { +ReturnValue Game::internalMoveCreature(std::shared_ptr creature, Direction direction, uint32_t flags /*= 0*/) { if (!creature) { return RETURNVALUE_NOTPOSSIBLE; } @@ -1221,14 +1225,14 @@ ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, creature->setLastPosition(creature->getPosition()); const Position ¤tPos = creature->getPosition(); Position destPos = getNextPosition(direction, currentPos); - Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); bool diagonalMovement = (direction & DIRECTION_DIAGONAL_MASK) != 0; if (player && !diagonalMovement) { // try go up auto tile = creature->getTile(); if (currentPos.z != 8 && tile && tile->hasHeight(3)) { - Tile* tmpTile = map.getTile(currentPos.x, currentPos.y, currentPos.getZ() - 1); + std::shared_ptr tmpTile = map.getTile(currentPos.x, currentPos.y, currentPos.getZ() - 1); if (tmpTile == nullptr || (tmpTile->getGround() == nullptr && !tmpTile->hasFlag(TILESTATE_BLOCKSOLID))) { tmpTile = map.getTile(destPos.x, destPos.y, destPos.getZ() - 1); if (tmpTile && tmpTile->getGround() && !tmpTile->hasFlag(TILESTATE_BLOCKSOLID)) { @@ -1244,7 +1248,7 @@ ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, // try go down if (currentPos.z != 7 && currentPos.z == destPos.z) { - Tile* tmpTile = map.getTile(destPos.x, destPos.y, destPos.z); + std::shared_ptr tmpTile = map.getTile(destPos.x, destPos.y, destPos.z); if (tmpTile == nullptr || (tmpTile->getGround() == nullptr && !tmpTile->hasFlag(TILESTATE_BLOCKSOLID))) { tmpTile = map.getTile(destPos.x, destPos.y, destPos.z + 1); if (tmpTile && tmpTile->hasHeight(3)) { @@ -1256,51 +1260,51 @@ ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, } } - Tile* toTile = map.getTile(destPos); + std::shared_ptr toTile = map.getTile(destPos); if (!toTile) { return RETURNVALUE_NOTPOSSIBLE; } - return internalMoveCreature(*creature, *toTile, flags); + return internalMoveCreature(creature, toTile, flags); } -ReturnValue Game::internalMoveCreature(Creature &creature, Tile &toTile, uint32_t flags /*= 0*/) { - if (creature.hasCondition(CONDITION_ROOTED)) { +ReturnValue Game::internalMoveCreature(const std::shared_ptr &creature, const std::shared_ptr &toTile, uint32_t flags /*= 0*/) { + if (creature->hasCondition(CONDITION_ROOTED)) { return RETURNVALUE_NOTPOSSIBLE; } // check if we can move the creature to the destination - ReturnValue ret = toTile.queryAdd(0, creature, 1, flags); + ReturnValue ret = toTile->queryAdd(0, creature, 1, flags); if (ret != RETURNVALUE_NOERROR) { return ret; } - if (creature.hasCondition(CONDITION_ROOTED)) { + if (creature->hasCondition(CONDITION_ROOTED)) { return RETURNVALUE_NOTPOSSIBLE; } - if (creature.hasCondition(CONDITION_FEARED)) { - const MagicField* field = toTile.getFieldItem(); + if (creature->hasCondition(CONDITION_FEARED)) { + std::shared_ptr field = toTile->getFieldItem(); if (field && !field->isBlocking() && field->getDamage() != 0) { return RETURNVALUE_NOTPOSSIBLE; } } map.moveCreature(creature, toTile); - if (creature.getParent() != &toTile) { + if (creature->getParent() != toTile) { return RETURNVALUE_NOERROR; } int32_t index = 0; - Item* toItem = nullptr; - Tile* subCylinder = nullptr; - Tile* toCylinder = &toTile; - Tile* fromCylinder = nullptr; + std::shared_ptr toItem = nullptr; + std::shared_ptr subCylinder = nullptr; + std::shared_ptr toCylinder = toTile; + std::shared_ptr fromCylinder = nullptr; uint32_t n = 0; - while ((subCylinder = toCylinder->queryDestination(index, creature, &toItem, flags)) != toCylinder) { - map.moveCreature(creature, *subCylinder); + while ((subCylinder = toCylinder->queryDestination(index, creature, &toItem, flags)->getTile()) != toCylinder) { + map.moveCreature(creature, subCylinder); - if (creature.getParent() != subCylinder) { + if (creature->getParent() != subCylinder) { // could happen if a script move the creature fromCylinder = nullptr; break; @@ -1322,7 +1326,7 @@ ReturnValue Game::internalMoveCreature(Creature &creature, Tile &toTile, uint32_ if (fromPosition.z != toPosition.z && (fromPosition.x != toPosition.x || fromPosition.y != toPosition.y)) { Direction dir = getDirectionTo(fromPosition, toPosition); if ((dir & DIRECTION_DIAGONAL_MASK) == 0) { - internalCreatureTurn(&creature, dir); + internalCreatureTurn(creature, dir); } } } @@ -1331,14 +1335,14 @@ ReturnValue Game::internalMoveCreature(Creature &creature, Tile &toTile, uint32_ } void Game::playerMoveItemByPlayerID(uint32_t playerId, const Position &fromPos, uint16_t itemId, uint8_t fromStackPos, const Position &toPos, uint8_t count) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } playerMoveItem(player, fromPos, itemId, fromStackPos, toPos, count, nullptr, nullptr); } -void Game::playerMoveItem(Player* player, const Position &fromPos, uint16_t itemId, uint8_t fromStackPos, const Position &toPos, uint8_t count, Item* item, Cylinder* toCylinder) { +void Game::playerMoveItem(std::shared_ptr player, const Position &fromPos, uint16_t itemId, uint8_t fromStackPos, const Position &toPos, uint8_t count, std::shared_ptr item, std::shared_ptr toCylinder) { if (!player->canDoAction()) { uint32_t delay = player->getNextActionTime(); std::shared_ptr task = createPlayerTask(delay, std::bind(&Game::playerMoveItemByPlayerID, this, player->getID(), fromPos, itemId, fromStackPos, toPos, count), "Game::playerMoveItemByPlayerID"); @@ -1366,7 +1370,7 @@ void Game::playerMoveItem(Player* player, const Position &fromPos, uint16_t item fromIndex = fromStackPos; } - Thing* thing = internalGetThing(player, fromPos, fromIndex, itemId, STACKPOS_MOVE); + std::shared_ptr thing = internalGetThing(player, fromPos, fromIndex, itemId, STACKPOS_MOVE); if (!thing || !thing->getItem()) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -1380,7 +1384,7 @@ void Game::playerMoveItem(Player* player, const Position &fromPos, uint16_t item return; } - Cylinder* fromCylinder = nullptr; + std::shared_ptr fromCylinder = nullptr; if (fromPos.x == 0xFFFF && (fromPos.y == 0x20 || fromPos.y == 0x21)) { // '0x20' -> From depot. // '0x21' -> From inbox. @@ -1446,7 +1450,7 @@ void Game::playerMoveItem(Player* player, const Position &fromPos, uint16_t item return; } - const Tile* toCylinderTile = toCylinder->getTile(); + std::shared_ptr toCylinderTile = toCylinder->getTile(); const Position &mapToPos = toCylinderTile->getPosition(); // hangable item specific code @@ -1479,7 +1483,7 @@ void Game::playerMoveItem(Player* player, const Position &fromPos, uint16_t item if (fromPos.x != 0xFFFF && Position::areInRange<1, 1>(mapFromPos, playerPos) && !Position::areInRange<1, 1, 0>(mapFromPos, walkPos)) { // need to pickup the item first - Item* moveItem = nullptr; + std::shared_ptr moveItem = nullptr; ReturnValue ret = internalMoveItem(fromCylinder, player, INDEX_WHEREEVER, item, count, &moveItem); if (ret != RETURNVALUE_NOERROR) { @@ -1532,8 +1536,8 @@ void Game::playerMoveItem(Player* player, const Position &fromPos, uint16_t item } if (item->isWrapable()) { - HouseTile* toHouseTile = dynamic_cast(map.getTile(mapToPos)); - HouseTile* fromHouseTile = dynamic_cast(map.getTile(mapFromPos)); + auto toHouseTile = map.getTile(mapToPos)->dynamic_self_cast(); + auto fromHouseTile = map.getTile(mapFromPos)->dynamic_self_cast(); if (fromHouseTile && (!toHouseTile || toHouseTile->getHouse()->getId() != fromHouseTile->getHouse()->getId())) { player->sendCancelMessage("You can't move this item outside a house."); return; @@ -1554,22 +1558,21 @@ void Game::playerMoveItem(Player* player, const Position &fromPos, uint16_t item g_callbacks().executeCallback(EventCallback_t::playerOnItemMoved, &EventCallback::playerOnItemMoved, player, item, count, fromPos, toPos, fromCylinder, toCylinder); } -bool Game::isTryingToStow(const Position &toPos, Cylinder* toCylinder) const { +bool Game::isTryingToStow(const Position &toPos, std::shared_ptr toCylinder) const { return toCylinder->getContainer() && toCylinder->getItem()->getID() == ITEM_LOCKER && toPos.getZ() == ITEM_SUPPLY_STASH_INDEX; } -ReturnValue Game::checkMoveItemToCylinder(Player* player, Cylinder* fromCylinder, Cylinder* toCylinder, Item* item, Position toPos) { +ReturnValue Game::checkMoveItemToCylinder(std::shared_ptr player, std::shared_ptr fromCylinder, std::shared_ptr toCylinder, std::shared_ptr item, Position toPos) { if (!player || !toCylinder || !item) { return RETURNVALUE_NOTPOSSIBLE; } - if (Container* toCylinderContainer = toCylinder->getContainer()) { + if (std::shared_ptr toCylinderContainer = toCylinder->getContainer()) { auto containerID = toCylinderContainer->getID(); // check the store inbox index if gold pouch forces it as containerID if (containerID == ITEM_STORE_INBOX) { - Item* cylinderItem = toCylinderContainer->getItemByIndex(toPos.getZ()); - + auto cylinderItem = toCylinderContainer->getItemByIndex(toPos.getZ()); if (cylinderItem && cylinderItem->getID() == ITEM_GOLD_POUCH) { containerID = ITEM_GOLD_POUCH; } @@ -1594,7 +1597,7 @@ ReturnValue Game::checkMoveItemToCylinder(Player* player, Cylinder* fromCylinder return RETURNVALUE_NOERROR; } - const Container* topParentContainer = toCylinderContainer->getRootContainer(); + std::shared_ptr topParentContainer = toCylinderContainer->getRootContainer(); const auto parentContainer = topParentContainer->getParent() ? topParentContainer->getParent()->getContainer() : nullptr; auto isStoreInbox = parentContainer && parentContainer->isStoreInbox(); if (!item->isStoreItem() && (containerID == ITEM_STORE_INBOX || isStoreInbox)) { @@ -1603,7 +1606,9 @@ ReturnValue Game::checkMoveItemToCylinder(Player* player, Cylinder* fromCylinder if (item->isStoreItem()) { bool isValidMoveItem = false; - if (HouseTile* fromHouseTile = dynamic_cast(fromCylinder->getTile()); fromHouseTile && fromHouseTile->getHouse()->getOwner() != player->getGUID()) { + auto fromHouseTile = fromCylinder->getTile(); + auto house = fromHouseTile ? fromHouseTile->getHouse() : nullptr; + if (house && house->getHouseAccessLevel(player) < HOUSE_OWNER) { return RETURNVALUE_NOTPOSSIBLE; } @@ -1621,40 +1626,41 @@ ReturnValue Game::checkMoveItemToCylinder(Player* player, Cylinder* fromCylinder } if (item->getContainer() && !item->isStoreItem()) { - for (Item* containerItem : item->getContainer()->getItems(true)) { + for (std::shared_ptr containerItem : item->getContainer()->getItems(true)) { if (containerItem->isStoreItem() && ((containerID != ITEM_GOLD_POUCH && containerID != ITEM_DEPOT && containerID != ITEM_STORE_INBOX) || (topParentContainer->getParent() && topParentContainer->getParent()->getContainer() && (!topParentContainer->getParent()->getContainer()->isDepotChest() || topParentContainer->getParent()->getContainer()->getID() != ITEM_STORE_INBOX)))) { return RETURNVALUE_NOTPOSSIBLE; } } } } else if (toCylinder->getTile()) { - HouseTile* toHouseTile = dynamic_cast(toCylinder->getTile()); + const auto toHouseTile = toCylinder->getTile(); + auto house = toHouseTile ? toHouseTile->getHouse() : nullptr; if (fromCylinder->getContainer()) { if (item->isStoreItem()) { - if (!toHouseTile || toHouseTile && toHouseTile->getHouse()->getOwner() != player->getGUID()) { + if (house && house->getHouseAccessLevel(player) < HOUSE_OWNER) { return RETURNVALUE_NOTPOSSIBLE; } } if (item->getContainer() && !item->isStoreItem()) { - for (Item* containerItem : item->getContainer()->getItems(true)) { + for (std::shared_ptr containerItem : item->getContainer()->getItems(true)) { if (containerItem->isStoreItem()) { return RETURNVALUE_NOTPOSSIBLE; } } } - return RETURNVALUE_NOERROR; - } + if (item->isStoreItem() && !toHouseTile) { + return RETURNVALUE_NOTPOSSIBLE; + } - if (item->isStoreItem() && !toHouseTile) { - return RETURNVALUE_NOTPOSSIBLE; + return RETURNVALUE_NOERROR; } } return RETURNVALUE_NOERROR; } -ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, int32_t index, Item* item, uint32_t count, Item** movedItem, uint32_t flags /*= 0*/, Creature* actor /*=nullptr*/, Item* tradeItem /* = nullptr*/, bool checkTile /* = true*/) { +ReturnValue Game::internalMoveItem(std::shared_ptr fromCylinder, std::shared_ptr toCylinder, int32_t index, std::shared_ptr item, uint32_t count, std::shared_ptr* movedItem, uint32_t flags /*= 0*/, std::shared_ptr actor /*=nullptr*/, std::shared_ptr tradeItem /* = nullptr*/, bool checkTile /* = true*/) { if (fromCylinder == nullptr) { g_logger().error("[{}] fromCylinder is nullptr", __FUNCTION__); return RETURNVALUE_NOTPOSSIBLE; @@ -1665,20 +1671,19 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, } if (checkTile) { - if (Tile* fromTile = fromCylinder->getTile()) { - auto it = browseFields.find(fromTile); - if (it != browseFields.end() && it->second == fromCylinder) { + if (std::shared_ptr fromTile = fromCylinder->getTile()) { + if (fromTile && browseFields.contains(fromTile) && browseFields[fromTile].lock() == fromCylinder) { fromCylinder = fromTile; } } } - Item* toItem = nullptr; + std::shared_ptr toItem = nullptr; - Cylinder* subCylinder; + std::shared_ptr subCylinder; int floorN = 0; - while ((subCylinder = toCylinder->queryDestination(index, *item, &toItem, flags)) != toCylinder) { + while ((subCylinder = toCylinder->queryDestination(index, item, &toItem, flags)) != toCylinder) { toCylinder = subCylinder; flags = 0; @@ -1700,20 +1705,20 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, } // check if we can add this item - ReturnValue ret = toCylinder->queryAdd(index, *item, count, flags, actor); + ReturnValue ret = toCylinder->queryAdd(index, item, count, flags, actor); if (ret == RETURNVALUE_NEEDEXCHANGE) { // check if we can add it to source cylinder - ret = fromCylinder->queryAdd(fromCylinder->getThingIndex(item), *toItem, toItem->getItemCount(), 0); + ret = fromCylinder->queryAdd(fromCylinder->getThingIndex(item), toItem, toItem->getItemCount(), 0); if (ret == RETURNVALUE_NOERROR) { // check how much we can move uint32_t maxExchangeQueryCount = 0; - ReturnValue retExchangeMaxCount = fromCylinder->queryMaxCount(INDEX_WHEREEVER, *toItem, toItem->getItemCount(), maxExchangeQueryCount, 0); + ReturnValue retExchangeMaxCount = fromCylinder->queryMaxCount(INDEX_WHEREEVER, toItem, toItem->getItemCount(), maxExchangeQueryCount, 0); if (retExchangeMaxCount != RETURNVALUE_NOERROR && maxExchangeQueryCount == 0) { return retExchangeMaxCount; } - if (toCylinder->queryRemove(*toItem, toItem->getItemCount(), flags, actor) == RETURNVALUE_NOERROR) { + if (toCylinder->queryRemove(toItem, toItem->getItemCount(), flags, actor) == RETURNVALUE_NOERROR) { int32_t oldToItemIndex = toCylinder->getThingIndex(toItem); toCylinder->removeThing(toItem, toItem->getItemCount()); fromCylinder->addThing(toItem); @@ -1727,7 +1732,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, fromCylinder->postAddNotification(toItem, toCylinder, newToItemIndex); } - ret = toCylinder->queryAdd(index, *item, count, flags); + ret = toCylinder->queryAdd(index, item, count, flags); toItem = nullptr; } } @@ -1739,7 +1744,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, // check how much we can move uint32_t maxQueryCount = 0; - ReturnValue retMaxCount = toCylinder->queryMaxCount(index, *item, count, maxQueryCount, flags); + ReturnValue retMaxCount = toCylinder->queryMaxCount(index, item, count, maxQueryCount, flags); if (retMaxCount != RETURNVALUE_NOERROR && maxQueryCount == 0) { return retMaxCount; } @@ -1751,9 +1756,9 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, m = maxQueryCount; } - Item* moveItem = item; + std::shared_ptr moveItem = item; // check if we can remove this item - ret = fromCylinder->queryRemove(*item, m, flags, actor); + ret = fromCylinder->queryRemove(item, m, flags, actor); if (ret != RETURNVALUE_NOERROR) { return ret; } @@ -1763,7 +1768,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, return RETURNVALUE_NOTENOUGHROOM; } - Cylinder* tmpCylinder = toCylinder->getParent(); + std::shared_ptr tmpCylinder = toCylinder->getParent(); while (tmpCylinder) { if (tmpCylinder->getItem() == tradeItem) { return RETURNVALUE_NOTENOUGHROOM; @@ -1775,7 +1780,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, // remove the item int32_t itemIndex = fromCylinder->getThingIndex(item); - Item* updateItem = nullptr; + std::shared_ptr updateItem = nullptr; fromCylinder->removeThing(item, m); // update item(s) @@ -1800,7 +1805,6 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, if (item->isRemoved()) { item->stopDecaying(); - ReleaseItem(item); } } @@ -1837,7 +1841,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, } } - Item* quiver = toCylinder->getItem(); + std::shared_ptr quiver = toCylinder->getItem(); if (quiver && quiver->isQuiver() && quiver->getHoldingPlayer() && quiver->getHoldingPlayer()->getThing(CONST_SLOT_RIGHT) == quiver) { @@ -1880,7 +1884,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, return ret; } - if (Player* player = actor->getPlayer()) { + if (std::shared_ptr player = actor->getPlayer()) { // Refresh depot search window if necessary if (player->isDepotSearchOpenOnItem(item->getID()) && ((fromCylinder->getItem() && fromCylinder->getItem()->isInsideDepot(true)) || (toCylinder->getItem() && toCylinder->getItem()->isInsideDepot(true)))) { player->requestDepotSearchItem(item->getID(), item->getTier()); @@ -1901,12 +1905,12 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, return ret; } -ReturnValue Game::internalAddItem(Cylinder* toCylinder, Item* item, int32_t index /*= INDEX_WHEREEVER*/, uint32_t flags /* = 0*/, bool test /* = false*/) { +ReturnValue Game::internalAddItem(std::shared_ptr toCylinder, std::shared_ptr item, int32_t index /*= INDEX_WHEREEVER*/, uint32_t flags /* = 0*/, bool test /* = false*/) { uint32_t remainderCount = 0; return internalAddItem(toCylinder, item, index, flags, test, remainderCount); } -ReturnValue Game::internalAddItem(Cylinder* toCylinder, Item* item, int32_t index, uint32_t flags, bool test, uint32_t &remainderCount) { +ReturnValue Game::internalAddItem(std::shared_ptr toCylinder, std::shared_ptr item, int32_t index, uint32_t flags, bool test, uint32_t &remainderCount) { if (toCylinder == nullptr) { g_logger().error("[{}] fromCylinder is nullptr", __FUNCTION__); return RETURNVALUE_NOTPOSSIBLE; @@ -1918,12 +1922,12 @@ ReturnValue Game::internalAddItem(Cylinder* toCylinder, Item* item, int32_t inde auto addedItem = toCylinder->getItem(); - Cylinder* destCylinder = toCylinder; - Item* toItem = nullptr; - toCylinder = toCylinder->queryDestination(index, *item, &toItem, flags); + std::shared_ptr destCylinder = toCylinder; + std::shared_ptr toItem = nullptr; + toCylinder = toCylinder->queryDestination(index, item, &toItem, flags); // check if we can add this item - ReturnValue ret = toCylinder->queryAdd(index, *item, item->getItemCount(), flags); + ReturnValue ret = toCylinder->queryAdd(index, item, item->getItemCount(), flags); if (ret != RETURNVALUE_NOERROR) { return ret; } @@ -1933,7 +1937,7 @@ ReturnValue Game::internalAddItem(Cylinder* toCylinder, Item* item, int32_t inde since the queryDestination can return a cylinder that might only hold a part of the full amount. */ uint32_t maxQueryCount = 0; - ret = destCylinder->queryMaxCount(INDEX_WHEREEVER, *item, item->getItemCount(), maxQueryCount, flags); + ret = destCylinder->queryMaxCount(INDEX_WHEREEVER, item, item->getItemCount(), maxQueryCount, flags); if (ret != RETURNVALUE_NOERROR && addedItem && addedItem->getID() != ITEM_REWARD_CONTAINER) { return ret; @@ -1952,10 +1956,9 @@ ReturnValue Game::internalAddItem(Cylinder* toCylinder, Item* item, int32_t inde int32_t count = m - n; if (count > 0) { if (item->getItemCount() != count) { - Item* remainderItem = item->clone(); + std::shared_ptr remainderItem = item->clone(); remainderItem->setItemCount(count); if (internalAddItem(destCylinder, remainderItem, INDEX_WHEREEVER, flags, false) != RETURNVALUE_NOERROR) { - ReleaseItem(remainderItem); remainderCount = count; } } else { @@ -1969,7 +1972,6 @@ ReturnValue Game::internalAddItem(Cylinder* toCylinder, Item* item, int32_t inde } else { // fully merged with toItem, item will be destroyed item->onRemoved(); - ReleaseItem(item); int32_t itemIndex = toCylinder->getThingIndex(toItem); if (itemIndex != -1) { @@ -1994,27 +1996,26 @@ ReturnValue Game::internalAddItem(Cylinder* toCylinder, Item* item, int32_t inde return RETURNVALUE_NOERROR; } -ReturnValue Game::internalRemoveItem(Item* item, int32_t count /*= -1*/, bool test /*= false*/, uint32_t flags /*= 0*/, bool force /*= false*/) { +ReturnValue Game::internalRemoveItem(std::shared_ptr item, int32_t count /*= -1*/, bool test /*= false*/, uint32_t flags /*= 0*/, bool force /*= false*/) { if (item == nullptr) { g_logger().debug("{} - Item is nullptr", __FUNCTION__); return RETURNVALUE_NOTPOSSIBLE; } - Cylinder* cylinder = item->getParent(); + std::shared_ptr cylinder = item->getParent(); if (cylinder == nullptr) { g_logger().debug("{} - Cylinder is nullptr", __FUNCTION__); return RETURNVALUE_NOTPOSSIBLE; } - Tile* fromTile = cylinder->getTile(); + std::shared_ptr fromTile = cylinder->getTile(); if (fromTile) { - auto it = browseFields.find(fromTile); - if (it != browseFields.end() && it->second == cylinder) { + if (fromTile && browseFields.contains(fromTile) && browseFields[fromTile].lock() == cylinder) { cylinder = fromTile; } } if (count == -1) { count = item->getItemCount(); } - ReturnValue ret = cylinder->queryRemove(*item, count, flags | FLAG_IGNORENOTMOVEABLE); + ReturnValue ret = cylinder->queryRemove(item, count, flags | FLAG_IGNORENOTMOVEABLE); if (!force && ret != RETURNVALUE_NOERROR) { g_logger().debug("{} - Failed to execute query remove", __FUNCTION__); return ret; @@ -2039,13 +2040,12 @@ ReturnValue Game::internalRemoveItem(Item* item, int32_t count /*= -1*/, bool te if (item->isRemoved()) { item->onRemoved(); item->stopDecaying(); - ReleaseItem(item); } cylinder->postRemoveNotification(item, nullptr, index); } - Item* quiver = cylinder->getItem(); + std::shared_ptr quiver = cylinder->getItem(); if (quiver && quiver->isQuiver() && quiver->getHoldingPlayer() && quiver->getHoldingPlayer()->getThing(CONST_SLOT_RIGHT) == quiver) { @@ -2055,14 +2055,13 @@ ReturnValue Game::internalRemoveItem(Item* item, int32_t count /*= -1*/, bool te return RETURNVALUE_NOERROR; } -ReturnValue Game::internalPlayerAddItem(Player* player, Item* item, bool dropOnMap /*= true*/, Slots_t slot /*= CONST_SLOT_WHEREEVER*/) { +ReturnValue Game::internalPlayerAddItem(std::shared_ptr player, std::shared_ptr item, bool dropOnMap /*= true*/, Slots_t slot /*= CONST_SLOT_WHEREEVER*/) { uint32_t remainderCount = 0; ReturnValue ret = internalAddItem(player, item, static_cast(slot), 0, false, remainderCount); if (remainderCount != 0) { - Item* remainderItem = Item::CreateItem(item->getID(), remainderCount); + std::shared_ptr remainderItem = Item::CreateItem(item->getID(), remainderCount); ReturnValue remaindRet = internalAddItem(player->getTile(), remainderItem, INDEX_WHEREEVER, FLAG_NOLIMIT); if (remaindRet != RETURNVALUE_NOERROR) { - ReleaseItem(remainderItem); player->sendLootStats(item, static_cast(item->getItemCount())); } } @@ -2078,20 +2077,20 @@ ReturnValue Game::internalPlayerAddItem(Player* player, Item* item, bool dropOnM return ret; } -Item* Game::findItemOfType(const Cylinder* cylinder, uint16_t itemId, bool depthSearch /*= true*/, int32_t subType /*= -1*/) const { +std::shared_ptr Game::findItemOfType(std::shared_ptr cylinder, uint16_t itemId, bool depthSearch /*= true*/, int32_t subType /*= -1*/) const { if (cylinder == nullptr) { g_logger().error("[{}] Cylinder is nullptr", __FUNCTION__); return nullptr; } - std::vector containers; + std::vector> containers; for (size_t i = cylinder->getFirstIndex(), j = cylinder->getLastIndex(); i < j; ++i) { - Thing* thing = cylinder->getThing(i); + std::shared_ptr thing = cylinder->getThing(i); if (!thing) { continue; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { continue; } @@ -2101,7 +2100,7 @@ Item* Game::findItemOfType(const Cylinder* cylinder, uint16_t itemId, bool depth } if (depthSearch) { - Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container) { containers.push_back(container); } @@ -2110,13 +2109,13 @@ Item* Game::findItemOfType(const Cylinder* cylinder, uint16_t itemId, bool depth size_t i = 0; while (i < containers.size()) { - Container* container = containers[i++]; - for (Item* item : container->getItemList()) { + std::shared_ptr container = containers[i++]; + for (std::shared_ptr item : container->getItemList()) { if (item->getID() == itemId && (subType == -1 || subType == item->getSubType())) { return item; } - Container* subContainer = item->getContainer(); + std::shared_ptr subContainer = item->getContainer(); if (subContainer) { containers.push_back(subContainer); } @@ -2125,7 +2124,7 @@ Item* Game::findItemOfType(const Cylinder* cylinder, uint16_t itemId, bool depth return nullptr; } -bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/, bool useBalance /*= false*/) { +bool Game::removeMoney(std::shared_ptr cylinder, uint64_t money, uint32_t flags /*= 0*/, bool useBalance /*= false*/) { if (cylinder == nullptr) { g_logger().error("[{}] cylinder is nullptr", __FUNCTION__); return false; @@ -2133,19 +2132,19 @@ bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0* if (money == 0) { return true; } - std::vector containers; - std::multimap moneyMap; + std::vector> containers; + std::multimap> moneyMap; uint64_t moneyCount = 0; for (size_t i = cylinder->getFirstIndex(), j = cylinder->getLastIndex(); i < j; ++i) { - Thing* thing = cylinder->getThing(i); + std::shared_ptr thing = cylinder->getThing(i); if (!thing) { continue; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { continue; } - Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container) { containers.push_back(container); } else { @@ -2158,9 +2157,9 @@ bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0* } size_t i = 0; while (i < containers.size()) { - Container* container = containers[i++]; - for (Item* item : container->getItemList()) { - Container* tmpContainer = item->getContainer(); + std::shared_ptr container = containers[i++]; + for (std::shared_ptr item : container->getItemList()) { + std::shared_ptr tmpContainer = item->getContainer(); if (tmpContainer) { containers.push_back(tmpContainer); } else { @@ -2173,7 +2172,7 @@ bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0* } } - Player* player = useBalance ? dynamic_cast(cylinder) : nullptr; + std::shared_ptr player = useBalance ? std::dynamic_pointer_cast(cylinder) : nullptr; uint64_t balance = 0; if (useBalance && player) { balance = player->getBankBalance(); @@ -2184,7 +2183,7 @@ bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0* } for (const auto &moneyEntry : moneyMap) { - Item* item = moneyEntry.second; + std::shared_ptr item = moneyEntry.second; if (moneyEntry.first < money) { internalRemoveItem(item); money -= moneyEntry.first; @@ -2207,7 +2206,7 @@ bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0* return true; } -void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) { +void Game::addMoney(std::shared_ptr cylinder, uint64_t money, uint32_t flags /*= 0*/) { if (cylinder == nullptr) { g_logger().error("[{}] cylinder is nullptr", __FUNCTION__); return; @@ -2221,7 +2220,7 @@ void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) while (crystalCoins > 0) { const uint16_t count = std::min(100, crystalCoins); - Item* remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, count); + std::shared_ptr remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, count); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { @@ -2233,7 +2232,7 @@ void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) uint16_t platinumCoins = money / 100; if (platinumCoins != 0) { - Item* remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins); + std::shared_ptr remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { @@ -2244,7 +2243,7 @@ void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) } if (money != 0) { - Item* remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money); + std::shared_ptr remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { @@ -2253,22 +2252,19 @@ void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) } } -Item* Game::transformItem(Item* item, uint16_t newId, int32_t newCount /*= -1*/) { +std::shared_ptr Game::transformItem(std::shared_ptr item, uint16_t newId, int32_t newCount /*= -1*/) { if (item->getID() == newId && (newCount == -1 || (newCount == item->getSubType() && newCount != 0))) { // chargeless item placed on map = infinite return item; } - Cylinder* cylinder = item->getParent(); + std::shared_ptr cylinder = item->getParent(); if (cylinder == nullptr) { return nullptr; } - Tile* fromTile = cylinder->getTile(); - if (fromTile) { - auto it = browseFields.find(fromTile); - if (it != browseFields.end() && it->second == cylinder) { - cylinder = fromTile; - } + std::shared_ptr fromTile = cylinder->getTile(); + if (fromTile && browseFields.contains(fromTile) && browseFields[fromTile].lock() == cylinder) { + cylinder = fromTile; } int32_t itemIndex = cylinder->getThingIndex(item); @@ -2298,10 +2294,9 @@ Item* Game::transformItem(Item* item, uint16_t newId, int32_t newCount /*= -1*/) } cylinder->addThing(item); - Cylinder* newParent = item->getParent(); + std::shared_ptr newParent = item->getParent(); if (newParent == nullptr) { item->stopDecaying(); - ReleaseItem(item); return nullptr; } @@ -2327,7 +2322,7 @@ Item* Game::transformItem(Item* item, uint16_t newId, int32_t newCount /*= -1*/) internalRemoveItem(item); return nullptr; } else if (newItemId != newId) { - // Replacing the the old item with the new while maintaining the old position + // Replacing the the old item with the std::make_shared< while> maintaining the old position auto newItem = item->transform(newItemId); if (newItem == nullptr) { g_logger().error("[{}] new item with id {} is nullptr, (ERROR CODE: 01)", __FUNCTION__, newItemId); @@ -2359,7 +2354,7 @@ Item* Game::transformItem(Item* item, uint16_t newId, int32_t newCount /*= -1*/) cylinder->updateThing(item, itemId, count); cylinder->postAddNotification(item, cylinder, itemIndex); - Item* quiver = cylinder->getItem(); + std::shared_ptr quiver = cylinder->getItem(); if (quiver && quiver->isQuiver() && quiver->getHoldingPlayer() && quiver->getHoldingPlayer()->getThing(CONST_SLOT_RIGHT) == quiver) { @@ -2371,7 +2366,7 @@ Item* Game::transformItem(Item* item, uint16_t newId, int32_t newCount /*= -1*/) } } - Item* quiver = cylinder->getItem(); + std::shared_ptr quiver = cylinder->getItem(); if (quiver && quiver->isQuiver() && quiver->getHoldingPlayer() && quiver->getHoldingPlayer()->getThing(CONST_SLOT_RIGHT) == quiver) { @@ -2388,7 +2383,7 @@ Item* Game::transformItem(Item* item, uint16_t newId, int32_t newCount /*= -1*/) return newItem; } -ReturnValue Game::internalTeleport(Thing* thing, const Position &newPos, bool pushMove /* = true*/, uint32_t flags /*= 0*/) { +ReturnValue Game::internalTeleport(std::shared_ptr thing, const Position &newPos, bool pushMove /* = true*/, uint32_t flags /*= 0*/) { if (thing == nullptr) { g_logger().error("[{}] thing is nullptr", __FUNCTION__); return RETURNVALUE_NOTPOSSIBLE; @@ -2400,38 +2395,38 @@ ReturnValue Game::internalTeleport(Thing* thing, const Position &newPos, bool pu return RETURNVALUE_NOTPOSSIBLE; } - Tile* toTile = map.getTile(newPos); + std::shared_ptr toTile = map.getTile(newPos); if (!toTile) { return RETURNVALUE_NOTPOSSIBLE; } - if (Creature* creature = thing->getCreature()) { - ReturnValue ret = toTile->queryAdd(0, *creature, 1, FLAG_NOLIMIT); + if (std::shared_ptr creature = thing->getCreature()) { + ReturnValue ret = toTile->queryAdd(0, creature, 1, FLAG_NOLIMIT); if (ret != RETURNVALUE_NOERROR) { return ret; } - map.moveCreature(*creature, *toTile, !pushMove); + map.moveCreature(creature, toTile, !pushMove); return RETURNVALUE_NOERROR; - } else if (Item* item = thing->getItem()) { + } else if (std::shared_ptr item = thing->getItem()) { return internalMoveItem(item->getParent(), toTile, INDEX_WHEREEVER, item, item->getItemCount(), nullptr, flags); } return RETURNVALUE_NOTPOSSIBLE; } -void Game::internalQuickLootCorpse(Player* player, Container* corpse) { +void Game::internalQuickLootCorpse(std::shared_ptr player, std::shared_ptr corpse) { if (!player || !corpse) { return; } - std::vector itemList; + std::vector> itemList; bool ignoreListItems = (player->quickLootFilter == QUICKLOOTFILTER_SKIPPEDLOOT); bool missedAnyGold = false; bool missedAnyItem = false; for (ContainerIterator it = corpse->iterator(); it.hasNext(); it.advance()) { - Item* item = *it; + std::shared_ptr item = *it; bool listed = player->isQuickLootListedItem(item); if ((listed && ignoreListItems) || (!listed && !ignoreListItems)) { if (item->getWorth() != 0) { @@ -2450,7 +2445,7 @@ void Game::internalQuickLootCorpse(Player* player, Container* corpse) { uint32_t totalLootedGold = 0; uint32_t totalLootedItems = 0; - for (Item* item : itemList) { + for (std::shared_ptr item : itemList) { uint32_t worth = item->getWorth(); uint16_t baseCount = item->getItemCount(); ObjectCategory_t category = getObjectCategory(item); @@ -2562,11 +2557,11 @@ void Game::internalQuickLootCorpse(Player* player, Container* corpse) { player->lastQuickLootNotification = OTSYS_TIME(); } -Container* Game::findLootContainer(Player* player, bool &fallbackConsumed, ObjectCategory_t category) { - Container* lootContainer = player->getLootContainer(category); +std::shared_ptr Game::findLootContainer(std::shared_ptr player, bool &fallbackConsumed, ObjectCategory_t category) { + auto lootContainer = player->getLootContainer(category); if (!lootContainer && player->quickLootFallbackToMainContainer && !fallbackConsumed) { - Item* fallbackItem = player->getInventoryItem(CONST_SLOT_BACKPACK); - Container* mainBackpack = fallbackItem ? fallbackItem->getContainer() : nullptr; + auto fallbackItem = player->getInventoryItem(CONST_SLOT_BACKPACK); + auto mainBackpack = fallbackItem ? fallbackItem->getContainer() : nullptr; if (mainBackpack) { player->setLootContainer(OBJECTCATEGORY_DEFAULT, mainBackpack); @@ -2579,10 +2574,10 @@ Container* Game::findLootContainer(Player* player, bool &fallbackConsumed, Objec return lootContainer; } -Container* Game::findNextAvailableContainer(ContainerIterator &containerIterator, Container*&lootContainer, Container*&lastSubContainer) { +std::shared_ptr Game::findNextAvailableContainer(ContainerIterator &containerIterator, std::shared_ptr &lootContainer, std::shared_ptr &lastSubContainer) { while (containerIterator.hasNext()) { - Item* cur = *containerIterator; - Container* subContainer = cur ? cur->getContainer() : nullptr; + std::shared_ptr cur = *containerIterator; + std::shared_ptr subContainer = cur ? cur->getContainer() : nullptr; containerIterator.advance(); if (subContainer) { @@ -2594,7 +2589,7 @@ Container* Game::findNextAvailableContainer(ContainerIterator &containerIterator // Fix last empty sub-container if (lastSubContainer && !lastSubContainer->empty()) { - Item* cur = lastSubContainer->getItemByIndex(lastSubContainer->size() - 1); + auto cur = lastSubContainer->getItemByIndex(lastSubContainer->size() - 1); lootContainer = cur ? cur->getContainer() : nullptr; lastSubContainer = nullptr; return lootContainer; @@ -2603,12 +2598,12 @@ Container* Game::findNextAvailableContainer(ContainerIterator &containerIterator return nullptr; } -bool Game::handleFallbackLogic(const Player* player, Container*&lootContainer, ContainerIterator &containerIterator, const bool &fallbackConsumed) { +bool Game::handleFallbackLogic(std::shared_ptr player, std::shared_ptr &lootContainer, ContainerIterator &containerIterator, const bool &fallbackConsumed) { if (fallbackConsumed || !player->quickLootFallbackToMainContainer) { return false; } - Item* fallbackItem = player->getInventoryItem(CONST_SLOT_BACKPACK); + std::shared_ptr fallbackItem = player->getInventoryItem(CONST_SLOT_BACKPACK); if (!fallbackItem || !fallbackItem->getContainer()) { return false; } @@ -2619,8 +2614,8 @@ bool Game::handleFallbackLogic(const Player* player, Container*&lootContainer, C return true; } -ReturnValue Game::processMoveOrAddItemToLootContainer(Item* item, Container* lootContainer, uint32_t &remainderCount, Player* player) { - Item* moveItem = nullptr; +ReturnValue Game::processMoveOrAddItemToLootContainer(std::shared_ptr item, std::shared_ptr lootContainer, uint32_t &remainderCount, std::shared_ptr player) { + std::shared_ptr moveItem = nullptr; ReturnValue ret; if (item->getParent()) { ret = internalMoveItem(item->getParent(), lootContainer, INDEX_WHEREEVER, item, item->getItemCount(), &moveItem, 0, player, nullptr, false); @@ -2633,8 +2628,8 @@ ReturnValue Game::processMoveOrAddItemToLootContainer(Item* item, Container* loo return ret; } -ReturnValue Game::processLootItems(Player* player, Container* lootContainer, Item* item, bool &fallbackConsumed) { - Container* lastSubContainer = nullptr; +ReturnValue Game::processLootItems(std::shared_ptr player, std::shared_ptr lootContainer, std::shared_ptr item, bool &fallbackConsumed) { + std::shared_ptr lastSubContainer = nullptr; uint32_t remainderCount = item->getItemCount(); ContainerIterator containerIterator = lootContainer->iterator(); @@ -2645,7 +2640,7 @@ ReturnValue Game::processLootItems(Player* player, Container* lootContainer, Ite return ret; } - const Container* nextContainer = findNextAvailableContainer(containerIterator, lootContainer, lastSubContainer); + std::shared_ptr nextContainer = findNextAvailableContainer(containerIterator, lootContainer, lastSubContainer); if (!nextContainer && !handleFallbackLogic(player, lootContainer, containerIterator, fallbackConsumed)) { break; } @@ -2655,7 +2650,7 @@ ReturnValue Game::processLootItems(Player* player, Container* lootContainer, Ite return ret; } -ReturnValue Game::internalCollectLootItems(Player* player, Item* item, ObjectCategory_t category /* = OBJECTCATEGORY_DEFAULT*/) { +ReturnValue Game::internalCollectLootItems(std::shared_ptr player, std::shared_ptr item, ObjectCategory_t category /* = OBJECTCATEGORY_DEFAULT*/) { if (!player || !item) { return RETURNVALUE_NOTPOSSIBLE; } @@ -2684,7 +2679,7 @@ ReturnValue Game::internalCollectLootItems(Player* player, Item* item, ObjectCat } bool fallbackConsumed = false; - Container* lootContainer = findLootContainer(player, fallbackConsumed, category); + std::shared_ptr lootContainer = findLootContainer(player, fallbackConsumed, category); if (!lootContainer) { return RETURNVALUE_NOTPOSSIBLE; } @@ -2692,12 +2687,12 @@ ReturnValue Game::internalCollectLootItems(Player* player, Item* item, ObjectCat return processLootItems(player, lootContainer, item, fallbackConsumed); } -ReturnValue Game::collectRewardChestItems(Player* player, uint32_t maxMoveItems /* = 0*/) { +ReturnValue Game::collectRewardChestItems(std::shared_ptr player, uint32_t maxMoveItems /* = 0*/) { // Check if have item on player reward chest - RewardChest* rewardChest = player->getRewardChest(); - if (!rewardChest || rewardChest->empty()) { - g_logger().debug("Reward chest is wrong or empty"); - return RETURNVALUE_NOTPOSSIBLE; + std::shared_ptr rewardChest = player->getRewardChest(); + if (rewardChest->empty()) { + g_logger().debug("Reward chest is empty"); + return RETURNVALUE_REWARDCHESTISEMPTY; } auto rewardItemsVector = player->getRewardsFromContainer(rewardChest->getContainer()); @@ -2735,7 +2730,7 @@ ReturnValue Game::collectRewardChestItems(Player* player, uint32_t maxMoveItems return RETURNVALUE_NOERROR; } -ObjectCategory_t Game::getObjectCategory(const Item* item) { +ObjectCategory_t Game::getObjectCategory(std::shared_ptr item) { ObjectCategory_t category = OBJECTCATEGORY_DEFAULT; if (!item) { return OBJECTCATEGORY_NONE; @@ -2829,7 +2824,7 @@ uint64_t Game::getItemMarketPrice(const std::map &itemMap, b return total; } -Item* searchForItem(const Container* container, uint16_t itemId, bool hasTier /* = false*/, uint8_t tier /* = 0*/) { +std::shared_ptr searchForItem(std::shared_ptr container, uint16_t itemId, bool hasTier /* = false*/, uint8_t tier /* = 0*/) { for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) { if ((*it)->getID() == itemId && (!hasTier || (*it)->getTier() == tier)) { return *it; @@ -2868,7 +2863,7 @@ Slots_t getSlotType(const ItemType &it) { // Implementation of player invoked events void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* = false*/, uint8_t tier /* = 0*/) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -2881,12 +2876,12 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* = return; } - Item* item = player->getInventoryItem(CONST_SLOT_BACKPACK); + std::shared_ptr item = player->getInventoryItem(CONST_SLOT_BACKPACK); if (!item) { return; } - const Container* backpack = item->getContainer(); + std::shared_ptr backpack = item->getContainer(); if (!backpack) { return; } @@ -2894,13 +2889,13 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* = const ItemType &it = Item::items[itemId]; Slots_t slot = getSlotType(it); - Item* slotItem = player->getInventoryItem(slot); - Item* equipItem = searchForItem(backpack, it.id, hasTier, tier); + auto slotItem = player->getInventoryItem(slot); + auto equipItem = searchForItem(backpack, it.id, hasTier, tier); if (slotItem && slotItem->getID() == it.id && (!it.stackable || slotItem->getItemCount() == slotItem->getStackSize() || !equipItem)) { internalMoveItem(slotItem->getParent(), player, CONST_SLOT_WHEREEVER, slotItem, slotItem->getItemCount(), nullptr); } else if (equipItem) { if (it.weaponType == WEAPON_AMMO) { - Item* quiver = player->getInventoryItem(CONST_SLOT_RIGHT); + auto quiver = player->getInventoryItem(CONST_SLOT_RIGHT); if (quiver && quiver->isQuiver()) { internalMoveItem(equipItem->getParent(), quiver->getContainer(), 0, equipItem, equipItem->getItemCount(), nullptr); return; @@ -2912,7 +2907,7 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* = } void Game::playerMove(uint32_t playerId, Direction direction) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -2925,7 +2920,7 @@ void Game::playerMove(uint32_t playerId, Direction direction) { } void Game::forcePlayerMove(uint32_t playerId, Direction direction) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -2937,7 +2932,7 @@ void Game::forcePlayerMove(uint32_t playerId, Direction direction) { player->startAutoWalk(std::forward_list { direction }, true); } -bool Game::playerBroadcastMessage(Player* player, const std::string &text) const { +bool Game::playerBroadcastMessage(std::shared_ptr player, const std::string &text) const { if (!player->hasFlag(PlayerFlags_t::CanBroadcast)) { return false; } @@ -2952,13 +2947,13 @@ bool Game::playerBroadcastMessage(Player* player, const std::string &text) const } void Game::playerCreatePrivateChannel(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->isPremium()) { return; } - ChatChannel* channel = g_chat().createChannel(*player, CHANNEL_PRIVATE); - if (!channel || !channel->addUser(*player)) { + ChatChannel* channel = g_chat().createChannel(player, CHANNEL_PRIVATE); + if (!channel || !channel->addUser(player)) { return; } @@ -2966,17 +2961,17 @@ void Game::playerCreatePrivateChannel(uint32_t playerId) { } void Game::playerChannelInvite(uint32_t playerId, const std::string &name) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - PrivateChatChannel* channel = g_chat().getPrivateChannel(*player); + PrivateChatChannel* channel = g_chat().getPrivateChannel(player); if (!channel) { return; } - Player* invitePlayer = getPlayerByName(name); + std::shared_ptr invitePlayer = getPlayerByName(name); if (!invitePlayer) { return; } @@ -2985,21 +2980,21 @@ void Game::playerChannelInvite(uint32_t playerId, const std::string &name) { return; } - channel->invitePlayer(*player, *invitePlayer); + channel->invitePlayer(player, invitePlayer); } void Game::playerChannelExclude(uint32_t playerId, const std::string &name) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - PrivateChatChannel* channel = g_chat().getPrivateChannel(*player); + PrivateChatChannel* channel = g_chat().getPrivateChannel(player); if (!channel) { return; } - Player* excludePlayer = getPlayerByName(name); + std::shared_ptr excludePlayer = getPlayerByName(name); if (!excludePlayer) { return; } @@ -3008,11 +3003,11 @@ void Game::playerChannelExclude(uint32_t playerId, const std::string &name) { return; } - channel->excludePlayer(*player, *excludePlayer); + channel->excludePlayer(player, excludePlayer); } void Game::playerRequestChannels(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3021,12 +3016,12 @@ void Game::playerRequestChannels(uint32_t playerId) { } void Game::playerOpenChannel(uint32_t playerId, uint16_t channelId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - const ChatChannel* channel = g_chat().addUserToChannel(*player, channelId); + const ChatChannel* channel = g_chat().addUserToChannel(player, channelId); if (!channel) { return; } @@ -3043,16 +3038,16 @@ void Game::playerOpenChannel(uint32_t playerId, uint16_t channelId) { } void Game::playerCloseChannel(uint32_t playerId, uint16_t channelId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - g_chat().removeUserFromChannel(*player, channelId); + g_chat().removeUserFromChannel(player, channelId); } void Game::playerOpenPrivateChannel(uint32_t playerId, std::string &receiver) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3071,22 +3066,22 @@ void Game::playerOpenPrivateChannel(uint32_t playerId, std::string &receiver) { } void Game::playerCloseNpcChannel(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } SpectatorHashSet spectators; map.getSpectators(spectators, player->getPosition()); - for (Creature* spectator : spectators) { - if (Npc* npc = spectator->getNpc()) { + for (std::shared_ptr spectator : spectators) { + if (auto npc = spectator->getNpc()) { npc->onPlayerCloseChannel(player); } } } void Game::playerReceivePing(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3095,7 +3090,7 @@ void Game::playerReceivePing(uint32_t playerId) { } void Game::playerReceivePingBack(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3104,7 +3099,7 @@ void Game::playerReceivePingBack(uint32_t playerId) { } void Game::playerAutoWalk(uint32_t playerId, const std::forward_list &listDir) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3115,7 +3110,7 @@ void Game::playerAutoWalk(uint32_t playerId, const std::forward_list } void Game::forcePlayerAutoWalk(uint32_t playerId, const std::forward_list &listDir) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3132,7 +3127,7 @@ void Game::forcePlayerAutoWalk(uint32_t playerId, const std::forward_list player = getPlayerByID(playerId); if (!player) { return; } @@ -3141,7 +3136,7 @@ void Game::playerStopAutoWalk(uint32_t playerId) { } void Game::playerUseItemEx(uint32_t playerId, const Position &fromPos, uint8_t fromStackPos, uint16_t fromItemId, const Position &toPos, uint8_t toStackPos, uint16_t toItemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3151,13 +3146,13 @@ void Game::playerUseItemEx(uint32_t playerId, const Position &fromPos, uint8_t f return; } - Thing* thing = internalGetThing(player, fromPos, fromStackPos, fromItemId, STACKPOS_FIND_THING); + std::shared_ptr thing = internalGetThing(player, fromPos, fromStackPos, fromItemId, STACKPOS_FIND_THING); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || !item->isMultiUse() || item->getID() != fromItemId) { player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT); return; @@ -3191,7 +3186,7 @@ void Game::playerUseItemEx(uint32_t playerId, const Position &fromPos, uint8_t f uint8_t itemStackPos = fromStackPos; if (fromPos.x != 0xFFFF && toPos.x != 0xFFFF && Position::areInRange<1, 1, 0>(fromPos, player->getPosition()) && !Position::areInRange<1, 1, 0>(fromPos, toPos)) { - Item* moveItem = nullptr; + std::shared_ptr moveItem = nullptr; ret = internalMoveItem(item->getParent(), player, INDEX_WHEREEVER, item, item->getItemCount(), &moveItem); if (ret != RETURNVALUE_NOERROR) { @@ -3255,7 +3250,7 @@ void Game::playerUseItemEx(uint32_t playerId, const Position &fromPos, uint8_t f if (item->isInsideDepot(true)) { mustReloadDepotSearch = true; } else { - if (Thing* targetThing = internalGetThing(player, toPos, toStackPos, toItemId, STACKPOS_FIND_THING); + if (auto targetThing = internalGetThing(player, toPos, toStackPos, toItemId, STACKPOS_FIND_THING); targetThing && targetThing->getItem() && targetThing->getItem()->isInsideDepot(true)) { mustReloadDepotSearch = true; } @@ -3270,7 +3265,7 @@ void Game::playerUseItemEx(uint32_t playerId, const Position &fromPos, uint8_t f } void Game::playerUseItem(uint32_t playerId, const Position &pos, uint8_t stackPos, uint8_t index, uint16_t itemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3280,13 +3275,13 @@ void Game::playerUseItem(uint32_t playerId, const Position &pos, uint8_t stackPo return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_FIND_THING); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_FIND_THING); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || item->isMultiUse() || item->getID() != itemId) { player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT); return; @@ -3364,12 +3359,12 @@ void Game::playerUseItem(uint32_t playerId, const Position &pos, uint8_t stackPo } void Game::playerUseWithCreature(uint32_t playerId, const Position &fromPos, uint8_t fromStackPos, uint32_t creatureId, uint16_t itemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Creature* creature = getCreatureByID(creatureId); + std::shared_ptr creature = getCreatureByID(creatureId); if (!creature) { return; } @@ -3386,21 +3381,21 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position &fromPos, uin } } - Thing* thing = internalGetThing(player, fromPos, fromStackPos, itemId, STACKPOS_FIND_THING); + std::shared_ptr thing = internalGetThing(player, fromPos, fromStackPos, itemId, STACKPOS_FIND_THING); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || !item->isMultiUse() || item->getID() != itemId) { player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT); return; } if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) { - if (HouseTile* houseTile = dynamic_cast(item->getTile())) { - House* house = houseTile->getHouse(); + if (std::shared_ptr houseTile = std::dynamic_pointer_cast(item->getTile())) { + const auto &house = houseTile->getHouse(); if (house && item->getRealParent() && item->getRealParent() != player && (!house->isInvited(player) || house->getHouseAccessLevel(player) == HOUSE_GUEST)) { player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT); return; @@ -3431,7 +3426,7 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position &fromPos, uin uint8_t itemStackPos = fromStackPos; if (fromPos.x != 0xFFFF && Position::areInRange<1, 1, 0>(fromPos, player->getPosition()) && !Position::areInRange<1, 1, 0>(fromPos, toPos)) { - Item* moveItem = nullptr; + std::shared_ptr moveItem = nullptr; ret = internalMoveItem(item->getParent(), player, INDEX_WHEREEVER, item, item->getItemCount(), &moveItem); if (ret != RETURNVALUE_NOERROR) { player->sendCancelMessage(ret); @@ -3493,7 +3488,7 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position &fromPos, uin } void Game::playerCloseContainer(uint32_t playerId, uint8_t cid) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3503,19 +3498,19 @@ void Game::playerCloseContainer(uint32_t playerId, uint8_t cid) { } void Game::playerMoveUpContainer(uint32_t playerId, uint8_t cid) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Container* container = player->getContainerByID(cid); + std::shared_ptr container = player->getContainerByID(cid); if (!container) { return; } - Container* parentContainer = dynamic_cast(container->getRealParent()); + std::shared_ptr parentContainer = std::dynamic_pointer_cast(container->getRealParent()); if (!parentContainer) { - Tile* tile = container->getTile(); + std::shared_ptr tile = container->getTile(); if (!tile) { return; } @@ -3529,13 +3524,11 @@ void Game::playerMoveUpContainer(uint32_t playerId, uint8_t cid) { } auto it = browseFields.find(tile); - if (it == browseFields.end()) { - parentContainer = new Container(tile); - parentContainer->incrementReferenceCounter(); + if (it == browseFields.end() || it->second.expired()) { + parentContainer = Container::create(tile); browseFields[tile] = parentContainer; - g_scheduler().addEvent(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()), "Game::decreaseBrowseFieldRef"); } else { - parentContainer = it->second; + parentContainer = it->second.lock(); } } @@ -3552,12 +3545,12 @@ void Game::playerMoveUpContainer(uint32_t playerId, uint8_t cid) { } void Game::playerUpdateContainer(uint32_t playerId, uint8_t cid) { - Player* player = getPlayerByGUID(playerId); + std::shared_ptr player = getPlayerByGUID(playerId); if (!player) { return; } - Container* container = player->getContainerByID(cid); + std::shared_ptr container = player->getContainerByID(cid); if (!container) { return; } @@ -3566,17 +3559,17 @@ void Game::playerUpdateContainer(uint32_t playerId, uint8_t cid) { } void Game::playerRotateItem(uint32_t playerId, const Position &pos, uint8_t stackPos, const uint16_t itemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || item->getID() != itemId || !item->isRotatable() || item->hasAttribute(ItemAttribute_t::UNIQUEID)) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -3606,17 +3599,17 @@ void Game::playerRotateItem(uint32_t playerId, const Position &pos, uint8_t stac } void Game::playerConfigureShowOffSocket(uint32_t playerId, const Position &pos, uint8_t stackPos, const uint16_t itemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || pos.x == 0xFFFF) { return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || item->getID() != itemId || !item->isPodium() || item->hasAttribute(ItemAttribute_t::UNIQUEID)) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -3648,17 +3641,17 @@ void Game::playerConfigureShowOffSocket(uint32_t playerId, const Position &pos, } void Game::playerSetShowOffSocket(uint32_t playerId, Outfit_t &outfit, const Position &pos, uint8_t stackPos, const uint16_t itemId, uint8_t podiumVisible, uint8_t direction) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || pos.x == 0xFFFF) { return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || item->getID() != itemId || !item->isPodium() || item->hasAttribute(ItemAttribute_t::UNIQUEID)) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -3763,33 +3756,33 @@ void Game::playerSetShowOffSocket(uint32_t playerId, Outfit_t &outfit, const Pos g_game().map.getSpectators(spectators, pos, true); // Send to client - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendUpdateTileItem(tile, pos, item); } } } void Game::playerWrapableItem(uint32_t playerId, const Position &pos, uint8_t stackPos, const uint16_t itemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - House* house = map.houses.getHouseByPlayerId(player->getGUID()); + const auto &house = map.houses.getHouseByPlayerId(player->getGUID()); if (!house) { player->sendCancelMessage("You don't own a house, you need own a house to use this."); return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_FIND_THING); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_FIND_THING); if (!thing) { return; } - Item* item = thing->getItem(); - Tile* tile = map.getTile(item->getPosition()); - HouseTile* houseTile = dynamic_cast(tile); + std::shared_ptr item = thing->getItem(); + std::shared_ptr tile = map.getTile(item->getPosition()); + std::shared_ptr houseTile = std::dynamic_pointer_cast(tile); if (!tile->hasFlag(TILESTATE_PROTECTIONZONE) || !houseTile) { player->sendCancelMessage("You may construct this only inside a house."); return; @@ -3817,7 +3810,7 @@ void Game::playerWrapableItem(uint32_t playerId, const Position &pos, uint8_t st return; } - const Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && container->getItemHoldingCount() > 0) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -3853,7 +3846,7 @@ void Game::playerWrapableItem(uint32_t playerId, const Position &pos, uint8_t st addMagicEffect(pos, CONST_ME_POFF); } -Item* Game::wrapItem(Item* item, House* house) { +std::shared_ptr Game::wrapItem(std::shared_ptr item, std::shared_ptr house) { uint16_t hiddenCharges = 0; uint16_t amount = item->getItemCount(); if (isCaskItem(item->getID())) { @@ -3864,7 +3857,7 @@ Item* Game::wrapItem(Item* item, House* house) { house->removeBed(item->getBed()); } uint16_t oldItemID = item->getID(); - Item* newItem = transformItem(item, ITEM_DECORATION_KIT); + std::shared_ptr newItem = transformItem(item, ITEM_DECORATION_KIT); newItem->setCustomAttribute("unWrapId", static_cast(oldItemID)); item->setAttribute(ItemAttribute_t::DESCRIPTION, "Unwrap it in your own house to create a <" + item->getName() + ">."); if (hiddenCharges > 0) { @@ -3877,7 +3870,7 @@ Item* Game::wrapItem(Item* item, House* house) { return newItem; } -void Game::unwrapItem(Item* item, uint16_t unWrapId, House* house, Player* player) { +void Game::unwrapItem(std::shared_ptr item, uint16_t unWrapId, std::shared_ptr house, std::shared_ptr player) { auto hiddenCharges = item->getAttribute(DATE); const ItemType &newiType = Item::items.getItemType(unWrapId); if (player != nullptr && house != nullptr && newiType.isBed() && house->getMaxBeds() > -1 && house->getBedCount() >= house->getMaxBeds()) { @@ -3888,7 +3881,7 @@ void Game::unwrapItem(Item* item, uint16_t unWrapId, House* house, Player* playe if (!amount) { amount = 1; } - Item* newItem = transformItem(item, unWrapId, amount); + std::shared_ptr newItem = transformItem(item, unWrapId, amount); if (house && newiType.isBed()) { house->addBed(newItem->getBed()); } @@ -3903,7 +3896,7 @@ void Game::unwrapItem(Item* item, uint16_t unWrapId, House* house, Player* playe } void Game::playerWriteItem(uint32_t playerId, uint32_t windowTextId, const std::string &text) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3911,7 +3904,7 @@ void Game::playerWriteItem(uint32_t playerId, uint32_t windowTextId, const std:: uint16_t maxTextLength = 0; uint32_t internalWindowTextId = 0; - Item* writeItem = player->getWriteItem(internalWindowTextId, maxTextLength); + std::shared_ptr writeItem = player->getWriteItem(internalWindowTextId, maxTextLength); if (text.length() > maxTextLength || windowTextId != internalWindowTextId) { return; } @@ -3921,9 +3914,9 @@ void Game::playerWriteItem(uint32_t playerId, uint32_t windowTextId, const std:: return; } - Cylinder* topParent = writeItem->getTopParent(); + std::shared_ptr topParent = writeItem->getTopParent(); - Player* owner = dynamic_cast(topParent); + std::shared_ptr owner = std::dynamic_pointer_cast(topParent); if (owner && owner != player) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -3962,7 +3955,7 @@ void Game::playerWriteItem(uint32_t playerId, uint32_t windowTextId, const std:: } void Game::playerBrowseField(uint32_t playerId, const Position &pos) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -3985,7 +3978,7 @@ void Game::playerBrowseField(uint32_t playerId, const Position &pos) { return; } - Tile* tile = map.getTile(pos); + std::shared_ptr tile = map.getTile(pos); if (!tile) { return; } @@ -3998,20 +3991,18 @@ void Game::playerBrowseField(uint32_t playerId, const Position &pos) { return; } - Container* container; + std::shared_ptr container; auto it = browseFields.find(tile); - if (it == browseFields.end()) { - container = new Container(tile); - container->incrementReferenceCounter(); + if (it == browseFields.end() || it->second.expired()) { + container = Container::create(tile); browseFields[tile] = container; - g_scheduler().addEvent(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()), "Game::decreaseBrowseFieldRef"); } else { - container = it->second; + container = it->second.lock(); } uint8_t dummyContainerId = 0xF - ((pos.x % 3) * 3 + (pos.y % 3)); - Container* openContainer = player->getContainerByID(dummyContainerId); + std::shared_ptr openContainer = player->getContainerByID(dummyContainerId); if (openContainer) { player->onCloseContainer(openContainer); player->closeContainer(dummyContainerId); @@ -4022,7 +4013,7 @@ void Game::playerBrowseField(uint32_t playerId, const Position &pos) { } void Game::playerStowItem(uint32_t playerId, const Position &pos, uint16_t itemId, uint8_t stackpos, uint8_t count, bool allItems) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -4032,12 +4023,12 @@ void Game::playerStowItem(uint32_t playerId, const Position &pos, uint16_t itemI return; } - Thing* thing = internalGetThing(player, pos, stackpos, itemId, STACKPOS_TOPDOWN_ITEM); + std::shared_ptr thing = internalGetThing(player, pos, stackpos, itemId, STACKPOS_TOPDOWN_ITEM); if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || item->getID() != itemId || item->getItemCount() < count || item->isStoreItem()) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -4058,7 +4049,7 @@ void Game::playerStowItem(uint32_t playerId, const Position &pos, uint16_t itemI } void Game::playerStashWithdraw(uint32_t playerId, uint16_t itemId, uint32_t count, uint8_t) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -4073,7 +4064,7 @@ void Game::playerStashWithdraw(uint32_t playerId, uint16_t itemId, uint32_t coun } uint16_t freeSlots = player->getFreeBackpackSlots(); - Container* stashContainer = player->getLootContainer(OBJECTCATEGORY_STASHRETRIEVE); + auto stashContainer = player->getLootContainer(OBJECTCATEGORY_STASHRETRIEVE); if (stashContainer && !(player->quickLootFallbackToMainContainer)) { freeSlots = stashContainer->getFreeSlots(); } @@ -4131,12 +4122,12 @@ void Game::playerStashWithdraw(uint32_t playerId, uint16_t itemId, uint32_t coun } void Game::playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index, uint8_t containerCategory) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Container* container = player->getContainerByID(containerId); + std::shared_ptr container = player->getContainerByID(containerId); if (!container || !container->hasPagination()) { return; } @@ -4156,7 +4147,7 @@ void Game::playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_ } void Game::playerUpdateHouseWindow(uint32_t playerId, uint8_t listId, uint32_t windowTextId, const std::string &text) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -4164,7 +4155,7 @@ void Game::playerUpdateHouseWindow(uint32_t playerId, uint8_t listId, uint32_t w uint32_t internalWindowTextId; uint32_t internalListId; - House* house = player->getEditHouse(internalWindowTextId, internalListId); + const auto &house = player->getEditHouse(internalWindowTextId, internalListId); if (house && house->canEditAccessList(internalListId, player) && internalWindowTextId == windowTextId && listId == 0) { house->setAccessList(internalListId, text); } @@ -4173,12 +4164,12 @@ void Game::playerUpdateHouseWindow(uint32_t playerId, uint8_t listId, uint32_t w } void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t stackPos, uint32_t tradePlayerId, uint16_t itemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Player* tradePartner = getPlayerByID(tradePlayerId); + std::shared_ptr tradePartner = getPlayerByID(tradePlayerId); if (!tradePartner || tradePartner == player) { player->sendTextMessage(MESSAGE_FAILURE, "Sorry, not possible."); return; @@ -4196,21 +4187,21 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st return; } - Thing* tradeThing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); + std::shared_ptr tradeThing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); if (!tradeThing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - Item* tradeItem = tradeThing->getItem(); + std::shared_ptr tradeItem = tradeThing->getItem(); if (tradeItem->getID() != itemId || !tradeItem->isPickupable() || tradeItem->hasAttribute(ItemAttribute_t::UNIQUEID)) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) { - if (HouseTile* houseTile = dynamic_cast(tradeItem->getTile())) { - House* house = houseTile->getHouse(); + if (std::shared_ptr houseTile = std::dynamic_pointer_cast(tradeItem->getTile())) { + const auto &house = houseTile->getHouse(); if (house && tradeItem->getRealParent() != player && (!house->isInvited(player) || house->getHouseAccessLevel(player) == HOUSE_GUEST)) { player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE); return; @@ -4238,10 +4229,10 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st return; } - Container* tradeItemContainer = tradeItem->getContainer(); + std::shared_ptr tradeItemContainer = tradeItem->getContainer(); if (tradeItemContainer) { for (const auto &it : tradeItems) { - Item* item = it.first; + std::shared_ptr item = it.first; if (tradeItem == item) { player->sendTextMessage(MESSAGE_TRADE, "This item is already being traded."); return; @@ -4252,7 +4243,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st return; } - Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && container->isHoldingItem(tradeItem)) { player->sendTextMessage(MESSAGE_TRADE, "This item is already being traded."); return; @@ -4260,13 +4251,13 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st } } else { for (const auto &it : tradeItems) { - Item* item = it.first; + std::shared_ptr item = it.first; if (tradeItem == item) { player->sendTextMessage(MESSAGE_TRADE, "This item is already being traded."); return; } - Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && container->isHoldingItem(tradeItem)) { player->sendTextMessage(MESSAGE_TRADE, "This item is already being traded."); return; @@ -4274,7 +4265,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st } } - Container* tradeContainer = tradeItem->getContainer(); + auto tradeContainer = tradeItem->getContainer(); if (tradeContainer && tradeContainer->getItemHoldingCount() + 1 > 100) { player->sendTextMessage(MESSAGE_TRADE, "You can not trade more than 100 items."); return; @@ -4286,7 +4277,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st } if (tradeItemContainer) { - for (Item* containerItem : tradeItemContainer->getItems(true)) { + for (std::shared_ptr containerItem : tradeItemContainer->getItems(true)) { if (containerItem->isStoreItem()) { player->sendTextMessage(MESSAGE_TRADE, "This item cannot be trade."); return; @@ -4305,7 +4296,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st internalStartTrade(player, tradePartner, tradeItem); } -bool Game::internalStartTrade(Player* player, Player* tradePartner, Item* tradeItem) { +bool Game::internalStartTrade(std::shared_ptr player, std::shared_ptr tradePartner, std::shared_ptr tradeItem) { if (player->tradeState != TRADE_NONE && !(player->tradeState == TRADE_ACKNOWLEDGE && player->tradePartner == tradePartner)) { player->sendCancelMessage(RETURNVALUE_YOUAREALREADYTRADING); return false; @@ -4317,7 +4308,6 @@ bool Game::internalStartTrade(Player* player, Player* tradePartner, Item* tradeI player->tradePartner = tradePartner; player->tradeItem = tradeItem; player->tradeState = TRADE_INITIATED; - tradeItem->incrementReferenceCounter(); tradeItems[tradeItem] = player->getID(); player->sendTradeItemRequest(player->getName(), tradeItem, true); @@ -4329,7 +4319,7 @@ bool Game::internalStartTrade(Player* player, Player* tradePartner, Item* tradeI tradePartner->tradeState = TRADE_ACKNOWLEDGE; tradePartner->tradePartner = player; } else { - Item* counterOfferItem = tradePartner->tradeItem; + std::shared_ptr counterOfferItem = tradePartner->tradeItem; player->sendTradeItemRequest(tradePartner->getName(), counterOfferItem, false); tradePartner->sendTradeItemRequest(player->getName(), tradeItem, false); } @@ -4338,7 +4328,7 @@ bool Game::internalStartTrade(Player* player, Player* tradePartner, Item* tradeI } void Game::playerAcceptTrade(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -4347,7 +4337,7 @@ void Game::playerAcceptTrade(uint32_t playerId) { return; } - Player* tradePartner = player->tradePartner; + std::shared_ptr tradePartner = player->tradePartner; if (!tradePartner) { return; } @@ -4360,8 +4350,8 @@ void Game::playerAcceptTrade(uint32_t playerId) { player->setTradeState(TRADE_ACCEPT); if (tradePartner->getTradeState() == TRADE_ACCEPT) { - Item* tradeItem1 = player->tradeItem; - Item* tradeItem2 = tradePartner->tradeItem; + std::shared_ptr tradeItem1 = player->tradeItem; + std::shared_ptr tradeItem2 = tradePartner->tradeItem; if (!g_events().eventPlayerOnTradeAccept(player, tradePartner, tradeItem1, tradeItem2)) { internalCloseTrade(player); return; @@ -4377,13 +4367,11 @@ void Game::playerAcceptTrade(uint32_t playerId) { auto it = tradeItems.find(tradeItem1); if (it != tradeItems.end()) { - ReleaseItem(it->first); tradeItems.erase(it); } it = tradeItems.find(tradeItem2); if (it != tradeItems.end()) { - ReleaseItem(it->first); tradeItems.erase(it); } @@ -4395,8 +4383,8 @@ void Game::playerAcceptTrade(uint32_t playerId) { ret1 = internalRemoveItem(tradeItem1, tradeItem1->getItemCount(), true); ret2 = internalRemoveItem(tradeItem2, tradeItem2->getItemCount(), true); if (ret1 == RETURNVALUE_NOERROR && ret2 == RETURNVALUE_NOERROR) { - Cylinder* cylinder1 = tradeItem1->getParent(); - Cylinder* cylinder2 = tradeItem2->getParent(); + std::shared_ptr cylinder1 = tradeItem1->getParent(); + std::shared_ptr cylinder2 = tradeItem2->getParent(); uint32_t count1 = tradeItem1->getItemCount(); uint32_t count2 = tradeItem2->getItemCount(); @@ -4441,7 +4429,7 @@ void Game::playerAcceptTrade(uint32_t playerId) { } } -std::string Game::getTradeErrorDescription(ReturnValue ret, Item* item) { +std::string Game::getTradeErrorDescription(ReturnValue ret, std::shared_ptr item) { if (item) { if (ret == RETURNVALUE_NOTENOUGHCAPACITY) { std::ostringstream ss; @@ -4473,17 +4461,17 @@ std::string Game::getTradeErrorDescription(ReturnValue ret, Item* item) { } void Game::playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, uint8_t index) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Player* tradePartner = player->tradePartner; + std::shared_ptr tradePartner = player->tradePartner; if (!tradePartner) { return; } - Item* tradeItem; + std::shared_ptr tradeItem; if (lookAtCounterOffer) { tradeItem = tradePartner->getTradeItem(); } else { @@ -4507,17 +4495,17 @@ void Game::playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, uint8_t return; } - Container* tradeContainer = tradeItem->getContainer(); + std::shared_ptr tradeContainer = tradeItem->getContainer(); if (!tradeContainer) { return; } - std::vector containers { tradeContainer }; + std::vector> containers { tradeContainer }; size_t i = 0; while (i < containers.size()) { - const Container* container = containers[i++]; - for (Item* item : container->getItemList()) { - Container* tmpContainer = item->getContainer(); + std::shared_ptr container = containers[i++]; + for (std::shared_ptr item : container->getItemList()) { + std::shared_ptr tmpContainer = item->getContainer(); if (tmpContainer) { containers.push_back(tmpContainer); } @@ -4532,7 +4520,7 @@ void Game::playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, uint8_t } void Game::playerCloseTrade(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -4540,8 +4528,8 @@ void Game::playerCloseTrade(uint32_t playerId) { internalCloseTrade(player); } -void Game::internalCloseTrade(Player* player) { - Player* tradePartner = player->tradePartner; +void Game::internalCloseTrade(std::shared_ptr player) { + std::shared_ptr tradePartner = player->tradePartner; if ((tradePartner && tradePartner->getTradeState() == TRADE_TRANSFER) || player->getTradeState() == TRADE_TRANSFER) { return; } @@ -4549,7 +4537,6 @@ void Game::internalCloseTrade(Player* player) { if (player->getTradeItem()) { auto it = tradeItems.find(player->getTradeItem()); if (it != tradeItems.end()) { - ReleaseItem(it->first); tradeItems.erase(it); } @@ -4567,7 +4554,6 @@ void Game::internalCloseTrade(Player* player) { if (tradePartner->getTradeItem()) { auto it = tradeItems.find(tradePartner->getTradeItem()); if (it != tradeItems.end()) { - ReleaseItem(it->first); tradeItems.erase(it); } @@ -4588,12 +4574,12 @@ void Game::playerBuyItem(uint32_t playerId, uint16_t itemId, uint8_t count, uint return; } - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Npc* merchant = player->getShopOwner(); + std::shared_ptr merchant = player->getShopOwner(); if (!merchant) { return; } @@ -4626,12 +4612,12 @@ void Game::playerSellItem(uint32_t playerId, uint16_t itemId, uint8_t count, uin return; } - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Npc* merchant = player->getShopOwner(); + std::shared_ptr merchant = player->getShopOwner(); if (!merchant) { return; } @@ -4656,7 +4642,7 @@ void Game::playerSellItem(uint32_t playerId, uint16_t itemId, uint8_t count, uin } void Game::playerCloseShop(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -4665,12 +4651,12 @@ void Game::playerCloseShop(uint32_t playerId) { } void Game::playerLookInShop(uint32_t playerId, uint16_t itemId, uint8_t count) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Npc* merchant = player->getShopOwner(); + std::shared_ptr merchant = player->getShopOwner(); if (!merchant) { return; } @@ -4695,12 +4681,12 @@ void Game::playerLookInShop(uint32_t playerId, uint16_t itemId, uint8_t count) { } void Game::playerLookAt(uint32_t playerId, uint16_t itemId, const Position &pos, uint8_t stackPos) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_LOOK); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_LOOK); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -4730,12 +4716,12 @@ void Game::playerLookAt(uint32_t playerId, uint16_t itemId, const Position &pos, } void Game::playerLookInBattleList(uint32_t playerId, uint32_t creatureId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Creature* creature = getCreatureByID(creatureId); + std::shared_ptr creature = getCreatureByID(creatureId); if (!creature) { return; } @@ -4764,8 +4750,8 @@ void Game::playerLookInBattleList(uint32_t playerId, uint32_t creatureId) { g_callbacks().executeCallback(EventCallback_t::playerOnLookInBattleList, &EventCallback::playerOnLookInBattleList, player, creature, lookDistance); } -void Game::playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t itemId, uint8_t stackPos, Item* defaultItem, bool lootAllCorpses, bool autoLoot) { - Player* player = getPlayerByID(playerId); +void Game::playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t itemId, uint8_t stackPos, std::shared_ptr defaultItem, bool lootAllCorpses, bool autoLoot) { + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -4801,9 +4787,9 @@ void Game::playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t item player->setNextActionTask(nullptr); } - Item* item = nullptr; + std::shared_ptr item = nullptr; if (!defaultItem) { - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_FIND_THING); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_FIND_THING); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -4819,7 +4805,7 @@ void Game::playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t item return; } - Container* corpse = nullptr; + std::shared_ptr corpse = nullptr; if (pos.x == 0xffff) { corpse = item->getParent()->getContainer(); if (corpse && corpse->getID() == ITEM_BROWSEFIELD) { @@ -4895,9 +4881,9 @@ void Game::playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t item } } -void Game::playerLootAllCorpses(Player* player, const Position &pos, bool lootAllCorpses) { +void Game::playerLootAllCorpses(std::shared_ptr player, const Position &pos, bool lootAllCorpses) { if (lootAllCorpses) { - Tile* tile = g_game().map.getTile(pos.x, pos.y, pos.z); + std::shared_ptr tile = g_game().map.getTile(pos.x, pos.y, pos.z); if (!tile) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -4905,12 +4891,12 @@ void Game::playerLootAllCorpses(Player* player, const Position &pos, bool lootAl const TileItemVector* itemVector = tile->getItemList(); uint16_t corpses = 0; - for (Item* tileItem : *itemVector) { + for (auto &tileItem : *itemVector) { if (!tileItem) { continue; } - Container* tileCorpse = tileItem->getContainer(); + std::shared_ptr tileCorpse = tileItem->getContainer(); if (!tileCorpse || !tileCorpse->isCorpse() || tileCorpse->hasAttribute(ItemAttribute_t::UNIQUEID) || tileCorpse->hasAttribute(ItemAttribute_t::ACTIONID)) { continue; } @@ -4945,18 +4931,18 @@ void Game::playerLootAllCorpses(Player* player, const Position &pos, bool lootAl } void Game::playerSetLootContainer(uint32_t playerId, ObjectCategory_t category, const Position &pos, uint16_t itemId, uint8_t stackPos) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || pos.x != 0xffff) { return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_USEITEM); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_USEITEM); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; } - Container* container = thing->getContainer(); + std::shared_ptr container = thing->getContainer(); if (!container || (container->getID() == ITEM_GOLD_POUCH && category != OBJECTCATEGORY_GOLD && !g_configManager().getBoolean(TOGGLE_GOLD_POUCH_ALLOW_ANYTHING))) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -4967,10 +4953,10 @@ void Game::playerSetLootContainer(uint32_t playerId, ObjectCategory_t category, return; } - Container* previousContainer = player->setLootContainer(category, container); + std::shared_ptr previousContainer = player->setLootContainer(category, container); player->sendLootContainers(); - Cylinder* parent = container->getParent(); + std::shared_ptr parent = container->getParent(); if (parent) { parent->updateThing(container, container->getID(), container->getItemCount()); } @@ -4984,16 +4970,16 @@ void Game::playerSetLootContainer(uint32_t playerId, ObjectCategory_t category, } void Game::playerClearLootContainer(uint32_t playerId, ObjectCategory_t category) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Container* previousContainer = player->setLootContainer(category, nullptr); + std::shared_ptr previousContainer = player->setLootContainer(category, nullptr); player->sendLootContainers(); if (previousContainer != nullptr) { - Cylinder* parent = previousContainer->getParent(); + std::shared_ptr parent = previousContainer->getParent(); if (parent) { parent->updateThing(previousContainer, previousContainer->getID(), previousContainer->getItemCount()); } @@ -5001,12 +4987,12 @@ void Game::playerClearLootContainer(uint32_t playerId, ObjectCategory_t category } void Game::playerOpenLootContainer(uint32_t playerId, ObjectCategory_t category) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Container* container = player->getLootContainer(category); + std::shared_ptr container = player->getLootContainer(category); if (!container) { return; } @@ -5015,7 +5001,7 @@ void Game::playerOpenLootContainer(uint32_t playerId, ObjectCategory_t category) } void Game::playerSetQuickLootFallback(uint32_t playerId, bool fallback) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5024,7 +5010,7 @@ void Game::playerSetQuickLootFallback(uint32_t playerId, bool fallback) { } void Game::playerQuickLootBlackWhitelist(uint32_t playerId, QuickLootFilter_t filter, const std::vector itemIds) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5037,7 +5023,7 @@ void Game::playerQuickLootBlackWhitelist(uint32_t playerId, QuickLootFilter_t fi * Depot search system ******************************************************************************/ void Game::playerRequestDepotItems(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->isDepotSearchAvailable()) { return; } @@ -5052,7 +5038,7 @@ void Game::playerRequestDepotItems(uint32_t playerId) { } void Game::playerRequestCloseDepotSearch(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->isDepotSearchOpen()) { return; } @@ -5062,7 +5048,7 @@ void Game::playerRequestCloseDepotSearch(uint32_t playerId) { } void Game::playerRequestDepotSearchItem(uint32_t playerId, uint16_t itemId, uint8_t tier) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->isDepotSearchOpen()) { return; } @@ -5077,7 +5063,7 @@ void Game::playerRequestDepotSearchItem(uint32_t playerId, uint16_t itemId, uint } void Game::playerRequestDepotSearchRetrieve(uint32_t playerId, uint16_t itemId, uint8_t tier, uint8_t type) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->isDepotSearchOpenOnItem(itemId)) { return; } @@ -5092,7 +5078,7 @@ void Game::playerRequestDepotSearchRetrieve(uint32_t playerId, uint16_t itemId, } void Game::playerRequestOpenContainerFromDepotSearch(uint32_t playerId, const Position &pos) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->isDepotSearchOpen()) { return; } @@ -5107,7 +5093,7 @@ void Game::playerRequestOpenContainerFromDepotSearch(uint32_t playerId, const Po } void Game::playerCancelAttackAndFollow(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5118,7 +5104,7 @@ void Game::playerCancelAttackAndFollow(uint32_t playerId) { } void Game::playerSetAttackedCreature(uint32_t playerId, uint32_t creatureId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5129,7 +5115,7 @@ void Game::playerSetAttackedCreature(uint32_t playerId, uint32_t creatureId) { return; } - Creature* attackCreature = getCreatureByID(creatureId); + std::shared_ptr attackCreature = getCreatureByID(creatureId); if (!attackCreature) { player->setAttackedCreature(nullptr); player->sendCancelTarget(); @@ -5149,7 +5135,7 @@ void Game::playerSetAttackedCreature(uint32_t playerId, uint32_t creatureId) { } void Game::playerFollowCreature(uint32_t playerId, uint32_t creatureId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5160,7 +5146,7 @@ void Game::playerFollowCreature(uint32_t playerId, uint32_t creatureId) { } void Game::playerSetFightModes(uint32_t playerId, FightMode_t fightMode, bool chaseMode, bool secureMode) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5175,12 +5161,12 @@ void Game::playerRequestAddVip(uint32_t playerId, const std::string &name) { return; } - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Player* vipPlayer = getPlayerByName(name); + std::shared_ptr vipPlayer = getPlayerByName(name); if (!vipPlayer) { uint32_t guid; bool specialVip; @@ -5191,14 +5177,14 @@ void Game::playerRequestAddVip(uint32_t playerId, const std::string &name) { } if (specialVip && !player->hasFlag(PlayerFlags_t::SpecialVIP)) { - player->sendTextMessage(MESSAGE_FAILURE, "You can not add this player."); + player->sendTextMessage(MESSAGE_FAILURE, "You can not add this player->"); return; } player->addVIP(guid, formattedName, VIPSTATUS_OFFLINE); } else { if (vipPlayer->hasFlag(PlayerFlags_t::SpecialVIP) && !player->hasFlag(PlayerFlags_t::SpecialVIP)) { - player->sendTextMessage(MESSAGE_FAILURE, "You can not add this player."); + player->sendTextMessage(MESSAGE_FAILURE, "You can not add this player->"); return; } @@ -5211,7 +5197,7 @@ void Game::playerRequestAddVip(uint32_t playerId, const std::string &name) { } void Game::playerRequestRemoveVip(uint32_t playerId, uint32_t guid) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5220,7 +5206,7 @@ void Game::playerRequestRemoveVip(uint32_t playerId, uint32_t guid) { } void Game::playerRequestEditVip(uint32_t playerId, uint32_t guid, const std::string &description, uint32_t icon, bool notify) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5229,7 +5215,7 @@ void Game::playerRequestEditVip(uint32_t playerId, uint32_t guid, const std::str } void Game::playerApplyImbuement(uint32_t playerId, uint16_t imbuementid, uint8_t slot, bool protectionCharm) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5243,7 +5229,7 @@ void Game::playerApplyImbuement(uint32_t playerId, uint16_t imbuementid, uint8_t return; } - Item* item = player->imbuingItem; + std::shared_ptr item = player->imbuingItem; if (!item) { return; } @@ -5258,7 +5244,7 @@ void Game::playerApplyImbuement(uint32_t playerId, uint16_t imbuementid, uint8_t } void Game::playerClearImbuement(uint32_t playerid, uint8_t slot) { - Player* player = getPlayerByID(playerid); + std::shared_ptr player = getPlayerByID(playerid); if (!player) { return; } @@ -5267,7 +5253,7 @@ void Game::playerClearImbuement(uint32_t playerid, uint8_t slot) { return; } - Item* item = player->imbuingItem; + std::shared_ptr item = player->imbuingItem; if (!item) { return; } @@ -5276,7 +5262,7 @@ void Game::playerClearImbuement(uint32_t playerid, uint8_t slot) { } void Game::playerCloseImbuementWindow(uint32_t playerid) { - Player* player = getPlayerByID(playerid); + std::shared_ptr player = getPlayerByID(playerid); if (!player) { return; } @@ -5286,7 +5272,7 @@ void Game::playerCloseImbuementWindow(uint32_t playerid) { } void Game::playerTurn(uint32_t playerId, Direction dir) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5308,7 +5294,7 @@ void Game::playerRequestOutfit(uint32_t playerId) { return; } - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5317,7 +5303,7 @@ void Game::playerRequestOutfit(uint32_t playerId) { } void Game::playerToggleMount(uint32_t playerId, bool mount) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5330,7 +5316,7 @@ void Game::playerChangeOutfit(uint32_t playerId, Outfit_t outfit, uint8_t isMoun return; } - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5342,7 +5328,7 @@ void Game::playerChangeOutfit(uint32_t playerId, Outfit_t outfit, uint8_t isMoun outfit.lookMount = randomMount->clientId; } - const auto &playerOutfit = Outfits::getInstance().getOutfitByLookType(player->getSex(), outfit.lookType); + const auto playerOutfit = Outfits::getInstance().getOutfitByLookType(player->getSex(), outfit.lookType); if (!playerOutfit) { outfit.lookMount = 0; } @@ -5357,7 +5343,7 @@ void Game::playerChangeOutfit(uint32_t playerId, Outfit_t outfit, uint8_t isMoun return; } - const Tile* playerTile = player->getTile(); + std::shared_ptr playerTile = player->getTile(); if (!playerTile) { return; } @@ -5392,7 +5378,7 @@ void Game::playerChangeOutfit(uint32_t playerId, Outfit_t outfit, uint8_t isMoun } void Game::playerShowQuestLog(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5402,7 +5388,7 @@ void Game::playerShowQuestLog(uint32_t playerId) { } void Game::playerShowQuestLine(uint32_t playerId, uint16_t questId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5412,7 +5398,7 @@ void Game::playerShowQuestLine(uint32_t playerId, uint16_t questId) { } void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type, const std::string &receiver, const std::string &text) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -5460,7 +5446,7 @@ void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type, c 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: @@ -5476,7 +5462,7 @@ void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type, c } } -bool Game::playerSaySpell(Player* player, SpeakClasses type, const std::string &text) { +bool Game::playerSaySpell(std::shared_ptr player, SpeakClasses type, const std::string &text) { if (player->walkExhausted()) { return true; } @@ -5505,13 +5491,13 @@ bool Game::playerSaySpell(Player* player, SpeakClasses type, const std::string & return false; } -void Game::playerWhisper(Player* player, const std::string &text) { +void Game::playerWhisper(std::shared_ptr player, const std::string &text) { SpectatorHashSet spectators; map.getSpectators(spectators, player->getPosition(), false, false, MAP_MAX_CLIENT_VIEW_PORT_X, MAP_MAX_CLIENT_VIEW_PORT_X, MAP_MAX_CLIENT_VIEW_PORT_Y, MAP_MAX_CLIENT_VIEW_PORT_Y); - // send to client - for (Creature* spectator : spectators) { - if (Player* spectatorPlayer = spectator->getPlayer()) { + // Send to client + for (auto spectator : spectators) { + if (auto spectatorPlayer = spectator->getPlayer()) { if (!Position::areInRange<1, 1>(player->getPosition(), spectatorPlayer->getPosition())) { spectatorPlayer->sendCreatureSay(player, TALKTYPE_WHISPER, "pspsps"); } else { @@ -5521,12 +5507,12 @@ void Game::playerWhisper(Player* player, const std::string &text) { } // event method - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { spectator->onCreatureSay(player, TALKTYPE_WHISPER, text); } } -bool Game::playerYell(Player* player, const std::string &text) { +bool Game::playerYell(std::shared_ptr player, const std::string &text) { if (player->getLevel() == 1) { player->sendTextMessage(MESSAGE_FAILURE, "You may not yell as long as you are on level 1."); return false; @@ -5538,7 +5524,7 @@ bool Game::playerYell(Player* player, const std::string &text) { } if (player->getAccountType() < account::AccountType::ACCOUNT_TYPE_GAMEMASTER) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_YELLTICKS, 30000, 0); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_YELLTICKS, 30000, 0); player->addCondition(condition); } @@ -5546,8 +5532,8 @@ bool Game::playerYell(Player* player, const std::string &text) { return true; } -bool Game::playerSpeakTo(Player* player, SpeakClasses type, const std::string &receiver, const std::string &text) { - Player* toPlayer = getPlayerByName(receiver); +bool Game::playerSpeakTo(std::shared_ptr player, SpeakClasses type, const std::string &receiver, const std::string &text) { + std::shared_ptr toPlayer = getPlayerByName(receiver); if (!toPlayer) { player->sendTextMessage(MESSAGE_FAILURE, "A player with this name is not online."); return false; @@ -5572,7 +5558,7 @@ bool Game::playerSpeakTo(Player* player, SpeakClasses type, const std::string &r return true; } -void Game::playerSpeakToNpc(Player* player, const std::string &text) { +void Game::playerSpeakToNpc(std::shared_ptr player, const std::string &text) { if (player == nullptr) { g_logger().error("[Game::playerSpeakToNpc] - Player is nullptr"); return; @@ -5586,7 +5572,7 @@ void Game::playerSpeakToNpc(Player* player, const std::string &text) { SpectatorHashSet spectators; map.getSpectators(spectators, player->getPosition()); - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { if (spectator->getNpc()) { spectator->onCreatureSay(player, TALKTYPE_PRIVATE_PN, text); } @@ -5608,12 +5594,12 @@ bool Game::isSightClear(const Position &fromPos, const Position &toPos, bool flo return map.isSightClear(fromPos, toPos, floorCheck); } -bool Game::internalCreatureTurn(Creature* creature, Direction dir) { +bool Game::internalCreatureTurn(std::shared_ptr creature, Direction dir) { if (creature->getDirection() == dir) { return false; } - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { player->cancelPush(); } creature->setDirection(dir); @@ -5621,8 +5607,8 @@ bool Game::internalCreatureTurn(Creature* creature, Direction dir) { // Send to client SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true, true); - for (Creature* spectator : spectators) { - Player* tmpPlayer = spectator->getPlayer(); + for (auto spectator : spectators) { + auto tmpPlayer = spectator->getPlayer(); if (!tmpPlayer) { continue; } @@ -5631,7 +5617,7 @@ bool Game::internalCreatureTurn(Creature* creature, Direction dir) { return true; } -bool Game::internalCreatureSay(Creature* creature, SpeakClasses type, const std::string &text, bool ghostMode, SpectatorHashSet* spectatorsPtr /* = nullptr*/, const Position* pos /* = nullptr*/) { +bool Game::internalCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text, bool ghostMode, SpectatorHashSet* spectatorsPtr /* = nullptr*/, const Position* pos /* = nullptr*/) { if (text.empty()) { return false; } @@ -5656,9 +5642,9 @@ bool Game::internalCreatureSay(Creature* creature, SpeakClasses type, const std: spectators = (*spectatorsPtr); } - // send to client - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + // Send to client + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { if (!ghostMode || tmpPlayer->canSeeCreature(creature)) { tmpPlayer->sendCreatureSay(creature, type, text, pos); } @@ -5666,7 +5652,7 @@ bool Game::internalCreatureSay(Creature* creature, SpeakClasses type, const std: } // event method - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { spectator->onCreatureSay(creature, type, text); if (creature != spectator) { g_events().eventCreatureOnHear(spectator, creature, text, type); @@ -5677,7 +5663,7 @@ bool Game::internalCreatureSay(Creature* creature, SpeakClasses type, const std: } void Game::checkCreatureWalk(uint32_t creatureId) { - Creature* creature = getCreatureByID(creatureId); + std::shared_ptr creature = getCreatureByID(creatureId); if (creature && creature->getHealth() > 0) { creature->onCreatureWalk(); cleanup(); @@ -5685,20 +5671,20 @@ void Game::checkCreatureWalk(uint32_t creatureId) { } void Game::updateCreatureWalk(uint32_t creatureId) { - Creature* creature = getCreatureByID(creatureId); + std::shared_ptr creature = getCreatureByID(creatureId); if (creature && creature->getHealth() > 0) { creature->goToFollowCreature(); } } void Game::checkCreatureAttack(uint32_t creatureId) { - Creature* creature = getCreatureByID(creatureId); + std::shared_ptr creature = getCreatureByID(creatureId); if (creature && creature->getHealth() > 0) { creature->onAttacking(0); } } -void Game::addCreatureCheck(Creature* creature) { +void Game::addCreatureCheck(std::shared_ptr creature) { creature->creatureCheck = true; if (creature->inCheckCreaturesVector) { @@ -5708,10 +5694,9 @@ void Game::addCreatureCheck(Creature* creature) { creature->inCheckCreaturesVector = true; checkCreatureLists[uniform_random(0, EVENT_CREATURECOUNT - 1)].push_back(creature); - creature->incrementReferenceCounter(); } -void Game::removeCreatureCheck(Creature* creature) { +void Game::removeCreatureCheck(std::shared_ptr creature) { if (creature->inCheckCreaturesVector) { creature->creatureCheck = false; } @@ -5723,7 +5708,7 @@ void Game::checkCreatures(size_t index) { auto &checkCreatureList = checkCreatureLists[index]; size_t it = 0, end = checkCreatureList.size(); while (it < end) { - Creature* creature = checkCreatureList[it]; + std::shared_ptr creature = checkCreatureList[it]; if (creature && creature->creatureCheck) { if (creature->getHealth() > 0) { creature->onThink(EVENT_CREATURE_THINK_INTERVAL); @@ -5735,7 +5720,6 @@ void Game::checkCreatures(size_t index) { ++it; } else { creature->inCheckCreaturesVector = false; - ReleaseCreature(creature); checkCreatureList[it] = checkCreatureList.back(); checkCreatureList.pop_back(); @@ -5745,57 +5729,67 @@ void Game::checkCreatures(size_t index) { cleanup(); } -void Game::changeSpeed(Creature* creature, int32_t varSpeedDelta) { +void Game::changeSpeed(std::shared_ptr creature, int32_t varSpeedDelta) { int32_t varSpeed = creature->getSpeed() - creature->getBaseSpeed(); varSpeed += varSpeedDelta; creature->setSpeed(varSpeed); - // send to clients + // Send to clients SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), false, true); - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendChangeSpeed(creature, creature->getStepSpeed()); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); + if (!player) { + continue; + } + + player->sendChangeSpeed(creature, creature->getStepSpeed()); } } -void Game::setCreatureSpeed(Creature* creature, int32_t speed) { +void Game::setCreatureSpeed(std::shared_ptr creature, int32_t speed) { creature->setBaseSpeed(static_cast(speed)); - // send creature speed to client + // Send creature speed to client SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), false, true); - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendChangeSpeed(creature, creature->getStepSpeed()); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); + if (!player) { + continue; + } + + player->sendChangeSpeed(creature, creature->getStepSpeed()); } } -void Game::changePlayerSpeed(Player &player, int32_t varSpeedDelta) { - int32_t varSpeed = player.getSpeed() - player.getBaseSpeed(); +void Game::changePlayerSpeed(const std::shared_ptr &player, int32_t varSpeedDelta) { + int32_t varSpeed = player->getSpeed() - player->getBaseSpeed(); varSpeed += varSpeedDelta; - player.setSpeed(varSpeed); + player->setSpeed(varSpeed); // Send new player speed to the spectators SpectatorHashSet spectators; - map.getSpectators(spectators, player.getPosition(), false, true); - for (Creature* creatureSpectator : spectators) { + map.getSpectators(spectators, player->getPosition(), false, true); + for (std::shared_ptr creatureSpectator : spectators) { if (creatureSpectator == nullptr) { g_logger().error("[Game::changePlayerSpeed] - Creature spectator is nullptr"); continue; } - const Player* playerSpectator = creatureSpectator->getPlayer(); + std::shared_ptr playerSpectator = creatureSpectator->getPlayer(); if (playerSpectator == nullptr) { g_logger().error("[Game::changePlayerSpeed] - Player spectator is nullptr"); continue; } - playerSpectator->sendChangeSpeed(&player, player.getStepSpeed()); + playerSpectator->sendChangeSpeed(player, player->getStepSpeed()); } } -void Game::internalCreatureChangeOutfit(Creature* creature, const Outfit_t &outfit) { +void Game::internalCreatureChangeOutfit(std::shared_ptr creature, const Outfit_t &outfit) { if (!g_events().eventCreatureOnChangeOutfit(creature, outfit)) { return; } @@ -5810,42 +5804,62 @@ void Game::internalCreatureChangeOutfit(Creature* creature, const Outfit_t &outf return; } - // send to clients + // Send to clients SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true, true); - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendCreatureChangeOutfit(creature, outfit); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); + if (!player) { + continue; + } + + player->sendCreatureChangeOutfit(creature, outfit); } } -void Game::internalCreatureChangeVisible(Creature* creature, bool visible) { - // send to clients +void Game::internalCreatureChangeVisible(std::shared_ptr creature, bool visible) { + // Send to clients SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true, true); - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendCreatureChangeVisible(creature, visible); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); + if (!player) { + continue; + } + + player->sendCreatureChangeVisible(creature, visible); } } -void Game::changeLight(const Creature* creature) { - // send to clients +void Game::changeLight(std::shared_ptr creature) { + // Send to clients SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true, true); - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendCreatureLight(creature); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); + if (!player) { + continue; + } + + player->sendCreatureLight(creature); } } -void Game::updateCreatureIcon(const Creature* creature) { - // send to clients +void Game::updateCreatureIcon(std::shared_ptr creature) { + // Send to clients SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true, true); - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendCreatureIcon(creature); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); + if (!player) { + continue; + } + + player->sendCreatureIcon(creature); } } -void Game::reloadCreature(const Creature* creature) { +void Game::reloadCreature(std::shared_ptr creature) { if (!creature) { g_logger().error("[{}] Creature is nullptr", __FUNCTION__); return; @@ -5853,8 +5867,8 @@ void Game::reloadCreature(const Creature* creature) { SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), false, true); - for (Creature* spectator : spectators) { - Player* tmpPlayer = spectator->getPlayer(); + for (auto spectator : spectators) { + auto tmpPlayer = spectator->getPlayer(); if (!tmpPlayer) { continue; } @@ -5862,15 +5876,15 @@ void Game::reloadCreature(const Creature* creature) { } } -void Game::sendSingleSoundEffect(const Position &pos, SoundEffect_t soundId, Creature* actor /* = nullptr*/) { +void Game::sendSingleSoundEffect(const Position &pos, SoundEffect_t soundId, std::shared_ptr actor /* = nullptr*/) { if (soundId == SoundEffect_t::SILENCE) { return; } SpectatorHashSet spectators; map.getSpectators(spectators, pos, false, true); - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { SourceEffect_t source = SourceEffect_t::CREATURES; if (!actor || actor->getNpc()) { source = SourceEffect_t::GLOBAL; @@ -5885,7 +5899,7 @@ void Game::sendSingleSoundEffect(const Position &pos, SoundEffect_t soundId, Cre } } -void Game::sendDoubleSoundEffect(const Position &pos, SoundEffect_t mainSoundEffect, SoundEffect_t secondarySoundEffect, Creature* actor /* = nullptr*/) { +void Game::sendDoubleSoundEffect(const Position &pos, SoundEffect_t mainSoundEffect, SoundEffect_t secondarySoundEffect, std::shared_ptr actor /* = nullptr*/) { if (secondarySoundEffect == SoundEffect_t::SILENCE) { sendSingleSoundEffect(pos, mainSoundEffect, actor); return; @@ -5893,8 +5907,8 @@ void Game::sendDoubleSoundEffect(const Position &pos, SoundEffect_t mainSoundEff SpectatorHashSet spectators; map.getSpectators(spectators, pos, false, true); - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { SourceEffect_t source = SourceEffect_t::CREATURES; if (!actor || actor->getNpc()) { source = SourceEffect_t::GLOBAL; @@ -5909,7 +5923,7 @@ void Game::sendDoubleSoundEffect(const Position &pos, SoundEffect_t mainSoundEff } } -bool Game::combatBlockHit(CombatDamage &damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field) { +bool Game::combatBlockHit(CombatDamage &damage, std::shared_ptr attacker, std::shared_ptr target, bool checkDefense, bool checkArmor, bool field) { if (damage.primary.type == COMBAT_NONE && damage.secondary.type == COMBAT_NONE) { return true; } @@ -5923,7 +5937,7 @@ bool Game::combatBlockHit(CombatDamage &damage, Creature* attacker, Creature* ta } // Skill dodge (ruse) - if (const Player* targetPlayer = target->getPlayer()) { + if (std::shared_ptr targetPlayer = target->getPlayer()) { if (auto playerArmor = targetPlayer->getInventoryItem(CONST_SLOT_ARMOR); playerArmor != nullptr && playerArmor->getTier()) { double_t chance = playerArmor->getDodgeChance(); @@ -5948,7 +5962,7 @@ bool Game::combatBlockHit(CombatDamage &damage, Creature* attacker, Creature* ta CombatParams damageReflectedParams; BlockType_t primaryBlockType, secondaryBlockType; - Player* targetPlayer = target->getPlayer(); + std::shared_ptr targetPlayer = target->getPlayer(); if (damage.primary.type != COMBAT_NONE) { // Damage reflection primary @@ -6094,10 +6108,10 @@ bool Game::combatBlockHit(CombatDamage &damage, Creature* attacker, Creature* ta return (primaryBlockType != BLOCK_NONE) && (secondaryBlockType != BLOCK_NONE); } -void Game::combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColor_t &color, uint16_t &effect) { +void Game::combatGetTypeInfo(CombatType_t combatType, std::shared_ptr target, TextColor_t &color, uint16_t &effect) { switch (combatType) { case COMBAT_PHYSICALDAMAGE: { - Item* splash = nullptr; + std::shared_ptr splash = nullptr; switch (target->getRace()) { case RACE_VENOM: color = TEXTCOLOR_LIGHTGREEN; @@ -6107,7 +6121,7 @@ void Game::combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColo case RACE_BLOOD: color = TEXTCOLOR_RED; effect = CONST_ME_DRAWBLOOD; - if (const Tile* tile = target->getTile()) { + if (std::shared_ptr tile = target->getTile()) { if (!tile->hasFlag(TILESTATE_PROTECTIONZONE)) { splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_BLOOD); } @@ -6205,7 +6219,7 @@ void Game::combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColo } // Hazard combat helpers -void Game::handleHazardSystemAttack(CombatDamage &damage, Player* player, const Monster* monster, bool isPlayerAttacker) { +void Game::handleHazardSystemAttack(CombatDamage &damage, std::shared_ptr player, std::shared_ptr monster, bool isPlayerAttacker) { if (damage.primary.value != 0 && monster->getHazard()) { if (isPlayerAttacker) { player->parseAttackDealtHazardSystem(damage, monster); @@ -6215,9 +6229,9 @@ void Game::handleHazardSystemAttack(CombatDamage &damage, Player* player, const } } -void Game::notifySpectators(const SpectatorHashSet &spectators, const Position &targetPos, Player* attackerPlayer, Monster* targetMonster) { +void Game::notifySpectators(const SpectatorHashSet &spectators, const Position &targetPos, std::shared_ptr attackerPlayer, std::shared_ptr targetMonster) { if (!spectators.empty()) { - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { if (!spectator) { continue; } @@ -6244,7 +6258,7 @@ void Game::notifySpectators(const SpectatorHashSet &spectators, const Position & } // Wheel of destiny combat helpers -void Game::applyWheelOfDestinyHealing(CombatDamage &damage, Player* attackerPlayer, const Creature* target) { +void Game::applyWheelOfDestinyHealing(CombatDamage &damage, std::shared_ptr attackerPlayer, std::shared_ptr target) { damage.primary.value += (damage.primary.value * damage.healingMultiplier) / 100.; if (attackerPlayer) { @@ -6267,7 +6281,7 @@ void Game::applyWheelOfDestinyHealing(CombatDamage &damage, Player* attackerPlay } } -void Game::applyWheelOfDestinyEffectsToDamage(CombatDamage &damage, const Player* attackerPlayer, const Creature* target) const { +void Game::applyWheelOfDestinyEffectsToDamage(CombatDamage &damage, std::shared_ptr attackerPlayer, std::shared_ptr target) const { // If damage is 0, it means the target is immune to the damage type, or that we missed. if (damage.primary.value == 0 && damage.secondary.value == 0) { return; @@ -6300,11 +6314,11 @@ void Game::applyWheelOfDestinyEffectsToDamage(CombatDamage &damage, const Player } } -int32_t Game::applyHealthChange(CombatDamage &damage, const Creature* target) const { +int32_t Game::applyHealthChange(CombatDamage &damage, std::shared_ptr target) const { int32_t targetHealth = target->getHealth(); // Wheel of destiny (Gift of Life) - if (const Player* targetPlayer = target->getPlayer()) { + if (std::shared_ptr targetPlayer = target->getPlayer()) { if (targetPlayer->wheel()->getInstant("Gift of Life") && targetPlayer->wheel()->getGiftOfCooldown() == 0 && (damage.primary.value + damage.secondary.value) >= targetHealth) { int32_t overkillMultiplier = (damage.primary.value + damage.secondary.value) - targetHealth; overkillMultiplier = (overkillMultiplier * 100) / targetPlayer->getMaxHealth(); @@ -6325,7 +6339,7 @@ int32_t Game::applyHealthChange(CombatDamage &damage, const Creature* target) co return targetHealth; } -bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage &damage, bool isEvent /*= false*/) { +bool Game::combatChangeHealth(std::shared_ptr attacker, std::shared_ptr target, CombatDamage &damage, bool isEvent /*= false*/) { using namespace std; const Position &targetPos = target->getPosition(); if (damage.primary.value > 0) { @@ -6333,20 +6347,20 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage return false; } - Player* attackerPlayer; + std::shared_ptr attackerPlayer; if (attacker) { attackerPlayer = attacker->getPlayer(); } else { attackerPlayer = nullptr; } - Player* targetPlayer = target->getPlayer(); + auto targetPlayer = target->getPlayer(); if (attackerPlayer && targetPlayer && attackerPlayer->getSkull() == SKULL_BLACK && attackerPlayer->getSkullClient(targetPlayer) == SKULL_NONE) { return false; } if (damage.origin != ORIGIN_NONE) { - const auto &events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE); + const auto events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE); if (!events.empty()) { for (const auto creatureEvent : events) { creatureEvent->executeHealthChange(target, attacker, damage); @@ -6369,7 +6383,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage } // Party hunt analyzer - if (Party* party = attackerPlayer ? attackerPlayer->getParty() : nullptr) { + if (auto party = attackerPlayer ? attackerPlayer->getParty() : nullptr) { party->addPlayerHealing(attackerPlayer, realHealthChange); } @@ -6387,9 +6401,8 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage SpectatorHashSet spectators; map.getSpectators(spectators, targetPos, false, true); - for (Creature* spectator : spectators) { - Player* tmpPlayer = spectator->getPlayer(); - + for (auto spectator : spectators) { + auto tmpPlayer = spectator->getPlayer(); if (!tmpPlayer) { continue; } @@ -6441,14 +6454,14 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage return true; } - Player* attackerPlayer; + std::shared_ptr attackerPlayer; if (attacker) { attackerPlayer = attacker->getPlayer(); } else { attackerPlayer = nullptr; } - Player* targetPlayer = target->getPlayer(); + auto targetPlayer = target->getPlayer(); if (attackerPlayer && targetPlayer && attackerPlayer->getSkull() == SKULL_BLACK && attackerPlayer->getSkullClient(targetPlayer) == SKULL_NONE) { return false; } @@ -6459,14 +6472,14 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage damage.primary.value = std::abs(damage.primary.value); damage.secondary.value = std::abs(damage.secondary.value); - Monster* targetMonster; + std::shared_ptr targetMonster; if (target && target->getMonster()) { targetMonster = target->getMonster(); } else { targetMonster = nullptr; } - const Monster* attackerMonster; + std::shared_ptr attackerMonster; if (attacker && attacker->getMonster()) { attackerMonster = attacker->getMonster(); } else { @@ -6480,9 +6493,9 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage int32_t distanceY = Position::getDistanceY(targetPos, attackerPos); int32_t damageX = attackerPlayer->getPerfectShotDamage(distanceX, true); int32_t damageY = attackerPlayer->getPerfectShotDamage(distanceY, true); - Item* item = attackerPlayer->getWeapon(); + std::shared_ptr item = attackerPlayer->getWeapon(); if (item && item->getWeaponType() == WEAPON_DISTANCE) { - Item* quiver = attackerPlayer->getInventoryItem(CONST_SLOT_RIGHT); + std::shared_ptr quiver = attackerPlayer->getInventoryItem(CONST_SLOT_RIGHT); if (quiver && quiver->getWeaponType()) { if (quiver->getPerfectShotRange() == distanceX) { damageX -= quiver->getPerfectShotDamage(); @@ -6576,7 +6589,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage } if (manaDamage != 0) { if (damage.origin != ORIGIN_NONE) { - const auto &events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); + const auto events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); if (!events.empty()) { for (const auto creatureEvent : events) { creatureEvent->executeManaChange(target, attacker, damage); @@ -6604,12 +6617,12 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage message.primary.value = manaDamage; message.primary.color = TEXTCOLOR_BLUE; - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { if (!spectator) { continue; } - Player* tmpPlayer = spectator->getPlayer(); + std::shared_ptr tmpPlayer = spectator->getPlayer(); if (!tmpPlayer) { continue; } @@ -6674,7 +6687,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage } if (damage.origin != ORIGIN_NONE) { - const auto &events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE); + const auto events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE); if (!events.empty()) { for (const auto creatureEvent : events) { creatureEvent->executeHealthChange(target, attacker, damage); @@ -6746,12 +6759,12 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage return true; } -void Game::updatePlayerPartyHuntAnalyzer(const CombatDamage &damage, const Player* player) const { +void Game::updatePlayerPartyHuntAnalyzer(const CombatDamage &damage, std::shared_ptr player) const { if (!player) { return; } - if (Party* party = player->getParty()) { + if (auto party = player->getParty()) { if (damage.primary.value != 0) { party->addPlayerDamage(player, damage.primary.value); } @@ -6762,8 +6775,8 @@ void Game::updatePlayerPartyHuntAnalyzer(const CombatDamage &damage, const Playe } void Game::sendDamageMessageAndEffects( - const Creature* attacker, Creature* target, const CombatDamage &damage, - const Position &targetPos, Player* attackerPlayer, Player* targetPlayer, + std::shared_ptr attacker, std::shared_ptr target, const CombatDamage &damage, + const Position &targetPos, std::shared_ptr attackerPlayer, std::shared_ptr targetPlayer, TextMessage &message, const SpectatorHashSet &spectators, int32_t realDamage ) { message.primary.value = damage.primary.value; @@ -6781,8 +6794,8 @@ bool Game::shouldSendMessage(const TextMessage &message) const { } void Game::sendMessages( - const Creature* attacker, const Creature* target, const CombatDamage &damage, - const Position &targetPos, Player* attackerPlayer, Player* targetPlayer, + std::shared_ptr attacker, std::shared_ptr target, const CombatDamage &damage, + const Position &targetPos, std::shared_ptr attackerPlayer, std::shared_ptr targetPlayer, TextMessage &message, const SpectatorHashSet &spectators, int32_t realDamage ) const { if (attackerPlayer) { @@ -6811,9 +6824,9 @@ void Game::sendMessages( std::string spectatorMessage; - for (Creature* spectator : spectators) { - Player* tmpPlayer = spectator->getPlayer(); - if (tmpPlayer->getPosition().z != targetPos.z) { + for (std::shared_ptr spectator : spectators) { + std::shared_ptr tmpPlayer = spectator->getPlayer(); + if (!tmpPlayer || tmpPlayer->getPosition().z != targetPos.z) { continue; } @@ -6829,8 +6842,8 @@ void Game::sendMessages( } void Game::buildMessageAsSpectator( - const Creature* attacker, const Creature* target, const CombatDamage &damage, - const Player* targetPlayer, TextMessage &message, std::stringstream &ss, + std::shared_ptr attacker, std::shared_ptr target, const CombatDamage &damage, + std::shared_ptr targetPlayer, TextMessage &message, std::stringstream &ss, const std::string &damageString, std::string &spectatorMessage ) const { if (spectatorMessage.empty()) { @@ -6860,8 +6873,8 @@ void Game::buildMessageAsSpectator( } void Game::buildMessageAsTarget( - const Creature* attacker, const CombatDamage &damage, const Player* attackerPlayer, - const Player* targetPlayer, TextMessage &message, std::stringstream &ss, + std::shared_ptr attacker, const CombatDamage &damage, std::shared_ptr attackerPlayer, + std::shared_ptr targetPlayer, TextMessage &message, std::stringstream &ss, const std::string &damageString ) const { ss.str({}); @@ -6881,7 +6894,7 @@ void Game::buildMessageAsTarget( } void Game::buildMessageAsAttacker( - const Creature* target, const CombatDamage &damage, TextMessage &message, + std::shared_ptr target, const CombatDamage &damage, TextMessage &message, std::stringstream &ss, const std::string &damageString ) const { ss.str({}); @@ -6897,7 +6910,7 @@ void Game::buildMessageAsAttacker( } void Game::sendEffects( - Creature* target, const CombatDamage &damage, const Position &targetPos, TextMessage &message, + std::shared_ptr target, const CombatDamage &damage, const Position &targetPos, TextMessage &message, const SpectatorHashSet &spectators ) { uint16_t hitEffect; @@ -6917,7 +6930,7 @@ void Game::sendEffects( } void Game::applyCharmRune( - const Monster* targetMonster, Player* attackerPlayer, Creature* target, const int32_t &realDamage + std::shared_ptr targetMonster, std::shared_ptr attackerPlayer, std::shared_ptr target, const int32_t &realDamage ) const { if (!targetMonster || !attackerPlayer) { return; @@ -6935,7 +6948,7 @@ void Game::applyCharmRune( // Mana leech void Game::applyManaLeech( - Player* attackerPlayer, const Monster* targetMonster, Creature* target, const CombatDamage &damage, const int32_t &realDamage + std::shared_ptr attackerPlayer, std::shared_ptr targetMonster, std::shared_ptr target, const CombatDamage &damage, const int32_t &realDamage ) const { // Wheel of destiny bonus - mana leech chance and amount auto wheelLeechChance = attackerPlayer->wheel()->checkDrainBodyLeech(target, SKILL_MANA_LEECH_CHANCE); @@ -6968,7 +6981,7 @@ void Game::applyManaLeech( // Life leech void Game::applyLifeLeech( - Player* attackerPlayer, const Monster* targetMonster, Creature* target, const CombatDamage &damage, const int32_t &realDamage + std::shared_ptr attackerPlayer, std::shared_ptr targetMonster, std::shared_ptr target, const CombatDamage &damage, const int32_t &realDamage ) const { // Wheel of destiny bonus - life leech chance and amount auto wheelLeechChance = attackerPlayer->wheel()->checkDrainBodyLeech(target, SKILL_LIFE_LEECH_CHANCE); @@ -6981,7 +6994,7 @@ void Game::applyLifeLeech( if (targetMonster) { if (uint16_t playerCharmRaceidVamp = attackerPlayer->parseRacebyCharm(CHARM_VAMP, false, 0); playerCharmRaceidVamp != 0 && playerCharmRaceidVamp == targetMonster->getRaceId()) { - if (const auto &lifec = g_iobestiary().getBestiaryCharm(CHARM_VAMP)) { + if (const auto lifec = g_iobestiary().getBestiaryCharm(CHARM_VAMP)) { lifeSkill += lifec->percent; } } @@ -7002,24 +7015,24 @@ int32_t Game::calculateLeechAmount(const int32_t &realDamage, const uint16_t &sk return std::clamp(static_cast(std::lround(intermediateResult)), 0, realDamage); } -bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage &damage) { +bool Game::combatChangeMana(std::shared_ptr attacker, std::shared_ptr target, CombatDamage &damage) { const Position &targetPos = target->getPosition(); auto manaChange = damage.primary.value + damage.secondary.value; if (manaChange > 0) { - Player* attackerPlayer; + std::shared_ptr attackerPlayer; if (attacker) { attackerPlayer = attacker->getPlayer(); } else { attackerPlayer = nullptr; } - Player* targetPlayer = target->getPlayer(); + auto targetPlayer = target->getPlayer(); if (attackerPlayer && targetPlayer && attackerPlayer->getSkull() == SKULL_BLACK && attackerPlayer->getSkullClient(targetPlayer) == SKULL_NONE) { return false; } if (damage.origin != ORIGIN_NONE) { - const auto &events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); + const auto events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); if (!events.empty()) { for (const auto creatureEvent : events) { creatureEvent->executeManaChange(target, attacker, damage); @@ -7058,9 +7071,8 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage & SpectatorHashSet spectators; map.getSpectators(spectators, targetPos, false, true); - for (Creature* spectator : spectators) { - Player* tmpPlayer = spectator->getPlayer(); - + for (auto spectator : spectators) { + auto tmpPlayer = spectator->getPlayer(); if (!tmpPlayer) { continue; } @@ -7092,14 +7104,14 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage & return false; } - Player* attackerPlayer; + std::shared_ptr attackerPlayer; if (attacker) { attackerPlayer = attacker->getPlayer(); } else { attackerPlayer = nullptr; } - Player* targetPlayer = target->getPlayer(); + auto targetPlayer = target->getPlayer(); if (attackerPlayer && targetPlayer && attackerPlayer->getSkull() == SKULL_BLACK && attackerPlayer->getSkullClient(targetPlayer) == SKULL_NONE) { return false; } @@ -7116,7 +7128,7 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage & } if (damage.origin != ORIGIN_NONE) { - const auto &events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); + const auto events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); if (!events.empty()) { for (const auto creatureEvent : events) { creatureEvent->executeManaChange(target, attacker, damage); @@ -7158,9 +7170,8 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage & SpectatorHashSet spectators; map.getSpectators(spectators, targetPos, false, true); - for (Creature* spectator : spectators) { - Player* tmpPlayer = spectator->getPlayer(); - + for (auto spectator : spectators) { + auto tmpPlayer = spectator->getPlayer(); if (!tmpPlayer) { continue; } @@ -7207,49 +7218,49 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage & return true; } -void Game::addCreatureHealth(const Creature* target) { +void Game::addCreatureHealth(std::shared_ptr target) { SpectatorHashSet spectators; map.getSpectators(spectators, target->getPosition(), true, true); addCreatureHealth(spectators, target); } -void Game::addCreatureHealth(const SpectatorHashSet &spectators, const Creature* target) { +void Game::addCreatureHealth(const SpectatorHashSet &spectators, std::shared_ptr target) { uint8_t healthPercent = std::ceil((static_cast(target->getHealth()) / std::max(target->getMaxHealth(), 1)) * 100); - if (const Player* targetPlayer = target->getPlayer()) { - if (Party* party = targetPlayer->getParty()) { + if (std::shared_ptr targetPlayer = target->getPlayer()) { + if (std::shared_ptr party = targetPlayer->getParty()) { party->updatePlayerHealth(targetPlayer, target, healthPercent); } - } else if (const Creature* master = target->getMaster()) { - if (const Player* masterPlayer = master->getPlayer()) { - if (Party* party = masterPlayer->getParty()) { + } else if (std::shared_ptr master = target->getMaster()) { + if (std::shared_ptr masterPlayer = master->getPlayer()) { + if (std::shared_ptr party = masterPlayer->getParty()) { party->updatePlayerHealth(masterPlayer, target, healthPercent); } } } - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (std::shared_ptr spectator : spectators) { + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendCreatureHealth(target); } } } -void Game::addPlayerMana(const Player* target) { - if (Party* party = target->getParty()) { +void Game::addPlayerMana(std::shared_ptr target) { + if (std::shared_ptr party = target->getParty()) { uint8_t manaPercent = std::ceil((static_cast(target->getMana()) / std::max(target->getMaxMana(), 1)) * 100); party->updatePlayerMana(target, manaPercent); } } -void Game::addPlayerVocation(const Player* target) { - if (Party* party = target->getParty()) { +void Game::addPlayerVocation(std::shared_ptr target) { + if (auto party = target->getParty()) { party->updatePlayerVocation(target); } SpectatorHashSet spectators; map.getSpectators(spectators, target->getPosition(), true, true); - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendPlayerVocation(target); } } @@ -7262,8 +7273,8 @@ void Game::addMagicEffect(const Position &pos, uint16_t effect) { } void Game::addMagicEffect(const SpectatorHashSet &spectators, const Position &pos, uint16_t effect) { - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendMagicEffect(pos, effect); } } @@ -7276,8 +7287,8 @@ void Game::removeMagicEffect(const Position &pos, uint16_t effect) { } void Game::removeMagicEffect(const SpectatorHashSet &spectators, const Position &pos, uint16_t effect) { - for (Creature* spectator : spectators) { - if (const Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (const auto tmpPlayer = spectator->getPlayer()) { tmpPlayer->removeMagicEffect(pos, effect); } } @@ -7291,8 +7302,8 @@ void Game::addDistanceEffect(const Position &fromPos, const Position &toPos, uin } void Game::addDistanceEffect(const SpectatorHashSet &spectators, const Position &fromPos, const Position &toPos, uint16_t effect) { - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendDistanceShoot(fromPos, toPos, effect); } } @@ -7408,32 +7419,19 @@ void Game::shutdown() { ConnectionManager::getInstance().closeAll(); + g_luaEnvironment().collectGarbage(); + g_logger().info("Done!"); } void Game::cleanup() { - // free memory - for (auto creature : ToReleaseCreatures) { - creature->decrementReferenceCounter(); - } - ToReleaseCreatures.clear(); - - for (auto item : ToReleaseItems) { - item->decrementReferenceCounter(); - } - ToReleaseItems.clear(); -} - -void Game::ReleaseCreature(Creature* creature) { - ToReleaseCreatures.push_back(creature); -} - -void Game::ReleaseItem(Item* item) { - if (!item) { - return; + for (auto it = browseFields.begin(); it != browseFields.end();) { + if (it->second.expired()) { + it = browseFields.erase(it); + } else { + ++it; + } } - - ToReleaseItems.push_back(item); } void Game::addBestiaryList(uint16_t raceid, std::string name) { @@ -7452,45 +7450,59 @@ void Game::broadcastMessage(const std::string &text, MessageClasses type) const } } -void Game::updateCreatureWalkthrough(const Creature* creature) { - // send to clients +void Game::updateCreatureWalkthrough(std::shared_ptr creature) { + // Send to clients SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true, true); - for (Creature* spectator : spectators) { - Player* tmpPlayer = spectator->getPlayer(); + for (auto spectator : spectators) { + auto tmpPlayer = spectator->getPlayer(); + if (!tmpPlayer) { + continue; + } + tmpPlayer->sendCreatureWalkthrough(creature, tmpPlayer->canWalkthroughEx(creature)); } } -void Game::updateCreatureSkull(const Creature* creature) { +void Game::updateCreatureSkull(std::shared_ptr creature) { if (getWorldType() != WORLD_TYPE_PVP) { return; } SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true, true); - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendCreatureSkull(creature); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); + if (!player) { + continue; + } + + player->sendCreatureSkull(creature); } } -void Game::updatePlayerShield(Player* player) { +void Game::updatePlayerShield(std::shared_ptr player) { SpectatorHashSet spectators; map.getSpectators(spectators, player->getPosition(), true, true); - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendCreatureShield(player); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); + if (!player) { + continue; + } + + player->sendCreatureShield(player); } } -void Game::updateCreatureType(Creature* creature) { +void Game::updateCreatureType(std::shared_ptr creature) { if (!creature) { return; } - const Player* masterPlayer = nullptr; + std::shared_ptr masterPlayer = nullptr; CreatureType_t creatureType = creature->getType(); if (creatureType == CREATURETYPE_MONSTER) { - const Creature* master = creature->getMaster(); + std::shared_ptr master = creature->getMaster(); if (master) { masterPlayer = master->getPlayer(); if (masterPlayer) { @@ -7502,12 +7514,12 @@ void Game::updateCreatureType(Creature* creature) { creatureType = CREATURETYPE_HIDDEN; } - // send to clients + // Send to clients SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true, true); if (creatureType == CREATURETYPE_SUMMON_OTHERS) { - for (Creature* spectator : spectators) { - Player* player = spectator->getPlayer(); + for (auto spectator : spectators) { + auto player = spectator->getPlayer(); if (!player) { continue; } @@ -7519,8 +7531,8 @@ void Game::updateCreatureType(Creature* creature) { } } } else { - for (Creature* spectator : spectators) { - if (Player* player = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto player = spectator->getPlayer()) { player->sendCreatureType(creature, creatureType); } } @@ -7598,12 +7610,12 @@ void Game::playerInviteToParty(uint32_t playerId, uint32_t invitedId) { return; } - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Player* invitedPlayer = getPlayerByID(invitedId); + std::shared_ptr invitedPlayer = getPlayerByID(invitedId); if (!invitedPlayer || invitedPlayer->isInviting(player)) { return; } @@ -7615,17 +7627,17 @@ void Game::playerInviteToParty(uint32_t playerId, uint32_t invitedId) { return; } - Party* party = player->getParty(); + std::shared_ptr party = player->getParty(); if (!party) { - party = new Party(player); + party = Party::create(player); } else if (party->getLeader() != player) { return; } - party->invitePlayer(*invitedPlayer); + party->invitePlayer(invitedPlayer); } -void Game::updatePlayerHelpers(Player* player) { +void Game::updatePlayerHelpers(std::shared_ptr player) { if (!player) { return; } @@ -7634,27 +7646,28 @@ void Game::updatePlayerHelpers(Player* player) { SpectatorHashSet spectators; map.getSpectators(spectators, player->getPosition(), true, true); - for (Creature* spectator : spectators) { - if (!spectator || !spectator->getPlayer()) { + for (auto spectator : spectators) { + auto specPlayer = spectator->getPlayer(); + if (!specPlayer) { continue; } - spectator->getPlayer()->sendCreatureHelpers(player->getID(), helpers); + specPlayer->sendCreatureHelpers(player->getID(), helpers); } } void Game::playerJoinParty(uint32_t playerId, uint32_t leaderId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Player* leader = getPlayerByID(leaderId); + std::shared_ptr leader = getPlayerByID(leaderId); if (!leader || !leader->isInviting(player)) { return; } - Party* party = leader->getParty(); + auto party = leader->getParty(); if (!party || party->getLeader() != leader) { return; } @@ -7664,40 +7677,40 @@ void Game::playerJoinParty(uint32_t playerId, uint32_t leaderId) { return; } - party->joinParty(*player); + party->joinParty(player); } void Game::playerRevokePartyInvitation(uint32_t playerId, uint32_t invitedId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Party* party = player->getParty(); + std::shared_ptr party = player->getParty(); if (!party || party->getLeader() != player) { return; } - Player* invitedPlayer = getPlayerByID(invitedId); + std::shared_ptr invitedPlayer = getPlayerByID(invitedId); if (!invitedPlayer || !player->isInviting(invitedPlayer)) { return; } - party->revokeInvitation(*invitedPlayer); + party->revokeInvitation(invitedPlayer); } void Game::playerPassPartyLeadership(uint32_t playerId, uint32_t newLeaderId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Party* party = player->getParty(); + std::shared_ptr party = player->getParty(); if (!party || party->getLeader() != player) { return; } - Player* newLeader = getPlayerByID(newLeaderId); + std::shared_ptr newLeader = getPlayerByID(newLeaderId); if (!newLeader || !player->isPartner(newLeader)) { return; } @@ -7706,12 +7719,12 @@ void Game::playerPassPartyLeadership(uint32_t playerId, uint32_t newLeaderId) { } void Game::playerLeaveParty(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Party* party = player->getParty(); + std::shared_ptr party = player->getParty(); if (!party || player->hasCondition(CONDITION_INFIGHT)) { return; } @@ -7720,13 +7733,13 @@ void Game::playerLeaveParty(uint32_t playerId) { } void Game::playerEnableSharedPartyExperience(uint32_t playerId, bool sharedExpActive) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Party* party = player->getParty(); - Tile* playerTile = player->getTile(); + auto party = player->getParty(); + auto playerTile = player->getTile(); if (!party || (player->hasCondition(CONDITION_INFIGHT) && playerTile && !playerTile->hasFlag(TILESTATE_PROTECTIONZONE))) { return; } @@ -7735,7 +7748,7 @@ void Game::playerEnableSharedPartyExperience(uint32_t playerId, bool sharedExpAc } void Game::sendGuildMotd(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -7747,7 +7760,7 @@ void Game::sendGuildMotd(uint32_t playerId) { } void Game::kickPlayer(uint32_t playerId, bool displayEffect) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -7755,7 +7768,7 @@ void Game::kickPlayer(uint32_t playerId, bool displayEffect) { player->removePlayer(displayEffect); } -void Game::playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, CyclopediaCharacterInfoType_t characterInfoType, uint16_t entriesPerPage, uint16_t page) { +void Game::playerCyclopediaCharacterInfo(std::shared_ptr player, uint32_t characterID, CyclopediaCharacterInfoType_t characterInfoType, uint16_t entriesPerPage, uint16_t page) { uint32_t playerGUID = player->getGUID(); if (characterID != playerGUID) { // For now allow viewing only our character since we don't have tournaments supported @@ -7780,7 +7793,7 @@ void Game::playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, C uint32_t playerID = player->getID(); std::function callback = [playerID, page, entriesPerPage](DBResult_ptr result, bool) { - Player* player = g_game().getPlayerByID(playerID); + std::shared_ptr player = g_game().getPlayerByID(playerID); if (!player) { return; } @@ -7845,7 +7858,7 @@ void Game::playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, C uint32_t playerID = player->getID(); std::function callback = [playerID, page, entriesPerPage](DBResult_ptr result, bool) { - Player* player = g_game().getPlayerByID(playerID); + std::shared_ptr player = g_game().getPlayerByID(playerID); if (!player) { return; } @@ -7915,7 +7928,7 @@ void Game::playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, C } } -void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t category, uint32_t vocation, const std::string &, uint16_t page, uint8_t entriesPerPage) { +void Game::playerHighscores(std::shared_ptr player, HighscoreType_t type, uint8_t category, uint32_t vocation, const std::string &, uint16_t page, uint8_t entriesPerPage) { if (player->hasAsyncOngoingTask(PlayerAsyncTask_Highscore)) { return; } @@ -7961,7 +7974,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) { @@ -7981,7 +7994,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) { @@ -7999,7 +8012,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego uint32_t playerID = player->getID(); std::function callback = [playerID, category, vocation, entriesPerPage](DBResult_ptr result, bool) { - Player* player = g_game().getPlayerByID(playerID); + std::shared_ptr player = g_game().getPlayerByID(playerID); if (!player) { return; } @@ -8034,7 +8047,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego } void Game::playerReportRuleViolationReport(uint32_t playerId, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8044,7 +8057,7 @@ void Game::playerReportRuleViolationReport(uint32_t playerId, const std::string } void Game::playerReportBug(uint32_t playerId, const std::string &message, const Position &position, uint8_t category) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8054,7 +8067,7 @@ void Game::playerReportBug(uint32_t playerId, const std::string &message, const } void Game::playerDebugAssert(uint32_t playerId, const std::string &assertLine, const std::string &date, const std::string &description, const std::string &comment) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8069,30 +8082,30 @@ void Game::playerDebugAssert(uint32_t playerId, const std::string &assertLine, c } void Game::playerPreyAction(uint32_t playerId, uint8_t slot, uint8_t action, uint8_t option, int8_t index, uint16_t raceId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - g_ioprey().ParsePreyAction(player, static_cast(slot), static_cast(action), static_cast(option), index, raceId); + g_ioprey().parsePreyAction(player, static_cast(slot), static_cast(action), static_cast(option), index, raceId); } void Game::playerTaskHuntingAction(uint32_t playerId, uint8_t slot, uint8_t action, bool upgrade, uint16_t raceId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - g_ioprey().ParseTaskHuntingAction(player, static_cast(slot), static_cast(action), upgrade, raceId); + g_ioprey().parseTaskHuntingAction(player, static_cast(slot), static_cast(action), upgrade, raceId); } void Game::playerNpcGreet(uint32_t playerId, uint32_t npcId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Npc* npc = getNpcByID(npcId); + std::shared_ptr npc = getNpcByID(npcId); if (!npc) { return; } @@ -8111,7 +8124,7 @@ void Game::playerNpcGreet(uint32_t playerId, uint32_t npcId) { } void Game::playerLeaveMarket(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8120,7 +8133,7 @@ void Game::playerLeaveMarket(uint32_t playerId) { } void Game::playerBrowseMarket(uint32_t playerId, uint16_t itemId, uint8_t tier) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8145,7 +8158,7 @@ void Game::playerBrowseMarket(uint32_t playerId, uint16_t itemId, uint8_t tier) } void Game::playerBrowseMarketOwnOffers(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8160,7 +8173,7 @@ void Game::playerBrowseMarketOwnOffers(uint32_t playerId) { } void Game::playerBrowseMarketOwnHistory(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8175,28 +8188,28 @@ void Game::playerBrowseMarketOwnHistory(uint32_t playerId) { } namespace { - bool removeOfferItems(Player &player, DepotLocker &depotLocker, const ItemType &itemType, uint16_t amount, uint8_t tier, std::ostringstream &offerStatus) { + bool removeOfferItems(const std::shared_ptr &player, const std::shared_ptr &depotLocker, const ItemType &itemType, uint16_t amount, uint8_t tier, std::ostringstream &offerStatus) { uint16_t removeAmount = amount; if ( // Init-statement - auto stashItemCount = player.getStashItemCount(itemType.wareId); + auto stashItemCount = player->getStashItemCount(itemType.wareId); // Condition stashItemCount > 0 ) { - if (removeAmount > stashItemCount && player.withdrawItem(itemType.wareId, stashItemCount)) { + if (removeAmount > stashItemCount && player->withdrawItem(itemType.wareId, stashItemCount)) { removeAmount -= stashItemCount; - } else if (player.withdrawItem(itemType.wareId, removeAmount)) { + } else if (player->withdrawItem(itemType.wareId, removeAmount)) { removeAmount = 0; } else { - offerStatus << "Failed to remove stash items from player " << player.getName(); + offerStatus << "Failed to remove stash items from player " << player->getName(); return false; } } - auto [itemVector, totalCount] = player.getLockerItemsAndCountById(depotLocker, tier, itemType.id); + auto [itemVector, totalCount] = player->getLockerItemsAndCountById(depotLocker, tier, itemType.id); if (removeAmount > 0) { if (totalCount == 0 || itemVector.size() == 0) { - offerStatus << "Player " << player.getName() << " not have item for create offer"; + offerStatus << "Player " << player->getName() << " not have item for create offer"; return false; } @@ -8215,7 +8228,7 @@ namespace { // Condition ret != RETURNVALUE_NOERROR ) { - offerStatus << "Failed to remove items from player " << player.getName() << " error: " << getReturnMessage(ret); + offerStatus << "Failed to remove items from player " << player->getName() << " error: " << getReturnMessage(ret); return false; } @@ -8229,7 +8242,7 @@ namespace { } auto ret = g_game().internalRemoveItem(item); if (ret != RETURNVALUE_NOERROR) { - offerStatus << "Failed to remove items from player " << player.getName() << " error: " << getReturnMessage(ret); + offerStatus << "Failed to remove items from player " << player->getName() << " error: " << getReturnMessage(ret); return false; } else { removeAmount -= 1; @@ -8238,7 +8251,7 @@ namespace { } } if (removeAmount > 0) { - g_logger().error("Player {} tried to sell an item {} without this item", itemType.id, player.getName()); + g_logger().error("Player {} tried to sell an item {} without this item", itemType.id, player->getName()); offerStatus << "The item you tried to market is not correct. Check the item again."; return false; } @@ -8246,7 +8259,7 @@ namespace { } } // namespace -bool checkCanInitCreateMarketOffer(const Player* player, uint8_t type, const ItemType &it, uint16_t amount, uint64_t price, std::ostringstream &offerStatus) { +bool checkCanInitCreateMarketOffer(std::shared_ptr player, uint8_t type, const ItemType &it, uint16_t amount, uint64_t price, std::ostringstream &offerStatus) { if (!player) { offerStatus << "Failed to load player"; return false; @@ -8312,7 +8325,7 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite // Initialize variables // Before creating the offer we will compare it with the RETURN VALUE ERROR std::ostringstream offerStatus; - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); const ItemType &it = Item::items[itemId]; // Make sure everything is ok before the create market offer starts @@ -8331,7 +8344,7 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite return; } - DepotLocker* depotLocker = player->getDepotLocker(player->getLastDepotId()); + std::shared_ptr depotLocker = player->getDepotLocker(player->getLastDepotId()); if (depotLocker == nullptr) { offerStatus << "Depot locker is nullptr for player " << player->getName(); return; @@ -8348,7 +8361,7 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite // Do not register a transaction for coins creating an offer player->getAccount()->removeCoins(account::CoinType::TRANSFERABLE, static_cast(amount), ""); } else { - if (!removeOfferItems(*player, *depotLocker, it, amount, tier, offerStatus)) { + if (!removeOfferItems(player, depotLocker, it, amount, tier, offerStatus)) { g_logger().error("[{}] failed to remove item with id {}, from player {}, errorcode: {}", __FUNCTION__, it.id, player->getName(), offerStatus.str()); return; } @@ -8404,7 +8417,7 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite } void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16_t counter) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->getAccount()) { return; } @@ -8440,9 +8453,8 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 uint16_t tmpAmount = offer.amount; while (tmpAmount > 0) { int32_t stackCount = std::min(it.stackSize, tmpAmount); - Item* item = Item::CreateItem(it.id, stackCount); + std::shared_ptr item = Item::CreateItem(it.id, stackCount); if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { - delete item; break; } @@ -8461,9 +8473,8 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 } for (uint16_t i = 0; i < offer.amount; ++i) { - Item* item = Item::CreateItem(it.id, subType); + std::shared_ptr item = Item::CreateItem(it.id, subType); if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { - delete item; break; } @@ -8488,7 +8499,7 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16_t counter, uint16_t amount) { std::ostringstream offerStatus; - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || !player->getAccount()) { offerStatus << "Failed to load player"; return; @@ -8526,17 +8537,16 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 // The player has an offer to by something and someone is going to sell to item type // so the market action is 'buy' as who created the offer is buying. if (offer.type == MARKETACTION_BUY) { - DepotLocker* depotLocker = player->getDepotLocker(player->getLastDepotId()); + std::shared_ptr depotLocker = player->getDepotLocker(player->getLastDepotId()); if (depotLocker == nullptr) { offerStatus << "Depot locker is nullptr"; return; } - Player* buyerPlayer = getPlayerByGUID(offer.playerId); + std::shared_ptr buyerPlayer = getPlayerByGUID(offer.playerId); if (!buyerPlayer) { - buyerPlayer = new Player(nullptr); + buyerPlayer = std::make_shared(nullptr); if (!IOLoginData::loadPlayerById(buyerPlayer, offer.playerId)) { - delete buyerPlayer; offerStatus << "Failed to load buyer player " << player->getName(); return; } @@ -8571,7 +8581,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 "Sold on Market" ); } else { - if (!removeOfferItems(*player, *depotLocker, it, amount, offer.tier, offerStatus)) { + if (!removeOfferItems(player, depotLocker, it, amount, offer.tier, offerStatus)) { g_logger().error("[{}] failed to remove item with id {}, from player {}, errorcode: {}", __FUNCTION__, it.id, player->getName(), offerStatus.str()); return; } @@ -8598,10 +8608,10 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 uint16_t tmpAmount = amount; while (tmpAmount > 0) { uint16_t stackCount = std::min(it.stackSize, tmpAmount); - Item* item = Item::CreateItem(it.id, stackCount); + std::shared_ptr item = Item::CreateItem(it.id, stackCount); if (internalAddItem(buyerPlayer->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { offerStatus << "Failed to add player inbox stackable item for buy offer for player " << player->getName(); - delete item; + break; } @@ -8620,10 +8630,10 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 } for (uint16_t i = 0; i < amount; ++i) { - Item* item = Item::CreateItem(it.id, subType); + std::shared_ptr item = Item::CreateItem(it.id, subType); if (internalAddItem(buyerPlayer->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { offerStatus << "Failed to add player inbox item for buy offer for player " << player->getName(); - delete item; + break; } @@ -8635,15 +8645,14 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 if (buyerPlayer->isOffline()) { IOLoginData::savePlayer(buyerPlayer); - delete buyerPlayer; } } else if (offer.type == MARKETACTION_SELL) { - Player* sellerPlayer = getPlayerByGUID(offer.playerId); + std::shared_ptr sellerPlayer = getPlayerByGUID(offer.playerId); if (!sellerPlayer) { - sellerPlayer = new Player(nullptr); + sellerPlayer = std::make_shared(nullptr); if (!IOLoginData::loadPlayerById(sellerPlayer, offer.playerId)) { offerStatus << "Failed to load seller player"; - delete sellerPlayer; + return; } } @@ -8673,7 +8682,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 uint16_t tmpAmount = amount; while (tmpAmount > 0) { uint16_t stackCount = std::min(it.stackSize, tmpAmount); - Item* item = Item::CreateItem(it.id, stackCount); + std::shared_ptr item = Item::CreateItem(it.id, stackCount); if ( // Init-statement auto ret = internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT); @@ -8682,7 +8691,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 ) { g_logger().error("{} - Create offer internal add item error code: {}", __FUNCTION__, getReturnMessage(ret)); offerStatus << "Failed to add inbox stackable item for sell offer for player " << player->getName(); - delete item; + break; } @@ -8701,7 +8710,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 } for (uint16_t i = 0; i < amount; ++i) { - Item* item = Item::CreateItem(it.id, subType); + std::shared_ptr item = Item::CreateItem(it.id, subType); if ( // Init-statement auto ret = internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT); @@ -8709,7 +8718,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 ret != RETURNVALUE_NOERROR ) { offerStatus << "Failed to add inbox item for sell offer for player " << player->getName(); - delete item; + break; } @@ -8730,7 +8739,6 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 if (sellerPlayer->isOffline()) { IOLoginData::savePlayer(sellerPlayer); - delete sellerPlayer; } } @@ -8765,7 +8773,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 } void Game::parsePlayerExtendedOpcode(uint32_t playerId, uint8_t opcode, const std::string &buffer) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8776,7 +8784,7 @@ void Game::parsePlayerExtendedOpcode(uint32_t playerId, uint8_t opcode, const st } void Game::forceRemoveCondition(uint32_t creatureId, ConditionType_t conditionType, ConditionId_t conditionId) { - Creature* creature = getCreatureByID(creatureId); + std::shared_ptr creature = getCreatureByID(creatureId); if (!creature) { return; } @@ -8784,7 +8792,7 @@ void Game::forceRemoveCondition(uint32_t creatureId, ConditionType_t conditionTy creature->removeCondition(conditionType, conditionId, true); } -void Game::sendOfflineTrainingDialog(Player* player) { +void Game::sendOfflineTrainingDialog(std::shared_ptr player) { if (!player) { return; } @@ -8795,7 +8803,7 @@ void Game::sendOfflineTrainingDialog(Player* player) { } void Game::playerAnswerModalWindow(uint32_t playerId, uint32_t modalWindowId, uint8_t button, uint8_t choice) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8810,7 +8818,7 @@ void Game::playerAnswerModalWindow(uint32_t playerId, uint32_t modalWindowId, ui if (modalWindowId == std::numeric_limits::max()) { if (button == 1) { if (choice == SKILL_SWORD || choice == SKILL_AXE || choice == SKILL_CLUB || choice == SKILL_DISTANCE || choice == SKILL_MAGLEVEL) { - BedItem* bedItem = player->getBedItem(); + auto bedItem = player->getBedItem(); if (bedItem && bedItem->sleep(player)) { player->setOfflineTrainingSkill(static_cast(choice)); return; @@ -8829,7 +8837,7 @@ void Game::playerAnswerModalWindow(uint32_t playerId, uint32_t modalWindowId, ui } void Game::playerForgeFuseItems(uint32_t playerId, uint16_t itemId, uint8_t tier, bool usedCore, bool reduceTierLoss) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8854,7 +8862,7 @@ void Game::playerForgeFuseItems(uint32_t playerId, uint16_t itemId, uint8_t tier } void Game::playerForgeTransferItemTier(uint32_t playerId, uint16_t donorItemId, uint8_t tier, uint16_t receiveItemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8863,7 +8871,7 @@ void Game::playerForgeTransferItemTier(uint32_t playerId, uint16_t donorItemId, } void Game::playerForgeResourceConversion(uint32_t playerId, uint8_t action) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8878,7 +8886,7 @@ void Game::playerForgeResourceConversion(uint32_t playerId, uint8_t action) { } void Game::playerBrowseForgeHistory(uint32_t playerId, uint8_t page) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8893,7 +8901,7 @@ void Game::playerBrowseForgeHistory(uint32_t playerId, uint8_t page) { } void Game::playerBosstiarySlot(uint32_t playerId, uint8_t slotId, uint32_t selectedBossId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -8919,17 +8927,17 @@ void Game::playerBosstiarySlot(uint32_t playerId, uint8_t slotId, uint32_t selec } void Game::playerSetMonsterPodium(uint32_t playerId, uint32_t monsterRaceId, const Position &pos, uint8_t stackPos, const uint16_t itemId, uint8_t direction, const std::pair &podiumAndMonsterVisible) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || pos.x == 0xFFFF) { return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || item->getID() != itemId || !item->isPodium() || item->hasAttribute(ItemAttribute_t::UNIQUEID)) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -8971,7 +8979,7 @@ void Game::playerSetMonsterPodium(uint32_t playerId, uint32_t monsterRaceId, con return; } - const auto &[podiumVisible, monsterVisible] = podiumAndMonsterVisible; + const auto [podiumVisible, monsterVisible] = podiumAndMonsterVisible; bool changeTentuglyName = false; if (auto monsterOutfit = mType->info.outfit; (monsterOutfit.lookType != 0 || monsterOutfit.lookTypeEx != 0) && monsterVisible) { @@ -9014,25 +9022,25 @@ void Game::playerSetMonsterPodium(uint32_t playerId, uint32_t monsterRaceId, con g_game().map.getSpectators(spectators, pos, true); // Send to client - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendUpdateTileItem(tile, pos, item); } } } void Game::playerRotatePodium(uint32_t playerId, const Position &pos, uint8_t stackPos, const uint16_t itemId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_TOPDOWN_ITEM); if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item || item->getID() != itemId || item->hasAttribute(ItemAttribute_t::UNIQUEID)) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -9087,6 +9095,7 @@ void Game::playerRotatePodium(uint32_t playerId, const Position &pos, uint8_t st // We retrieve the outfit information to be able to rotate the podium of renown in the new direction Outfit_t newOutfit; newOutfit.lookType = InternalGame::getCustomAttributeValue(item, "LookType"); + newOutfit.lookAddons = InternalGame::getCustomAttributeValue(item, "LookAddons"); newOutfit.lookHead = InternalGame::getCustomAttributeValue(item, "LookHead"); newOutfit.lookBody = InternalGame::getCustomAttributeValue(item, "LookBody"); newOutfit.lookLegs = InternalGame::getCustomAttributeValue(item, "LookLegs"); @@ -9106,7 +9115,7 @@ void Game::playerRotatePodium(uint32_t playerId, const Position &pos, uint8_t st } void Game::playerRequestInventoryImbuements(uint32_t playerId, bool isTrackerOpen) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player || player->isRemoved()) { return; } @@ -9116,7 +9125,7 @@ void Game::playerRequestInventoryImbuements(uint32_t playerId, bool isTrackerOpe return; } - std::map itemsWithImbueSlotMap; + std::map> itemsWithImbueSlotMap; for (uint8_t inventorySlot = CONST_SLOT_FIRST; inventorySlot <= CONST_SLOT_LAST; ++inventorySlot) { auto item = player->getInventoryItem(static_cast(inventorySlot)); if (!item) { @@ -9138,7 +9147,7 @@ void Game::playerRequestInventoryImbuements(uint32_t playerId, bool isTrackerOpe } void Game::playerOpenWheel(uint32_t playerId, uint32_t ownerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -9158,7 +9167,7 @@ void Game::playerOpenWheel(uint32_t playerId, uint32_t ownerId) { } void Game::playerSaveWheel(uint32_t playerId, NetworkMessage &msg) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -9176,7 +9185,7 @@ void Game::playerSaveWheel(uint32_t playerId, NetworkMessage &msg) { ********************/ void Game::updatePlayerSaleItems(uint32_t playerId) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } @@ -9186,33 +9195,33 @@ void Game::updatePlayerSaleItems(uint32_t playerId) { player->setScheduledSaleUpdate(false); } -void Game::addPlayer(Player* player) { +void Game::addPlayer(std::shared_ptr player) { const std::string &lowercase_name = asLowerCaseString(player->getName()); mappedPlayerNames[lowercase_name] = player; wildcardTree.insert(lowercase_name); players[player->getID()] = player; } -void Game::removePlayer(Player* player) { +void Game::removePlayer(std::shared_ptr player) { const std::string &lowercase_name = asLowerCaseString(player->getName()); mappedPlayerNames.erase(lowercase_name); wildcardTree.remove(lowercase_name); players.erase(player->getID()); } -void Game::addNpc(Npc* npc) { +void Game::addNpc(std::shared_ptr npc) { npcs[npc->getID()] = npc; } -void Game::removeNpc(Npc* npc) { +void Game::removeNpc(std::shared_ptr npc) { npcs.erase(npc->getID()); } -void Game::addMonster(Monster* monster) { +void Game::addMonster(std::shared_ptr monster) { monsters[monster->getID()] = monster; } -void Game::removeMonster(Monster* monster) { +void Game::removeMonster(std::shared_ptr monster) { monsters.erase(monster->getID()); } @@ -9254,21 +9263,9 @@ void Game::removeGuild(uint32_t guildId) { guilds.erase(guildId); } -void Game::decreaseBrowseFieldRef(const Position &pos) { - Tile* tile = map.getTile(pos.x, pos.y, pos.z); - if (!tile) { - return; - } - - auto it = browseFields.find(tile); - if (it != browseFields.end()) { - it->second->decrementReferenceCounter(); - } -} - -void Game::internalRemoveItems(const std::vector itemVector, uint32_t amount, bool stackable) { +void Game::internalRemoveItems(const std::vector> &itemVector, uint32_t amount, bool stackable) { if (stackable) { - for (Item* item : itemVector) { + for (std::shared_ptr item : itemVector) { if (item->getItemCount() > amount) { internalRemoveItem(item, amount); break; @@ -9278,13 +9275,13 @@ void Game::internalRemoveItems(const std::vector itemVector, uint32_t amo } } } else { - for (Item* item : itemVector) { + for (std::shared_ptr item : itemVector) { internalRemoveItem(item); } } } -BedItem* Game::getBedBySleeper(uint32_t guid) const { +std::shared_ptr Game::getBedBySleeper(uint32_t guid) const { auto it = bedSleepersMap.find(guid); if (it == bedSleepersMap.end()) { return nullptr; @@ -9292,7 +9289,7 @@ BedItem* Game::getBedBySleeper(uint32_t guid) const { return it->second; } -void Game::setBedSleeper(BedItem* bed, uint32_t guid) { +void Game::setBedSleeper(std::shared_ptr bed, uint32_t guid) { bedSleepersMap[guid] = bed; } @@ -9303,7 +9300,7 @@ void Game::removeBedSleeper(uint32_t guid) { } } -Item* Game::getUniqueItem(uint16_t uniqueId) { +std::shared_ptr Game::getUniqueItem(uint16_t uniqueId) { auto it = uniqueItems.find(uniqueId); if (it == uniqueItems.end()) { return nullptr; @@ -9311,7 +9308,7 @@ Item* Game::getUniqueItem(uint16_t uniqueId) { return it->second; } -bool Game::addUniqueItem(uint16_t uniqueId, Item* item) { +bool Game::addUniqueItem(uint16_t uniqueId, std::shared_ptr item) { auto result = uniqueItems.emplace(uniqueId, item); if (!result.second) { g_logger().warn("Duplicate unique id: {}", uniqueId); @@ -9348,17 +9345,17 @@ bool Game::hasDistanceEffect(uint16_t effectId) { void Game::createLuaItemsOnMap() { for (const auto [position, itemId] : mapLuaItemsStored) { - Item* item = Item::CreateItem(itemId, 1); + std::shared_ptr item = Item::CreateItem(itemId, 1); if (!item) { g_logger().warn("[Game::createLuaItemsOnMap] - Cannot create item with id {}", itemId); continue; } if (position.x != 0) { - Tile* tile = g_game().map.getTile(position); + std::shared_ptr tile = g_game().map.getTile(position); if (!tile) { g_logger().warn("[Game::createLuaItemsOnMap] - Tile is wrong or not found position: {}", position.toString()); - delete item; + continue; } @@ -9373,15 +9370,15 @@ void Game::createLuaItemsOnMap() { } } -void Game::sendUpdateCreature(const Creature* creature) { +void Game::sendUpdateCreature(std::shared_ptr creature) { if (!creature) { return; } SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), true); - for (Creature* spectator : spectators) { - if (const Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (const auto tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendUpdateCreature(creature); } } @@ -9400,7 +9397,7 @@ uint32_t Game::makeInfluencedMonster() { auto maxTries = forgeableMonsters.size(); uint16_t tries = 0; - Monster* monster = nullptr; + std::shared_ptr monster = nullptr; while (true) { if (tries == maxTries) { return 0; @@ -9477,7 +9474,7 @@ uint32_t Game::makeFiendishMonster(uint32_t forgeableMonsterId /* = 0*/, bool cr auto maxTries = forgeableMonsters.size(); uint16_t tries = 0; - Monster* monster = nullptr; + std::shared_ptr monster = nullptr; while (true) { if (tries == maxTries) { return 0; @@ -9552,7 +9549,7 @@ uint32_t Game::makeFiendishMonster(uint32_t forgeableMonsterId /* = 0*/, bool cr } void Game::updateFiendishMonsterStatus(uint32_t monsterId, const std::string &monsterName) { - Monster* monster = getMonsterByID(monsterId); + std::shared_ptr monster = getMonsterByID(monsterId); if (!monster) { g_logger().warn("[{}] Failed to update monster with id {} and name {}, monster not found", __FUNCTION__, monsterId, monsterName); return; @@ -9677,7 +9674,7 @@ void Game::checkForgeEventId(uint32_t monsterId) { } } -bool Game::addInfluencedMonster(Monster* monster) { +bool Game::addInfluencedMonster(std::shared_ptr monster) { if (monster && monster->canBeForgeMonster()) { if (auto maxInfluencedMonsters = static_cast(g_configManager().getNumber(FORGE_INFLUENCED_CREATURES_LIMIT)); // If condition @@ -9693,8 +9690,8 @@ bool Game::addInfluencedMonster(Monster* monster) { return false; } -bool Game::addItemStoreInbox(const Player* player, uint32_t itemId) { - Item* decoKit = Item::CreateItem(ITEM_DECORATION_KIT, 1); +bool Game::addItemStoreInbox(std::shared_ptr player, uint32_t itemId) { + std::shared_ptr decoKit = Item::CreateItem(ITEM_DECORATION_KIT, 1); if (!decoKit) { return false; } @@ -9703,17 +9700,17 @@ bool Game::addItemStoreInbox(const Player* player, uint32_t itemId) { decoKit->setAttribute(ItemAttribute_t::DESCRIPTION, description); decoKit->setCustomAttribute("unWrapId", static_cast(itemId)); - Thing* thing = player->getThing(CONST_SLOT_STORE_INBOX); + std::shared_ptr thing = player->getThing(CONST_SLOT_STORE_INBOX); if (!thing) { return false; } - Item* inboxItem = thing->getItem(); + std::shared_ptr inboxItem = thing->getItem(); if (!inboxItem) { return false; } - Container* inboxContainer = inboxItem->getContainer(); + std::shared_ptr inboxContainer = inboxItem->getContainer(); if (!inboxContainer) { return false; } @@ -9725,7 +9722,7 @@ bool Game::addItemStoreInbox(const Player* player, uint32_t itemId) { return true; } -void Game::addPlayerUniqueLogin(Player* player) { +void Game::addPlayerUniqueLogin(std::shared_ptr player) { if (!player) { g_logger().error("Attempted to add null player to unique player names list"); return; @@ -9735,14 +9732,14 @@ void Game::addPlayerUniqueLogin(Player* player) { m_uniqueLoginPlayerNames[lowercase_name] = player; } -Player* Game::getPlayerUniqueLogin(const std::string &playerName) const { +std::shared_ptr Game::getPlayerUniqueLogin(const std::string &playerName) const { if (playerName.empty()) { g_logger().error("Attempted to get player with empty name string"); return nullptr; } auto it = m_uniqueLoginPlayerNames.find(asLowerCaseString(playerName)); - return (it != m_uniqueLoginPlayerNames.end()) ? it->second : nullptr; + return (it != m_uniqueLoginPlayerNames.end()) ? it->second.lock() : nullptr; } void Game::removePlayerUniqueLogin(const std::string &playerName) { @@ -9755,18 +9752,18 @@ void Game::removePlayerUniqueLogin(const std::string &playerName) { m_uniqueLoginPlayerNames.erase(lowercase_name); } -void Game::removePlayerUniqueLogin(Player* player) { +void Game::removePlayerUniqueLogin(std::shared_ptr player) { if (!player) { g_logger().error("Attempted to remove null player from unique player names list."); return; } - const std::string &lowercase_name = asLowerCaseString(player->getName()); - m_uniqueLoginPlayerNames.erase(lowercase_name); + const std::string &lowercaseName = asLowerCaseString(player->getName()); + m_uniqueLoginPlayerNames.erase(lowercaseName); } void Game::playerCheckActivity(const std::string &playerName, int interval) { - Player* player = getPlayerUniqueLogin(playerName); + std::shared_ptr player = getPlayerUniqueLogin(playerName); if (!player) { return; } @@ -9799,12 +9796,12 @@ void Game::playerCheckActivity(const std::string &playerName, int interval) { } void Game::playerRewardChestCollect(uint32_t playerId, const Position &pos, uint16_t itemId, uint8_t stackPos, uint32_t maxMoveItems /* = 0*/) { - Player* player = getPlayerByID(playerId); + std::shared_ptr player = getPlayerByID(playerId); if (!player) { return; } - Thing* thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_FIND_THING); + std::shared_ptr thing = internalGetThing(player, pos, stackPos, itemId, STACKPOS_FIND_THING); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -9821,6 +9818,18 @@ void Game::playerRewardChestCollect(uint32_t playerId, const Position &pos, uint return; } + // Updates the parent of the reward chest and reward containers to avoid memory usage after cleaning + auto playerRewardChest = player->getRewardChest(); + if (playerRewardChest->empty()) { + player->sendCancelMessage(RETURNVALUE_REWARDCHESTISEMPTY); + return; + } + + playerRewardChest->setParent(item->getContainer()->getParent()->getTile()); + for (const auto &[mapRewardId, reward] : player->rewardMap) { + reward->setParent(playerRewardChest); + } + std::lock_guard lock(player->quickLootMutex); ReturnValue returnValue = collectRewardChestItems(player, maxMoveItems); @@ -9829,7 +9838,7 @@ void Game::playerRewardChestCollect(uint32_t playerId, const Position &pos, uint } } -bool Game::tryRetrieveStashItems(Player* player, Item* item) { +bool Game::tryRetrieveStashItems(std::shared_ptr player, std::shared_ptr item) { return internalCollectLootItems(player, item, OBJECTCATEGORY_STASHRETRIEVE) == RETURNVALUE_NOERROR; } @@ -9841,6 +9850,46 @@ const std::unique_ptr &Game::getIOWheel() const { return m_IOWheel; } +void Game::transferHouseItemsToDepot() { + if (!g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART)) { + return; + } + + if (!transferHouseItemsToPlayer.empty()) { + g_logger().info("Initializing house transfer items"); + } + + uint16_t transferSuccess = 0; + for (const auto &[houseId, playerGuid] : transferHouseItemsToPlayer) { + auto house = map.houses.getHouse(houseId); + if (house) { + auto offlinePlayer = std::make_shared(nullptr); + if (!IOLoginData::loadPlayerById(offlinePlayer, playerGuid)) { + continue; + } + + if (!offlinePlayer) { + continue; + } + + g_logger().info("Tranfering items to the inbox from player '{}'", offlinePlayer->getName()); + if (house->tryTransferOwnership(offlinePlayer, true)) { + transferSuccess++; + house->setNewOwnerGuid(-1, true); + } + } + } + if (transferSuccess > 0) { + g_logger().info("Finished house transfer items from '{}' players", transferSuccess); + transferHouseItemsToPlayer.clear(); + Map::save(); + } +} + +void Game::setTransferPlayerHouseItems(uint32_t houseId, uint32_t playerId) { + transferHouseItemsToPlayer[houseId] = playerId; +} + template phmap::parallel_flat_hash_set setDifference(const phmap::parallel_flat_hash_set &setA, const phmap::parallel_flat_hash_set &setB) { phmap::parallel_flat_hash_set setResult; @@ -9852,7 +9901,7 @@ phmap::parallel_flat_hash_set setDifference(const phmap::parallel_flat_hash_s return setResult; } -ReturnValue Game::beforeCreatureZoneChange(Creature* creature, const phmap::parallel_flat_hash_set> &fromZones, const phmap::parallel_flat_hash_set> &toZones, bool force /* = false*/) const { +ReturnValue Game::beforeCreatureZoneChange(std::shared_ptr creature, const phmap::parallel_flat_hash_set> &fromZones, const phmap::parallel_flat_hash_set> &toZones, bool force /* = false*/) const { if (!creature) { return RETURNVALUE_NOTPOSSIBLE; } @@ -9882,7 +9931,7 @@ ReturnValue Game::beforeCreatureZoneChange(Creature* creature, const phmap::para return RETURNVALUE_NOERROR; } -void Game::afterCreatureZoneChange(Creature* creature, const phmap::parallel_flat_hash_set> &fromZones, const phmap::parallel_flat_hash_set> &toZones) const { +void Game::afterCreatureZoneChange(std::shared_ptr creature, const phmap::parallel_flat_hash_set> &fromZones, const phmap::parallel_flat_hash_set> &toZones) const { if (!creature) { return; } diff --git a/src/game/game.hpp b/src/game/game.hpp index 047a7f474..583862cce 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -42,6 +42,7 @@ static constexpr int32_t EVENT_LIGHTINTERVAL_MS = 10000; static constexpr int32_t EVENT_DECAYINTERVAL = 250; static constexpr int32_t EVENT_DECAY_BUCKETS = 4; static constexpr int32_t EVENT_FORGEABLEMONSTERCHECKINTERVAL = 300000; +static constexpr int32_t EVENT_LUA_GARBAGE_COLLECTION = 60000 * 10; // 10min class Game { public: @@ -88,51 +89,67 @@ class Game { return worldType; } - std::map getTeamFinderList() const { + const std::map> &getTeamFinderList() const { return teamFinderMap; } - void registerTeamFinderAssemble(uint32_t leaderGuid, TeamFinder* teamFinder) { - teamFinderMap[leaderGuid] = teamFinder; + + const std::unique_ptr &getTeamFinder(const std::shared_ptr &player) const { + auto it = teamFinderMap.find(player->getGUID()); + if (it != teamFinderMap.end()) { + return it->second; + } + + return TeamFinderNull; + } + + const std::unique_ptr &getOrCreateTeamFinder(const std::shared_ptr &player) { + auto it = teamFinderMap.find(player->getGUID()); + if (it != teamFinderMap.end()) { + return it->second; + } + + return teamFinderMap[player->getGUID()] = std::make_unique(); } + void removeTeamFinderListed(uint32_t leaderGuid) { teamFinderMap.erase(leaderGuid); } - Cylinder* internalGetCylinder(Player* player, const Position &pos); - Thing* internalGetThing(Player* player, const Position &pos, int32_t index, uint32_t itemId, StackPosType_t type); - static void internalGetPosition(Item* item, Position &pos, uint8_t &stackpos); + std::shared_ptr internalGetCylinder(std::shared_ptr player, const Position &pos); + std::shared_ptr internalGetThing(std::shared_ptr player, const Position &pos, int32_t index, uint32_t itemId, StackPosType_t type); + static void internalGetPosition(std::shared_ptr item, Position &pos, uint8_t &stackpos); - static std::string getTradeErrorDescription(ReturnValue ret, Item* item); + static std::string getTradeErrorDescription(ReturnValue ret, std::shared_ptr item); - Creature* getCreatureByID(uint32_t id); + std::shared_ptr getCreatureByID(uint32_t id); - Monster* getMonsterByID(uint32_t id); + std::shared_ptr getMonsterByID(uint32_t id); - Npc* getNpcByID(uint32_t id); + std::shared_ptr getNpcByID(uint32_t id); - Creature* getCreatureByName(const std::string &s); + std::shared_ptr getCreatureByName(const std::string &s); - Npc* getNpcByName(const std::string &s); + std::shared_ptr getNpcByName(const std::string &s); - Player* getPlayerByID(uint32_t id, bool allowOffline = false); + std::shared_ptr getPlayerByID(uint32_t id, bool allowOffline = false); - Player* getPlayerByName(const std::string &s, bool allowOffline = false); + std::shared_ptr getPlayerByName(const std::string &s, bool allowOffline = false); - Player* getPlayerByGUID(const uint32_t &guid); + std::shared_ptr getPlayerByGUID(const uint32_t &guid); - ReturnValue getPlayerByNameWildcard(const std::string &s, Player*&player); + ReturnValue getPlayerByNameWildcard(const std::string &s, std::shared_ptr &player); - Player* getPlayerByAccount(uint32_t acc); + std::shared_ptr getPlayerByAccount(uint32_t acc); - bool internalPlaceCreature(Creature* creature, const Position &pos, bool extendedPos = false, bool forced = false, bool creatureCheck = false); + bool internalPlaceCreature(std::shared_ptr creature, const Position &pos, bool extendedPos = false, bool forced = false, bool creatureCheck = false); - bool placeCreature(Creature* creature, const Position &pos, bool extendedPos = false, bool force = false); + bool placeCreature(std::shared_ptr creature, const Position &pos, bool extendedPos = false, bool force = false); - bool removeCreature(Creature* creature, bool isLogout = true); + bool removeCreature(std::shared_ptr creature, bool isLogout = true); void executeDeath(uint32_t creatureId); - void addCreatureCheck(Creature* creature); - static void removeCreatureCheck(Creature* creature); + void addCreatureCheck(std::shared_ptr creature); + static void removeCreatureCheck(std::shared_ptr creature); size_t getPlayersOnline() const { return players.size(); @@ -173,43 +190,43 @@ class Game { bool gameIsDay(); - ReturnValue internalMoveCreature(Creature* creature, Direction direction, uint32_t flags = 0); - ReturnValue internalMoveCreature(Creature &creature, Tile &toTile, uint32_t flags = 0); + ReturnValue internalMoveCreature(std::shared_ptr creature, Direction direction, uint32_t flags = 0); + ReturnValue internalMoveCreature(const std::shared_ptr &creature, const std::shared_ptr &toTile, uint32_t flags = 0); - ReturnValue checkMoveItemToCylinder(Player* player, Cylinder* fromCylinder, Cylinder* toCylinder, Item* item, Position toPos); - ReturnValue internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, int32_t index, Item* item, uint32_t count, Item** movedItem, uint32_t flags = 0, Creature* actor = nullptr, Item* tradeItem = nullptr, bool checkTile = true); + ReturnValue checkMoveItemToCylinder(std::shared_ptr player, std::shared_ptr fromCylinder, std::shared_ptr toCylinder, std::shared_ptr item, Position toPos); + ReturnValue internalMoveItem(std::shared_ptr fromCylinder, std::shared_ptr toCylinder, int32_t index, std::shared_ptr item, uint32_t count, std::shared_ptr* movedItem, uint32_t flags = 0, std::shared_ptr actor = nullptr, std::shared_ptr tradeItem = nullptr, bool checkTile = true); - ReturnValue internalAddItem(Cylinder* toCylinder, Item* item, int32_t index = INDEX_WHEREEVER, uint32_t flags = 0, bool test = false); - ReturnValue internalAddItem(Cylinder* toCylinder, Item* item, int32_t index, uint32_t flags, bool test, uint32_t &remainderCount); - ReturnValue internalRemoveItem(Item* item, int32_t count = -1, bool test = false, uint32_t flags = 0, bool force = false); + ReturnValue internalAddItem(std::shared_ptr toCylinder, std::shared_ptr item, int32_t index = INDEX_WHEREEVER, uint32_t flags = 0, bool test = false); + ReturnValue internalAddItem(std::shared_ptr toCylinder, std::shared_ptr item, int32_t index, uint32_t flags, bool test, uint32_t &remainderCount); + ReturnValue internalRemoveItem(std::shared_ptr item, int32_t count = -1, bool test = false, uint32_t flags = 0, bool force = false); - ReturnValue internalPlayerAddItem(Player* player, Item* item, bool dropOnMap = true, Slots_t slot = CONST_SLOT_WHEREEVER); + ReturnValue internalPlayerAddItem(std::shared_ptr player, std::shared_ptr item, bool dropOnMap = true, Slots_t slot = CONST_SLOT_WHEREEVER); - Item* findItemOfType(const Cylinder* cylinder, uint16_t itemId, bool depthSearch = true, int32_t subType = -1) const; + std::shared_ptr findItemOfType(std::shared_ptr cylinder, uint16_t itemId, bool depthSearch = true, int32_t subType = -1) const; void createLuaItemsOnMap(); - bool removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags = 0, bool useBank = false); + bool removeMoney(std::shared_ptr cylinder, uint64_t money, uint32_t flags = 0, bool useBank = false); - void addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags = 0); + void addMoney(std::shared_ptr cylinder, uint64_t money, uint32_t flags = 0); - Item* transformItem(Item* item, uint16_t newId, int32_t newCount = -1); + std::shared_ptr transformItem(std::shared_ptr item, uint16_t newId, int32_t newCount = -1); - ReturnValue internalTeleport(Thing* thing, const Position &newPos, bool pushMove = true, uint32_t flags = 0); + ReturnValue internalTeleport(std::shared_ptr thing, const Position &newPos, bool pushMove = true, uint32_t flags = 0); - bool internalCreatureTurn(Creature* creature, Direction dir); + bool internalCreatureTurn(std::shared_ptr creature, Direction dir); - bool internalCreatureSay(Creature* creature, SpeakClasses type, const std::string &text, bool ghostMode, SpectatorHashSet* spectatorsPtr = nullptr, const Position* pos = nullptr); + bool internalCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text, bool ghostMode, SpectatorHashSet* spectatorsPtr = nullptr, const Position* pos = nullptr); - ObjectCategory_t getObjectCategory(const Item* item); + ObjectCategory_t getObjectCategory(const std::shared_ptr item); uint64_t getItemMarketPrice(const std::map &itemMap, bool buyPrice) const; void loadPlayersRecord(); void checkPlayersRecord(); - void sendSingleSoundEffect(const Position &pos, SoundEffect_t soundId, Creature* actor = nullptr); - void sendDoubleSoundEffect(const Position &pos, SoundEffect_t mainSoundEffect, SoundEffect_t secondarySoundEffect, Creature* actor = nullptr); + void sendSingleSoundEffect(const Position &pos, SoundEffect_t soundId, std::shared_ptr actor = nullptr); + void sendDoubleSoundEffect(const Position &pos, SoundEffect_t mainSoundEffect, SoundEffect_t secondarySoundEffect, std::shared_ptr actor = nullptr); void sendGuildMotd(uint32_t playerId); void kickPlayer(uint32_t playerId, bool displayEffect); @@ -241,30 +258,30 @@ class Game { void playerRequestInventoryImbuements(uint32_t playerId, bool isTrackerOpen); - bool addItemStoreInbox(const Player* player, uint32_t itemId); + bool addItemStoreInbox(std::shared_ptr player, uint32_t itemId); void playerRewardChestCollect(uint32_t playerId, const Position &pos, uint16_t itemId, uint8_t stackPos, uint32_t maxMoveItems = 0); void playerReportRuleViolationReport(uint32_t playerId, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation); - void playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, CyclopediaCharacterInfoType_t characterInfoType, uint16_t entriesPerPage, uint16_t page); + void playerCyclopediaCharacterInfo(std::shared_ptr player, uint32_t characterID, CyclopediaCharacterInfoType_t characterInfoType, uint16_t entriesPerPage, uint16_t page); - void playerHighscores(Player* player, HighscoreType_t type, uint8_t category, uint32_t vocation, const std::string &worldName, uint16_t page, uint8_t entriesPerPage); + void playerHighscores(std::shared_ptr player, HighscoreType_t type, uint8_t category, uint32_t vocation, const std::string &worldName, uint16_t page, uint8_t entriesPerPage); void updatePlayerSaleItems(uint32_t playerId); - bool internalStartTrade(Player* player, Player* partner, Item* tradeItem); - void internalCloseTrade(Player* player); - bool playerBroadcastMessage(Player* player, const std::string &text) const; + bool internalStartTrade(std::shared_ptr player, std::shared_ptr partner, std::shared_ptr tradeItem); + void internalCloseTrade(std::shared_ptr player); + bool playerBroadcastMessage(std::shared_ptr player, const std::string &text) const; void broadcastMessage(const std::string &text, MessageClasses type) const; // Implementation of player invoked events void playerTeleport(uint32_t playerId, const Position &pos); void playerMoveThing(uint32_t playerId, const Position &fromPos, uint16_t itemId, uint8_t fromStackPos, const Position &toPos, uint8_t count); void playerMoveCreatureByID(uint32_t playerId, uint32_t movingCreatureId, const Position &movingCreatureOrigPos, const Position &toPos); - void playerMoveCreature(Player* playerId, Creature* movingCreature, const Position &movingCreatureOrigPos, Tile* toTile); + void playerMoveCreature(std::shared_ptr playerId, std::shared_ptr movingCreature, const Position &movingCreatureOrigPos, std::shared_ptr toTile); void playerMoveItemByPlayerID(uint32_t playerId, const Position &fromPos, uint16_t itemId, uint8_t fromStackPos, const Position &toPos, uint8_t count); - void playerMoveItem(Player* player, const Position &fromPos, uint16_t itemId, uint8_t fromStackPos, const Position &toPos, uint8_t count, Item* item, Cylinder* toCylinder); + void playerMoveItem(std::shared_ptr player, const Position &fromPos, uint16_t itemId, uint8_t fromStackPos, const Position &toPos, uint8_t count, std::shared_ptr item, std::shared_ptr toCylinder); void playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier = false, uint8_t tier = 0); void playerMove(uint32_t playerId, Direction direction); void forcePlayerMove(uint32_t playerId, Direction direction); @@ -311,8 +328,8 @@ class Game { void playerSetFightModes(uint32_t playerId, FightMode_t fightMode, bool chaseMode, bool secureMode); void playerLookAt(uint32_t playerId, uint16_t itemId, const Position &pos, uint8_t stackPos); void playerLookInBattleList(uint32_t playerId, uint32_t creatureId); - void playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t itemId, uint8_t stackPos, Item* defaultItem = nullptr, bool lootAllCorpses = false, bool autoLoot = false); - void playerLootAllCorpses(Player* player, const Position &pos, bool lootAllCorpses); + void playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t itemId, uint8_t stackPos, std::shared_ptr defaultItem = nullptr, bool lootAllCorpses = false, bool autoLoot = false); + void playerLootAllCorpses(std::shared_ptr player, const Position &pos, bool lootAllCorpses); void playerSetLootContainer(uint32_t playerId, ObjectCategory_t category, const Position &pos, uint16_t itemId, uint8_t stackPos); void playerClearLootContainer(uint32_t playerId, ObjectCategory_t category); ; @@ -325,7 +342,7 @@ class Game { void playerRequestDepotSearchItem(uint32_t playerId, uint16_t itemId, uint8_t tier); void playerRequestDepotSearchRetrieve(uint32_t playerId, uint16_t itemId, uint8_t tier, uint8_t type); void playerRequestOpenContainerFromDepotSearch(uint32_t playerId, const Position &pos); - void playerMoveThingFromDepotSearch(Player* player, uint16_t itemId, uint8_t tier, uint8_t count, const Position &fromPos, const Position &toPos, bool allItems = false); + void playerMoveThingFromDepotSearch(std::shared_ptr player, uint16_t itemId, uint8_t tier, uint8_t count, const Position &fromPos, const Position &toPos, bool allItems = false); void playerRequestAddVip(uint32_t playerId, const std::string &name); void playerRequestRemoveVip(uint32_t playerId, uint32_t guid); @@ -359,13 +376,11 @@ class Game { void playerOpenWheel(uint32_t playerId, uint32_t ownerId); void playerSaveWheel(uint32_t playerId, NetworkMessage &msg); - void updatePlayerHelpers(Player* player); + void updatePlayerHelpers(std::shared_ptr player); void cleanup(); void shutdown(); void dieSafely(std::string errorMsg); - void ReleaseCreature(Creature* creature); - void ReleaseItem(Item* item); void addBestiaryList(uint16_t raceid, std::string name); const std::map &getBestiaryList() const { return BestiaryList; @@ -383,18 +398,18 @@ class Game { bool canThrowObjectTo(const Position &fromPos, const Position &toPos, bool checkLineOfSight = true, int32_t rangex = MAP_MAX_CLIENT_VIEW_PORT_X, int32_t rangey = MAP_MAX_CLIENT_VIEW_PORT_Y); bool isSightClear(const Position &fromPos, const Position &toPos, bool sameFloor); - void changeSpeed(Creature* creature, int32_t varSpeedDelta); - void setCreatureSpeed(Creature* creature, int32_t speed); // setCreatureSpeed - void changePlayerSpeed(Player &player, int32_t varSpeedDelta); - void internalCreatureChangeOutfit(Creature* creature, const Outfit_t &oufit); - void internalCreatureChangeVisible(Creature* creature, bool visible); - void changeLight(const Creature* creature); - void updateCreatureIcon(const Creature* creature); - void reloadCreature(const Creature* creature); - void updateCreatureSkull(const Creature* player); - void updatePlayerShield(Player* player); - void updateCreatureType(Creature* creature); - void updateCreatureWalkthrough(const Creature* creature); + void changeSpeed(std::shared_ptr creature, int32_t varSpeedDelta); + void setCreatureSpeed(std::shared_ptr creature, int32_t speed); // setCreatureSpeed + void changePlayerSpeed(const std::shared_ptr &player, int32_t varSpeedDelta); + void internalCreatureChangeOutfit(std::shared_ptr creature, const Outfit_t &oufit); + void internalCreatureChangeVisible(std::shared_ptr creature, bool visible); + void changeLight(const std::shared_ptr creature); + void updateCreatureIcon(const std::shared_ptr creature); + void reloadCreature(const std::shared_ptr creature); + void updateCreatureSkull(std::shared_ptr player); + void updatePlayerShield(std::shared_ptr player); + void updateCreatureType(std::shared_ptr creature); + void updateCreatureWalkthrough(const std::shared_ptr creature); GameState_t getGameState() const; void setGameState(GameState_t newState); @@ -407,37 +422,37 @@ class Game { void checkCreatures(size_t index); void checkLight(); - bool combatBlockHit(CombatDamage &damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field); + bool combatBlockHit(CombatDamage &damage, std::shared_ptr attacker, std::shared_ptr target, bool checkDefense, bool checkArmor, bool field); - void combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColor_t &color, uint16_t &effect); + void combatGetTypeInfo(CombatType_t combatType, std::shared_ptr target, TextColor_t &color, uint16_t &effect); // Hazard combat helpers - void handleHazardSystemAttack(CombatDamage &damage, Player* player, const Monster* monster, bool isPlayerAttacker); - void notifySpectators(const SpectatorHashSet &spectators, const Position &targetPos, Player* attackerPlayer, Monster* targetMonster); + void handleHazardSystemAttack(CombatDamage &damage, std::shared_ptr player, const std::shared_ptr monster, bool isPlayerAttacker); + void notifySpectators(const SpectatorHashSet &spectators, const Position &targetPos, std::shared_ptr attackerPlayer, std::shared_ptr targetMonster); // Wheel of destiny combat helpers - void applyWheelOfDestinyHealing(CombatDamage &damage, Player* attackerPlayer, const Creature* target); - void applyWheelOfDestinyEffectsToDamage(CombatDamage &damage, const Player* attackerPlayer, const Creature* target) const; - int32_t applyHealthChange(CombatDamage &damage, const Creature* target) const; + void applyWheelOfDestinyHealing(CombatDamage &damage, std::shared_ptr attackerPlayer, std::shared_ptr target); + void applyWheelOfDestinyEffectsToDamage(CombatDamage &damage, std::shared_ptr attackerPlayer, std::shared_ptr target) const; + int32_t applyHealthChange(CombatDamage &damage, std::shared_ptr target) const; - bool combatChangeHealth(Creature* attacker, Creature* target, CombatDamage &damage, bool isEvent = false); - void applyCharmRune(const Monster* targetMonster, Player* attackerPlayer, Creature* target, const int32_t &realDamage) const; + bool combatChangeHealth(std::shared_ptr attacker, std::shared_ptr target, CombatDamage &damage, bool isEvent = false); + void applyCharmRune(std::shared_ptr targetMonster, std::shared_ptr attackerPlayer, std::shared_ptr target, const int32_t &realDamage) const; void applyManaLeech( - Player* attackerPlayer, const Monster* targetMonster, - Creature* target, const CombatDamage &damage, const int32_t &realDamage + std::shared_ptr attackerPlayer, std::shared_ptr targetMonster, + std::shared_ptr target, const CombatDamage &damage, const int32_t &realDamage ) const; void applyLifeLeech( - Player* attackerPlayer, const Monster* targetMonster, - Creature* target, const CombatDamage &damage, const int32_t &realDamage + std::shared_ptr attackerPlayer, std::shared_ptr targetMonster, + std::shared_ptr target, const CombatDamage &damage, const int32_t &realDamage ) const; int32_t calculateLeechAmount(const int32_t &realDamage, const uint16_t &skillAmount, int targetsAffected) const; - bool combatChangeMana(Creature* attacker, Creature* target, CombatDamage &damage); + bool combatChangeMana(std::shared_ptr attacker, std::shared_ptr target, CombatDamage &damage); // Animation help functions - void addCreatureHealth(const Creature* target); - static void addCreatureHealth(const SpectatorHashSet &spectators, const Creature* target); - void addPlayerMana(const Player* target); - void addPlayerVocation(const Player* target); + void addCreatureHealth(const std::shared_ptr target); + static void addCreatureHealth(const SpectatorHashSet &spectators, const std::shared_ptr target); + void addPlayerMana(const std::shared_ptr target); + void addPlayerVocation(const std::shared_ptr target); void addMagicEffect(const Position &pos, uint16_t effect); static void addMagicEffect(const SpectatorHashSet &spectators, const Position &pos, uint16_t effect); void removeMagicEffect(const Position &pos, uint16_t effect); @@ -463,18 +478,18 @@ class Game { motdNum++; } - void sendOfflineTrainingDialog(Player* player); + void sendOfflineTrainingDialog(std::shared_ptr player); const std::map> &getItemsPrice() const { return itemsPriceMap; } - const phmap::flat_hash_map &getPlayers() const { + const phmap::flat_hash_map> &getPlayers() const { return players; } - const std::map &getMonsters() const { + const std::map> &getMonsters() const { return monsters; } - const std::map &getNpcs() const { + const std::map> &getNpcs() const { return npcs; } @@ -482,31 +497,30 @@ class Game { return itemsClassifications; } - void addPlayer(Player* player); - void removePlayer(Player* player); + void addPlayer(std::shared_ptr player); + void removePlayer(std::shared_ptr player); - void addNpc(Npc* npc); - void removeNpc(Npc* npc); + void addNpc(std::shared_ptr npc); + void removeNpc(std::shared_ptr npc); - void addMonster(Monster* npc); - void removeMonster(Monster* npc); + void addMonster(std::shared_ptr npc); + void removeMonster(std::shared_ptr npc); std::shared_ptr getGuild(uint32_t id, bool allowOffline = false) const; std::shared_ptr getGuildByName(const std::string &name, bool allowOffline = false) const; void addGuild(const std::shared_ptr guild); void removeGuild(uint32_t guildId); - void decreaseBrowseFieldRef(const Position &pos); - phmap::flat_hash_map browseFields; + phmap::flat_hash_map, std::weak_ptr> browseFields; - void internalRemoveItems(const std::vector itemVector, uint32_t amount, bool stackable); + void internalRemoveItems(const std::vector> &itemVector, uint32_t amount, bool stackable); - BedItem* getBedBySleeper(uint32_t guid) const; - void setBedSleeper(BedItem* bed, uint32_t guid); + std::shared_ptr getBedBySleeper(uint32_t guid) const; + void setBedSleeper(std::shared_ptr bed, uint32_t guid); void removeBedSleeper(uint32_t guid); - Item* getUniqueItem(uint16_t uniqueId); - bool addUniqueItem(uint16_t uniqueId, Item* item); + std::shared_ptr getUniqueItem(uint16_t uniqueId); + bool addUniqueItem(uint16_t uniqueId, std::shared_ptr item); void removeUniqueItem(uint16_t uniqueId); bool hasEffect(uint16_t effectId); @@ -518,21 +532,21 @@ class Game { Raids raids; Canary::protobuf::appearances::Appearances appearances; - phmap::flat_hash_set getTilesToClean() const { + phmap::flat_hash_set> getTilesToClean() const { return tilesToClean; } - void addTileToClean(Tile* tile) { + void addTileToClean(std::shared_ptr tile) { tilesToClean.emplace(tile); } - void removeTileToClean(Tile* tile) { + void removeTileToClean(std::shared_ptr tile) { tilesToClean.erase(tile); } void clearTilesToClean() { tilesToClean.clear(); } - void playerInspectItem(Player* player, const Position &pos); - void playerInspectItem(Player* player, uint16_t itemId, uint8_t itemCount, bool cyclopedia); + void playerInspectItem(std::shared_ptr player, const Position &pos); + void playerInspectItem(std::shared_ptr player, uint16_t itemId, uint8_t itemCount, bool cyclopedia); void addCharmRune(const std::shared_ptr charm) { CharmList.push_back(charm); @@ -579,9 +593,9 @@ class Game { uint32_t makeFiendishMonster(uint32_t forgeableMonsterId = 0, bool createForgeableMonsters = false); uint32_t makeInfluencedMonster(); - bool addInfluencedMonster(Monster* monster); - void sendUpdateCreature(const Creature* creature); - Item* wrapItem(Item* item, House* house); + bool addInfluencedMonster(std::shared_ptr monster); + void sendUpdateCreature(std::shared_ptr creature); + std::shared_ptr wrapItem(std::shared_ptr item, std::shared_ptr house); /** * @brief Adds a player to the unique login map. @@ -590,7 +604,7 @@ class Game { * * @param player A pointer to the Player object to add. */ - void addPlayerUniqueLogin(Player* player); + void addPlayerUniqueLogin(std::shared_ptr player); /** * @brief Gets a player from the unique login map using their name. @@ -601,7 +615,7 @@ class Game { * @param playerName The name of the player to search for. * @return A pointer to the Player object if found, null otherwise. */ - Player* getPlayerUniqueLogin(const std::string &playerName) const; + std::shared_ptr getPlayerUniqueLogin(const std::string &playerName) const; /** * @brief Removes a player from the unique login map using their name. @@ -619,7 +633,7 @@ class Game { * * @param player A pointer to the Player object to remove. */ - void removePlayerUniqueLogin(Player* player); + void removePlayerUniqueLogin(std::shared_ptr player); void playerCheckActivity(const std::string &playerName, int interval); /** @@ -632,24 +646,27 @@ class Game { * @param item Pointer to the item to be checked. * @return True if stash items can be retrieved, false otherwise. */ - bool tryRetrieveStashItems(Player* player, Item* item); + bool tryRetrieveStashItems(std::shared_ptr player, std::shared_ptr item); - ReturnValue beforeCreatureZoneChange(Creature* creature, const phmap::parallel_flat_hash_set> &fromZones, const phmap::parallel_flat_hash_set> &toZones, bool force = false) const; - void afterCreatureZoneChange(Creature* creature, const phmap::parallel_flat_hash_set> &fromZones, const phmap::parallel_flat_hash_set> &toZones) const; + ReturnValue beforeCreatureZoneChange(std::shared_ptr creature, const phmap::parallel_flat_hash_set> &fromZones, const phmap::parallel_flat_hash_set> &toZones, bool force = false) const; + void afterCreatureZoneChange(std::shared_ptr creature, const phmap::parallel_flat_hash_set> &fromZones, const phmap::parallel_flat_hash_set> &toZones) const; std::unique_ptr &getIOWheel(); const std::unique_ptr &getIOWheel() const; + void setTransferPlayerHouseItems(uint32_t houseId, uint32_t playerId); + void transferHouseItemsToDepot(); + private: std::map forgeMonsterEventIds; std::set fiendishMonsters; std::set influencedMonsters; void checkImbuements(); - bool playerSaySpell(Player* player, SpeakClasses type, const std::string &text); - void playerWhisper(Player* player, const std::string &text); - bool playerYell(Player* player, const std::string &text); - bool playerSpeakTo(Player* player, SpeakClasses type, const std::string &receiver, const std::string &text); - void playerSpeakToNpc(Player* player, const std::string &text); + bool playerSaySpell(std::shared_ptr player, SpeakClasses type, const std::string &text); + void playerWhisper(std::shared_ptr player, const std::string &text); + bool playerYell(std::shared_ptr player, const std::string &text); + bool playerSpeakTo(std::shared_ptr player, SpeakClasses type, const std::string &receiver, const std::string &text); + void playerSpeakToNpc(std::shared_ptr player, const std::string &text); std::shared_ptr createPlayerTask(uint32_t delay, std::function f, std::string context) const; /** @@ -657,7 +674,7 @@ class Game { * \param player Player pointer * \param corpse Container pointer to be looted */ - void internalQuickLootCorpse(Player* player, Container* corpse); + void internalQuickLootCorpse(std::shared_ptr player, std::shared_ptr corpse); /** * @brief Finds the container for loot based on the given parameters. @@ -671,7 +688,7 @@ class Game { * * @return Pointer to the loot container or nullptr if not found. */ - Container* findLootContainer(Player* player, bool &fallbackConsumed, ObjectCategory_t category); + std::shared_ptr findLootContainer(std::shared_ptr player, bool &fallbackConsumed, ObjectCategory_t category); /** * @brief Finds the next available sub-container within a container. @@ -681,7 +698,7 @@ class Game { * @param lootContainer Reference to the loot container being used. * @return Pointer to the next available container or nullptr if not found. */ - Container* findNextAvailableContainer(ContainerIterator &containerIterator, Container*&lastSubContainer, Container*&lootContainer); + std::shared_ptr findNextAvailableContainer(ContainerIterator &containerIterator, std::shared_ptr &lastSubContainer, std::shared_ptr &lootContainer); /** * @brief Handles the fallback logic for loot containers. @@ -692,7 +709,7 @@ class Game { * @param fallbackConsumed Reference to a boolean flag indicating whether a fallback has been consumed. * @return True if fallback logic was handled, false otherwise. */ - bool handleFallbackLogic(const Player* player, Container*&lootContainer, ContainerIterator &containerIterator, const bool &fallbackConsumed); + bool handleFallbackLogic(std::shared_ptr player, std::shared_ptr &lootContainer, ContainerIterator &containerIterator, const bool &fallbackConsumed); /** * @brief Processes the movement or addition of an item to a loot container. @@ -703,7 +720,7 @@ class Game { * @param player Pointer to the player object. * @return Return value indicating success or error. */ - ReturnValue processMoveOrAddItemToLootContainer(Item* item, Container* lootContainer, uint32_t &remainderCount, Player* player); + ReturnValue processMoveOrAddItemToLootContainer(std::shared_ptr item, std::shared_ptr lootContainer, uint32_t &remainderCount, std::shared_ptr player); /** * @brief Processes loot items and places them into the appropriate containers. @@ -714,7 +731,7 @@ class Game { * @param fallbackConsumed Reference to a boolean flag indicating whether a fallback has been consumed. * @return Return value indicating success or error. */ - ReturnValue processLootItems(Player* player, Container* lootContainer, Item* item, bool &fallbackConsumed); + ReturnValue processLootItems(std::shared_ptr player, std::shared_ptr lootContainer, std::shared_ptr item, bool &fallbackConsumed); /** * @brief Internally collects loot items from a given item and places them into the loot container. @@ -724,7 +741,7 @@ class Game { * @param category Category of the item (default is OBJECTCATEGORY_DEFAULT). * @return Return value indicating success or error. */ - ReturnValue internalCollectLootItems(Player* player, Item* item, ObjectCategory_t category = OBJECTCATEGORY_DEFAULT); + ReturnValue internalCollectLootItems(std::shared_ptr player, std::shared_ptr item, ObjectCategory_t category = OBJECTCATEGORY_DEFAULT); /** * @brief Collects items from the reward chest. @@ -733,13 +750,13 @@ class Game { * @param maxMoveItems Maximum number of items to move (default is 0, which means no limit). * @return Return value indicating success or error. */ - ReturnValue collectRewardChestItems(Player* player, uint32_t maxMoveItems = 0); + ReturnValue collectRewardChestItems(std::shared_ptr player, uint32_t maxMoveItems = 0); - phmap::flat_hash_map m_uniqueLoginPlayerNames; - phmap::flat_hash_map players; - phmap::flat_hash_map mappedPlayerNames; + phmap::flat_hash_map> m_uniqueLoginPlayerNames; + phmap::flat_hash_map> players; + phmap::flat_hash_map> mappedPlayerNames; phmap::flat_hash_map> guilds; - phmap::flat_hash_map uniqueItems; + phmap::flat_hash_map> uniqueItems; std::map stages; /* Items stored from the lua scripts positions @@ -752,9 +769,7 @@ class Game { std::string boostedCreature = ""; std::vector> CharmList; - std::vector ToReleaseCreatures; - std::vector checkCreatureLists[EVENT_CREATURECOUNT]; - std::vector ToReleaseItems; + std::vector> checkCreatureLists[EVENT_CREATURECOUNT]; std::vector registeredMagicEffects; std::vector registeredDistanceEffects; @@ -765,18 +780,20 @@ class Game { WildcardTreeNode wildcardTree { false }; - std::map npcs; - std::map monsters; + std::map> npcs; + std::map> monsters; std::vector forgeableMonsters; - std::map teamFinderMap; // [leaderGUID] = TeamFinder* + std::map> teamFinderMap; // [leaderGUID] = TeamFinder* + + std::map transferHouseItemsToPlayer; // list of items that are in trading state, mapped to the player - std::map tradeItems; + std::map, uint32_t> tradeItems; - std::map bedSleepersMap; + std::map> bedSleepersMap; - phmap::flat_hash_set tilesToClean; + phmap::flat_hash_set> tilesToClean; ModalWindow offlineTrainingWindow { std::numeric_limits::max(), "Choose a Skill", "Please choose a skill:" }; @@ -813,47 +830,47 @@ class Game { std::vector itemsClassifications; - bool isTryingToStow(const Position &toPos, Cylinder* toCylinder) const; + bool isTryingToStow(const Position &toPos, std::shared_ptr toCylinder) const; void sendDamageMessageAndEffects( - const Creature* attacker, Creature* target, const CombatDamage &damage, const Position &targetPos, - Player* attackerPlayer, Player* targetPlayer, TextMessage &message, + std::shared_ptr attacker, std::shared_ptr target, const CombatDamage &damage, const Position &targetPos, + std::shared_ptr attackerPlayer, std::shared_ptr targetPlayer, TextMessage &message, const SpectatorHashSet &spectators, int32_t realDamage ); - void updatePlayerPartyHuntAnalyzer(const CombatDamage &damage, const Player* player) const; + void updatePlayerPartyHuntAnalyzer(const CombatDamage &damage, std::shared_ptr player) const; void sendEffects( - Creature* target, const CombatDamage &damage, const Position &targetPos, + std::shared_ptr target, const CombatDamage &damage, const Position &targetPos, TextMessage &message, const SpectatorHashSet &spectators ); void sendMessages( - const Creature* attacker, const Creature* target, const CombatDamage &damage, - const Position &targetPos, Player* attackerPlayer, Player* targetPlayer, + std::shared_ptr attacker, std::shared_ptr target, const CombatDamage &damage, + const Position &targetPos, std::shared_ptr attackerPlayer, std::shared_ptr targetPlayer, TextMessage &message, const SpectatorHashSet &spectators, int32_t realDamage ) const; bool shouldSendMessage(const TextMessage &message) const; void buildMessageAsAttacker( - const Creature* target, const CombatDamage &damage, TextMessage &message, + std::shared_ptr target, const CombatDamage &damage, TextMessage &message, std::stringstream &ss, const std::string &damageString ) const; void buildMessageAsTarget( - const Creature* attacker, const CombatDamage &damage, const Player* attackerPlayer, - const Player* targetPlayer, TextMessage &message, std::stringstream &ss, + std::shared_ptr attacker, const CombatDamage &damage, std::shared_ptr attackerPlayer, + std::shared_ptr targetPlayer, TextMessage &message, std::stringstream &ss, const std::string &damageString ) const; void buildMessageAsSpectator( - const Creature* attacker, const Creature* target, const CombatDamage &damage, - const Player* targetPlayer, TextMessage &message, std::stringstream &ss, + std::shared_ptr attacker, std::shared_ptr target, const CombatDamage &damage, + std::shared_ptr targetPlayer, TextMessage &message, std::stringstream &ss, const std::string &damageString, std::string &spectatorMessage ) const; - void unwrapItem(Item* item, uint16_t unWrapId, House* house, Player* player); + void unwrapItem(std::shared_ptr item, uint16_t unWrapId, std::shared_ptr house, std::shared_ptr player); // Variable members (m_) std::unique_ptr m_IOWheel; diff --git a/src/game/movement/teleport.cpp b/src/game/movement/teleport.cpp index 31bd42d11..5fdb984e1 100644 --- a/src/game/movement/teleport.cpp +++ b/src/game/movement/teleport.cpp @@ -31,28 +31,28 @@ void Teleport::serializeAttr(PropWriteStream &propWriteStream) const { propWriteStream.write(destPos.z); } -ReturnValue Teleport::queryAdd(int32_t, const Thing &, uint32_t, uint32_t, Creature*) const { +ReturnValue Teleport::queryAdd(int32_t, const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr) { return RETURNVALUE_NOTPOSSIBLE; } -ReturnValue Teleport::queryMaxCount(int32_t, const Thing &, uint32_t, uint32_t &, uint32_t) const { +ReturnValue Teleport::queryMaxCount(int32_t, const std::shared_ptr &, uint32_t, uint32_t &, uint32_t) { return RETURNVALUE_NOTPOSSIBLE; } -ReturnValue Teleport::queryRemove(const Thing &, uint32_t, uint32_t, Creature* /*= nullptr */) const { +ReturnValue Teleport::queryRemove(const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr /*= nullptr */) { return RETURNVALUE_NOERROR; } -Cylinder* Teleport::queryDestination(int32_t &, const Thing &, Item**, uint32_t &) { - return this; +std::shared_ptr Teleport::queryDestination(int32_t &, const std::shared_ptr &, std::shared_ptr*, uint32_t &) { + return getTeleport(); } -bool Teleport::checkInfinityLoop(Tile* destTile) { +bool Teleport::checkInfinityLoop(std::shared_ptr destTile) { if (!destTile) { return false; } - if (Teleport* teleport = destTile->getTeleportItem()) { + if (std::shared_ptr teleport = destTile->getTeleportItem()) { const Position &nextDestPos = teleport->getDestPos(); if (getPosition() == nextDestPos) { return true; @@ -62,16 +62,16 @@ bool Teleport::checkInfinityLoop(Tile* destTile) { return false; } -void Teleport::addThing(Thing* thing) { +void Teleport::addThing(std::shared_ptr thing) { return addThing(0, thing); } -void Teleport::addThing(int32_t, Thing* thing) { +void Teleport::addThing(int32_t, std::shared_ptr thing) { if (!thing) { return; } - Tile* destTile = g_game().map.getTile(destPos); + std::shared_ptr destTile = g_game().map.getTile(destPos); if (!destTile) { return; } @@ -87,15 +87,15 @@ void Teleport::addThing(int32_t, Thing* thing) { const MagicEffectClasses effect = Item::items[id].magicEffect; - if (Creature* creature = thing->getCreature()) { + if (std::shared_ptr creature = thing->getCreature()) { Position origPos = creature->getPosition(); g_game().internalCreatureTurn(creature, origPos.x > destPos.x ? DIRECTION_WEST : DIRECTION_EAST); - g_game().map.moveCreature(*creature, *destTile); + g_game().map.moveCreature(creature, destTile); if (effect != CONST_ME_NONE) { g_game().addMagicEffect(origPos, effect); g_game().addMagicEffect(destTile->getPosition(), effect); } - } else if (Item* item = thing->getItem()) { + } else if (std::shared_ptr item = thing->getItem()) { if (effect != CONST_ME_NONE) { g_game().addMagicEffect(destTile->getPosition(), effect); g_game().addMagicEffect(item->getPosition(), effect); @@ -104,22 +104,22 @@ void Teleport::addThing(int32_t, Thing* thing) { } } -void Teleport::updateThing(Thing*, uint16_t, uint32_t) { +void Teleport::updateThing(std::shared_ptr, uint16_t, uint32_t) { // } -void Teleport::replaceThing(uint32_t, Thing*) { +void Teleport::replaceThing(uint32_t, std::shared_ptr) { // } -void Teleport::removeThing(Thing*, uint32_t) { +void Teleport::removeThing(std::shared_ptr, uint32_t) { // } -void Teleport::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { +void Teleport::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { getParent()->postAddNotification(thing, oldParent, index, LINK_PARENT); } -void Teleport::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { +void Teleport::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { getParent()->postRemoveNotification(thing, newParent, index, LINK_PARENT); } diff --git a/src/game/movement/teleport.hpp b/src/game/movement/teleport.hpp index 1000b9daf..ed2d752ad 100644 --- a/src/game/movement/teleport.hpp +++ b/src/game/movement/teleport.hpp @@ -16,11 +16,8 @@ class Teleport final : public Item, public Cylinder { explicit Teleport(uint16_t type) : Item(type) {}; - Teleport* getTeleport() override { - return this; - } - const Teleport* getTeleport() const override { - return this; + std::shared_ptr getTeleport() override { + return static_self_cast(); } // serialization @@ -34,24 +31,24 @@ class Teleport final : public Item, public Cylinder { destPos = std::move(pos); } - bool checkInfinityLoop(Tile* destTile); + bool checkInfinityLoop(std::shared_ptr destTile); // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - ReturnValue queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const override; - ReturnValue queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - Cylinder* queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + ReturnValue queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) override; + ReturnValue queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + std::shared_ptr queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) override; - void addThing(Thing* thing) override; - void addThing(int32_t index, Thing* thing) override; + void addThing(std::shared_ptr thing) override; + void addThing(int32_t index, std::shared_ptr thing) override; - void updateThing(Thing* thing, uint16_t itemId, uint32_t count) override; - void replaceThing(uint32_t index, Thing* thing) override; + void updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) override; + void replaceThing(uint32_t index, std::shared_ptr thing) override; - void removeThing(Thing* thing, uint32_t count) override; + void removeThing(std::shared_ptr thing, uint32_t count) override; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; private: Position destPos; diff --git a/src/game/scheduling/dispatcher.cpp b/src/game/scheduling/dispatcher.cpp index 9f37393e3..9423c8799 100644 --- a/src/game/scheduling/dispatcher.cpp +++ b/src/game/scheduling/dispatcher.cpp @@ -21,12 +21,12 @@ Dispatcher &Dispatcher::getInstance() { return inject(); } -void Dispatcher::addTask(std::function f, std::string context) { - addTask(std::make_shared(std::move(f), std::move(context))); +void Dispatcher::addTask(std::function f, const std::string &context) { + addTask(std::make_shared(std::move(f), context)); } -void Dispatcher::addTask(std::function f, std::string context, uint32_t expiresAfterMs) { - addTask(std::make_shared(std::move(f), std::move(context)), expiresAfterMs); +void Dispatcher::addTask(std::function f, const std::string &context, uint32_t expiresAfterMs) { + addTask(std::make_shared(std::move(f), context), expiresAfterMs); } void Dispatcher::addTask(const std::shared_ptr task) { diff --git a/src/game/scheduling/dispatcher.hpp b/src/game/scheduling/dispatcher.hpp index 2beda8b34..7590773bd 100644 --- a/src/game/scheduling/dispatcher.hpp +++ b/src/game/scheduling/dispatcher.hpp @@ -30,8 +30,8 @@ class Dispatcher { static Dispatcher &getInstance(); - void addTask(std::function f, std::string context); - void addTask(std::function f, std::string context, uint32_t expiresAfterMs); + void addTask(std::function f, const std::string &context); + void addTask(std::function f, const std::string &context, uint32_t expiresAfterMs); void addTask(const std::shared_ptr task); void addTask(const std::shared_ptr task, uint32_t expiresAfterMs); diff --git a/src/game/scheduling/task.hpp b/src/game/scheduling/task.hpp index 1424679e8..a0d02a722 100644 --- a/src/game/scheduling/task.hpp +++ b/src/game/scheduling/task.hpp @@ -45,16 +45,28 @@ class Task { bool hasTraceableContext() const { return std::set { + "Creature::checkCreatureWalk", + "Decay::checkDecay", + "Game::checkCreatureAttack", "Game::checkCreatures", "Game::checkImbuements", "Game::checkLight", "Game::createFiendishMonsters", "Game::createInfluencedMonsters", + "Game::updateCreatureWalk", "Game::updateForgeableMonsters", "GlobalEvents::think", + "LuaEnvironment::executeTimerEvent", + "Modules::executeOnRecvbyte", "OutputMessagePool::sendAll", + "ProtocolGame::addGameTask", + "ProtocolGame::parsePacketFromDispatcher", + "Raids::checkRaids", "SpawnMonster::checkSpawnMonster", + "SpawnMonster::scheduleSpawn", + "SpawnNpc::checkSpawnNpc", "Webhook::run", + "sendRecvMessageCallback", } .contains(context); } diff --git a/src/game/zones/zone.cpp b/src/game/zones/zone.cpp index 56fc3a1af..40ec4e018 100644 --- a/src/game/zones/zone.cpp +++ b/src/game/zones/zone.cpp @@ -35,7 +35,7 @@ std::shared_ptr Zone::addZone(const std::string &name) { void Zone::addArea(Area area) { for (const Position &pos : area) { positions.insert(pos); - Tile* tile = g_game().map.getTile(pos); + std::shared_ptr tile = g_game().map.getTile(pos); if (tile) { for (auto item : *tile->getItemList()) { itemAdded(item); @@ -50,7 +50,7 @@ void Zone::addArea(Area area) { void Zone::subtractArea(Area area) { for (const Position &pos : area) { positions.erase(pos); - Tile* tile = g_game().map.getTile(pos); + std::shared_ptr tile = g_game().map.getTile(pos); if (tile) { for (auto item : *tile->getItemList()) { itemRemoved(item); @@ -66,7 +66,7 @@ bool Zone::isPositionInZone(const Position &pos) const { return positions.contains(pos); } -Position Zone::getRemoveDestination(Creature* creature /* = nullptr */) const { +Position Zone::getRemoveDestination(const std::shared_ptr &creature /* = nullptr */) const { if (!creature || !creature->getPlayer()) { return Position(); } @@ -87,11 +87,11 @@ const phmap::parallel_flat_hash_set &Zone::getPositions() const { return positions; } -const phmap::parallel_flat_hash_set &Zone::getTiles() const { - static phmap::parallel_flat_hash_set tiles; +const phmap::parallel_flat_hash_set> &Zone::getTiles() const { + static phmap::parallel_flat_hash_set> tiles; tiles.clear(); for (const auto &position : positions) { - Tile* tile = g_game().map.getTile(position); + const auto tile = g_game().map.getTile(position); if (tile) { tiles.insert(tile); } @@ -99,11 +99,11 @@ const phmap::parallel_flat_hash_set &Zone::getTiles() const { return tiles; } -const phmap::parallel_flat_hash_set &Zone::getCreatures() const { - static phmap::parallel_flat_hash_set creatures; +const phmap::parallel_flat_hash_set> &Zone::getCreatures() const { + static phmap::parallel_flat_hash_set> creatures; creatures.clear(); for (const auto creatureId : creaturesCache) { - auto creature = g_game().getCreatureByID(creatureId); + const auto creature = g_game().getCreatureByID(creatureId); if (creature) { creatures.insert(creature); } @@ -111,11 +111,11 @@ const phmap::parallel_flat_hash_set &Zone::getCreatures() const { return creatures; } -const phmap::parallel_flat_hash_set &Zone::getPlayers() const { - static phmap::parallel_flat_hash_set players; +const phmap::parallel_flat_hash_set> &Zone::getPlayers() const { + static phmap::parallel_flat_hash_set> players; players.clear(); for (const auto playerId : playersCache) { - auto player = g_game().getPlayerByID(playerId); + const auto player = g_game().getPlayerByID(playerId); if (player) { players.insert(player); } @@ -123,11 +123,11 @@ const phmap::parallel_flat_hash_set &Zone::getPlayers() const { return players; } -const phmap::parallel_flat_hash_set &Zone::getMonsters() const { - static phmap::parallel_flat_hash_set monsters; +const phmap::parallel_flat_hash_set> &Zone::getMonsters() const { + static phmap::parallel_flat_hash_set> monsters; monsters.clear(); for (const auto monsterId : monstersCache) { - auto monster = g_game().getMonsterByID(monsterId); + const auto monster = g_game().getMonsterByID(monsterId); if (monster) { monsters.insert(monster); } @@ -135,11 +135,11 @@ const phmap::parallel_flat_hash_set &Zone::getMonsters() const { return monsters; } -const phmap::parallel_flat_hash_set &Zone::getNpcs() const { - static phmap::parallel_flat_hash_set npcs; +const phmap::parallel_flat_hash_set> &Zone::getNpcs() const { + static phmap::parallel_flat_hash_set> npcs; npcs.clear(); for (const auto npcId : npcsCache) { - auto npc = g_game().getNpcByID(npcId); + const auto npc = g_game().getNpcByID(npcId); if (npc) { npcs.insert(npc); } @@ -147,7 +147,7 @@ const phmap::parallel_flat_hash_set &Zone::getNpcs() const { return npcs; } -const phmap::parallel_flat_hash_set &Zone::getItems() const { +const phmap::parallel_flat_hash_set> &Zone::getItems() const { return itemsCache; } @@ -194,7 +194,7 @@ const phmap::parallel_flat_hash_set> &Zone::getZones() { return zonesSet; } -void Zone::creatureAdded(Creature* creature) { +void Zone::creatureAdded(const std::shared_ptr &creature) { if (!creature) { return; } @@ -227,7 +227,7 @@ void Zone::creatureAdded(Creature* creature) { } } -void Zone::creatureRemoved(Creature* creature) { +void Zone::creatureRemoved(const std::shared_ptr &creature) { if (!creature) { return; } @@ -243,7 +243,7 @@ void Zone::creatureRemoved(Creature* creature) { } } -void Zone::thingAdded(Thing* thing) { +void Zone::thingAdded(const std::shared_ptr &thing) { if (!thing) { return; } @@ -255,14 +255,14 @@ void Zone::thingAdded(Thing* thing) { } } -void Zone::itemAdded(Item* item) { +void Zone::itemAdded(const std::shared_ptr &item) { if (!item) { return; } itemsCache.insert(item); } -void Zone::itemRemoved(Item* item) { +void Zone::itemRemoved(const std::shared_ptr &item) { if (!item) { return; } diff --git a/src/game/zones/zone.hpp b/src/game/zones/zone.hpp index 27626d469..f2f9545e8 100644 --- a/src/game/zones/zone.hpp +++ b/src/game/zones/zone.hpp @@ -10,6 +10,7 @@ #pragma once #include "game/movement/position.hpp" +#include "items/item.hpp" class Tile; class Creature; @@ -93,24 +94,24 @@ class Zone { void addArea(Area area); void subtractArea(Area area); bool isPositionInZone(const Position &position) const; - Position getRemoveDestination(Creature* creature = nullptr) const; + Position getRemoveDestination(const std::shared_ptr &creature = nullptr) const; void setRemoveDestination(const Position &position) { removeDestination = position; } const phmap::parallel_flat_hash_set &getPositions() const; - const phmap::parallel_flat_hash_set &getTiles() const; - const phmap::parallel_flat_hash_set &getCreatures() const; - const phmap::parallel_flat_hash_set &getPlayers() const; - const phmap::parallel_flat_hash_set &getMonsters() const; - const phmap::parallel_flat_hash_set &getNpcs() const; - const phmap::parallel_flat_hash_set &getItems() const; - - void creatureAdded(Creature* creature); - void creatureRemoved(Creature* creature); - void thingAdded(Thing* thing); - void itemAdded(Item* item); - void itemRemoved(Item* item); + const phmap::parallel_flat_hash_set> &getTiles() const; + const phmap::parallel_flat_hash_set> &getCreatures() const; + const phmap::parallel_flat_hash_set> &getPlayers() const; + const phmap::parallel_flat_hash_set> &getMonsters() const; + const phmap::parallel_flat_hash_set> &getNpcs() const; + const phmap::parallel_flat_hash_set> &getItems() const; + + void creatureAdded(const std::shared_ptr &creature); + void creatureRemoved(const std::shared_ptr &creature); + void thingAdded(const std::shared_ptr &thing); + void itemAdded(const std::shared_ptr &item); + void itemRemoved(const std::shared_ptr &item); void removePlayers() const; void removeMonsters() const; @@ -127,7 +128,7 @@ class Zone { std::string name; phmap::parallel_flat_hash_set positions; - phmap::parallel_flat_hash_set itemsCache; + phmap::parallel_flat_hash_set> itemsCache; phmap::parallel_flat_hash_set creaturesCache; phmap::parallel_flat_hash_set monstersCache; phmap::parallel_flat_hash_set npcsCache; diff --git a/src/io/functions/iologindata_load_player.cpp b/src/io/functions/iologindata_load_player.cpp index 39dcf910f..0fa1cd867 100644 --- a/src/io/functions/iologindata_load_player.cpp +++ b/src/io/functions/iologindata_load_player.cpp @@ -13,7 +13,7 @@ #include "io/functions/iologindata_load_player.hpp" #include "game/game.hpp" -void IOLoginDataLoad::loadItems(ItemsMap &itemsMap, DBResult_ptr result, Player &player) { +void IOLoginDataLoad::loadItems(ItemsMap &itemsMap, DBResult_ptr result, const std::shared_ptr &player) { try { do { uint32_t sid = result->getNumber("sid"); @@ -26,18 +26,18 @@ void IOLoginDataLoad::loadItems(ItemsMap &itemsMap, DBResult_ptr result, Player propStream.init(attr, attrSize); try { - Item* item = Item::CreateItem(type, count); + std::shared_ptr item = Item::CreateItem(type, count); if (item) { if (!item->unserializeAttr(propStream)) { - g_logger().warn("[{}] - Failed to deserialize item attributes {}, from player {}, from account id {}", __FUNCTION__, item->getID(), player.getName(), player.getAccountId()); - savePlayer(&player); + g_logger().warn("[{}] - Failed to deserialize item attributes {}, from player {}, from account id {}", __FUNCTION__, item->getID(), player->getName(), player->getAccountId()); + savePlayer(player); g_logger().info("[{}] - Deleting wrong item: {}", __FUNCTION__, item->getID()); - delete item; + continue; } itemsMap[sid] = std::make_pair(item, pid); } else { - g_logger().warn("[{}] - Failed to create item of type {} for player {}, from account id {}", __FUNCTION__, type, player.getName(), player.getAccountId()); + g_logger().warn("[{}] - Failed to create item of type {} for player {}, from account id {}", __FUNCTION__, type, player->getName(), player->getAccountId()); } } catch (const std::exception &e) { g_logger().warn("[{}] - Exception during the creation or deserialization of the item: {}", __FUNCTION__, e.what()); @@ -49,7 +49,7 @@ void IOLoginDataLoad::loadItems(ItemsMap &itemsMap, DBResult_ptr result, Player } } -bool IOLoginDataLoad::preLoadPlayer(Player* player, const std::string &name) { +bool IOLoginDataLoad::preLoadPlayer(std::shared_ptr player, const std::string &name) { Database &db = Database::getInstance(); std::ostringstream query; @@ -103,7 +103,7 @@ bool IOLoginDataLoad::preLoadPlayer(Player* player, const std::string &name) { return true; } -bool IOLoginDataLoad::loadPlayerFirst(Player* player, DBResult_ptr result) { +bool IOLoginDataLoad::loadPlayerFirst(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return false; @@ -162,7 +162,7 @@ bool IOLoginDataLoad::loadPlayerFirst(Player* player, DBResult_ptr result) { player->offlineTrainingTime = result->getNumber("offlinetraining_time") * 1000; auto skill = result->getInt8FromString(result->getString("offlinetraining_skill"), __FUNCTION__); player->setOfflineTrainingSkill(skill); - Town* town = g_game().map.towns.getTown(result->getNumber("town_id")); + const auto &town = g_game().map.towns.getTown(result->getNumber("town_id")); if (!town) { g_logger().error("Player {} has town id {} which doesn't exist", player->name, result->getNumber("town_id")); return false; @@ -183,7 +183,7 @@ bool IOLoginDataLoad::loadPlayerFirst(Player* player, DBResult_ptr result) { return true; } -void IOLoginDataLoad::loadPlayerExperience(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerExperience(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -206,7 +206,7 @@ void IOLoginDataLoad::loadPlayerExperience(Player* player, DBResult_ptr result) } } -void IOLoginDataLoad::loadPlayerBlessings(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerBlessings(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -219,7 +219,7 @@ void IOLoginDataLoad::loadPlayerBlessings(Player* player, DBResult_ptr result) { } } -void IOLoginDataLoad::loadPlayerConditions(const Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerConditions(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -230,20 +230,16 @@ void IOLoginDataLoad::loadPlayerConditions(const Player* player, DBResult_ptr re PropStream propStream; propStream.init(attr, attrSize); - std::list> conditionList; - Condition* condition = Condition::createCondition(propStream); + auto condition = Condition::createCondition(propStream); while (condition) { - std::unique_ptr uniqueCondition(condition); - if (uniqueCondition->unserialize(propStream)) { - conditionList.push_front(std::move(uniqueCondition)); - } else { - uniqueCondition.release(); // Release memory ownership + if (condition->unserialize(propStream)) { + player->storedConditionList.push_front(condition); } condition = Condition::createCondition(propStream); } } -void IOLoginDataLoad::loadPlayerDefaultOutfit(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerDefaultOutfit(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -274,7 +270,7 @@ void IOLoginDataLoad::loadPlayerDefaultOutfit(Player* player, DBResult_ptr resul player->currentOutfit = player->defaultOutfit; } -void IOLoginDataLoad::loadPlayerSkullSystem(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerSkullSystem(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -296,7 +292,7 @@ void IOLoginDataLoad::loadPlayerSkullSystem(Player* player, DBResult_ptr result) } } -void IOLoginDataLoad::loadPlayerSkill(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerSkill(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -318,7 +314,7 @@ void IOLoginDataLoad::loadPlayerSkill(Player* player, DBResult_ptr result) { } } -void IOLoginDataLoad::loadPlayerKills(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerKills(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -337,7 +333,7 @@ void IOLoginDataLoad::loadPlayerKills(Player* player, DBResult_ptr result) { } } -void IOLoginDataLoad::loadPlayerGuild(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerGuild(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -387,7 +383,7 @@ void IOLoginDataLoad::loadPlayerGuild(Player* player, DBResult_ptr result) { } } -void IOLoginDataLoad::loadPlayerStashItems(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerStashItems(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -403,7 +399,7 @@ void IOLoginDataLoad::loadPlayerStashItems(Player* player, DBResult_ptr result) } } -void IOLoginDataLoad::loadPlayerBestiaryCharms(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerBestiaryCharms(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -456,7 +452,7 @@ void IOLoginDataLoad::loadPlayerBestiaryCharms(Player* player, DBResult_ptr resu } } -void IOLoginDataLoad::loadPlayerInstantSpellList(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerInstantSpellList(std::shared_ptr player, DBResult_ptr result) { if (!player) { g_logger().warn("[IOLoginData::loadPlayer] - Player nullptr: {}", __FUNCTION__); return; @@ -472,7 +468,7 @@ void IOLoginDataLoad::loadPlayerInstantSpellList(Player* player, DBResult_ptr re } } -void IOLoginDataLoad::loadPlayerInventoryItems(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerInventoryItems(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -484,15 +480,15 @@ void IOLoginDataLoad::loadPlayerInventoryItems(Player* player, DBResult_ptr resu query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; ItemsMap inventoryItems; - std::vector> openContainersList; + std::vector>> openContainersList; try { if ((result = db.storeQuery(query.str()))) { - loadItems(inventoryItems, result, *player); + loadItems(inventoryItems, result, player); for (ItemsMap::const_reverse_iterator it = inventoryItems.rbegin(), end = inventoryItems.rend(); it != end; ++it) { - const std::pair &pair = it->second; - Item* item = pair.first; + const std::pair, int32_t> &pair = it->second; + std::shared_ptr item = pair.first; if (!item) { continue; } @@ -508,14 +504,14 @@ void IOLoginDataLoad::loadPlayerInventoryItems(Player* player, DBResult_ptr resu continue; } - Container* container = it2->second.first->getContainer(); + std::shared_ptr container = it2->second.first->getContainer(); if (container) { container->internalAddThing(item); item->startDecaying(); } } - Container* itemContainer = item->getContainer(); + std::shared_ptr itemContainer = item->getContainer(); if (itemContainer) { if (!oldProtocol) { auto cid = item->getAttribute(ItemAttribute_t::OPENCONTAINER); @@ -536,7 +532,7 @@ void IOLoginDataLoad::loadPlayerInventoryItems(Player* player, DBResult_ptr resu } if (!oldProtocol) { - std::ranges::sort(openContainersList.begin(), openContainersList.end(), [](const std::pair &left, const std::pair &right) { + std::ranges::sort(openContainersList.begin(), openContainersList.end(), [](const std::pair> &left, const std::pair> &right) { return left.first < right.first; }); @@ -550,7 +546,7 @@ void IOLoginDataLoad::loadPlayerInventoryItems(Player* player, DBResult_ptr resu } } -void IOLoginDataLoad::loadPlayerStoreInbox(Player* player) { +void IOLoginDataLoad::loadPlayerStoreInbox(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::loadPlayer] - Player nullptr: {}", __FUNCTION__); return; @@ -561,7 +557,7 @@ void IOLoginDataLoad::loadPlayerStoreInbox(Player* player) { } } -void IOLoginDataLoad::loadRewardItems(Player* player) { +void IOLoginDataLoad::loadRewardItems(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::loadPlayer] - Player nullptr: {}", __FUNCTION__); return; @@ -573,13 +569,13 @@ void IOLoginDataLoad::loadRewardItems(Player* player) { query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_rewards` WHERE `player_id` = " << player->getGUID() << " ORDER BY `pid`, `sid` ASC"; if (auto result = Database::getInstance().storeQuery(query.str())) { - loadItems(rewardItems, result, *player); + loadItems(rewardItems, result, player); bindRewardBag(player, rewardItems); insertItemsIntoRewardBag(rewardItems); } } -void IOLoginDataLoad::loadPlayerDepotItems(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerDepotItems(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -590,15 +586,14 @@ void IOLoginDataLoad::loadPlayerDepotItems(Player* player, DBResult_ptr result) std::ostringstream query; query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; if ((result = db.storeQuery(query.str()))) { - - loadItems(depotItems, result, *player); + loadItems(depotItems, result, player); for (ItemsMap::const_reverse_iterator it = depotItems.rbegin(), end = depotItems.rend(); it != end; ++it) { - const std::pair &pair = it->second; - Item* item = pair.first; + const std::pair, int32_t> &pair = it->second; + std::shared_ptr item = pair.first; int32_t pid = pair.second; if (pid >= 0 && pid < 100) { - DepotChest* depotChest = player->getDepotChest(pid, true); + std::shared_ptr depotChest = player->getDepotChest(pid, true); if (depotChest) { depotChest->internalAddThing(item); item->startDecaying(); @@ -609,7 +604,7 @@ void IOLoginDataLoad::loadPlayerDepotItems(Player* player, DBResult_ptr result) continue; } - Container* container = it2->second.first->getContainer(); + std::shared_ptr container = it2->second.first->getContainer(); if (container) { container->internalAddThing(item); item->startDecaying(); @@ -619,7 +614,7 @@ void IOLoginDataLoad::loadPlayerDepotItems(Player* player, DBResult_ptr result) } } -void IOLoginDataLoad::loadPlayerInboxItems(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerInboxItems(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -629,13 +624,12 @@ void IOLoginDataLoad::loadPlayerInboxItems(Player* player, DBResult_ptr result) std::ostringstream query; query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_inboxitems` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; if ((result = db.storeQuery(query.str()))) { - ItemsMap inboxItems; - loadItems(inboxItems, result, *player); + loadItems(inboxItems, result, player); for (ItemsMap::const_reverse_iterator it = inboxItems.rbegin(), end = inboxItems.rend(); it != end; ++it) { - const std::pair &pair = it->second; - Item* item = pair.first; + const std::pair, int32_t> &pair = it->second; + std::shared_ptr item = pair.first; int32_t pid = pair.second; if (pid >= 0 && pid < 100) { player->getInbox()->internalAddThing(item); @@ -646,7 +640,7 @@ void IOLoginDataLoad::loadPlayerInboxItems(Player* player, DBResult_ptr result) continue; } - Container* container = it2->second.first->getContainer(); + std::shared_ptr container = it2->second.first->getContainer(); if (container) { container->internalAddThing(item); item->startDecaying(); @@ -656,7 +650,7 @@ void IOLoginDataLoad::loadPlayerInboxItems(Player* player, DBResult_ptr result) } } -void IOLoginDataLoad::loadPlayerStorageMap(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerStorageMap(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -672,7 +666,7 @@ void IOLoginDataLoad::loadPlayerStorageMap(Player* player, DBResult_ptr result) } } -void IOLoginDataLoad::loadPlayerVip(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerVip(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -688,7 +682,7 @@ void IOLoginDataLoad::loadPlayerVip(Player* player, DBResult_ptr result) { } } -void IOLoginDataLoad::loadPlayerPreyClass(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerPreyClass(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -729,13 +723,13 @@ void IOLoginDataLoad::loadPlayerPreyClass(Player* player, DBResult_ptr result) { slot->raceIdList.push_back(raceId); } - player->setPreySlotClass(std::move(slot)); + player->setPreySlotClass(slot); } while (result->next()); } } } -void IOLoginDataLoad::loadPlayerTaskHuntingClass(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerTaskHuntingClass(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -779,13 +773,13 @@ void IOLoginDataLoad::loadPlayerTaskHuntingClass(Player* player, DBResult_ptr re slot->state = PreyTaskDataState_Selection; } - player->setTaskHuntingSlotClass(std::move(slot)); + player->setTaskHuntingSlotClass(slot); } while (result->next()); } } } -void IOLoginDataLoad::loadPlayerForgeHistory(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerForgeHistory(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -806,7 +800,7 @@ void IOLoginDataLoad::loadPlayerForgeHistory(Player* player, DBResult_ptr result } } -void IOLoginDataLoad::loadPlayerBosstiary(Player* player, DBResult_ptr result) { +void IOLoginDataLoad::loadPlayerBosstiary(std::shared_ptr player, DBResult_ptr result) { if (!result || !player) { g_logger().warn("[IOLoginData::loadPlayer] - Player or Result nullptr: {}", __FUNCTION__); return; @@ -838,7 +832,7 @@ void IOLoginDataLoad::loadPlayerBosstiary(Player* player, DBResult_ptr result) { } } -void IOLoginDataLoad::bindRewardBag(Player* player, ItemsMap &rewardItemsMap) { +void IOLoginDataLoad::bindRewardBag(std::shared_ptr player, ItemsMap &rewardItemsMap) { if (!player) { g_logger().warn("[IOLoginData::loadPlayer] - Player nullptr: {}", __FUNCTION__); return; @@ -849,7 +843,7 @@ void IOLoginDataLoad::bindRewardBag(Player* player, ItemsMap &rewardItemsMap) { if (pid == 0) { auto reward = player->getReward(item->getAttribute(ItemAttribute_t::DATE), true); if (reward) { - itemPair = std::pair(reward->getItem(), player->getRewardChest()->getID()); + itemPair = std::pair, int32_t>(reward->getItem(), player->getRewardChest()->getID()); } } else { break; @@ -859,8 +853,8 @@ void IOLoginDataLoad::bindRewardBag(Player* player, ItemsMap &rewardItemsMap) { void IOLoginDataLoad::insertItemsIntoRewardBag(const ItemsMap &rewardItemsMap) { for (const auto &it : std::views::reverse(rewardItemsMap)) { - const std::pair &pair = it.second; - Item* item = pair.first; + const std::pair, int32_t> &pair = it.second; + std::shared_ptr item = pair.first; int32_t pid = pair.second; if (pid == 0) { break; @@ -871,14 +865,14 @@ void IOLoginDataLoad::insertItemsIntoRewardBag(const ItemsMap &rewardItemsMap) { continue; } - Container* container = it2->second.first->getContainer(); + std::shared_ptr container = it2->second.first->getContainer(); if (container) { container->internalAddThing(item); } } } -void IOLoginDataLoad::loadPlayerInitializeSystem(Player* player) { +void IOLoginDataLoad::loadPlayerInitializeSystem(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::loadPlayer] - Player nullptr: {}", __FUNCTION__); return; @@ -892,7 +886,7 @@ void IOLoginDataLoad::loadPlayerInitializeSystem(Player* player) { player->initializeTaskHunting(); } -void IOLoginDataLoad::loadPlayerUpdateSystem(Player* player) { +void IOLoginDataLoad::loadPlayerUpdateSystem(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::loadPlayer] - Player nullptr: {}", __FUNCTION__); return; diff --git a/src/io/functions/iologindata_load_player.hpp b/src/io/functions/iologindata_load_player.hpp index 9ea937c7d..e8b0b4094 100644 --- a/src/io/functions/iologindata_load_player.hpp +++ b/src/io/functions/iologindata_load_player.hpp @@ -13,38 +13,38 @@ class IOLoginDataLoad : public IOLoginData { public: - static bool loadPlayerFirst(Player* player, DBResult_ptr result); - static bool preLoadPlayer(Player* player, const std::string &name); - static void loadPlayerExperience(Player* player, DBResult_ptr result); - static void loadPlayerBlessings(Player* player, DBResult_ptr result); - static void loadPlayerConditions(const Player* player, DBResult_ptr result); - static void loadPlayerDefaultOutfit(Player* player, DBResult_ptr result); - static void loadPlayerSkullSystem(Player* player, DBResult_ptr result); - static void loadPlayerSkill(Player* player, DBResult_ptr result); - static void loadPlayerKills(Player* player, DBResult_ptr result); - static void loadPlayerGuild(Player* player, DBResult_ptr result); - static void loadPlayerStashItems(Player* player, DBResult_ptr result); - static void loadPlayerBestiaryCharms(Player* player, DBResult_ptr result); - static void loadPlayerInstantSpellList(Player* player, DBResult_ptr result); - static void loadPlayerInventoryItems(Player* player, DBResult_ptr result); - static void loadPlayerStoreInbox(Player* player); - static void loadPlayerDepotItems(Player* player, DBResult_ptr result); - static void loadRewardItems(Player* player); - static void loadPlayerInboxItems(Player* player, DBResult_ptr result); - static void loadPlayerStorageMap(Player* player, DBResult_ptr result); - static void loadPlayerVip(Player* player, DBResult_ptr result); - static void loadPlayerPreyClass(Player* player, DBResult_ptr result); - static void loadPlayerTaskHuntingClass(Player* player, DBResult_ptr result); - static void loadPlayerForgeHistory(Player* player, DBResult_ptr result); - static void loadPlayerBosstiary(Player* player, DBResult_ptr result); - static void loadPlayerInitializeSystem(Player* player); - static void loadPlayerUpdateSystem(Player* player); + static bool loadPlayerFirst(std::shared_ptr player, DBResult_ptr result); + static bool preLoadPlayer(std::shared_ptr player, const std::string &name); + static void loadPlayerExperience(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerBlessings(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerConditions(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerDefaultOutfit(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerSkullSystem(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerSkill(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerKills(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerGuild(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerStashItems(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerBestiaryCharms(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerInstantSpellList(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerInventoryItems(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerStoreInbox(std::shared_ptr player); + static void loadPlayerDepotItems(std::shared_ptr player, DBResult_ptr result); + static void loadRewardItems(std::shared_ptr player); + static void loadPlayerInboxItems(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerStorageMap(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerVip(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerPreyClass(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerTaskHuntingClass(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerForgeHistory(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerBosstiary(std::shared_ptr player, DBResult_ptr result); + static void loadPlayerInitializeSystem(std::shared_ptr player); + static void loadPlayerUpdateSystem(std::shared_ptr player); private: - using ItemsMap = std::map>; + using ItemsMap = std::map, uint32_t>>; - static void bindRewardBag(Player* player, ItemsMap &rewardItemsMap); + static void bindRewardBag(std::shared_ptr player, ItemsMap &rewardItemsMap); static void insertItemsIntoRewardBag(const ItemsMap &rewardItemsMap); - static void loadItems(ItemsMap &itemsMap, DBResult_ptr result, Player &player); + static void loadItems(ItemsMap &itemsMap, DBResult_ptr result, const std::shared_ptr &player); }; diff --git a/src/io/functions/iologindata_save_player.cpp b/src/io/functions/iologindata_save_player.cpp index 130fa9e88..1c3db4053 100644 --- a/src/io/functions/iologindata_save_player.cpp +++ b/src/io/functions/iologindata_save_player.cpp @@ -12,7 +12,7 @@ #include "io/functions/iologindata_save_player.hpp" #include "game/game.hpp" -bool IOLoginDataSave::saveItems(const Player* player, const ItemBlockList &itemList, DBInsert &query_insert, PropWriteStream &propWriteStream) { +bool IOLoginDataSave::saveItems(std::shared_ptr player, const ItemBlockList &itemList, DBInsert &query_insert, PropWriteStream &propWriteStream) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -22,19 +22,19 @@ bool IOLoginDataSave::saveItems(const Player* player, const ItemBlockList &itemL std::ostringstream ss; // Initialize variables - using ContainerBlock = std::pair; + using ContainerBlock = std::pair, int32_t>; std::list queue; int32_t runningId = 100; // Loop through each item in itemList - const auto &openContainers = player->getOpenContainers(); + const auto openContainers = player->getOpenContainers(); for (const auto &it : itemList) { int32_t pid = it.first; - Item* item = it.second; + std::shared_ptr item = it.second; ++runningId; // Update container attributes if necessary - if (Container* container = item->getContainer()) { + if (std::shared_ptr container = item->getContainer()) { if (!container) { continue; // Check for null container } @@ -82,7 +82,7 @@ bool IOLoginDataSave::saveItems(const Player* player, const ItemBlockList &itemL // Loop through containers in queue while (!queue.empty()) { const ContainerBlock &cb = queue.front(); - Container* container = cb.first; + std::shared_ptr container = cb.first; int32_t parentId = cb.second; queue.pop_front(); @@ -91,7 +91,7 @@ bool IOLoginDataSave::saveItems(const Player* player, const ItemBlockList &itemL } // Loop through items in container - for (Item* item : container->getItemList()) { + for (std::shared_ptr item : container->getItemList()) { if (!item) { continue; // Check for null item } @@ -99,7 +99,7 @@ bool IOLoginDataSave::saveItems(const Player* player, const ItemBlockList &itemL ++runningId; // Update sub-container attributes if necessary - Container* subContainer = item->getContainer(); + std::shared_ptr subContainer = item->getContainer(); if (subContainer) { queue.emplace_back(subContainer, runningId); if (subContainer->getAttribute(ItemAttribute_t::OPENCONTAINER) > 0) { @@ -148,7 +148,7 @@ bool IOLoginDataSave::saveItems(const Player* player, const ItemBlockList &itemL return true; } -bool IOLoginDataSave::savePlayerFirst(Player* player) { +bool IOLoginDataSave::savePlayerFirst(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -227,7 +227,7 @@ bool IOLoginDataSave::savePlayerFirst(Player* player) { // serialize conditions PropWriteStream propWriteStream; - for (Condition* condition : player->conditions) { + for (const auto &condition : player->conditions) { if (condition->isPersistent()) { condition->serialize(propWriteStream); propWriteStream.write(CONDITIONATTR_END); @@ -313,7 +313,7 @@ bool IOLoginDataSave::savePlayerFirst(Player* player) { return true; } -bool IOLoginDataSave::savePlayerStash(const Player* player) { +bool IOLoginDataSave::savePlayerStash(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -339,7 +339,7 @@ bool IOLoginDataSave::savePlayerStash(const Player* player) { return true; } -bool IOLoginDataSave::savePlayerSpells(const Player* player) { +bool IOLoginDataSave::savePlayerSpells(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -368,7 +368,7 @@ bool IOLoginDataSave::savePlayerSpells(const Player* player) { return true; } -bool IOLoginDataSave::savePlayerKills(const Player* player) { +bool IOLoginDataSave::savePlayerKills(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -397,7 +397,7 @@ bool IOLoginDataSave::savePlayerKills(const Player* player) { return true; } -bool IOLoginDataSave::savePlayerBestiarySystem(const Player* player) { +bool IOLoginDataSave::savePlayerBestiarySystem(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -447,7 +447,7 @@ bool IOLoginDataSave::savePlayerBestiarySystem(const Player* player) { return true; } -bool IOLoginDataSave::savePlayerItem(const Player* player) { +bool IOLoginDataSave::savePlayerItem(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -466,7 +466,7 @@ bool IOLoginDataSave::savePlayerItem(const Player* player) { ItemBlockList itemList; for (int32_t slotId = CONST_SLOT_FIRST; slotId <= CONST_SLOT_LAST; ++slotId) { - Item* item = player->inventory[slotId]; + std::shared_ptr item = player->inventory[slotId]; if (item) { itemList.emplace_back(slotId, item); } @@ -479,7 +479,7 @@ bool IOLoginDataSave::savePlayerItem(const Player* player) { return true; } -bool IOLoginDataSave::savePlayerDepotItems(const Player* player) { +bool IOLoginDataSave::savePlayerDepotItems(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -501,7 +501,7 @@ bool IOLoginDataSave::savePlayerDepotItems(const Player* player) { DBInsert depotQuery("INSERT INTO `player_depotitems` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES "); for (const auto &[pid, depotChest] : player->depotChests) { - for (Item* item : depotChest->getItemList()) { + for (std::shared_ptr item : depotChest->getItemList()) { depotList.emplace_back(pid, item); } } @@ -514,7 +514,7 @@ bool IOLoginDataSave::savePlayerDepotItems(const Player* player) { return true; } -bool IOLoginDataSave::saveRewardItems(Player* player) { +bool IOLoginDataSave::saveRewardItems(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -548,7 +548,7 @@ bool IOLoginDataSave::saveRewardItems(Player* player) { return true; } -bool IOLoginDataSave::savePlayerInbox(const Player* player) { +bool IOLoginDataSave::savePlayerInbox(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -566,7 +566,7 @@ bool IOLoginDataSave::savePlayerInbox(const Player* player) { query.str(""); DBInsert inboxQuery("INSERT INTO `player_inboxitems` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES "); - for (Item* item : player->getInbox()->getItemList()) { + for (const auto &item : player->getInbox()->getItemList()) { inboxList.emplace_back(0, item); } @@ -576,7 +576,7 @@ bool IOLoginDataSave::savePlayerInbox(const Player* player) { return true; } -bool IOLoginDataSave::savePlayerPreyClass(Player* player) { +bool IOLoginDataSave::savePlayerPreyClass(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -586,8 +586,7 @@ bool IOLoginDataSave::savePlayerPreyClass(Player* player) { if (g_configManager().getBoolean(PREY_ENABLED)) { std::ostringstream query; for (uint8_t slotId = PreySlot_First; slotId <= PreySlot_Last; slotId++) { - PreySlot* slot = player->getPreySlotById(static_cast(slotId)); - if (slot) { + if (const auto &slot = player->getPreySlotById(static_cast(slotId))) { query.str(std::string()); query << "INSERT INTO player_prey (`player_id`, `slot`, `state`, `raceid`, `option`, `bonus_type`, `bonus_rarity`, `bonus_percentage`, `bonus_time`, `free_reroll`, `monster_list`) " << "VALUES (" << player->getGUID() << ", " @@ -631,7 +630,7 @@ bool IOLoginDataSave::savePlayerPreyClass(Player* player) { return true; } -bool IOLoginDataSave::savePlayerTaskHuntingClass(Player* player) { +bool IOLoginDataSave::savePlayerTaskHuntingClass(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -641,8 +640,7 @@ bool IOLoginDataSave::savePlayerTaskHuntingClass(Player* player) { if (g_configManager().getBoolean(TASK_HUNTING_ENABLED)) { std::ostringstream query; for (uint8_t slotId = PreySlot_First; slotId <= PreySlot_Last; slotId++) { - TaskHuntingSlot* slot = player->getTaskHuntingSlotById(static_cast(slotId)); - if (slot) { + if (const auto &slot = player->getTaskHuntingSlotById(static_cast(slotId))) { query.str(""); query << "INSERT INTO `player_taskhunt` (`player_id`, `slot`, `state`, `raceid`, `upgrade`, `rarity`, `kills`, `disabled_time`, `free_reroll`, `monster_list`) VALUES ("; query << player->getGUID() << ", "; @@ -684,7 +682,7 @@ bool IOLoginDataSave::savePlayerTaskHuntingClass(Player* player) { return true; } -bool IOLoginDataSave::savePlayerForgeHistory(Player* player) { +bool IOLoginDataSave::savePlayerForgeHistory(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -718,7 +716,7 @@ bool IOLoginDataSave::savePlayerForgeHistory(Player* player) { return true; } -bool IOLoginDataSave::savePlayerBosstiary(const Player* player) { +bool IOLoginDataSave::savePlayerBosstiary(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; @@ -762,7 +760,7 @@ bool IOLoginDataSave::savePlayerBosstiary(const Player* player) { return true; } -bool IOLoginDataSave::savePlayerStorage(Player* player) { +bool IOLoginDataSave::savePlayerStorage(std::shared_ptr player) { if (!player) { g_logger().warn("[IOLoginData::savePlayer] - Player nullptr: {}", __FUNCTION__); return false; diff --git a/src/io/functions/iologindata_save_player.hpp b/src/io/functions/iologindata_save_player.hpp index 8b35dd7f5..1c3cf89cb 100644 --- a/src/io/functions/iologindata_save_player.hpp +++ b/src/io/functions/iologindata_save_player.hpp @@ -13,26 +13,26 @@ class IOLoginDataSave : public IOLoginData { public: - static bool savePlayerFirst(Player* player); - static bool savePlayerStash(const Player* player); - static bool savePlayerSpells(const Player* player); - static bool savePlayerKills(const Player* player); - static bool savePlayerBestiarySystem(const Player* player); - static bool savePlayerItem(const Player* player); - static bool savePlayerDepotItems(const Player* player); - static bool saveRewardItems(Player* player); - static bool savePlayerInbox(const Player* player); - static bool savePlayerPreyClass(Player* player); - static bool savePlayerTaskHuntingClass(Player* player); - static bool savePlayerForgeHistory(Player* player); - static bool savePlayerBosstiary(const Player* player); - static bool savePlayerStorage(Player* palyer); + static bool savePlayerFirst(std::shared_ptr player); + static bool savePlayerStash(std::shared_ptr player); + static bool savePlayerSpells(std::shared_ptr player); + static bool savePlayerKills(std::shared_ptr player); + static bool savePlayerBestiarySystem(std::shared_ptr player); + static bool savePlayerItem(std::shared_ptr player); + static bool savePlayerDepotItems(std::shared_ptr player); + static bool saveRewardItems(std::shared_ptr player); + static bool savePlayerInbox(std::shared_ptr player); + static bool savePlayerPreyClass(std::shared_ptr player); + static bool savePlayerTaskHuntingClass(std::shared_ptr player); + static bool savePlayerForgeHistory(std::shared_ptr player); + static bool savePlayerBosstiary(std::shared_ptr player); + static bool savePlayerStorage(std::shared_ptr palyer); protected: - using ItemBlockList = std::list>; - using ItemDepotList = std::list>; - using ItemRewardList = std::list>; - using ItemInboxList = std::list>; + using ItemBlockList = std::list>>; + using ItemDepotList = std::list>>; + using ItemRewardList = std::list>>; + using ItemInboxList = std::list>>; - static bool saveItems(const Player* player, const ItemBlockList &itemList, DBInsert &query_insert, PropWriteStream &stream); + static bool saveItems(std::shared_ptr player, const ItemBlockList &itemList, DBInsert &query_insert, PropWriteStream &stream); }; diff --git a/src/io/io_bosstiary.cpp b/src/io/io_bosstiary.cpp index 45a650765..cda3336af 100644 --- a/src/io/io_bosstiary.cpp +++ b/src/io/io_bosstiary.cpp @@ -164,7 +164,7 @@ std::shared_ptr IOBosstiary::getMonsterTypeByBossRaceId(uint16_t ra return nullptr; } -void IOBosstiary::addBosstiaryKill(Player* player, const std::shared_ptr mtype, uint32_t amount /*= 1*/) const { +void IOBosstiary::addBosstiaryKill(std::shared_ptr player, const std::shared_ptr mtype, uint32_t amount /*= 1*/) const { if (!player || !mtype) { return; } @@ -176,6 +176,7 @@ void IOBosstiary::addBosstiaryKill(Player* player, const std::shared_ptraddBestiaryKillCount(bossId, amount); + player->refreshCyclopediaMonsterTracker(true); auto newBossLevel = getBossCurrentLevel(player, bossId); if (oldBossLevel == newBossLevel) { return; @@ -230,7 +231,7 @@ uint32_t IOBosstiary::calculateBossPoints(uint16_t lootBonus) const { return static_cast((2.5 * lootBonus * lootBonus) - (477.5 * lootBonus) + 24000); } -phmap::parallel_flat_hash_set IOBosstiary::getBosstiaryFinished(const Player* player, uint8_t level /* = 1*/) const { +phmap::parallel_flat_hash_set IOBosstiary::getBosstiaryFinished(std::shared_ptr player, uint8_t level /* = 1*/) const { phmap::parallel_flat_hash_set unlockedMonsters; if (!player) { return unlockedMonsters; @@ -264,7 +265,7 @@ phmap::parallel_flat_hash_set IOBosstiary::getBosstiaryFinished(const return unlockedMonsters; } -uint8_t IOBosstiary::getBossCurrentLevel(const Player* player, uint16_t bossId) const { +uint8_t IOBosstiary::getBossCurrentLevel(std::shared_ptr player, uint16_t bossId) const { if (bossId == 0 || !player) { return 0; } @@ -299,7 +300,7 @@ uint32_t IOBosstiary::calculteRemoveBoss(uint8_t removeTimes) const { return 300000 * removeTimes - 500000; } -std::vector IOBosstiary::getBosstiaryCooldownRaceId(const Player* player) const { +std::vector IOBosstiary::getBosstiaryCooldownRaceId(std::shared_ptr player) const { std::vector bossesCooldownRaceId; if (!player) { return bossesCooldownRaceId; diff --git a/src/io/io_bosstiary.hpp b/src/io/io_bosstiary.hpp index 912ee1fab..bbb1367e8 100644 --- a/src/io/io_bosstiary.hpp +++ b/src/io/io_bosstiary.hpp @@ -60,13 +60,13 @@ class IOBosstiary { uint16_t getBoostedBossId() const; std::shared_ptr getMonsterTypeByBossRaceId(uint16_t raceId) const; - void addBosstiaryKill(Player* player, const std::shared_ptr mtype, uint32_t amount = 1) const; + void addBosstiaryKill(std::shared_ptr player, const std::shared_ptr mtype, uint32_t amount = 1) const; uint16_t calculateLootBonus(uint32_t bossPoints) const; uint32_t calculateBossPoints(uint16_t lootBonus) const; - phmap::parallel_flat_hash_set getBosstiaryFinished(const Player* player, uint8_t level = 1) const; - uint8_t getBossCurrentLevel(const Player* player, uint16_t bossId) const; + phmap::parallel_flat_hash_set getBosstiaryFinished(std::shared_ptr player, uint8_t level = 1) const; + uint8_t getBossCurrentLevel(std::shared_ptr player, uint16_t bossId) const; uint32_t calculteRemoveBoss(uint8_t removeTimes) const; - std::vector getBosstiaryCooldownRaceId(const Player* player) const; + std::vector getBosstiaryCooldownRaceId(std::shared_ptr player) const; const std::vector &getBossRaceKillStages(BosstiaryRarity_t race) const; private: diff --git a/src/io/io_wheel.cpp b/src/io/io_wheel.cpp index 976284bae..3db059a80 100644 --- a/src/io/io_wheel.cpp +++ b/src/io/io_wheel.cpp @@ -59,7 +59,7 @@ namespace InternalPlayerWheel { if (spell) { g_logger().debug("[{}] registering instant spell with name {}", __FUNCTION__, spell->getName()); // Increase data - const auto &increaseData = spellData.increase; + const auto increaseData = spellData.increase; if (increaseData.damage > 0) { spell->setWheelOfDestinyBoost(WheelSpellBoost_t::DAMAGE, gradeType, increaseData.damage); } @@ -74,7 +74,7 @@ namespace InternalPlayerWheel { } // Decrease data - const auto &decreaseData = spellData.decrease; + const auto decreaseData = spellData.decrease; if (decreaseData.cooldown > 0) { spell->setWheelOfDestinyBoost(WheelSpellBoost_t::COOLDOWN, gradeType, decreaseData.cooldown * 1000); } @@ -85,7 +85,7 @@ namespace InternalPlayerWheel { spell->setWheelOfDestinyBoost(WheelSpellBoost_t::SECONDARY_GROUP_COOLDOWN, gradeType, decreaseData.secondaryGroupCooldown * 1000); } // Leech data - const auto &leechData = spellData.leech; + const auto leechData = spellData.leech; if (leechData.mana > 0) { spell->setWheelOfDestinyBoost(WheelSpellBoost_t::MANA_LEECH, gradeType, leechData.mana * 100); } @@ -124,7 +124,7 @@ bool IOWheel::initializeGlobalData(bool reload /* = false*/) { // Register spells for druid for (const auto &data : getWheelBonusData().spells.druid) { for (size_t i = 1; i < 3; ++i) { - const auto &grade = data.grade[i]; + const auto grade = data.grade[i]; InternalPlayerWheel::registerWheelSpellTable(grade, data.name, static_cast(i)); } } @@ -170,7 +170,7 @@ const std::vector &IOWheel::getFocusSpells() const { return InternalPlayerWheel::m_focusSpells; } -using VocationBonusFunction = std::function; +using VocationBonusFunction = std::function &, uint16_t, uint8_t, PlayerWheelMethodsBonusData &)>; using VocationBonusMap = std::map; const VocationBonusMap &IOWheel::getWheelMapFunctions() const { return m_vocationBonusMap; @@ -306,8 +306,8 @@ void IOWheel::initializeSorcererSpells() { m_wheelBonusData.spells.sorcerer[4].grade[2].decrease.secondaryGroupCooldown = 4; } -bool IOWheel::isMaxPointAddedToSlot(Player &player, uint16_t points, WheelSlots_t slotType) const { - return points == player.wheel()->getPointsBySlotType(slotType) && points == player.wheel()->getMaxPointsPerSlot(slotType); +bool IOWheel::isMaxPointAddedToSlot(const std::shared_ptr &player, uint16_t points, WheelSlots_t slotType) const { + return points == player->wheel()->getPointsBySlotType(slotType) && points == player->wheel()->getMaxPointsPerSlot(slotType); } bool IOWheel::isKnight(uint8_t vocationId) const { @@ -326,13 +326,13 @@ bool IOWheel::isDruid(uint8_t vocationId) const { return vocationId == Vocation_t::VOCATION_DRUID_CIP; } -void IOWheel::addSpell(Player &player, PlayerWheelMethodsBonusData &bonusData, WheelSlots_t slotType, uint16_t points, const std::string &spellName) const { +void IOWheel::addSpell(const std::shared_ptr &player, PlayerWheelMethodsBonusData &bonusData, WheelSlots_t slotType, uint16_t points, const std::string &spellName) const { if (isMaxPointAddedToSlot(player, points, slotType)) { bonusData.spells.push_back(spellName); } } -void IOWheel::increaseResistance(Player &player, PlayerWheelMethodsBonusData &bonusData, WheelSlots_t slotType, uint16_t points, CombatType_t combat, int16_t value) const { +void IOWheel::increaseResistance(const std::shared_ptr &player, PlayerWheelMethodsBonusData &bonusData, WheelSlots_t slotType, uint16_t points, CombatType_t combat, int16_t value) const { if (isMaxPointAddedToSlot(player, points, slotType)) { bonusData.resistance[combatTypeToIndex(combat)] += value; } @@ -384,7 +384,7 @@ void IOWheel::initializeWheelMapFunctions() { } // SLOT_GREEN_200 = 1 -void IOWheel::slotGreen200(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreen200(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { auto pointsInSlot = isMaxPointAddedToSlot(player, points, WheelSlots_t::SLOT_GREEN_200); if (isKnight(vocationCipId)) { bonusData.stats.health += 3 * points; @@ -410,13 +410,13 @@ void IOWheel::slotGreen200(Player &player, uint16_t points, uint8_t vocationCipI } // SLOT_GREEN_TOP_150 = 2 -void IOWheel::slotGreenTop150(Player &player, uint16_t points, uint8_t, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreenTop150(const std::shared_ptr &player, uint16_t points, uint8_t, PlayerWheelMethodsBonusData &bonusData) const { bonusData.mitigation += 0.03 * points; increaseResistance(player, bonusData, WheelSlots_t::SLOT_GREEN_TOP_150, points, COMBAT_ICEDAMAGE, 200); } // SLOT_GREEN_TOP_100 = 3 -void IOWheel::slotGreenTop100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreenTop100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.health += 3 * points; } else if (isPaladin(vocationCipId)) { @@ -430,7 +430,7 @@ void IOWheel::slotGreenTop100(Player &player, uint16_t points, uint8_t vocationC } // SLOT_RED_TOP_100 = 4 -void IOWheel::slotRedTop100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRedTop100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { auto pointsInSlot = isMaxPointAddedToSlot(player, points, WheelSlots_t::SLOT_RED_TOP_100); if (isKnight(vocationCipId)) { bonusData.stats.mana += 1 * points; @@ -451,7 +451,7 @@ void IOWheel::slotRedTop100(Player &player, uint16_t points, uint8_t vocationCip } // SLOT_RED_TOP_150 = 5 -void IOWheel::slotRedTop150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRedTop150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.health += 3 * points; } else if (isPaladin(vocationCipId)) { @@ -466,7 +466,7 @@ void IOWheel::slotRedTop150(Player &player, uint16_t points, uint8_t vocationCip } // SLOT_RED_200 = 6 -void IOWheel::slotRed200(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRed200(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_RED_200, points, "Front Sweep"); bonusData.stats.health += 3 * points; @@ -489,7 +489,7 @@ void IOWheel::slotRed200(Player &player, uint16_t points, uint8_t vocationCipId, } // SLOT_GREEN_BOTTOM_150 = 7 -void IOWheel::slotGreenBottom150(Player &player, uint16_t points, uint8_t, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreenBottom150(const std::shared_ptr &player, uint16_t points, uint8_t, PlayerWheelMethodsBonusData &bonusData) const { bonusData.mitigation += 0.03 * points; // 0,03% if (isMaxPointAddedToSlot(player, points, WheelSlots_t::SLOT_GREEN_BOTTOM_150)) { bonusData.leech.manaLeech += 0.25; // 0,25% @@ -497,7 +497,7 @@ void IOWheel::slotGreenBottom150(Player &player, uint16_t points, uint8_t, Playe } // SLOT_GREEN_MIDDLE_100 = 8 -void IOWheel::slotGreenMiddle100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreenMiddle100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_GREEN_MIDDLE_100, points, "Groundshaker"); bonusData.stats.health += 3 * points; @@ -515,7 +515,7 @@ void IOWheel::slotGreenMiddle100(Player &player, uint16_t points, uint8_t vocati } // SLOT_GREEN_TOP_75 = 9 -void IOWheel::slotGreenTop75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreenTop75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.mana += 1 * points; } else if (isPaladin(vocationCipId)) { @@ -529,7 +529,7 @@ void IOWheel::slotGreenTop75(Player &player, uint16_t points, uint8_t vocationCi } // SLOT_RED_TOP_75 = 10 -void IOWheel::slotRedTop75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRedTop75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.capacity += 5 * points; } else if (isPaladin(vocationCipId)) { @@ -542,7 +542,7 @@ void IOWheel::slotRedTop75(Player &player, uint16_t points, uint8_t vocationCipI } // SLOT_RED_MIDDLE_100 = 11 -void IOWheel::slotRedMiddle100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRedMiddle100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_RED_MIDDLE_100, points, "Chivalrous Challenge"); bonusData.stats.mana += 1 * points; @@ -560,7 +560,7 @@ void IOWheel::slotRedMiddle100(Player &player, uint16_t points, uint8_t vocation } // SLOT_RED_BOTTOM_150 = 12 -void IOWheel::slotRedBottom150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRedBottom150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.health += 3 * points; } else if (isPaladin(vocationCipId)) { @@ -574,7 +574,7 @@ void IOWheel::slotRedBottom150(Player &player, uint16_t points, uint8_t vocation } // SLOT_GREEN_BOTTOM_100 = 13 -void IOWheel::slotGreenBottom100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreenBottom100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_GREEN_BOTTOM_100, points, "Intense Wound Cleansing"); bonusData.stats.health += 3 * points; @@ -592,7 +592,7 @@ void IOWheel::slotGreenBottom100(Player &player, uint16_t points, uint8_t vocati } // SLOT_GREEN_BOTTOM_75 = 14 -void IOWheel::slotGreenBottom75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreenBottom75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { auto pointsInSlot = isMaxPointAddedToSlot(player, points, WheelSlots_t::SLOT_GREEN_BOTTOM_75); if (isKnight(vocationCipId)) { bonusData.stats.mana += 1 * points; @@ -613,7 +613,7 @@ void IOWheel::slotGreenBottom75(Player &player, uint16_t points, uint8_t vocatio } // SLOT_GREEN_50 = 15 -void IOWheel::slotGreen50(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotGreen50(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.capacity += 5 * points; } else if (isPaladin(vocationCipId)) { @@ -626,7 +626,7 @@ void IOWheel::slotGreen50(Player &player, uint16_t points, uint8_t vocationCipId } // SLOT_RED_50 = 16 -void IOWheel::slotRed50(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRed50(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { bonusData.mitigation += 0.03 * points; // 0,03% if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_RED_50, points, "Fierce Berserk"); @@ -640,7 +640,7 @@ void IOWheel::slotRed50(Player &player, uint16_t points, uint8_t vocationCipId, } // SLOT_RED_BOTTOM_75 = 17 -void IOWheel::slotRedBottom75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRedBottom75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.capacity += 5 * points; } else if (isPaladin(vocationCipId)) { @@ -654,7 +654,7 @@ void IOWheel::slotRedBottom75(Player &player, uint16_t points, uint8_t vocationC } // SLOT_RED_BOTTOM_100 = 18 -void IOWheel::slotRedBottom100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotRedBottom100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.mana += 1 * points; } else if (isPaladin(vocationCipId)) { @@ -667,13 +667,13 @@ void IOWheel::slotRedBottom100(Player &player, uint16_t points, uint8_t vocation } // SLOT_BLUE_TOP_100 = 19 -void IOWheel::slotBlueTop100(Player &player, uint16_t points, uint8_t, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlueTop100(const std::shared_ptr &player, uint16_t points, uint8_t, PlayerWheelMethodsBonusData &bonusData) const { bonusData.mitigation += 0.03 * points; // 0,03% increaseResistance(player, bonusData, WheelSlots_t::SLOT_BLUE_TOP_100, points, COMBAT_ENERGYDAMAGE, 200); } // SLOT_BLUE_TOP_75 = 20 -void IOWheel::slotBlueTop75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlueTop75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.health += 3 * points; } else if (isPaladin(vocationCipId)) { @@ -687,7 +687,7 @@ void IOWheel::slotBlueTop75(Player &player, uint16_t points, uint8_t vocationCip } // SLOT_BLUE_50 = 21 -void IOWheel::slotBlue50(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlue50(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_BLUE_50, points, "Front Sweep"); bonusData.stats.mana += 1 * points; @@ -707,7 +707,7 @@ void IOWheel::slotBlue50(Player &player, uint16_t points, uint8_t vocationCipId, } // SLOT_PURPLE_50 = 22 -void IOWheel::slotPurple50(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurple50(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.health += 3 * points; } else if (isPaladin(vocationCipId)) { @@ -720,7 +720,7 @@ void IOWheel::slotPurple50(Player &player, uint16_t points, uint8_t vocationCipI } // SLOT_PURPLE_TOP_75 = 23 -void IOWheel::slotPurpleTop75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurpleTop75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { bonusData.mitigation += 0.03 * points; // 0,03% auto pointsInSlot = isMaxPointAddedToSlot(player, points, WheelSlots_t::SLOT_PURPLE_TOP_75); if (isKnight(vocationCipId)) { @@ -739,7 +739,7 @@ void IOWheel::slotPurpleTop75(Player &player, uint16_t points, uint8_t vocationC } // SLOT_PURPLE_TOP_100 = 24 -void IOWheel::slotPurpleTop100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurpleTop100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_PURPLE_TOP_100, points, "Groundshaker"); bonusData.stats.capacity += 5 * points; @@ -757,7 +757,7 @@ void IOWheel::slotPurpleTop100(Player &player, uint16_t points, uint8_t vocation } // SLOT_BLUE_TOP_150 = 25 -void IOWheel::slotBlueTop150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlueTop150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.capacity += 5 * points; } else if (isPaladin(vocationCipId)) { @@ -772,7 +772,7 @@ void IOWheel::slotBlueTop150(Player &player, uint16_t points, uint8_t vocationCi } // SLOT_BLUE_MIDDLE_100 = 26 -void IOWheel::slotBlueMiddle100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlueMiddle100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { bonusData.mitigation += 0.03 * points; // 0,03% if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_BLUE_MIDDLE_100, points, "Chivalrous Challenge"); @@ -788,7 +788,7 @@ void IOWheel::slotBlueMiddle100(Player &player, uint16_t points, uint8_t vocatio } // SLOT_BLUE_BOTTOM_75 = 27 -void IOWheel::slotBlueBottom75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlueBottom75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.health += 3 * points; } else if (isPaladin(vocationCipId)) { @@ -801,14 +801,14 @@ void IOWheel::slotBlueBottom75(Player &player, uint16_t points, uint8_t vocation } // SLOT_PURPLE_BOTTOM_75 = 28 -void IOWheel::slotPurpleBottom75(Player &player, uint16_t points, uint8_t, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurpleBottom75(const std::shared_ptr &player, uint16_t points, uint8_t, PlayerWheelMethodsBonusData &bonusData) const { bonusData.mitigation += 0.03 * points; // 0,03% increaseResistance(player, bonusData, WheelSlots_t::SLOT_PURPLE_BOTTOM_75, points, COMBAT_HOLYDAMAGE, 100); increaseResistance(player, bonusData, WheelSlots_t::SLOT_PURPLE_BOTTOM_75, points, COMBAT_DEATHDAMAGE, 100); } // SLOT_PURPLE_MIDDLE_100 = 29 -void IOWheel::slotPurpleMiddle100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurpleMiddle100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_PURPLE_MIDDLE_100, points, "Intense Wound Cleansing"); bonusData.stats.capacity += 5 * points; @@ -826,7 +826,7 @@ void IOWheel::slotPurpleMiddle100(Player &player, uint16_t points, uint8_t vocat } // SLOT_PURPLE_TOP_150 = 30 -void IOWheel::slotPurpleTop150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurpleTop150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.mana += 1 * points; } else if (isPaladin(vocationCipId)) { @@ -840,7 +840,7 @@ void IOWheel::slotPurpleTop150(Player &player, uint16_t points, uint8_t vocation } // SLOT_BLUE_200 = 31 -void IOWheel::slotBlue200(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlue200(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { addSpell(player, bonusData, WheelSlots_t::SLOT_BLUE_200, points, "Fierce Berserk"); bonusData.stats.health += 3 * points; @@ -861,7 +861,7 @@ void IOWheel::slotBlue200(Player &player, uint16_t points, uint8_t vocationCipId } // SLOT_BLUE_BOTTOM_150 = 32 -void IOWheel::slotBlueBottom150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlueBottom150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.capacity += 5 * points; } else if (isPaladin(vocationCipId)) { @@ -875,7 +875,7 @@ void IOWheel::slotBlueBottom150(Player &player, uint16_t points, uint8_t vocatio } // SLOT_BLUE_BOTTOM_100 = 33 -void IOWheel::slotBlueBottom100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotBlueBottom100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { bonusData.mitigation += 0.03 * points; // 0,03% bool onSlot = isMaxPointAddedToSlot(player, points, WheelSlots_t::SLOT_BLUE_BOTTOM_100); if (isKnight(vocationCipId) && onSlot) { @@ -888,7 +888,7 @@ void IOWheel::slotBlueBottom100(Player &player, uint16_t points, uint8_t vocatio } // SLOT_PURPLE_BOTTOM_100 = 34 -void IOWheel::slotPurpleBottom100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurpleBottom100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.capacity += 5 * points; } else if (isPaladin(vocationCipId)) { @@ -902,7 +902,7 @@ void IOWheel::slotPurpleBottom100(Player &player, uint16_t points, uint8_t vocat } // SLOT_PURPLE_BOTTOM_150 = 35 -void IOWheel::slotPurpleBottom150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurpleBottom150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { if (isKnight(vocationCipId)) { bonusData.stats.mana += 1 * points; } else if (isPaladin(vocationCipId)) { @@ -915,7 +915,7 @@ void IOWheel::slotPurpleBottom150(Player &player, uint16_t points, uint8_t vocat } // SLOT_PURPLE_200 = 36 -void IOWheel::slotPurple200(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { +void IOWheel::slotPurple200(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const { bool isPointsAtSlot = isMaxPointAddedToSlot(player, points, WheelSlots_t::SLOT_PURPLE_200); if (isKnight(vocationCipId)) { bonusData.stats.health += 3 * points; diff --git a/src/io/io_wheel.hpp b/src/io/io_wheel.hpp index 08017e071..f1b95f200 100644 --- a/src/io/io_wheel.hpp +++ b/src/io/io_wheel.hpp @@ -155,7 +155,7 @@ class IOWheel : public IOWheelBonusData { */ const std::vector &getFocusSpells() const; - using VocationBonusFunction = std::function; + using VocationBonusFunction = std::function &, uint16_t, uint8_t, PlayerWheelMethodsBonusData &)>; using VocationBonusMap = std::map; /** * @brief Retrieves the mapping of wheel slots to vocation bonus functions. @@ -258,7 +258,7 @@ class IOWheel : public IOWheelBonusData { * @param slotType The slot type to be checked. * @return true if the number of points is equal to the player's points in the specified slot type, false otherwise. */ - bool isMaxPointAddedToSlot(Player &player, uint16_t points, WheelSlots_t slotType) const; + bool isMaxPointAddedToSlot(const std::shared_ptr &player, uint16_t points, WheelSlots_t slotType) const; /** * @brief Checks if the vocation ID corresponds to a knight. @@ -296,7 +296,7 @@ class IOWheel : public IOWheelBonusData { * @param points The number of points required to add the spell. * @param spellName The name of the spell to add. */ - void addSpell(Player &player, PlayerWheelMethodsBonusData &bonusData, WheelSlots_t slotType, uint16_t points, const std::string &spellName) const; + void addSpell(const std::shared_ptr &player, PlayerWheelMethodsBonusData &bonusData, WheelSlots_t slotType, uint16_t points, const std::string &spellName) const; /** * @brief Increases the resistance value of the specified combat type for the player's bonus data if the number of points is equal to the player's points in the specified slot type. @@ -307,7 +307,7 @@ class IOWheel : public IOWheelBonusData { * @param combat The combat type to increase the resistance for. * @param value The value to increase the resistance by. */ - void increaseResistance(Player &player, PlayerWheelMethodsBonusData &bonusData, WheelSlots_t slotType, uint16_t points, CombatType_t combat, int16_t value) const; + void increaseResistance(const std::shared_ptr &player, PlayerWheelMethodsBonusData &bonusData, WheelSlots_t slotType, uint16_t points, CombatType_t combat, int16_t value) const; /** * @brief Initialize the wheel map functions. @@ -327,51 +327,51 @@ class IOWheel : public IOWheelBonusData { * @details It's important to note that although the functions have similar objectives, they are tailored to each specific vocation, allowing for proper customization for each one. Furthermore, these functions are designed to prevent code redundancy, promoting a modular structure that is easy to maintain. * @note Note: Due to the large number of similar functions in this module, we have chosen not to document each function individually to avoid excessive documentation work. However, the information provided in this general description should provide a sufficient overview of the purpose and operation of these functions. */ - void slotGreen200(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotGreenTop150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotGreenTop100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreen200(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreenTop150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreenTop100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRedTop100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRedTop150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRed200(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRedTop100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRedTop150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRed200(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotGreenBottom150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotGreenMiddle100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotGreenTop75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreenBottom150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreenMiddle100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreenTop75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRedTop75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRedMiddle100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRedBottom150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRedTop75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRedMiddle100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRedBottom150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotGreenBottom100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotGreenBottom75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotGreen50(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreenBottom100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreenBottom75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotGreen50(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRed50(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRedBottom75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotRedBottom100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRed50(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRedBottom75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotRedBottom100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlueTop100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlueTop75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlue50(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlueTop100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlueTop75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlue50(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurple50(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurpleTop75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurpleTop100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurple50(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurpleTop75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurpleTop100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlueTop150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlueMiddle100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlueBottom75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlueTop150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlueMiddle100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlueBottom75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurpleBottom75(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurpleMiddle100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurpleTop150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurpleBottom75(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurpleMiddle100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurpleTop150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlue200(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlueBottom150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotBlueBottom100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlue200(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlueBottom150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotBlueBottom100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurpleBottom100(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurpleBottom150(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; - void slotPurple200(Player &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurpleBottom100(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurpleBottom150(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; + void slotPurple200(const std::shared_ptr &player, uint16_t points, uint8_t vocationCipId, PlayerWheelMethodsBonusData &bonusData) const; }; diff --git a/src/io/iobestiary.cpp b/src/io/iobestiary.cpp index 2cb73b40e..079742889 100644 --- a/src/io/iobestiary.cpp +++ b/src/io/iobestiary.cpp @@ -17,7 +17,7 @@ SoftSingleton IOBestiary::instanceTracker("IOBestiary"); -bool IOBestiary::parseCharmCombat(const std::shared_ptr charm, Player* player, Creature* target, int32_t realDamage, bool dueToPotion, bool checkArmor) { +bool IOBestiary::parseCharmCombat(const std::shared_ptr charm, std::shared_ptr player, std::shared_ptr target, int32_t realDamage, bool dueToPotion, bool checkArmor) { if (!charm || !player || !target) { return false; } @@ -25,7 +25,7 @@ bool IOBestiary::parseCharmCombat(const std::shared_ptr charm, Player* pl CombatDamage charmDamage; if (charm->type == CHARM_OFFENSIVE) { if (charm->id == CHARM_CRIPPLE) { - ConditionSpeed* cripple = static_cast(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_PARALYZE, 10000, 0)); + std::shared_ptr cripple = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_PARALYZE, 10000, 0)->static_self_cast(); cripple->setFormulaVars(-1, 81, -1, 81); target->addCondition(cripple); player->sendCancelMessage(charm->cancelMsg); @@ -69,14 +69,14 @@ bool IOBestiary::parseCharmCombat(const std::shared_ptr charm, Player* pl return true; } case CHARM_ADRENALINE: { - ConditionSpeed* adrenaline = static_cast(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_HASTE, 10000, 0)); + std::shared_ptr adrenaline = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_HASTE, 10000, 0)->static_self_cast(); adrenaline->setFormulaVars(1.5, -0, 1.5, -0); player->addCondition(adrenaline); player->sendCancelMessage(charm->cancelMsg); return false; } case CHARM_NUMB: { - ConditionSpeed* numb = static_cast(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_PARALYZE, 10000, 0)); + std::shared_ptr numb = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_PARALYZE, 10000, 0)->static_self_cast(); numb->setFormulaVars(-1, 81, -1, 81); target->addCondition(numb); player->sendCancelMessage(charm->cancelMsg); @@ -146,7 +146,7 @@ uint8_t IOBestiary::getKillStatus(const std::shared_ptr mtype, uint return 4; } -void IOBestiary::resetCharmRuneCreature(Player* player, const std::shared_ptr charm) { +void IOBestiary::resetCharmRuneCreature(std::shared_ptr player, const std::shared_ptr charm) { if (!player || !charm) { return; } @@ -156,7 +156,7 @@ void IOBestiary::resetCharmRuneCreature(Player* player, const std::shared_ptrparseRacebyCharm(charm->id, true, 0); } -void IOBestiary::setCharmRuneCreature(Player* player, const std::shared_ptr charm, uint16_t raceid) { +void IOBestiary::setCharmRuneCreature(std::shared_ptr player, const std::shared_ptr charm, uint16_t raceid) { if (!player || !charm) { return; } @@ -166,7 +166,7 @@ void IOBestiary::setCharmRuneCreature(Player* player, const std::shared_ptrsetUsedRunesBit(Toggle); } -std::list IOBestiary::getCharmUsedRuneBitAll(Player* player) { +std::list IOBestiary::getCharmUsedRuneBitAll(std::shared_ptr player) { int32_t input = player->getUsedRunesBit(); ; int8_t i = 0; @@ -182,7 +182,7 @@ std::list IOBestiary::getCharmUsedRuneBitAll(Player* player) { return rtn; } -uint16_t IOBestiary::getBestiaryRaceUnlocked(Player* player, BestiaryType_t race) const { +uint16_t IOBestiary::getBestiaryRaceUnlocked(std::shared_ptr player, BestiaryType_t race) const { if (!player) { return 0; } @@ -199,7 +199,7 @@ uint16_t IOBestiary::getBestiaryRaceUnlocked(Player* player, BestiaryType_t race return count; } -void IOBestiary::addCharmPoints(Player* player, uint16_t amount, bool negative /*= false*/) { +void IOBestiary::addCharmPoints(std::shared_ptr player, uint16_t amount, bool negative /*= false*/) { if (!player) { return; } @@ -213,7 +213,7 @@ void IOBestiary::addCharmPoints(Player* player, uint16_t amount, bool negative / player->setCharmPoints(myCharms); } -void IOBestiary::addBestiaryKill(Player* player, const std::shared_ptr mtype, uint32_t amount /*= 1*/) { +void IOBestiary::addBestiaryKill(std::shared_ptr player, const std::shared_ptr mtype, uint32_t amount /*= 1*/) { uint16_t raceid = mtype->info.raceid; if (raceid == 0 || !player || !mtype) { return; @@ -237,15 +237,11 @@ void IOBestiary::addBestiaryKill(Player* player, const std::shared_ptrgetCyclopediaMonsterTrackerSet(false); - for (const auto mType : trackerUnorderedSet) { - if (raceid == mType->info.raceid) { - player->refreshCyclopediaMonsterTracker(trackerUnorderedSet, false); - } - } + // Reload bestiary tracker + player->refreshCyclopediaMonsterTracker(); } -charmRune_t IOBestiary::getCharmFromTarget(Player* player, const std::shared_ptr mtype) { +charmRune_t IOBestiary::getCharmFromTarget(std::shared_ptr player, const std::shared_ptr mtype) { if (!player || !mtype) { return CHARM_NONE; } @@ -287,7 +283,7 @@ int32_t IOBestiary::bitToggle(int32_t input, const std::shared_ptr charm, } } -void IOBestiary::sendBuyCharmRune(Player* player, charmRune_t runeID, uint8_t action, uint16_t raceid) { +void IOBestiary::sendBuyCharmRune(std::shared_ptr player, charmRune_t runeID, uint8_t action, uint16_t raceid) { const auto charm = getBestiaryCharm(runeID); if (!player || !charm) { return; @@ -388,7 +384,7 @@ std::map IOBestiary::getMonsterElements(const std::shared_ptr< return defaultMap; } -std::map IOBestiary::getBestiaryKillCountByMonsterIDs(Player* player, std::map mtype_list) const { +std::map IOBestiary::getBestiaryKillCountByMonsterIDs(std::shared_ptr player, std::map mtype_list) const { std::map raceMonsters = {}; for (const auto &it : mtype_list) { uint16_t raceid = it.first; @@ -400,7 +396,7 @@ std::map IOBestiary::getBestiaryKillCountByMonsterIDs(Player return raceMonsters; } -phmap::parallel_flat_hash_set IOBestiary::getBestiaryFinished(Player* player) const { +phmap::parallel_flat_hash_set IOBestiary::getBestiaryFinished(std::shared_ptr player) const { phmap::parallel_flat_hash_set finishedMonsters; auto bestiaryMap = g_game().getBestiaryList(); diff --git a/src/io/iobestiary.hpp b/src/io/iobestiary.hpp index e072e9ae8..26f802dcb 100644 --- a/src/io/iobestiary.hpp +++ b/src/io/iobestiary.hpp @@ -55,28 +55,28 @@ class IOBestiary { } std::shared_ptr getBestiaryCharm(charmRune_t activeCharm, bool force = false) const; - void addBestiaryKill(Player* player, const std::shared_ptr mtype, uint32_t amount = 1); - bool parseCharmCombat(const std::shared_ptr charm, Player* player, Creature* target, int32_t realDamage, bool dueToPotion = false, bool checkArmor = false); - void addCharmPoints(Player* player, uint16_t amount, bool negative = false); - void sendBuyCharmRune(Player* player, charmRune_t runeID, uint8_t action, uint16_t raceid); - void setCharmRuneCreature(Player* player, const std::shared_ptr charm, uint16_t raceid); - void resetCharmRuneCreature(Player* player, const std::shared_ptr charm); + void addBestiaryKill(std::shared_ptr player, const std::shared_ptr mtype, uint32_t amount = 1); + bool parseCharmCombat(const std::shared_ptr charm, std::shared_ptr player, std::shared_ptr target, int32_t realDamage, bool dueToPotion = false, bool checkArmor = false); + void addCharmPoints(std::shared_ptr player, uint16_t amount, bool negative = false); + void sendBuyCharmRune(std::shared_ptr player, charmRune_t runeID, uint8_t action, uint16_t raceid); + void setCharmRuneCreature(std::shared_ptr player, const std::shared_ptr charm, uint16_t raceid); + void resetCharmRuneCreature(std::shared_ptr player, const std::shared_ptr charm); int8_t calculateDifficult(uint32_t chance) const; uint8_t getKillStatus(const std::shared_ptr mtype, uint32_t killAmount) const; - uint16_t getBestiaryRaceUnlocked(Player* player, BestiaryType_t race) const; + uint16_t getBestiaryRaceUnlocked(std::shared_ptr player, BestiaryType_t race) const; int32_t bitToggle(int32_t input, const std::shared_ptr charm, bool on) const; bool hasCharmUnlockedRuneBit(const std::shared_ptr charm, int32_t input) const; - std::list getCharmUsedRuneBitAll(Player* player); - phmap::parallel_flat_hash_set getBestiaryFinished(Player* player) const; + std::list getCharmUsedRuneBitAll(std::shared_ptr player); + phmap::parallel_flat_hash_set getBestiaryFinished(std::shared_ptr player) const; - charmRune_t getCharmFromTarget(Player* player, const std::shared_ptr mtype); + charmRune_t getCharmFromTarget(std::shared_ptr player, const std::shared_ptr mtype); - std::map getBestiaryKillCountByMonsterIDs(Player* player, std::map mtype_list) const; + std::map getBestiaryKillCountByMonsterIDs(std::shared_ptr player, std::map mtype_list) const; std::map getMonsterElements(const std::shared_ptr mtype) const; std::map findRaceByName(const std::string &race, bool Onlystring = true, BestiaryType_t raceNumber = BESTY_RACE_NONE) const; diff --git a/src/io/iologindata.cpp b/src/io/iologindata.cpp index 3314cd5cf..307d41a9c 100644 --- a/src/io/iologindata.cpp +++ b/src/io/iologindata.cpp @@ -85,23 +85,24 @@ void IOLoginData::updateOnlineStatus(uint32_t guid, bool login) { } // The boolean "disable" will desactivate the loading of information that is not relevant to the preload, for example, forge, bosstiary, etc. None of this we need to access if the player is offline -bool IOLoginData::loadPlayerById(Player* player, uint32_t id, bool disable /* = true*/) { +bool IOLoginData::loadPlayerById(std::shared_ptr player, uint32_t id, bool disable /* = true*/) { Database &db = Database::getInstance(); std::ostringstream query; query << "SELECT * FROM `players` WHERE `id` = " << id; return loadPlayer(player, db.storeQuery(query.str()), disable); } -bool IOLoginData::loadPlayerByName(Player* player, const std::string &name, bool disable /* = true*/) { +bool IOLoginData::loadPlayerByName(std::shared_ptr player, const std::string &name, bool disable /* = true*/) { Database &db = Database::getInstance(); std::ostringstream query; query << "SELECT * FROM `players` WHERE `name` = " << db.escapeString(name); return loadPlayer(player, db.storeQuery(query.str()), disable); } -bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result, bool disable /* = false*/) { +bool IOLoginData::loadPlayer(std::shared_ptr player, DBResult_ptr result, bool disable /* = false*/) { if (!result || !player) { - g_logger().warn("[IOLoginData::loadPlayer] - Player or Resultnullptr: {}", __FUNCTION__); + std::string nullptrType = !result ? "Result" : "Player"; + g_logger().warn("[{}] - {} is nullptr", __FUNCTION__, nullptrType); return false; } @@ -185,7 +186,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result, bool disable / } } -bool IOLoginData::savePlayer(Player* player) { +bool IOLoginData::savePlayer(std::shared_ptr player) { bool success = DBTransaction::executeWithinTransaction([player]() { return savePlayerGuard(player); }); @@ -197,7 +198,7 @@ bool IOLoginData::savePlayer(Player* player) { return success; } -bool IOLoginData::savePlayerGuard(Player* player) { +bool IOLoginData::savePlayerGuard(std::shared_ptr player) { if (!player) { throw DatabaseException("Player nullptr in function: " + std::string(__FUNCTION__)); } diff --git a/src/io/iologindata.hpp b/src/io/iologindata.hpp index baae9a57b..724967d28 100644 --- a/src/io/iologindata.hpp +++ b/src/io/iologindata.hpp @@ -13,17 +13,17 @@ #include "creatures/players/player.hpp" #include "database/database.hpp" -using ItemBlockList = std::list>; +using ItemBlockList = std::list>>; class IOLoginData { public: static bool gameWorldAuthentication(const std::string &accountDescriptor, const std::string &sessionOrPassword, std::string &characterName, uint32_t &accountId, bool oldProcotol); static account::AccountType getAccountType(uint32_t accountId); static void updateOnlineStatus(uint32_t guid, bool login); - static bool loadPlayerById(Player* player, uint32_t id, bool disable = true); - static bool loadPlayerByName(Player* player, const std::string &name, bool disable = true); - static bool loadPlayer(Player* player, DBResult_ptr result, bool disable = true); - static bool savePlayer(Player* player); + static bool loadPlayerById(std::shared_ptr player, uint32_t id, bool disable = true); + static bool loadPlayerByName(std::shared_ptr player, const std::string &name, bool disable = true); + static bool loadPlayer(std::shared_ptr player, DBResult_ptr result, bool disable = true); + static bool savePlayer(std::shared_ptr player); static uint32_t getGuidByName(const std::string &name); static bool getGuidByNameEx(uint32_t &guid, bool &specialVip, std::string &name); static std::string getNameByGuid(uint32_t guid); @@ -37,5 +37,5 @@ class IOLoginData { static void removeVIPEntry(uint32_t accountId, uint32_t guid); private: - static bool savePlayerGuard(Player* player); + static bool savePlayerGuard(std::shared_ptr player); }; diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp index 841cff76b..dba8214a6 100644 --- a/src/io/iomapserialize.cpp +++ b/src/io/iomapserialize.cpp @@ -10,6 +10,7 @@ #include "pch.hpp" #include "io/iomapserialize.hpp" +#include "io/iologindata.hpp" #include "game/game.hpp" #include "items/bed.hpp" @@ -34,7 +35,7 @@ void IOMapSerialize::loadHouseItems(Map* map) { continue; } - Tile* tile = map->getTile(x, y, z); + std::shared_ptr tile = map->getTile(x, y, z); if (!tile) { continue; } @@ -77,7 +78,7 @@ bool IOMapSerialize::SaveHouseItemsGuard() { PropWriteStream stream; for (const auto &[key, house] : g_game().map.houses.getHouses()) { // save house items - for (HouseTile* tile : house->getTiles()) { + for (std::shared_ptr tile : house->getTiles()) { saveTile(stream, tile); size_t attributesSize; @@ -100,7 +101,7 @@ bool IOMapSerialize::SaveHouseItemsGuard() { return true; } -bool IOMapSerialize::loadContainer(PropStream &propStream, Container* container) { +bool IOMapSerialize::loadContainer(PropStream &propStream, std::shared_ptr container) { while (container->serializationCount > 0) { if (!loadItem(propStream, container)) { g_logger().warn("Deserialization error for container item: {}", container->getID()); @@ -119,13 +120,13 @@ bool IOMapSerialize::loadContainer(PropStream &propStream, Container* container) uint32_t NEW_BEDS_START_ID = 30000; -bool IOMapSerialize::loadItem(PropStream &propStream, Cylinder* parent, bool isHouseItem /*= false*/) { +bool IOMapSerialize::loadItem(PropStream &propStream, std::shared_ptr parent, bool isHouseItem /*= false*/) { uint16_t id; if (!propStream.read(id)) { return false; } - Tile* tile = nullptr; + std::shared_ptr tile = nullptr; if (parent->getParent() == nullptr) { tile = parent->getTile(); } @@ -136,12 +137,11 @@ bool IOMapSerialize::loadItem(PropStream &propStream, Cylinder* parent, bool isH } if (iType.moveable || !tile || iType.isCarpet() || iType.isBed()) { // create a new item - Item* item = Item::CreateItem(id); + std::shared_ptr item = Item::CreateItem(id); if (item) { if (item->unserializeAttr(propStream)) { - Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && !loadContainer(propStream, container)) { - delete item; return false; } @@ -149,18 +149,21 @@ bool IOMapSerialize::loadItem(PropStream &propStream, Cylinder* parent, bool isH item->startDecaying(); } else { g_logger().warn("Deserialization error in {}", id); - delete item; + return false; } } } else { // Stationary items like doors/beds/blackboards/bookcases - Item* item = nullptr; + std::shared_ptr item = nullptr; if (const TileItemVector* items = tile->getItemList()) { - for (Item* findItem : *items) { + for (auto &findItem : *items) { if (findItem->getID() == id) { item = findItem; break; + } else if (iType.m_transformOnUse && findItem->getID() == iType.m_transformOnUse) { + item = findItem; + break; } else if (iType.isDoor() && findItem->getDoor()) { item = findItem; break; @@ -173,7 +176,7 @@ bool IOMapSerialize::loadItem(PropStream &propStream, Cylinder* parent, bool isH if (item) { if (item->unserializeAttr(propStream)) { - Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && !loadContainer(propStream, container)) { return false; } @@ -184,15 +187,15 @@ bool IOMapSerialize::loadItem(PropStream &propStream, Cylinder* parent, bool isH } } else { // The map changed since the last save, just read the attributes - std::unique_ptr dummy(Item::CreateItem(id)); + auto dummy = Item::CreateItem(id); if (dummy) { dummy->unserializeAttr(propStream); - Container* container = dummy->getContainer(); + std::shared_ptr container = dummy->getContainer(); if (container) { if (!loadContainer(propStream, container)) { return false; } - } else if (BedItem* bedItem = dynamic_cast(dummy.get())) { + } else if (std::shared_ptr bedItem = std::dynamic_pointer_cast(dummy)) { uint32_t sleeperGUID = bedItem->getSleeper(); if (sleeperGUID != 0) { g_game().removeBedSleeper(sleeperGUID); @@ -204,8 +207,8 @@ bool IOMapSerialize::loadItem(PropStream &propStream, Cylinder* parent, bool isH return true; } -void IOMapSerialize::saveItem(PropWriteStream &stream, const Item* item) { - const Container* container = item->getContainer(); +void IOMapSerialize::saveItem(PropWriteStream &stream, std::shared_ptr item) { + std::shared_ptr container = item->getContainer(); // Write ID & props stream.write(item->getID()); @@ -223,19 +226,16 @@ void IOMapSerialize::saveItem(PropWriteStream &stream, const Item* item) { stream.write(0x00); // attr end } -void IOMapSerialize::saveTile(PropWriteStream &stream, const Tile* tile) { +void IOMapSerialize::saveTile(PropWriteStream &stream, std::shared_ptr tile) { const TileItemVector* tileItems = tile->getItemList(); if (!tileItems) { return; } - std::forward_list items; + std::forward_list> items; uint16_t count = 0; - for (Item* item : *tileItems) { - const ItemType &it = Item::items[item->getID()]; - - // Note that these are NEGATED, ie. these are the items that will be saved. - if (!(it.moveable || it.isCarpet() || item->getDoor() || (item->getContainer() && !item->getContainer()->empty()) || it.canWriteText || item->getBed())) { + for (auto &item : *tileItems) { + if (!item->isSavedToHouses()) { continue; } @@ -250,7 +250,7 @@ void IOMapSerialize::saveTile(PropWriteStream &stream, const Tile* tile) { stream.write(tilePosition.z); stream.write(count); - for (const Item* item : items) { + for (std::shared_ptr item : items) { saveItem(stream, item); } } @@ -259,15 +259,31 @@ void IOMapSerialize::saveTile(PropWriteStream &stream, const Tile* tile) { bool IOMapSerialize::loadHouseInfo() { Database &db = Database::getInstance(); - DBResult_ptr result = db.storeQuery("SELECT `id`, `owner`, `paid`, `warnings` FROM `houses`"); + DBResult_ptr result = db.storeQuery("SELECT `id`, `owner`, `new_owner`, `paid`, `warnings` FROM `houses`"); if (!result) { return false; } do { - House* house = g_game().map.houses.getHouse(result->getNumber("id")); + auto houseId = result->getNumber("id"); + const auto &house = g_game().map.houses.getHouse(houseId); if (house) { - house->setOwner(result->getNumber("owner"), false); + uint32_t owner = result->getNumber("owner"); + int32_t newOwner = result->getNumber("new_owner"); + // Transfer house owner + auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART); + if (isTransferOnRestart && newOwner >= 0) { + g_game().setTransferPlayerHouseItems(houseId, owner); + if (newOwner == 0) { + g_logger().debug("Removing house id '{}' owner", houseId); + house->setOwner(0); + } else { + g_logger().debug("Setting house id '{}' owner to player GUID '{}'", houseId, newOwner); + house->setOwner(newOwner); + } + } else { + house->setOwner(owner, false); + } house->setPaidUntil(result->getNumber("paid")); house->setPayRentWarnings(result->getNumber("warnings")); } @@ -276,7 +292,7 @@ bool IOMapSerialize::loadHouseInfo() { result = db.storeQuery("SELECT `house_id`, `listid`, `list` FROM `house_lists`"); if (result) { do { - House* house = g_game().map.houses.getHouse(result->getNumber("house_id")); + const auto &house = g_game().map.houses.getHouse(result->getNumber("house_id")); if (house) { house->setAccessList(result->getNumber("listid"), result->getString("list")); } @@ -300,33 +316,31 @@ bool IOMapSerialize::saveHouseInfo() { bool IOMapSerialize::SaveHouseInfoGuard() { Database &db = Database::getInstance(); - if (!db.executeQuery("DELETE FROM `house_lists`")) { - return false; - } - std::ostringstream query; + DBInsert houseUpdate("INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`) VALUES "); + houseUpdate.upsert({ "owner", "paid", "warnings", "name", "town_id", "rent", "size", "beds" }); + for (const auto &[key, house] : g_game().map.houses.getHouses()) { - query << "SELECT `id` FROM `houses` WHERE `id` = " << house->getId(); - DBResult_ptr result = db.storeQuery(query.str()); - if (result) { - query.str(std::string()); - query << "UPDATE `houses` SET `owner` = " << house->getOwner() << ", `paid` = " << house->getPaidUntil() << ", `warnings` = " << house->getPayRentWarnings() << ", `name` = " << db.escapeString(house->getName()) << ", `town_id` = " << house->getTownId() << ", `rent` = " << house->getRent() << ", `size` = " << house->getTiles().size() << ", `beds` = " << house->getBedCount() << " WHERE `id` = " << house->getId(); - } else { - query.str(std::string()); - query << "INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`) VALUES (" << house->getId() << ',' << house->getOwner() << ',' << house->getPaidUntil() << ',' << house->getPayRentWarnings() << ',' << db.escapeString(house->getName()) << ',' << house->getTownId() << ',' << house->getRent() << ',' << house->getTiles().size() << ',' << house->getBedCount() << ')'; + std::string values = fmt::format("{},{},{},{},{},{},{},{},{}", house->getId(), house->getOwner(), house->getPaidUntil(), house->getPayRentWarnings(), db.escapeString(house->getName()), house->getTownId(), house->getRent(), house->getSize(), house->getBedCount()); + + if (!houseUpdate.addRow(values)) { + return false; } + } - db.executeQuery(query.str()); - query.str(std::string()); + if (!houseUpdate.execute()) { + return false; } - DBInsert stmt("INSERT INTO `house_lists` (`house_id` , `listid` , `list`) VALUES "); + DBInsert listUpdate("INSERT INTO `house_lists` (`house_id` , `listid` , `list`, `version`) VALUES "); + listUpdate.upsert({ "list", "version" }); + auto version = getTimeUsNow(); for (const auto &[key, house] : g_game().map.houses.getHouses()) { std::string listText; if (house->getAccessList(GUEST_LIST, listText) && !listText.empty()) { - query << house->getId() << ',' << GUEST_LIST << ',' << db.escapeString(listText); - if (!stmt.addRow(query)) { + query << house->getId() << ',' << GUEST_LIST << ',' << db.escapeString(listText) << ',' << version; + if (!listUpdate.addRow(query)) { return false; } @@ -334,18 +348,18 @@ bool IOMapSerialize::SaveHouseInfoGuard() { } if (house->getAccessList(SUBOWNER_LIST, listText) && !listText.empty()) { - query << house->getId() << ',' << SUBOWNER_LIST << ',' << db.escapeString(listText); - if (!stmt.addRow(query)) { + query << house->getId() << ',' << SUBOWNER_LIST << ',' << db.escapeString(listText) << ',' << version; + if (!listUpdate.addRow(query)) { return false; } listText.clear(); } - for (Door* door : house->getDoors()) { + for (std::shared_ptr door : house->getDoors()) { if (door->getAccessList(listText) && !listText.empty()) { - query << house->getId() << ',' << door->getDoorId() << ',' << db.escapeString(listText); - if (!stmt.addRow(query)) { + query << house->getId() << ',' << door->getDoorId() << ',' << db.escapeString(listText) << ',' << version; + if (!listUpdate.addRow(query)) { return false; } @@ -354,7 +368,11 @@ bool IOMapSerialize::SaveHouseInfoGuard() { } } - if (!stmt.execute()) { + if (!listUpdate.execute()) { + return false; + } + + if (!db.executeQuery(fmt::format("DELETE FROM `house_lists` WHERE `version` < {}", version))) { return false; } diff --git a/src/io/iomapserialize.hpp b/src/io/iomapserialize.hpp index 1fe13af92..017dd9705 100644 --- a/src/io/iomapserialize.hpp +++ b/src/io/iomapserialize.hpp @@ -21,9 +21,9 @@ class IOMapSerialize { private: static bool SaveHouseInfoGuard(); static bool SaveHouseItemsGuard(); - static void saveItem(PropWriteStream &stream, const Item* item); - static void saveTile(PropWriteStream &stream, const Tile* tile); + static void saveItem(PropWriteStream &stream, std::shared_ptr item); + static void saveTile(PropWriteStream &stream, std::shared_ptr tile); - static bool loadContainer(PropStream &propStream, Container* container); - static bool loadItem(PropStream &propStream, Cylinder* parent, bool isHouseItem = false); + static bool loadContainer(PropStream &propStream, std::shared_ptr container); + static bool loadItem(PropStream &propStream, std::shared_ptr parent, bool isHouseItem = false); }; diff --git a/src/io/iomarket.cpp b/src/io/iomarket.cpp index cf07aa04f..8feb7f38d 100644 --- a/src/io/iomarket.cpp +++ b/src/io/iomarket.cpp @@ -131,11 +131,11 @@ void IOMarket::processExpiredOffers(DBResult_ptr result, bool) { continue; } - Player* player = g_game().getPlayerByGUID(playerId); + std::shared_ptr player = g_game().getPlayerByGUID(playerId); if (!player) { - player = new Player(nullptr); + player = std::make_shared(nullptr); if (!IOLoginData::loadPlayerById(player, playerId)) { - delete player; + continue; } } @@ -144,10 +144,10 @@ void IOMarket::processExpiredOffers(DBResult_ptr result, bool) { uint16_t tmpAmount = amount; while (tmpAmount > 0) { uint16_t stackCount = std::min(100, tmpAmount); - Item* item = Item::CreateItem(itemType.id, stackCount); + std::shared_ptr item = Item::CreateItem(itemType.id, stackCount); if (g_game().internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { g_logger().error("[{}] Ocurred an error to add item with id {} to player {}", __FUNCTION__, itemType.id, player->getName()); - delete item; + break; } @@ -166,9 +166,9 @@ void IOMarket::processExpiredOffers(DBResult_ptr result, bool) { } for (uint16_t i = 0; i < amount; ++i) { - Item* item = Item::CreateItem(itemType.id, subType); + std::shared_ptr item = Item::CreateItem(itemType.id, subType); if (g_game().internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { - delete item; + break; } @@ -180,12 +180,11 @@ void IOMarket::processExpiredOffers(DBResult_ptr result, bool) { if (player->isOffline()) { IOLoginData::savePlayer(player); - delete player; } } else { uint64_t totalPrice = result->getNumber("price") * amount; - Player* player = g_game().getPlayerByGUID(playerId); + std::shared_ptr player = g_game().getPlayerByGUID(playerId); if (player) { player->setBankBalance(player->getBankBalance() + totalPrice); } else { diff --git a/src/io/ioprey.cpp b/src/io/ioprey.cpp index 23aa3d794..b81dad1fd 100644 --- a/src/io/ioprey.cpp +++ b/src/io/ioprey.cpp @@ -246,13 +246,13 @@ void TaskHuntingSlot::reloadReward() { } // Prey/Task hunting global class -void IOPrey::CheckPlayerPreys(Player* player, uint8_t amount) const { +void IOPrey::checkPlayerPreys(std::shared_ptr player, uint8_t amount) const { if (!player) { return; } for (uint8_t slotId = PreySlot_First; slotId <= PreySlot_Last; slotId++) { - if (PreySlot* slot = player->getPreySlotById(static_cast(slotId)); + if (const auto &slot = player->getPreySlotById(static_cast(slotId)); slot && slot->isOccupied()) { if (slot->bonusTimeLeft <= amount) { if (slot->option == PreyOption_AutomaticReroll) { @@ -289,8 +289,8 @@ void IOPrey::CheckPlayerPreys(Player* player, uint8_t amount) const { } } -void IOPrey::ParsePreyAction(Player* player, PreySlot_t slotId, PreyAction_t action, PreyOption_t option, int8_t index, uint16_t raceId) const { - PreySlot* slot = player->getPreySlotById(slotId); +void IOPrey::parsePreyAction(std::shared_ptr player, PreySlot_t slotId, PreyAction_t action, PreyOption_t option, int8_t index, uint16_t raceId) const { + const auto &slot = player->getPreySlotById(slotId); if (!slot || slot->state == PreyDataState_Locked) { player->sendMessageDialog("To unlock this prey slot first you must buy it on store."); return; @@ -382,15 +382,15 @@ void IOPrey::ParsePreyAction(Player* player, PreySlot_t slotId, PreyAction_t act slot->option = option; } else { - g_logger().warn("[IOPrey::ParsePreyAction] - Unknown prey action: {}", fmt::underlying(action)); + g_logger().warn("[IOPrey::parsePreyAction] - Unknown prey action: {}", fmt::underlying(action)); return; } player->reloadPreySlot(slotId); } -void IOPrey::ParseTaskHuntingAction(Player* player, PreySlot_t slotId, PreyTaskAction_t action, bool upgrade, uint16_t raceId) const { - TaskHuntingSlot* slot = player->getTaskHuntingSlotById(slotId); +void IOPrey::parseTaskHuntingAction(std::shared_ptr player, PreySlot_t slotId, PreyTaskAction_t action, bool upgrade, uint16_t raceId) const { + const auto &slot = player->getTaskHuntingSlotById(slotId); if (!slot || slot->state == PreyTaskDataState_Locked) { player->sendMessageDialog("To unlock this task hunting slot first you must buy it on store."); return; @@ -476,7 +476,7 @@ void IOPrey::ParseTaskHuntingAction(Player* player, PreySlot_t slotId, PreyTaskA return; } - if (const TaskHuntingOption* option = GetTaskRewardOption(slot)) { + if (const auto &option = getTaskRewardOption(slot)) { uint64_t reward; int32_t boostChange = uniform_random(0, 100); if (slot->rarity >= 4 && boostChange <= 5) { @@ -516,13 +516,13 @@ void IOPrey::ParseTaskHuntingAction(Player* player, PreySlot_t slotId, PreyTaskA slot->disabledUntilTimeStamp = OTSYS_TIME() + g_configManager().getNumber(TASK_HUNTING_LIMIT_EXHAUST) * 1000; } } else { - g_logger().warn("[IOPrey::ParseTaskHuntingAction] - Unknown task action: {}", fmt::underlying(action)); + g_logger().warn("[IOPrey::parseTaskHuntingAction] - Unknown task action: {}", fmt::underlying(action)); return; } player->reloadTaskSlot(slotId); } -void IOPrey::InitializeTaskHuntOptions() { +void IOPrey::initializeTaskHuntOptions() { if (!g_configManager().getBoolean(TASK_HUNTING_ENABLED)) { return; } @@ -540,7 +540,8 @@ void IOPrey::InitializeTaskHuntOptions() { auto reward = static_cast(std::round((10 * kills) / killStage)); // Amount of task stars on task hunting for (uint8_t star = 1; star <= limitOfStars; ++star) { - auto option = new TaskHuntingOption(); + const auto &option = taskOption.emplace_back(std::make_unique()); + option->difficult = static_cast(difficulty); option->rarity = star; @@ -550,8 +551,6 @@ void IOPrey::InitializeTaskHuntOptions() { option->secondKills = kills * 2; option->secondReward = reward * 2; - taskOption.push_back(option); - reward = static_cast(std::round((reward * (115 + (difficulty * limitOfStars))) / 100)); } @@ -578,7 +577,7 @@ void IOPrey::InitializeTaskHuntOptions() { }); msg.addByte(static_cast(taskOption.size())); - std::for_each(taskOption.begin(), taskOption.end(), [&msg](const TaskHuntingOption* option) { + std::for_each(taskOption.begin(), taskOption.end(), [&msg](const std::unique_ptr &option) { msg.addByte(static_cast(option->difficult)); msg.addByte(option->rarity); msg.add(option->firstKills); @@ -589,14 +588,14 @@ void IOPrey::InitializeTaskHuntOptions() { baseDataMessage = msg; } -TaskHuntingOption* IOPrey::GetTaskRewardOption(const TaskHuntingSlot* slot) const { +const std::unique_ptr &IOPrey::getTaskRewardOption(const std::unique_ptr &slot) const { if (!slot) { - return nullptr; + return TaskHuntingOptionNull; } const auto mtype = g_monsters().getMonsterTypeByRaceId(slot->selectedRaceId); if (!mtype) { - return nullptr; + return TaskHuntingOptionNull; } PreyTaskDifficult_t difficult; @@ -608,12 +607,13 @@ TaskHuntingOption* IOPrey::GetTaskRewardOption(const TaskHuntingSlot* slot) cons difficult = PreyTaskDifficult_Hard; } - if (auto it = std::find_if(taskOption.begin(), taskOption.end(), [difficult, slot](const TaskHuntingOption* optionIt) { - return optionIt->difficult == difficult && optionIt->rarity == slot->rarity; - }); - it != taskOption.end()) { + auto it = std::find_if(taskOption.begin(), taskOption.end(), [difficult, &slot](const std::unique_ptr &optionIt) { + return optionIt->difficult == difficult && optionIt->rarity == slot->rarity; + }); + + if (it != taskOption.end()) { return *it; } - return nullptr; + return TaskHuntingOptionNull; } diff --git a/src/io/ioprey.hpp b/src/io/ioprey.hpp index 005971562..2219e630b 100644 --- a/src/io/ioprey.hpp +++ b/src/io/ioprey.hpp @@ -12,6 +12,14 @@ #include "lib/di/container.hpp" #include "server/network/protocol/protocolgame.hpp" +class PreySlot; +class TaskHuntingSlot; +class TaskHuntingOption; + +static const std::unique_ptr &PreySlotNull {}; +static const std::unique_ptr &TaskHuntingSlotNull {}; +static const std::unique_ptr &TaskHuntingOptionNull {}; + enum PreySlot_t : uint8_t { PreySlot_One = 0, PreySlot_Two = 1, @@ -217,24 +225,20 @@ class IOPrey { return inject(); } - void CheckPlayerPreys(Player* player, uint8_t amount) const; - void ParsePreyAction(Player* player, PreySlot_t slotId, PreyAction_t action, PreyOption_t option, int8_t index, uint16_t raceId) const; + void checkPlayerPreys(std::shared_ptr player, uint8_t amount) const; + void parsePreyAction(std::shared_ptr player, PreySlot_t slotId, PreyAction_t action, PreyOption_t option, int8_t index, uint16_t raceId) const; - void ParseTaskHuntingAction(Player* player, PreySlot_t slotId, PreyTaskAction_t action, bool upgrade, uint16_t raceId) const; + void parseTaskHuntingAction(std::shared_ptr player, PreySlot_t slotId, PreyTaskAction_t action, bool upgrade, uint16_t raceId) const; - void InitializeTaskHuntOptions(); - TaskHuntingOption* GetTaskRewardOption(const TaskHuntingSlot* slot) const; - - std::vector GetTaskOptions() const { - return taskOption; - } + void initializeTaskHuntOptions(); + const std::unique_ptr &getTaskRewardOption(const std::unique_ptr &slot) const; - NetworkMessage GetTaskHuntingBaseDate() const { + NetworkMessage getTaskHuntingBaseDate() const { return baseDataMessage; } NetworkMessage baseDataMessage; - std::vector taskOption; + std::vector> taskOption; }; constexpr auto g_ioprey = IOPrey::getInstance; diff --git a/src/items/bed.cpp b/src/items/bed.cpp index f166320a2..6c93e988a 100644 --- a/src/items/bed.cpp +++ b/src/items/bed.cpp @@ -31,7 +31,7 @@ Attr_ReadValue BedItem::readAttr(AttrTypes_t attr, PropStream &propStream) { std::string name = IOLoginData::getNameByGuid(guid); if (!name.empty()) { setAttribute(ItemAttribute_t::DESCRIPTION, name + " is sleeping there."); - g_game().setBedSleeper(this, guid); + g_game().setBedSleeper(static_self_cast(), guid); sleeperGUID = guid; } } @@ -67,18 +67,18 @@ void BedItem::serializeAttr(PropWriteStream &propWriteStream) const { } } -BedItem* BedItem::getNextBedItem() const { +std::shared_ptr BedItem::getNextBedItem() { Direction dir = Item::items[id].bedPartnerDir; Position targetPos = getNextPosition(dir, getPosition()); - const Tile* tile = g_game().map.getTile(targetPos); + std::shared_ptr tile = g_game().map.getTile(targetPos); if (tile == nullptr) { return nullptr; } return tile->getBedItem(); } -bool BedItem::canUse(Player* player) { +bool BedItem::canUse(std::shared_ptr player) { if ((player == nullptr) || (house == nullptr) || !player->isPremium()) { return false; } @@ -99,18 +99,18 @@ bool BedItem::canUse(Player* player) { return true; } - Player sleeper(nullptr); - if (!IOLoginData::loadPlayerById(&sleeper, sleeperGUID)) { + auto sleeper = std::make_shared(nullptr); + if (!IOLoginData::loadPlayerById(sleeper, sleeperGUID)) { return false; } - if (house->getHouseAccessLevel(&sleeper) > house->getHouseAccessLevel(player)) { + if (house->getHouseAccessLevel(sleeper) > house->getHouseAccessLevel(player)) { return false; } return true; } -bool BedItem::trySleep(Player* player) { +bool BedItem::trySleep(std::shared_ptr player) { if (!house || player->isRemoved()) { return false; } @@ -126,7 +126,7 @@ bool BedItem::trySleep(Player* player) { return true; } -bool BedItem::sleep(Player* player) { +bool BedItem::sleep(std::shared_ptr player) { if (house == nullptr) { return false; } @@ -135,7 +135,7 @@ bool BedItem::sleep(Player* player) { return false; } - BedItem* nextBedItem = getNextBedItem(); + std::shared_ptr nextBedItem = getNextBedItem(); internalSetSleeper(player); @@ -144,10 +144,10 @@ bool BedItem::sleep(Player* player) { } // update the bedSleepersMap - g_game().setBedSleeper(this, player->getGUID()); + g_game().setBedSleeper(static_self_cast(), player->getGUID()); // make the player walk onto the bed - g_game().map.moveCreature(*player, *getTile()); + g_game().map.moveCreature(player, getTile()); // display 'Zzzz'/sleep effect g_game().addMagicEffect(player->getPosition(), CONST_ME_SLEEP); @@ -165,7 +165,7 @@ bool BedItem::sleep(Player* player) { return true; } -void BedItem::wakeUp(Player* player) { +void BedItem::wakeUp(std::shared_ptr player) { if (house == nullptr) { return; } @@ -175,10 +175,10 @@ void BedItem::wakeUp(Player* player) { if (sleeperGUID != 0) { if (player == nullptr) { - Player regenPlayer(nullptr); - if (IOLoginData::loadPlayerById(®enPlayer, sleeperGUID)) { - regeneratePlayer(®enPlayer); - IOLoginData::savePlayer(®enPlayer); + auto regenPlayer = std::make_shared(nullptr); + if (IOLoginData::loadPlayerById(regenPlayer, sleeperGUID)) { + regeneratePlayer(regenPlayer); + IOLoginData::savePlayer(regenPlayer); } } else { regeneratePlayer(player); @@ -189,7 +189,7 @@ void BedItem::wakeUp(Player* player) { // update the bedSleepersMap g_game().removeBedSleeper(sleeperGUID); - BedItem* nextBedItem = getNextBedItem(); + std::shared_ptr nextBedItem = getNextBedItem(); // unset sleep info internalRemoveSleeper(); @@ -206,10 +206,10 @@ void BedItem::wakeUp(Player* player) { } } -void BedItem::regeneratePlayer(Player* player) const { +void BedItem::regeneratePlayer(std::shared_ptr player) const { const uint32_t sleptTime = time(nullptr) - sleepStart; - Condition* condition = player->getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT); + std::shared_ptr condition = player->getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT); if (condition != nullptr) { uint32_t regen; if (condition->getTicks() != -1) { @@ -232,24 +232,24 @@ void BedItem::regeneratePlayer(Player* player) const { player->changeSoul(soulRegen); } -void BedItem::updateAppearance(const Player* player) { +void BedItem::updateAppearance(std::shared_ptr player) { const ItemType &it = Item::items[id]; if (it.type == ITEM_TYPE_BED) { if ((player != nullptr) && it.transformToOnUse[player->getSex()] != 0) { const ItemType &newType = Item::items[it.transformToOnUse[player->getSex()]]; if (newType.type == ITEM_TYPE_BED) { - g_game().transformItem(this, it.transformToOnUse[player->getSex()]); + g_game().transformItem(static_self_cast(), it.transformToOnUse[player->getSex()]); } } else if (it.transformToFree != 0) { const ItemType &newType = Item::items[it.transformToFree]; if (newType.type == ITEM_TYPE_BED) { - g_game().transformItem(this, it.transformToFree); + g_game().transformItem(static_self_cast(), it.transformToFree); } } } } -void BedItem::internalSetSleeper(const Player* player) { +void BedItem::internalSetSleeper(std::shared_ptr player) { std::string desc_str = player->getName() + " is sleeping there."; sleeperGUID = player->getGUID(); diff --git a/src/items/bed.hpp b/src/items/bed.hpp index 95b39e3b9..6fafe858a 100644 --- a/src/items/bed.hpp +++ b/src/items/bed.hpp @@ -18,11 +18,8 @@ class BedItem final : public Item { public: explicit BedItem(uint16_t id); - BedItem* getBed() override { - return this; - } - const BedItem* getBed() const override { - return this; + std::shared_ptr getBed() override { + return static_self_cast(); } Attr_ReadValue readAttr(AttrTypes_t attr, PropStream &propStream) override; @@ -36,27 +33,27 @@ class BedItem final : public Item { return sleeperGUID; } - void setHouse(House* h) { + void setHouse(const std::shared_ptr &h) { house = h; } - bool canUse(Player* player); + bool canUse(std::shared_ptr player); - bool trySleep(Player* player); - bool sleep(Player* player); - void wakeUp(Player* player); + bool trySleep(std::shared_ptr player); + bool sleep(std::shared_ptr player); + void wakeUp(std::shared_ptr player); - BedItem* getNextBedItem() const; + std::shared_ptr getNextBedItem(); friend class MapCache; private: - void updateAppearance(const Player* player); - void regeneratePlayer(Player* player) const; - void internalSetSleeper(const Player* player); + void updateAppearance(std::shared_ptr player); + void regeneratePlayer(std::shared_ptr player) const; + void internalSetSleeper(std::shared_ptr player); void internalRemoveSleeper(); - House* house = nullptr; + std::shared_ptr house; uint64_t sleepStart; uint32_t sleeperGUID; }; diff --git a/src/items/containers/container.cpp b/src/items/containers/container.cpp index fbe9486c3..262a647e0 100644 --- a/src/items/containers/container.cpp +++ b/src/items/containers/container.cpp @@ -30,56 +30,58 @@ Container::Container(uint16_t initType, uint16_t initSize, bool initUnlocked /*= unlocked(initUnlocked), pagination(initPagination) { } -Container::Container(Tile* tile) : - Container(ITEM_BROWSEFIELD, 30, false, true) { +std::shared_ptr Container::create(uint16_t type) { + return std::make_shared(type); +} + +std::shared_ptr Container::create(uint16_t type, uint16_t size, bool unlocked /*= true*/, bool pagination /*= false*/) { + return std::make_shared(type, size, unlocked, pagination); +} + +std::shared_ptr Container::create(std::shared_ptr tile) { + auto container = std::make_shared(ITEM_BROWSEFIELD, 30, false, true); TileItemVector* itemVector = tile->getItemList(); if (itemVector) { - for (Item* item : *itemVector) { + for (auto &item : *itemVector) { if (((item->getContainer() || item->hasProperty(CONST_PROP_MOVEABLE)) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVEABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) && !item->hasAttribute(ItemAttribute_t::UNIQUEID)) { - itemlist.push_front(item); - item->setParent(this); + container->itemlist.push_front(item); + item->setParent(container); } } } - setParent(tile); + container->setParent(tile); + return container; } Container::~Container() { if (getID() == ITEM_BROWSEFIELD) { - g_game().browseFields.erase(getTile()); - - for (Item* item : itemlist) { - item->setParent(parent); - } - } else { - for (Item* item : itemlist) { - item->setParent(nullptr); - item->decrementReferenceCounter(); + for (std::shared_ptr item : itemlist) { + item->setParent(m_parent); } } } -Item* Container::clone() const { - Container* clone = static_cast(Item::clone()); - for (Item* item : itemlist) { +std::shared_ptr Container::clone() const { + std::shared_ptr clone = std::static_pointer_cast(Item::clone()); + for (std::shared_ptr item : itemlist) { clone->addItem(item->clone()); } clone->totalWeight = totalWeight; return clone; } -Container* Container::getParentContainer() { - Thing* thing = getParent(); +std::shared_ptr Container::getParentContainer() { + std::shared_ptr thing = getParent(); if (!thing) { return nullptr; } return thing->getContainer(); } -Container* Container::getTopParentContainer() const { - Thing* thing = getParent(); - Thing* prevThing = const_cast(this); +std::shared_ptr Container::getTopParentContainer() { + std::shared_ptr thing = getParent(); + std::shared_ptr prevThing = getContainer(); if (!thing) { return prevThing->getContainer(); } @@ -96,17 +98,23 @@ Container* Container::getTopParentContainer() const { return thing->getContainer(); } -Container* Container::getRootContainer() const { +std::shared_ptr Container::getRootContainer() { return getTopParentContainer(); } -bool Container::hasParent() const { - return getID() != ITEM_BROWSEFIELD && dynamic_cast(getParent()) == nullptr; +bool Container::hasParent() { + auto parent = getParent(); + if (!parent) { + return false; + } + auto creature = parent->getCreature(); + bool isPlayer = creature && creature->getPlayer() != nullptr; + return getID() != ITEM_BROWSEFIELD && !isPlayer; } -void Container::addItem(Item* item) { +void Container::addItem(std::shared_ptr item) { itemlist.push_back(item); - item->setParent(this); + item->setParent(getContainer()); } StashContainerList Container::getStowableItems() const { @@ -115,11 +123,11 @@ StashContainerList Container::getStowableItems() const { if (item->getContainer() != NULL) { auto subContainer = item->getContainer()->getStowableItems(); for (auto subContItem : subContainer) { - Item* containerItem = subContItem.first; - toReturnList.push_back(std::pair(containerItem, static_cast(containerItem->getItemCount()))); + std::shared_ptr containerItem = subContItem.first; + toReturnList.push_back(std::pair, uint32_t>(containerItem, static_cast(containerItem->getItemCount()))); } } else if (item->isItemStorable()) { - toReturnList.push_back(std::pair(item, static_cast(item->getItemCount()))); + toReturnList.push_back(std::pair, uint32_t>(item, static_cast(item->getItemCount()))); } } @@ -159,7 +167,7 @@ bool Container::unserializeItemNode(OTB::Loader &loader, const OTB::Node &node, return false; } - Item* item = Item::CreateItem(id, itemPosition); + std::shared_ptr item = Item::CreateItem(id, itemPosition); if (!item) { continue; } @@ -188,7 +196,7 @@ bool Container::countsToLootAnalyzerBalance() { void Container::updateItemWeight(int32_t diff) { totalWeight += diff; - Container* parentContainer = this; // credits: SaiyansKing + std::shared_ptr parentContainer = getContainer(); while ((parentContainer = parentContainer->getParentContainer()) != nullptr) { parentContainer->totalWeight += diff; } @@ -198,17 +206,17 @@ uint32_t Container::getWeight() const { return Item::getWeight() + totalWeight; } -std::string Container::getContentDescription(bool oldProtocol) const { +std::string Container::getContentDescription(bool oldProtocol) { std::ostringstream os; return getContentDescription(os, oldProtocol).str(); } -std::ostringstream &Container::getContentDescription(std::ostringstream &os, bool oldProtocol) const { +std::ostringstream &Container::getContentDescription(std::ostringstream &os, bool oldProtocol) { bool firstitem = true; for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { - Item* item = *it; + std::shared_ptr item = *it; - Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && !container->empty()) { continue; } @@ -245,11 +253,11 @@ bool Container::isStoreInboxFiltered() const { return false; } -std::deque Container::getStoreInboxFilteredItems() const { +std::deque> Container::getStoreInboxFilteredItems() const { const auto enumName = getAttribute(ItemAttribute_t::STORE_INBOX_CATEGORY); ItemDeque storeInboxFilteredList; if (isStoreInboxFiltered()) { - for (Item* item : getItemList()) { + for (std::shared_ptr item : getItemList()) { auto itemId = item->getID(); auto attribute = item->getCustomAttribute("unWrapId"); uint16_t unWrapId = attribute ? static_cast(attribute->getInteger()) : 0; @@ -291,8 +299,8 @@ phmap::flat_hash_set Container::getStoreInboxValidCategorie return validCategories; } -Item* Container::getFilteredItemByIndex(size_t index) const { - const auto &filteredItems = getStoreInboxFilteredItems(); +std::shared_ptr Container::getFilteredItemByIndex(size_t index) const { + const auto filteredItems = getStoreInboxFilteredItems(); if (index >= filteredItems.size()) { return nullptr; } @@ -307,7 +315,7 @@ Item* Container::getFilteredItemByIndex(size_t index) const { return *it; } -Item* Container::getItemByIndex(size_t index) const { +std::shared_ptr Container::getItemByIndex(size_t index) const { if (index >= size()) { return nullptr; } @@ -315,7 +323,7 @@ Item* Container::getItemByIndex(size_t index) const { return itemlist[index]; } -uint32_t Container::getItemHoldingCount() const { +uint32_t Container::getItemHoldingCount() { uint32_t counter = 0; for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { ++counter; @@ -323,7 +331,7 @@ uint32_t Container::getItemHoldingCount() const { return counter; } -uint32_t Container::getContainerHoldingCount() const { +uint32_t Container::getContainerHoldingCount() { uint32_t counter = 0; for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { if ((*it)->getContainer()) { @@ -333,7 +341,7 @@ uint32_t Container::getContainerHoldingCount() const { return counter; } -bool Container::isHoldingItem(const Item* item) const { +bool Container::isHoldingItem(std::shared_ptr item) { for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { if (*it == item) { return true; @@ -342,9 +350,9 @@ bool Container::isHoldingItem(const Item* item) const { return false; } -bool Container::isHoldingItemWithId(const uint16_t id) const { +bool Container::isHoldingItemWithId(const uint16_t id) { for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { - const Item* item = *it; + std::shared_ptr item = *it; if (item->getID() == id) { return true; } @@ -352,52 +360,52 @@ bool Container::isHoldingItemWithId(const uint16_t id) const { return false; } -void Container::onAddContainerItem(Item* item) { +void Container::onAddContainerItem(std::shared_ptr item) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, getPosition(), false, true, 2, 2, 2, 2); // send to client - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendAddContainerItem(this, item); + for (std::shared_ptr spectator : spectators) { + spectator->getPlayer()->sendAddContainerItem(getContainer(), item); } // event methods - for (Creature* spectator : spectators) { + for (std::shared_ptr spectator : spectators) { spectator->getPlayer()->onAddContainerItem(item); } } -void Container::onUpdateContainerItem(uint32_t index, Item* oldItem, Item* newItem) { +void Container::onUpdateContainerItem(uint32_t index, std::shared_ptr oldItem, std::shared_ptr newItem) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, getPosition(), false, true, 2, 2, 2, 2); // send to client - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendUpdateContainerItem(this, index, newItem); + for (std::shared_ptr spectator : spectators) { + spectator->getPlayer()->sendUpdateContainerItem(getContainer(), index, newItem); } // event methods - for (Creature* spectator : spectators) { - spectator->getPlayer()->onUpdateContainerItem(this, oldItem, newItem); + for (std::shared_ptr spectator : spectators) { + spectator->getPlayer()->onUpdateContainerItem(getContainer(), oldItem, newItem); } } -void Container::onRemoveContainerItem(uint32_t index, Item* item) { +void Container::onRemoveContainerItem(uint32_t index, std::shared_ptr item) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, getPosition(), false, true, 2, 2, 2, 2); // send change to client - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendRemoveContainerItem(this, index); + for (std::shared_ptr spectator : spectators) { + spectator->getPlayer()->sendRemoveContainerItem(getContainer(), index); } // event methods - for (Creature* spectator : spectators) { - spectator->getPlayer()->onRemoveContainerItem(this, item); + for (std::shared_ptr spectator : spectators) { + spectator->getPlayer()->onRemoveContainerItem(getContainer(), item); } } -ReturnValue Container::queryAdd(int32_t addIndex, const Thing &addThing, uint32_t addCount, uint32_t flags, Creature* actor /* = nullptr*/) const { +ReturnValue Container::queryAdd(int32_t addIndex, const std::shared_ptr &addThing, uint32_t addCount, uint32_t flags, std::shared_ptr actor /* = nullptr*/) { bool childIsOwner = hasBitSet(FLAG_CHILDISOWNER, flags); if (childIsOwner) { // a child container is querying, since we are the top container (not carried by a player) @@ -409,7 +417,7 @@ ReturnValue Container::queryAdd(int32_t addIndex, const Thing &addThing, uint32_ return RETURNVALUE_NOTPOSSIBLE; } - const Item* item = addThing.getItem(); + std::shared_ptr item = addThing->getItem(); if (item == nullptr) { return RETURNVALUE_NOTPOSSIBLE; } @@ -418,21 +426,21 @@ ReturnValue Container::queryAdd(int32_t addIndex, const Thing &addThing, uint32_ return RETURNVALUE_CANNOTPICKUP; } - if (item == this) { + if (item == getItem()) { return RETURNVALUE_THISISIMPOSSIBLE; } - const Cylinder* cylinder = getParent(); + std::shared_ptr cylinder = getParent(); auto noLimit = hasBitSet(FLAG_NOLIMIT, flags); while (cylinder) { - if (cylinder == &addThing) { + if (cylinder == addThing) { return RETURNVALUE_THISISIMPOSSIBLE; } - const Container* container = cylinder->getContainer(); + std::shared_ptr container = cylinder->getContainer(); if (!noLimit && container && container->isInbox()) { return RETURNVALUE_CONTAINERNOTENOUGHROOM; } - const Cylinder* parent = cylinder->getParent(); + std::shared_ptr parent = cylinder->getParent(); if (cylinder == parent) { g_logger().error("Container::queryAdd: parent == cylinder. Preventing infinite loop."); return RETURNVALUE_NOTPOSSIBLE; @@ -444,8 +452,8 @@ ReturnValue Container::queryAdd(int32_t addIndex, const Thing &addThing, uint32_ return RETURNVALUE_CONTAINERNOTENOUGHROOM; } - if (const Container* topParentContainer = getTopParentContainer()) { - if (const Container* addContainer = item->getContainer()) { + if (std::shared_ptr topParentContainer = getTopParentContainer()) { + if (std::shared_ptr addContainer = item->getContainer()) { uint32_t addContainerCount = addContainer->getContainerHoldingCount() + 1; uint32_t maxContainer = static_cast(g_configManager().getNumber(MAX_CONTAINER)); if (addContainerCount + topParentContainer->getContainerHoldingCount() > maxContainer) { @@ -467,16 +475,16 @@ ReturnValue Container::queryAdd(int32_t addIndex, const Thing &addThing, uint32_ return RETURNVALUE_ONLYAMMOINQUIVER; } - const Cylinder* topParent = getTopParent(); - if (topParent != this) { - return topParent->queryAdd(INDEX_WHEREEVER, *item, addCount, flags | FLAG_CHILDISOWNER, actor); + std::shared_ptr topParent = getTopParent(); + if (topParent != getContainer()) { + return topParent->queryAdd(INDEX_WHEREEVER, item, addCount, flags | FLAG_CHILDISOWNER, actor); } else { return RETURNVALUE_NOERROR; } } -ReturnValue Container::queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const { - const Item* item = thing.getItem(); +ReturnValue Container::queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) { + std::shared_ptr item = thing->getItem(); if (item == nullptr) { maxQueryCount = 0; return RETURNVALUE_NOTPOSSIBLE; @@ -495,16 +503,16 @@ ReturnValue Container::queryMaxCount(int32_t index, const Thing &thing, uint32_t if (index == INDEX_WHEREEVER) { // Iterate through every item and check how much free stackable slots there is. uint32_t slotIndex = 0; - for (Item* containerItem : itemlist) { + for (std::shared_ptr containerItem : itemlist) { if (containerItem != item && containerItem->equals(item) && containerItem->getItemCount() < containerItem->getStackSize()) { uint32_t remainder = (containerItem->getStackSize() - containerItem->getItemCount()); - if (queryAdd(slotIndex++, *item, remainder, flags) == RETURNVALUE_NOERROR) { + if (queryAdd(slotIndex++, item, remainder, flags) == RETURNVALUE_NOERROR) { n += remainder; } } } } else { - const Item* destItem = getItemByIndex(index); + std::shared_ptr destItem = getItemByIndex(index); if (item->equals(destItem) && destItem->getItemCount() < destItem->getStackSize()) { n = destItem->getStackSize() - destItem->getItemCount(); } @@ -524,14 +532,14 @@ ReturnValue Container::queryMaxCount(int32_t index, const Thing &thing, uint32_t return RETURNVALUE_NOERROR; } -ReturnValue Container::queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* actor /*= nullptr */) const { - int32_t index = getThingIndex(&thing); +ReturnValue Container::queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor /*= nullptr */) { + int32_t index = getThingIndex(thing); if (index == -1) { g_logger().debug("{} - Failed to get thing index", __FUNCTION__); return RETURNVALUE_NOTPOSSIBLE; } - const Item* item = thing.getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { g_logger().debug("{} - Item is nullptr", __FUNCTION__); return RETURNVALUE_NOTPOSSIBLE; @@ -546,28 +554,28 @@ ReturnValue Container::queryRemove(const Thing &thing, uint32_t count, uint32_t g_logger().debug("{} - Item is not moveable", __FUNCTION__); return RETURNVALUE_NOTMOVEABLE; } - const HouseTile* houseTile = dynamic_cast(getTopParent()); + std::shared_ptr houseTile = std::dynamic_pointer_cast(getTopParent()); if (houseTile) { return houseTile->queryRemove(thing, count, flags, actor); } return RETURNVALUE_NOERROR; } -Cylinder* Container::queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) { +std::shared_ptr Container::queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) { if (!unlocked) { *destItem = nullptr; - return this; + return getContainer(); } if (index == 254 /*move up*/) { index = INDEX_WHEREEVER; *destItem = nullptr; - Container* parentContainer = dynamic_cast(getParent()); + std::shared_ptr parentContainer = std::dynamic_pointer_cast(getParent()); if (parentContainer) { return parentContainer; } - return this; + return getContainer(); } if (index == 255 /*add wherever*/) { @@ -585,18 +593,18 @@ Cylinder* Container::queryDestination(int32_t &index, const Thing &thing, Item** *destItem = nullptr; } - const Item* item = thing.getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { - return this; + return getContainer(); } if (index != INDEX_WHEREEVER) { - Item* itemFromIndex = getItemByIndex(index); + std::shared_ptr itemFromIndex = getItemByIndex(index); if (itemFromIndex) { *destItem = itemFromIndex; } - Cylinder* subCylinder = dynamic_cast(*destItem); + std::shared_ptr subCylinder = std::dynamic_pointer_cast(*destItem); if (subCylinder) { index = INDEX_WHEREEVER; *destItem = nullptr; @@ -605,30 +613,30 @@ Cylinder* Container::queryDestination(int32_t &index, const Thing &thing, Item** } bool autoStack = !hasBitSet(FLAG_IGNOREAUTOSTACK, flags); - if (autoStack && item->isStackable() && item->getParent() != this) { + if (autoStack && item->isStackable() && item->getParent() != getContainer()) { if (*destItem && (*destItem)->equals(item) && (*destItem)->getItemCount() < (*destItem)->getStackSize()) { - return this; + return getContainer(); } // try find a suitable item to stack with uint32_t n = 0; - for (Item* listItem : itemlist) { + for (std::shared_ptr listItem : itemlist) { if (listItem != item && listItem->equals(item) && listItem->getItemCount() < listItem->getStackSize()) { *destItem = listItem; index = n; - return this; + return getContainer(); } ++n; } } - return this; + return getContainer(); } -void Container::addThing(Thing* thing) { +void Container::addThing(std::shared_ptr thing) { return addThing(0, thing); } -void Container::addThing(int32_t index, Thing* thing) { +void Container::addThing(int32_t index, std::shared_ptr thing) { if (!thing) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -637,12 +645,12 @@ void Container::addThing(int32_t index, Thing* thing) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - item->setParent(this); + item->setParent(getContainer()); itemlist.push_front(item); updateItemWeight(item->getWeight()); @@ -652,7 +660,7 @@ void Container::addThing(int32_t index, Thing* thing) { } } -void Container::addItemBack(Item* item) { +void Container::addItemBack(std::shared_ptr item) { addItem(item); updateItemWeight(item->getWeight()); @@ -662,13 +670,13 @@ void Container::addItemBack(Item* item) { } } -void Container::updateThing(Thing* thing, uint16_t itemId, uint32_t count) { +void Container::updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) { int32_t index = getThingIndex(thing); if (index == -1) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -684,19 +692,19 @@ void Container::updateThing(Thing* thing, uint16_t itemId, uint32_t count) { } } -void Container::replaceThing(uint32_t index, Thing* thing) { - Item* item = thing->getItem(); +void Container::replaceThing(uint32_t index, std::shared_ptr thing) { + std::shared_ptr item = thing->getItem(); if (!item) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* replacedItem = getItemByIndex(index); + std::shared_ptr replacedItem = getItemByIndex(index); if (!replacedItem) { return /*RETURNVALUE_NOTPOSSIBLE*/; } itemlist[index] = item; - item->setParent(this); + item->setParent(getContainer()); updateItemWeight(-static_cast(replacedItem->getWeight()) + item->getWeight()); // send change to client @@ -704,11 +712,11 @@ void Container::replaceThing(uint32_t index, Thing* thing) { onUpdateContainerItem(index, replacedItem, item); } - replacedItem->setParent(nullptr); + replacedItem->resetParent(); } -void Container::removeThing(Thing* thing, uint32_t count) { - Item* item = thing->getItem(); +void Container::removeThing(std::shared_ptr thing, uint32_t count) { + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -736,14 +744,14 @@ void Container::removeThing(Thing* thing, uint32_t count) { onRemoveContainerItem(index, item); } - item->setParent(nullptr); + item->resetParent(); itemlist.erase(itemlist.begin() + index); } } -int32_t Container::getThingIndex(const Thing* thing) const { +int32_t Container::getThingIndex(std::shared_ptr thing) const { int32_t index = 0; - for (Item* item : itemlist) { + for (std::shared_ptr item : itemlist) { if (item == thing) { return index; } @@ -762,7 +770,7 @@ size_t Container::getLastIndex() const { uint32_t Container::getItemTypeCount(uint16_t itemId, int32_t subType /* = -1*/) const { uint32_t count = 0; - for (Item* item : itemlist) { + for (std::shared_ptr item : itemlist) { if (item->getID() == itemId) { count += countByType(item, subType); } @@ -771,35 +779,35 @@ uint32_t Container::getItemTypeCount(uint16_t itemId, int32_t subType /* = -1*/) } std::map &Container::getAllItemTypeCount(std::map &countMap) const { - for (Item* item : itemlist) { + for (std::shared_ptr item : itemlist) { countMap[item->getID()] += item->getItemCount(); } return countMap; } -Thing* Container::getThing(size_t index) const { +std::shared_ptr Container::getThing(size_t index) const { return getItemByIndex(index); } -ItemVector Container::getItems(bool recursive /*= false*/) const { +ItemVector Container::getItems(bool recursive /*= false*/) { ItemVector containerItems; if (recursive) { for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { containerItems.push_back(*it); } } else { - for (Item* item : itemlist) { + for (std::shared_ptr item : itemlist) { containerItems.push_back(item); } } return containerItems; } -void Container::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { - Cylinder* topParent = getTopParent(); +void Container::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { + std::shared_ptr topParent = getTopParent(); if (topParent->getCreature()) { topParent->postAddNotification(thing, oldParent, index, LINK_TOPPARENT); - } else if (topParent == this) { + } else if (topParent == getContainer()) { // let the tile class notify surrounding players if (topParent->getParent()) { topParent->getParent()->postAddNotification(thing, oldParent, index, LINK_NEAR); @@ -809,11 +817,11 @@ void Container::postAddNotification(Thing* thing, const Cylinder* oldParent, int } } -void Container::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { - Cylinder* topParent = getTopParent(); +void Container::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { + std::shared_ptr topParent = getTopParent(); if (topParent->getCreature()) { topParent->postRemoveNotification(thing, newParent, index, LINK_TOPPARENT); - } else if (topParent == this) { + } else if (topParent == getContainer()) { // let the tile class notify surrounding players if (topParent->getParent()) { topParent->getParent()->postRemoveNotification(thing, newParent, index, LINK_NEAR); @@ -823,44 +831,44 @@ void Container::postRemoveNotification(Thing* thing, const Cylinder* newParent, } } -void Container::internalAddThing(Thing* thing) { +void Container::internalAddThing(std::shared_ptr thing) { internalAddThing(0, thing); } -void Container::internalAddThing(uint32_t, Thing* thing) { +void Container::internalAddThing(uint32_t, std::shared_ptr thing) { if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return; } - item->setParent(this); + item->setParent(getContainer()); itemlist.push_front(item); updateItemWeight(item->getWeight()); } void Container::startDecaying() { - g_decay().startDecay(this); + g_decay().startDecay(getContainer()); for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { g_decay().startDecay(*it); } } void Container::stopDecaying() { - g_decay().stopDecay(this); + g_decay().stopDecay(getContainer()); for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { g_decay().stopDecay(*it); } } -uint16_t Container::getFreeSlots() const { +uint16_t Container::getFreeSlots() { uint16_t counter = std::max(0, capacity() - size()); - for (Item* item : itemlist) { - if (Container* container = item->getContainer()) { + for (std::shared_ptr item : itemlist) { + if (std::shared_ptr container = item->getContainer()) { counter += std::max(0, container->getFreeSlots()); } } @@ -868,16 +876,16 @@ uint16_t Container::getFreeSlots() const { return counter; } -ContainerIterator Container::iterator() const { +ContainerIterator Container::iterator() { ContainerIterator cit; if (!itemlist.empty()) { - cit.over.push_back(this); + cit.over.push_back(getContainer()); cit.cur = itemlist.begin(); } return cit; } -void Container::removeItem(Thing* thing, bool sendUpdateToClient /* = false*/) { +void Container::removeItem(std::shared_ptr thing, bool sendUpdateToClient /* = false*/) { if (thing == nullptr) { return; } @@ -895,17 +903,17 @@ void Container::removeItem(Thing* thing, bool sendUpdateToClient /* = false*/) { } itemlist.erase(it); - itemToRemove->setParent(nullptr); + itemToRemove->resetParent(); } } -Item* ContainerIterator::operator*() { +std::shared_ptr ContainerIterator::operator*() { return *cur; } void ContainerIterator::advance() { - if (Item* i = *cur) { - if (Container* c = i->getContainer()) { + if (std::shared_ptr i = *cur) { + if (std::shared_ptr c = i->getContainer()) { if (!c->empty()) { over.push_back(c); } diff --git a/src/items/containers/container.hpp b/src/items/containers/container.hpp index b58929b36..815611200 100644 --- a/src/items/containers/container.hpp +++ b/src/items/containers/container.hpp @@ -26,10 +26,10 @@ class ContainerIterator { } void advance(); - Item* operator*(); + std::shared_ptr operator*(); private: - std::list over; + std::list> over; ItemDeque::const_iterator cur; friend class Container; @@ -39,42 +39,33 @@ class Container : public Item, public Cylinder { public: explicit Container(uint16_t type); Container(uint16_t type, uint16_t size, bool unlocked = true, bool pagination = false); - explicit Container(Tile* type); ~Container(); + static std::shared_ptr create(uint16_t type); + static std::shared_ptr create(uint16_t type, uint16_t size, bool unlocked = true, bool pagination = false); + static std::shared_ptr create(std::shared_ptr type); + // non-copyable Container(const Container &) = delete; Container &operator=(const Container &) = delete; - Item* clone() const override final; + std::shared_ptr clone() const override final; - Container* getContainer() override final { - return this; - } - const Container* getContainer() const override final { - return this; + std::shared_ptr getContainer() override final { + return static_self_cast(); } - Container* getRootContainer() const; + std::shared_ptr getRootContainer(); - virtual DepotLocker* getDepotLocker() { - return nullptr; - } - virtual const DepotLocker* getDepotLocker() const { + virtual std::shared_ptr getDepotLocker() { return nullptr; } - virtual RewardChest* getRewardChest() { - return nullptr; - } - virtual const RewardChest* getRewardChest() const { + virtual std::shared_ptr getRewardChest() { return nullptr; } - virtual Reward* getReward() { - return nullptr; - } - virtual const Reward* getReward() const { + virtual std::shared_ptr getReward() { return nullptr; } virtual bool isInbox() const { @@ -86,7 +77,7 @@ class Container : public Item, public Cylinder { Attr_ReadValue readAttr(AttrTypes_t attr, PropStream &propStream) override; bool unserializeItemNode(OTB::Loader &loader, const OTB::Node &node, PropStream &propStream, Position &itemPosition) override; - std::string getContentDescription(bool oldProtocol) const; + std::string getContentDescription(bool oldProtocol); size_t size() const { return itemlist.size(); @@ -98,7 +89,7 @@ class Container : public Item, public Cylinder { return maxSize; } - ContainerIterator iterator() const; + ContainerIterator iterator(); const ItemDeque &getItemList() const { return itemlist; @@ -112,21 +103,21 @@ class Container : public Item, public Cylinder { } bool countsToLootAnalyzerBalance(); - bool hasParent() const; - void addItem(Item* item); + bool hasParent(); + void addItem(std::shared_ptr item); StashContainerList getStowableItems() const; bool isStoreInbox() const; bool isStoreInboxFiltered() const; - std::deque getStoreInboxFilteredItems() const; + std::deque> getStoreInboxFilteredItems() const; phmap::flat_hash_set getStoreInboxValidCategories() const; - Item* getFilteredItemByIndex(size_t index) const; - Item* getItemByIndex(size_t index) const; - bool isHoldingItem(const Item* item) const; - bool isHoldingItemWithId(const uint16_t id) const; - - uint32_t getItemHoldingCount() const; - uint32_t getContainerHoldingCount() const; - uint16_t getFreeSlots() const; + std::shared_ptr getFilteredItemByIndex(size_t index) const; + std::shared_ptr getItemByIndex(size_t index) const; + bool isHoldingItem(std::shared_ptr item); + bool isHoldingItemWithId(const uint16_t id); + + uint32_t getItemHoldingCount(); + uint32_t getContainerHoldingCount(); + uint16_t getFreeSlots(); uint32_t getWeight() const override final; bool isUnlocked() const { @@ -137,41 +128,41 @@ class Container : public Item, public Cylinder { } // cylinder implementations - virtual ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - ReturnValue queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const override final; - ReturnValue queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override final; - Cylinder* queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) override final; + virtual ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + ReturnValue queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) override final; + ReturnValue queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override final; + std::shared_ptr queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) override final; - void addThing(Thing* thing) override final; - void addThing(int32_t index, Thing* thing) override final; - void addItemBack(Item* item); + void addThing(std::shared_ptr thing) override final; + void addThing(int32_t index, std::shared_ptr thing) override final; + void addItemBack(std::shared_ptr item); - void updateThing(Thing* thing, uint16_t itemId, uint32_t count) override final; - void replaceThing(uint32_t index, Thing* thing) override final; + void updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) override final; + void replaceThing(uint32_t index, std::shared_ptr thing) override final; - void removeThing(Thing* thing, uint32_t count) override final; + void removeThing(std::shared_ptr thing, uint32_t count) override final; - int32_t getThingIndex(const Thing* thing) const override final; + int32_t getThingIndex(std::shared_ptr 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; std::map &getAllItemTypeCount(std::map &countMap) const override final; - Thing* getThing(size_t index) const override final; + std::shared_ptr getThing(size_t index) const override final; - ItemVector getItems(bool recursive = false) const; + ItemVector getItems(bool recursive = false); - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void internalAddThing(Thing* thing) override final; - void internalAddThing(uint32_t index, Thing* thing) override final; + void internalAddThing(std::shared_ptr thing) override final; + void internalAddThing(uint32_t index, std::shared_ptr thing) override final; void startDecaying() override; void stopDecaying() override; - virtual void removeItem(Thing* thing, bool sendUpdateToClient = false); + virtual void removeItem(std::shared_ptr thing, bool sendUpdateToClient = false); protected: - std::ostringstream &getContentDescription(std::ostringstream &os, bool oldProtocol) const; + std::ostringstream &getContentDescription(std::ostringstream &os, bool oldProtocol); uint32_t m_maxItems; uint32_t maxSize; @@ -185,12 +176,12 @@ class Container : public Item, public Cylinder { friend class MapCache; private: - void onAddContainerItem(Item* item); - void onUpdateContainerItem(uint32_t index, Item* oldItem, Item* newItem); - void onRemoveContainerItem(uint32_t index, Item* item); + void onAddContainerItem(std::shared_ptr item); + void onUpdateContainerItem(uint32_t index, std::shared_ptr oldItem, std::shared_ptr newItem); + void onRemoveContainerItem(uint32_t index, std::shared_ptr item); - Container* getParentContainer(); - Container* getTopParentContainer() const; + std::shared_ptr getParentContainer(); + std::shared_ptr getTopParentContainer(); void updateItemWeight(int32_t diff); friend class ContainerIterator; diff --git a/src/items/containers/depot/depotchest.cpp b/src/items/containers/depot/depotchest.cpp index 2e116d90f..011915798 100644 --- a/src/items/containers/depot/depotchest.cpp +++ b/src/items/containers/depot/depotchest.cpp @@ -19,8 +19,8 @@ DepotChest::DepotChest(uint16_t type) : pagination = true; } -ReturnValue DepotChest::queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor /* = nullptr*/) const { - const Item* item = thing.getItem(); +ReturnValue DepotChest::queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor /* = nullptr*/) { + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return RETURNVALUE_NOTPOSSIBLE; } @@ -33,15 +33,15 @@ ReturnValue DepotChest::queryAdd(int32_t index, const Thing &thing, uint32_t cou addCount = 1; } - if (item->getTopParent() != this) { - if (const Container* container = item->getContainer()) { + if (item->getTopParent().get() != this) { + if (std::shared_ptr container = item->getContainer()) { addCount = container->getItemHoldingCount() + 1; } else { addCount = 1; } } - if (Cylinder* localParent = getRealParent()) { + if (std::shared_ptr localParent = getRealParent()) { if (localParent->getContainer()->getItemHoldingCount() + addCount > maxDepotItems) { return RETURNVALUE_DEPOTISFULL; } @@ -53,23 +53,24 @@ ReturnValue DepotChest::queryAdd(int32_t index, const Thing &thing, uint32_t cou return Container::queryAdd(index, thing, count, flags, actor); } -void DepotChest::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { - Cylinder* localParent = getParent(); +void DepotChest::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { + std::shared_ptr localParent = getParent(); if (localParent != nullptr) { localParent->postAddNotification(thing, oldParent, index, LINK_PARENT); } } -void DepotChest::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { - Cylinder* localParent = getParent(); +void DepotChest::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { + std::shared_ptr localParent = getParent(); if (localParent != nullptr) { localParent->postRemoveNotification(thing, newParent, index, LINK_PARENT); } } -Cylinder* DepotChest::getParent() const { - if (parent && parent->getParent()) { - return parent->getParent()->getParent(); +std::shared_ptr DepotChest::getParent() { + auto parentLocked = m_parent.lock(); + if (parentLocked && parentLocked->getParent()) { + return parentLocked->getParent()->getParent(); } return nullptr; } diff --git a/src/items/containers/depot/depotchest.hpp b/src/items/containers/depot/depotchest.hpp index 001e63d2e..069bad382 100644 --- a/src/items/containers/depot/depotchest.hpp +++ b/src/items/containers/depot/depotchest.hpp @@ -21,10 +21,10 @@ class DepotChest final : public Container { } // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; bool isDepotChest() const override { return true; @@ -34,13 +34,13 @@ class DepotChest final : public Container { bool canRemove() const override { return false; } - bool isRemoved() const override { + bool isRemoved() override { return false; } - Cylinder* getParent() const override; - Cylinder* getRealParent() const override { - return parent; + std::shared_ptr getParent() override; + std::shared_ptr getRealParent() override { + return m_parent.lock(); } private: diff --git a/src/items/containers/depot/depotlocker.cpp b/src/items/containers/depot/depotlocker.cpp index e09542845..c431e8bd5 100644 --- a/src/items/containers/depot/depotlocker.cpp +++ b/src/items/containers/depot/depotlocker.cpp @@ -24,23 +24,25 @@ Attr_ReadValue DepotLocker::readAttr(AttrTypes_t attr, PropStream &propStream) { return Item::readAttr(attr, propStream); } -ReturnValue DepotLocker::queryAdd(int32_t, const Thing &, uint32_t, uint32_t, Creature*) const { +ReturnValue DepotLocker::queryAdd(int32_t, const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr) { return RETURNVALUE_NOTENOUGHROOM; } -void DepotLocker::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { - if (parent != nullptr) { - parent->postAddNotification(thing, oldParent, index, LINK_PARENT); +void DepotLocker::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { + auto parentLocked = m_parent.lock(); + if (parentLocked) { + parentLocked->postAddNotification(thing, oldParent, index, LINK_PARENT); } } -void DepotLocker::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { - if (parent != nullptr) { - parent->postRemoveNotification(thing, newParent, index, LINK_PARENT); +void DepotLocker::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { + auto parentLocked = m_parent.lock(); + if (parentLocked) { + parentLocked->postRemoveNotification(thing, newParent, index, LINK_PARENT); } } -void DepotLocker::removeInbox(Inbox* inbox) { +void DepotLocker::removeInbox(std::shared_ptr inbox) { auto cit = std::find(itemlist.begin(), itemlist.end(), inbox); if (cit == itemlist.end()) { return; diff --git a/src/items/containers/depot/depotlocker.hpp b/src/items/containers/depot/depotlocker.hpp index 4cf9b127b..b8f33c15c 100644 --- a/src/items/containers/depot/depotlocker.hpp +++ b/src/items/containers/depot/depotlocker.hpp @@ -16,14 +16,11 @@ class DepotLocker final : public Container { public: explicit DepotLocker(uint16_t type, uint16_t size); - DepotLocker* getDepotLocker() override { - return this; - } - const DepotLocker* getDepotLocker() const override { - return this; + std::shared_ptr getDepotLocker() override { + return static_self_cast(); } - void removeInbox(Inbox* inbox); + void removeInbox(std::shared_ptr inbox); // serialization Attr_ReadValue readAttr(AttrTypes_t attr, PropStream &propStream) override; @@ -36,15 +33,15 @@ class DepotLocker final : public Container { } // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; bool canRemove() const override { return false; } - bool isRemoved() const override { + bool isRemoved() override { return false; } diff --git a/src/items/containers/inbox/inbox.cpp b/src/items/containers/inbox/inbox.cpp index 126b4ea35..7859cd3be 100644 --- a/src/items/containers/inbox/inbox.cpp +++ b/src/items/containers/inbox/inbox.cpp @@ -17,19 +17,19 @@ Inbox::Inbox(uint16_t type) : maxInboxItems = std::numeric_limits::max(); } -ReturnValue Inbox::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t flags, Creature*) const { +ReturnValue Inbox::queryAdd(int32_t, const std::shared_ptr &thing, uint32_t, uint32_t flags, std::shared_ptr) { int32_t addCount = 0; if (!hasBitSet(FLAG_NOLIMIT, flags)) { return RETURNVALUE_CONTAINERNOTENOUGHROOM; } - const Item* item = thing.getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { return RETURNVALUE_NOTPOSSIBLE; } - if (item == this) { + if (item.get() == this) { return RETURNVALUE_THISISIMPOSSIBLE; } @@ -37,8 +37,8 @@ ReturnValue Inbox::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t flag return RETURNVALUE_CANNOTPICKUP; } - if (item->getTopParent() != this) { // MY - if (const Container* container = item->getContainer()) { + if (item->getTopParent().get() != this) { // MY + if (std::shared_ptr container = item->getContainer()) { addCount = container->getItemHoldingCount() + 1; } else { addCount = 1; @@ -52,23 +52,24 @@ ReturnValue Inbox::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t flag return RETURNVALUE_NOERROR; } -void Inbox::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { - Cylinder* localParent = getParent(); +void Inbox::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { + std::shared_ptr localParent = getParent(); if (localParent != nullptr) { localParent->postAddNotification(thing, oldParent, index, LINK_PARENT); } } -void Inbox::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { - Cylinder* localParent = getParent(); +void Inbox::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { + std::shared_ptr localParent = getParent(); if (localParent != nullptr) { localParent->postRemoveNotification(thing, newParent, index, LINK_PARENT); } } -Cylinder* Inbox::getParent() const { - if (parent) { - return parent->getParent(); +std::shared_ptr Inbox::getParent() { + auto parentLocked = m_parent.lock(); + if (parentLocked) { + return parentLocked->getParent(); } return nullptr; } diff --git a/src/items/containers/inbox/inbox.hpp b/src/items/containers/inbox/inbox.hpp index b58f03d67..058f96e02 100644 --- a/src/items/containers/inbox/inbox.hpp +++ b/src/items/containers/inbox/inbox.hpp @@ -20,10 +20,10 @@ class Inbox final : public Container { } // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; bool isInbox() const override { return true; @@ -33,13 +33,13 @@ class Inbox final : public Container { bool canRemove() const override { return false; } - bool isRemoved() const override { + bool isRemoved() override { return false; } - Cylinder* getParent() const override; - Cylinder* getRealParent() const override { - return parent; + std::shared_ptr getParent() override; + std::shared_ptr getRealParent() override { + return m_parent.lock(); } private: diff --git a/src/items/containers/mailbox/mailbox.cpp b/src/items/containers/mailbox/mailbox.cpp index af3b79eae..bfc732939 100644 --- a/src/items/containers/mailbox/mailbox.cpp +++ b/src/items/containers/mailbox/mailbox.cpp @@ -13,63 +13,63 @@ #include "game/game.hpp" #include "io/iologindata.hpp" -ReturnValue Mailbox::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t, Creature*) const { - const Item* item = thing.getItem(); +ReturnValue Mailbox::queryAdd(int32_t, const std::shared_ptr &thing, uint32_t, uint32_t, std::shared_ptr) { + std::shared_ptr item = thing->getItem(); if (item && Mailbox::canSend(item)) { return RETURNVALUE_NOERROR; } return RETURNVALUE_NOTPOSSIBLE; } -ReturnValue Mailbox::queryMaxCount(int32_t, const Thing &, uint32_t count, uint32_t &maxQueryCount, uint32_t) const { +ReturnValue Mailbox::queryMaxCount(int32_t, const std::shared_ptr &, uint32_t count, uint32_t &maxQueryCount, uint32_t) { maxQueryCount = std::max(1, count); return RETURNVALUE_NOERROR; } -ReturnValue Mailbox::queryRemove(const Thing &, uint32_t, uint32_t, Creature* /*= nullptr */) const { +ReturnValue Mailbox::queryRemove(const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr /*= nullptr */) { return RETURNVALUE_NOTPOSSIBLE; } -Cylinder* Mailbox::queryDestination(int32_t &, const Thing &, Item**, uint32_t &) { - return this; +std::shared_ptr Mailbox::queryDestination(int32_t &, const std::shared_ptr &, std::shared_ptr*, uint32_t &) { + return getMailbox(); } -void Mailbox::addThing(Thing* thing) { +void Mailbox::addThing(std::shared_ptr thing) { return addThing(0, thing); } -void Mailbox::addThing(int32_t, Thing* thing) { +void Mailbox::addThing(int32_t, std::shared_ptr thing) { if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item && Mailbox::canSend(item)) { sendItem(item); } } -void Mailbox::updateThing(Thing*, uint16_t, uint32_t) { +void Mailbox::updateThing(std::shared_ptr, uint16_t, uint32_t) { // } -void Mailbox::replaceThing(uint32_t, Thing*) { +void Mailbox::replaceThing(uint32_t, std::shared_ptr) { // } -void Mailbox::removeThing(Thing*, uint32_t) { +void Mailbox::removeThing(std::shared_ptr, uint32_t) { // } -void Mailbox::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { +void Mailbox::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { getParent()->postAddNotification(thing, oldParent, index, LINK_PARENT); } -void Mailbox::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { +void Mailbox::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { getParent()->postRemoveNotification(thing, newParent, index, LINK_PARENT); } -bool Mailbox::sendItem(Item* item) const { +bool Mailbox::sendItem(std::shared_ptr item) const { std::string receiver; if (!getReceiver(item, receiver)) { return false; @@ -83,14 +83,14 @@ bool Mailbox::sendItem(Item* item) const { if (item && item->getContainer() && item->getTile()) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, item->getTile()->getPosition(), false, true); - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { if (spectator && spectator->getPlayer()) { spectator->getPlayer()->autoCloseContainers(item->getContainer()); } } } - Player* player = g_game().getPlayerByName(receiver, true); + std::shared_ptr player = g_game().getPlayerByName(receiver, true); std::string writer; time_t date = time(0); std::string text; @@ -101,7 +101,7 @@ bool Mailbox::sendItem(Item* item) const { } if (player && item) { if (g_game().internalMoveItem(item->getParent(), player->getInbox(), INDEX_WHEREEVER, item, item->getItemCount(), nullptr, FLAG_NOLIMIT) == RETURNVALUE_NOERROR) { - Item* newItem = g_game().transformItem(item, item->getID() + 1); + auto newItem = g_game().transformItem(item, item->getID() + 1); if (newItem && newItem->getID() == ITEM_LETTER_STAMPED && writer != "") { newItem->setAttribute(ItemAttribute_t::WRITER, writer); newItem->setAttribute(ItemAttribute_t::DATE, date); @@ -111,7 +111,6 @@ bool Mailbox::sendItem(Item* item) const { player->onReceiveMail(); } else { IOLoginData::savePlayer(player); - delete player; } return true; } @@ -119,10 +118,10 @@ bool Mailbox::sendItem(Item* item) const { return false; } -bool Mailbox::getReceiver(Item* item, std::string &name) const { - const Container* container = item->getContainer(); +bool Mailbox::getReceiver(std::shared_ptr item, std::string &name) const { + std::shared_ptr container = item->getContainer(); if (container) { - for (Item* containerItem : container->getItemList()) { + for (std::shared_ptr containerItem : container->getItemList()) { if (containerItem->getID() == ITEM_LABEL && getReceiver(containerItem, name)) { return true; } @@ -140,6 +139,6 @@ bool Mailbox::getReceiver(Item* item, std::string &name) const { return true; } -bool Mailbox::canSend(const Item* item) { +bool Mailbox::canSend(std::shared_ptr item) { return item->getID() == ITEM_PARCEL || item->getID() == ITEM_LETTER; } diff --git a/src/items/containers/mailbox/mailbox.hpp b/src/items/containers/mailbox/mailbox.hpp index bf22096d0..3d57c72b5 100644 --- a/src/items/containers/mailbox/mailbox.hpp +++ b/src/items/containers/mailbox/mailbox.hpp @@ -17,33 +17,30 @@ class Mailbox final : public Item, public Cylinder { explicit Mailbox(uint16_t itemId) : Item(itemId) { } - Mailbox* getMailbox() override { - return this; - } - const Mailbox* getMailbox() const override { - return this; + std::shared_ptr getMailbox() override { + return static_self_cast(); } // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - ReturnValue queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const override; - ReturnValue queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - Cylinder* queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + ReturnValue queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) override; + ReturnValue queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + std::shared_ptr queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) override; - void addThing(Thing* thing) override; - void addThing(int32_t index, Thing* thing) override; + void addThing(std::shared_ptr thing) override; + void addThing(int32_t index, std::shared_ptr thing) override; - void updateThing(Thing* thing, uint16_t itemId, uint32_t count) override; - void replaceThing(uint32_t index, Thing* thing) override; + void updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) override; + void replaceThing(uint32_t index, std::shared_ptr thing) override; - void removeThing(Thing* thing, uint32_t count) override; + void removeThing(std::shared_ptr thing, uint32_t count) override; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; private: - bool getReceiver(Item* item, std::string &name) const; - bool sendItem(Item* item) const; + bool getReceiver(std::shared_ptr item, std::string &name) const; + bool sendItem(std::shared_ptr item) const; - static bool canSend(const Item* item); + static bool canSend(std::shared_ptr item); }; diff --git a/src/items/containers/rewards/reward.cpp b/src/items/containers/rewards/reward.cpp index 7dac4a719..62ef98b0c 100644 --- a/src/items/containers/rewards/reward.cpp +++ b/src/items/containers/rewards/reward.cpp @@ -18,17 +18,17 @@ Reward::Reward() : pagination = true; } -ReturnValue Reward::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t, Creature* actor /* = nullptr*/) const { +ReturnValue Reward::queryAdd(int32_t, const std::shared_ptr &thing, uint32_t, uint32_t, std::shared_ptr actor /* = nullptr*/) { if (actor) { return RETURNVALUE_NOTPOSSIBLE; } - const Item* item = thing.getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { return RETURNVALUE_NOTPOSSIBLE; } - if (item == this) { + if (item.get() == this) { return RETURNVALUE_THISISIMPOSSIBLE; } @@ -39,20 +39,20 @@ ReturnValue Reward::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t, Cr return RETURNVALUE_NOERROR; } -void Reward::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { - Cylinder* localParent = getParent(); +void Reward::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { + std::shared_ptr localParent = getParent(); if (localParent != nullptr) { localParent->postAddNotification(thing, oldParent, index, LINK_PARENT); } } -void Reward::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { - Cylinder* localParent = getParent(); +void Reward::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { + std::shared_ptr localParent = getParent(); if (localParent != nullptr) { localParent->postRemoveNotification(thing, newParent, index, LINK_PARENT); } } -Cylinder* Reward::getParent() const { - return parent; +std::shared_ptr Reward::getParent() { + return m_parent.lock(); } diff --git a/src/items/containers/rewards/reward.hpp b/src/items/containers/rewards/reward.hpp index 8bc6ae274..f372fbfb7 100644 --- a/src/items/containers/rewards/reward.hpp +++ b/src/items/containers/rewards/reward.hpp @@ -15,26 +15,23 @@ class Reward : public Container { public: explicit Reward(); - Reward* getReward() final { - return this; - } - const Reward* getReward() const final { - return this; + std::shared_ptr getReward() final { + return static_self_cast(); } // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const final; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) final; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) final; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) final; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) final; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) final; // overrides bool canRemove() const final { return true; } - Cylinder* getParent() const final; - Cylinder* getRealParent() const final { - return parent; + std::shared_ptr getParent() final; + std::shared_ptr getRealParent() final { + return m_parent.lock(); } }; diff --git a/src/items/containers/rewards/rewardchest.cpp b/src/items/containers/rewards/rewardchest.cpp index 0ed966d78..007294911 100644 --- a/src/items/containers/rewards/rewardchest.cpp +++ b/src/items/containers/rewards/rewardchest.cpp @@ -18,7 +18,7 @@ RewardChest::RewardChest(uint16_t type) : pagination = true; } -ReturnValue RewardChest::queryAdd(int32_t, const Thing &, uint32_t, uint32_t, Creature* actor /* = nullptr*/) const { +ReturnValue RewardChest::queryAdd(int32_t, const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr actor /* = nullptr*/) { if (actor) { return RETURNVALUE_NOTPOSSIBLE; } @@ -26,20 +26,22 @@ ReturnValue RewardChest::queryAdd(int32_t, const Thing &, uint32_t, uint32_t, Cr return RETURNVALUE_NOERROR; } -void RewardChest::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { - if (parent != nullptr) { - parent->postAddNotification(thing, oldParent, index, LINK_PARENT); +void RewardChest::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { + auto parentLocked = m_parent.lock(); + if (parentLocked) { + parentLocked->postAddNotification(thing, oldParent, index, LINK_PARENT); } } -void RewardChest::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { - if (parent != nullptr) { - parent->postRemoveNotification(thing, newParent, index, LINK_PARENT); +void RewardChest::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { + auto parentLocked = m_parent.lock(); + if (parentLocked) { + parentLocked->postRemoveNotification(thing, newParent, index, LINK_PARENT); } } // Second argument is disabled by default because not need to send to client in the RewardChest -void RewardChest::removeItem(Thing* thing, bool /* sendToClient = false*/) { +void RewardChest::removeItem(std::shared_ptr thing, bool /* sendToClient = false*/) { if (thing == nullptr) { return; } @@ -52,6 +54,6 @@ void RewardChest::removeItem(Thing* thing, bool /* sendToClient = false*/) { auto it = std::ranges::find(itemlist.begin(), itemlist.end(), itemToRemove); if (it != itemlist.end()) { itemlist.erase(it); - itemToRemove->setParent(nullptr); + itemToRemove->resetParent(); } } diff --git a/src/items/containers/rewards/rewardchest.hpp b/src/items/containers/rewards/rewardchest.hpp index 6f09d8579..295eafc06 100644 --- a/src/items/containers/rewards/rewardchest.hpp +++ b/src/items/containers/rewards/rewardchest.hpp @@ -15,22 +15,19 @@ class RewardChest final : public Container { public: explicit RewardChest(uint16_t type); - RewardChest* getRewardChest() final { - return this; - } - const RewardChest* getRewardChest() const final { - return this; + std::shared_ptr getRewardChest() final { + return static_self_cast(); } // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const final; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) final; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) final; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) final; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) final; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) final; bool canRemove() const final { return false; } - void removeItem(Thing* thing, bool sendToClient = false) override; + void removeItem(std::shared_ptr thing, bool sendToClient = false) override; }; diff --git a/src/items/cylinder.cpp b/src/items/cylinder.cpp index e88bc1a0c..c328b1fbd 100644 --- a/src/items/cylinder.cpp +++ b/src/items/cylinder.cpp @@ -11,9 +11,9 @@ #include "items/cylinder.hpp" -VirtualCylinder* VirtualCylinder::virtualCylinder = new VirtualCylinder; +std::shared_ptr VirtualCylinder::virtualCylinder = std::make_shared(); -int32_t Cylinder::getThingIndex(const Thing*) const { +int32_t Cylinder::getThingIndex(std::shared_ptr) const { return -1; } @@ -33,15 +33,15 @@ std::map &Cylinder::getAllItemTypeCount(std::map Cylinder::getThing(size_t) const { return nullptr; } -void Cylinder::internalAddThing(Thing*) { +void Cylinder::internalAddThing(std::shared_ptr) { // } -void Cylinder::internalAddThing(uint32_t, Thing*) { +void Cylinder::internalAddThing(uint32_t, std::shared_ptr) { // } diff --git a/src/items/cylinder.hpp b/src/items/cylinder.hpp index f0d1b1423..bab34b5ce 100644 --- a/src/items/cylinder.hpp +++ b/src/items/cylinder.hpp @@ -30,7 +30,7 @@ class Cylinder : virtual public Thing { * \param actor the creature trying to add the thing * \returns ReturnValue holds the return value */ - virtual ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const = 0; + virtual ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) = 0; /** * Query the cylinder how much it can accept @@ -42,7 +42,7 @@ class Cylinder : virtual public Thing { * \param flags optional flags to modify the default behaviour * \returns ReturnValue holds the return value */ - virtual ReturnValue queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const = 0; + virtual ReturnValue queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) = 0; /** * Query if the cylinder can remove an object @@ -51,7 +51,7 @@ class Cylinder : virtual public Thing { * \param flags optional flags to modify the default behaviour * \returns ReturnValue holds the return value */ - virtual ReturnValue queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* = nullptr) const = 0; + virtual ReturnValue queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr = nullptr) = 0; /** * Query the destination cylinder @@ -63,20 +63,20 @@ class Cylinder : virtual public Thing { * this method can modify the flags * \returns Cylinder returns the destination cylinder */ - virtual Cylinder* queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) = 0; + virtual std::shared_ptr queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) = 0; /** * Add the object to the cylinder * \param thing is the object to add */ - virtual void addThing(Thing* thing) = 0; + virtual void addThing(std::shared_ptr thing) = 0; /** * Add the object to the cylinder * \param index points to the destination index (inventory slot/container position) * \param thing is the object to add */ - virtual void addThing(int32_t index, Thing* thing) = 0; + virtual void addThing(int32_t index, std::shared_ptr thing) = 0; /** * Update the item count or type for an object @@ -84,21 +84,21 @@ class Cylinder : virtual public Thing { * \param itemId is the new item id * \param count is the new count value */ - virtual void updateThing(Thing* thing, uint16_t itemId, uint32_t count) = 0; + virtual void updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) = 0; /** * Replace an object with a new * \param index is the position to change (inventory slot/container position) * \param thing is the object to update */ - virtual void replaceThing(uint32_t index, Thing* thing) = 0; + virtual void replaceThing(uint32_t index, std::shared_ptr thing) = 0; /** * Remove an object * \param thing is the object to delete * \param count is the new count value */ - virtual void removeThing(Thing* thing, uint32_t count) = 0; + virtual void removeThing(std::shared_ptr thing, uint32_t count) = 0; /** * Is sent after an operation (move/add) to update internal values @@ -106,7 +106,7 @@ class Cylinder : virtual public Thing { * \param index is the objects new index value * \param link holds the relation the object has to the cylinder */ - virtual void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) = 0; + virtual void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) = 0; /** * Is sent after an operation (move/remove) to update internal values @@ -114,14 +114,14 @@ class Cylinder : virtual public Thing { * \param index is the previous index of the removed object * \param link holds the relation the object has to the cylinder */ - virtual void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) = 0; + virtual void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) = 0; /** * Gets the index of an object * \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 int32_t getThingIndex(std::shared_ptr thing) const; /** * Returns the first index @@ -139,7 +139,7 @@ class Cylinder : virtual public Thing { * Gets the object based on index * \returns the object, returns nullptr if not found */ - virtual Thing* getThing(size_t index) const; + virtual std::shared_ptr getThing(size_t index) const; /** * Get the amount of items of a certain type @@ -160,54 +160,54 @@ class Cylinder : virtual public Thing { * Adds an object to the cylinder without sending to the client(s) * \param thing is the object to add */ - virtual void internalAddThing(Thing* thing); + virtual void internalAddThing(std::shared_ptr thing); /** * Adds an object to the cylinder without sending to the client(s) * \param thing is the object to add * \param index points to the destination index (inventory slot/container position) */ - virtual void internalAddThing(uint32_t index, Thing* thing); + virtual void internalAddThing(uint32_t index, std::shared_ptr thing); virtual void startDecaying(); }; class VirtualCylinder final : public Cylinder { public: - static VirtualCylinder* virtualCylinder; + static std::shared_ptr virtualCylinder; - virtual ReturnValue queryAdd(int32_t, const Thing &, uint32_t, uint32_t, Creature* = nullptr) const override { + virtual ReturnValue queryAdd(int32_t, const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr = nullptr) override { return RETURNVALUE_NOTPOSSIBLE; } - virtual ReturnValue queryMaxCount(int32_t, const Thing &, uint32_t, uint32_t &, uint32_t) const override { + virtual ReturnValue queryMaxCount(int32_t, const std::shared_ptr &, uint32_t, uint32_t &, uint32_t) override { return RETURNVALUE_NOTPOSSIBLE; } - virtual ReturnValue queryRemove(const Thing &, uint32_t, uint32_t, Creature* = nullptr) const override { + virtual ReturnValue queryRemove(const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr = nullptr) override { return RETURNVALUE_NOTPOSSIBLE; } - virtual Cylinder* queryDestination(int32_t &, const Thing &, Item**, uint32_t &) override { + virtual std::shared_ptr queryDestination(int32_t &, const std::shared_ptr &, std::shared_ptr*, uint32_t &) override { return nullptr; } - virtual void addThing(Thing*) override { } - virtual void addThing(int32_t, Thing*) override { } - virtual void updateThing(Thing*, uint16_t, uint32_t) override { } - virtual void replaceThing(uint32_t, Thing*) override { } - virtual void removeThing(Thing*, uint32_t) override { } + virtual void addThing(std::shared_ptr) override { } + virtual void addThing(int32_t, std::shared_ptr) override { } + virtual void updateThing(std::shared_ptr, uint16_t, uint32_t) override { } + virtual void replaceThing(uint32_t, std::shared_ptr) override { } + virtual void removeThing(std::shared_ptr, uint32_t) override { } - virtual void postAddNotification(Thing*, const Cylinder*, int32_t, CylinderLink_t = LINK_OWNER) override { } - virtual void postRemoveNotification(Thing*, const Cylinder*, int32_t, CylinderLink_t = LINK_OWNER) override { } + virtual void postAddNotification(std::shared_ptr, std::shared_ptr, int32_t, CylinderLink_t = LINK_OWNER) override { } + virtual void postRemoveNotification(std::shared_ptr, std::shared_ptr, int32_t, CylinderLink_t = LINK_OWNER) override { } - bool isPushable() const override { + bool isPushable() override { return false; } int32_t getThrowRange() const override { return 1; } - std::string getDescription(int32_t) const override { + std::string getDescription(int32_t) override { return {}; } - bool isRemoved() const override { + bool isRemoved() override { return false; } }; diff --git a/src/items/decay/decay.cpp b/src/items/decay/decay.cpp index 0dbf2fa0f..77c7eb9f3 100644 --- a/src/items/decay/decay.cpp +++ b/src/items/decay/decay.cpp @@ -13,7 +13,7 @@ #include "game/game.hpp" #include "game/scheduling/scheduler.hpp" -void Decay::startDecay(Item* item) { +void Decay::startDecay(std::shared_ptr item) { if (!item) { return; } @@ -49,43 +49,42 @@ void Decay::startDecay(Item* item) { } } - item->incrementReferenceCounter(); item->setDecaying(DECAYING_TRUE); item->setAttribute(ItemAttribute_t::DURATION_TIMESTAMP, timestamp); decayMap[timestamp].push_back(item); } } -void Decay::stopDecay(Item* item) { +void Decay::stopDecay(std::shared_ptr item) { if (item->hasAttribute(ItemAttribute_t::DECAYSTATE)) { auto timestamp = item->getAttribute(ItemAttribute_t::DURATION_TIMESTAMP); if (item->hasAttribute(ItemAttribute_t::DURATION_TIMESTAMP)) { auto it = decayMap.find(timestamp); if (it != decayMap.end()) { - std::vector &decayItems = it->second; + auto &decayItems = it->second; size_t i = 0, end = decayItems.size(); + auto decayItem = decayItems[i]; if (end == 1) { - if (item == decayItems[i]) { + if (item == decayItem) { if (item->hasAttribute(ItemAttribute_t::DURATION)) { // Incase we removed duration attribute don't assign new duration item->setDuration(item->getDuration()); } item->removeAttribute(ItemAttribute_t::DECAYSTATE); - g_game().ReleaseItem(item); decayMap.erase(it); } return; } while (i < end) { - if (item == decayItems[i]) { + decayItem = decayItems[i]; + if (item == decayItem) { if (item->hasAttribute(ItemAttribute_t::DURATION)) { // Incase we removed duration attribute don't assign new duration item->setDuration(item->getDuration()); } item->removeAttribute(ItemAttribute_t::DECAYSTATE); - g_game().ReleaseItem(item); decayItems[i] = decayItems.back(); decayItems.pop_back(); @@ -104,7 +103,7 @@ void Decay::stopDecay(Item* item) { void Decay::checkDecay() { int64_t timestamp = OTSYS_TIME(); - std::vector tempItems; + std::vector> tempItems; tempItems.reserve(32); // Small preallocation auto it = decayMap.begin(), end = decayMap.end(); @@ -114,12 +113,15 @@ void Decay::checkDecay() { } // Iterating here is unsafe so let's copy our items into temporary vector - std::vector &decayItems = it->second; - tempItems.insert(tempItems.end(), decayItems.begin(), decayItems.end()); + auto &decayItems = it->second; + tempItems.reserve(tempItems.size() + decayItems.size()); + for (auto &decayItem : decayItems) { + tempItems.push_back(decayItem); + } it = decayMap.erase(it); } - for (Item* item : tempItems) { + for (const auto &item : tempItems) { if (!item->canDecay()) { item->setDuration(item->getDuration()); item->setDecaying(DECAYING_FALSE); @@ -127,19 +129,17 @@ void Decay::checkDecay() { item->setDecaying(DECAYING_FALSE); internalDecayItem(item); } - - g_game().ReleaseItem(item); } if (it != end) { - eventId = g_scheduler().addEvent(std::max(SCHEDULER_MINTICKS, static_cast(it->first - timestamp)), std::bind(&Decay::checkDecay, this), __FUNCTION__); + eventId = g_scheduler().addEvent(std::max(SCHEDULER_MINTICKS, static_cast(it->first - timestamp)), std::bind(&Decay::checkDecay, this), "Decay::checkDecay"); } } -void Decay::internalDecayItem(Item* item) { +void Decay::internalDecayItem(std::shared_ptr item) { const ItemType &it = Item::items[item->getID()]; if (it.decayTo != 0) { - Player* player = item->getHoldingPlayer(); + std::shared_ptr player = item->getHoldingPlayer(); if (player) { bool needUpdateSkills = false; for (int32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { diff --git a/src/items/decay/decay.hpp b/src/items/decay/decay.hpp index 9c3a39a61..4447da2a0 100644 --- a/src/items/decay/decay.hpp +++ b/src/items/decay/decay.hpp @@ -22,15 +22,16 @@ class Decay { return inject(); } - void startDecay(Item* item); - void stopDecay(Item* item); + void startDecay(std::shared_ptr item); + void stopDecay(std::shared_ptr item); private: void checkDecay(); - void internalDecayItem(Item* item); + void internalDecayItem(std::shared_ptr item); uint32_t eventId { 0 }; - std::map> decayMap; + // order is important, so we use an std::map + std::map>> decayMap; }; constexpr auto g_decay = Decay::getInstance; diff --git a/src/items/functions/item/item_parse.cpp b/src/items/functions/item/item_parse.cpp index 2172326f0..986b1f532 100644 --- a/src/items/functions/item/item_parse.cpp +++ b/src/items/functions/item/item_parse.cpp @@ -653,7 +653,7 @@ CombatType_t ItemParse::parseFieldCombatType(std::string lowerStringValue, pugi: return COMBAT_NONE; } -void ItemParse::parseFieldCombatDamage(ConditionDamage* conditionDamage, std::string stringValue, pugi::xml_node attributeNode) { +void ItemParse::parseFieldCombatDamage(std::shared_ptr conditionDamage, std::string stringValue, pugi::xml_node attributeNode) { uint32_t combatTicks = 0; int32_t combatDamage = 0; int32_t combatStart = 0; @@ -697,7 +697,7 @@ void ItemParse::parseFieldCombatDamage(ConditionDamage* conditionDamage, std::st void ItemParse::parseField(const std::string &tmpStrValue, pugi::xml_node attributeNode, pugi::xml_attribute valueAttribute, ItemType &itemType) { if (tmpStrValue == "field") { CombatType_t combatType = COMBAT_NONE; - ConditionDamage* conditionDamage = nullptr; + std::shared_ptr conditionDamage = nullptr; // Parse fields conditions (fire/energy/poison/drown/physical) combatType = parseFieldCombatType(tmpStrValue, valueAttribute); @@ -705,13 +705,12 @@ void ItemParse::parseField(const std::string &tmpStrValue, pugi::xml_node attrib if (combatType != COMBAT_NONE) { if (conditionDamage) { - delete conditionDamage; } - conditionDamage = new ConditionDamage(conditionId, conditionType); + conditionDamage = std::make_shared(conditionId, conditionType); itemType.combatType = combatType; - itemType.conditionDamage.reset(conditionDamage); + itemType.conditionDamage = conditionDamage; parseFieldCombatDamage(conditionDamage, tmpStrValue, attributeNode); diff --git a/src/items/functions/item/item_parse.hpp b/src/items/functions/item/item_parse.hpp index 510129df9..f29fc7997 100644 --- a/src/items/functions/item/item_parse.hpp +++ b/src/items/functions/item/item_parse.hpp @@ -315,5 +315,5 @@ class ItemParse : public Items { // Parent of the function: static void parseField static std::tuple parseFieldConditions(std::string lowerStringValue, pugi::xml_attribute valueAttribute); static CombatType_t parseFieldCombatType(std::string string, pugi::xml_attribute valueAttribute); - static void parseFieldCombatDamage(ConditionDamage* conditionDamage, std::string stringValue, pugi::xml_node attributeNode); + static void parseFieldCombatDamage(std::shared_ptr conditionDamage, std::string stringValue, pugi::xml_node attributeNode); }; diff --git a/src/items/item.cpp b/src/items/item.cpp index f38ac6c9e..9d185eacf 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -28,8 +28,8 @@ Items Item::items; -Item* Item::CreateItem(const uint16_t type, uint16_t count /*= 0*/, Position* itemPosition /*= nullptr*/) { - Item* newItem = nullptr; +std::shared_ptr Item::CreateItem(const uint16_t type, uint16_t count /*= 0*/, Position* itemPosition /*= nullptr*/) { + std::shared_ptr newItem = nullptr; const ItemType &it = Item::items[type]; if (it.stackable && count == 0) { @@ -38,33 +38,31 @@ Item* Item::CreateItem(const uint16_t type, uint16_t count /*= 0*/, Position* it if (it.id != 0) { if (it.isDepot()) { - newItem = new DepotLocker(type, 4); + newItem = std::make_shared(type, 4); } else if (it.isRewardChest()) { - newItem = new RewardChest(type); + newItem = std::make_shared(type); } else if (it.isContainer()) { - newItem = new Container(type); + newItem = std::make_shared(type); } else if (it.isTeleport()) { - newItem = new Teleport(type); + newItem = std::make_shared(type); } else if (it.isMagicField()) { - newItem = new MagicField(type); + newItem = std::make_shared(type); } else if (it.isDoor()) { - newItem = new Door(type); + newItem = std::make_shared(type); } else if (it.isTrashHolder()) { - newItem = new TrashHolder(type); + newItem = std::make_shared(type); } else if (it.isMailbox()) { - newItem = new Mailbox(type); + newItem = std::make_shared(type); } else if (it.isBed()) { - newItem = new BedItem(type); + newItem = std::make_shared(type); } else { auto itemMap = ItemTransformationMap.find(static_cast(it.id)); if (itemMap != ItemTransformationMap.end()) { - newItem = new Item(itemMap->second, count); + newItem = std::make_shared(itemMap->second, count); } else { - newItem = new Item(type, count); + newItem = std::make_shared(type, count); } } - - newItem->incrementReferenceCounter(); } else if (type > 0 && itemPosition) { auto position = *itemPosition; g_logger().warn("[Item::CreateItem] Item with id '{}', in position '{}' not exists in the appearances.dat and cannot be created.", type, position.toString()); @@ -89,7 +87,7 @@ void Item::setImbuement(uint8_t slot, uint16_t imbuementId, uint32_t duration) { } void Item::addImbuement(uint8_t slot, uint16_t imbuementId, uint32_t duration) { - Player* player = getHoldingPlayer(); + std::shared_ptr player = getHoldingPlayer(); if (!player) { return; } @@ -129,7 +127,7 @@ bool Item::hasImbuementCategoryId(uint16_t categoryId) const { return false; } -Container* Item::CreateItemAsContainer(const uint16_t type, uint16_t size) { +std::shared_ptr Item::CreateItemAsContainer(const uint16_t type, uint16_t size) { if (const ItemType &it = Item::items[type]; it.id == 0 || it.stackable @@ -142,12 +140,11 @@ Container* Item::CreateItemAsContainer(const uint16_t type, uint16_t size) { return nullptr; } - Container* newItem = new Container(type, size); - newItem->incrementReferenceCounter(); + std::shared_ptr newItem = std::make_shared(type, size); return newItem; } -Item* Item::CreateItem(uint16_t itemId, Position &itemPosition) { +std::shared_ptr Item::CreateItem(uint16_t itemId, Position &itemPosition) { switch (itemId) { case ITEM_FIREFIELD_PVP_FULL: itemId = ITEM_FIREFIELD_PERSISTENT_FULL; @@ -207,28 +204,28 @@ Item::Item(const uint16_t itemId, uint16_t itemCount /*= 0*/) : setDefaultDuration(); } -Item::Item(const Item &i) : - Thing(), id(i.id), count(i.count), loadedFromMap(i.loadedFromMap) { - if (i.attributePtr) { - attributePtr.reset(new ItemAttribute(*i.attributePtr)); +Item::Item(const std::shared_ptr &i) : + Thing(), id(i->id), count(i->count), loadedFromMap(i->loadedFromMap) { + if (i->attributePtr) { + attributePtr = std::make_unique(*i->attributePtr); } } -Item* Item::clone() const { - Item* item = Item::CreateItem(id, count); +std::shared_ptr Item::clone() const { + std::shared_ptr item = Item::CreateItem(id, count); if (item == nullptr) { g_logger().error("[{}] item is nullptr", __FUNCTION__); return nullptr; } if (attributePtr) { - item->attributePtr.reset(new ItemAttribute(*attributePtr)); + item->attributePtr = std::make_unique(*attributePtr); } return item; } -bool Item::equals(const Item* compareItem) const { +bool Item::equals(std::shared_ptr compareItem) const { if (!compareItem) { return false; } @@ -276,7 +273,7 @@ void Item::setDefaultSubtype() { } void Item::onRemoved() { - ScriptEnvironment::removeTempItem(this); + ScriptEnvironment::removeTempItem(static_self_cast()); if (hasAttribute(ItemAttribute_t::UNIQUEID)) { g_game().removeUniqueItem(getAttribute(ItemAttribute_t::UNIQUEID)); @@ -284,6 +281,7 @@ void Item::onRemoved() { } void Item::setID(uint16_t newid) { + g_logger().debug("[Item::setID] - Setting item id from {} to {}", id, newid); const ItemType &prevIt = Item::items[id]; id = newid; @@ -308,27 +306,9 @@ void Item::setID(uint16_t newid) { } } -Cylinder* Item::getTopParent() { - Cylinder* aux = getParent(); - Cylinder* prevaux = dynamic_cast(this); - if (!aux) { - return prevaux; - } - - while (aux && aux->getParent() != nullptr) { - prevaux = aux; - aux = aux->getParent(); - } - - if (prevaux) { - return prevaux; - } - return aux; -} - -const Cylinder* Item::getTopParent() const { - const Cylinder* aux = getParent(); - const Cylinder* prevaux = dynamic_cast(this); +std::shared_ptr Item::getTopParent() { + std::shared_ptr aux = getParent(); + std::shared_ptr prevaux = std::dynamic_pointer_cast(shared_from_this()); if (!aux) { return prevaux; } @@ -344,22 +324,13 @@ const Cylinder* Item::getTopParent() const { return aux; } -Tile* Item::getTile() { - Cylinder* cylinder = getTopParent(); - // get root cylinder - if (cylinder && cylinder->getParent()) { - cylinder = cylinder->getParent(); - } - return dynamic_cast(cylinder); -} - -const Tile* Item::getTile() const { - const Cylinder* cylinder = getTopParent(); +std::shared_ptr Item::getTile() { + std::shared_ptr cylinder = getTopParent(); // get root cylinder if (cylinder && cylinder->getParent()) { cylinder = cylinder->getParent(); } - return dynamic_cast(cylinder); + return std::dynamic_pointer_cast(cylinder); } uint16_t Item::getSubType() const { @@ -374,8 +345,8 @@ uint16_t Item::getSubType() const { return static_cast(count); } -Player* Item::getHoldingPlayer() const { - Cylinder* p = getParent(); +std::shared_ptr Item::getHoldingPlayer() { + std::shared_ptr p = getParent(); while (p) { if (p->getCreature()) { return p->getCreature()->getPlayer(); @@ -1037,7 +1008,7 @@ uint32_t Item::getWeight() const { } std::vector> -Item::getDescriptions(const ItemType &it, const Item* item /*= nullptr*/) { +Item::getDescriptions(const ItemType &it, std::shared_ptr item /*= nullptr*/) { std::ostringstream ss; std::vector> descriptions; bool isTradeable = true; @@ -1319,7 +1290,7 @@ Item::getDescriptions(const ItemType &it, const Item* item /*= nullptr*/) { for (uint8_t i = 0; i < item->getImbuementSlot(); ++i) { slotName = fmt::format("Imbuement Slot {}", i + 1); ss.str(""); - const auto &castItem = item; + const auto castItem = item; if (!castItem) { continue; } @@ -1826,7 +1797,7 @@ Item::getDescriptions(const ItemType &it, const Item* item /*= nullptr*/) { return descriptions; } -std::string Item::parseImbuementDescription(const Item* item) { +std::string Item::parseImbuementDescription(std::shared_ptr item) { std::ostringstream s; if (item && item->getImbuementSlot() >= 1) { s << std::endl @@ -1858,12 +1829,17 @@ std::string Item::parseImbuementDescription(const Item* item) { return s.str(); } -SoundEffect_t Item::getMovementSound(Cylinder* toCylinder) const { +bool Item::isSavedToHouses() { + const auto &it = items[id]; + return it.moveable || it.isWrappable() || it.isCarpet() || getDoor() || (getContainer() && !getContainer()->empty()) || it.canWriteText || getBed() || it.m_transformOnUse; +} + +SoundEffect_t Item::getMovementSound(std::shared_ptr toCylinder) const { if (!toCylinder) { return SoundEffect_t::ITEM_MOVE_DEFAULT; } - if (const Container* toContainer = toCylinder->getContainer(); + if (std::shared_ptr toContainer = toCylinder->getContainer(); toContainer && toContainer->getHoldingPlayer()) { return SoundEffect_t::ITEM_MOVE_BACKPACK; } @@ -1920,7 +1896,7 @@ SoundEffect_t Item::getMovementSound(Cylinder* toCylinder) const { return SoundEffect_t::ITEM_MOVE_DEFAULT; } -std::string Item::parseClassificationDescription(const Item* item) { +std::string Item::parseClassificationDescription(std::shared_ptr item) { std::ostringstream string; if (item && item->getClassification() >= 1) { string << std::endl @@ -1951,7 +1927,7 @@ std::string Item::parseShowDurationSpeed(int32_t speed, bool &begin) { return description.str(); } -std::string Item::parseShowDuration(const Item* item) { +std::string Item::parseShowDuration(std::shared_ptr item) { if (!item) { return {}; } @@ -1994,7 +1970,7 @@ std::string Item::parseShowDuration(const Item* item) { return description.str(); } -std::string Item::parseShowAttributesDescription(const Item* item, const uint16_t itemId) { +std::string Item::parseShowAttributesDescription(std::shared_ptr item, const uint16_t itemId) { std::ostringstream itemDescription; const ItemType &itemType = Item::items[itemId]; if (itemType.armor != 0 || (item && item->getArmor() != 0) || itemType.showAttributes) { @@ -2220,7 +2196,7 @@ std::string Item::parseShowAttributesDescription(const Item* item, const uint16_ return itemDescription.str(); } -std::string Item::getDescription(const ItemType &it, int32_t lookDistance, const Item* item /*= nullptr*/, int32_t subType /*= -1*/, bool addArticle /*= true*/) { +std::string Item::getDescription(const ItemType &it, int32_t lookDistance, std::shared_ptr item /*= nullptr*/, int32_t subType /*= -1*/, bool addArticle /*= true*/) { std::string text = ""; std::ostringstream s; @@ -2962,12 +2938,12 @@ std::string Item::getDescription(const ItemType &it, int32_t lookDistance, const return s.str(); } -std::string Item::getDescription(int32_t lookDistance) const { +std::string Item::getDescription(int32_t lookDistance) { const ItemType &it = items[id]; - return getDescription(it, lookDistance, this); + return getDescription(it, lookDistance, getItem()); } -std::string Item::getNameDescription(const ItemType &it, const Item* item /*= nullptr*/, int32_t subType /*= -1*/, bool addArticle /*= true*/) { +std::string Item::getNameDescription(const ItemType &it, std::shared_ptr item /*= nullptr*/, int32_t subType /*= -1*/, bool addArticle /*= true*/) { if (item) { subType = item->getSubType(); } @@ -2998,9 +2974,9 @@ std::string Item::getNameDescription(const ItemType &it, const Item* item /*= nu return s.str(); } -std::string Item::getNameDescription() const { +std::string Item::getNameDescription() { const ItemType &it = items[id]; - return getNameDescription(it, this); + return getNameDescription(it, getItem()); } std::string Item::getWeightDescription(const ItemType &it, uint32_t weight, uint32_t count /*= 1*/) { @@ -3043,12 +3019,12 @@ void Item::addUniqueId(uint16_t uniqueId) { return; } - if (g_game().addUniqueItem(uniqueId, this)) { + if (g_game().addUniqueItem(uniqueId, static_self_cast())) { setAttribute(ItemAttribute_t::UNIQUEID, uniqueId); } } -bool Item::canDecay() const { +bool Item::canDecay() { if (isRemoved() || isDecayDisabled()) { return false; } @@ -3103,36 +3079,37 @@ LightInfo Item::getLightInfo() const { } void Item::startDecaying() { - g_decay().startDecay(this); + g_decay().startDecay(static_self_cast()); } void Item::stopDecaying() { - g_decay().stopDecay(this); + g_logger().debug("Item::stopDecaying"); + g_decay().stopDecay(static_self_cast()); } -Item* Item::transform(uint16_t itemId, uint16_t itemCount /*= -1*/) { - Cylinder* cylinder = getParent(); +std::shared_ptr Item::transform(uint16_t itemId, uint16_t itemCount /*= -1*/) { + std::shared_ptr cylinder = getParent(); if (cylinder == nullptr) { g_logger().info("[{}] failed to transform item {}, cylinder is nullptr", __FUNCTION__, getID()); return nullptr; } - Tile* fromTile = cylinder->getTile(); + std::shared_ptr fromTile = cylinder->getTile(); if (fromTile) { auto it = g_game().browseFields.find(fromTile); - if (it != g_game().browseFields.end() && it->second == cylinder) { + if (it != g_game().browseFields.end() && it->second.lock() == cylinder) { cylinder = fromTile; } } - Item* newItem; + std::shared_ptr newItem; if (itemCount == -1) { newItem = Item::CreateItem(itemId, 1); } else { newItem = Item::CreateItem(itemId, itemCount); } - int32_t itemIndex = cylinder->getThingIndex(this); + int32_t itemIndex = cylinder->getThingIndex(static_self_cast()); auto duration = getDuration(); if (duration > 0) { newItem->setDuration(duration); @@ -3141,10 +3118,9 @@ Item* Item::transform(uint16_t itemId, uint16_t itemCount /*= -1*/) { cylinder->replaceThing(itemIndex, newItem); cylinder->postAddNotification(newItem, cylinder, itemIndex); - setParent(nullptr); - cylinder->postRemoveNotification(this, cylinder, itemIndex); + resetParent(); + cylinder->postRemoveNotification(static_self_cast(), cylinder, itemIndex); stopDecaying(); - g_game().ReleaseItem(this); newItem->startDecaying(); return newItem; } @@ -3175,17 +3151,17 @@ bool Item::hasMarketAttributes() const { return true; } -bool Item::isInsideDepot(bool includeInbox /* = false*/) const { - if (const Container* thisContainer = getContainer(); thisContainer && (thisContainer->getDepotLocker() || thisContainer->isDepotChest() || (includeInbox && thisContainer->isInbox()))) { +bool Item::isInsideDepot(bool includeInbox /* = false*/) { + if (std::shared_ptr thisContainer = getContainer(); thisContainer && (thisContainer->getDepotLocker() || thisContainer->isDepotChest() || (includeInbox && thisContainer->isInbox()))) { return true; } - const Cylinder* cylinder = getParent(); + std::shared_ptr cylinder = getParent(); if (!cylinder) { return false; } - const Container* container = cylinder->getContainer(); + std::shared_ptr container = cylinder->getContainer(); if (!container) { return false; } @@ -3203,6 +3179,6 @@ bool Item::isInsideDepot(bool includeInbox /* = false*/) const { void Item::updateTileFlags() { if (auto tile = getTile()) { - tile->updateTileFlags(this); + tile->updateTileFlags(static_self_cast()); } } diff --git a/src/items/item.hpp b/src/items/item.hpp index b54b47411..b8db280de 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -159,14 +159,14 @@ class ItemProperties { protected: std::unique_ptr &initAttributePtr() { if (!attributePtr) { - attributePtr.reset(new ItemAttribute()); + attributePtr = std::make_unique(); } return attributePtr; } const std::unique_ptr &initAttributePtr() const { if (!attributePtr) { - std::bit_cast(this)->attributePtr.reset(new ItemAttribute()); + std::bit_cast(this)->attributePtr = std::make_unique(); } return attributePtr; @@ -212,70 +212,51 @@ class ItemProperties { friend class Item; }; -class Item : virtual public Thing, public ItemProperties { +class Item : virtual public Thing, public ItemProperties, public SharedObject { public: // Factory member to create item of right type based on type - static Item* CreateItem(const uint16_t type, uint16_t count = 0, Position* itemPosition = nullptr); - static Container* CreateItemAsContainer(const uint16_t type, uint16_t size); - static Item* CreateItem(uint16_t itemId, Position &itemPosition); + static std::shared_ptr CreateItem(const uint16_t type, uint16_t count = 0, Position* itemPosition = nullptr); + static std::shared_ptr CreateItemAsContainer(const uint16_t type, uint16_t size); + static std::shared_ptr CreateItem(uint16_t itemId, Position &itemPosition); static Items items; // Constructor for items Item(const uint16_t type, uint16_t count = 0); - Item(const Item &i); - virtual Item* clone() const; + Item(const std::shared_ptr &i); + virtual std::shared_ptr clone() const; virtual ~Item() = default; // non-assignable Item &operator=(const Item &) = delete; - bool equals(const Item* compareItem) const; + bool equals(std::shared_ptr compareItem) const; - Item* getItem() override final { - return this; + std::shared_ptr getItem() override final { + return static_self_cast(); } - const Item* getItem() const override final { - return this; - } - virtual Teleport* getTeleport() { - return nullptr; - } - virtual const Teleport* getTeleport() const { - return nullptr; - } - virtual TrashHolder* getTrashHolder() { - return nullptr; - } - virtual const TrashHolder* getTrashHolder() const { - return nullptr; - } - virtual Mailbox* getMailbox() { - return nullptr; - } - virtual const Mailbox* getMailbox() const { - return nullptr; - } - virtual Door* getDoor() { + virtual std::shared_ptr getTeleport() { return nullptr; } - virtual const Door* getDoor() const { + virtual std::shared_ptr getTrashHolder() { return nullptr; } - virtual MagicField* getMagicField() { + virtual std::shared_ptr getMailbox() { return nullptr; } - virtual const MagicField* getMagicField() const { + virtual std::shared_ptr getDoor() { return nullptr; } - virtual BedItem* getBed() { + virtual std::shared_ptr getMagicField() { return nullptr; } - virtual const BedItem* getBed() const { + virtual std::shared_ptr getBed() { return nullptr; } - SoundEffect_t getMovementSound(Cylinder* toCylinder) const; + bool isSavedToHouses(); + + SoundEffect_t getMovementSound(std::shared_ptr toCylinder) const; void setIsLootTrackeable(bool value) { isLootTrackeable = value; @@ -285,19 +266,19 @@ class Item : virtual public Thing, public ItemProperties { return isLootTrackeable; } - static std::string parseImbuementDescription(const Item* item); + static std::string parseImbuementDescription(std::shared_ptr item); static std::string parseShowDurationSpeed(int32_t speed, bool &begin); - static std::string parseShowDuration(const Item* item); - static std::string parseShowAttributesDescription(const Item* item, const uint16_t itemId); - static std::string parseClassificationDescription(const Item* item); + static std::string parseShowDuration(std::shared_ptr item); + static std::string parseShowAttributesDescription(std::shared_ptr item, const uint16_t itemId); + static std::string parseClassificationDescription(std::shared_ptr item); - static std::vector> getDescriptions(const ItemType &it, const Item* item = nullptr); - static std::string getDescription(const ItemType &it, int32_t lookDistance, const Item* item = nullptr, int32_t subType = -1, bool addArticle = true); - static std::string getNameDescription(const ItemType &it, const Item* item = nullptr, int32_t subType = -1, bool addArticle = true); + static std::vector> getDescriptions(const ItemType &it, std::shared_ptr item = nullptr); + static std::string getDescription(const ItemType &it, int32_t lookDistance, std::shared_ptr item = nullptr, int32_t subType = -1, bool addArticle = true); + static std::string getNameDescription(const ItemType &it, std::shared_ptr item = nullptr, int32_t subType = -1, bool addArticle = true); static std::string getWeightDescription(const ItemType &it, uint32_t weight, uint32_t count = 1); - std::string getDescription(int32_t lookDistance) const override final; - std::string getNameDescription() const; + std::string getDescription(int32_t lookDistance) override final; + std::string getNameDescription(); std::string getWeightDescription() const; // serialization @@ -307,7 +288,7 @@ class Item : virtual public Thing, public ItemProperties { virtual void serializeAttr(PropWriteStream &propWriteStream) const; - bool isPushable() const override final { + bool isPushable() override final { return isMoveable(); } int32_t getThrowRange() const override final { @@ -320,7 +301,7 @@ class Item : virtual public Thing, public ItemProperties { void setID(uint16_t newid); // Returns the player that is holding this item in his inventory - Player* getHoldingPlayer() const; + std::shared_ptr getHoldingPlayer(); WeaponType_t getWeaponType() const { return items[id].weaponType; @@ -532,7 +513,7 @@ class Item : virtual public Thing, public ItemProperties { count = n; } - static uint32_t countByType(const Item* item, int32_t subType) { + static uint32_t countByType(std::shared_ptr item, int32_t subType) { if (subType == -1 || subType == item->getSubType()) { return item->getItemCount(); } @@ -556,7 +537,7 @@ class Item : virtual public Thing, public ItemProperties { return items[id].decayTime * 1000; } - bool canDecay() const; + bool canDecay(); virtual bool canRemove() const { return true; @@ -565,12 +546,12 @@ class Item : virtual public Thing, public ItemProperties { return true; } virtual void onRemoved(); - virtual void onTradeEvent(TradeEvents_t, Player*) { } + virtual void onTradeEvent(TradeEvents_t, std::shared_ptr) { } virtual void startDecaying(); virtual void stopDecaying(); - Item* transform(uint16_t itemId, uint16_t itemCount = -1); + std::shared_ptr transform(uint16_t itemId, uint16_t itemCount = -1); bool isLoadedFromMap() const { return loadedFromMap; @@ -582,30 +563,26 @@ class Item : virtual public Thing, public ItemProperties { bool hasMarketAttributes() const; - void incrementReferenceCounter() { - ++referenceCounter; - } - void decrementReferenceCounter() { - if (--referenceCounter == 0) { - delete this; - } + std::shared_ptr getParent() override { + return m_parent.lock(); } - - Cylinder* getParent() const override { - return parent; + void setParent(std::weak_ptr cylinder) override { + m_parent = cylinder; } - void setParent(Cylinder* cylinder) override { - parent = cylinder; + void resetParent() { + m_parent.reset(); } - Cylinder* getTopParent(); - const Cylinder* getTopParent() const; - Tile* getTile() override; - const Tile* getTile() const override; - bool isRemoved() const override { - return !parent || parent->isRemoved(); + std::shared_ptr getTopParent(); + std::shared_ptr getTile() override; + bool isRemoved() override { + auto parent = getParent(); + if (parent) { + return parent->isRemoved(); + } + return true; } - bool isInsideDepot(bool includeInbox = false) const; + bool isInsideDepot(bool includeInbox = false); /** * @brief Get the Imbuement Info object @@ -703,9 +680,7 @@ class Item : virtual public Thing, public ItemProperties { void checkDecayMapItemOnMove(); protected: - Cylinder* parent = nullptr; - - uint32_t referenceCounter = 0; + std::weak_ptr m_parent; uint16_t id; // the same id as in ItemType uint8_t count = 1; // number of stacked items @@ -723,6 +698,6 @@ class Item : virtual public Thing, public ItemProperties { friend class MapCache; }; -using ItemList = std::list; -using ItemDeque = std::deque; -using StashContainerList = std::vector>; +using ItemList = std::list>; +using ItemDeque = std::deque>; +using StashContainerList = std::vector, uint32_t>>; diff --git a/src/items/items.cpp b/src/items/items.cpp index 986f2b272..ca8e20e5b 100644 --- a/src/items/items.cpp +++ b/src/items/items.cpp @@ -162,6 +162,10 @@ void Items::loadFromProtobuf() { iType.pickupable = object.flags().take(); iType.rotatable = object.flags().rotate(); iType.wrapContainer = object.flags().wrap() || object.flags().unwrap(); + if (iType.wrapContainer) { + iType.wrapableTo = ITEM_DECORATION_KIT; + iType.wrapable = true; + } iType.multiUse = object.flags().multiuse(); iType.moveable = object.flags().unmove() == false; iType.canReadText = (object.flags().has_lenshelp() && object.flags().lenshelp().id() == 1112) || (object.flags().has_write() && object.flags().write().max_text_length() != 0) || (object.flags().has_write_once() && object.flags().write_once().max_text_length_once() != 0); diff --git a/src/items/items.hpp b/src/items/items.hpp index b21dbc7e4..d8b761894 100644 --- a/src/items/items.hpp +++ b/src/items/items.hpp @@ -204,7 +204,7 @@ class ItemType { Abilities &getAbilities() { if (!abilities) { - abilities.reset(new Abilities()); + abilities = std::make_unique(); } return *abilities; } @@ -242,7 +242,7 @@ class ItemType { std::string m_primaryType; std::unique_ptr abilities; - std::unique_ptr conditionDamage; + std::shared_ptr conditionDamage; uint32_t levelDoor = 0; uint32_t decayTime = 0; diff --git a/src/items/thing.cpp b/src/items/thing.cpp index f06989f51..0665f15a6 100644 --- a/src/items/thing.cpp +++ b/src/items/thing.cpp @@ -12,18 +12,10 @@ #include "items/thing.hpp" #include "items/tile.hpp" -const Position &Thing::getPosition() const { - const Tile* tile = getTile(); +const Position &Thing::getPosition() { + std::shared_ptr tile = getTile(); if (!tile) { - return Tile::nullptr_tile.getPosition(); + return Tile::nullptr_tile->getPosition(); } return tile->getPosition(); } - -Tile* Thing::getTile() { - return dynamic_cast(this); -} - -const Tile* Thing::getTile() const { - return dynamic_cast(this); -} diff --git a/src/items/thing.hpp b/src/items/thing.hpp index 990755e54..0a6161783 100644 --- a/src/items/thing.hpp +++ b/src/items/thing.hpp @@ -26,46 +26,47 @@ class Thing { Thing(const Thing &) = delete; Thing &operator=(const Thing &) = delete; - virtual std::string getDescription(int32_t lookDistance) const = 0; + virtual std::string getDescription(int32_t lookDistance) = 0; - virtual Cylinder* getParent() const { + virtual std::shared_ptr getParent() { return nullptr; } - virtual Cylinder* getRealParent() const { + virtual std::shared_ptr getRealParent() { return getParent(); } - virtual void setParent(Cylinder*) { + virtual void setParent(std::weak_ptr) { // } - virtual Tile* getTile(); - virtual const Tile* getTile() const; + virtual std::shared_ptr getTile() { + return nullptr; + } - virtual const Position &getPosition() const; + virtual const Position &getPosition(); virtual int32_t getThrowRange() const = 0; - virtual bool isPushable() const = 0; + virtual bool isPushable() = 0; - virtual Container* getContainer() { + virtual std::shared_ptr getContainer() { return nullptr; } - virtual const Container* getContainer() const { + virtual std::shared_ptr getContainer() const { return nullptr; } - virtual Item* getItem() { + virtual std::shared_ptr getItem() { return nullptr; } - virtual const Item* getItem() const { + virtual std::shared_ptr getItem() const { return nullptr; } - virtual Creature* getCreature() { + virtual std::shared_ptr getCreature() { return nullptr; } - virtual const Creature* getCreature() const { + virtual std::shared_ptr getCreature() const { return nullptr; } - virtual bool isRemoved() const { + virtual bool isRemoved() { return true; } }; diff --git a/src/items/tile.cpp b/src/items/tile.cpp index a7bc61158..37063181c 100644 --- a/src/items/tile.cpp +++ b/src/items/tile.cpp @@ -22,8 +22,8 @@ #include "map/house/housetile.hpp" #include "io/iomap.hpp" -StaticTile real_nullptr_tile(0xFFFF, 0xFFFF, 0xFF); -Tile &Tile::nullptr_tile = real_nullptr_tile; +auto real_nullptr_tile = std::make_shared(0xFFFF, 0xFFFF, 0xFF); +const std::shared_ptr &Tile::nullptr_tile = real_nullptr_tile; bool Tile::hasProperty(ItemProperty prop) const { if (ground && ground->hasProperty(prop)) { @@ -31,7 +31,7 @@ bool Tile::hasProperty(ItemProperty prop) const { } if (const TileItemVector* items = getItemList()) { - for (const Item* item : *items) { + for (auto &item : *items) { if (item->hasProperty(prop)) { return true; } @@ -40,7 +40,7 @@ bool Tile::hasProperty(ItemProperty prop) const { return false; } -bool Tile::hasProperty(const Item* exclude, ItemProperty prop) const { +bool Tile::hasProperty(std::shared_ptr exclude, ItemProperty prop) const { assert(exclude); if (ground && exclude != ground && ground->hasProperty(prop)) { @@ -48,7 +48,7 @@ bool Tile::hasProperty(const Item* exclude, ItemProperty prop) const { } if (const TileItemVector* items = getItemList()) { - for (const Item* item : *items) { + for (auto &item : *items) { if (item != exclude && item->hasProperty(prop)) { return true; } @@ -72,7 +72,7 @@ bool Tile::hasHeight(uint32_t n) const { } if (const TileItemVector* items = getItemList()) { - for (const Item* item : *items) { + for (auto &item : *items) { if (item->hasProperty(CONST_PROP_HASHEIGHT)) { ++height; } @@ -113,11 +113,11 @@ uint32_t Tile::getDownItemCount() const { return 0; } -std::string Tile::getDescription(int32_t) const { +std::string Tile::getDescription(int32_t) { return "You dont know why, but you cant see anything!"; } -Teleport* Tile::getTeleportItem() const { +std::shared_ptr Tile::getTeleportItem() const { if (!hasFlag(TILESTATE_TELEPORT)) { return nullptr; } @@ -132,7 +132,7 @@ Teleport* Tile::getTeleportItem() const { return nullptr; } -MagicField* Tile::getFieldItem() const { +std::shared_ptr Tile::getFieldItem() const { if (!hasFlag(TILESTATE_MAGICFIELD)) { return nullptr; } @@ -151,7 +151,7 @@ MagicField* Tile::getFieldItem() const { return nullptr; } -TrashHolder* Tile::getTrashHolder() const { +std::shared_ptr Tile::getTrashHolder() const { if (!hasFlag(TILESTATE_TRASHHOLDER)) { return nullptr; } @@ -170,7 +170,7 @@ TrashHolder* Tile::getTrashHolder() const { return nullptr; } -Mailbox* Tile::getMailbox() const { +std::shared_ptr Tile::getMailbox() const { if (!hasFlag(TILESTATE_MAILBOX)) { return nullptr; } @@ -189,7 +189,7 @@ Mailbox* Tile::getMailbox() const { return nullptr; } -BedItem* Tile::getBedItem() const { +std::shared_ptr Tile::getBedItem() const { if (!hasFlag(TILESTATE_BED)) { return nullptr; } @@ -208,7 +208,7 @@ BedItem* Tile::getBedItem() const { return nullptr; } -Creature* Tile::getTopCreature() const { +std::shared_ptr Tile::getTopCreature() const { if (const CreatureVector* creatures = getCreatures()) { if (!creatures->empty()) { return *creatures->begin(); @@ -217,7 +217,7 @@ Creature* Tile::getTopCreature() const { return nullptr; } -const Creature* Tile::getBottomCreature() const { +std::shared_ptr Tile::getBottomCreature() const { if (const CreatureVector* creatures = getCreatures()) { if (!creatures->empty()) { return *creatures->rbegin(); @@ -226,23 +226,23 @@ const Creature* Tile::getBottomCreature() const { return nullptr; } -Creature* Tile::getTopVisibleCreature(const Creature* creature) const { +std::shared_ptr Tile::getTopVisibleCreature(std::shared_ptr creature) const { if (const CreatureVector* creatures = getCreatures()) { if (creature) { - const Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player && player->isAccessPlayer()) { return getTopCreature(); } - for (Creature* tileCreature : *creatures) { + for (auto &tileCreature : *creatures) { if (creature->canSeeCreature(tileCreature)) { return tileCreature; } } } else { - for (Creature* tileCreature : *creatures) { + for (auto &tileCreature : *creatures) { if (!tileCreature->isInvisible()) { - const Player* player = tileCreature->getPlayer(); + std::shared_ptr player = tileCreature->getPlayer(); if (!player || !player->isInGhostMode()) { return tileCreature; } @@ -253,10 +253,10 @@ Creature* Tile::getTopVisibleCreature(const Creature* creature) const { return nullptr; } -const Creature* Tile::getBottomVisibleCreature(const Creature* creature) const { +std::shared_ptr Tile::getBottomVisibleCreature(std::shared_ptr creature) const { if (const CreatureVector* creatures = getCreatures()) { if (creature) { - const Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player && player->isAccessPlayer()) { return getBottomCreature(); } @@ -269,7 +269,7 @@ const Creature* Tile::getBottomVisibleCreature(const Creature* creature) const { } else { for (auto it = creatures->rbegin(), end = creatures->rend(); it != end; ++it) { if (!(*it)->isInvisible()) { - const Player* player = (*it)->getPlayer(); + std::shared_ptr player = (*it)->getPlayer(); if (!player || !player->isInGhostMode()) { return *it; } @@ -280,21 +280,21 @@ const Creature* Tile::getBottomVisibleCreature(const Creature* creature) const { return nullptr; } -Item* Tile::getTopDownItem() const { +std::shared_ptr Tile::getTopDownItem() const { if (const TileItemVector* items = getItemList()) { return items->getTopDownItem(); } return nullptr; } -Item* Tile::getTopTopItem() const { +std::shared_ptr Tile::getTopTopItem() const { if (const TileItemVector* items = getItemList()) { return items->getTopTopItem(); } return nullptr; } -Item* Tile::getItemByTopOrder(int32_t topOrder) { +std::shared_ptr Tile::getItemByTopOrder(int32_t topOrder) { // topOrder: // 1: borders // 2: ladders, signs, splashes @@ -310,8 +310,8 @@ Item* Tile::getItemByTopOrder(int32_t topOrder) { return nullptr; } -Thing* Tile::getTopVisibleThing(const Creature* creature) { - Thing* thing = getTopVisibleCreature(creature); +std::shared_ptr Tile::getTopVisibleThing(std::shared_ptr creature) { + std::shared_ptr thing = getTopVisibleCreature(creature); if (thing) { return thing; } @@ -336,12 +336,15 @@ Thing* Tile::getTopVisibleThing(const Creature* creature) { return ground; } -void Tile::onAddTileItem(Item* item) { +void Tile::onAddTileItem(std::shared_ptr item) { if ((item->hasProperty(CONST_PROP_MOVEABLE) || item->getContainer()) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVEABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) { - auto it = g_game().browseFields.find(this); + auto it = g_game().browseFields.find(static_self_cast()); if (it != g_game().browseFields.end()) { - it->second->addItemBack(item); - item->setParent(this); + auto lockedCylinder = it->second.lock(); + if (lockedCylinder) { + lockedCylinder->addItemBack(item); + item->setParent(getTile()); + } } } @@ -353,21 +356,21 @@ void Tile::onAddTileItem(Item* item) { g_game().map.getSpectators(spectators, cylinderMapPos, true); // send to client - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { - tmpPlayer->sendAddTileItem(this, cylinderMapPos, item); + for (std::shared_ptr spectator : spectators) { + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { + tmpPlayer->sendAddTileItem(static_self_cast(), cylinderMapPos, item); } } // event methods - for (Creature* spectator : spectators) { - spectator->onAddTileItem(this, cylinderMapPos); + for (std::shared_ptr spectator : spectators) { + spectator->onAddTileItem(static_self_cast(), cylinderMapPos); } if ((!hasFlag(TILESTATE_PROTECTIONZONE) || g_configManager().getBoolean(CLEAN_PROTECTION_ZONES)) && item->isCleanable()) { if (!this->getHouse()) { - g_game().addTileToClean(this); + g_game().addTileToClean(static_self_cast()); } } @@ -407,22 +410,28 @@ void Tile::onAddTileItem(Item* item) { } } -void Tile::onUpdateTileItem(Item* oldItem, const ItemType &oldType, Item* newItem, const ItemType &newType) { +void Tile::onUpdateTileItem(std::shared_ptr oldItem, const ItemType &oldType, std::shared_ptr newItem, const ItemType &newType) { if ((newItem->hasProperty(CONST_PROP_MOVEABLE) || newItem->getContainer()) || (newItem->isWrapable() && newItem->hasProperty(CONST_PROP_MOVEABLE) && !oldItem->hasProperty(CONST_PROP_BLOCKPATH))) { - auto it = g_game().browseFields.find(this); + auto it = g_game().browseFields.find(getTile()); if (it != g_game().browseFields.end()) { - int32_t index = it->second->getThingIndex(oldItem); - if (index != -1) { - it->second->replaceThing(index, newItem); - newItem->setParent(this); + auto lockedCylinder = it->second.lock(); + if (lockedCylinder) { + int32_t index = lockedCylinder->getThingIndex(oldItem); + if (index != -1) { + lockedCylinder->replaceThing(index, newItem); + newItem->setParent(static_self_cast()); + } } } } else if ((oldItem->hasProperty(CONST_PROP_MOVEABLE) || oldItem->getContainer()) || (oldItem->isWrapable() && !oldItem->hasProperty(CONST_PROP_MOVEABLE) && !oldItem->hasProperty(CONST_PROP_BLOCKPATH))) { - auto it = g_game().browseFields.find(this); + auto it = g_game().browseFields.find(getTile()); if (it != g_game().browseFields.end()) { - Cylinder* oldParent = oldItem->getParent(); - it->second->removeThing(oldItem, oldItem->getItemCount()); - oldItem->setParent(oldParent); + auto lockedCylinder = it->second.lock(); + if (lockedCylinder) { + std::shared_ptr oldParent = oldItem->getParent(); + lockedCylinder->removeThing(oldItem, oldItem->getItemCount()); + oldItem->setParent(oldParent); + } } } @@ -432,23 +441,26 @@ void Tile::onUpdateTileItem(Item* oldItem, const ItemType &oldType, Item* newIte g_game().map.getSpectators(spectators, cylinderMapPos, true); // send to client - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { - tmpPlayer->sendUpdateTileItem(this, cylinderMapPos, newItem); + for (std::shared_ptr spectator : spectators) { + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { + tmpPlayer->sendUpdateTileItem(static_self_cast(), cylinderMapPos, newItem); } } // event methods - for (Creature* spectator : spectators) { - spectator->onUpdateTileItem(this, cylinderMapPos, oldItem, oldType, newItem, newType); + for (std::shared_ptr spectator : spectators) { + spectator->onUpdateTileItem(static_self_cast(), cylinderMapPos, oldItem, oldType, newItem, newType); } } -void Tile::onRemoveTileItem(const SpectatorHashSet &spectators, const std::vector &oldStackPosVector, Item* item) { +void Tile::onRemoveTileItem(const SpectatorHashSet &spectators, const std::vector &oldStackPosVector, std::shared_ptr item) { if ((item->hasProperty(CONST_PROP_MOVEABLE) || item->getContainer()) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVEABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) { - auto it = g_game().browseFields.find(this); + auto it = g_game().browseFields.find(getTile()); if (it != g_game().browseFields.end()) { - it->second->removeThing(item, item->getItemCount()); + auto lockedCylinder = it->second.lock(); + if (lockedCylinder) { + lockedCylinder->removeThing(item, item->getItemCount()); + } } } for (const auto zone : getZones()) { @@ -462,21 +474,21 @@ void Tile::onRemoveTileItem(const SpectatorHashSet &spectators, const std::vecto // send to client size_t i = 0; - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (std::shared_ptr spectator : spectators) { + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendRemoveTileThing(cylinderMapPos, oldStackPosVector[i++]); } } // event methods - for (Creature* spectator : spectators) { - spectator->onRemoveTileItem(this, cylinderMapPos, iType, item); + for (std::shared_ptr spectator : spectators) { + spectator->onRemoveTileItem(static_self_cast(), cylinderMapPos, iType, item); } if (!hasFlag(TILESTATE_PROTECTIONZONE) || g_configManager().getBoolean(CLEAN_PROTECTION_ZONES)) { auto items = getItemList(); if (!items || items->empty()) { - g_game().removeTileToClean(this); + g_game().removeTileToClean(static_self_cast()); return; } @@ -489,7 +501,7 @@ void Tile::onRemoveTileItem(const SpectatorHashSet &spectators, const std::vecto } if (!ret) { - g_game().removeTileToClean(this); + g_game().removeTileToClean(static_self_cast()); } } @@ -528,17 +540,17 @@ void Tile::onUpdateTile(const SpectatorHashSet &spectators) { const Position &cylinderMapPos = getPosition(); // send to clients - for (Creature* spectator : spectators) { - spectator->getPlayer()->sendUpdateTile(this, cylinderMapPos); + for (std::shared_ptr spectator : spectators) { + spectator->getPlayer()->sendUpdateTile(getTile(), cylinderMapPos); } } -ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileFlags, Creature*) const { +ReturnValue Tile::queryAdd(int32_t, const std::shared_ptr &thing, uint32_t, uint32_t tileFlags, std::shared_ptr) { if (hasBitSet(FLAG_NOLIMIT, tileFlags)) { return RETURNVALUE_NOERROR; } - if (const Creature* creature = thing.getCreature()) { + if (auto creature = thing->getCreature()) { if (creature->getNpc()) { ReturnValue returnValue = checkNpcCanWalkIntoTile(); @@ -555,7 +567,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF return RETURNVALUE_NOTPOSSIBLE; } - if (const Monster* monster = creature->getMonster()) { + if (std::shared_ptr monster = creature->getMonster()) { if (hasFlag(TILESTATE_PROTECTIONZONE | TILESTATE_FLOORCHANGE | TILESTATE_TELEPORT) && (!monster->isFamiliar() || (monster->isFamiliar() && monster->getMaster() && monster->getMaster()->getAttackedCreature()))) { return RETURNVALUE_NOTPOSSIBLE; } @@ -569,19 +581,19 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF const CreatureVector* creatures = getCreatures(); if (monster->canPushCreatures() && !monster->isSummon()) { if (creatures) { - for (Creature* tileCreature : *creatures) { + for (auto &tileCreature : *creatures) { if (tileCreature->getPlayer() && tileCreature->getPlayer()->isInGhostMode()) { continue; } - const Monster* creatureMonster = tileCreature->getMonster(); + std::shared_ptr creatureMonster = tileCreature->getMonster(); if (!creatureMonster || !tileCreature->isPushable() || (creatureMonster->isSummon() && creatureMonster->getMaster()->getPlayer())) { return RETURNVALUE_NOTPOSSIBLE; } } } } else if (creatures && !creatures->empty()) { - for (const Creature* tileCreature : *creatures) { + for (auto &tileCreature : *creatures) { if (!tileCreature->isInGhostMode()) { return RETURNVALUE_NOTENOUGHROOM; } @@ -624,9 +636,9 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF } const CreatureVector* creatures = getCreatures(); - if (const Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { if (creatures && !creatures->empty() && !hasBitSet(FLAG_IGNOREBLOCKCREATURE, tileFlags) && !player->isAccessPlayer()) { - for (const Creature* tileCreature : *creatures) { + for (auto &tileCreature : *creatures) { if (!player->canWalkthrough(tileCreature)) { return RETURNVALUE_NOTPOSSIBLE; } @@ -642,7 +654,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF return RETURNVALUE_NOTPOSSIBLE; } - const Tile* playerTile = player->getTile(); + const auto playerTile = player->getTile(); if (playerTile && player->isPzLocked()) { if (!playerTile->hasFlag(TILESTATE_PVPZONE)) { // player is trying to enter a pvp zone while being pz-locked @@ -660,7 +672,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF } } } else if (creatures && !creatures->empty() && !hasBitSet(FLAG_IGNOREBLOCKCREATURE, tileFlags)) { - for (const Creature* tileCreature : *creatures) { + for (auto &tileCreature : *creatures) { if (!tileCreature->isInGhostMode()) { return RETURNVALUE_NOTENOUGHROOM; } @@ -673,7 +685,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF // NO PVP magic wall or wild growth field check if (creature && creature->getPlayer()) { if (const auto fieldList = getItemList()) { - for (Item* findfield : *fieldList) { + for (auto &findfield : *fieldList) { if (findfield && (findfield->getID() == ITEM_WILDGROWTH_SAFE || findfield->getID() == ITEM_MAGICWALL_SAFE)) { if (!creature->isInGhostMode()) { g_game().internalRemoveItem(findfield, 1); @@ -695,7 +707,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF } if (const auto items = getItemList()) { - for (const Item* item : *items) { + for (auto &item : *items) { const ItemType &iiType = Item::items[item->getID()]; if (iiType.blockSolid && (!iiType.moveable || item->hasAttribute(ItemAttribute_t::UNIQUEID))) { return RETURNVALUE_NOTPOSSIBLE; @@ -703,7 +715,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF } } } - } else if (const Item* item = thing.getItem()) { + } else if (auto item = thing->getItem()) { const TileItemVector* items = getItemList(); if (items && items->size() >= 0x3E8) { return RETURNVALUE_NOTPOSSIBLE; @@ -716,7 +728,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF const CreatureVector* creatures = getCreatures(); if (creatures && !creatures->empty() && item->isBlocking() && !hasBitSet(FLAG_IGNOREBLOCKCREATURE, tileFlags)) { - for (const Creature* tileCreature : *creatures) { + for (auto &tileCreature : *creatures) { if (!tileCreature->isInGhostMode()) { return RETURNVALUE_NOTENOUGHROOM; } @@ -725,7 +737,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF if (itemIsHangable && hasFlag(TILESTATE_SUPPORTS_HANGABLE)) { if (items) { - for (const Item* tileItem : *items) { + for (auto &tileItem : *items) { if (tileItem->isHangable()) { return RETURNVALUE_NEEDEXCHANGE; } @@ -735,7 +747,7 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF if (ground) { const ItemType &iiType = Item::items[ground->getID()]; if (iiType.blockSolid) { - if (!iiType.pickupable || item->isMagicField() || item->isBlocking()) { + if (!iiType.pickupable && iiType.type != ITEM_TYPE_TRASHHOLDER || item->isMagicField() || item->isBlocking()) { if (!item->isPickupable() && !item->isCarpet()) { return RETURNVALUE_NOTENOUGHROOM; } @@ -748,9 +760,9 @@ ReturnValue Tile::queryAdd(int32_t, const Thing &thing, uint32_t, uint32_t tileF } if (items) { - for (const Item* tileItem : *items) { + for (auto &tileItem : *items) { const ItemType &iiType = Item::items[tileItem->getID()]; - if (!iiType.blockSolid) { + if (!iiType.blockSolid || iiType.type == ITEM_TYPE_TRASHHOLDER) { continue; } @@ -784,18 +796,18 @@ bool Tile::hasHarmfulField() const { return hasFlag(TILESTATE_MAGICFIELD) && getFieldItem() && !getFieldItem()->isBlocking() && getFieldItem()->getDamage() > 0; } -ReturnValue Tile::queryMaxCount(int32_t, const Thing &, uint32_t count, uint32_t &maxQueryCount, uint32_t) const { +ReturnValue Tile::queryMaxCount(int32_t, const std::shared_ptr &, uint32_t count, uint32_t &maxQueryCount, uint32_t) { maxQueryCount = std::max(1, count); return RETURNVALUE_NOERROR; } -ReturnValue Tile::queryRemove(const Thing &thing, uint32_t count, uint32_t tileFlags, Creature* /*= nullptr */) const { - int32_t index = getThingIndex(&thing); +ReturnValue Tile::queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t tileFlags, std::shared_ptr /*= nullptr */) { + int32_t index = getThingIndex(thing); if (index == -1) { return RETURNVALUE_NOTPOSSIBLE; } - const Item* item = thing.getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return RETURNVALUE_NOTPOSSIBLE; } @@ -811,8 +823,8 @@ ReturnValue Tile::queryRemove(const Thing &thing, uint32_t count, uint32_t tileF return RETURNVALUE_NOERROR; } -Tile* Tile::queryDestination(int32_t &, const Thing &, Item** destItem, uint32_t &tileFlags) { - Tile* destTile = nullptr; +std::shared_ptr Tile::queryDestination(int32_t &, const std::shared_ptr &, std::shared_ptr* destItem, uint32_t &tileFlags) { + std::shared_ptr destTile = nullptr; *destItem = nullptr; if (hasFlag(TILESTATE_FLOORCHANGE_DOWN)) { @@ -820,17 +832,17 @@ Tile* Tile::queryDestination(int32_t &, const Thing &, Item** destItem, uint32_t uint16_t dy = tilePos.y; uint8_t dz = tilePos.z + 1; - const Tile* southDownTile = g_game().map.getTile(dx, dy - 1, dz); + std::shared_ptr southDownTile = g_game().map.getTile(dx, dy - 1, dz); if (southDownTile && southDownTile->hasFlag(TILESTATE_FLOORCHANGE_SOUTH_ALT)) { dy -= 2; destTile = g_game().map.getTile(dx, dy, dz); } else { - const Tile* eastDownTile = g_game().map.getTile(dx - 1, dy, dz); + std::shared_ptr eastDownTile = g_game().map.getTile(dx - 1, dy, dz); if (eastDownTile && eastDownTile->hasFlag(TILESTATE_FLOORCHANGE_EAST_ALT)) { dx -= 2; destTile = g_game().map.getTile(dx, dy, dz); } else { - const Tile* downTile = g_game().map.getTile(dx, dy, dz); + std::shared_ptr downTile = g_game().map.getTile(dx, dy, dz); if (downTile) { if (downTile->hasFlag(TILESTATE_FLOORCHANGE_NORTH)) { ++dy; @@ -893,13 +905,13 @@ Tile* Tile::queryDestination(int32_t &, const Thing &, Item** destItem, uint32_t } if (destTile == nullptr) { - destTile = this; + destTile = static_self_cast(); } else { tileFlags |= FLAG_NOLIMIT; // Will ignore that there is blocking items/creatures } if (destTile) { - Thing* destThing = destTile->getTopDownItem(); + std::shared_ptr destThing = destTile->getTopDownItem(); if (destThing) { *destItem = destThing->getItem(); } @@ -907,8 +919,8 @@ Tile* Tile::queryDestination(int32_t &, const Thing &, Item** destItem, uint32_t return destTile; } -std::vector Tile::getSurroundingTiles() const { - const auto &position = getPosition(); +std::vector> Tile::getSurroundingTiles() { + const auto position = getPosition(); return { g_game().map.getTile(position.x - 1, position.y, position.z), g_game().map.getTile(position.x + 1, position.y, position.z), @@ -921,23 +933,23 @@ std::vector Tile::getSurroundingTiles() const { }; } -void Tile::addThing(Thing* thing) { +void Tile::addThing(std::shared_ptr thing) { addThing(0, thing); } -void Tile::addThing(int32_t, Thing* thing) { +void Tile::addThing(int32_t, std::shared_ptr thing) { if (!thing) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Creature* creature = thing->getCreature(); + std::shared_ptr creature = thing->getCreature(); if (creature) { g_game().map.clearSpectatorCache(); - creature->setParent(this); + creature->setParent(static_self_cast()); CreatureVector* creatures = makeCreatures(); creatures->insert(creatures->begin(), creature); } else { - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -947,7 +959,7 @@ void Tile::addThing(int32_t, Thing* thing) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - item->setParent(this); + item->setParent(static_self_cast()); const ItemType &itemType = Item::items[item->getID()]; if (itemType.isGroundTile()) { @@ -957,9 +969,8 @@ void Tile::addThing(int32_t, Thing* thing) { } else { const ItemType &oldType = Item::items[ground->getID()]; - Item* oldGround = ground; - ground->setParent(nullptr); - g_game().ReleaseItem(ground); + std::shared_ptr oldGround = ground; + ground->resetParent(); ground = item; resetTileFlags(oldGround); setTileFlags(item); @@ -970,14 +981,13 @@ void Tile::addThing(int32_t, Thing* thing) { if (itemType.isSplash() && items) { // remove old splash if exists for (ItemVector::const_iterator it = items->getBeginTopItem(), end = items->getEndTopItem(); it != end; ++it) { - Item* oldSplash = *it; + std::shared_ptr oldSplash = *it; if (!Item::items[oldSplash->getID()].isSplash()) { continue; } removeThing(oldSplash, 1); - oldSplash->setParent(nullptr); - g_game().ReleaseItem(oldSplash); + oldSplash->resetParent(); postRemoveNotification(oldSplash, nullptr, 0); break; } @@ -1008,19 +1018,17 @@ void Tile::addThing(int32_t, Thing* thing) { // remove old field item if exists if (items) { for (ItemVector::const_iterator it = items->getBeginDownItem(), end = items->getEndDownItem(); it != end; ++it) { - MagicField* oldField = (*it)->getMagicField(); + std::shared_ptr oldField = (*it)->getMagicField(); if (oldField) { if (oldField->isReplaceable()) { removeThing(oldField, 1); - oldField->setParent(nullptr); - g_game().ReleaseItem(oldField); + oldField->resetParent(); postRemoveNotification(oldField, nullptr, 0); break; } else { // This magic field cannot be replaced. - item->setParent(nullptr); - g_game().ReleaseItem(item); + item->resetParent(); return; } } @@ -1036,13 +1044,13 @@ void Tile::addThing(int32_t, Thing* thing) { } } -void Tile::updateThing(Thing* thing, uint16_t itemId, uint32_t count) { +void Tile::updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) { int32_t index = getThingIndex(thing); if (index == -1) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return /*RETURNVALUE_NOTPOSSIBLE*/; } @@ -1056,15 +1064,15 @@ void Tile::updateThing(Thing* thing, uint16_t itemId, uint32_t count) { onUpdateTileItem(item, oldType, item, newType); } -void Tile::replaceThing(uint32_t index, Thing* thing) { +void Tile::replaceThing(uint32_t index, std::shared_ptr thing) { int32_t pos = index; - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return /*RETURNVALUE_NOTPOSSIBLE*/; } - Item* oldItem = nullptr; + std::shared_ptr oldItem = nullptr; bool isInserted = false; if (ground) { @@ -1114,7 +1122,7 @@ void Tile::replaceThing(uint32_t index, Thing* thing) { } if (isInserted) { - item->setParent(this); + item->setParent(static_self_cast()); resetTileFlags(oldItem); setTileFlags(item); @@ -1122,13 +1130,13 @@ void Tile::replaceThing(uint32_t index, Thing* thing) { const ItemType &newType = Item::items[item->getID()]; onUpdateTileItem(oldItem, oldType, item, newType); - oldItem->setParent(nullptr); + oldItem->resetParent(); return /*RETURNVALUE_NOERROR*/; } } -void Tile::removeThing(Thing* thing, uint32_t count) { - Creature* creature = thing->getCreature(); +void Tile::removeThing(std::shared_ptr thing, uint32_t count) { + std::shared_ptr creature = thing->getCreature(); if (creature) { CreatureVector* creatures = getCreatures(); if (creatures) { @@ -1141,7 +1149,7 @@ void Tile::removeThing(Thing* thing, uint32_t count) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { return; } @@ -1152,7 +1160,7 @@ void Tile::removeThing(Thing* thing, uint32_t count) { } if (item == ground) { - ground->setParent(nullptr); + ground->resetParent(); ground = nullptr; SpectatorHashSet spectators; @@ -1176,13 +1184,13 @@ void Tile::removeThing(Thing* thing, uint32_t count) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, getPosition(), true); - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (std::shared_ptr spectator : spectators) { + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { oldStackPosVector.push_back(getStackposOfItem(tmpPlayer, item)); } } - item->setParent(nullptr); + item->resetParent(); items->erase(it); onRemoveTileItem(spectators, oldStackPosVector, item); } else { @@ -1201,13 +1209,13 @@ void Tile::removeThing(Thing* thing, uint32_t count) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, getPosition(), true); - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (std::shared_ptr spectator : spectators) { + if (std::shared_ptr tmpPlayer = spectator->getPlayer()) { oldStackPosVector.push_back(getStackposOfItem(tmpPlayer, item)); } } - item->setParent(nullptr); + item->resetParent(); items->erase(it); items->decreaseDownItemCount(); onRemoveTileItem(spectators, oldStackPosVector, item); @@ -1215,12 +1223,12 @@ void Tile::removeThing(Thing* thing, uint32_t count) { } } -void Tile::removeCreature(Creature* creature) { +void Tile::removeCreature(std::shared_ptr creature) { g_game().map.getQTNode(tilePos.x, tilePos.y)->removeCreature(creature); removeThing(creature, 0); } -int32_t Tile::getThingIndex(const Thing* thing) const { +int32_t Tile::getThingIndex(std::shared_ptr thing) const { int32_t n = -1; if (ground) { if (ground == thing) { @@ -1231,7 +1239,7 @@ int32_t Tile::getThingIndex(const Thing* thing) const { const TileItemVector* items = getItemList(); if (items) { - const Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item && item->isAlwaysOnTop()) { for (auto it = items->getBeginTopItem(), end = items->getEndTopItem(); it != end; ++it) { ++n; @@ -1246,7 +1254,7 @@ int32_t Tile::getThingIndex(const Thing* thing) const { if (const CreatureVector* creatures = getCreatures()) { if (thing->getCreature()) { - for (Creature* creature : *creatures) { + for (auto &creature : *creatures) { ++n; if (creature == thing) { return n; @@ -1258,7 +1266,7 @@ int32_t Tile::getThingIndex(const Thing* thing) const { } if (items) { - const Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item && !item->isAlwaysOnTop()) { for (auto it = items->getBeginDownItem(), end = items->getEndDownItem(); it != end; ++it) { ++n; @@ -1271,7 +1279,7 @@ int32_t Tile::getThingIndex(const Thing* thing) const { return -1; } -int32_t Tile::getClientIndexOfCreature(const Player* player, const Creature* creature) const { +int32_t Tile::getClientIndexOfCreature(std::shared_ptr player, std::shared_ptr creature) const { int32_t n; if (ground) { n = 1; @@ -1296,7 +1304,7 @@ int32_t Tile::getClientIndexOfCreature(const Player* player, const Creature* cre return -1; } -int32_t Tile::getStackposOfCreature(const Player* player, const Creature* creature) const { +int32_t Tile::getStackposOfCreature(std::shared_ptr player, std::shared_ptr creature) const { int32_t n; if (ground) { n = 1; @@ -1326,7 +1334,7 @@ int32_t Tile::getStackposOfCreature(const Player* player, const Creature* creatu return -1; } -int32_t Tile::getStackposOfItem(const Player* player, const Item* item) const { +int32_t Tile::getStackposOfItem(std::shared_ptr player, std::shared_ptr item) const { int32_t n = 0; if (ground) { if (ground == item) { @@ -1354,7 +1362,7 @@ int32_t Tile::getStackposOfItem(const Player* player, const Item* item) const { } if (const CreatureVector* creatures = getCreatures()) { - for (const Creature* creature : *creatures) { + for (auto &creature : *creatures) { if (player->canSeeCreature(creature)) { if (++n >= 10) { return -1; @@ -1391,7 +1399,7 @@ uint32_t Tile::getItemTypeCount(uint16_t itemId, int32_t subType /*= -1*/) const const TileItemVector* items = getItemList(); if (items) { - for (const Item* item : *items) { + for (auto &item : *items) { if (item->getID() == itemId) { count += Item::countByType(item, subType); } @@ -1400,7 +1408,7 @@ uint32_t Tile::getItemTypeCount(uint16_t itemId, int32_t subType /*= -1*/) const return count; } -Thing* Tile::getThing(size_t index) const { +std::shared_ptr Tile::getThing(size_t index) const { if (ground) { if (index == 0) { return ground; @@ -1431,39 +1439,35 @@ Thing* Tile::getThing(size_t index) const { return nullptr; } -void Tile::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link /*= LINK_OWNER*/) { +void Tile::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link /*= LINK_OWNER*/) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, getPosition(), true, true); - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { spectator->getPlayer()->postAddNotification(thing, oldParent, index, LINK_NEAR); } // add a reference to this item, it may be deleted after being added (mailbox for example) - Creature* creature = thing->getCreature(); - Item* item; + std::shared_ptr creature = thing->getCreature(); + std::shared_ptr item; if (creature) { - creature->incrementReferenceCounter(); item = nullptr; } else { item = thing->getItem(); - if (item) { - item->incrementReferenceCounter(); - } } if (link == LINK_OWNER) { if (hasFlag(TILESTATE_TELEPORT)) { - Teleport* teleport = getTeleportItem(); + std::shared_ptr teleport = getTeleportItem(); if (teleport) { teleport->addThing(thing); } } else if (hasFlag(TILESTATE_TRASHHOLDER)) { - TrashHolder* trashholder = getTrashHolder(); + std::shared_ptr trashholder = getTrashHolder(); if (trashholder) { trashholder->addThing(thing); } } else if (hasFlag(TILESTATE_MAILBOX)) { - Mailbox* mailbox = getMailbox(); + std::shared_ptr mailbox = getMailbox(); if (mailbox) { mailbox->addThing(thing); } @@ -1471,21 +1475,14 @@ 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, static_self_cast(), MOVE_EVENT_STEP_IN); } else if (item) { - g_moveEvents().onItemMove(*item, *this, true); + g_moveEvents().onItemMove(item, static_self_cast(), true); } } - - // release the reference to this item onces we are finished - if (creature) { - g_game().ReleaseCreature(creature); - } else if (item) { - g_game().ReleaseItem(item); - } } -void Tile::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { +void Tile::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, getPosition(), true, true); @@ -1493,35 +1490,35 @@ void Tile::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32 onUpdateTile(spectators); } - for (Creature* spectator : spectators) { + for (auto spectator : spectators) { spectator->getPlayer()->postRemoveNotification(thing, newParent, index, LINK_NEAR); } // calling movement scripts - Creature* creature = thing->getCreature(); + std::shared_ptr creature = thing->getCreature(); if (creature) { - g_moveEvents().onCreatureMove(*creature, *this, MOVE_EVENT_STEP_OUT); + g_moveEvents().onCreatureMove(creature, static_self_cast(), MOVE_EVENT_STEP_OUT); } else { - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item) { - g_moveEvents().onItemMove(*item, *this, false); + g_moveEvents().onItemMove(item, static_self_cast(), false); } } } -void Tile::internalAddThing(Thing* thing) { +void Tile::internalAddThing(std::shared_ptr thing) { internalAddThing(0, thing); if (!thing || !thing->getParent()) { return; } if (auto house = thing->getTile()->getHouse()) { - if (Item* item = thing->getItem()) { - if (item->getParent() != this) { + if (std::shared_ptr item = thing->getItem()) { + if (item->getParent().get() != this) { return; } - Door* door = item->getDoor(); + std::shared_ptr door = item->getDoor(); if (door && door->getDoorId() != 0) { house->addDoor(door); } @@ -1529,7 +1526,7 @@ void Tile::internalAddThing(Thing* thing) { } } -void Tile::internalAddThing(uint32_t, Thing* thing) { +void Tile::internalAddThing(uint32_t, std::shared_ptr thing) { if (!thing) { return; } @@ -1537,15 +1534,15 @@ void Tile::internalAddThing(uint32_t, Thing* thing) { zone->thingAdded(thing); } - thing->setParent(this); + thing->setParent(static_self_cast()); - Creature* creature = thing->getCreature(); + std::shared_ptr creature = thing->getCreature(); if (creature) { g_game().map.clearSpectatorCache(); CreatureVector* creatures = makeCreatures(); creatures->insert(creatures->begin(), creature); } else { - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item == nullptr) { return; } @@ -1586,12 +1583,12 @@ void Tile::internalAddThing(uint32_t, Thing* thing) { } } -void Tile::updateTileFlags(const Item* item) { +void Tile::updateTileFlags(std::shared_ptr item) { resetTileFlags(item); setTileFlags(item); } -void Tile::setTileFlags(const Item* item) { +void Tile::setTileFlags(std::shared_ptr item) { if (!hasFlag(TILESTATE_FLOORCHANGE)) { const ItemType &it = Item::items[item->getID()]; if (it.floorChange != 0) { @@ -1639,7 +1636,7 @@ void Tile::setTileFlags(const Item* item) { setFlag(TILESTATE_BED); } - const Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && container->getDepotLocker()) { setFlag(TILESTATE_DEPOT); } @@ -1649,7 +1646,7 @@ void Tile::setTileFlags(const Item* item) { } } -void Tile::resetTileFlags(const Item* item) { +void Tile::resetTileFlags(std::shared_ptr item) { const ItemType &it = Item::items[item->getID()]; if (it.floorChange != 0) { resetFlag(TILESTATE_FLOORCHANGE); @@ -1699,7 +1696,7 @@ void Tile::resetTileFlags(const Item* item) { resetFlag(TILESTATE_BED); } - const Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && container->getDepotLocker()) { resetFlag(TILESTATE_DEPOT); } @@ -1713,27 +1710,27 @@ bool Tile::isMoveableBlocking() const { return !ground || hasFlag(TILESTATE_BLOCKSOLID); } -Item* Tile::getUseItem(int32_t index) const { +std::shared_ptr Tile::getUseItem(int32_t index) const { const TileItemVector* items = getItemList(); if (!items || items->size() == 0) { return ground; } - if (Thing* thing = getThing(index)) { + if (std::shared_ptr thing = getThing(index)) { return thing->getItem(); } return nullptr; } -Item* Tile::getDoorItem() const { +std::shared_ptr Tile::getDoorItem() const { const TileItemVector* items = getItemList(); if (!items || items->size() == 0) { return ground; } if (items) { - for (Item* item : *items) { + for (auto &item : *items) { const ItemType &it = Item::items[item->getID()]; if (it.isDoor()) { return item; diff --git a/src/items/tile.hpp b/src/items/tile.hpp index 3569675f3..35f5e3623 100644 --- a/src/items/tile.hpp +++ b/src/items/tile.hpp @@ -23,9 +23,9 @@ class BedItem; class House; class Zone; -using CreatureVector = std::vector; -using ItemVector = std::vector; -using SpectatorHashSet = phmap::flat_hash_set; +using CreatureVector = std::vector>; +using ItemVector = std::vector>; +using SpectatorHashSet = phmap::flat_hash_set>; class TileItemVector : private ItemVector { public: @@ -77,13 +77,13 @@ class TileItemVector : private ItemVector { uint32_t getDownItemCount() const { return downItemCount; } - inline Item* getTopTopItem() const { + inline std::shared_ptr getTopTopItem() const { if (getTopItemCount() == 0) { return nullptr; } return *(getEndTopItem() - 1); } - inline Item* getTopDownItem() const { + inline std::shared_ptr getTopDownItem() const { if (downItemCount == 0) { return nullptr; } @@ -100,14 +100,12 @@ class TileItemVector : private ItemVector { uint32_t downItemCount = 0; }; -class Tile : public Cylinder { +class Tile : public Cylinder, public SharedObject { public: - static Tile &nullptr_tile; + static const std::shared_ptr &nullptr_tile; Tile(uint16_t x, uint16_t y, uint8_t z) : tilePos(x, y, z) { } - virtual ~Tile() { - delete ground; - }; + virtual ~Tile() {}; // non-copyable Tile(const Tile &) = delete; @@ -120,32 +118,35 @@ class Tile : public Cylinder { virtual CreatureVector* getCreatures() = 0; virtual const CreatureVector* getCreatures() const = 0; virtual CreatureVector* makeCreatures() = 0; - virtual House* getHouse() { + virtual std::shared_ptr getHouse() { return nullptr; } int32_t getThrowRange() const override final { return 0; } - bool isPushable() const override final { + bool isPushable() override final { return false; } - MagicField* getFieldItem() const; - Teleport* getTeleportItem() const; - TrashHolder* getTrashHolder() const; - Mailbox* getMailbox() const; - BedItem* getBedItem() const; + std::shared_ptr getTile() override final { + return static_self_cast(); + } + std::shared_ptr getFieldItem() const; + std::shared_ptr getTeleportItem() const; + std::shared_ptr getTrashHolder() const; + std::shared_ptr getMailbox() const; + std::shared_ptr getBedItem() const; - Creature* getTopCreature() const; - const Creature* getBottomCreature() const; - Creature* getTopVisibleCreature(const Creature* creature) const; - const Creature* getBottomVisibleCreature(const Creature* creature) const; - Item* getTopTopItem() const; - Item* getTopDownItem() const; + std::shared_ptr getTopCreature() const; + std::shared_ptr getBottomCreature() const; + std::shared_ptr getTopVisibleCreature(std::shared_ptr creature) const; + std::shared_ptr getBottomVisibleCreature(std::shared_ptr creature) const; + std::shared_ptr getTopTopItem() const; + std::shared_ptr getTopDownItem() const; bool isMoveableBlocking() const; - Thing* getTopVisibleThing(const Creature* creature); - Item* getItemByTopOrder(int32_t topOrder); + std::shared_ptr getTopVisibleThing(std::shared_ptr creature); + std::shared_ptr getItemByTopOrder(int32_t topOrder); size_t getThingCount() const { size_t thingCount = getCreatureCount() + getItemCount(); @@ -161,7 +162,7 @@ class Tile : public Cylinder { uint32_t getDownItemCount() const; bool hasProperty(ItemProperty prop) const; - bool hasProperty(const Item* exclude, ItemProperty prop) const; + bool hasProperty(std::shared_ptr exclude, ItemProperty prop) const; bool hasFlag(uint32_t flag) const { return hasBitSet(flag, this->flags); @@ -191,74 +192,74 @@ class Tile : public Cylinder { bool hasHeight(uint32_t n) const; - std::string getDescription(int32_t lookDistance) const override final; + std::string getDescription(int32_t lookDistance) override final; - int32_t getClientIndexOfCreature(const Player* player, const Creature* creature) const; - int32_t getStackposOfCreature(const Player* player, const Creature* creature) const; - int32_t getStackposOfItem(const Player* player, const Item* item) const; + int32_t getClientIndexOfCreature(std::shared_ptr player, std::shared_ptr creature) const; + int32_t getStackposOfCreature(std::shared_ptr player, std::shared_ptr creature) const; + int32_t getStackposOfItem(std::shared_ptr player, std::shared_ptr item) const; // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - ReturnValue queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const override final; - ReturnValue queryRemove(const Thing &thing, uint32_t count, uint32_t tileFlags, Creature* actor = nullptr) const override; - Tile* queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + ReturnValue queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) override final; + ReturnValue queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t tileFlags, std::shared_ptr actor = nullptr) override; + std::shared_ptr queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) override; - std::vector getSurroundingTiles() const; + std::vector> getSurroundingTiles(); - void addThing(Thing* thing) override final; - void addThing(int32_t index, Thing* thing) override; + void addThing(std::shared_ptr thing) override final; + void addThing(int32_t index, std::shared_ptr thing) override; - void updateTileFlags(const Item* item); - void updateThing(Thing* thing, uint16_t itemId, uint32_t count) override final; - void replaceThing(uint32_t index, Thing* thing) override final; + void updateTileFlags(std::shared_ptr item); + void updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) override final; + void replaceThing(uint32_t index, std::shared_ptr thing) override final; - void removeThing(Thing* thing, uint32_t count) override final; + void removeThing(std::shared_ptr thing, uint32_t count) override final; - void removeCreature(Creature* creature); + void removeCreature(std::shared_ptr creature); - int32_t getThingIndex(const Thing* thing) const override final; + int32_t getThingIndex(std::shared_ptr 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; - Thing* getThing(size_t index) const override final; + std::shared_ptr getThing(size_t index) const override final; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override final; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override final; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override final; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override final; - void internalAddThing(Thing* thing) override; - void virtual internalAddThing(uint32_t index, Thing* thing) override; + void internalAddThing(std::shared_ptr thing) override; + void virtual internalAddThing(uint32_t index, std::shared_ptr thing) override; - const Position &getPosition() const override final { + const Position &getPosition() override final { return tilePos; } - bool isRemoved() const override final { + bool isRemoved() override final { return false; } - Item* getUseItem(int32_t index) const; - Item* getDoorItem() const; + std::shared_ptr getUseItem(int32_t index) const; + std::shared_ptr getDoorItem() const; - Item* getGround() const { + std::shared_ptr getGround() const { return ground; } - void setGround(Item* item) { + void setGround(std::shared_ptr item) { ground = item; } private: - void onAddTileItem(Item* item); - void onUpdateTileItem(Item* oldItem, const ItemType &oldType, Item* newItem, const ItemType &newType); - void onRemoveTileItem(const SpectatorHashSet &spectators, const std::vector &oldStackPosVector, Item* item); + void onAddTileItem(std::shared_ptr item); + void onUpdateTileItem(std::shared_ptr oldItem, const ItemType &oldType, std::shared_ptr newItem, const ItemType &newType); + void onRemoveTileItem(const SpectatorHashSet &spectators, const std::vector &oldStackPosVector, std::shared_ptr item); void onUpdateTile(const SpectatorHashSet &spectators); - void setTileFlags(const Item* item); - void resetTileFlags(const Item* item); + void setTileFlags(std::shared_ptr item); + void resetTileFlags(std::shared_ptr item); bool hasHarmfulField() const; ReturnValue checkNpcCanWalkIntoTile() const; protected: - Item* ground = nullptr; + std::shared_ptr ground = nullptr; Position tilePos; uint32_t flags = 0; std::shared_ptr zone; @@ -274,11 +275,6 @@ class DynamicTile : public Tile { public: DynamicTile(uint16_t x, uint16_t y, uint8_t z) : Tile(x, y, z) { } - ~DynamicTile() { - for (Item* item : items) { - item->decrementReferenceCounter(); - } - } // non-copyable DynamicTile(const DynamicTile &) = delete; @@ -314,13 +310,6 @@ class StaticTile final : public Tile { public: StaticTile(uint16_t x, uint16_t y, uint8_t z) : Tile(x, y, z) { } - ~StaticTile() { - if (items) { - for (Item* item : *items) { - item->decrementReferenceCounter(); - } - } - } // non-copyable StaticTile(const StaticTile &) = delete; @@ -334,7 +323,7 @@ class StaticTile final : public Tile { } TileItemVector* makeItemList() override { if (!items) { - items.reset(new TileItemVector); + items = std::make_unique(); } return items.get(); } @@ -347,7 +336,7 @@ class StaticTile final : public Tile { } CreatureVector* makeCreatures() override { if (!creatures) { - creatures.reset(new CreatureVector); + creatures = std::make_unique(); } return creatures.get(); } diff --git a/src/items/trashholder.cpp b/src/items/trashholder.cpp index 353efabdc..024bb31fc 100644 --- a/src/items/trashholder.cpp +++ b/src/items/trashholder.cpp @@ -12,44 +12,44 @@ #include "items/trashholder.hpp" #include "game/game.hpp" -ReturnValue TrashHolder::queryAdd(int32_t, const Thing &, uint32_t, uint32_t, Creature*) const { +ReturnValue TrashHolder::queryAdd(int32_t, const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr) { return RETURNVALUE_NOERROR; } -ReturnValue TrashHolder::queryMaxCount(int32_t, const Thing &, uint32_t queryCount, uint32_t &maxQueryCount, uint32_t) const { +ReturnValue TrashHolder::queryMaxCount(int32_t, const std::shared_ptr &, uint32_t queryCount, uint32_t &maxQueryCount, uint32_t) { maxQueryCount = std::max(1, queryCount); return RETURNVALUE_NOERROR; } -ReturnValue TrashHolder::queryRemove(const Thing &, uint32_t, uint32_t, Creature* /*= nullptr*/) const { +ReturnValue TrashHolder::queryRemove(const std::shared_ptr &, uint32_t, uint32_t, std::shared_ptr /*= nullptr*/) { return RETURNVALUE_NOTPOSSIBLE; } -Cylinder* TrashHolder::queryDestination(int32_t &, const Thing &, Item**, uint32_t &) { - return this; +std::shared_ptr TrashHolder::queryDestination(int32_t &, const std::shared_ptr &, std::shared_ptr*, uint32_t &) { + return static_self_cast(); } -void TrashHolder::addThing(Thing* thing) { +void TrashHolder::addThing(std::shared_ptr thing) { return addThing(0, thing); } -void TrashHolder::addThing(int32_t, Thing* thing) { +void TrashHolder::addThing(int32_t, std::shared_ptr thing) { if (!thing) { return; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (!item) { return; } - if (item == this || !item->hasProperty(CONST_PROP_MOVEABLE)) { + if (item.get() == this || !item->hasProperty(CONST_PROP_MOVEABLE)) { return; } const ItemType &it = Item::items[id]; if (item->isHangable() && it.isGroundTile()) { - Tile* tile = dynamic_cast(getParent()); + std::shared_ptr tile = std::dynamic_pointer_cast(getParent()); if (tile && tile->hasFlag(TILESTATE_SUPPORTS_HANGABLE)) { return; } @@ -65,22 +65,22 @@ void TrashHolder::addThing(int32_t, Thing* thing) { } } -void TrashHolder::updateThing(Thing*, uint16_t, uint32_t) { +void TrashHolder::updateThing(std::shared_ptr, uint16_t, uint32_t) { // } -void TrashHolder::replaceThing(uint32_t, Thing*) { +void TrashHolder::replaceThing(uint32_t, std::shared_ptr) { // } -void TrashHolder::removeThing(Thing*, uint32_t) { +void TrashHolder::removeThing(std::shared_ptr, uint32_t) { // } -void TrashHolder::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t) { +void TrashHolder::postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t) { getParent()->postAddNotification(thing, oldParent, index, LINK_PARENT); } -void TrashHolder::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t) { +void TrashHolder::postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t) { getParent()->postRemoveNotification(thing, newParent, index, LINK_PARENT); } diff --git a/src/items/trashholder.hpp b/src/items/trashholder.hpp index cdc465949..5043e897d 100644 --- a/src/items/trashholder.hpp +++ b/src/items/trashholder.hpp @@ -17,27 +17,24 @@ class TrashHolder final : public Item, public Cylinder { explicit TrashHolder(uint16_t itemId) : Item(itemId) { } - TrashHolder* getTrashHolder() override { - return this; - } - const TrashHolder* getTrashHolder() const override { - return this; + std::shared_ptr getTrashHolder() override { + return static_self_cast(); } // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - ReturnValue queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const override; - ReturnValue queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; - Cylinder* queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + ReturnValue queryMaxCount(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) override; + ReturnValue queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; + std::shared_ptr queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) override; - void addThing(Thing* thing) override; - void addThing(int32_t index, Thing* thing) override; + void addThing(std::shared_ptr thing) override; + void addThing(int32_t index, std::shared_ptr thing) override; - void updateThing(Thing* thing, uint16_t itemId, uint32_t count) override; - void replaceThing(uint32_t index, Thing* thing) override; + void updateThing(std::shared_ptr thing, uint16_t itemId, uint32_t count) override; + void replaceThing(uint32_t index, std::shared_ptr thing) override; - void removeThing(Thing* thing, uint32_t count) override; + void removeThing(std::shared_ptr thing, uint32_t count) override; - void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; - void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; + void postRemoveNotification(std::shared_ptr thing, std::shared_ptr newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; }; diff --git a/src/items/weapons/weapons.cpp b/src/items/weapons/weapons.cpp index aae19c09f..995b71518 100644 --- a/src/items/weapons/weapons.cpp +++ b/src/items/weapons/weapons.cpp @@ -17,7 +17,7 @@ Weapons::Weapons() = default; Weapons::~Weapons() = default; -const Weapon* Weapons::getWeapon(const Item* item) const { +const Weapon* Weapons::getWeapon(std::shared_ptr item) const { if (!item) { return nullptr; } @@ -57,7 +57,7 @@ void Weapon::configureWeapon(const ItemType &it) { id = it.id; } -int32_t Weapon::playerWeaponCheck(Player* player, Creature* target, uint8_t shootRange) const { +int32_t Weapon::playerWeaponCheck(std::shared_ptr player, std::shared_ptr target, uint8_t shootRange) const { const Position &playerPos = player->getPosition(); const Position &targetPos = target->getPosition(); if (playerPos.z != targetPos.z) { @@ -107,7 +107,7 @@ int32_t Weapon::playerWeaponCheck(Player* player, Creature* target, uint8_t shoo return 100; } -bool Weapon::useWeapon(Player* player, Item* item, Creature* target) const { +bool Weapon::useWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr target) const { int32_t damageModifier = playerWeaponCheck(player, target, item->getShootRange()); if (damageModifier == 0) { return false; @@ -117,7 +117,7 @@ bool Weapon::useWeapon(Player* player, Item* item, Creature* target) const { return true; } -CombatDamage Weapon::getCombatDamage(CombatDamage combat, Player* player, Item* item, int32_t damageModifier) const { +CombatDamage Weapon::getCombatDamage(CombatDamage combat, std::shared_ptr player, std::shared_ptr item, int32_t damageModifier) const { // Local variables uint32_t level = player->getLevel(); int16_t elementalAttack = getElementDamageValue(); @@ -140,7 +140,7 @@ CombatDamage Weapon::getCombatDamage(CombatDamage combat, Player* player, Item* return combat; } -bool Weapon::useFist(Player* player, Creature* target) { +bool Weapon::useFist(std::shared_ptr player, std::shared_ptr target) { if (!Position::areInRange<1, 1>(player->getPosition(), target->getPosition())) { return false; } @@ -170,7 +170,7 @@ bool Weapon::useFist(Player* player, Creature* target) { return true; } -void Weapon::internalUseWeapon(Player* player, Item* item, Creature* target, int32_t damageModifier, int32_t cleavePercent) const { +void Weapon::internalUseWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr target, int32_t damageModifier, int32_t cleavePercent) const { if (player) { if (params.soundCastEffect == SoundEffect_t::SILENCE) { g_game().sendDoubleSoundEffect(player->getPosition(), player->getHitSoundEffect(), player->getAttackSoundEffect(), player); @@ -225,7 +225,7 @@ void Weapon::internalUseWeapon(Player* player, Item* item, Creature* target, int onUsedWeapon(player, item, target->getTile()); } -void Weapon::internalUseWeapon(Player* player, Item* item, Tile* tile) const { +void Weapon::internalUseWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr tile) const { if (isLoadedCallback()) { LuaVariant var; var.type = VARIANT_TARGETPOSITION; @@ -239,7 +239,7 @@ void Weapon::internalUseWeapon(Player* player, Item* item, Tile* tile) const { onUsedWeapon(player, item, tile); } -void Weapon::onUsedWeapon(Player* player, Item* item, Tile* destTile) const { +void Weapon::onUsedWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr destTile) const { if (!player->hasFlag(PlayerFlags_t::NotGainSkill)) { skills_t skillType; uint32_t skillPoint; @@ -293,7 +293,7 @@ void Weapon::onUsedWeapon(Player* player, Item* item, Tile* destTile) const { } } -uint32_t Weapon::getManaCost(const Player* player) const { +uint32_t Weapon::getManaCost(std::shared_ptr player) const { if (mana != 0) { return mana; } @@ -305,7 +305,7 @@ uint32_t Weapon::getManaCost(const Player* player) const { return (player->getMaxMana() * manaPercent) / 100; } -int32_t Weapon::getHealthCost(const Player* player) const { +int32_t Weapon::getHealthCost(std::shared_ptr player) const { if (health != 0) { return health; } @@ -317,7 +317,7 @@ int32_t Weapon::getHealthCost(const Player* player) const { return (player->getMaxHealth() * healthPercent) / 100; } -bool Weapon::executeUseWeapon(Player* player, const LuaVariant &var) const { +bool Weapon::executeUseWeapon(std::shared_ptr player, const LuaVariant &var) const { // onUseWeapon(player, var) if (!getScriptInterface()->reserveScriptEnv()) { std::string playerName = player ? player->getName() : "Player nullptr"; @@ -340,7 +340,7 @@ bool Weapon::executeUseWeapon(Player* player, const LuaVariant &var) const { return getScriptInterface()->callFunction(2); } -void Weapon::decrementItemCount(Item* item) { +void Weapon::decrementItemCount(std::shared_ptr item) { uint16_t count = item->getItemCount(); if (count > 1) { g_game().transformItem(item, item->getID(), count - 1); @@ -370,7 +370,7 @@ void WeaponMelee::configureWeapon(const ItemType &it) { Weapon::configureWeapon(it); } -bool WeaponMelee::useWeapon(Player* player, Item* item, Creature* target) const { +bool WeaponMelee::useWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr target) const { int32_t damageModifier = playerWeaponCheck(player, target, item->getShootRange()); if (damageModifier == 0) { return false; @@ -402,12 +402,12 @@ bool WeaponMelee::useWeapon(Player* player, Item* item, Creature* target) const secondCleaveTargetPos.y++; } } - Tile* firstTile = g_game().map.getTile(firstCleaveTargetPos.x, firstCleaveTargetPos.y, firstCleaveTargetPos.z); - Tile* secondTile = g_game().map.getTile(secondCleaveTargetPos.x, secondCleaveTargetPos.y, secondCleaveTargetPos.z); + std::shared_ptr firstTile = g_game().map.getTile(firstCleaveTargetPos.x, firstCleaveTargetPos.y, firstCleaveTargetPos.z); + std::shared_ptr secondTile = g_game().map.getTile(secondCleaveTargetPos.x, secondCleaveTargetPos.y, secondCleaveTargetPos.z); if (firstTile) { if (CreatureVector* tileCreatures = firstTile->getCreatures()) { - for (Creature* tileCreature : *tileCreatures) { + for (auto &tileCreature : *tileCreatures) { if (tileCreature->getMonster() || (tileCreature->getPlayer() && !player->hasSecureMode())) { internalUseWeapon(player, item, tileCreature, damageModifier, cleavePercent); } @@ -416,7 +416,7 @@ bool WeaponMelee::useWeapon(Player* player, Item* item, Creature* target) const } if (secondTile) { if (CreatureVector* tileCreatures = secondTile->getCreatures()) { - for (Creature* tileCreature : *tileCreatures) { + for (auto &tileCreature : *tileCreatures) { if (tileCreature->getMonster() || (tileCreature->getPlayer() && !player->hasSecureMode())) { internalUseWeapon(player, item, tileCreature, damageModifier, cleavePercent); } @@ -430,7 +430,7 @@ bool WeaponMelee::useWeapon(Player* player, Item* item, Creature* target) const return true; } -bool WeaponMelee::getSkillType(const Player* player, const Item* item, skills_t &skill, uint32_t &skillpoint) const { +bool WeaponMelee::getSkillType(std::shared_ptr player, std::shared_ptr item, skills_t &skill, uint32_t &skillpoint) const { if (player->getAddAttackSkill() && player->getLastAttackBlockType() != BLOCK_IMMUNITY) { skillpoint = 1; } else { @@ -460,7 +460,7 @@ bool WeaponMelee::getSkillType(const Player* player, const Item* item, skills_t return false; } -int32_t WeaponMelee::getElementDamage(const Player* player, const Creature*, const Item* item) const { +int32_t WeaponMelee::getElementDamage(std::shared_ptr player, std::shared_ptr, std::shared_ptr item) const { if (elementType == COMBAT_NONE) { return 0; } @@ -479,7 +479,7 @@ int16_t WeaponMelee::getElementDamageValue() const { return elementDamage; } -int32_t WeaponMelee::getWeaponDamage(const Player* player, const Creature*, const Item* item, bool maxDamage /*= false*/) const { +int32_t WeaponMelee::getWeaponDamage(std::shared_ptr player, std::shared_ptr, std::shared_ptr item, bool maxDamage /*= false*/) const { using namespace std; int32_t attackSkill = player->getWeaponSkill(item); int32_t attackValue = std::max(0, item->getAttack()); @@ -519,11 +519,11 @@ void WeaponDistance::configureWeapon(const ItemType &it) { Weapon::configureWeapon(it); } -bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) const { +bool WeaponDistance::useWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr target) const { int32_t damageModifier; const ItemType &it = Item::items[id]; if (it.weaponType == WEAPON_AMMO) { - Item* mainWeaponItem = player->getWeapon(true); + std::shared_ptr mainWeaponItem = player->getWeapon(true); const Weapon* mainWeapon = g_weapons().getWeapon(mainWeaponItem); if (mainWeapon) { damageModifier = mainWeapon->playerWeaponCheck(player, target, mainWeaponItem->getShootRange()); @@ -547,7 +547,7 @@ bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) con int32_t damageY = player->getPerfectShotDamage(distanceY); if (it.weaponType == WEAPON_DISTANCE) { - Item* quiver = player->getInventoryItem(CONST_SLOT_RIGHT); + std::shared_ptr quiver = player->getInventoryItem(CONST_SLOT_RIGHT); if (quiver && quiver->getWeaponType()) { if (quiver->getPerfectShotRange() == distanceX) { damageX -= quiver->getPerfectShotDamage(); @@ -660,7 +660,7 @@ bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) con } if (!perfectShot && item->getWeaponType() == WEAPON_AMMO) { - Item* bow = player->getWeapon(true); + std::shared_ptr bow = player->getWeapon(true); if (bow && bow->getHitChance() != 0) { chance += bow->getHitChance(); } @@ -670,7 +670,7 @@ bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) con Weapon::internalUseWeapon(player, item, target, damageModifier); } else { // miss target - Tile* destTile = target->getTile(); + std::shared_ptr destTile = target->getTile(); if (!Position::areInRange<1, 1, 0>(player->getPosition(), target->getPosition())) { static std::vector> destList { @@ -682,7 +682,7 @@ bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) con for (const auto &dir : destList) { // Blocking tiles or tiles without ground ain't valid targets for spears - Tile* tmpTile = g_game().map.getTile(static_cast(destPos.x + dir.first), static_cast(destPos.y + dir.second), destPos.z); + auto tmpTile = g_game().map.getTile(static_cast(destPos.x + dir.first), static_cast(destPos.y + dir.second), destPos.z); if (tmpTile && !tmpTile->hasFlag(TILESTATE_IMMOVABLEBLOCKSOLID) && tmpTile->getGround() != nullptr) { destTile = tmpTile; break; @@ -695,14 +695,14 @@ bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) con return true; } -int32_t WeaponDistance::getElementDamage(const Player* player, const Creature* target, const Item* item) const { +int32_t WeaponDistance::getElementDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item) const { if (elementType == COMBAT_NONE) { return 0; } int32_t attackValue = elementDamage; if (item->getWeaponType() == WEAPON_AMMO) { - Item* weapon = player->getWeapon(true); + std::shared_ptr weapon = player->getWeapon(true); if (weapon) { attackValue += item->getAttack(); attackValue += weapon->getAttack(); @@ -730,12 +730,12 @@ int16_t WeaponDistance::getElementDamageValue() const { return elementDamage; } -int32_t WeaponDistance::getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage /*= false*/) const { +int32_t WeaponDistance::getWeaponDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, bool maxDamage /*= false*/) const { int32_t attackValue = item->getAttack(); bool hasElement = false; if (item->getWeaponType() == WEAPON_AMMO) { - Item* weapon = player->getWeapon(true); + std::shared_ptr weapon = player->getWeapon(true); if (weapon) { const ItemType &it = Item::items[item->getID()]; if (it.abilities && it.abilities->elementDamage != 0) { @@ -772,7 +772,7 @@ int32_t WeaponDistance::getWeaponDamage(const Player* player, const Creature* ta return -normal_random(minValue, (maxValue * static_cast(player->getVocation()->distDamageMultiplier))); } -bool WeaponDistance::getSkillType(const Player* player, const Item*, skills_t &skill, uint32_t &skillpoint) const { +bool WeaponDistance::getSkillType(std::shared_ptr player, std::shared_ptr, skills_t &skill, uint32_t &skillpoint) const { skill = SKILL_DISTANCE; if (player->getAddAttackSkill()) { @@ -805,7 +805,7 @@ void WeaponWand::configureWeapon(const ItemType &it) { Weapon::configureWeapon(it); } -int32_t WeaponWand::getWeaponDamage(const Player*, const Creature*, const Item*, bool maxDamage /*= false*/) const { +int32_t WeaponWand::getWeaponDamage(std::shared_ptr, std::shared_ptr, std::shared_ptr, bool maxDamage /*= false*/) const { if (maxDamage) { return -maxChange; } diff --git a/src/items/weapons/weapons.hpp b/src/items/weapons/weapons.hpp index 7dd9ba27b..90785983e 100644 --- a/src/items/weapons/weapons.hpp +++ b/src/items/weapons/weapons.hpp @@ -36,7 +36,7 @@ class Weapons final : public Scripts { return inject(); } - const Weapon* getWeapon(const Item* item) const; + const Weapon* getWeapon(std::shared_ptr item) const; static int32_t getMaxMeleeDamage(int32_t attackSkill, int32_t attackValue); static int32_t getMaxWeaponDamage(uint32_t level, int32_t attackSkill, int32_t attackValue, float attackFactor, bool isMelee); @@ -59,15 +59,15 @@ class Weapon : public Script { return false; } - int32_t playerWeaponCheck(Player* player, Creature* target, uint8_t shootRange) const; - static bool useFist(Player* player, Creature* target); - virtual bool useWeapon(Player* player, Item* item, Creature* target) const; + int32_t playerWeaponCheck(std::shared_ptr player, std::shared_ptr target, uint8_t shootRange) const; + static bool useFist(std::shared_ptr player, std::shared_ptr target); + virtual bool useWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr target) const; - virtual int32_t getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage = false) const = 0; - virtual int32_t getElementDamage(const Player* player, const Creature* target, const Item* item) const = 0; + virtual int32_t getWeaponDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, bool maxDamage = false) const = 0; + virtual int32_t getElementDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item) const = 0; virtual CombatType_t getElementType() const = 0; virtual int16_t getElementDamageValue() const = 0; - virtual CombatDamage getCombatDamage(CombatDamage combat, Player* player, Item* item, int32_t damageModifier) const; + virtual CombatDamage getCombatDamage(CombatDamage combat, std::shared_ptr player, std::shared_ptr item, int32_t damageModifier) const; uint16_t getID() const { return id; } @@ -174,17 +174,17 @@ class Weapon : public Script { } protected: - void internalUseWeapon(Player* player, Item* item, Creature* target, int32_t damageModifier, int32_t cleavePercent = 0) const; - void internalUseWeapon(Player* player, Item* item, Tile* tile) const; + void internalUseWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr target, int32_t damageModifier, int32_t cleavePercent = 0) const; + void internalUseWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr tile) const; private: - virtual bool getSkillType(const Player*, const Item*, skills_t &, uint32_t &) const { + virtual bool getSkillType(std::shared_ptr, std::shared_ptr, skills_t &, uint32_t &) const { return false; } - uint32_t getManaCost(const Player* player) const; - int32_t getHealthCost(const Player* player) const; - bool executeUseWeapon(Player* player, const LuaVariant &var) const; + uint32_t getManaCost(std::shared_ptr player) const; + int32_t getHealthCost(std::shared_ptr player) const; + bool executeUseWeapon(std::shared_ptr player, const LuaVariant &var) const; uint16_t id = 0; @@ -202,9 +202,9 @@ class Weapon : public Script { bool wieldUnproperly = false; std::string vocationString = ""; - void onUsedWeapon(Player* player, Item* item, Tile* destTile) const; + void onUsedWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr destTile) const; - static void decrementItemCount(Item* item); + static void decrementItemCount(std::shared_ptr item); WeaponAction_t action = WEAPONACTION_NONE; CombatParams params; @@ -228,17 +228,17 @@ class WeaponMelee final : public Weapon { void configureWeapon(const ItemType &it) override; - bool useWeapon(Player* player, Item* item, Creature* target) const override; + bool useWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr target) const override; - int32_t getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage = false) const override; - int32_t getElementDamage(const Player* player, const Creature* target, const Item* item) const override; + int32_t getWeaponDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, bool maxDamage = false) const override; + int32_t getElementDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item) const override; CombatType_t getElementType() const override { return elementType; } virtual int16_t getElementDamageValue() const override; private: - bool getSkillType(const Player* player, const Item* item, skills_t &skill, uint32_t &skillpoint) const override; + bool getSkillType(std::shared_ptr player, std::shared_ptr item, skills_t &skill, uint32_t &skillpoint) const override; uint16_t elementDamage = 0; CombatType_t elementType = COMBAT_NONE; }; @@ -256,17 +256,17 @@ class WeaponDistance final : public Weapon { return true; } - bool useWeapon(Player* player, Item* item, Creature* target) const override; + bool useWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr target) const override; - int32_t getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage = false) const override; - int32_t getElementDamage(const Player* player, const Creature* target, const Item* item) const override; + int32_t getWeaponDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, bool maxDamage = false) const override; + int32_t getElementDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item) const override; CombatType_t getElementType() const override { return elementType; } virtual int16_t getElementDamageValue() const override; private: - bool getSkillType(const Player* player, const Item* item, skills_t &skill, uint32_t &skillpoint) const override; + bool getSkillType(std::shared_ptr player, std::shared_ptr item, skills_t &skill, uint32_t &skillpoint) const override; CombatType_t elementType = COMBAT_NONE; uint16_t elementDamage = 0; @@ -282,8 +282,8 @@ class WeaponWand final : public Weapon { void configureWeapon(const ItemType &it) override; - int32_t getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage = false) const override; - int32_t getElementDamage(const Player*, const Creature*, const Item*) const override { + int32_t getWeaponDamage(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, bool maxDamage = false) const override; + int32_t getElementDamage(std::shared_ptr, std::shared_ptr, std::shared_ptr) const override { return 0; } CombatType_t getElementType() const override { @@ -299,7 +299,7 @@ class WeaponWand final : public Weapon { } private: - bool getSkillType(const Player*, const Item*, skills_t &, uint32_t &) const override { + bool getSkillType(std::shared_ptr, std::shared_ptr, skills_t &, uint32_t &) const override { return false; } diff --git a/src/kv/kv.cpp b/src/kv/kv.cpp index 812b68492..c71767a15 100644 --- a/src/kv/kv.cpp +++ b/src/kv/kv.cpp @@ -64,7 +64,15 @@ std::optional KVStore::get(const std::string &key, bool forceLoad return value; } - auto &[value, timestamp] = store_[key]; - lruQueue_.splice(lruQueue_.begin(), lruQueue_, timestamp); + auto &[value, lruIt] = store_[key]; + if (value.isDeleted()) { + lruQueue_.splice(lruQueue_.end(), lruQueue_, lruIt); + return std::nullopt; + } + lruQueue_.splice(lruQueue_.begin(), lruQueue_, lruIt); return value; } + +void KVStore::remove(const std::string &key) { + set(key, ValueWrapper::deleted()); +} diff --git a/src/kv/kv.hpp b/src/kv/kv.hpp index 27c61751b..674df8744 100644 --- a/src/kv/kv.hpp +++ b/src/kv/kv.hpp @@ -36,6 +36,8 @@ class KVStore { virtual std::optional get(const std::string &key, bool forceLoad = false); + void remove(const std::string &key); + template T get(const std::string &key, bool forceLoad = false); @@ -64,6 +66,7 @@ class KVStore { } virtual std::optional load(const std::string &key) = 0; virtual bool save(const std::string &key, const ValueWrapper &value) = 0; + Logger &logger; private: diff --git a/src/kv/kv_sql.cpp b/src/kv/kv_sql.cpp index d73bb5912..f967b5060 100644 --- a/src/kv/kv_sql.cpp +++ b/src/kv/kv_sql.cpp @@ -42,28 +42,36 @@ std::optional KVSQL::load(const std::string &key) { } bool KVSQL::save(const std::string &key, const ValueWrapper &value) { + auto update = dbUpdate(); + prepareSave(key, value, update); + return update.execute(); +} + +bool KVSQL::prepareSave(const std::string &key, const ValueWrapper &value, DBInsert &update) { auto protoValue = ProtoSerializable::toProto(value); std::string data; if (!protoValue.SerializeToString(&data)) { return false; } - auto query = fmt::format( - "REPLACE INTO `kv_store` (`key_name`, `timestamp`, `value`) VALUES ({}, {}, {})", - db.escapeString(key), - getTimeMsNow(), - db.escapeString(data) - ); - return db.executeQuery(query); + if (value.isDeleted()) { + auto query = fmt::format("DELETE FROM `kv_store` WHERE `key_name` = {}", db.escapeString(key)); + return db.executeQuery(query); + } + + update.upsert({ "timestamp", "value" }); + update.addRow(fmt::format("({}, {}, {})", db.escapeString(key), getTimeMsNow(), db.escapeString(data))); + return true; } bool KVSQL::saveAll() { auto store = getStore(); bool success = DBTransaction::executeWithinTransaction([this, &store]() { - return std::ranges::all_of(store, [this](const auto &kv) { + auto update = dbUpdate(); + return std::ranges::all_of(store, [this, &update](const auto &kv) { const auto &[key, value] = kv; - return save(key, value.first); + return prepareSave(key, value.first, update); }); - return true; + return update.execute(); }); if (!success) { diff --git a/src/kv/kv_sql.hpp b/src/kv/kv_sql.hpp index 178891179..8f107a209 100644 --- a/src/kv/kv_sql.hpp +++ b/src/kv/kv_sql.hpp @@ -24,10 +24,14 @@ class KVSQL final : public KVStore { bool saveAll() override; -protected: +private: std::optional load(const std::string &key) override; bool save(const std::string &key, const ValueWrapper &value) override; + bool prepareSave(const std::string &key, const ValueWrapper &value, DBInsert &update); + + DBInsert dbUpdate() const { + return DBInsert("INSERT INTO `kv_store` (`key_name`, `timestamp`, `value`) VALUES"); + } -private: Database &db; }; diff --git a/src/kv/value_wrapper.hpp b/src/kv/value_wrapper.hpp index d079a6690..11c3c588d 100644 --- a/src/kv/value_wrapper.hpp +++ b/src/kv/value_wrapper.hpp @@ -39,6 +39,12 @@ class ValueWrapper { explicit(false) ValueWrapper(const phmap::flat_hash_map &value, uint64_t timestamp = 0); explicit(false) ValueWrapper(const std::initializer_list> &init_list, uint64_t timestamp = 0); + static ValueWrapper deleted() { + static ValueWrapper wrapper; + wrapper.setDeleted(true); + return wrapper; + } + template T get() const { return std::get(data_); @@ -65,6 +71,14 @@ class ValueWrapper { timestamp_ = timestamp; } + void setDeleted(bool deleted) { + deleted_ = deleted; + } + + bool isDeleted() const { + return deleted_; + } + bool operator==(const ValueWrapper &rhs) const; explicit(false) operator std::string() const { @@ -90,6 +104,7 @@ class ValueWrapper { private: ValueVariant data_; uint64_t timestamp_ = 0; + bool deleted_ = false; template static MapType createMapFromRange(Iter begin, Iter end, uint64_t timestamp) { diff --git a/src/lua/callbacks/creaturecallback.cpp b/src/lua/callbacks/creaturecallback.cpp index 577d26e7a..df5845f46 100644 --- a/src/lua/callbacks/creaturecallback.cpp +++ b/src/lua/callbacks/creaturecallback.cpp @@ -15,6 +15,7 @@ bool CreatureCallback::startScriptInterface(int32_t scriptId) { } if (!scriptInterface->reserveScriptEnv()) { + auto targetCreature = m_targetCreature.lock(); g_logger().error( "[CreatureCallback::startScriptInterface] - {} {} Call stack overflow. Too many lua script calls being nested.", getCreatureClass(targetCreature), @@ -34,12 +35,12 @@ bool CreatureCallback::startScriptInterface(int32_t scriptId) { return true; } -void CreatureCallback::pushSpecificCreature(Creature* creature) { - if (Npc* npc = creature->getNpc()) { +void CreatureCallback::pushSpecificCreature(std::shared_ptr creature) { + if (std::shared_ptr npc = creature->getNpc()) { LuaScriptInterface::pushUserdata(L, npc); - } else if (Monster* monster = creature->getMonster()) { + } else if (std::shared_ptr monster = creature->getMonster()) { LuaScriptInterface::pushUserdata(L, monster); - } else if (Player* player = creature->getPlayer()) { + } else if (std::shared_ptr player = creature->getPlayer()) { LuaScriptInterface::pushUserdata(L, player); } else { return; @@ -49,7 +50,10 @@ void CreatureCallback::pushSpecificCreature(Creature* creature) { LuaScriptInterface::setMetatable(L, -1, getCreatureClass(creature)); } -std::string CreatureCallback::getCreatureClass(Creature* creature) { +std::string CreatureCallback::getCreatureClass(std::shared_ptr creature) { + if (!creature) { + return ""; + } if (creature->getNpc()) { return "Npc"; } diff --git a/src/lua/callbacks/creaturecallback.hpp b/src/lua/callbacks/creaturecallback.hpp index fccc921b4..4b017e773 100644 --- a/src/lua/callbacks/creaturecallback.hpp +++ b/src/lua/callbacks/creaturecallback.hpp @@ -16,19 +16,19 @@ class Creature; class CreatureCallback { public: - CreatureCallback(LuaScriptInterface* scriptInterface, Creature* targetCreature) : - scriptInterface(scriptInterface), targetCreature(targetCreature) {}; + CreatureCallback(LuaScriptInterface* scriptInterface, std::shared_ptr targetCreature) : + scriptInterface(scriptInterface), m_targetCreature(targetCreature) {}; ~CreatureCallback() { } bool startScriptInterface(int32_t scriptId); - void pushSpecificCreature(Creature* creature); + void pushSpecificCreature(std::shared_ptr creature); bool persistLuaState() { return params > 0 && scriptInterface->callFunction(params); } - void pushCreature(Creature* creature) { + void pushCreature(std::shared_ptr creature) { params++; LuaScriptInterface::pushUserdata(L, creature); LuaScriptInterface::setCreatureMetatable(L, -1, creature); @@ -55,11 +55,11 @@ class CreatureCallback { } protected: - static std::string getCreatureClass(Creature* creature); + static std::string getCreatureClass(std::shared_ptr creature); private: LuaScriptInterface* scriptInterface; - Creature* targetCreature; + std::weak_ptr m_targetCreature; uint32_t params = 0; lua_State* L = nullptr; }; diff --git a/src/lua/callbacks/event_callback.cpp b/src/lua/callbacks/event_callback.cpp index 4ad8358d0..6444446bd 100644 --- a/src/lua/callbacks/event_callback.cpp +++ b/src/lua/callbacks/event_callback.cpp @@ -49,7 +49,7 @@ void EventCallback::setType(EventCallback_t type) { // Lua functions // Creature -bool EventCallback::creatureOnChangeOutfit(Creature* creature, const Outfit_t &outfit) const { +bool EventCallback::creatureOnChangeOutfit(std::shared_ptr creature, const Outfit_t &outfit) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::creatureOnChangeOutfit - Creature {}] " "Call stack overflow. Too many lua script calls being nested.", @@ -71,7 +71,7 @@ bool EventCallback::creatureOnChangeOutfit(Creature* creature, const Outfit_t &o return getScriptInterface()->callFunction(2); } -ReturnValue EventCallback::creatureOnAreaCombat(Creature* creature, Tile* tile, bool aggressive) const { +ReturnValue EventCallback::creatureOnAreaCombat(std::shared_ptr creature, std::shared_ptr tile, bool aggressive) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::creatureOnAreaCombat - " "Creature {} on tile position {}] " @@ -111,7 +111,7 @@ ReturnValue EventCallback::creatureOnAreaCombat(Creature* creature, Tile* tile, return returnValue; } -ReturnValue EventCallback::creatureOnTargetCombat(Creature* creature, Creature* target) const { +ReturnValue EventCallback::creatureOnTargetCombat(std::shared_ptr creature, std::shared_ptr target) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::creatureOnTargetCombat - " "Creature {} target {}] " @@ -149,7 +149,7 @@ ReturnValue EventCallback::creatureOnTargetCombat(Creature* creature, Creature* return returnValue; } -void EventCallback::creatureOnHear(Creature* creature, Creature* speaker, const std::string &words, SpeakClasses type) const { +void EventCallback::creatureOnHear(std::shared_ptr creature, std::shared_ptr speaker, const std::string &words, SpeakClasses type) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::creatureOnHear - " "Creature {} speaker {}] " @@ -176,7 +176,7 @@ void EventCallback::creatureOnHear(Creature* creature, Creature* speaker, const getScriptInterface()->callVoidFunction(4); } -void EventCallback::creatureOnDrainHealth(Creature* creature, Creature* attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) const { +void EventCallback::creatureOnDrainHealth(std::shared_ptr creature, std::shared_ptr attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::creatureOnDrainHealth - " "Creature {} attacker {}] " @@ -228,7 +228,7 @@ void EventCallback::creatureOnDrainHealth(Creature* creature, Creature* attacker } // Party -bool EventCallback::partyOnJoin(Party* party, Player* player) const { +bool EventCallback::partyOnJoin(std::shared_ptr party, std::shared_ptr player) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::partyOnJoin - " "Player {}] " @@ -252,7 +252,7 @@ bool EventCallback::partyOnJoin(Party* party, Player* player) const { return getScriptInterface()->callFunction(2); } -bool EventCallback::partyOnLeave(Party* party, Player* player) const { +bool EventCallback::partyOnLeave(std::shared_ptr party, std::shared_ptr player) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::partyOnLeave - " "Player {}] " @@ -276,11 +276,11 @@ bool EventCallback::partyOnLeave(Party* party, Player* player) const { return getScriptInterface()->callFunction(2); } -bool EventCallback::partyOnDisband(Party* party) const { +bool EventCallback::partyOnDisband(std::shared_ptr party) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::partyOnDisband - Party leader {}] Call stack " "overflow. Too many lua script calls being nested.", - party->getLeader()->getName()); + party->getLeader() ? party->getLeader()->getName() : "unknown"); return false; } @@ -296,9 +296,9 @@ bool EventCallback::partyOnDisband(Party* party) const { return getScriptInterface()->callFunction(1); } -void EventCallback::partyOnShareExperience(Party* party, uint64_t &exp) const { +void EventCallback::partyOnShareExperience(std::shared_ptr party, uint64_t &exp) const { if (!getScriptInterface()->reserveScriptEnv()) { - g_logger().error("Party leader {}. Call stack overflow. Too many lua script calls being nested.", party->getLeader()->getName()); + g_logger().error("Party leader {}. Call stack overflow. Too many lua script calls being nested.", party->getLeader() ? party->getLeader()->getName() : "unknown"); return; } @@ -324,7 +324,7 @@ void EventCallback::partyOnShareExperience(Party* party, uint64_t &exp) const { } // Player -bool EventCallback::playerOnBrowseField(Player* player, const Position &position) const { +bool EventCallback::playerOnBrowseField(std::shared_ptr player, const Position &position) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnBrowseField - " "Player {}] " @@ -347,7 +347,7 @@ bool EventCallback::playerOnBrowseField(Player* player, const Position &position return getScriptInterface()->callFunction(2); } -void EventCallback::playerOnLook(Player* player, const Position &position, Thing* thing, uint8_t stackpos, int32_t lookDistance) const { +void EventCallback::playerOnLook(std::shared_ptr player, const Position &position, std::shared_ptr thing, uint8_t stackpos, int32_t lookDistance) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnLook - " "Player {}] " @@ -365,10 +365,10 @@ void EventCallback::playerOnLook(Player* player, const Position &position, Thing LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); - if (Creature* creature = thing->getCreature()) { + if (std::shared_ptr creature = thing->getCreature()) { LuaScriptInterface::pushUserdata(L, creature); LuaScriptInterface::setCreatureMetatable(L, -1, creature); - } else if (Item* item = thing->getItem()) { + } else if (std::shared_ptr item = thing->getItem()) { LuaScriptInterface::pushUserdata(L, item); LuaScriptInterface::setItemMetatable(L, -1, item); } else { @@ -381,7 +381,7 @@ void EventCallback::playerOnLook(Player* player, const Position &position, Thing getScriptInterface()->callVoidFunction(4); } -void EventCallback::playerOnLookInBattleList(Player* player, Creature* creature, int32_t lookDistance) const { +void EventCallback::playerOnLookInBattleList(std::shared_ptr player, std::shared_ptr creature, int32_t lookDistance) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnLookInBattleList - " "Player {}] " @@ -407,7 +407,7 @@ void EventCallback::playerOnLookInBattleList(Player* player, Creature* creature, getScriptInterface()->callVoidFunction(3); } -void EventCallback::playerOnLookInTrade(Player* player, Player* partner, Item* item, int32_t lookDistance) const { +void EventCallback::playerOnLookInTrade(std::shared_ptr player, std::shared_ptr partner, std::shared_ptr item, int32_t lookDistance) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnLookInTrade - " "Player {}] " @@ -436,7 +436,7 @@ void EventCallback::playerOnLookInTrade(Player* player, Player* partner, Item* i getScriptInterface()->callVoidFunction(4); } -bool EventCallback::playerOnLookInShop(Player* player, const ItemType* itemType, uint8_t count) const { +bool EventCallback::playerOnLookInShop(std::shared_ptr player, const ItemType* itemType, uint8_t count) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnLookInShop - " "Player {} itemType {}] " @@ -462,7 +462,7 @@ bool EventCallback::playerOnLookInShop(Player* player, const ItemType* itemType, return getScriptInterface()->callFunction(3); } -void EventCallback::playerOnRemoveCount(Player* player, Item* item) const { +void EventCallback::playerOnRemoveCount(std::shared_ptr player, std::shared_ptr item) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnMove - " "Player {} item {}] " @@ -486,7 +486,7 @@ void EventCallback::playerOnRemoveCount(Player* player, Item* item) const { getScriptInterface()->callFunction(2); } -bool EventCallback::playerOnMoveItem(Player* player, Item* item, uint16_t count, const Position &fromPos, const Position &toPos, Cylinder* fromCylinder, Cylinder* toCylinder) const { +bool EventCallback::playerOnMoveItem(std::shared_ptr player, std::shared_ptr item, uint16_t count, const Position &fromPos, const Position &toPos, std::shared_ptr fromCylinder, std::shared_ptr toCylinder) const { if (!getScriptInterface()) { g_logger().error("script interface nullptr"); return false; @@ -521,7 +521,7 @@ bool EventCallback::playerOnMoveItem(Player* player, Item* item, uint16_t count, return getScriptInterface()->callFunction(7); } -void EventCallback::playerOnItemMoved(Player* player, Item* item, uint16_t count, const Position &fromPosition, const Position &toPosition, Cylinder* fromCylinder, Cylinder* toCylinder) const { +void EventCallback::playerOnItemMoved(std::shared_ptr player, std::shared_ptr item, uint16_t count, const Position &fromPosition, const Position &toPosition, std::shared_ptr fromCylinder, std::shared_ptr toCylinder) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnItemMoved - " "Player {} item {}] " @@ -552,7 +552,7 @@ void EventCallback::playerOnItemMoved(Player* player, Item* item, uint16_t count getScriptInterface()->callVoidFunction(7); } -void EventCallback::playerOnChangeZone(Player* player, ZoneType_t zone) const { +void EventCallback::playerOnChangeZone(std::shared_ptr player, ZoneType_t zone) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnChangeZone - " "Player {}] " @@ -574,7 +574,7 @@ void EventCallback::playerOnChangeZone(Player* player, ZoneType_t zone) const { getScriptInterface()->callVoidFunction(2); } -bool EventCallback::playerOnMoveCreature(Player* player, Creature* creature, const Position &fromPosition, const Position &toPosition) const { +bool EventCallback::playerOnMoveCreature(std::shared_ptr player, std::shared_ptr creature, const Position &fromPosition, const Position &toPosition) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnMoveCreature - " "Player {} creature {}] " @@ -601,7 +601,7 @@ bool EventCallback::playerOnMoveCreature(Player* player, Creature* creature, con return getScriptInterface()->callFunction(4); } -void EventCallback::playerOnReportRuleViolation(Player* player, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation) const { +void EventCallback::playerOnReportRuleViolation(std::shared_ptr player, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnReportRuleViolation - " "Player {}] " @@ -630,7 +630,7 @@ void EventCallback::playerOnReportRuleViolation(Player* player, const std::strin getScriptInterface()->callVoidFunction(6); } -void EventCallback::playerOnReportBug(Player* player, const std::string &message, const Position &position, uint8_t category) const { +void EventCallback::playerOnReportBug(std::shared_ptr player, const std::string &message, const Position &position, uint8_t category) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnReportBug - " "Player {}] " @@ -655,7 +655,7 @@ void EventCallback::playerOnReportBug(Player* player, const std::string &message getScriptInterface()->callFunction(4); } -bool EventCallback::playerOnTurn(Player* player, Direction direction) const { +bool EventCallback::playerOnTurn(std::shared_ptr player, Direction direction) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnTurn - " "Player {}] " @@ -678,7 +678,7 @@ bool EventCallback::playerOnTurn(Player* player, Direction direction) const { return getScriptInterface()->callFunction(2); } -bool EventCallback::playerOnTradeRequest(Player* player, Player* target, Item* item) const { +bool EventCallback::playerOnTradeRequest(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnTradeRequest - " "Player {} target {}] " @@ -705,7 +705,7 @@ bool EventCallback::playerOnTradeRequest(Player* player, Player* target, Item* i return getScriptInterface()->callFunction(3); } -bool EventCallback::playerOnTradeAccept(Player* player, Player* target, Item* item, Item* targetItem) const { +bool EventCallback::playerOnTradeAccept(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, std::shared_ptr targetItem) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnTradeAccept - " "Player {} target {}] " @@ -735,7 +735,7 @@ bool EventCallback::playerOnTradeAccept(Player* player, Player* target, Item* it return getScriptInterface()->callFunction(4); } -void EventCallback::playerOnGainExperience(Player* player, Creature* target, uint64_t &exp, uint64_t rawExp) const { +void EventCallback::playerOnGainExperience(std::shared_ptr player, std::shared_ptr target, uint64_t &exp, uint64_t rawExp) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnGainExperience - " "Player {} target {}] " @@ -773,7 +773,7 @@ void EventCallback::playerOnGainExperience(Player* player, Creature* target, uin getScriptInterface()->resetScriptEnv(); } -void EventCallback::playerOnLoseExperience(Player* player, uint64_t &exp) const { +void EventCallback::playerOnLoseExperience(std::shared_ptr player, uint64_t &exp) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnLoseExperience - " "Player {}] " @@ -803,7 +803,7 @@ void EventCallback::playerOnLoseExperience(Player* player, uint64_t &exp) const getScriptInterface()->resetScriptEnv(); } -void EventCallback::playerOnGainSkillTries(Player* player, skills_t skill, uint64_t &tries) const { +void EventCallback::playerOnGainSkillTries(std::shared_ptr player, skills_t skill, uint64_t &tries) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnGainSkillTries - " "Player {} skill {}] " @@ -834,7 +834,7 @@ void EventCallback::playerOnGainSkillTries(Player* player, skills_t skill, uint6 getScriptInterface()->resetScriptEnv(); } -void EventCallback::playerOnCombat(Player* player, Creature* target, Item* item, CombatDamage &damage) const { +void EventCallback::playerOnCombat(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, CombatDamage &damage) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnCombat - " "Player {} target {}] " @@ -896,7 +896,7 @@ void EventCallback::playerOnCombat(Player* player, Creature* target, Item* item, getScriptInterface()->resetScriptEnv(); } -void EventCallback::playerOnRequestQuestLog(Player* player) const { +void EventCallback::playerOnRequestQuestLog(std::shared_ptr player) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnRequestQuestLog - " "Player {}] " @@ -917,7 +917,7 @@ void EventCallback::playerOnRequestQuestLog(Player* player) const { getScriptInterface()->callVoidFunction(1); } -void EventCallback::playerOnRequestQuestLine(Player* player, uint16_t questId) const { +void EventCallback::playerOnRequestQuestLine(std::shared_ptr player, uint16_t questId) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::playerOnRequestQuestLine - " "Player {} questId {}] " @@ -940,7 +940,7 @@ void EventCallback::playerOnRequestQuestLine(Player* player, uint16_t questId) c getScriptInterface()->callVoidFunction(2); } -void EventCallback::playerOnInventoryUpdate(Player* player, Item* item, Slots_t slot, bool equip) const { +void EventCallback::playerOnInventoryUpdate(std::shared_ptr player, std::shared_ptr item, Slots_t slot, bool equip) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[{}] Call stack overflow", __FUNCTION__); return; @@ -964,7 +964,7 @@ void EventCallback::playerOnInventoryUpdate(Player* player, Item* item, Slots_t getScriptInterface()->callVoidFunction(4); } -bool EventCallback::playerOnRotateItem(Player* player, Item* item, const Position &position) const { +bool EventCallback::playerOnRotateItem(std::shared_ptr player, std::shared_ptr item, const Position &position) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[{}] Call stack overflow", __FUNCTION__); return false; @@ -987,7 +987,7 @@ bool EventCallback::playerOnRotateItem(Player* player, Item* item, const Positio return getScriptInterface()->callFunction(3); } -void EventCallback::playerOnStorageUpdate(Player* player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime) const { +void EventCallback::playerOnStorageUpdate(std::shared_ptr player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::eventOnStorageUpdate - " "Player {} key {}] " @@ -1014,7 +1014,7 @@ void EventCallback::playerOnStorageUpdate(Player* player, const uint32_t key, co } // Monster -void EventCallback::monsterOnDropLoot(Monster* monster, Container* corpse) const { +void EventCallback::monsterOnDropLoot(std::shared_ptr monster, std::shared_ptr corpse) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::monsterOnDropLoot - " "Monster corpse {}] " @@ -1038,7 +1038,7 @@ void EventCallback::monsterOnDropLoot(Monster* monster, Container* corpse) const return getScriptInterface()->callVoidFunction(2); } -void EventCallback::monsterPostDropLoot(Monster* monster, Container* corpse) const { +void EventCallback::monsterPostDropLoot(std::shared_ptr monster, std::shared_ptr corpse) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::monsterPostDropLoot - " "Monster corpse {}] " @@ -1062,7 +1062,7 @@ void EventCallback::monsterPostDropLoot(Monster* monster, Container* corpse) con return getScriptInterface()->callVoidFunction(2); } -void EventCallback::monsterOnSpawn(Monster* monster, const Position &position) const { +void EventCallback::monsterOnSpawn(std::shared_ptr monster, const Position &position) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("{} - " "Position {}" @@ -1091,7 +1091,7 @@ void EventCallback::monsterOnSpawn(Monster* monster, const Position &position) c } // Npc -void EventCallback::npcOnSpawn(Npc* npc, const Position &position) const { +void EventCallback::npcOnSpawn(std::shared_ptr npc, const Position &position) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("{} - " "Position {}" @@ -1119,7 +1119,7 @@ void EventCallback::npcOnSpawn(Npc* npc, const Position &position) const { getScriptInterface()->resetScriptEnv(); } -bool EventCallback::zoneBeforeCreatureEnter(std::shared_ptr zone, Creature* creature) const { +bool EventCallback::zoneBeforeCreatureEnter(std::shared_ptr zone, std::shared_ptr creature) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::zoneBeforeCreatureEnter - " "Zone {} Creature {}] " @@ -1143,7 +1143,7 @@ bool EventCallback::zoneBeforeCreatureEnter(std::shared_ptr zone, Creature return getScriptInterface()->callFunction(2); } -bool EventCallback::zoneBeforeCreatureLeave(std::shared_ptr zone, Creature* creature) const { +bool EventCallback::zoneBeforeCreatureLeave(std::shared_ptr zone, std::shared_ptr creature) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::zoneBeforeCreatureLeave - " "Zone {} Creature {}] " @@ -1167,7 +1167,7 @@ bool EventCallback::zoneBeforeCreatureLeave(std::shared_ptr zone, Creature return getScriptInterface()->callFunction(2); } -void EventCallback::zoneAfterCreatureEnter(std::shared_ptr zone, Creature* creature) const { +void EventCallback::zoneAfterCreatureEnter(std::shared_ptr zone, std::shared_ptr creature) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::zoneAfterCreatureEnter - " "Zone {} Creature {}] " @@ -1191,7 +1191,7 @@ void EventCallback::zoneAfterCreatureEnter(std::shared_ptr zone, Creature* getScriptInterface()->callVoidFunction(2); } -void EventCallback::zoneAfterCreatureLeave(std::shared_ptr zone, Creature* creature) const { +void EventCallback::zoneAfterCreatureLeave(std::shared_ptr zone, std::shared_ptr creature) const { if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[EventCallback::zoneAfterCreatureLeave - " "Zone {} Creature {}] " diff --git a/src/lua/callbacks/event_callback.hpp b/src/lua/callbacks/event_callback.hpp index f1dea466f..152c86b8e 100644 --- a/src/lua/callbacks/event_callback.hpp +++ b/src/lua/callbacks/event_callback.hpp @@ -79,57 +79,57 @@ class EventCallback : public Script { */ // Creature - bool creatureOnChangeOutfit(Creature* creature, const Outfit_t &outfit) const; - ReturnValue creatureOnAreaCombat(Creature* creature, Tile* tile, bool aggressive) const; - ReturnValue creatureOnTargetCombat(Creature* creature, Creature* target) const; - void creatureOnHear(Creature* creature, Creature* speaker, const std::string &words, SpeakClasses type) const; - void creatureOnDrainHealth(Creature* creature, Creature* attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) const; + bool creatureOnChangeOutfit(std::shared_ptr creature, const Outfit_t &outfit) const; + ReturnValue creatureOnAreaCombat(std::shared_ptr creature, std::shared_ptr tile, bool aggressive) const; + ReturnValue creatureOnTargetCombat(std::shared_ptr creature, std::shared_ptr target) const; + void creatureOnHear(std::shared_ptr creature, std::shared_ptr speaker, const std::string &words, SpeakClasses type) const; + void creatureOnDrainHealth(std::shared_ptr creature, std::shared_ptr attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) const; // Party - bool partyOnJoin(Party* party, Player* player) const; - bool partyOnLeave(Party* party, Player* player) const; - bool partyOnDisband(Party* party) const; - void partyOnShareExperience(Party* party, uint64_t &exp) const; + bool partyOnJoin(std::shared_ptr party, std::shared_ptr player) const; + bool partyOnLeave(std::shared_ptr party, std::shared_ptr player) const; + bool partyOnDisband(std::shared_ptr party) const; + void partyOnShareExperience(std::shared_ptr party, uint64_t &exp) const; // Player - bool playerOnBrowseField(Player* player, const Position &position) const; - void playerOnLook(Player* player, const Position &position, Thing* thing, uint8_t stackpos, int32_t lookDistance) const; - void playerOnLookInBattleList(Player* player, Creature* creature, int32_t lookDistance) const; - void playerOnLookInTrade(Player* player, Player* partner, Item* item, int32_t lookDistance) const; - bool playerOnLookInShop(Player* player, const ItemType* itemType, uint8_t count) const; - bool playerOnMoveItem(Player* player, Item* item, uint16_t count, const Position &fromPosition, const Position &toPosition, Cylinder* fromCylinder, Cylinder* toCylinder) const; - void playerOnItemMoved(Player* player, Item* item, uint16_t count, const Position &fromPosition, const Position &toPosition, Cylinder* fromCylinder, Cylinder* toCylinder) const; - void playerOnChangeZone(Player* player, ZoneType_t zone) const; - bool playerOnMoveCreature(Player* player, Creature* creature, const Position &fromPosition, const Position &toPosition) const; - void playerOnReportRuleViolation(Player* player, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation) const; - void playerOnReportBug(Player* player, const std::string &message, const Position &position, uint8_t category) const; - bool playerOnTurn(Player* player, Direction direction) const; - bool playerOnTradeRequest(Player* player, Player* target, Item* item) const; - bool playerOnTradeAccept(Player* player, Player* target, Item* item, Item* targetItem) const; - void playerOnGainExperience(Player* player, Creature* target, uint64_t &exp, uint64_t rawExp) const; - void playerOnLoseExperience(Player* player, uint64_t &exp) const; - void playerOnGainSkillTries(Player* player, skills_t skill, uint64_t &tries) const; - void playerOnRemoveCount(Player* player, Item* item) const; - void playerOnRequestQuestLog(Player* player) const; - void playerOnRequestQuestLine(Player* player, uint16_t questId) const; - void playerOnStorageUpdate(Player* player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime) const; - void playerOnCombat(Player* player, Creature* target, Item* item, CombatDamage &damage) const; - void playerOnInventoryUpdate(Player* player, Item* item, Slots_t slot, bool equip) const; - bool playerOnRotateItem(Player* player, Item* item, const Position &position) const; + bool playerOnBrowseField(std::shared_ptr player, const Position &position) const; + void playerOnLook(std::shared_ptr player, const Position &position, std::shared_ptr thing, uint8_t stackpos, int32_t lookDistance) const; + void playerOnLookInBattleList(std::shared_ptr player, std::shared_ptr creature, int32_t lookDistance) const; + void playerOnLookInTrade(std::shared_ptr player, std::shared_ptr partner, std::shared_ptr item, int32_t lookDistance) const; + bool playerOnLookInShop(std::shared_ptr player, const ItemType* itemType, uint8_t count) const; + bool playerOnMoveItem(std::shared_ptr player, std::shared_ptr item, uint16_t count, const Position &fromPosition, const Position &toPosition, std::shared_ptr fromCylinder, std::shared_ptr toCylinder) const; + void playerOnItemMoved(std::shared_ptr player, std::shared_ptr item, uint16_t count, const Position &fromPosition, const Position &toPosition, std::shared_ptr fromCylinder, std::shared_ptr toCylinder) const; + void playerOnChangeZone(std::shared_ptr player, ZoneType_t zone) const; + bool playerOnMoveCreature(std::shared_ptr player, std::shared_ptr creature, const Position &fromPosition, const Position &toPosition) const; + void playerOnReportRuleViolation(std::shared_ptr player, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation) const; + void playerOnReportBug(std::shared_ptr player, const std::string &message, const Position &position, uint8_t category) const; + bool playerOnTurn(std::shared_ptr player, Direction direction) const; + bool playerOnTradeRequest(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item) const; + bool playerOnTradeAccept(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, std::shared_ptr targetItem) const; + void playerOnGainExperience(std::shared_ptr player, std::shared_ptr target, uint64_t &exp, uint64_t rawExp) const; + void playerOnLoseExperience(std::shared_ptr player, uint64_t &exp) const; + void playerOnGainSkillTries(std::shared_ptr player, skills_t skill, uint64_t &tries) const; + void playerOnRemoveCount(std::shared_ptr player, std::shared_ptr item) const; + void playerOnRequestQuestLog(std::shared_ptr player) const; + void playerOnRequestQuestLine(std::shared_ptr player, uint16_t questId) const; + void playerOnStorageUpdate(std::shared_ptr player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime) const; + void playerOnCombat(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, CombatDamage &damage) const; + void playerOnInventoryUpdate(std::shared_ptr player, std::shared_ptr item, Slots_t slot, bool equip) const; + bool playerOnRotateItem(std::shared_ptr player, std::shared_ptr item, const Position &position) const; // Monster - void monsterOnDropLoot(Monster* monster, Container* corpse) const; - void monsterPostDropLoot(Monster* monster, Container* corpse) const; - void monsterOnSpawn(Monster* monster, const Position &position) const; + void monsterOnDropLoot(std::shared_ptr monster, std::shared_ptr corpse) const; + void monsterPostDropLoot(std::shared_ptr monster, std::shared_ptr corpse) const; + void monsterOnSpawn(std::shared_ptr monster, const Position &position) const; // Npc - void npcOnSpawn(Npc* npc, const Position &position) const; + void npcOnSpawn(std::shared_ptr npc, const Position &position) const; // Zone - bool zoneBeforeCreatureEnter(std::shared_ptr zone, Creature* creature) const; - bool zoneBeforeCreatureLeave(std::shared_ptr zone, Creature* creature) const; - void zoneAfterCreatureEnter(std::shared_ptr zone, Creature* creature) const; - void zoneAfterCreatureLeave(std::shared_ptr zone, Creature* creature) const; + bool zoneBeforeCreatureEnter(std::shared_ptr zone, std::shared_ptr creature) const; + bool zoneBeforeCreatureLeave(std::shared_ptr zone, std::shared_ptr creature) const; + void zoneAfterCreatureEnter(std::shared_ptr zone, std::shared_ptr creature) const; + void zoneAfterCreatureLeave(std::shared_ptr zone, std::shared_ptr creature) const; /** * @note here end the lua binder functions } diff --git a/src/lua/callbacks/events_callbacks.hpp b/src/lua/callbacks/events_callbacks.hpp index e8e556068..7eb471430 100644 --- a/src/lua/callbacks/events_callbacks.hpp +++ b/src/lua/callbacks/events_callbacks.hpp @@ -78,8 +78,14 @@ class EventsCallbacks { template void executeCallback(EventCallback_t eventType, CallbackFunc callbackFunc, Args &&... args) { for (const auto &callback : getCallbacksByType(eventType)) { + auto argsCopy = std::make_tuple(args...); if (callback && callback->isLoadedCallback()) { - ((*callback).*callbackFunc)(std::forward(args)...); + std::apply( + [&callback, &callbackFunc](auto &&... args) { + ((*callback).*callbackFunc)(std::forward(args)...); + }, + argsCopy + ); } } } @@ -96,8 +102,14 @@ class EventsCallbacks { bool allCallbacksSucceeded = true; for (const auto &callback : getCallbacksByType(eventType)) { - if (callback && callback->isLoadedCallback()) { // Verifique se o callback é não nulo - bool callbackResult = ((*callback).*callbackFunc)(std::forward(args)...); + auto argsCopy = std::make_tuple(args...); + if (callback && callback->isLoadedCallback()) { + bool callbackResult = std::apply( + [&callback, &callbackFunc](auto &&... args) { + return ((*callback).*callbackFunc)(std::forward(args)...); + }, + argsCopy + ); allCallbacksSucceeded = allCallbacksSucceeded && callbackResult; } } diff --git a/src/lua/creature/actions.cpp b/src/lua/creature/actions.cpp index e760d3c66..6a79d697e 100644 --- a/src/lua/creature/actions.cpp +++ b/src/lua/creature/actions.cpp @@ -166,7 +166,7 @@ bool Actions::registerLuaEvent(const std::shared_ptr action) { return false; } -ReturnValue Actions::canUse(const Player* player, const Position &pos) { +ReturnValue Actions::canUse(std::shared_ptr player, const Position &pos) { if (pos.x != 0xFFFF) { const Position &playerPos = player->getPosition(); if (playerPos.z != pos.z) { @@ -180,7 +180,7 @@ ReturnValue Actions::canUse(const Player* player, const Position &pos) { return RETURNVALUE_NOERROR; } -ReturnValue Actions::canUse(const Player* player, const Position &pos, const Item* item) { +ReturnValue Actions::canUse(std::shared_ptr player, const Position &pos, std::shared_ptr item) { const std::shared_ptr action = getAction(item); if (action != nullptr) { return action->canExecuteAction(player, pos); @@ -188,7 +188,7 @@ ReturnValue Actions::canUse(const Player* player, const Position &pos, const Ite return RETURNVALUE_NOERROR; } -ReturnValue Actions::canUseFar(const Creature* creature, const Position &toPos, bool checkLineOfSight, bool checkFloor) { +ReturnValue Actions::canUseFar(std::shared_ptr creature, const Position &toPos, bool checkLineOfSight, bool checkFloor) { if (toPos.x == 0xFFFF) { return RETURNVALUE_NOERROR; } @@ -209,7 +209,7 @@ ReturnValue Actions::canUseFar(const Creature* creature, const Position &toPos, return RETURNVALUE_NOERROR; } -std::shared_ptr Actions::getAction(const Item* item) { +std::shared_ptr Actions::getAction(std::shared_ptr item) { if (item->hasAttribute(ItemAttribute_t::UNIQUEID)) { auto it = uniqueItemMap.find(item->getAttribute(ItemAttribute_t::UNIQUEID)); if (it != uniqueItemMap.end()) { @@ -231,9 +231,9 @@ std::shared_ptr Actions::getAction(const Item* item) { if (auto iteratePositions = actionPositionMap.find(item->getPosition()); iteratePositions != actionPositionMap.end()) { - if (const Tile* tile = item->getTile(); + if (std::shared_ptr tile = item->getTile(); tile) { - if (const Player* player = item->getHoldingPlayer(); + if (std::shared_ptr player = item->getHoldingPlayer(); player && item->getTopParent() == player) { g_logger().debug("[Actions::getAction] - The position only is valid for use item in the map, player name {}", player->getName()); return nullptr; @@ -247,8 +247,8 @@ std::shared_ptr Actions::getAction(const Item* item) { return g_spells().getRuneSpell(item->getID()); } -ReturnValue Actions::internalUseItem(Player* player, const Position &pos, uint8_t index, Item* item, bool isHotkey) { - if (Door* door = item->getDoor()) { +ReturnValue Actions::internalUseItem(std::shared_ptr player, const Position &pos, uint8_t index, std::shared_ptr item, bool isHotkey) { + if (std::shared_ptr door = item->getDoor()) { if (!door->canUse(player)) { return RETURNVALUE_CANNOTUSETHISOBJECT; } @@ -282,7 +282,7 @@ ReturnValue Actions::internalUseItem(Player* player, const Position &pos, uint8_ } } - if (BedItem* bed = item->getBed()) { + if (std::shared_ptr bed = item->getBed()) { if (!bed->canUse(player)) { return RETURNVALUE_CANNOTUSETHISOBJECT; } @@ -295,12 +295,12 @@ ReturnValue Actions::internalUseItem(Player* player, const Position &pos, uint8_ return RETURNVALUE_NOERROR; } - if (Container* container = item->getContainer()) { - Container* openContainer; + if (std::shared_ptr container = item->getContainer()) { + std::shared_ptr openContainer; // depot container - if (DepotLocker* depot = container->getDepotLocker()) { - DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId()); + if (std::shared_ptr depot = container->getDepotLocker()) { + std::shared_ptr myDepotLocker = player->getDepotLocker(depot->getDepotId()); myDepotLocker->setParent(depot->getParent()->getTile()); openContainer = myDepotLocker; player->setLastDepotId(depot->getDepotId()); @@ -310,17 +310,17 @@ ReturnValue Actions::internalUseItem(Player* player, const Position &pos, uint8_ // reward chest if (container->getRewardChest() != nullptr && container->getParent()) { - RewardChest* myRewardChest = player->getRewardChest(); - if (myRewardChest->size() == 0) { + std::shared_ptr playerRewardChest = player->getRewardChest(); + if (playerRewardChest->empty()) { return RETURNVALUE_REWARDCHESTISEMPTY; } - myRewardChest->setParent(container->getParent()->getTile()); + playerRewardChest->setParent(container->getParent()->getTile()); for (const auto &[mapRewardId, reward] : player->rewardMap) { - reward->setParent(myRewardChest); + reward->setParent(playerRewardChest); } - openContainer = myRewardChest; + openContainer = playerRewardChest; } auto rewardId = container->getAttribute(ItemAttribute_t::DATE); @@ -383,7 +383,7 @@ ReturnValue Actions::internalUseItem(Player* player, const Position &pos, uint8_ return RETURNVALUE_CANNOTUSETHISOBJECT; } -bool Actions::useItem(Player* player, const Position &pos, uint8_t index, Item* item, bool isHotkey) { +bool Actions::useItem(std::shared_ptr player, const Position &pos, uint8_t index, std::shared_ptr item, bool isHotkey) { const ItemType &it = Item::items[item->getID()]; if (it.isRune() || it.type == ITEM_TYPE_POTION) { if (player->walkExhausted()) { @@ -415,7 +415,7 @@ bool Actions::useItem(Player* player, const Position &pos, uint8_t index, Item* return true; } -bool Actions::useItemEx(Player* player, const Position &fromPos, const Position &toPos, uint8_t toStackPos, Item* item, bool isHotkey, Creature* creature /* = nullptr*/) { +bool Actions::useItemEx(std::shared_ptr player, const Position &fromPos, const Position &toPos, uint8_t toStackPos, std::shared_ptr item, bool isHotkey, std::shared_ptr creature /* = nullptr*/) { const ItemType &it = Item::items[item->getID()]; if (it.isRune() || it.type == ITEM_TYPE_POTION) { if (player->walkExhausted()) { @@ -467,7 +467,7 @@ bool Actions::useItemEx(Player* player, const Position &fromPos, const Position return true; } -void Actions::showUseHotkeyMessage(Player* player, const Item* item, uint32_t count) { +void Actions::showUseHotkeyMessage(std::shared_ptr player, std::shared_ptr item, uint32_t count) { std::ostringstream ss; const ItemType &it = Item::items[item->getID()]; @@ -491,7 +491,7 @@ void Actions::showUseHotkeyMessage(Player* player, const Item* item, uint32_t co Action::Action(LuaScriptInterface* interface) : Script(interface) { } -ReturnValue Action::canExecuteAction(const Player* player, const Position &toPos) { +ReturnValue Action::canExecuteAction(std::shared_ptr player, const Position &toPos) { if (!allowFarUse) { return g_actions().canUse(player, toPos); } @@ -499,14 +499,14 @@ ReturnValue Action::canExecuteAction(const Player* player, const Position &toPos return g_actions().canUseFar(player, toPos, checkLineOfSight, checkFloor); } -Thing* Action::getTarget(Player* player, Creature* targetCreature, const Position &toPosition, uint8_t toStackPos) const { +std::shared_ptr Action::getTarget(std::shared_ptr player, std::shared_ptr targetCreature, const Position &toPosition, uint8_t toStackPos) const { if (targetCreature != nullptr) { return targetCreature; } return g_game().internalGetThing(player, toPosition, toStackPos, 0, STACKPOS_USETARGET); } -bool Action::executeUse(Player* player, Item* item, const Position &fromPosition, Thing* target, const Position &toPosition, bool isHotkey) { +bool Action::executeUse(std::shared_ptr player, std::shared_ptr item, const Position &fromPosition, std::shared_ptr target, const Position &toPosition, bool isHotkey) { // onUse(player, item, fromPosition, target, toPosition, isHotkey) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[Action::executeUse - Player {}, on item {}] " diff --git a/src/lua/creature/actions.hpp b/src/lua/creature/actions.hpp index b93dee55a..c0fb1a277 100644 --- a/src/lua/creature/actions.hpp +++ b/src/lua/creature/actions.hpp @@ -21,7 +21,7 @@ class Action : public Script { explicit Action(LuaScriptInterface* interface); // Scripting - virtual bool executeUse(Player* player, Item* item, const Position &fromPosition, Thing* target, const Position &toPosition, bool isHotkey); + virtual bool executeUse(std::shared_ptr player, std::shared_ptr item, const Position &fromPosition, std::shared_ptr target, const Position &toPosition, bool isHotkey); bool getAllowFarUse() const { return allowFarUse; @@ -96,13 +96,13 @@ class Action : public Script { positions.emplace_back(pos); } - virtual ReturnValue canExecuteAction(const Player* player, const Position &toPos); + virtual ReturnValue canExecuteAction(std::shared_ptr player, const Position &toPos); virtual bool hasOwnErrorHandler() { return false; } - virtual Thing* getTarget(Player* player, Creature* targetCreature, const Position &toPosition, uint8_t toStackPos) const; + virtual std::shared_ptr getTarget(std::shared_ptr player, std::shared_ptr targetCreature, const Position &toPosition, uint8_t toStackPos) const; private: std::string getScriptTypeName() const override { @@ -110,8 +110,8 @@ class Action : public Script { } std::function player, std::shared_ptr item, + const Position &fromPosition, std::shared_ptr target, const Position &toPosition, bool isHotkey )> useFunction = nullptr; @@ -143,12 +143,12 @@ class Actions final : public Scripts { return inject(); } - 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); + bool useItem(std::shared_ptr player, const Position &pos, uint8_t index, std::shared_ptr item, bool isHotkey); + bool useItemEx(std::shared_ptr player, const Position &fromPos, const Position &toPos, uint8_t toStackPos, std::shared_ptr item, bool isHotkey, std::shared_ptr creature = nullptr); - ReturnValue canUse(const Player* player, const Position &pos); - ReturnValue canUse(const Player* player, const Position &pos, const Item* item); - ReturnValue canUseFar(const Creature* creature, const Position &toPos, bool checkLineOfSight, bool checkFloor); + ReturnValue canUse(std::shared_ptr player, const Position &pos); + ReturnValue canUse(std::shared_ptr player, const Position &pos, std::shared_ptr item); + ReturnValue canUseFar(std::shared_ptr creature, const Position &toPos, bool checkLineOfSight, bool checkFloor); bool registerLuaItemEvent(const std::shared_ptr action); bool registerLuaUniqueEvent(const std::shared_ptr action); @@ -211,8 +211,8 @@ class Actions final : public Scripts { actionItemMap.try_emplace(actionId, action); } - ReturnValue internalUseItem(Player* player, const Position &pos, uint8_t index, Item* item, bool isHotkey); - static void showUseHotkeyMessage(Player* player, const Item* item, uint32_t count); + ReturnValue internalUseItem(std::shared_ptr player, const Position &pos, uint8_t index, std::shared_ptr item, bool isHotkey); + static void showUseHotkeyMessage(std::shared_ptr player, std::shared_ptr item, uint32_t count); using ActionUseMap = std::map>; ActionUseMap useItemMap; @@ -220,7 +220,7 @@ class Actions final : public Scripts { ActionUseMap actionItemMap; std::map> actionPositionMap; - std::shared_ptr getAction(const Item* item); + std::shared_ptr getAction(std::shared_ptr item); }; constexpr auto g_actions = Actions::getInstance; diff --git a/src/lua/creature/creatureevent.cpp b/src/lua/creature/creatureevent.cpp index 1480b5782..b1984be2f 100644 --- a/src/lua/creature/creatureevent.cpp +++ b/src/lua/creature/creatureevent.cpp @@ -55,7 +55,7 @@ std::shared_ptr CreatureEvents::getEventByName(const std::string return nullptr; } -bool CreatureEvents::playerLogin(Player* player) const { +bool CreatureEvents::playerLogin(std::shared_ptr player) const { // fire global event if is registered for (const auto &it : creatureEvents) { if (it.second->getEventType() == CREATURE_EVENT_LOGIN) { @@ -67,7 +67,7 @@ bool CreatureEvents::playerLogin(Player* player) const { return true; } -bool CreatureEvents::playerLogout(Player* player) const { +bool CreatureEvents::playerLogout(std::shared_ptr player) const { // fire global event if is registered for (const auto &it : creatureEvents) { if (it.second->getEventType() == CREATURE_EVENT_LOGOUT) { @@ -80,7 +80,7 @@ bool CreatureEvents::playerLogout(Player* player) const { } bool CreatureEvents::playerAdvance( - Player* player, + std::shared_ptr player, skills_t skill, uint32_t oldLevel, uint32_t newLevel @@ -171,7 +171,7 @@ void CreatureEvent::clearEvent() { loaded = false; } -bool CreatureEvent::executeOnLogin(Player* player) const { +bool CreatureEvent::executeOnLogin(std::shared_ptr player) const { // onLogin(player) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeOnLogin - Player {} event {}]" @@ -191,7 +191,7 @@ bool CreatureEvent::executeOnLogin(Player* player) const { return getScriptInterface()->callFunction(1); } -bool CreatureEvent::executeOnLogout(Player* player) const { +bool CreatureEvent::executeOnLogout(std::shared_ptr player) const { // onLogout(player) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeOnLogout - Player {} event {}] " @@ -211,7 +211,7 @@ bool CreatureEvent::executeOnLogout(Player* player) const { return getScriptInterface()->callFunction(1); } -bool CreatureEvent::executeOnThink(Creature* creature, uint32_t interval) const { +bool CreatureEvent::executeOnThink(std::shared_ptr creature, uint32_t interval) const { // onThink(creature, interval) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeOnThink - Creature {} event {}] " @@ -233,7 +233,7 @@ bool CreatureEvent::executeOnThink(Creature* creature, uint32_t interval) const return getScriptInterface()->callFunction(2); } -bool CreatureEvent::executeOnPrepareDeath(Creature* creature, Creature* killer) const { +bool CreatureEvent::executeOnPrepareDeath(std::shared_ptr creature, std::shared_ptr killer) const { // onPrepareDeath(creature, killer) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeOnPrepareDeath - Creature {} killer {}" @@ -262,7 +262,7 @@ bool CreatureEvent::executeOnPrepareDeath(Creature* creature, Creature* killer) return getScriptInterface()->callFunction(2); } -bool CreatureEvent::executeOnDeath(Creature* creature, Item* corpse, Creature* killer, Creature* mostDamageKiller, bool lastHitUnjustified, bool mostDamageUnjustified) const { +bool CreatureEvent::executeOnDeath(std::shared_ptr creature, std::shared_ptr corpse, std::shared_ptr killer, std::shared_ptr mostDamageKiller, bool lastHitUnjustified, bool mostDamageUnjustified) const { // onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeOnDeath - Creature {} killer {} event {}] " @@ -302,7 +302,7 @@ bool CreatureEvent::executeOnDeath(Creature* creature, Item* corpse, Creature* k return getScriptInterface()->callFunction(6); } -bool CreatureEvent::executeAdvance(Player* player, skills_t skill, uint32_t oldLevel, uint32_t newLevel) const { +bool CreatureEvent::executeAdvance(std::shared_ptr player, skills_t skill, uint32_t oldLevel, uint32_t newLevel) const { // onAdvance(player, skill, oldLevel, newLevel) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeAdvance - Player {} event {}] " @@ -326,7 +326,7 @@ bool CreatureEvent::executeAdvance(Player* player, skills_t skill, uint32_t oldL return getScriptInterface()->callFunction(4); } -void CreatureEvent::executeOnKill(Creature* creature, Creature* target, bool lastHit) const { +void CreatureEvent::executeOnKill(std::shared_ptr creature, std::shared_ptr target, bool lastHit) const { // onKill(creature, target, lastHit) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeOnKill - Creature {} target {} event {}] " @@ -349,7 +349,7 @@ void CreatureEvent::executeOnKill(Creature* creature, Creature* target, bool las getScriptInterface()->callVoidFunction(3); } -void CreatureEvent::executeModalWindow(Player* player, uint32_t modalWindowId, uint8_t buttonId, uint8_t choiceId) const { +void CreatureEvent::executeModalWindow(std::shared_ptr player, uint32_t modalWindowId, uint8_t buttonId, uint8_t choiceId) const { // onModalWindow(player, modalWindowId, buttonId, choiceId) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeModalWindow - " @@ -375,7 +375,7 @@ void CreatureEvent::executeModalWindow(Player* player, uint32_t modalWindowId, u getScriptInterface()->callVoidFunction(4); } -bool CreatureEvent::executeTextEdit(Player* player, Item* item, const std::string &text) const { +bool CreatureEvent::executeTextEdit(std::shared_ptr player, std::shared_ptr item, const std::string &text) const { // onTextEdit(player, item, text) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeTextEdit - Player {} event {}] " @@ -399,7 +399,7 @@ bool CreatureEvent::executeTextEdit(Player* player, Item* item, const std::strin return getScriptInterface()->callFunction(3); } -void CreatureEvent::executeHealthChange(Creature* creature, Creature* attacker, CombatDamage &damage) const { +void CreatureEvent::executeHealthChange(std::shared_ptr creature, std::shared_ptr attacker, CombatDamage &damage) const { // onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeHealthChange - " @@ -444,7 +444,7 @@ void CreatureEvent::executeHealthChange(Creature* creature, Creature* attacker, getScriptInterface()->resetScriptEnv(); } -void CreatureEvent::executeManaChange(Creature* creature, Creature* attacker, CombatDamage &damage) const { +void CreatureEvent::executeManaChange(std::shared_ptr creature, std::shared_ptr attacker, CombatDamage &damage) const { // onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeManaChange - " @@ -484,7 +484,7 @@ void CreatureEvent::executeManaChange(Creature* creature, Creature* attacker, Co getScriptInterface()->resetScriptEnv(); } -void CreatureEvent::executeExtendedOpcode(Player* player, uint8_t opcode, const std::string &buffer) const { +void CreatureEvent::executeExtendedOpcode(std::shared_ptr player, uint8_t opcode, const std::string &buffer) const { // onExtendedOpcode(player, opcode, buffer) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[CreatureEvent::executeExtendedOpcode - " diff --git a/src/lua/creature/creatureevent.hpp b/src/lua/creature/creatureevent.hpp index 06dbb7293..24052aa84 100644 --- a/src/lua/creature/creatureevent.hpp +++ b/src/lua/creature/creatureevent.hpp @@ -43,18 +43,18 @@ class CreatureEvent final : public Script { void copyEvent(const std::shared_ptr creatureEvent); // scripting - bool executeOnLogin(Player* player) const; - bool executeOnLogout(Player* player) const; - bool executeOnThink(Creature* creature, uint32_t interval) const; - bool executeOnPrepareDeath(Creature* creature, Creature* killer) const; - bool executeOnDeath(Creature* creature, Item* corpse, Creature* killer, Creature* mostDamageKiller, bool lastHitUnjustified, bool mostDamageUnjustified) const; - void executeOnKill(Creature* creature, Creature* target, bool lastHit) const; - bool executeAdvance(Player* player, skills_t, uint32_t, uint32_t) const; - void executeModalWindow(Player* player, uint32_t modalWindowId, uint8_t buttonId, uint8_t choiceId) const; - bool executeTextEdit(Player* player, Item* item, const std::string &text) const; - void executeHealthChange(Creature* creature, Creature* attacker, CombatDamage &damage) const; - void executeManaChange(Creature* creature, Creature* attacker, CombatDamage &damage) const; - void executeExtendedOpcode(Player* player, uint8_t opcode, const std::string &buffer) const; + bool executeOnLogin(std::shared_ptr player) const; + bool executeOnLogout(std::shared_ptr player) const; + bool executeOnThink(std::shared_ptr creature, uint32_t interval) const; + bool executeOnPrepareDeath(std::shared_ptr creature, std::shared_ptr killer) const; + bool executeOnDeath(std::shared_ptr creature, std::shared_ptr corpse, std::shared_ptr killer, std::shared_ptr mostDamageKiller, bool lastHitUnjustified, bool mostDamageUnjustified) const; + void executeOnKill(std::shared_ptr creature, std::shared_ptr target, bool lastHit) const; + bool executeAdvance(std::shared_ptr player, skills_t, uint32_t, uint32_t) const; + void executeModalWindow(std::shared_ptr player, uint32_t modalWindowId, uint8_t buttonId, uint8_t choiceId) const; + bool executeTextEdit(std::shared_ptr player, std::shared_ptr item, const std::string &text) const; + void executeHealthChange(std::shared_ptr creature, std::shared_ptr attacker, CombatDamage &damage) const; + void executeManaChange(std::shared_ptr creature, std::shared_ptr attacker, CombatDamage &damage) const; + void executeExtendedOpcode(std::shared_ptr player, uint8_t opcode, const std::string &buffer) const; // private: @@ -78,9 +78,9 @@ class CreatureEvents final : public Scripts { } // global events - bool playerLogin(Player* player) const; - bool playerLogout(Player* player) const; - bool playerAdvance(Player* player, skills_t, uint32_t, uint32_t) const; + bool playerLogin(std::shared_ptr player) const; + bool playerLogout(std::shared_ptr player) const; + bool playerAdvance(std::shared_ptr player, skills_t, uint32_t, uint32_t) const; std::shared_ptr getEventByName(const std::string &name, bool forceLoaded = true); diff --git a/src/lua/creature/events.cpp b/src/lua/creature/events.cpp index 1625e50fd..176044d66 100644 --- a/src/lua/creature/events.cpp +++ b/src/lua/creature/events.cpp @@ -150,7 +150,7 @@ bool Events::loadFromXml() { } // Monster -void Events::eventMonsterOnSpawn(Monster* monster, const Position &position) { +void Events::eventMonsterOnSpawn(std::shared_ptr monster, const Position &position) { // Monster:onSpawn(position) or Monster.onSpawn(self, position) if (info.monsterOnSpawn == -1) { return; @@ -184,7 +184,7 @@ void Events::eventMonsterOnSpawn(Monster* monster, const Position &position) { } // Npc -void Events::eventNpcOnSpawn(Npc* npc, const Position &position) { +void Events::eventNpcOnSpawn(std::shared_ptr npc, const Position &position) { // Npc:onSpawn(position) or Npc.onSpawn(self, position) if (info.npcOnSpawn == -1) { return; @@ -218,7 +218,7 @@ void Events::eventNpcOnSpawn(Npc* npc, const Position &position) { } // Creature -bool Events::eventCreatureOnChangeOutfit(Creature* creature, const Outfit_t &outfit) { +bool Events::eventCreatureOnChangeOutfit(std::shared_ptr creature, const Outfit_t &outfit) { // Creature:onChangeOutfit(outfit) or Creature.onChangeOutfit(self, outfit) if (info.creatureOnChangeOutfit == -1) { return true; @@ -245,7 +245,7 @@ bool Events::eventCreatureOnChangeOutfit(Creature* creature, const Outfit_t &out return scriptInterface.callFunction(2); } -ReturnValue Events::eventCreatureOnAreaCombat(Creature* creature, Tile* tile, bool aggressive) { +ReturnValue Events::eventCreatureOnAreaCombat(std::shared_ptr creature, std::shared_ptr tile, bool aggressive) { // Creature:onAreaCombat(tile, aggressive) or Creature.onAreaCombat(self, tile, aggressive) if (info.creatureOnAreaCombat == -1) { return RETURNVALUE_NOERROR; @@ -290,7 +290,7 @@ ReturnValue Events::eventCreatureOnAreaCombat(Creature* creature, Tile* tile, bo return returnValue; } -ReturnValue Events::eventCreatureOnTargetCombat(Creature* creature, Creature* target) { +ReturnValue Events::eventCreatureOnTargetCombat(std::shared_ptr creature, std::shared_ptr target) { // Creature:onTargetCombat(target) or Creature.onTargetCombat(self, target) if (info.creatureOnTargetCombat == -1) { return RETURNVALUE_NOERROR; @@ -333,7 +333,7 @@ ReturnValue Events::eventCreatureOnTargetCombat(Creature* creature, Creature* ta return returnValue; } -void Events::eventCreatureOnHear(Creature* creature, Creature* speaker, const std::string &words, SpeakClasses type) { +void Events::eventCreatureOnHear(std::shared_ptr creature, std::shared_ptr speaker, const std::string &words, SpeakClasses type) { // Creature:onHear(speaker, words, type) if (info.creatureOnHear == -1) { return; @@ -365,7 +365,7 @@ void Events::eventCreatureOnHear(Creature* creature, Creature* speaker, const st scriptInterface.callVoidFunction(4); } -void Events::eventCreatureOnDrainHealth(Creature* creature, Creature* attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) { +void Events::eventCreatureOnDrainHealth(std::shared_ptr creature, std::shared_ptr attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) { if (info.creatureOnDrainHealth == -1) { return; } @@ -421,7 +421,7 @@ void Events::eventCreatureOnDrainHealth(Creature* creature, Creature* attacker, } // Party -bool Events::eventPartyOnJoin(Party* party, Player* player) { +bool Events::eventPartyOnJoin(std::shared_ptr party, std::shared_ptr player) { // Party:onJoin(player) or Party.onJoin(self, player) if (info.partyOnJoin == -1) { return true; @@ -450,7 +450,7 @@ bool Events::eventPartyOnJoin(Party* party, Player* player) { return scriptInterface.callFunction(2); } -bool Events::eventPartyOnLeave(Party* party, Player* player) { +bool Events::eventPartyOnLeave(std::shared_ptr party, std::shared_ptr player) { // Party:onLeave(player) or Party.onLeave(self, player) if (info.partyOnLeave == -1) { return true; @@ -479,7 +479,7 @@ bool Events::eventPartyOnLeave(Party* party, Player* player) { return scriptInterface.callFunction(2); } -bool Events::eventPartyOnDisband(Party* party) { +bool Events::eventPartyOnDisband(std::shared_ptr party) { // Party:onDisband() or Party.onDisband(self) if (info.partyOnDisband == -1) { return true; @@ -488,7 +488,7 @@ bool Events::eventPartyOnDisband(Party* party) { if (!scriptInterface.reserveScriptEnv()) { g_logger().error("[Events::eventPartyOnDisband - Party leader {}] Call stack " "overflow. Too many lua script calls being nested.", - party->getLeader()->getName()); + party->getLeader() ? party->getLeader()->getName() : "unknown"); return false; } @@ -504,14 +504,14 @@ bool Events::eventPartyOnDisband(Party* party) { return scriptInterface.callFunction(1); } -void Events::eventPartyOnShareExperience(Party* party, uint64_t &exp) { +void Events::eventPartyOnShareExperience(std::shared_ptr party, uint64_t &exp) { // Party:onShareExperience(exp) or Party.onShareExperience(self, exp) if (info.partyOnShareExperience == -1) { return; } if (!scriptInterface.reserveScriptEnv()) { - g_logger().error("Party leader {}. Call stack overflow. Too many lua script calls being nested.", party->getLeader()->getName()); + g_logger().error("Party leader {}. Call stack overflow. Too many lua script calls being nested.", party->getLeader() ? party->getLeader()->getName() : "unknown"); return; } @@ -537,7 +537,7 @@ void Events::eventPartyOnShareExperience(Party* party, uint64_t &exp) { } // Player -bool Events::eventPlayerOnBrowseField(Player* player, const Position &position) { +bool Events::eventPlayerOnBrowseField(std::shared_ptr player, const Position &position) { // Player:onBrowseField(position) or Player.onBrowseField(self, position) if (info.playerOnBrowseField == -1) { return true; @@ -565,7 +565,7 @@ bool Events::eventPlayerOnBrowseField(Player* player, const Position &position) return scriptInterface.callFunction(2); } -void Events::eventPlayerOnLook(Player* player, const Position &position, Thing* thing, uint8_t stackpos, int32_t lookDistance) { +void Events::eventPlayerOnLook(std::shared_ptr player, const Position &position, std::shared_ptr thing, uint8_t stackpos, int32_t lookDistance) { // Player:onLook(thing, position, distance) or Player.onLook(self, thing, position, distance) if (info.playerOnLook == -1) { return; @@ -588,10 +588,10 @@ void Events::eventPlayerOnLook(Player* player, const Position &position, Thing* LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); - if (Creature* creature = thing->getCreature()) { + if (std::shared_ptr creature = thing->getCreature()) { LuaScriptInterface::pushUserdata(L, creature); LuaScriptInterface::setCreatureMetatable(L, -1, creature); - } else if (Item* item = thing->getItem()) { + } else if (std::shared_ptr item = thing->getItem()) { LuaScriptInterface::pushUserdata(L, item); LuaScriptInterface::setItemMetatable(L, -1, item); } else { @@ -604,7 +604,7 @@ void Events::eventPlayerOnLook(Player* player, const Position &position, Thing* scriptInterface.callVoidFunction(4); } -void Events::eventPlayerOnLookInBattleList(Player* player, Creature* creature, int32_t lookDistance) { +void Events::eventPlayerOnLookInBattleList(std::shared_ptr player, std::shared_ptr creature, int32_t lookDistance) { // Player:onLookInBattleList(creature, position, distance) or Player.onLookInBattleList(self, creature, position, distance) if (info.playerOnLookInBattleList == -1) { return; @@ -635,7 +635,7 @@ void Events::eventPlayerOnLookInBattleList(Player* player, Creature* creature, i scriptInterface.callVoidFunction(3); } -void Events::eventPlayerOnLookInTrade(Player* player, Player* partner, Item* item, int32_t lookDistance) { +void Events::eventPlayerOnLookInTrade(std::shared_ptr player, std::shared_ptr partner, std::shared_ptr item, int32_t lookDistance) { // Player:onLookInTrade(partner, item, distance) or Player.onLookInTrade(self, partner, item, distance) if (info.playerOnLookInTrade == -1) { return; @@ -669,7 +669,7 @@ void Events::eventPlayerOnLookInTrade(Player* player, Player* partner, Item* ite scriptInterface.callVoidFunction(4); } -bool Events::eventPlayerOnLookInShop(Player* player, const ItemType* itemType, uint8_t count) { +bool Events::eventPlayerOnLookInShop(std::shared_ptr player, const ItemType* itemType, uint8_t count) { // Player:onLookInShop(itemType, count) or Player.onLookInShop(self, itemType, count) if (info.playerOnLookInShop == -1) { return true; @@ -700,7 +700,7 @@ bool Events::eventPlayerOnLookInShop(Player* player, const ItemType* itemType, u return scriptInterface.callFunction(3); } -bool Events::eventPlayerOnRemoveCount(Player* player, Item* item) { +bool Events::eventPlayerOnRemoveCount(std::shared_ptr player, std::shared_ptr item) { // Player:onMove() if (info.playerOnRemoveCount == -1) { return true; @@ -729,7 +729,7 @@ bool Events::eventPlayerOnRemoveCount(Player* player, Item* item) { return scriptInterface.callFunction(2); } -bool Events::eventPlayerOnMoveItem(Player* player, Item* item, uint16_t count, const Position &fromPosition, const Position &toPosition, Cylinder* fromCylinder, Cylinder* toCylinder) { +bool Events::eventPlayerOnMoveItem(std::shared_ptr player, std::shared_ptr item, uint16_t count, const Position &fromPosition, const Position &toPosition, std::shared_ptr fromCylinder, std::shared_ptr toCylinder) { // Player:onMoveItem(item, count, fromPosition, toPosition) or Player.onMoveItem(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder) if (info.playerOnMoveItem == -1) { return true; @@ -765,7 +765,7 @@ bool Events::eventPlayerOnMoveItem(Player* player, Item* item, uint16_t count, c return scriptInterface.callFunction(7); } -void Events::eventPlayerOnItemMoved(Player* player, Item* item, uint16_t count, const Position &fromPosition, const Position &toPosition, Cylinder* fromCylinder, Cylinder* toCylinder) { +void Events::eventPlayerOnItemMoved(std::shared_ptr player, std::shared_ptr item, uint16_t count, const Position &fromPosition, const Position &toPosition, std::shared_ptr fromCylinder, std::shared_ptr toCylinder) { // Player:onItemMoved(item, count, fromPosition, toPosition) or Player.onItemMoved(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder) if (info.playerOnItemMoved == -1) { return; @@ -801,7 +801,7 @@ void Events::eventPlayerOnItemMoved(Player* player, Item* item, uint16_t count, scriptInterface.callVoidFunction(7); } -void Events::eventPlayerOnChangeZone(Player* player, ZoneType_t zone) { +void Events::eventPlayerOnChangeZone(std::shared_ptr player, ZoneType_t zone) { // Player:onChangeZone(zone) if (info.playerOnChangeZone == -1) { return; @@ -828,7 +828,7 @@ void Events::eventPlayerOnChangeZone(Player* player, ZoneType_t zone) { scriptInterface.callVoidFunction(2); } -bool Events::eventPlayerOnMoveCreature(Player* player, Creature* creature, const Position &fromPosition, const Position &toPosition) { +bool Events::eventPlayerOnMoveCreature(std::shared_ptr player, std::shared_ptr creature, const Position &fromPosition, const Position &toPosition) { // Player:onMoveCreature(creature, fromPosition, toPosition) or Player.onMoveCreature(self, creature, fromPosition, toPosition) if (info.playerOnMoveCreature == -1) { return true; @@ -860,7 +860,7 @@ bool Events::eventPlayerOnMoveCreature(Player* player, Creature* creature, const return scriptInterface.callFunction(4); } -void Events::eventPlayerOnReportRuleViolation(Player* player, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation) { +void Events::eventPlayerOnReportRuleViolation(std::shared_ptr player, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation) { // Player:onReportRuleViolation(targetName, reportType, reportReason, comment, translation) if (info.playerOnReportRuleViolation == -1) { return; @@ -894,7 +894,7 @@ void Events::eventPlayerOnReportRuleViolation(Player* player, const std::string scriptInterface.callVoidFunction(6); } -bool Events::eventPlayerOnReportBug(Player* player, const std::string &message, const Position &position, uint8_t category) { +bool Events::eventPlayerOnReportBug(std::shared_ptr player, const std::string &message, const Position &position, uint8_t category) { // Player:onReportBug(message, position, category) if (info.playerOnReportBug == -1) { return true; @@ -924,7 +924,7 @@ bool Events::eventPlayerOnReportBug(Player* player, const std::string &message, return scriptInterface.callFunction(4); } -bool Events::eventPlayerOnTurn(Player* player, Direction direction) { +bool Events::eventPlayerOnTurn(std::shared_ptr player, Direction direction) { // Player:onTurn(direction) or Player.onTurn(self, direction) if (info.playerOnTurn == -1) { return true; @@ -952,7 +952,7 @@ bool Events::eventPlayerOnTurn(Player* player, Direction direction) { return scriptInterface.callFunction(2); } -bool Events::eventPlayerOnTradeRequest(Player* player, Player* target, Item* item) { +bool Events::eventPlayerOnTradeRequest(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item) { // Player:onTradeRequest(target, item) if (info.playerOnTradeRequest == -1) { return true; @@ -984,7 +984,7 @@ bool Events::eventPlayerOnTradeRequest(Player* player, Player* target, Item* ite return scriptInterface.callFunction(3); } -bool Events::eventPlayerOnTradeAccept(Player* player, Player* target, Item* item, Item* targetItem) { +bool Events::eventPlayerOnTradeAccept(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, std::shared_ptr targetItem) { // Player:onTradeAccept(target, item, targetItem) if (info.playerOnTradeAccept == -1) { return true; @@ -1019,7 +1019,7 @@ bool Events::eventPlayerOnTradeAccept(Player* player, Player* target, Item* item return scriptInterface.callFunction(4); } -void Events::eventPlayerOnGainExperience(Player* player, Creature* target, uint64_t &exp, uint64_t rawExp) { +void Events::eventPlayerOnGainExperience(std::shared_ptr player, std::shared_ptr target, uint64_t &exp, uint64_t rawExp) { // Player:onGainExperience(target, exp, rawExp) // rawExp gives the original exp which is not multiplied if (info.playerOnGainExperience == -1) { @@ -1063,7 +1063,7 @@ void Events::eventPlayerOnGainExperience(Player* player, Creature* target, uint6 scriptInterface.resetScriptEnv(); } -void Events::eventPlayerOnLoseExperience(Player* player, uint64_t &exp) { +void Events::eventPlayerOnLoseExperience(std::shared_ptr player, uint64_t &exp) { // Player:onLoseExperience(exp) if (info.playerOnLoseExperience == -1) { return; @@ -1098,7 +1098,7 @@ void Events::eventPlayerOnLoseExperience(Player* player, uint64_t &exp) { scriptInterface.resetScriptEnv(); } -void Events::eventPlayerOnGainSkillTries(Player* player, skills_t skill, uint64_t &tries) { +void Events::eventPlayerOnGainSkillTries(std::shared_ptr player, skills_t skill, uint64_t &tries) { // Player:onGainSkillTries(skill, tries) if (info.playerOnGainSkillTries == -1) { return; @@ -1134,7 +1134,7 @@ void Events::eventPlayerOnGainSkillTries(Player* player, skills_t skill, uint64_ scriptInterface.resetScriptEnv(); } -void Events::eventPlayerOnCombat(Player* player, Creature* target, Item* item, CombatDamage &damage) { +void Events::eventPlayerOnCombat(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, CombatDamage &damage) { // Player:onCombat(target, item, primaryDamage, primaryType, secondaryDamage, secondaryType) if (info.playerOnCombat == -1) { return; @@ -1191,7 +1191,7 @@ void Events::eventPlayerOnCombat(Player* player, Creature* target, Item* item, C scriptInterface.resetScriptEnv(); } -void Events::eventPlayerOnRequestQuestLog(Player* player) { +void Events::eventPlayerOnRequestQuestLog(std::shared_ptr player) { // Player:onRequestQuestLog() if (info.playerOnRequestQuestLog == -1) { return; @@ -1217,7 +1217,7 @@ void Events::eventPlayerOnRequestQuestLog(Player* player) { scriptInterface.callVoidFunction(1); } -void Events::eventPlayerOnRequestQuestLine(Player* player, uint16_t questId) { +void Events::eventPlayerOnRequestQuestLine(std::shared_ptr player, uint16_t questId) { // Player::onRequestQuestLine() if (info.playerOnRequestQuestLine == -1) { return; @@ -1245,7 +1245,7 @@ void Events::eventPlayerOnRequestQuestLine(Player* player, uint16_t questId) { scriptInterface.callVoidFunction(2); } -void Events::eventPlayerOnInventoryUpdate(Player* player, Item* item, Slots_t slot, bool equip) { +void Events::eventPlayerOnInventoryUpdate(std::shared_ptr player, std::shared_ptr item, Slots_t slot, bool equip) { // Player:onInventoryUpdate(item, slot, equip) if (info.playerOnInventoryUpdate == -1) { return; @@ -1274,7 +1274,7 @@ void Events::eventPlayerOnInventoryUpdate(Player* player, Item* item, Slots_t sl scriptInterface.callVoidFunction(4); } -void Events::eventOnStorageUpdate(Player* player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime) { +void Events::eventOnStorageUpdate(std::shared_ptr player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime) { // Player::onStorageUpdate(key, value, oldValue, currentTime) if (info.playerOnStorageUpdate == -1) { return; @@ -1306,7 +1306,7 @@ void Events::eventOnStorageUpdate(Player* player, const uint32_t key, const int3 } // Monster -void Events::eventMonsterOnDropLoot(Monster* monster, Container* corpse) { +void Events::eventMonsterOnDropLoot(std::shared_ptr monster, std::shared_ptr corpse) { // Monster:onDropLoot(corpse) if (info.monsterOnDropLoot == -1) { return; diff --git a/src/lua/creature/events.hpp b/src/lua/creature/events.hpp index ef09e438d..08260c8ae 100644 --- a/src/lua/creature/events.hpp +++ b/src/lua/creature/events.hpp @@ -81,49 +81,49 @@ class Events { } // Creature - bool eventCreatureOnChangeOutfit(Creature* creature, const Outfit_t &outfit); - ReturnValue eventCreatureOnAreaCombat(Creature* creature, Tile* tile, bool aggressive); - ReturnValue eventCreatureOnTargetCombat(Creature* creature, Creature* target); - void eventCreatureOnHear(Creature* creature, Creature* speaker, const std::string &words, SpeakClasses type); - void eventCreatureOnDrainHealth(Creature* creature, Creature* attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary); + bool eventCreatureOnChangeOutfit(std::shared_ptr creature, const Outfit_t &outfit); + ReturnValue eventCreatureOnAreaCombat(std::shared_ptr creature, std::shared_ptr tile, bool aggressive); + ReturnValue eventCreatureOnTargetCombat(std::shared_ptr creature, std::shared_ptr target); + void eventCreatureOnHear(std::shared_ptr creature, std::shared_ptr speaker, const std::string &words, SpeakClasses type); + void eventCreatureOnDrainHealth(std::shared_ptr creature, std::shared_ptr attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary); // Party - bool eventPartyOnJoin(Party* party, Player* player); - bool eventPartyOnLeave(Party* party, Player* player); - bool eventPartyOnDisband(Party* party); - void eventPartyOnShareExperience(Party* party, uint64_t &exp); + bool eventPartyOnJoin(std::shared_ptr party, std::shared_ptr player); + bool eventPartyOnLeave(std::shared_ptr party, std::shared_ptr player); + bool eventPartyOnDisband(std::shared_ptr party); + void eventPartyOnShareExperience(std::shared_ptr party, uint64_t &exp); // Player - bool eventPlayerOnBrowseField(Player* player, const Position &position); - void eventPlayerOnLook(Player* player, const Position &position, Thing* thing, uint8_t stackpos, int32_t lookDistance); - void eventPlayerOnLookInBattleList(Player* player, Creature* creature, int32_t lookDistance); - void eventPlayerOnLookInTrade(Player* player, Player* partner, Item* item, int32_t lookDistance); - bool eventPlayerOnLookInShop(Player* player, const ItemType* itemType, uint8_t count); - bool eventPlayerOnMoveItem(Player* player, Item* item, uint16_t count, const Position &fromPosition, const Position &toPosition, Cylinder* fromCylinder, Cylinder* toCylinder); - void eventPlayerOnItemMoved(Player* player, Item* item, uint16_t count, const Position &fromPosition, const Position &toPosition, Cylinder* fromCylinder, Cylinder* toCylinder); - void eventPlayerOnChangeZone(Player* player, ZoneType_t zone); - bool eventPlayerOnMoveCreature(Player* player, Creature* creature, const Position &fromPosition, const Position &toPosition); - void eventPlayerOnReportRuleViolation(Player* player, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation); - bool eventPlayerOnReportBug(Player* player, const std::string &message, const Position &position, uint8_t category); - bool eventPlayerOnTurn(Player* player, Direction direction); - bool eventPlayerOnTradeRequest(Player* player, Player* target, Item* item); - bool eventPlayerOnTradeAccept(Player* player, Player* target, Item* item, Item* targetItem); - void eventPlayerOnGainExperience(Player* player, Creature* target, uint64_t &exp, uint64_t rawExp); - void eventPlayerOnLoseExperience(Player* player, uint64_t &exp); - void eventPlayerOnGainSkillTries(Player* player, skills_t skill, uint64_t &tries); - bool eventPlayerOnRemoveCount(Player* player, Item* item); - void eventPlayerOnRequestQuestLog(Player* player); - void eventPlayerOnRequestQuestLine(Player* player, uint16_t questId); - void eventOnStorageUpdate(Player* player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime); - void eventPlayerOnCombat(Player* player, Creature* target, Item* item, CombatDamage &damage); - void eventPlayerOnInventoryUpdate(Player* player, Item* item, Slots_t slot, bool equip); + bool eventPlayerOnBrowseField(std::shared_ptr player, const Position &position); + void eventPlayerOnLook(std::shared_ptr player, const Position &position, std::shared_ptr thing, uint8_t stackpos, int32_t lookDistance); + void eventPlayerOnLookInBattleList(std::shared_ptr player, std::shared_ptr creature, int32_t lookDistance); + void eventPlayerOnLookInTrade(std::shared_ptr player, std::shared_ptr partner, std::shared_ptr item, int32_t lookDistance); + bool eventPlayerOnLookInShop(std::shared_ptr player, const ItemType* itemType, uint8_t count); + bool eventPlayerOnMoveItem(std::shared_ptr player, std::shared_ptr item, uint16_t count, const Position &fromPosition, const Position &toPosition, std::shared_ptr fromCylinder, std::shared_ptr toCylinder); + void eventPlayerOnItemMoved(std::shared_ptr player, std::shared_ptr item, uint16_t count, const Position &fromPosition, const Position &toPosition, std::shared_ptr fromCylinder, std::shared_ptr toCylinder); + void eventPlayerOnChangeZone(std::shared_ptr player, ZoneType_t zone); + bool eventPlayerOnMoveCreature(std::shared_ptr player, std::shared_ptr creature, const Position &fromPosition, const Position &toPosition); + void eventPlayerOnReportRuleViolation(std::shared_ptr player, const std::string &targetName, uint8_t reportType, uint8_t reportReason, const std::string &comment, const std::string &translation); + bool eventPlayerOnReportBug(std::shared_ptr player, const std::string &message, const Position &position, uint8_t category); + bool eventPlayerOnTurn(std::shared_ptr player, Direction direction); + bool eventPlayerOnTradeRequest(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item); + bool eventPlayerOnTradeAccept(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, std::shared_ptr targetItem); + void eventPlayerOnGainExperience(std::shared_ptr player, std::shared_ptr target, uint64_t &exp, uint64_t rawExp); + void eventPlayerOnLoseExperience(std::shared_ptr player, uint64_t &exp); + void eventPlayerOnGainSkillTries(std::shared_ptr player, skills_t skill, uint64_t &tries); + bool eventPlayerOnRemoveCount(std::shared_ptr player, std::shared_ptr item); + void eventPlayerOnRequestQuestLog(std::shared_ptr player); + void eventPlayerOnRequestQuestLine(std::shared_ptr player, uint16_t questId); + void eventOnStorageUpdate(std::shared_ptr player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime); + void eventPlayerOnCombat(std::shared_ptr player, std::shared_ptr target, std::shared_ptr item, CombatDamage &damage); + void eventPlayerOnInventoryUpdate(std::shared_ptr player, std::shared_ptr item, Slots_t slot, bool equip); // Monster - void eventMonsterOnDropLoot(Monster* monster, Container* corpse); - void eventMonsterOnSpawn(Monster* monster, const Position &position); + void eventMonsterOnDropLoot(std::shared_ptr monster, std::shared_ptr corpse); + void eventMonsterOnSpawn(std::shared_ptr monster, const Position &position); // Monster - void eventNpcOnSpawn(Npc* npc, const Position &position); + void eventNpcOnSpawn(std::shared_ptr npc, const Position &position); private: LuaScriptInterface scriptInterface; diff --git a/src/lua/creature/movement.cpp b/src/lua/creature/movement.cpp index 929451189..a011c3234 100644 --- a/src/lua/creature/movement.cpp +++ b/src/lua/creature/movement.cpp @@ -147,7 +147,7 @@ bool MoveEvents::registerEvent(const std::shared_ptr moveEvent, int32 } } -std::shared_ptr MoveEvents::getEvent(Item &item, MoveEvent_t eventType, Slots_t slot) { +std::shared_ptr MoveEvents::getEvent(const std::shared_ptr &item, MoveEvent_t eventType, Slots_t slot) { uint32_t slotp; switch (slot) { case CONST_SLOT_HEAD: @@ -185,8 +185,8 @@ std::shared_ptr MoveEvents::getEvent(Item &item, MoveEvent_t eventTyp break; } - if (item.hasAttribute(ItemAttribute_t::ACTIONID)) { - std::map::iterator it = actionIdMap.find(item.getAttribute(ItemAttribute_t::ACTIONID)); + if (item->hasAttribute(ItemAttribute_t::ACTIONID)) { + std::map::iterator it = actionIdMap.find(item->getAttribute(ItemAttribute_t::ACTIONID)); if (it != actionIdMap.end()) { std::list> moveEventList = it->second.moveEvent[eventType]; for (const auto &moveEvent : moveEventList) { @@ -197,7 +197,7 @@ std::shared_ptr MoveEvents::getEvent(Item &item, MoveEvent_t eventTyp } } - auto it = itemIdMap.find(item.getID()); + auto it = itemIdMap.find(item->getID()); if (it != itemIdMap.end()) { std::list> &moveEventList = it->second.moveEvent[eventType]; for (const auto &moveEvent : moveEventList) { @@ -209,10 +209,10 @@ std::shared_ptr MoveEvents::getEvent(Item &item, MoveEvent_t eventTyp return nullptr; } -std::shared_ptr MoveEvents::getEvent(Item &item, MoveEvent_t eventType) { +std::shared_ptr MoveEvents::getEvent(const std::shared_ptr &item, MoveEvent_t eventType) { std::map::iterator it; - if (item.hasAttribute(ItemAttribute_t::UNIQUEID)) { - it = uniqueIdMap.find(item.getAttribute(ItemAttribute_t::UNIQUEID)); + if (item->hasAttribute(ItemAttribute_t::UNIQUEID)) { + it = uniqueIdMap.find(item->getAttribute(ItemAttribute_t::UNIQUEID)); if (it != uniqueIdMap.end()) { std::list> &moveEventList = it->second.moveEvent[eventType]; if (!moveEventList.empty()) { @@ -221,8 +221,8 @@ std::shared_ptr MoveEvents::getEvent(Item &item, MoveEvent_t eventTyp } } - if (item.hasAttribute(ItemAttribute_t::ACTIONID)) { - it = actionIdMap.find(item.getAttribute(ItemAttribute_t::ACTIONID)); + if (item->hasAttribute(ItemAttribute_t::ACTIONID)) { + it = actionIdMap.find(item->getAttribute(ItemAttribute_t::ACTIONID)); if (it != actionIdMap.end()) { std::list> &moveEventList = it->second.moveEvent[eventType]; if (!moveEventList.empty()) { @@ -231,7 +231,7 @@ std::shared_ptr MoveEvents::getEvent(Item &item, MoveEvent_t eventTyp } } - it = itemIdMap.find(item.getID()); + it = itemIdMap.find(item->getID()); if (it != itemIdMap.end()) { std::list> &moveEventList = it->second.moveEvent[eventType]; if (!moveEventList.empty()) { @@ -265,8 +265,8 @@ bool MoveEvents::registerEvent(const std::shared_ptr moveEvent, const } } -std::shared_ptr MoveEvents::getEvent(Tile &tile, MoveEvent_t eventType) { - if (auto it = positionsMap.find(tile.getPosition()); +std::shared_ptr MoveEvents::getEvent(const std::shared_ptr &tile, MoveEvent_t eventType) { + if (auto it = positionsMap.find(tile->getPosition()); it != positionsMap.end()) { std::list> &moveEventList = it->second.moveEvent[eventType]; if (!moveEventList.empty()) { @@ -276,8 +276,8 @@ std::shared_ptr MoveEvents::getEvent(Tile &tile, MoveEvent_t eventTyp return nullptr; } -uint32_t MoveEvents::onCreatureMove(Creature &creature, Tile &tile, MoveEvent_t eventType) { - const Position &pos = tile.getPosition(); +uint32_t MoveEvents::onCreatureMove(const std::shared_ptr &creature, const std::shared_ptr &tile, MoveEvent_t eventType) { + const Position &pos = tile->getPosition(); uint32_t ret = 1; @@ -286,18 +286,18 @@ uint32_t MoveEvents::onCreatureMove(Creature &creature, Tile &tile, MoveEvent_t ret &= moveEvent->fireStepEvent(creature, nullptr, pos); } - for (size_t i = tile.getFirstIndex(), j = tile.getLastIndex(); i < j; ++i) { - Thing* thing = tile.getThing(i); + for (size_t i = tile->getFirstIndex(), j = tile->getLastIndex(); i < j; ++i) { + std::shared_ptr thing = tile->getThing(i); if (!thing) { continue; } - Item* tileItem = thing->getItem(); + std::shared_ptr tileItem = thing->getItem(); if (!tileItem) { continue; } - moveEvent = getEvent(*tileItem, eventType); + moveEvent = getEvent(tileItem, eventType); if (moveEvent) { auto step = moveEvent->fireStepEvent(creature, tileItem, pos); // If there is any problem in the function, we will kill the loop @@ -310,27 +310,27 @@ uint32_t MoveEvents::onCreatureMove(Creature &creature, Tile &tile, MoveEvent_t return ret; } -uint32_t MoveEvents::onPlayerEquip(Player &player, Item &item, Slots_t slot, bool isCheck) { - const auto &moveEvent = getEvent(item, MOVE_EVENT_EQUIP, slot); +uint32_t MoveEvents::onPlayerEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot, bool isCheck) { + const auto moveEvent = getEvent(item, MOVE_EVENT_EQUIP, slot); if (!moveEvent) { return 1; } - g_events().eventPlayerOnInventoryUpdate(&player, &item, slot, true); - g_callbacks().executeCallback(EventCallback_t::playerOnInventoryUpdate, &EventCallback::playerOnInventoryUpdate, &player, &item, slot, true); + g_events().eventPlayerOnInventoryUpdate(player, item, slot, true); + g_callbacks().executeCallback(EventCallback_t::playerOnInventoryUpdate, &EventCallback::playerOnInventoryUpdate, player, item, slot, true); return moveEvent->fireEquip(player, item, slot, isCheck); } -uint32_t MoveEvents::onPlayerDeEquip(Player &player, Item &item, Slots_t slot) { - const auto &moveEvent = getEvent(item, MOVE_EVENT_DEEQUIP, slot); +uint32_t MoveEvents::onPlayerDeEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot) { + const auto moveEvent = getEvent(item, MOVE_EVENT_DEEQUIP, slot); if (!moveEvent) { return 1; } - g_events().eventPlayerOnInventoryUpdate(&player, &item, slot, false); - g_callbacks().executeCallback(EventCallback_t::playerOnInventoryUpdate, &EventCallback::playerOnInventoryUpdate, &player, &item, slot, false); + g_events().eventPlayerOnInventoryUpdate(player, item, slot, false); + g_callbacks().executeCallback(EventCallback_t::playerOnInventoryUpdate, &EventCallback::playerOnInventoryUpdate, player, item, slot, false); return moveEvent->fireEquip(player, item, slot, false); } -uint32_t MoveEvents::onItemMove(Item &item, Tile &tile, bool isAdd) { +uint32_t MoveEvents::onItemMove(const std::shared_ptr &item, const std::shared_ptr &tile, bool isAdd) { MoveEvent_t eventType1, eventType2; if (isAdd) { eventType1 = MOVE_EVENT_ADD_ITEM; @@ -344,29 +344,29 @@ uint32_t MoveEvents::onItemMove(Item &item, Tile &tile, bool isAdd) { auto moveEvent = getEvent(tile, eventType1); if (moveEvent) { // No tile item - ret &= moveEvent->fireAddRemItem(item, tile.getPosition()); + ret &= moveEvent->fireAddRemItem(item, tile->getPosition()); } moveEvent = getEvent(item, eventType1); if (moveEvent) { // No tile item - ret &= moveEvent->fireAddRemItem(item, tile.getPosition()); + ret &= moveEvent->fireAddRemItem(item, tile->getPosition()); } - for (size_t i = tile.getFirstIndex(), j = tile.getLastIndex(); i < j; ++i) { - Thing* thing = tile.getThing(i); + for (size_t i = tile->getFirstIndex(), j = tile->getLastIndex(); i < j; ++i) { + std::shared_ptr thing = tile->getThing(i); if (!thing) { continue; } - Item* tileItem = thing->getItem(); + std::shared_ptr tileItem = thing->getItem(); if (!tileItem) { continue; } - moveEvent = getEvent(*tileItem, eventType2); + moveEvent = getEvent(tileItem, eventType2); if (moveEvent) { - auto moveItem = moveEvent->fireAddRemItem(item, *tileItem, tile.getPosition()); + auto moveItem = moveEvent->fireAddRemItem(item, tileItem, tile->getPosition()); // If there is any problem in the function, we will kill the loop if (moveItem == 0) { break; @@ -409,7 +409,7 @@ std::string MoveEvent::getScriptTypeName() const { } } -uint32_t MoveEvent::StepInField(Creature* creature, Item* item, const Position &) { +uint32_t MoveEvent::StepInField(std::shared_ptr creature, std::shared_ptr item, const Position &) { if (creature == nullptr) { g_logger().error("[MoveEvent::StepInField] - Creature is nullptr"); return 0; @@ -420,27 +420,27 @@ uint32_t MoveEvent::StepInField(Creature* creature, Item* item, const Position & return 0; } - MagicField* field = item->getMagicField(); + std::shared_ptr field = item->getMagicField(); if (field) { - field->onStepInField(*creature); + field->onStepInField(creature); return 1; } return LUA_ERROR_ITEM_NOT_FOUND; } -uint32_t MoveEvent::StepOutField(Creature*, Item*, const Position &) { +uint32_t MoveEvent::StepOutField(std::shared_ptr, std::shared_ptr, const Position &) { return 1; } -uint32_t MoveEvent::AddItemField(Item* item, Item*, const Position &) { +uint32_t MoveEvent::AddItemField(std::shared_ptr item, std::shared_ptr, const Position &) { if (item == nullptr) { g_logger().error("[MoveEvent::AddItemField] - Item is nullptr"); return 0; } - if (MagicField* field = item->getMagicField()) { - Tile* tile = item->getTile(); + if (std::shared_ptr field = item->getMagicField()) { + std::shared_ptr tile = item->getTile(); if (tile == nullptr) { g_logger().debug("[MoveEvent::AddItemField] - Tile is nullptr"); return 0; @@ -450,24 +450,24 @@ uint32_t MoveEvent::AddItemField(Item* item, Item*, const Position &) { g_logger().debug("[MoveEvent::AddItemField] - Creatures is nullptr"); return 0; } - for (Creature* creature : *creatures) { + for (auto &creature : *creatures) { if (field == nullptr) { g_logger().debug("[MoveEvent::AddItemField] - MagicField is nullptr"); return 0; } - field->onStepInField(*creature); + field->onStepInField(creature); } return 1; } return LUA_ERROR_ITEM_NOT_FOUND; } -uint32_t MoveEvent::RemoveItemField(Item*, Item*, const Position &) { +uint32_t MoveEvent::RemoveItemField(std::shared_ptr, std::shared_ptr, const Position &) { return 1; } -uint32_t MoveEvent::EquipItem(const std::shared_ptr moveEvent, Player* player, Item* item, Slots_t slot, bool isCheck) { +uint32_t MoveEvent::EquipItem(const std::shared_ptr moveEvent, std::shared_ptr player, std::shared_ptr item, Slots_t slot, bool isCheck) { if (player == nullptr) { g_logger().error("[MoveEvent::EquipItem] - Player is nullptr"); return 0; @@ -520,24 +520,24 @@ uint32_t MoveEvent::EquipItem(const std::shared_ptr moveEvent, Player if (it.abilities) { if (it.abilities->invisible) { - Condition* condition = Condition::createCondition(static_cast(slot), CONDITION_INVISIBLE, -1, 0); + std::shared_ptr condition = Condition::createCondition(static_cast(slot), CONDITION_INVISIBLE, -1, 0); player->addCondition(condition); } if (it.abilities->manaShield) { - Condition* condition = Condition::createCondition(static_cast(slot), CONDITION_MANASHIELD, -1, 0); + std::shared_ptr condition = Condition::createCondition(static_cast(slot), CONDITION_MANASHIELD, -1, 0); player->addCondition(condition); } if (it.abilities->speed != 0) { - g_game().changePlayerSpeed(*player, it.abilities->speed); + g_game().changePlayerSpeed(player, it.abilities->speed); } player->addConditionSuppressions(it.abilities->conditionSuppressions); player->sendIcons(); if (it.abilities->regeneration) { - Condition* condition = Condition::createCondition(static_cast(slot), CONDITION_REGENERATION, -1, 0); + std::shared_ptr condition = Condition::createCondition(static_cast(slot), CONDITION_REGENERATION, -1, 0); if (it.abilities->getHealthGain() != 0) { condition->setParam(CONDITION_PARAM_HEALTHGAIN, it.abilities->getHealthGain()); @@ -581,7 +581,7 @@ uint32_t MoveEvent::EquipItem(const std::shared_ptr moveEvent, Player return 1; } -uint32_t MoveEvent::DeEquipItem(const std::shared_ptr MoveEvent, Player* player, Item* item, Slots_t slot, bool) { +uint32_t MoveEvent::DeEquipItem(const std::shared_ptr MoveEvent, std::shared_ptr player, std::shared_ptr item, Slots_t slot, bool) { if (player == nullptr) { g_logger().error("[MoveEvent::EquipItem] - Player is nullptr"); return 0; @@ -623,7 +623,7 @@ uint32_t MoveEvent::DeEquipItem(const std::shared_ptr MoveEvent, Play } if (it.abilities->speed != 0) { - g_game().changePlayerSpeed(*player, -it.abilities->speed); + g_game().changePlayerSpeed(player, -it.abilities->speed); } player->removeConditionSuppressions(); @@ -664,22 +664,22 @@ void MoveEvent::setEventType(MoveEvent_t type) { eventType = type; } -uint32_t MoveEvent::fireStepEvent(Creature &creature, Item* item, const Position &pos) const { +uint32_t MoveEvent::fireStepEvent(const std::shared_ptr &creature, std::shared_ptr item, const Position &pos) const { if (isLoadedCallback()) { return executeStep(creature, item, pos); } else { - return stepFunction(&creature, item, pos); + return stepFunction(creature, item, pos); } } -bool MoveEvent::executeStep(Creature &creature, Item* item, const Position &pos) const { +bool MoveEvent::executeStep(const std::shared_ptr &creature, std::shared_ptr item, const Position &pos) const { // onStepIn(creature, item, pos, fromPosition) // onStepOut(creature, item, pos, fromPosition) // Check if the new position is the same as the old one // If it is, log a warning and either teleport the player to their temple position if item type is an teleport - auto fromPosition = creature.getLastPosition(); - if (auto player = creature.getPlayer(); item && fromPosition == pos && getEventType() == MOVE_EVENT_STEP_IN) { + auto fromPosition = creature->getLastPosition(); + if (auto player = creature->getPlayer(); item && fromPosition == pos && getEventType() == MOVE_EVENT_STEP_IN) { if (const ItemType &itemType = Item::items[item->getID()]; player && itemType.isTeleport()) { g_logger().warn("[{}] cannot teleport player: {}, to the same position: {} of fromPosition: {}", __FUNCTION__, player->getName(), pos.toString(), fromPosition.toString()); g_game().internalTeleport(player, player->getTemplePosition()); @@ -694,11 +694,11 @@ bool MoveEvent::executeStep(Creature &creature, Item* item, const Position &pos) if (item != nullptr) { g_logger().error("[MoveEvent::executeStep - Creature {} item {}, position {}] " "Call stack overflow. Too many lua script calls being nested.", - creature.getName(), item->getName(), pos.toString()); + creature->getName(), item->getName(), pos.toString()); } else { g_logger().error("[MoveEvent::executeStep - Creature {}, position {}] " "Call stack overflow. Too many lua script calls being nested.", - creature.getName(), pos.toString()); + creature->getName(), pos.toString()); } return false; } @@ -709,8 +709,8 @@ bool MoveEvent::executeStep(Creature &creature, Item* item, const Position &pos) lua_State* L = getScriptInterface()->getLuaState(); getScriptInterface()->pushFunction(getScriptId()); - LuaScriptInterface::pushUserdata(L, &creature); - LuaScriptInterface::setCreatureMetatable(L, -1, &creature); + LuaScriptInterface::pushUserdata(L, creature); + LuaScriptInterface::setCreatureMetatable(L, -1, creature); LuaScriptInterface::pushThing(L, item); LuaScriptInterface::pushPosition(L, pos); LuaScriptInterface::pushPosition(L, fromPosition); @@ -718,26 +718,26 @@ bool MoveEvent::executeStep(Creature &creature, Item* item, const Position &pos) return getScriptInterface()->callFunction(4); } -uint32_t MoveEvent::fireEquip(Player &player, Item &item, Slots_t toSlot, bool isCheck) { +uint32_t MoveEvent::fireEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t toSlot, bool isCheck) { if (isLoadedCallback()) { - if (!equipFunction || equipFunction(static_self_cast(), &player, &item, toSlot, isCheck) == 1) { + if (!equipFunction || equipFunction(static_self_cast(), player, item, toSlot, isCheck) == 1) { if (executeEquip(player, item, toSlot, isCheck)) { return 1; } } return 0; } else { - return equipFunction(static_self_cast(), &player, &item, toSlot, isCheck); + return equipFunction(static_self_cast(), player, item, toSlot, isCheck); } } -bool MoveEvent::executeEquip(Player &player, Item &item, Slots_t onSlot, bool isCheck) const { +bool MoveEvent::executeEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t onSlot, bool isCheck) const { // onEquip(player, item, slot, isCheck) // onDeEquip(player, item, slot, isCheck) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[MoveEvent::executeEquip - Player {} item {}] " "Call stack overflow. Too many lua script calls being nested.", - player.getName(), item.getName()); + player->getName(), item->getName()); return false; } @@ -747,31 +747,31 @@ bool MoveEvent::executeEquip(Player &player, Item &item, Slots_t onSlot, bool is lua_State* L = getScriptInterface()->getLuaState(); getScriptInterface()->pushFunction(getScriptId()); - LuaScriptInterface::pushUserdata(L, &player); + LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); - LuaScriptInterface::pushThing(L, &item); + LuaScriptInterface::pushThing(L, item); lua_pushnumber(L, onSlot); LuaScriptInterface::pushBoolean(L, isCheck); return getScriptInterface()->callFunction(4); } -uint32_t MoveEvent::fireAddRemItem(Item &item, Item &fromTile, const Position &pos) const { +uint32_t MoveEvent::fireAddRemItem(const std::shared_ptr &item, const std::shared_ptr &fromTile, const Position &pos) const { if (isLoadedCallback()) { return executeAddRemItem(item, fromTile, pos); } else { - return moveFunction(&item, &fromTile, pos); + return moveFunction(item, fromTile, pos); } } -bool MoveEvent::executeAddRemItem(Item &item, Item &fromTile, const Position &pos) const { +bool MoveEvent::executeAddRemItem(const std::shared_ptr &item, const std::shared_ptr &fromTile, const Position &pos) const { // onAddItem(moveitem, tileitem, pos) // onRemoveItem(moveitem, tileitem, pos) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[MoveEvent::executeAddRemItem - " "Item {} item on tile x: {} y: {} z: {}] " "Call stack overflow. Too many lua script calls being nested.", - item.getName(), pos.getX(), pos.getY(), pos.getZ()); + item->getName(), pos.getX(), pos.getY(), pos.getZ()); return false; } @@ -781,29 +781,29 @@ bool MoveEvent::executeAddRemItem(Item &item, Item &fromTile, const Position &po lua_State* L = getScriptInterface()->getLuaState(); getScriptInterface()->pushFunction(getScriptId()); - LuaScriptInterface::pushThing(L, &item); - LuaScriptInterface::pushThing(L, &fromTile); + LuaScriptInterface::pushThing(L, item); + LuaScriptInterface::pushThing(L, fromTile); LuaScriptInterface::pushPosition(L, pos); return getScriptInterface()->callFunction(3); } -uint32_t MoveEvent::fireAddRemItem(Item &item, const Position &pos) const { +uint32_t MoveEvent::fireAddRemItem(const std::shared_ptr &item, const Position &pos) const { if (isLoadedCallback()) { return executeAddRemItem(item, pos); } else { - return moveFunction(&item, nullptr, pos); + return moveFunction(item, nullptr, pos); } } -bool MoveEvent::executeAddRemItem(Item &item, const Position &pos) const { +bool MoveEvent::executeAddRemItem(const std::shared_ptr &item, const Position &pos) const { // onaddItem(moveitem, pos) // onRemoveItem(moveitem, pos) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[MoveEvent::executeAddRemItem - " "Item {} item on tile x: {} y: {} z: {}] " "Call stack overflow. Too many lua script calls being nested.", - item.getName(), pos.getX(), pos.getY(), pos.getZ()); + item->getName(), pos.getX(), pos.getY(), pos.getZ()); return false; } @@ -813,7 +813,7 @@ bool MoveEvent::executeAddRemItem(Item &item, const Position &pos) const { lua_State* L = getScriptInterface()->getLuaState(); getScriptInterface()->pushFunction(getScriptId()); - LuaScriptInterface::pushThing(L, &item); + LuaScriptInterface::pushThing(L, item); LuaScriptInterface::pushPosition(L, pos); return getScriptInterface()->callFunction(2); diff --git a/src/lua/creature/movement.hpp b/src/lua/creature/movement.hpp index a4b613c4a..d410cf2a0 100644 --- a/src/lua/creature/movement.hpp +++ b/src/lua/creature/movement.hpp @@ -36,10 +36,10 @@ class MoveEvents final : public Scripts { return inject(); } - uint32_t onCreatureMove(Creature &creature, 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); - uint32_t onItemMove(Item &item, Tile &tile, bool isAdd); + uint32_t onCreatureMove(const std::shared_ptr &creature, const std::shared_ptr &tile, MoveEvent_t eventType); + uint32_t onPlayerEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot, bool isCheck); + uint32_t onPlayerDeEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot); + uint32_t onItemMove(const std::shared_ptr &item, const std::shared_ptr &tile, bool isAdd); std::map getPositionsMap() const { return positionsMap; @@ -105,7 +105,7 @@ class MoveEvents final : public Scripts { actionIdMap.try_emplace(actionId, moveEventList); } - std::shared_ptr getEvent(Item &item, MoveEvent_t eventType); + std::shared_ptr getEvent(const std::shared_ptr &item, MoveEvent_t eventType); bool registerLuaItemEvent(const std::shared_ptr moveEvent); bool registerLuaActionEvent(const std::shared_ptr moveEvent); @@ -120,9 +120,9 @@ class MoveEvents final : public Scripts { bool registerEvent(const std::shared_ptr moveEvent, int32_t id, std::map &moveListMap) const; bool registerEvent(const std::shared_ptr moveEvent, const Position &position, std::map &moveListMap) const; - std::shared_ptr getEvent(Tile &tile, MoveEvent_t eventType); + std::shared_ptr getEvent(const std::shared_ptr &tile, MoveEvent_t eventType); - std::shared_ptr getEvent(Item &item, MoveEvent_t eventType, Slots_t slot); + std::shared_ptr getEvent(const std::shared_ptr &item, MoveEvent_t eventType, Slots_t slot); std::map uniqueIdMap; std::map actionIdMap; @@ -139,21 +139,21 @@ class MoveEvent final : public Script, public SharedObject { MoveEvent_t getEventType() const; void setEventType(MoveEvent_t type); - uint32_t fireStepEvent(Creature &creature, Item* item, const Position &pos) const; - uint32_t fireAddRemItem(Item &item, Item &tileItem, const Position &pos) const; - uint32_t fireAddRemItem(Item &item, const Position &pos) const; - uint32_t fireEquip(Player &player, Item &item, Slots_t slot, bool isCheck); + uint32_t fireStepEvent(const std::shared_ptr &creature, std::shared_ptr item, const Position &pos) const; + uint32_t fireAddRemItem(const std::shared_ptr &item, const std::shared_ptr &tileItem, const Position &pos) const; + uint32_t fireAddRemItem(const std::shared_ptr &item, const Position &pos) const; + uint32_t fireEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot, bool isCheck); uint32_t getSlot() const { return slot; } // Scripting to lua interface - bool executeStep(Creature &creature, Item* item, const Position &pos) const; - bool executeEquip(Player &player, Item &item, Slots_t slot, bool isCheck) const; - bool executeAddRemItem(Item &item, Item &tileItem, const Position &pos) const; + bool executeStep(const std::shared_ptr &creature, std::shared_ptr item, const Position &pos) const; + bool executeEquip(const std::shared_ptr &player, const std::shared_ptr &item, Slots_t slot, bool isCheck) const; + bool executeAddRemItem(const std::shared_ptr &item, const std::shared_ptr &tileItem, const Position &pos) const; // No have tile item - bool executeAddRemItem(Item &item, const Position &pos) const; + bool executeAddRemItem(const std::shared_ptr &item, const Position &pos) const; // // onEquip information @@ -242,14 +242,14 @@ class MoveEvent final : public Script, public SharedObject { wieldInfo |= info; } - static uint32_t StepInField(Creature* creature, Item* item, const Position &pos); - static uint32_t StepOutField(Creature* creature, Item* item, const Position &pos); + static uint32_t StepInField(std::shared_ptr creature, std::shared_ptr item, const Position &pos); + static uint32_t StepOutField(std::shared_ptr creature, std::shared_ptr item, const Position &pos); - static uint32_t AddItemField(Item* item, Item* tileItem, const Position &pos); - static uint32_t RemoveItemField(Item* item, Item* tileItem, const Position &pos); + static uint32_t AddItemField(std::shared_ptr item, std::shared_ptr tileItem, const Position &pos); + static uint32_t RemoveItemField(std::shared_ptr item, std::shared_ptr tileItem, const Position &pos); - static uint32_t EquipItem(const std::shared_ptr moveEvent, Player* player, Item* item, Slots_t slot, bool boolean); - static uint32_t DeEquipItem(const std::shared_ptr moveEvent, Player* player, Item* item, Slots_t slot, bool boolean); + static uint32_t EquipItem(const std::shared_ptr moveEvent, std::shared_ptr player, std::shared_ptr item, Slots_t slot, bool boolean); + static uint32_t DeEquipItem(const std::shared_ptr moveEvent, std::shared_ptr player, std::shared_ptr item, Slots_t slot, bool boolean); private: std::string getScriptTypeName() const override; @@ -259,23 +259,23 @@ class MoveEvent final : public Script, public SharedObject { MoveEvent_t eventType = MOVE_EVENT_NONE; /// Step function std::function creature, + std::shared_ptr item, const Position &pos )> stepFunction; // Move function std::function item, + std::shared_ptr tileItem, const Position &pos )> moveFunction; // equipFunction std::function moveEvent, - Player* player, - Item* item, + std::shared_ptr player, + std::shared_ptr item, Slots_t slot, bool boolean )> diff --git a/src/lua/creature/raids.cpp b/src/lua/creature/raids.cpp index 93936d94a..93335b0c7 100644 --- a/src/lua/creature/raids.cpp +++ b/src/lua/creature/raids.cpp @@ -131,7 +131,7 @@ void Raids::checkRaids() { } } - checkRaidsEvent = g_scheduler().addEvent(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this), __FUNCTION__); + checkRaidsEvent = g_scheduler().addEvent(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this), "Raids::checkRaids"); } void Raids::clear() { @@ -210,7 +210,7 @@ bool Raid::loadFromXml(const std::string &filename) { } void Raid::startRaid() { - const auto &raidEvent = getNextRaidEvent(); + const auto raidEvent = getNextRaidEvent(); if (raidEvent) { state = RAIDSTATE_EXECUTING; nextEventEvent = g_scheduler().addEvent(raidEvent->getDelay(), std::bind(&Raid::executeRaidEvent, this, raidEvent), "Raid::executeRaidEvent"); @@ -223,7 +223,7 @@ void Raid::startRaid() { void Raid::executeRaidEvent(const std::shared_ptr raidEvent) { if (raidEvent->executeEvent()) { nextEvent++; - const auto &newRaidEvent = getNextRaidEvent(); + const auto newRaidEvent = getNextRaidEvent(); if (newRaidEvent) { uint32_t ticks = static_cast(std::max(RAID_MINTICKS, newRaidEvent->getDelay() - raidEvent->getDelay())); @@ -365,14 +365,14 @@ bool SingleSpawnEvent::configureRaidEvent(const pugi::xml_node &eventNode) { } bool SingleSpawnEvent::executeEvent() { - Monster* monster = Monster::createMonster(monsterName); + std::shared_ptr monster = Monster::createMonster(monsterName); if (!monster) { g_logger().error("{} - Cant create monster {}", __FUNCTION__, monsterName); return false; } if (!g_game().placeCreature(monster, position, false, true)) { - delete monster; + g_logger().error("{} - Cant create monster {}", __FUNCTION__, monsterName); return false; } @@ -529,7 +529,7 @@ bool AreaSpawnEvent::executeEvent() { for (const MonsterSpawn &spawn : spawnMonsterList) { uint32_t amount = uniform_random(spawn.minAmount, spawn.maxAmount); for (uint32_t i = 0; i < amount; ++i) { - Monster* monster = Monster::createMonster(spawn.name); + std::shared_ptr monster = Monster::createMonster(spawn.name); if (!monster) { g_logger().error("{} - Can't create monster {}", __FUNCTION__, spawn.name); return false; @@ -537,7 +537,7 @@ bool AreaSpawnEvent::executeEvent() { bool success = false; for (int32_t tries = 0; tries < MAXIMUM_TRIES_PER_MONSTER; tries++) { - const Tile* tile = g_game().map.getTile(static_cast(uniform_random(fromPos.x, toPos.x)), static_cast(uniform_random(fromPos.y, toPos.y)), static_cast(uniform_random(fromPos.z, toPos.z))); + std::shared_ptr tile = g_game().map.getTile(static_cast(uniform_random(fromPos.x, toPos.x)), static_cast(uniform_random(fromPos.y, toPos.y)), static_cast(uniform_random(fromPos.z, toPos.z))); if (tile && !tile->isMoveableBlocking() && !tile->hasFlag(TILESTATE_PROTECTIONZONE) && tile->getTopCreature() == nullptr && g_game().placeCreature(monster, tile->getPosition(), false, true)) { success = true; monster->setForgeMonster(false); @@ -546,7 +546,6 @@ bool AreaSpawnEvent::executeEvent() { } if (!success) { - delete monster; } } } diff --git a/src/lua/creature/talkaction.cpp b/src/lua/creature/talkaction.cpp index 13e407464..4386f6f9b 100644 --- a/src/lua/creature/talkaction.cpp +++ b/src/lua/creature/talkaction.cpp @@ -25,7 +25,7 @@ bool TalkActions::registerLuaEvent(const TalkAction_ptr &talkAction) { return inserted; } -bool TalkActions::checkWord(Player* player, SpeakClasses type, const std::string &words, const std::string_view &word, const TalkAction_ptr &talkActionPtr) const { +bool TalkActions::checkWord(std::shared_ptr player, SpeakClasses type, const std::string &words, const std::string_view &word, const TalkAction_ptr &talkActionPtr) const { auto spacePos = std::ranges::find_if(words.begin(), words.end(), ::isspace); std::string firstWord = words.substr(0, spacePos - words.begin()); @@ -61,7 +61,7 @@ bool TalkActions::checkWord(Player* player, SpeakClasses type, const std::string return talkActionPtr->executeSay(player, words, param, type); } -TalkActionResult_t TalkActions::checkPlayerCanSayTalkAction(Player* player, SpeakClasses type, const std::string &words) const { +TalkActionResult_t TalkActions::checkPlayerCanSayTalkAction(std::shared_ptr player, SpeakClasses type, const std::string &words) const { for (const auto &[talkactionWords, talkActionPtr] : talkActions) { if (talkactionWords.find(',') != std::string::npos) { auto wordsList = split(talkactionWords); @@ -79,7 +79,7 @@ TalkActionResult_t TalkActions::checkPlayerCanSayTalkAction(Player* player, Spea return TALKACTION_CONTINUE; } -bool TalkAction::executeSay(Player* player, const std::string &words, const std::string ¶m, SpeakClasses type) const { +bool TalkAction::executeSay(std::shared_ptr player, const std::string &words, const std::string ¶m, SpeakClasses type) const { // onSay(player, words, param, type) if (!getScriptInterface()->reserveScriptEnv()) { g_logger().error("[TalkAction::executeSay - Player {} words {}] " diff --git a/src/lua/creature/talkaction.hpp b/src/lua/creature/talkaction.hpp index f5e42ff7c..bc078a72d 100644 --- a/src/lua/creature/talkaction.hpp +++ b/src/lua/creature/talkaction.hpp @@ -44,7 +44,7 @@ class TalkAction : public Script { } // scripting - bool executeSay(Player* player, const std::string &words, const std::string ¶m, SpeakClasses type) const; + bool executeSay(std::shared_ptr player, const std::string &words, const std::string ¶m, SpeakClasses type) const; // void setGroupType(account::GroupType newGroupType) { @@ -78,8 +78,8 @@ class TalkActions final : public Scripts { return inject(); } - bool checkWord(Player* player, SpeakClasses type, const std::string &words, const std::string_view &word, const TalkAction_ptr &talkActionPtr) const; - TalkActionResult_t checkPlayerCanSayTalkAction(Player* player, SpeakClasses type, const std::string &words) const; + bool checkWord(std::shared_ptr player, SpeakClasses type, const std::string &words, const std::string_view &word, const TalkAction_ptr &talkActionPtr) const; + TalkActionResult_t checkPlayerCanSayTalkAction(std::shared_ptr player, SpeakClasses type, const std::string &words) const; bool registerLuaEvent(const TalkAction_ptr &talkAction); void clear(); diff --git a/src/lua/functions/core/game/bank_functions.cpp b/src/lua/functions/core/game/bank_functions.cpp index 2997de4d4..90e4fdecb 100644 --- a/src/lua/functions/core/game/bank_functions.cpp +++ b/src/lua/functions/core/game/bank_functions.cpp @@ -59,11 +59,13 @@ int BankFunctions::luaBankTransfer(lua_State* L) { // Bank.transfer(fromPlayerOrGuild, toPlayerOrGuild, amount) auto source = getBank(L, 1); if (source == nullptr) { + g_logger().debug("BankFunctions::luaBankTransfer: source is null"); lua_pushnil(L); return 1; } std::shared_ptr destination = getBank(L, 2); if (destination == nullptr) { + g_logger().debug("BankFunctions::luaBankTransfer: destination is null"); lua_pushnil(L); return 1; } @@ -98,9 +100,7 @@ int BankFunctions::luaBankWithdraw(lua_State* L) { return 1; } - // TODO: When Player is also shared_ptr, we won't need to verride the deleter - const auto bankablePlayer = std::shared_ptr(player, [](Bankable*) {}); - const auto bank = std::make_shared(bankablePlayer); + const auto bank = std::make_shared(player); pushBoolean(L, bank->withdraw(player, amount)); return 1; } @@ -119,9 +119,7 @@ int BankFunctions::luaBankDeposit(lua_State* L) { if (!player) { return 1; } - // TODO: When Player is also shared_ptr, we won't need to verride the deleter - const auto bankablePlayer = std::shared_ptr(player, [](Bankable*) {}); - const auto bank = std::make_shared(bankablePlayer); + const auto bank = std::make_shared(player); uint64_t amount = 0; if (lua_isnumber(L, 2)) { @@ -154,11 +152,9 @@ std::shared_ptr BankFunctions::getBank(lua_State* L, int32_t arg, bool isG } return std::make_shared(guild); } - Player* player = getPlayer(L, arg, true); + std::shared_ptr player = getPlayer(L, arg, true); if (!player) { return nullptr; } - // TODO: When Player is also shared_ptr, we won't need to verride the deleter - const auto bankablePlayer = std::shared_ptr(player, [](Bankable*) {}); - return std::make_shared(bankablePlayer); + return std::make_shared(player); } diff --git a/src/lua/functions/core/game/config_functions.cpp b/src/lua/functions/core/game/config_functions.cpp index 153844dd5..a64f1d91b 100644 --- a/src/lua/functions/core/game/config_functions.cpp +++ b/src/lua/functions/core/game/config_functions.cpp @@ -249,6 +249,8 @@ void ConfigFunctions::init(lua_State* L) { registerEnumIn(L, "configKeys", VIP_AUTOLOOT_VIP_ONLY); registerEnumIn(L, "configKeys", VIP_STAY_ONLINE); registerEnumIn(L, "configKeys", VIP_FAMILIAR_TIME_COOLDOWN_REDUCTION); + + registerEnumIn(L, "configKeys", TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART); #undef registerEnumIn } diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index 6f872c690..c10d69882 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -75,7 +75,7 @@ int GameFunctions::luaGameGetSpectators(lua_State* L) { lua_createtable(L, spectators.size(), 0); int index = 0; - for (Creature* creature : spectators) { + for (std::shared_ptr creature : spectators) { pushUserdata(L, creature); setCreatureMetatable(L, -1, creature); lua_rawseti(L, -2, ++index); @@ -192,7 +192,7 @@ int GameFunctions::luaGameGetMonsterTypes(lua_State* L) { int GameFunctions::luaGameGetTowns(lua_State* L) { // Game.getTowns() - const auto &towns = g_game().map.towns.getTowns(); + const auto towns = g_game().map.towns.getTowns(); lua_createtable(L, towns.size(), 0); int index = 0; @@ -206,7 +206,7 @@ int GameFunctions::luaGameGetTowns(lua_State* L) { int GameFunctions::luaGameGetHouses(lua_State* L) { // Game.getHouses() - const auto &houses = g_game().map.houses.getHouses(); + const auto houses = g_game().map.houses.getHouses(); lua_createtable(L, houses.size(), 0); int index = 0; @@ -301,7 +301,7 @@ int GameFunctions::luaGameCreateItem(lua_State* L) { subType -= stackCount; } - Item* item = Item::CreateItem(itemId, stackCount); + std::shared_ptr item = Item::CreateItem(itemId, stackCount); if (!item) { if (!hasTable) { lua_pushnil(L); @@ -310,9 +310,9 @@ int GameFunctions::luaGameCreateItem(lua_State* L) { } if (position.x != 0) { - Tile* tile = g_game().map.getTile(position); + std::shared_ptr tile = g_game().map.getTile(position); if (!tile) { - delete item; + if (!hasTable) { lua_pushnil(L); } @@ -321,7 +321,7 @@ int GameFunctions::luaGameCreateItem(lua_State* L) { ReturnValue ret = g_game().internalAddItem(tile, item, INDEX_WHEREEVER, FLAG_NOLIMIT); if (ret != RETURNVALUE_NOERROR) { - delete item; + if (!hasTable) { lua_pushnil(L); } @@ -360,7 +360,7 @@ int GameFunctions::luaGameCreateContainer(lua_State* L) { } } - Container* container = Item::CreateItemAsContainer(id, size); + std::shared_ptr container = Item::CreateItemAsContainer(id, size); if (!container) { lua_pushnil(L); return 1; @@ -368,9 +368,9 @@ int GameFunctions::luaGameCreateContainer(lua_State* L) { if (lua_gettop(L) >= 3) { const Position &position = getPosition(L, 3); - Tile* tile = g_game().map.getTile(position); + std::shared_ptr tile = g_game().map.getTile(position); if (!tile) { - delete container; + lua_pushnil(L); return 1; } @@ -388,7 +388,7 @@ int GameFunctions::luaGameCreateContainer(lua_State* L) { int GameFunctions::luaGameCreateMonster(lua_State* L) { // Game.createMonster(monsterName, position[, extended = false[, force = false[, master = nil]]]) - Monster* monster = Monster::createMonster(getString(L, 1)); + std::shared_ptr monster = Monster::createMonster(getString(L, 1)); if (!monster) { lua_pushnil(L); return 1; @@ -396,7 +396,7 @@ int GameFunctions::luaGameCreateMonster(lua_State* L) { bool isSummon = false; if (lua_gettop(L) >= 5) { - Creature* master = getCreature(L, 5); + std::shared_ptr master = getCreature(L, 5); if (master) { monster->setMaster(master, true); isSummon = true; @@ -413,8 +413,8 @@ int GameFunctions::luaGameCreateMonster(lua_State* L) { if (mtype && mtype->info.raceid > 0 && mtype->info.bosstiaryRace == BosstiaryRarity_t::RARITY_ARCHFOE) { SpectatorHashSet spectators; g_game().map.getSpectators(spectators, monster->getPosition(), true); - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (std::shared_ptr spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { auto bossesOnTracker = g_ioBosstiary().getBosstiaryCooldownRaceId(tmpPlayer); // If not have boss to update, then kill loop for economize resources if (bossesOnTracker.size() == 0) { @@ -432,7 +432,6 @@ int GameFunctions::luaGameCreateMonster(lua_State* L) { if (isSummon) { monster->setMaster(nullptr); } else { - delete monster; } lua_pushnil(L); } @@ -441,7 +440,7 @@ int GameFunctions::luaGameCreateMonster(lua_State* L) { int GameFunctions::luaGameGenerateNpc(lua_State* L) { // Game.generateNpc(npcName) - Npc* npc = Npc::createNpc(getString(L, 1)); + std::shared_ptr npc = Npc::createNpc(getString(L, 1)); if (!npc) { lua_pushnil(L); return 1; @@ -454,7 +453,7 @@ int GameFunctions::luaGameGenerateNpc(lua_State* L) { int GameFunctions::luaGameCreateNpc(lua_State* L) { // Game.createNpc(npcName, position[, extended = false[, force = false]]) - Npc* npc = Npc::createNpc(getString(L, 1)); + std::shared_ptr npc = Npc::createNpc(getString(L, 1)); if (!npc) { lua_pushnil(L); return 1; @@ -467,7 +466,7 @@ int GameFunctions::luaGameCreateNpc(lua_State* L) { pushUserdata(L, npc); setMetatable(L, -1, "Npc"); } else { - delete npc; + lua_pushnil(L); } return 1; @@ -495,7 +494,7 @@ int GameFunctions::luaGameCreateTile(lua_State* L) { int GameFunctions::luaGameGetBestiaryCharm(lua_State* L) { // Game.getBestiaryCharm() - const auto &c_list = g_game().getCharmList(); + const auto c_list = g_game().getCharmList(); lua_createtable(L, c_list.size(), 0); int index = 0; @@ -534,7 +533,7 @@ int GameFunctions::luaGameStartRaid(lua_State* L) { // Game.startRaid(raidName) const std::string &raidName = getString(L, 1); - const auto &raid = g_game().raids.getRaidByName(raidName); + const auto raid = g_game().raids.getRaidByName(raidName); if (!raid || !raid->isLoaded()) { lua_pushnumber(L, RETURNVALUE_NOSUCHRAIDEXISTS); return 1; @@ -598,9 +597,8 @@ int GameFunctions::luaGameHasDistanceEffect(lua_State* L) { int GameFunctions::luaGameGetOfflinePlayer(lua_State* L) { uint32_t playerId = getNumber(L, 1); - Player* offlinePlayer = new Player(nullptr); + auto offlinePlayer = std::make_shared(nullptr); if (!IOLoginData::loadPlayerById(offlinePlayer, playerId)) { - delete offlinePlayer; lua_pushnil(L); } else { pushUserdata(L, offlinePlayer); @@ -613,11 +611,10 @@ int GameFunctions::luaGameGetOfflinePlayer(lua_State* L) { int GameFunctions::luaGameGetNormalizedPlayerName(lua_State* L) { // Game.getNormalizedPlayerName(name) auto name = getString(L, 1); - Player* player = g_game().getPlayerByName(name, true); + std::shared_ptr player = g_game().getPlayerByName(name, true); if (player) { pushString(L, player->getName()); if (!player->isOnline()) { - delete player; } } else { lua_pushnil(L); @@ -639,7 +636,7 @@ int GameFunctions::luaGameGetNormalizedGuildName(lua_State* L) { int GameFunctions::luaGameAddInfluencedMonster(lua_State* L) { // Game.addInfluencedMonster(monster) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -696,7 +693,7 @@ int GameFunctions::luaGameGetDummies(lua_State* L) { local rate = dummies[1] -- Retrieve dummy rate */ - const auto &dummies = Item::items.getDummys(); + const auto dummies = Item::items.getDummys(); lua_createtable(L, dummies.size(), 0); for (const auto &[dummyId, rate] : dummies) { lua_pushnumber(L, static_cast(rate)); @@ -744,7 +741,7 @@ int GameFunctions::luaGameGetBoostedBoss(lua_State* L) { int GameFunctions::luaGameGetTalkActions(lua_State* L) { // Game.getTalkActions() - const auto &talkactionsMap = g_talkActions().getTalkActionsMap(); + const auto talkactionsMap = g_talkActions().getTalkActionsMap(); lua_createtable(L, static_cast(talkactionsMap.size()), 0); for (const auto &[talkName, talkactionSharedPtr] : talkactionsMap) { diff --git a/src/lua/functions/core/game/global_functions.cpp b/src/lua/functions/core/game/global_functions.cpp index 4a4a4dee6..e0a2ddcc7 100644 --- a/src/lua/functions/core/game/global_functions.cpp +++ b/src/lua/functions/core/game/global_functions.cpp @@ -22,7 +22,7 @@ class Creature; int GlobalFunctions::luaDoPlayerAddItem(lua_State* L) { // doPlayerAddItem(cid, itemid, count/subtype, canDropOnMap) // doPlayerAddItem(cid, itemid, count, canDropOnMap, subtype) - Player* player = getPlayer(L, 1); + std::shared_ptr player = getPlayer(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -58,7 +58,7 @@ int GlobalFunctions::luaDoPlayerAddItem(lua_State* L) { stackCount = it.stackSize; } - Item* newItem = Item::CreateItem(itemId, stackCount); + std::shared_ptr newItem = Item::CreateItem(itemId, stackCount); if (!newItem) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -71,7 +71,6 @@ int GlobalFunctions::luaDoPlayerAddItem(lua_State* L) { ReturnValue ret = g_game().internalPlayerAddItem(player, newItem, canDropOnMap); if (ret != RETURNVALUE_NOERROR) { - delete newItem; pushBoolean(L, false); return 1; } @@ -95,7 +94,7 @@ int GlobalFunctions::luaDoPlayerAddItem(lua_State* L) { int GlobalFunctions::luaDoSetCreatureLight(lua_State* L) { // doSetCreatureLight(cid, lightLevel, lightColor, time) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -105,7 +104,7 @@ int GlobalFunctions::luaDoSetCreatureLight(lua_State* L) { uint16_t level = getNumber(L, 2); uint16_t color = getNumber(L, 3); uint32_t time = getNumber(L, 4); - Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_LIGHT, time, level | (color << 8)); + std::shared_ptr condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_LIGHT, time, level | (color << 8)); creature->addCondition(condition); pushBoolean(L, true); return 1; @@ -119,7 +118,7 @@ int GlobalFunctions::luaIsValidUID(lua_State* L) { int GlobalFunctions::luaIsDepot(lua_State* L) { // isDepot(uid) - Container* container = getScriptEnv()->getContainerByUID(getNumber(L, -1)); + std::shared_ptr container = getScriptEnv()->getContainerByUID(getNumber(L, -1)); pushBoolean(L, container && container->getDepotLocker()); return 1; } @@ -127,7 +126,7 @@ int GlobalFunctions::luaIsDepot(lua_State* L) { int GlobalFunctions::luaIsMoveable(lua_State* L) { // isMoveable(uid) // isMovable(uid) - Thing* thing = getScriptEnv()->getThingByUID(getNumber(L, -1)); + std::shared_ptr thing = getScriptEnv()->getThingByUID(getNumber(L, -1)); pushBoolean(L, thing && thing->isPushable()); return 1; } @@ -137,7 +136,7 @@ int GlobalFunctions::luaDoAddContainerItem(lua_State* L) { uint32_t uid = getNumber(L, 1); ScriptEnvironment* env = getScriptEnv(); - Container* container = env->getContainerByUID(uid); + std::shared_ptr container = env->getContainerByUID(uid); if (!container) { reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND)); pushBoolean(L, false); @@ -163,7 +162,7 @@ int GlobalFunctions::luaDoAddContainerItem(lua_State* L) { while (itemCount > 0) { int32_t stackCount = std::min(it.stackSize, subType); - Item* newItem = Item::CreateItem(itemId, stackCount); + std::shared_ptr newItem = Item::CreateItem(itemId, stackCount); if (!newItem) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -176,7 +175,6 @@ int GlobalFunctions::luaDoAddContainerItem(lua_State* L) { ReturnValue ret = g_game().internalAddItem(container, newItem); if (ret != RETURNVALUE_NOERROR) { - delete newItem; pushBoolean(L, false); return 1; } @@ -200,14 +198,14 @@ int GlobalFunctions::luaGetDepotId(lua_State* L) { // getDepotId(uid) uint32_t uid = getNumber(L, -1); - Container* container = getScriptEnv()->getContainerByUID(uid); + std::shared_ptr container = getScriptEnv()->getContainerByUID(uid); if (!container) { reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND)); pushBoolean(L, false); return 1; } - DepotLocker* depotLocker = container->getDepotLocker(); + std::shared_ptr depotLocker = container->getDepotLocker(); if (!depotLocker) { reportErrorFunc("Depot not found"); pushBoolean(L, false); @@ -250,7 +248,7 @@ int GlobalFunctions::luaCreateCombatArea(lua_State* L) { } uint32_t areaId = g_luaEnvironment().createAreaObject(env->getScriptInterface()); - AreaCombat* area = g_luaEnvironment().getAreaObject(areaId); + const auto &area = g_luaEnvironment().getAreaObject(areaId); int parameters = lua_gettop(L); if (parameters >= 2) { @@ -279,7 +277,7 @@ int GlobalFunctions::luaCreateCombatArea(lua_State* L) { int GlobalFunctions::luaDoAreaCombatHealth(lua_State* L) { // doAreaCombatHealth(cid, type, pos, area, min, max, effect[, origin = ORIGIN_SPELL]) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature && (!isNumber(L, 1) || getNumber(L, 1) != 0)) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -287,7 +285,7 @@ int GlobalFunctions::luaDoAreaCombatHealth(lua_State* L) { } uint32_t areaId = getNumber(L, 4); - const AreaCombat* area = g_luaEnvironment().getAreaObject(areaId); + const auto &area = g_luaEnvironment().getAreaObject(areaId); if (area || areaId == 0) { CombatType_t combatType = getNumber(L, 2); @@ -319,14 +317,14 @@ int GlobalFunctions::luaDoAreaCombatHealth(lua_State* L) { int GlobalFunctions::luaDoTargetCombatHealth(lua_State* L) { // doTargetCombatHealth(cid, target, type, min, max, effect[, origin = ORIGIN_SPELL]) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature && (!isNumber(L, 1) || getNumber(L, 1) != 0)) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } - Creature* target = getCreature(L, 2); + std::shared_ptr target = getCreature(L, 2); if (!target) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -364,7 +362,7 @@ int GlobalFunctions::luaDoTargetCombatHealth(lua_State* L) { int GlobalFunctions::luaDoAreaCombatMana(lua_State* L) { // doAreaCombatMana(cid, pos, area, min, max, effect[, origin = ORIGIN_SPELL]) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature && (!isNumber(L, 1) || getNumber(L, 1) != 0)) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -372,7 +370,7 @@ int GlobalFunctions::luaDoAreaCombatMana(lua_State* L) { } uint32_t areaId = getNumber(L, 3); - const AreaCombat* area = g_luaEnvironment().getAreaObject(areaId); + const auto &area = g_luaEnvironment().getAreaObject(areaId); if (area || areaId == 0) { CombatParams params; params.impactEffect = getNumber(L, 6); @@ -402,14 +400,14 @@ int GlobalFunctions::luaDoAreaCombatMana(lua_State* L) { int GlobalFunctions::luaDoTargetCombatMana(lua_State* L) { // doTargetCombatMana(cid, target, min, max, effect[, origin = ORIGIN_SPELL) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature && (!isNumber(L, 1) || getNumber(L, 1) != 0)) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } - Creature* target = getCreature(L, 2); + std::shared_ptr target = getCreature(L, 2); if (!target) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -442,14 +440,14 @@ int GlobalFunctions::luaDoTargetCombatMana(lua_State* L) { int GlobalFunctions::luaDoAreaCombatCondition(lua_State* L) { // doAreaCombatCondition(cid, pos, area, condition, effect) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature && (!isNumber(L, 1) || getNumber(L, 1) != 0)) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } - const Condition* condition = getUserdata(L, 4); + const std::shared_ptr condition = getUserdataShared(L, 4); if (!condition) { reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND)); pushBoolean(L, false); @@ -457,7 +455,7 @@ int GlobalFunctions::luaDoAreaCombatCondition(lua_State* L) { } uint32_t areaId = getNumber(L, 3); - const AreaCombat* area = g_luaEnvironment().getAreaObject(areaId); + const auto &area = g_luaEnvironment().getAreaObject(areaId); if (area || areaId == 0) { CombatParams params; params.impactEffect = getNumber(L, 5); @@ -473,21 +471,21 @@ int GlobalFunctions::luaDoAreaCombatCondition(lua_State* L) { int GlobalFunctions::luaDoTargetCombatCondition(lua_State* L) { // doTargetCombatCondition(cid, target, condition, effect) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature && (!isNumber(L, 1) || getNumber(L, 1) != 0)) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } - Creature* target = getCreature(L, 2); + std::shared_ptr target = getCreature(L, 2); if (!target) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } - const Condition* condition = getUserdata(L, 3); + const std::shared_ptr condition = getUserdataShared(L, 3); if (!condition) { reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND)); pushBoolean(L, false); @@ -504,7 +502,7 @@ int GlobalFunctions::luaDoTargetCombatCondition(lua_State* L) { int GlobalFunctions::luaDoAreaCombatDispel(lua_State* L) { // doAreaCombatDispel(cid, pos, area, type, effect) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature && (!isNumber(L, 1) || getNumber(L, 1) != 0)) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -512,7 +510,7 @@ int GlobalFunctions::luaDoAreaCombatDispel(lua_State* L) { } uint32_t areaId = getNumber(L, 3); - const AreaCombat* area = g_luaEnvironment().getAreaObject(areaId); + const auto &area = g_luaEnvironment().getAreaObject(areaId); if (area || areaId == 0) { CombatParams params; params.impactEffect = getNumber(L, 5); @@ -529,14 +527,14 @@ int GlobalFunctions::luaDoAreaCombatDispel(lua_State* L) { int GlobalFunctions::luaDoTargetCombatDispel(lua_State* L) { // doTargetCombatDispel(cid, target, type, effect) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature && (!isNumber(L, 1) || getNumber(L, 1) != 0)) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } - Creature* target = getCreature(L, 2); + std::shared_ptr target = getCreature(L, 2); if (!target) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -553,14 +551,14 @@ int GlobalFunctions::luaDoTargetCombatDispel(lua_State* L) { int GlobalFunctions::luaDoChallengeCreature(lua_State* L) { // doChallengeCreature(cid, target, targetChangeCooldown) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } - Creature* target = getCreature(L, 2); + std::shared_ptr target = getCreature(L, 2); if (!target) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -742,14 +740,14 @@ int GlobalFunctions::luaDebugPrint(lua_State* L) { int GlobalFunctions::luaIsInWar(lua_State* L) { // isInWar(cid, target) - Player* player = getPlayer(L, 1); + std::shared_ptr player = getPlayer(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } - Player* targetPlayer = getPlayer(L, 2); + std::shared_ptr targetPlayer = getPlayer(L, 2); if (!targetPlayer) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); diff --git a/src/lua/functions/core/game/lua_enums.cpp b/src/lua/functions/core/game/lua_enums.cpp index 8a28b0655..8d8618529 100644 --- a/src/lua/functions/core/game/lua_enums.cpp +++ b/src/lua/functions/core/game/lua_enums.cpp @@ -110,6 +110,7 @@ void LuaEnums::init(lua_State* L) { initBosstiaryEnums(L); initSoundEnums(L); initWheelEnums(L); + initAttributeConditionSubIdEnums(L); } void LuaEnums::initOthersEnums(lua_State* L) { @@ -441,6 +442,13 @@ void LuaEnums::initConditionParamEnums(lua_State* L) { registerEnum(L, CONDITION_PARAM_CHARM_CHANCE_MODIFIER); } +void LuaEnums::initAttributeConditionSubIdEnums(lua_State* L) { + std::string luaNamespace = "AttrSubId_"; + for (auto value : magic_enum::enum_values()) { + registerEnumClassNamespace(L, luaNamespace, value); + } +} + void LuaEnums::initConstMeEnums(lua_State* L) { registerEnum(L, CONST_ME_NONE); registerEnum(L, CONST_ME_DRAWBLOOD); @@ -883,6 +891,7 @@ void LuaEnums::initItemIdEnums(lua_State* L) { registerEnum(L, ITEM_FORGE_SLIVER); registerEnum(L, ITEM_FORGE_CORE); registerEnum(L, ITEM_PRIMAL_POD); + registerEnum(L, ITEM_DECORATION_KIT); registerEnum(L, ItemID_t::HIRELING_LAMP); } diff --git a/src/lua/functions/core/game/lua_enums.hpp b/src/lua/functions/core/game/lua_enums.hpp index 0acec93a9..055741b3f 100644 --- a/src/lua/functions/core/game/lua_enums.hpp +++ b/src/lua/functions/core/game/lua_enums.hpp @@ -34,6 +34,7 @@ class LuaEnums final : LuaScriptInterface { static void initConditionEnums(lua_State* L); static void initConditionIdEnums(lua_State* L); static void initConditionParamEnums(lua_State* L); + static void initAttributeConditionSubIdEnums(lua_State* L); static void initConstMeEnums(lua_State* L); static void initConstAniEnums(lua_State* L); static void initConstPropEnums(lua_State* L); diff --git a/src/lua/functions/core/game/modal_window_functions.cpp b/src/lua/functions/core/game/modal_window_functions.cpp index 125e51487..11441993f 100644 --- a/src/lua/functions/core/game/modal_window_functions.cpp +++ b/src/lua/functions/core/game/modal_window_functions.cpp @@ -19,23 +19,14 @@ int ModalWindowFunctions::luaModalWindowCreate(lua_State* L) { const std::string &title = getString(L, 3); uint32_t id = getNumber(L, 2); - pushUserdata(L, new ModalWindow(id, title, message)); + pushUserdata(L, std::make_shared(id, title, message)); setMetatable(L, -1, "ModalWindow"); return 1; } -int ModalWindowFunctions::luaModalWindowDelete(lua_State* L) { - ModalWindow** windowPtr = getRawUserdata(L, 1); - if (windowPtr && *windowPtr) { - delete *windowPtr; - *windowPtr = nullptr; - } - return 0; -} - int ModalWindowFunctions::luaModalWindowGetId(lua_State* L) { // modalWindow:getId() - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { lua_pushnumber(L, window->id); } else { @@ -46,7 +37,7 @@ int ModalWindowFunctions::luaModalWindowGetId(lua_State* L) { int ModalWindowFunctions::luaModalWindowGetTitle(lua_State* L) { // modalWindow:getTitle() - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { pushString(L, window->title); } else { @@ -57,7 +48,7 @@ int ModalWindowFunctions::luaModalWindowGetTitle(lua_State* L) { int ModalWindowFunctions::luaModalWindowGetMessage(lua_State* L) { // modalWindow:getMessage() - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { pushString(L, window->message); } else { @@ -69,7 +60,7 @@ int ModalWindowFunctions::luaModalWindowGetMessage(lua_State* L) { int ModalWindowFunctions::luaModalWindowSetTitle(lua_State* L) { // modalWindow:setTitle(text) const std::string &text = getString(L, 2); - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { window->title = text; pushBoolean(L, true); @@ -82,7 +73,7 @@ int ModalWindowFunctions::luaModalWindowSetTitle(lua_State* L) { int ModalWindowFunctions::luaModalWindowSetMessage(lua_State* L) { // modalWindow:setMessage(text) const std::string &text = getString(L, 2); - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { window->message = text; pushBoolean(L, true); @@ -94,7 +85,7 @@ int ModalWindowFunctions::luaModalWindowSetMessage(lua_State* L) { int ModalWindowFunctions::luaModalWindowGetButtonCount(lua_State* L) { // modalWindow:getButtonCount() - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { lua_pushnumber(L, window->buttons.size()); } else { @@ -105,7 +96,7 @@ int ModalWindowFunctions::luaModalWindowGetButtonCount(lua_State* L) { int ModalWindowFunctions::luaModalWindowGetChoiceCount(lua_State* L) { // modalWindow:getChoiceCount() - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { lua_pushnumber(L, window->choices.size()); } else { @@ -118,7 +109,7 @@ int ModalWindowFunctions::luaModalWindowAddButton(lua_State* L) { // modalWindow:addButton(id, text) const std::string &text = getString(L, 3); uint8_t id = getNumber(L, 2); - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { window->buttons.emplace_back(text, id); pushBoolean(L, true); @@ -132,7 +123,7 @@ int ModalWindowFunctions::luaModalWindowAddChoice(lua_State* L) { // modalWindow:addChoice(id, text) const std::string &text = getString(L, 3); uint8_t id = getNumber(L, 2); - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { window->choices.emplace_back(text, id); pushBoolean(L, true); @@ -144,7 +135,7 @@ int ModalWindowFunctions::luaModalWindowAddChoice(lua_State* L) { int ModalWindowFunctions::luaModalWindowGetDefaultEnterButton(lua_State* L) { // modalWindow:getDefaultEnterButton() - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { lua_pushnumber(L, window->defaultEnterButton); } else { @@ -155,7 +146,7 @@ int ModalWindowFunctions::luaModalWindowGetDefaultEnterButton(lua_State* L) { int ModalWindowFunctions::luaModalWindowSetDefaultEnterButton(lua_State* L) { // modalWindow:setDefaultEnterButton(buttonId) - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { window->defaultEnterButton = getNumber(L, 2); pushBoolean(L, true); @@ -167,7 +158,7 @@ int ModalWindowFunctions::luaModalWindowSetDefaultEnterButton(lua_State* L) { int ModalWindowFunctions::luaModalWindowGetDefaultEscapeButton(lua_State* L) { // modalWindow:getDefaultEscapeButton() - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { lua_pushnumber(L, window->defaultEscapeButton); } else { @@ -178,7 +169,7 @@ int ModalWindowFunctions::luaModalWindowGetDefaultEscapeButton(lua_State* L) { int ModalWindowFunctions::luaModalWindowSetDefaultEscapeButton(lua_State* L) { // modalWindow:setDefaultEscapeButton(buttonId) - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { window->defaultEscapeButton = getNumber(L, 2); pushBoolean(L, true); @@ -190,7 +181,7 @@ int ModalWindowFunctions::luaModalWindowSetDefaultEscapeButton(lua_State* L) { int ModalWindowFunctions::luaModalWindowHasPriority(lua_State* L) { // modalWindow:hasPriority() - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { pushBoolean(L, window->priority); } else { @@ -201,7 +192,7 @@ int ModalWindowFunctions::luaModalWindowHasPriority(lua_State* L) { int ModalWindowFunctions::luaModalWindowSetPriority(lua_State* L) { // modalWindow:setPriority(priority) - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { window->priority = getBoolean(L, 2); pushBoolean(L, true); @@ -213,13 +204,13 @@ int ModalWindowFunctions::luaModalWindowSetPriority(lua_State* L) { int ModalWindowFunctions::luaModalWindowSendToPlayer(lua_State* L) { // modalWindow:sendToPlayer(player) - Player* player = getPlayer(L, 2); + std::shared_ptr player = getPlayer(L, 2); if (!player) { lua_pushnil(L); return 1; } - ModalWindow* window = getUserdata(L, 1); + const auto &window = getUserdataShared(L, 1); if (window) { if (!player->hasModalWindowOpen(window->id)) { player->sendModalWindow(*window); diff --git a/src/lua/functions/core/game/modal_window_functions.hpp b/src/lua/functions/core/game/modal_window_functions.hpp index 4d4ced163..78e935314 100644 --- a/src/lua/functions/core/game/modal_window_functions.hpp +++ b/src/lua/functions/core/game/modal_window_functions.hpp @@ -14,10 +14,8 @@ class ModalWindowFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "ModalWindow", "", ModalWindowFunctions::luaModalWindowCreate); + registerSharedClass(L, "ModalWindow", "", ModalWindowFunctions::luaModalWindowCreate); registerMetaMethod(L, "ModalWindow", "__eq", ModalWindowFunctions::luaUserdataCompare); - registerMetaMethod(L, "ModalWindow", "__gc", ModalWindowFunctions::luaModalWindowDelete); - registerMethod(L, "ModalWindow", "delete", ModalWindowFunctions::luaModalWindowDelete); registerMethod(L, "ModalWindow", "getId", ModalWindowFunctions::luaModalWindowGetId); registerMethod(L, "ModalWindow", "getTitle", ModalWindowFunctions::luaModalWindowGetTitle); @@ -46,7 +44,6 @@ class ModalWindowFunctions final : LuaScriptInterface { private: static int luaModalWindowCreate(lua_State* L); - static int luaModalWindowDelete(lua_State* L); static int luaModalWindowGetId(lua_State* L); static int luaModalWindowGetTitle(lua_State* L); diff --git a/src/lua/functions/core/game/zone_functions.cpp b/src/lua/functions/core/game/zone_functions.cpp index 8c4d06d02..9aa000caf 100644 --- a/src/lua/functions/core/game/zone_functions.cpp +++ b/src/lua/functions/core/game/zone_functions.cpp @@ -135,7 +135,7 @@ int ZoneFunctions::luaZoneGetTiles(lua_State* L) { int index = 0; for (auto tile : tiles) { index++; - pushUserdata(L, tile); + pushUserdata(L, tile.get()); setMetatable(L, -1, "Tile"); lua_rawseti(L, -2, index); } @@ -306,7 +306,7 @@ int ZoneFunctions::luaZoneGetByPosition(lua_State* L) { return 1; } int index = 0; - const auto &zones = tile->getZones(); + const auto zones = tile->getZones(); lua_createtable(L, static_cast(zones.size()), 0); for (auto zone : zones) { index++; @@ -319,7 +319,7 @@ int ZoneFunctions::luaZoneGetByPosition(lua_State* L) { int ZoneFunctions::luaZoneGetAll(lua_State* L) { // Zone.getAll() - const auto &zones = Zone::getZones(); + const auto zones = Zone::getZones(); lua_createtable(L, static_cast(zones.size()), 0); int index = 0; for (auto zone : zones) { diff --git a/src/lua/functions/core/network/network_message_functions.cpp b/src/lua/functions/core/network/network_message_functions.cpp index 6ca01e6af..a0f02631a 100644 --- a/src/lua/functions/core/network/network_message_functions.cpp +++ b/src/lua/functions/core/network/network_message_functions.cpp @@ -15,23 +15,14 @@ int NetworkMessageFunctions::luaNetworkMessageCreate(lua_State* L) { // NetworkMessage() - pushUserdata(L, new NetworkMessage); + pushUserdata(L, std::make_shared()); setMetatable(L, -1, "NetworkMessage"); return 1; } -int NetworkMessageFunctions::luaNetworkMessageDelete(lua_State* L) { - NetworkMessage** messagePtr = getRawUserdata(L, 1); - if (messagePtr && *messagePtr) { - delete *messagePtr; - *messagePtr = nullptr; - } - return 0; -} - int NetworkMessageFunctions::luaNetworkMessageGetByte(lua_State* L) { // networkMessage:getByte() - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { lua_pushnumber(L, message->getByte()); } else { @@ -42,7 +33,7 @@ int NetworkMessageFunctions::luaNetworkMessageGetByte(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageGetU16(lua_State* L) { // networkMessage:getU16() - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { lua_pushnumber(L, message->get()); } else { @@ -53,7 +44,7 @@ int NetworkMessageFunctions::luaNetworkMessageGetU16(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageGetU32(lua_State* L) { // networkMessage:getU32() - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { lua_pushnumber(L, message->get()); } else { @@ -64,7 +55,7 @@ int NetworkMessageFunctions::luaNetworkMessageGetU32(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageGetU64(lua_State* L) { // networkMessage:getU64() - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { lua_pushnumber(L, message->get()); } else { @@ -75,7 +66,7 @@ int NetworkMessageFunctions::luaNetworkMessageGetU64(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageGetString(lua_State* L) { // networkMessage:getString() - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { pushString(L, message->getString()); } else { @@ -86,7 +77,7 @@ int NetworkMessageFunctions::luaNetworkMessageGetString(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageGetPosition(lua_State* L) { // networkMessage:getPosition() - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { pushPosition(L, message->getPosition()); } else { @@ -98,7 +89,7 @@ int NetworkMessageFunctions::luaNetworkMessageGetPosition(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAddByte(lua_State* L) { // networkMessage:addByte(number) uint8_t number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->addByte(number); pushBoolean(L, true); @@ -111,7 +102,7 @@ int NetworkMessageFunctions::luaNetworkMessageAddByte(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAddU16(lua_State* L) { // networkMessage:addU16(number) uint16_t number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->add(number); pushBoolean(L, true); @@ -124,7 +115,7 @@ int NetworkMessageFunctions::luaNetworkMessageAddU16(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAddU32(lua_State* L) { // networkMessage:addU32(number) uint32_t number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->add(number); pushBoolean(L, true); @@ -137,7 +128,7 @@ int NetworkMessageFunctions::luaNetworkMessageAddU32(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAddU64(lua_State* L) { // networkMessage:addU64(number) uint64_t number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->add(number); pushBoolean(L, true); @@ -150,7 +141,7 @@ int NetworkMessageFunctions::luaNetworkMessageAddU64(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAdd8(lua_State* L) { // networkMessage:add8(number) auto number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->add(number); pushBoolean(L, true); @@ -163,7 +154,7 @@ int NetworkMessageFunctions::luaNetworkMessageAdd8(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAdd16(lua_State* L) { // networkMessage:add16(number) auto number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->add(number); pushBoolean(L, true); @@ -176,7 +167,7 @@ int NetworkMessageFunctions::luaNetworkMessageAdd16(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAdd32(lua_State* L) { // networkMessage:add32(number) auto number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->add(number); pushBoolean(L, true); @@ -189,7 +180,7 @@ int NetworkMessageFunctions::luaNetworkMessageAdd32(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAdd64(lua_State* L) { // networkMessage:add64(number) auto number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->add(number); pushBoolean(L, true); @@ -202,7 +193,7 @@ int NetworkMessageFunctions::luaNetworkMessageAdd64(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAddString(lua_State* L) { // networkMessage:addString(string) const std::string &string = getString(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->addString(string); pushBoolean(L, true); @@ -215,7 +206,7 @@ int NetworkMessageFunctions::luaNetworkMessageAddString(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAddPosition(lua_State* L) { // networkMessage:addPosition(position) const Position &position = getPosition(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->addPosition(position); pushBoolean(L, true); @@ -228,7 +219,7 @@ int NetworkMessageFunctions::luaNetworkMessageAddPosition(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAddDouble(lua_State* L) { // networkMessage:addDouble(number) double number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->addDouble(number); pushBoolean(L, true); @@ -240,21 +231,21 @@ int NetworkMessageFunctions::luaNetworkMessageAddDouble(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageAddItem(lua_State* L) { // networkMessage:addItem(item, player) - Item* item = getUserdata(L, 2); + const auto &item = getUserdataShared(L, 2); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); lua_pushnil(L); return 1; } - Player* player = getUserdata(L, 3); + std::shared_ptr player = getUserdataShared(L, 3); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushnil(L); return 1; } - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message && player->client) { player->client->AddItem(*message, item); pushBoolean(L, true); @@ -266,7 +257,7 @@ int NetworkMessageFunctions::luaNetworkMessageAddItem(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageReset(lua_State* L) { // networkMessage:reset() - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->reset(); pushBoolean(L, true); @@ -279,7 +270,7 @@ int NetworkMessageFunctions::luaNetworkMessageReset(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageSkipBytes(lua_State* L) { // networkMessage:skipBytes(number) int16_t number = getNumber(L, 2); - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (message) { message->skipBytes(number); pushBoolean(L, true); @@ -291,13 +282,13 @@ int NetworkMessageFunctions::luaNetworkMessageSkipBytes(lua_State* L) { int NetworkMessageFunctions::luaNetworkMessageSendToPlayer(lua_State* L) { // networkMessage:sendToPlayer(player) - NetworkMessage* message = getUserdata(L, 1); + const auto &message = getUserdataShared(L, 1); if (!message) { lua_pushnil(L); return 1; } - Player* player = getPlayer(L, 2); + const auto &player = getPlayer(L, 2); if (player) { player->sendNetworkMessage(*message); pushBoolean(L, true); diff --git a/src/lua/functions/core/network/network_message_functions.hpp b/src/lua/functions/core/network/network_message_functions.hpp index 637f3366d..df27dbd19 100644 --- a/src/lua/functions/core/network/network_message_functions.hpp +++ b/src/lua/functions/core/network/network_message_functions.hpp @@ -14,10 +14,9 @@ class NetworkMessageFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "NetworkMessage", "", NetworkMessageFunctions::luaNetworkMessageCreate); + registerSharedClass(L, "NetworkMessage", "", NetworkMessageFunctions::luaNetworkMessageCreate); registerMetaMethod(L, "NetworkMessage", "__eq", NetworkMessageFunctions::luaUserdataCompare); - registerMetaMethod(L, "NetworkMessage", "__gc", NetworkMessageFunctions::luaNetworkMessageDelete); - registerMethod(L, "NetworkMessage", "delete", NetworkMessageFunctions::luaNetworkMessageDelete); + registerMethod(L, "NetworkMessage", "delete", luaGarbageCollection); registerMethod(L, "NetworkMessage", "getByte", NetworkMessageFunctions::luaNetworkMessageGetByte); registerMethod(L, "NetworkMessage", "getU16", NetworkMessageFunctions::luaNetworkMessageGetU16); @@ -46,7 +45,6 @@ class NetworkMessageFunctions final : LuaScriptInterface { private: static int luaNetworkMessageCreate(lua_State* L); - static int luaNetworkMessageDelete(lua_State* L); static int luaNetworkMessageGetByte(lua_State* L); static int luaNetworkMessageGetU16(lua_State* L); diff --git a/src/lua/functions/creatures/combat/combat_functions.cpp b/src/lua/functions/creatures/combat/combat_functions.cpp index 50488ac0a..6c1529726 100644 --- a/src/lua/functions/creatures/combat/combat_functions.cpp +++ b/src/lua/functions/creatures/combat/combat_functions.cpp @@ -16,14 +16,14 @@ int CombatFunctions::luaCombatCreate(lua_State* L) { // Combat() - pushUserdata(L, g_luaEnvironment().createCombatObject(getScriptEnv()->getScriptInterface()).get()); + pushUserdata(L, g_luaEnvironment().createCombatObject(getScriptEnv()->getScriptInterface())); setMetatable(L, -1, "Combat"); return 1; } int CombatFunctions::luaCombatSetParameter(lua_State* L) { // combat:setParameter(key, value) - Combat* combat = getUserdata(L, 1); + const auto &combat = getUserdataShared(L, 1); if (!combat) { lua_pushnil(L); return 1; @@ -43,7 +43,7 @@ int CombatFunctions::luaCombatSetParameter(lua_State* L) { int CombatFunctions::luaCombatSetFormula(lua_State* L) { // combat:setFormula(type, mina, minb, maxa, maxb) - Combat* combat = getUserdata(L, 1); + const auto &combat = getUserdataShared(L, 1); if (!combat) { lua_pushnil(L); return 1; @@ -67,16 +67,17 @@ int CombatFunctions::luaCombatSetArea(lua_State* L) { return 1; } - const AreaCombat* area = g_luaEnvironment().getAreaObject(getNumber(L, 2)); + const std::unique_ptr &area = g_luaEnvironment().getAreaObject(getNumber(L, 2)); if (!area) { reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND)); lua_pushnil(L); return 1; } - Combat* combat = getUserdata(L, 1); + const auto &combat = getUserdataShared(L, 1); if (combat) { - combat->setArea(new AreaCombat(*area)); + auto areaClone = area->clone(); + combat->setArea(areaClone); pushBoolean(L, true); } else { lua_pushnil(L); @@ -86,8 +87,8 @@ int CombatFunctions::luaCombatSetArea(lua_State* L) { int CombatFunctions::luaCombatSetCondition(lua_State* L) { // combat:addCondition(condition) - Condition* condition = getUserdata(L, 2); - Combat* combat = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 2); + const auto &combat = getUserdataShared(L, 1); if (combat && condition) { combat->addCondition(condition->clone()); pushBoolean(L, true); @@ -99,7 +100,7 @@ int CombatFunctions::luaCombatSetCondition(lua_State* L) { int CombatFunctions::luaCombatSetCallback(lua_State* L) { // combat:setCallback(key, function) - Combat* combat = getUserdata(L, 1); + const auto &combat = getUserdataShared(L, 1); if (!combat) { lua_pushnil(L); return 1; @@ -124,7 +125,7 @@ int CombatFunctions::luaCombatSetCallback(lua_State* L) { int CombatFunctions::luaCombatSetOrigin(lua_State* L) { // combat:setOrigin(origin) - Combat* combat = getUserdata(L, 1); + const auto &combat = getUserdataShared(L, 1); if (combat) { combat->setOrigin(getNumber(L, 2)); pushBoolean(L, true); @@ -136,7 +137,7 @@ int CombatFunctions::luaCombatSetOrigin(lua_State* L) { int CombatFunctions::luaCombatExecute(lua_State* L) { // combat:execute(creature, variant) - Combat* combat = getUserdata(L, 1); + const auto &combat = getUserdataShared(L, 1); if (!combat) { pushBoolean(L, false); return 1; @@ -150,7 +151,7 @@ int CombatFunctions::luaCombatExecute(lua_State* L) { } } - Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); const LuaVariant &variant = getVariant(L, 3); combat->setInstantSpellName(variant.instantName); @@ -158,7 +159,7 @@ int CombatFunctions::luaCombatExecute(lua_State* L) { bool result = true; switch (variant.type) { case VARIANT_NUMBER: { - Creature* target = g_game().getCreatureByID(variant.number); + std::shared_ptr target = g_game().getCreatureByID(variant.number); if (!target) { pushBoolean(L, false); return 1; @@ -188,7 +189,7 @@ int CombatFunctions::luaCombatExecute(lua_State* L) { } case VARIANT_STRING: { - Player* target = g_game().getPlayerByName(variant.text); + std::shared_ptr target = g_game().getPlayerByName(variant.text); if (!target) { pushBoolean(L, false); return 1; diff --git a/src/lua/functions/creatures/combat/combat_functions.hpp b/src/lua/functions/creatures/combat/combat_functions.hpp index b6816c565..652255d7a 100644 --- a/src/lua/functions/creatures/combat/combat_functions.hpp +++ b/src/lua/functions/creatures/combat/combat_functions.hpp @@ -17,7 +17,7 @@ class CombatFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Combat", "", CombatFunctions::luaCombatCreate); + registerSharedClass(L, "Combat", "", CombatFunctions::luaCombatCreate); registerMetaMethod(L, "Combat", "__eq", CombatFunctions::luaUserdataCompare); registerMethod(L, "Combat", "setParameter", CombatFunctions::luaCombatSetParameter); diff --git a/src/lua/functions/creatures/combat/condition_functions.cpp b/src/lua/functions/creatures/combat/condition_functions.cpp index ac49eb6ff..efd468ac3 100644 --- a/src/lua/functions/creatures/combat/condition_functions.cpp +++ b/src/lua/functions/creatures/combat/condition_functions.cpp @@ -19,7 +19,7 @@ int ConditionFunctions::luaConditionCreate(lua_State* L) { ConditionId_t conditionId = getNumber(L, 3, CONDITIONID_COMBAT); uint32_t subId = getNumber(L, 4, 0); - Condition* condition = Condition::createCondition(conditionId, conditionType, 0, 0, false, subId); + std::shared_ptr condition = Condition::createCondition(conditionId, conditionType, 0, 0, false, subId); if (condition) { pushUserdata(L, condition); setMetatable(L, -1, "Condition"); @@ -31,17 +31,16 @@ int ConditionFunctions::luaConditionCreate(lua_State* L) { int ConditionFunctions::luaConditionDelete(lua_State* L) { // condition:delete() - Condition** conditionPtr = getRawUserdata(L, 1); + std::shared_ptr* conditionPtr = getRawUserDataShared(L, 1); if (conditionPtr && *conditionPtr) { - delete *conditionPtr; - *conditionPtr = nullptr; + conditionPtr->reset(); } return 0; } int ConditionFunctions::luaConditionGetId(lua_State* L) { // condition:getId() - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (condition) { lua_pushnumber(L, condition->getId()); } else { @@ -52,7 +51,7 @@ int ConditionFunctions::luaConditionGetId(lua_State* L) { int ConditionFunctions::luaConditionGetSubId(lua_State* L) { // condition:getSubId() - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (condition) { lua_pushnumber(L, condition->getSubId()); } else { @@ -63,7 +62,7 @@ int ConditionFunctions::luaConditionGetSubId(lua_State* L) { int ConditionFunctions::luaConditionGetType(lua_State* L) { // condition:getType() - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (condition) { lua_pushnumber(L, condition->getType()); } else { @@ -74,7 +73,7 @@ int ConditionFunctions::luaConditionGetType(lua_State* L) { int ConditionFunctions::luaConditionGetIcons(lua_State* L) { // condition:getIcons() - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (condition) { lua_pushnumber(L, condition->getIcons()); } else { @@ -85,7 +84,7 @@ int ConditionFunctions::luaConditionGetIcons(lua_State* L) { int ConditionFunctions::luaConditionGetEndTime(lua_State* L) { // condition:getEndTime() - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (condition) { lua_pushnumber(L, condition->getEndTime()); } else { @@ -96,7 +95,7 @@ int ConditionFunctions::luaConditionGetEndTime(lua_State* L) { int ConditionFunctions::luaConditionClone(lua_State* L) { // condition:clone() - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (condition) { pushUserdata(L, condition->clone()); setMetatable(L, -1, "Condition"); @@ -108,7 +107,7 @@ int ConditionFunctions::luaConditionClone(lua_State* L) { int ConditionFunctions::luaConditionGetTicks(lua_State* L) { // condition:getTicks() - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (condition) { lua_pushnumber(L, condition->getTicks()); } else { @@ -120,7 +119,7 @@ int ConditionFunctions::luaConditionGetTicks(lua_State* L) { int ConditionFunctions::luaConditionSetTicks(lua_State* L) { // condition:setTicks(ticks) int32_t ticks = getNumber(L, 2); - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (condition) { condition->setTicks(ticks); pushBoolean(L, true); @@ -132,7 +131,7 @@ int ConditionFunctions::luaConditionSetTicks(lua_State* L) { int ConditionFunctions::luaConditionSetParameter(lua_State* L) { // condition:setParameter(key, value) - Condition* condition = getUserdata(L, 1); + std::shared_ptr condition = getUserdataShared(L, 1); if (!condition) { lua_pushnil(L); return 1; @@ -156,7 +155,7 @@ int ConditionFunctions::luaConditionSetFormula(lua_State* L) { double maxa = getNumber(L, 4); double minb = getNumber(L, 3); double mina = getNumber(L, 2); - ConditionSpeed* condition = dynamic_cast(getUserdata(L, 1)); + std::shared_ptr condition = getUserdataShared(L, 1)->dynamic_self_cast(); if (condition) { condition->setFormulaVars(mina, minb, maxa, maxb); pushBoolean(L, true); @@ -189,7 +188,7 @@ int ConditionFunctions::luaConditionSetOutfit(lua_State* L) { outfit.lookTypeEx = getNumber(L, 2); } - ConditionOutfit* condition = dynamic_cast(getUserdata(L, 1)); + std::shared_ptr condition = getUserdataShared(L, 1)->dynamic_self_cast(); if (condition) { condition->setOutfit(outfit); pushBoolean(L, true); @@ -204,7 +203,7 @@ int ConditionFunctions::luaConditionAddDamage(lua_State* L) { int32_t value = getNumber(L, 4); int32_t time = getNumber(L, 3); int32_t rounds = getNumber(L, 2); - ConditionDamage* condition = dynamic_cast(getUserdata(L, 1)); + std::shared_ptr condition = getUserdataShared(L, 1)->dynamic_self_cast(); if (condition) { pushBoolean(L, condition->addDamage(rounds, time, value)); } else { diff --git a/src/lua/functions/creatures/combat/condition_functions.hpp b/src/lua/functions/creatures/combat/condition_functions.hpp index 5c2e7a277..7357cf9a9 100644 --- a/src/lua/functions/creatures/combat/condition_functions.hpp +++ b/src/lua/functions/creatures/combat/condition_functions.hpp @@ -14,7 +14,7 @@ class ConditionFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Condition", "", ConditionFunctions::luaConditionCreate); + registerSharedClass(L, "Condition", "", ConditionFunctions::luaConditionCreate); registerMetaMethod(L, "Condition", "__eq", ConditionFunctions::luaUserdataCompare); registerMetaMethod(L, "Condition", "__gc", ConditionFunctions::luaConditionDelete); registerMethod(L, "Condition", "delete", ConditionFunctions::luaConditionDelete); diff --git a/src/lua/functions/creatures/combat/spell_functions.cpp b/src/lua/functions/creatures/combat/spell_functions.cpp index 00bd785c6..3691645e2 100644 --- a/src/lua/functions/creatures/combat/spell_functions.cpp +++ b/src/lua/functions/creatures/combat/spell_functions.cpp @@ -88,8 +88,8 @@ int SpellFunctions::luaSpellOnCastSpell(lua_State* L) { const auto spell = getUserdataShared(L, 1); if (spell) { if (spell->spellType == SPELL_INSTANT) { - const auto &spellBase = getUserdataShared(L, 1); - const auto &instant = std::static_pointer_cast(spellBase); + const auto spellBase = getUserdataShared(L, 1); + const auto instant = std::static_pointer_cast(spellBase); if (!instant->loadCallback()) { pushBoolean(L, false); return 1; @@ -122,16 +122,16 @@ int SpellFunctions::luaSpellRegister(lua_State* L) { } if (spell->spellType == SPELL_INSTANT) { - const auto &spellBase = getUserdataShared(L, 1); - const auto &instant = std::static_pointer_cast(spellBase); + const auto spellBase = getUserdataShared(L, 1); + const auto instant = std::static_pointer_cast(spellBase); if (!instant->isLoadedCallback()) { pushBoolean(L, false); return 1; } pushBoolean(L, g_spells().registerInstantLuaEvent(instant)); } else if (spell->spellType == SPELL_RUNE) { - const auto &spellBase = getUserdataShared(L, 1); - const auto &rune = std::static_pointer_cast(spellBase); + const auto spellBase = getUserdataShared(L, 1); + const auto rune = std::static_pointer_cast(spellBase); if (rune->getMagicLevel() != 0 || rune->getLevel() != 0) { // Change information in the ItemType to get accurate description ItemType &iType = Item::items.getItemType(rune->getRuneItemId()); @@ -636,7 +636,7 @@ int SpellFunctions::luaSpellVocation(lua_State* L) { // only for InstantSpells int SpellFunctions::luaSpellWords(lua_State* L) { // spell:words(words[, separator = ""]) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_INSTANT, it means that this actually is no InstantSpell, so we return nil @@ -667,7 +667,7 @@ int SpellFunctions::luaSpellWords(lua_State* L) { // only for InstantSpells int SpellFunctions::luaSpellNeedDirection(lua_State* L) { // spell:needDirection(bool) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_INSTANT, it means that this actually is no InstantSpell, so we return nil @@ -691,7 +691,7 @@ int SpellFunctions::luaSpellNeedDirection(lua_State* L) { // only for InstantSpells int SpellFunctions::luaSpellHasParams(lua_State* L) { // spell:hasParams(bool) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_INSTANT, it means that this actually is no InstantSpell, so we return nil @@ -715,7 +715,7 @@ int SpellFunctions::luaSpellHasParams(lua_State* L) { // only for InstantSpells int SpellFunctions::luaSpellHasPlayerNameParam(lua_State* L) { // spell:hasPlayerNameParam(bool) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_INSTANT, it means that this actually is no InstantSpell, so we return nil @@ -739,7 +739,7 @@ int SpellFunctions::luaSpellHasPlayerNameParam(lua_State* L) { // only for InstantSpells int SpellFunctions::luaSpellNeedCasterTargetOrDirection(lua_State* L) { // spell:needCasterTargetOrDirection(bool) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_INSTANT, it means that this actually is no InstantSpell, so we return nil @@ -763,7 +763,7 @@ int SpellFunctions::luaSpellNeedCasterTargetOrDirection(lua_State* L) { // only for InstantSpells int SpellFunctions::luaSpellIsBlockingWalls(lua_State* L) { // spell:blockWalls(bool) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_INSTANT, it means that this actually is no InstantSpell, so we return nil @@ -787,7 +787,7 @@ int SpellFunctions::luaSpellIsBlockingWalls(lua_State* L) { // only for RuneSpells int SpellFunctions::luaSpellRuneId(lua_State* L) { // spell:runeId(id) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_RUNE, it means that this actually is no RuneSpell, so we return nil @@ -811,7 +811,7 @@ int SpellFunctions::luaSpellRuneId(lua_State* L) { // only for RuneSpells int SpellFunctions::luaSpellCharges(lua_State* L) { // spell:charges(charges) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_RUNE, it means that this actually is no RuneSpell, so we return nil @@ -835,7 +835,7 @@ int SpellFunctions::luaSpellCharges(lua_State* L) { // only for RuneSpells int SpellFunctions::luaSpellAllowFarUse(lua_State* L) { // spell:allowFarUse(bool) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_RUNE, it means that this actually is no RuneSpell, so we return nil @@ -859,7 +859,7 @@ int SpellFunctions::luaSpellAllowFarUse(lua_State* L) { // only for RuneSpells int SpellFunctions::luaSpellBlockWalls(lua_State* L) { // spell:blockWalls(bool) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_RUNE, it means that this actually is no RuneSpell, so we return nil @@ -883,7 +883,7 @@ int SpellFunctions::luaSpellBlockWalls(lua_State* L) { // only for RuneSpells int SpellFunctions::luaSpellCheckFloor(lua_State* L) { // spell:checkFloor(bool) - const auto &spellBase = getUserdataShared(L, 1); + const auto spellBase = getUserdataShared(L, 1); const auto spell = std::static_pointer_cast(spellBase); if (spell) { // if spell != SPELL_RUNE, it means that this actually is no RuneSpell, so we return nil diff --git a/src/lua/functions/creatures/combat/variant_functions.cpp b/src/lua/functions/creatures/combat/variant_functions.cpp index 28d914315..4741e69ed 100644 --- a/src/lua/functions/creatures/combat/variant_functions.cpp +++ b/src/lua/functions/creatures/combat/variant_functions.cpp @@ -16,7 +16,7 @@ int VariantFunctions::luaVariantCreate(lua_State* L) { // Variant(number or string or position or thing) LuaVariant variant; if (isUserdata(L, 2)) { - if (Thing* thing = getThing(L, 2)) { + if (std::shared_ptr thing = getThing(L, 2)) { variant.type = VARIANT_TARGETPOSITION; variant.pos = thing->getPosition(); } diff --git a/src/lua/functions/creatures/creature_functions.cpp b/src/lua/functions/creatures/creature_functions.cpp index d1ec3d19d..6257bf1ea 100644 --- a/src/lua/functions/creatures/creature_functions.cpp +++ b/src/lua/functions/creatures/creature_functions.cpp @@ -15,7 +15,7 @@ int CreatureFunctions::luaCreatureCreate(lua_State* L) { // Creature(id or name or userdata) - Creature* creature; + std::shared_ptr creature; if (isNumber(L, 2)) { creature = g_game().getCreatureByID(getNumber(L, 2)); } else if (isString(L, 2)) { @@ -26,7 +26,7 @@ int CreatureFunctions::luaCreatureCreate(lua_State* L) { lua_pushnil(L); return 1; } - creature = getUserdata(L, 2); + creature = getUserdataShared(L, 2); } else { creature = nullptr; } @@ -42,14 +42,14 @@ int CreatureFunctions::luaCreatureCreate(lua_State* L) { int CreatureFunctions::luaCreatureGetEvents(lua_State* L) { // creature:getEvents(type) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; } CreatureEventType_t eventType = getNumber(L, 2); - const auto &eventList = creature->getCreatureEvents(eventType); + const auto eventList = creature->getCreatureEvents(eventType); lua_createtable(L, static_cast(eventList.size()), 0); int index = 0; @@ -62,7 +62,7 @@ int CreatureFunctions::luaCreatureGetEvents(lua_State* L) { int CreatureFunctions::luaCreatureRegisterEvent(lua_State* L) { // creature:registerEvent(name) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { const std::string &name = getString(L, 2); pushBoolean(L, creature->registerCreatureEvent(name)); @@ -75,7 +75,7 @@ int CreatureFunctions::luaCreatureRegisterEvent(lua_State* L) { int CreatureFunctions::luaCreatureUnregisterEvent(lua_State* L) { // creature:unregisterEvent(name) const std::string &name = getString(L, 2); - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushBoolean(L, creature->unregisterCreatureEvent(name)); } else { @@ -86,7 +86,7 @@ int CreatureFunctions::luaCreatureUnregisterEvent(lua_State* L) { int CreatureFunctions::luaCreatureIsRemoved(lua_State* L) { // creature:isRemoved() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushBoolean(L, creature->isRemoved()); } else { @@ -97,13 +97,13 @@ int CreatureFunctions::luaCreatureIsRemoved(lua_State* L) { int CreatureFunctions::luaCreatureIsCreature(lua_State* L) { // creature:isCreature() - pushBoolean(L, getUserdata(L, 1) != nullptr); + pushBoolean(L, getUserdataShared(L, 1) != nullptr); return 1; } int CreatureFunctions::luaCreatureIsInGhostMode(lua_State* L) { // creature:isInGhostMode() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushBoolean(L, creature->isInGhostMode()); } else { @@ -114,7 +114,7 @@ int CreatureFunctions::luaCreatureIsInGhostMode(lua_State* L) { int CreatureFunctions::luaCreatureIsHealthHidden(lua_State* L) { // creature:isHealthHidden() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushBoolean(L, creature->isHealthHidden()); } else { @@ -125,7 +125,7 @@ int CreatureFunctions::luaCreatureIsHealthHidden(lua_State* L) { int CreatureFunctions::luaCreatureCanSee(lua_State* L) { // creature:canSee(position) - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { const Position &position = getPosition(L, 2); pushBoolean(L, creature->canSee(position)); @@ -137,9 +137,9 @@ int CreatureFunctions::luaCreatureCanSee(lua_State* L) { int CreatureFunctions::luaCreatureCanSeeCreature(lua_State* L) { // creature:canSeeCreature(creature) - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { - const Creature* otherCreature = getCreature(L, 2); + std::shared_ptr otherCreature = getCreature(L, 2); pushBoolean(L, creature->canSeeCreature(otherCreature)); } else { lua_pushnil(L); @@ -149,13 +149,13 @@ int CreatureFunctions::luaCreatureCanSeeCreature(lua_State* L) { int CreatureFunctions::luaCreatureGetParent(lua_State* L) { // creature:getParent() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; } - Cylinder* parent = creature->getParent(); + std::shared_ptr parent = creature->getParent(); if (!parent) { lua_pushnil(L); return 1; @@ -167,7 +167,7 @@ int CreatureFunctions::luaCreatureGetParent(lua_State* L) { int CreatureFunctions::luaCreatureGetId(lua_State* L) { // creature:getId() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { lua_pushnumber(L, creature->getID()); } else { @@ -178,7 +178,7 @@ int CreatureFunctions::luaCreatureGetId(lua_State* L) { int CreatureFunctions::luaCreatureGetName(lua_State* L) { // creature:getName() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushString(L, creature->getName()); } else { @@ -189,7 +189,7 @@ int CreatureFunctions::luaCreatureGetName(lua_State* L) { int CreatureFunctions::luaCreatureGetTypeName(lua_State* L) { // creature:getTypeName() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushString(L, creature->getTypeName()); } else { @@ -200,13 +200,13 @@ int CreatureFunctions::luaCreatureGetTypeName(lua_State* L) { int CreatureFunctions::luaCreatureGetTarget(lua_State* L) { // creature:getTarget() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; } - Creature* target = creature->getAttackedCreature(); + std::shared_ptr target = creature->getAttackedCreature(); if (target) { pushUserdata(L, target); setCreatureMetatable(L, -1, target); @@ -218,9 +218,9 @@ int CreatureFunctions::luaCreatureGetTarget(lua_State* L) { int CreatureFunctions::luaCreatureSetTarget(lua_State* L) { // creature:setTarget(target) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { - Creature* target = getCreature(L, 2); + std::shared_ptr target = getCreature(L, 2); pushBoolean(L, creature->setAttackedCreature(target)); } else { lua_pushnil(L); @@ -230,13 +230,13 @@ int CreatureFunctions::luaCreatureSetTarget(lua_State* L) { int CreatureFunctions::luaCreatureGetFollowCreature(lua_State* L) { // creature:getFollowCreature() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; } - Creature* followCreature = creature->getFollowCreature(); + std::shared_ptr followCreature = creature->getFollowCreature(); if (followCreature) { pushUserdata(L, followCreature); setCreatureMetatable(L, -1, followCreature); @@ -248,9 +248,9 @@ int CreatureFunctions::luaCreatureGetFollowCreature(lua_State* L) { int CreatureFunctions::luaCreatureSetFollowCreature(lua_State* L) { // creature:setFollowCreature(followedCreature) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { - Creature* followCreature = getCreature(L, 2); + std::shared_ptr followCreature = getCreature(L, 2); pushBoolean(L, creature->setFollowCreature(followCreature)); } else { lua_pushnil(L); @@ -260,13 +260,13 @@ int CreatureFunctions::luaCreatureSetFollowCreature(lua_State* L) { int CreatureFunctions::luaCreatureGetMaster(lua_State* L) { // creature:getMaster() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; } - Creature* master = creature->getMaster(); + std::shared_ptr master = creature->getMaster(); if (!master) { lua_pushnil(L); return 1; @@ -279,7 +279,7 @@ int CreatureFunctions::luaCreatureGetMaster(lua_State* L) { int CreatureFunctions::luaCreatureReload(lua_State* L) { // creature:reload() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -292,7 +292,7 @@ int CreatureFunctions::luaCreatureReload(lua_State* L) { int CreatureFunctions::luaCreatureSetMaster(lua_State* L) { // creature:setMaster(master) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -306,7 +306,7 @@ int CreatureFunctions::luaCreatureSetMaster(lua_State* L) { int CreatureFunctions::luaCreatureGetLight(lua_State* L) { // creature:getLight() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -320,7 +320,7 @@ int CreatureFunctions::luaCreatureGetLight(lua_State* L) { int CreatureFunctions::luaCreatureSetLight(lua_State* L) { // creature:setLight(color, level) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -337,7 +337,7 @@ int CreatureFunctions::luaCreatureSetLight(lua_State* L) { int CreatureFunctions::luaCreatureGetSpeed(lua_State* L) { // creature:getSpeed() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { lua_pushnumber(L, creature->getSpeed()); } else { @@ -348,7 +348,7 @@ int CreatureFunctions::luaCreatureGetSpeed(lua_State* L) { int CreatureFunctions::luaCreatureSetSpeed(lua_State* L) { // creature:setSpeed(speed) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -363,7 +363,7 @@ int CreatureFunctions::luaCreatureSetSpeed(lua_State* L) { int CreatureFunctions::luaCreatureGetBaseSpeed(lua_State* L) { // creature:getBaseSpeed() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { lua_pushnumber(L, creature->getBaseSpeed()); } else { @@ -374,7 +374,7 @@ int CreatureFunctions::luaCreatureGetBaseSpeed(lua_State* L) { int CreatureFunctions::luaCreatureChangeSpeed(lua_State* L) { // creature:changeSpeed(delta) - Creature* creature = getCreature(L, 1); + std::shared_ptr creature = getCreature(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -389,7 +389,7 @@ int CreatureFunctions::luaCreatureChangeSpeed(lua_State* L) { int CreatureFunctions::luaCreatureSetDropLoot(lua_State* L) { // creature:setDropLoot(doDrop) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { creature->setDropLoot(getBoolean(L, 2)); pushBoolean(L, true); @@ -401,7 +401,7 @@ int CreatureFunctions::luaCreatureSetDropLoot(lua_State* L) { int CreatureFunctions::luaCreatureSetSkillLoss(lua_State* L) { // creature:setSkillLoss(skillLoss) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { creature->setSkillLoss(getBoolean(L, 2)); pushBoolean(L, true); @@ -413,7 +413,7 @@ int CreatureFunctions::luaCreatureSetSkillLoss(lua_State* L) { int CreatureFunctions::luaCreatureGetPosition(lua_State* L) { // creature:getPosition() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushPosition(L, creature->getPosition()); } else { @@ -424,13 +424,13 @@ int CreatureFunctions::luaCreatureGetPosition(lua_State* L) { int CreatureFunctions::luaCreatureGetTile(lua_State* L) { // creature:getTile() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; } - Tile* tile = creature->getTile(); + std::shared_ptr tile = creature->getTile(); if (tile) { pushUserdata(L, tile); setMetatable(L, -1, "Tile"); @@ -442,7 +442,7 @@ int CreatureFunctions::luaCreatureGetTile(lua_State* L) { int CreatureFunctions::luaCreatureGetDirection(lua_State* L) { // creature:getDirection() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { lua_pushnumber(L, creature->getDirection()); } else { @@ -453,7 +453,7 @@ int CreatureFunctions::luaCreatureGetDirection(lua_State* L) { int CreatureFunctions::luaCreatureSetDirection(lua_State* L) { // creature:setDirection(direction) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushBoolean(L, g_game().internalCreatureTurn(creature, getNumber(L, 2))); } else { @@ -464,7 +464,7 @@ int CreatureFunctions::luaCreatureSetDirection(lua_State* L) { int CreatureFunctions::luaCreatureGetHealth(lua_State* L) { // creature:getHealth() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { lua_pushnumber(L, creature->getHealth()); } else { @@ -475,7 +475,7 @@ int CreatureFunctions::luaCreatureGetHealth(lua_State* L) { int CreatureFunctions::luaCreatureSetHealth(lua_State* L) { // creature:setHealth(health) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -484,7 +484,7 @@ int CreatureFunctions::luaCreatureSetHealth(lua_State* L) { creature->health = std::min(getNumber(L, 2), creature->healthMax); g_game().addCreatureHealth(creature); - Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player) { player->sendStats(); } @@ -494,7 +494,7 @@ int CreatureFunctions::luaCreatureSetHealth(lua_State* L) { int CreatureFunctions::luaCreatureAddHealth(lua_State* L) { // creature:addHealth(healthChange, combatType) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -515,7 +515,7 @@ int CreatureFunctions::luaCreatureAddHealth(lua_State* L) { int CreatureFunctions::luaCreatureGetMaxHealth(lua_State* L) { // creature:getMaxHealth() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { lua_pushnumber(L, creature->getMaxHealth()); } else { @@ -526,7 +526,7 @@ int CreatureFunctions::luaCreatureGetMaxHealth(lua_State* L) { int CreatureFunctions::luaCreatureSetMaxHealth(lua_State* L) { // creature:setMaxHealth(maxHealth) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -536,7 +536,7 @@ int CreatureFunctions::luaCreatureSetMaxHealth(lua_State* L) { creature->health = std::min(creature->health, creature->healthMax); g_game().addCreatureHealth(creature); - Player* player = creature->getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player) { player->sendStats(); } @@ -546,7 +546,7 @@ int CreatureFunctions::luaCreatureSetMaxHealth(lua_State* L) { int CreatureFunctions::luaCreatureSetHiddenHealth(lua_State* L) { // creature:setHiddenHealth(hide) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { creature->setHiddenHealth(getBoolean(L, 2)); g_game().addCreatureHealth(creature); @@ -559,7 +559,7 @@ int CreatureFunctions::luaCreatureSetHiddenHealth(lua_State* L) { int CreatureFunctions::luaCreatureIsMoveLocked(lua_State* L) { // creature:isMoveLocked() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushBoolean(L, creature->isMoveLocked()); } else { @@ -570,7 +570,7 @@ int CreatureFunctions::luaCreatureIsMoveLocked(lua_State* L) { int CreatureFunctions::luaCreatureSetMoveLocked(lua_State* L) { // creature:setMoveLocked(moveLocked) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { creature->setMoveLocked(getBoolean(L, 2)); pushBoolean(L, true); @@ -582,7 +582,7 @@ int CreatureFunctions::luaCreatureSetMoveLocked(lua_State* L) { int CreatureFunctions::luaCreatureGetSkull(lua_State* L) { // creature:getSkull() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { lua_pushnumber(L, creature->getSkull()); } else { @@ -593,7 +593,7 @@ int CreatureFunctions::luaCreatureGetSkull(lua_State* L) { int CreatureFunctions::luaCreatureSetSkull(lua_State* L) { // creature:setSkull(skull) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { creature->setSkull(getNumber(L, 2)); pushBoolean(L, true); @@ -605,7 +605,7 @@ int CreatureFunctions::luaCreatureSetSkull(lua_State* L) { int CreatureFunctions::luaCreatureGetOutfit(lua_State* L) { // creature:getOutfit() - const Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushOutfit(L, creature->getCurrentOutfit()); } else { @@ -616,7 +616,7 @@ int CreatureFunctions::luaCreatureGetOutfit(lua_State* L) { int CreatureFunctions::luaCreatureSetOutfit(lua_State* L) { // creature:setOutfit(outfit) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { Outfit_t outfit = getOutfit(L, 2); if (g_configManager().getBoolean(WARN_UNSAFE_SCRIPTS) && outfit.lookType != 0 && !g_game().isLookTypeRegistered(outfit.lookType)) { @@ -635,7 +635,7 @@ int CreatureFunctions::luaCreatureSetOutfit(lua_State* L) { int CreatureFunctions::luaCreatureGetCondition(lua_State* L) { // creature:getCondition(conditionType[, conditionId = CONDITIONID_COMBAT[, subId = 0]]) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -645,7 +645,7 @@ int CreatureFunctions::luaCreatureGetCondition(lua_State* L) { ConditionId_t conditionId = getNumber(L, 3, CONDITIONID_COMBAT); uint32_t subId = getNumber(L, 4, 0); - const Condition* condition = creature->getCondition(conditionType, conditionId, subId); + const std::shared_ptr condition = creature->getCondition(conditionType, conditionId, subId); if (condition) { pushUserdata(L, condition); setWeakMetatable(L, -1, "Condition"); @@ -657,8 +657,8 @@ int CreatureFunctions::luaCreatureGetCondition(lua_State* L) { int CreatureFunctions::luaCreatureAddCondition(lua_State* L) { // creature:addCondition(condition) - Creature* creature = getUserdata(L, 1); - Condition* condition = getUserdata(L, 2); + std::shared_ptr creature = getUserdataShared(L, 1); + std::shared_ptr condition = getUserdataShared(L, 2); if (creature && condition) { pushBoolean(L, creature->addCondition(condition->clone())); } else { @@ -669,7 +669,7 @@ int CreatureFunctions::luaCreatureAddCondition(lua_State* L) { int CreatureFunctions::luaCreatureRemoveCondition(lua_State* L) { // creature:removeCondition(conditionType[, conditionId = CONDITIONID_COMBAT[, subId = 0[, force = false]]]) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -678,7 +678,7 @@ int CreatureFunctions::luaCreatureRemoveCondition(lua_State* L) { ConditionType_t conditionType = getNumber(L, 2); ConditionId_t conditionId = getNumber(L, 3, CONDITIONID_COMBAT); uint32_t subId = getNumber(L, 4, 0); - const Condition* condition = creature->getCondition(conditionType, conditionId, subId); + const std::shared_ptr condition = creature->getCondition(conditionType, conditionId, subId); if (condition) { bool force = getBoolean(L, 5, false); creature->removeCondition(conditionType, conditionId, force); @@ -691,7 +691,7 @@ int CreatureFunctions::luaCreatureRemoveCondition(lua_State* L) { int CreatureFunctions::luaCreatureHasCondition(lua_State* L) { // creature:hasCondition(conditionType[, subId = 0]) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -705,7 +705,7 @@ int CreatureFunctions::luaCreatureHasCondition(lua_State* L) { int CreatureFunctions::luaCreatureIsImmune(lua_State* L) { // creature:isImmune(condition or conditionType) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -713,7 +713,7 @@ int CreatureFunctions::luaCreatureIsImmune(lua_State* L) { if (isNumber(L, 2)) { pushBoolean(L, creature->isImmune(getNumber(L, 2))); - } else if (Condition* condition = getUserdata(L, 2)) { + } else if (auto condition = getUserdataShared(L, 2)) { pushBoolean(L, creature->isImmune(condition->getType())); } else { lua_pushnil(L); @@ -723,20 +723,20 @@ int CreatureFunctions::luaCreatureIsImmune(lua_State* L) { int CreatureFunctions::luaCreatureRemove(lua_State* L) { // creature:remove([forced = true]) - Creature** creaturePtr = getRawUserdata(L, 1); + std::shared_ptr* creaturePtr = getRawUserDataShared(L, 1); if (!creaturePtr) { lua_pushnil(L); return 1; } - Creature* creature = *creaturePtr; + std::shared_ptr creature = *creaturePtr; if (!creature) { lua_pushnil(L); return 1; } bool forced = getBoolean(L, 2, true); - if (Player* player = creature->getPlayer()) { + if (std::shared_ptr player = creature->getPlayer()) { if (forced) { player->removePlayer(true); } else { @@ -756,7 +756,7 @@ int CreatureFunctions::luaCreatureTeleportTo(lua_State* L) { bool pushMovement = getBoolean(L, 3, false); const Position &position = getPosition(L, 2); - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature == nullptr) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -802,7 +802,7 @@ int CreatureFunctions::luaCreatureSay(lua_State* L) { } } - Creature* target = nullptr; + std::shared_ptr target = nullptr; if (parameters >= 5) { target = getCreature(L, 5); } @@ -811,7 +811,7 @@ int CreatureFunctions::luaCreatureSay(lua_State* L) { SpeakClasses type = getNumber(L, 3, TALKTYPE_MONSTER_SAY); const std::string &text = getString(L, 2); - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -832,7 +832,7 @@ int CreatureFunctions::luaCreatureSay(lua_State* L) { int CreatureFunctions::luaCreatureGetDamageMap(lua_State* L) { // creature:getDamageMap() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -850,7 +850,7 @@ int CreatureFunctions::luaCreatureGetDamageMap(lua_State* L) { int CreatureFunctions::luaCreatureGetSummons(lua_State* L) { // creature:getSummons() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -859,17 +859,19 @@ int CreatureFunctions::luaCreatureGetSummons(lua_State* L) { lua_createtable(L, creature->getSummonCount(), 0); int index = 0; - for (Creature* summon : creature->getSummons()) { - pushUserdata(L, summon); - setCreatureMetatable(L, -1, summon); - lua_rawseti(L, -2, ++index); + for (const auto &summon : creature->getSummons()) { + if (summon) { + pushUserdata(L, summon); + setCreatureMetatable(L, -1, summon); + lua_rawseti(L, -2, ++index); + } } return 1; } int CreatureFunctions::luaCreatureHasBeenSummoned(lua_State* L) { // creature:hasBeenSummoned() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushBoolean(L, creature->hasBeenSummoned()); } else { @@ -882,7 +884,7 @@ int CreatureFunctions::luaCreatureHasBeenSummoned(lua_State* L) { int CreatureFunctions::luaCreatureGetDescription(lua_State* L) { // creature:getDescription(distance) int32_t distance = getNumber(L, 2); - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { pushString(L, creature->getDescription(distance)); } else { @@ -893,7 +895,7 @@ int CreatureFunctions::luaCreatureGetDescription(lua_State* L) { int CreatureFunctions::luaCreatureGetPathTo(lua_State* L) { // creature:getPathTo(pos[, minTargetDist = 0[, maxTargetDist = 1[, fullPathSearch = true[, clearSight = true[, maxSearchDist = 0]]]]]) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -926,7 +928,7 @@ int CreatureFunctions::luaCreatureGetPathTo(lua_State* L) { int CreatureFunctions::luaCreatureMove(lua_State* L) { // creature:move(direction) // creature:move(tile[, flags = 0]) - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (!creature) { lua_pushnil(L); return 1; @@ -940,19 +942,19 @@ int CreatureFunctions::luaCreatureMove(lua_State* L) { } lua_pushnumber(L, g_game().internalMoveCreature(creature, direction, FLAG_NOLIMIT)); } else { - Tile* tile = getUserdata(L, 2); + std::shared_ptr tile = getUserdataShared(L, 2); if (!tile) { lua_pushnil(L); return 1; } - lua_pushnumber(L, g_game().internalMoveCreature(*creature, *tile, getNumber(L, 3))); + lua_pushnumber(L, g_game().internalMoveCreature(creature, tile, getNumber(L, 3))); } return 1; } int CreatureFunctions::luaCreatureGetZoneType(lua_State* L) { // creature:getZoneType() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { lua_pushnumber(L, creature->getZoneType()); } else { @@ -963,13 +965,13 @@ int CreatureFunctions::luaCreatureGetZoneType(lua_State* L) { int CreatureFunctions::luaCreatureGetZones(lua_State* L) { // creature:getZones() - Creature* creature = getUserdata(L, 1); + std::shared_ptr creature = getUserdataShared(L, 1); if (creature == nullptr) { lua_pushnil(L); return 1; } - const auto &zones = creature->getZones(); + const auto zones = creature->getZones(); lua_createtable(L, static_cast(zones.size()), 0); int index = 0; for (auto zone : zones) { @@ -983,7 +985,7 @@ int CreatureFunctions::luaCreatureGetZones(lua_State* L) { int CreatureFunctions::luaCreatureSetIcon(lua_State* L) { // creature:setIcon(key, category, icon[, number]) - auto creature = getUserdata(L, 1); + auto creature = getUserdataShared(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -1008,7 +1010,7 @@ int CreatureFunctions::luaCreatureSetIcon(lua_State* L) { int CreatureFunctions::luaCreatureGetIcons(lua_State* L) { // creature:getIcons() - const auto creature = getUserdata(L, 1); + const auto creature = getUserdataShared(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -1029,7 +1031,7 @@ int CreatureFunctions::luaCreatureGetIcons(lua_State* L) { int CreatureFunctions::luaCreatureGetIcon(lua_State* L) { // creature:getIcon(key) - const auto creature = getUserdata(L, 1); + const auto creature = getUserdataShared(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -1050,7 +1052,7 @@ int CreatureFunctions::luaCreatureGetIcon(lua_State* L) { int CreatureFunctions::luaCreatureRemoveIcon(lua_State* L) { // creature:removeIcon(key) - auto creature = getUserdata(L, 1); + auto creature = getUserdataShared(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -1064,7 +1066,7 @@ int CreatureFunctions::luaCreatureRemoveIcon(lua_State* L) { int CreatureFunctions::luaCreatureClearIcons(lua_State* L) { // creature:clearIcons() - auto creature = getUserdata(L, 1); + auto creature = getUserdataShared(L, 1); if (!creature) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); diff --git a/src/lua/functions/creatures/creature_functions.hpp b/src/lua/functions/creatures/creature_functions.hpp index 426e48591..af86c5c70 100644 --- a/src/lua/functions/creatures/creature_functions.hpp +++ b/src/lua/functions/creatures/creature_functions.hpp @@ -18,7 +18,7 @@ class CreatureFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Creature", "", CreatureFunctions::luaCreatureCreate); + registerSharedClass(L, "Creature", "", CreatureFunctions::luaCreatureCreate); registerMetaMethod(L, "Creature", "__eq", CreatureFunctions::luaUserdataCompare); registerMethod(L, "Creature", "getEvents", CreatureFunctions::luaCreatureGetEvents); registerMethod(L, "Creature", "registerEvent", CreatureFunctions::luaCreatureRegisterEvent); diff --git a/src/lua/functions/creatures/monster/monster_functions.cpp b/src/lua/functions/creatures/monster/monster_functions.cpp index bca5a2e42..fef180f08 100644 --- a/src/lua/functions/creatures/monster/monster_functions.cpp +++ b/src/lua/functions/creatures/monster/monster_functions.cpp @@ -17,7 +17,7 @@ int MonsterFunctions::luaMonsterCreate(lua_State* L) { // Monster(id or userdata) - Monster* monster; + std::shared_ptr monster; if (isNumber(L, 2)) { monster = g_game().getMonsterByID(getNumber(L, 2)); } else if (isUserdata(L, 2)) { @@ -25,7 +25,7 @@ int MonsterFunctions::luaMonsterCreate(lua_State* L) { lua_pushnil(L); return 1; } - monster = getUserdata(L, 2); + monster = getUserdataShared(L, 2); } else { monster = nullptr; } @@ -41,13 +41,13 @@ int MonsterFunctions::luaMonsterCreate(lua_State* L) { int MonsterFunctions::luaMonsterIsMonster(lua_State* L) { // monster:isMonster() - pushBoolean(L, getUserdata(L, 1) != nullptr); + pushBoolean(L, getUserdataShared(L, 1) != nullptr); return 1; } int MonsterFunctions::luaMonsterGetType(lua_State* L) { // monster:getType() - const Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { pushUserdata(L, monster->mType); setMetatable(L, -1, "MonsterType"); @@ -59,7 +59,7 @@ int MonsterFunctions::luaMonsterGetType(lua_State* L) { int MonsterFunctions::luaMonsterSetType(lua_State* L) { // monster:setType(name or raceid) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { std::shared_ptr mType = nullptr; if (isNumber(L, 2)) { @@ -94,8 +94,8 @@ int MonsterFunctions::luaMonsterSetType(lua_State* L) { // Reload creature on spectators SpectatorHashSet spectators; g_game().map.getSpectators(spectators, monster->getPosition(), true); - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendCreatureReload(monster); } } @@ -108,7 +108,7 @@ int MonsterFunctions::luaMonsterSetType(lua_State* L) { int MonsterFunctions::luaMonsterGetSpawnPosition(lua_State* L) { // monster:getSpawnPosition() - const Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { pushPosition(L, monster->getMasterPos()); } else { @@ -119,7 +119,7 @@ int MonsterFunctions::luaMonsterGetSpawnPosition(lua_State* L) { int MonsterFunctions::luaMonsterIsInSpawnRange(lua_State* L) { // monster:isInSpawnRange([position]) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { pushBoolean(L, monster->isInSpawnRange(lua_gettop(L) >= 2 ? getPosition(L, 2) : monster->getPosition())); } else { @@ -130,7 +130,7 @@ int MonsterFunctions::luaMonsterIsInSpawnRange(lua_State* L) { int MonsterFunctions::luaMonsterIsIdle(lua_State* L) { // monster:isIdle() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { pushBoolean(L, monster->getIdleStatus()); } else { @@ -141,7 +141,7 @@ int MonsterFunctions::luaMonsterIsIdle(lua_State* L) { int MonsterFunctions::luaMonsterSetIdle(lua_State* L) { // monster:setIdle(idle) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { lua_pushnil(L); return 1; @@ -154,9 +154,9 @@ int MonsterFunctions::luaMonsterSetIdle(lua_State* L) { int MonsterFunctions::luaMonsterIsTarget(lua_State* L) { // monster:isTarget(creature) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { - const Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); pushBoolean(L, monster->isTarget(creature)); } else { lua_pushnil(L); @@ -166,9 +166,9 @@ int MonsterFunctions::luaMonsterIsTarget(lua_State* L) { int MonsterFunctions::luaMonsterIsOpponent(lua_State* L) { // monster:isOpponent(creature) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { - const Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); pushBoolean(L, monster->isOpponent(creature)); } else { lua_pushnil(L); @@ -178,9 +178,9 @@ int MonsterFunctions::luaMonsterIsOpponent(lua_State* L) { int MonsterFunctions::luaMonsterIsFriend(lua_State* L) { // monster:isFriend(creature) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { - const Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); pushBoolean(L, monster->isFriend(creature)); } else { lua_pushnil(L); @@ -190,9 +190,9 @@ int MonsterFunctions::luaMonsterIsFriend(lua_State* L) { int MonsterFunctions::luaMonsterAddFriend(lua_State* L) { // monster:addFriend(creature) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { - Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); monster->addFriend(creature); pushBoolean(L, true); } else { @@ -203,9 +203,9 @@ int MonsterFunctions::luaMonsterAddFriend(lua_State* L) { int MonsterFunctions::luaMonsterRemoveFriend(lua_State* L) { // monster:removeFriend(creature) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { - Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); monster->removeFriend(creature); pushBoolean(L, true); } else { @@ -216,17 +216,17 @@ int MonsterFunctions::luaMonsterRemoveFriend(lua_State* L) { int MonsterFunctions::luaMonsterGetFriendList(lua_State* L) { // monster:getFriendList() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { lua_pushnil(L); return 1; } - const auto &friendList = monster->getFriendList(); + const auto friendList = monster->getFriendList(); lua_createtable(L, friendList.size(), 0); int index = 0; - for (Creature* creature : friendList) { + for (std::shared_ptr creature : friendList) { pushUserdata(L, creature); setCreatureMetatable(L, -1, creature); lua_rawseti(L, -2, ++index); @@ -236,7 +236,7 @@ int MonsterFunctions::luaMonsterGetFriendList(lua_State* L) { int MonsterFunctions::luaMonsterGetFriendCount(lua_State* L) { // monster:getFriendCount() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { lua_pushnumber(L, monster->getFriendList().size()); } else { @@ -247,13 +247,13 @@ int MonsterFunctions::luaMonsterGetFriendCount(lua_State* L) { int MonsterFunctions::luaMonsterAddTarget(lua_State* L) { // monster:addTarget(creature[, pushFront = false]) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { lua_pushnil(L); return 1; } - Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); bool pushFront = getBoolean(L, 3, false); monster->addTarget(creature, pushFront); pushBoolean(L, true); @@ -262,7 +262,7 @@ int MonsterFunctions::luaMonsterAddTarget(lua_State* L) { int MonsterFunctions::luaMonsterRemoveTarget(lua_State* L) { // monster:removeTarget(creature) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { lua_pushnil(L); return 1; @@ -275,17 +275,17 @@ int MonsterFunctions::luaMonsterRemoveTarget(lua_State* L) { int MonsterFunctions::luaMonsterGetTargetList(lua_State* L) { // monster:getTargetList() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { lua_pushnil(L); return 1; } - const auto &targetList = monster->getTargetList(); + const auto targetList = monster->getTargetList(); lua_createtable(L, targetList.size(), 0); int index = 0; - for (Creature* creature : targetList) { + for (std::shared_ptr creature : targetList) { pushUserdata(L, creature); setCreatureMetatable(L, -1, creature); lua_rawseti(L, -2, ++index); @@ -295,7 +295,7 @@ int MonsterFunctions::luaMonsterGetTargetList(lua_State* L) { int MonsterFunctions::luaMonsterGetTargetCount(lua_State* L) { // monster:getTargetCount() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { lua_pushnumber(L, monster->getTargetList().size()); } else { @@ -306,7 +306,7 @@ int MonsterFunctions::luaMonsterGetTargetCount(lua_State* L) { int MonsterFunctions::luaMonsterChangeTargetDistance(lua_State* L) { // monster:changeTargetDistance(distance[, duration = 12000]) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { int32_t distance = getNumber(L, 2, 1); uint32_t duration = getNumber(L, 3, 12000); @@ -319,7 +319,7 @@ int MonsterFunctions::luaMonsterChangeTargetDistance(lua_State* L) { int MonsterFunctions::luaMonsterIsChallenged(lua_State* L) { // monster:isChallenged() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { pushBoolean(L, monster->isChallenged()); } else { @@ -330,9 +330,9 @@ int MonsterFunctions::luaMonsterIsChallenged(lua_State* L) { int MonsterFunctions::luaMonsterSelectTarget(lua_State* L) { // monster:selectTarget(creature) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { - Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); pushBoolean(L, monster->selectTarget(creature)); } else { lua_pushnil(L); @@ -342,7 +342,7 @@ int MonsterFunctions::luaMonsterSelectTarget(lua_State* L) { int MonsterFunctions::luaMonsterSearchTarget(lua_State* L) { // monster:searchTarget([searchType = TARGETSEARCH_DEFAULT]) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (monster) { TargetSearchType_t searchType = getNumber(L, 2, TARGETSEARCH_DEFAULT); pushBoolean(L, monster->searchTarget(searchType)); @@ -354,7 +354,7 @@ int MonsterFunctions::luaMonsterSearchTarget(lua_State* L) { int MonsterFunctions::luaMonsterSetSpawnPosition(lua_State* L) { // monster:setSpawnPosition() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { lua_pushnil(L); return 1; @@ -374,7 +374,7 @@ int MonsterFunctions::luaMonsterSetSpawnPosition(lua_State* L) { int MonsterFunctions::luaMonsterGetRespawnType(lua_State* L) { // monster:getRespawnType() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { lua_pushnil(L); @@ -390,7 +390,7 @@ int MonsterFunctions::luaMonsterGetRespawnType(lua_State* L) { int MonsterFunctions::luaMonsterGetTimeToChangeFiendish(lua_State* L) { // monster:getTimeToChangeFiendish() - const Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -404,7 +404,7 @@ int MonsterFunctions::luaMonsterGetTimeToChangeFiendish(lua_State* L) { int MonsterFunctions::luaMonsterSetTimeToChangeFiendish(lua_State* L) { // monster:setTimeToChangeFiendish(endTime) time_t endTime = getNumber(L, 2, 1); - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -417,7 +417,7 @@ int MonsterFunctions::luaMonsterSetTimeToChangeFiendish(lua_State* L) { int MonsterFunctions::luaMonsterGetMonsterForgeClassification(lua_State* L) { // monster:getMonsterForgeClassification() - const Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -432,7 +432,7 @@ int MonsterFunctions::luaMonsterGetMonsterForgeClassification(lua_State* L) { int MonsterFunctions::luaMonsterSetMonsterForgeClassification(lua_State* L) { // monster:setMonsterForgeClassification(classication) ForgeClassifications_t classification = getNumber(L, 2); - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -445,7 +445,7 @@ int MonsterFunctions::luaMonsterSetMonsterForgeClassification(lua_State* L) { int MonsterFunctions::luaMonsterGetForgeStack(lua_State* L) { // monster:getForgeStack() - const Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -459,7 +459,7 @@ int MonsterFunctions::luaMonsterGetForgeStack(lua_State* L) { int MonsterFunctions::luaMonsterSetForgeStack(lua_State* L) { // monster:setForgeStack(stack) uint16_t stack = getNumber(L, 2, 0); - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -478,7 +478,7 @@ int MonsterFunctions::luaMonsterSetForgeStack(lua_State* L) { int MonsterFunctions::luaMonsterConfigureForgeSystem(lua_State* L) { // monster:configureForgeSystem() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -491,7 +491,7 @@ int MonsterFunctions::luaMonsterConfigureForgeSystem(lua_State* L) { int MonsterFunctions::luaMonsterClearFiendishStatus(lua_State* L) { // monster:clearFiendishStatus() - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -504,7 +504,7 @@ int MonsterFunctions::luaMonsterClearFiendishStatus(lua_State* L) { int MonsterFunctions::luaMonsterIsForgeable(lua_State* L) { // monster:isForgeable() - const Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -517,7 +517,7 @@ int MonsterFunctions::luaMonsterIsForgeable(lua_State* L) { int MonsterFunctions::luaMonsterGetName(lua_State* L) { // monster:getName() - const auto monster = getUserdata(L, 1); + const auto monster = getUserdataShared(L, 1); if (!monster) { reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); pushBoolean(L, false); @@ -530,7 +530,7 @@ int MonsterFunctions::luaMonsterGetName(lua_State* L) { int MonsterFunctions::luaMonsterHazard(lua_State* L) { // get: monster:hazard() ; set: monster:hazard(hazard) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); bool hazard = getBoolean(L, 2, false); if (monster) { if (lua_gettop(L) == 1) { @@ -547,7 +547,7 @@ int MonsterFunctions::luaMonsterHazard(lua_State* L) { int MonsterFunctions::luaMonsterHazardCrit(lua_State* L) { // get: monster:hazardCrit() ; set: monster:hazardCrit(hazardCrit) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); bool hazardCrit = getBoolean(L, 2, false); if (monster) { if (lua_gettop(L) == 1) { @@ -564,7 +564,7 @@ int MonsterFunctions::luaMonsterHazardCrit(lua_State* L) { int MonsterFunctions::luaMonsterHazardDodge(lua_State* L) { // get: monster:hazardDodge() ; set: monster:hazardDodge(hazardDodge) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); bool hazardDodge = getBoolean(L, 2, false); if (monster) { if (lua_gettop(L) == 1) { @@ -581,7 +581,7 @@ int MonsterFunctions::luaMonsterHazardDodge(lua_State* L) { int MonsterFunctions::luaMonsterHazardDamageBoost(lua_State* L) { // get: monster:hazardDamageBoost() ; set: monster:hazardDamageBoost(hazardDamageBoost) - Monster* monster = getUserdata(L, 1); + std::shared_ptr monster = getUserdataShared(L, 1); bool hazardDamageBoost = getBoolean(L, 2, false); if (monster) { if (lua_gettop(L) == 1) { diff --git a/src/lua/functions/creatures/monster/monster_functions.hpp b/src/lua/functions/creatures/monster/monster_functions.hpp index 95f972f1f..9dbb3f81c 100644 --- a/src/lua/functions/creatures/monster/monster_functions.hpp +++ b/src/lua/functions/creatures/monster/monster_functions.hpp @@ -18,7 +18,7 @@ class MonsterFunctions final : LuaScriptInterface { private: static void init(lua_State* L) { - registerClass(L, "Monster", "Creature", MonsterFunctions::luaMonsterCreate); + registerSharedClass(L, "Monster", "Creature", MonsterFunctions::luaMonsterCreate); registerMetaMethod(L, "Monster", "__eq", MonsterFunctions::luaUserdataCompare); registerMethod(L, "Monster", "isMonster", MonsterFunctions::luaMonsterIsMonster); registerMethod(L, "Monster", "getType", MonsterFunctions::luaMonsterGetType); diff --git a/src/lua/functions/creatures/monster/monster_type_functions.cpp b/src/lua/functions/creatures/monster/monster_type_functions.cpp index aa9103877..1beea8de6 100644 --- a/src/lua/functions/creatures/monster/monster_type_functions.cpp +++ b/src/lua/functions/creatures/monster/monster_type_functions.cpp @@ -622,7 +622,7 @@ int MonsterTypeFunctions::luaMonsterTypeBestiaryrace(lua_State* L) { int MonsterTypeFunctions::luaMonsterTypeCombatImmunities(lua_State* L) { // get: monsterType:combatImmunities() set: monsterType:combatImmunities(immunity) - const auto &monsterType = getUserdataShared(L, 1); + const auto monsterType = getUserdataShared(L, 1); if (!monsterType) { pushBoolean(L, false); reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_TYPE_NOT_FOUND)); @@ -678,7 +678,7 @@ int MonsterTypeFunctions::luaMonsterTypeCombatImmunities(lua_State* L) { int MonsterTypeFunctions::luaMonsterTypeConditionImmunities(lua_State* L) { // get: monsterType:conditionImmunities() set: monsterType:conditionImmunities(immunity) - const auto &monsterType = getUserdataShared(L, 1); + const auto monsterType = getUserdataShared(L, 1); if (!monsterType) { pushBoolean(L, false); reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_TYPE_NOT_FOUND)); diff --git a/src/lua/functions/creatures/npc/npc_functions.cpp b/src/lua/functions/creatures/npc/npc_functions.cpp index dd6563f65..56d8411d9 100644 --- a/src/lua/functions/creatures/npc/npc_functions.cpp +++ b/src/lua/functions/creatures/npc/npc_functions.cpp @@ -16,7 +16,7 @@ int NpcFunctions::luaNpcCreate(lua_State* L) { // Npc([id or name or userdata]) - Npc* npc; + std::shared_ptr npc; if (lua_gettop(L) >= 2) { if (isNumber(L, 2)) { npc = g_game().getNpcByID(getNumber(L, 2)); @@ -27,12 +27,12 @@ int NpcFunctions::luaNpcCreate(lua_State* L) { lua_pushnil(L); return 1; } - npc = getUserdata(L, 2); + npc = getUserdataShared(L, 2); } else { npc = nullptr; } } else { - npc = getUserdata(L, 1); + npc = getUserdataShared(L, 1); } if (npc) { @@ -46,13 +46,13 @@ int NpcFunctions::luaNpcCreate(lua_State* L) { int NpcFunctions::luaNpcIsNpc(lua_State* L) { // npc:isNpc() - pushBoolean(L, getUserdata(L, 1) != nullptr); + pushBoolean(L, getUserdataShared(L, 1) != nullptr); return 1; } int NpcFunctions::luaNpcSetMasterPos(lua_State* L) { // npc:setMasterPos(pos) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); pushBoolean(L, false); @@ -67,7 +67,7 @@ int NpcFunctions::luaNpcSetMasterPos(lua_State* L) { int NpcFunctions::luaNpcGetCurrency(lua_State* L) { // npc:getCurrency() - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); lua_pushnil(L); @@ -79,7 +79,7 @@ int NpcFunctions::luaNpcGetCurrency(lua_State* L) { int NpcFunctions::luaNpcSetCurrency(lua_State* L) { // npc:getCurrency() - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); pushBoolean(L, false); @@ -92,7 +92,7 @@ int NpcFunctions::luaNpcSetCurrency(lua_State* L) { int NpcFunctions::luaNpcGetSpeechBubble(lua_State* L) { // npc:getSpeechBubble() - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); lua_pushnil(L); @@ -104,7 +104,7 @@ int NpcFunctions::luaNpcGetSpeechBubble(lua_State* L) { int NpcFunctions::luaNpcSetSpeechBubble(lua_State* L) { // npc:setSpeechBubble(speechBubble) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); lua_pushnil(L); @@ -116,7 +116,7 @@ int NpcFunctions::luaNpcSetSpeechBubble(lua_State* L) { int NpcFunctions::luaNpcGetName(lua_State* L) { // npc:getName() - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); lua_pushnil(L); @@ -129,7 +129,7 @@ int NpcFunctions::luaNpcGetName(lua_State* L) { int NpcFunctions::luaNpcSetName(lua_State* L) { // npc:setName(name) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); const std::string &name = getString(L, 2); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); @@ -142,7 +142,7 @@ int NpcFunctions::luaNpcSetName(lua_State* L) { int NpcFunctions::luaNpcPlace(lua_State* L) { // npc:place(position[, extended = false[, force = true]]) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); lua_pushnil(L); @@ -175,7 +175,7 @@ int NpcFunctions::luaNpcSay(lua_State* L) { } } - Creature* target = nullptr; + std::shared_ptr target = nullptr; if (parameters >= 5) { target = getCreature(L, 5); } @@ -184,7 +184,7 @@ int NpcFunctions::luaNpcSay(lua_State* L) { SpeakClasses type = getNumber(L, 3, TALKTYPE_PRIVATE_NP); const std::string &text = getString(L, 2); - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { lua_pushnil(L); return 1; @@ -209,8 +209,8 @@ int NpcFunctions::luaNpcSay(lua_State* L) { */ int NpcFunctions::luaNpcTurnToCreature(lua_State* L) { // npc:turnToCreature(creature, true) - Npc* npc = getUserdata(L, 1); - Creature* creature = getCreature(L, 2); + std::shared_ptr npc = getUserdataShared(L, 1); + std::shared_ptr creature = getCreature(L, 2); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); @@ -235,8 +235,8 @@ int NpcFunctions::luaNpcTurnToCreature(lua_State* L) { int NpcFunctions::luaNpcSetPlayerInteraction(lua_State* L) { // npc:setPlayerInteraction(creature, topic = 0) - Npc* npc = getUserdata(L, 1); - Creature* creature = getCreature(L, 2); + std::shared_ptr npc = getUserdataShared(L, 1); + std::shared_ptr creature = getCreature(L, 2); uint16_t topicId = getNumber(L, 3, 0); if (!npc) { @@ -258,8 +258,8 @@ int NpcFunctions::luaNpcSetPlayerInteraction(lua_State* L) { int NpcFunctions::luaNpcRemovePlayerInteraction(lua_State* L) { // npc:removePlayerInteraction() - Npc* npc = getUserdata(L, 1); - Creature* creature = getCreature(L, 2); + std::shared_ptr npc = getUserdataShared(L, 1); + std::shared_ptr creature = getCreature(L, 2); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); @@ -280,8 +280,8 @@ int NpcFunctions::luaNpcRemovePlayerInteraction(lua_State* L) { int NpcFunctions::luaNpcIsInteractingWithPlayer(lua_State* L) { // npc:isInteractingWithPlayer(creature) - Npc* npc = getUserdata(L, 1); - Creature* creature = getCreature(L, 2); + std::shared_ptr npc = getUserdataShared(L, 1); + std::shared_ptr creature = getCreature(L, 2); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); @@ -301,8 +301,8 @@ int NpcFunctions::luaNpcIsInteractingWithPlayer(lua_State* L) { int NpcFunctions::luaNpcIsPlayerInteractingOnTopic(lua_State* L) { // npc:isPlayerInteractingOnTopic(creature, topicId = 0) - Npc* npc = getUserdata(L, 1); - Creature* creature = getCreature(L, 2); + std::shared_ptr npc = getUserdataShared(L, 1); + std::shared_ptr creature = getCreature(L, 2); uint32_t topicId = getNumber(L, 3, 0); if (!npc) { @@ -323,7 +323,7 @@ int NpcFunctions::luaNpcIsPlayerInteractingOnTopic(lua_State* L) { int NpcFunctions::luaNpcIsInTalkRange(lua_State* L) { // npc:isInTalkRange(position[, range = 4]) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); const Position &position = getPosition(L, 2); uint32_t range = getNumber(L, 3, 4); @@ -339,14 +339,14 @@ int NpcFunctions::luaNpcIsInTalkRange(lua_State* L) { int NpcFunctions::luaNpcOpenShopWindow(lua_State* L) { // npc:openShopWindow(player) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); pushBoolean(L, false); return 1; } - Player* player = getPlayer(L, 2); + std::shared_ptr player = getPlayer(L, 2); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -359,14 +359,14 @@ int NpcFunctions::luaNpcOpenShopWindow(lua_State* L) { int NpcFunctions::luaNpcCloseShopWindow(lua_State* L) { // npc:closeShopWindow(player) - Player* player = getPlayer(L, 2); + std::shared_ptr player = getPlayer(L, 2); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -383,7 +383,7 @@ int NpcFunctions::luaNpcCloseShopWindow(lua_State* L) { int NpcFunctions::luaNpcIsMerchant(lua_State* L) { // npc:isMerchant() - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); pushBoolean(L, false); @@ -403,7 +403,7 @@ int NpcFunctions::luaNpcIsMerchant(lua_State* L) { int NpcFunctions::luaNpcGetShopItem(lua_State* L) { // npc:getShopItem(itemId) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); @@ -427,7 +427,7 @@ int NpcFunctions::luaNpcGetShopItem(lua_State* L) { int NpcFunctions::luaNpcMove(lua_State* L) { // npc:move(direction) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (npc) { g_game().internalMoveCreature(npc, getNumber(L, 2)); } @@ -436,7 +436,7 @@ int NpcFunctions::luaNpcMove(lua_State* L) { int NpcFunctions::luaNpcTurn(lua_State* L) { // npc:turn(direction) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (npc) { g_game().internalCreatureTurn(npc, getNumber(L, 2)); } @@ -445,7 +445,7 @@ int NpcFunctions::luaNpcTurn(lua_State* L) { int NpcFunctions::luaNpcFollow(lua_State* L) { // npc:follow(player) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { pushBoolean(L, false); return 1; @@ -457,7 +457,7 @@ int NpcFunctions::luaNpcFollow(lua_State* L) { int NpcFunctions::luaNpcGetId(lua_State* L) { // npc:getId() - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); lua_pushnil(L); @@ -470,14 +470,14 @@ int NpcFunctions::luaNpcGetId(lua_State* L) { int NpcFunctions::luaNpcSellItem(lua_State* L) { // npc:sellItem(player, itemid, amount, subtype, actionid, ignoreCap, inBackpacks) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); pushBoolean(L, false); return 1; } - Player* player = getPlayer(L, 2); + std::shared_ptr player = getPlayer(L, 2); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -499,7 +499,7 @@ int NpcFunctions::luaNpcSellItem(lua_State* L) { uint32_t shoppingBagPrice = 20; double shoppingBagSlots = 20; - if (const Tile* tile = ignoreCap ? player->getTile() : nullptr; tile) { + if (std::shared_ptr tile = ignoreCap ? player->getTile() : nullptr; tile) { double slotsNedeed = 0; if (it.stackable) { slotsNedeed = inBackpacks ? std::ceil(std::ceil(amount / it.stackSize) / shoppingBagSlots) : std::ceil(amount / it.stackSize); @@ -529,20 +529,20 @@ int NpcFunctions::luaNpcSellItem(lua_State* L) { auto remainingAmount = static_cast(amount); if (inBackpacks) { while (remainingAmount > 0) { - Item* container = Item::CreateItem(ITEM_SHOPPING_BAG); + std::shared_ptr container = Item::CreateItem(ITEM_SHOPPING_BAG); if (!container) { break; } if (g_game().internalPlayerAddItem(player, container, ignoreCap, CONST_SLOT_WHEREEVER) != RETURNVALUE_NOERROR) { - delete container; + break; } backpacksPurchased++; uint8_t internalAmount = (remainingAmount > internalCount) ? internalCount : static_cast(remainingAmount); const ItemType &iType = Item::items[itemId]; - Item* item; + std::shared_ptr item; if (iType.isWrappable()) { item = Item::CreateItem(ITEM_DECORATION_KIT, subType); item->setAttribute(ItemAttribute_t::DESCRIPTION, "Unwrap this item in your own house to create a <" + iType.name + ">."); @@ -556,7 +556,7 @@ int NpcFunctions::luaNpcSellItem(lua_State* L) { while (remainingAmount > 0) { if (g_game().internalAddItem(container->getContainer(), item, INDEX_WHEREEVER, 0) != RETURNVALUE_NOERROR) { - delete item; + break; } @@ -575,7 +575,7 @@ int NpcFunctions::luaNpcSellItem(lua_State* L) { } else { uint8_t internalAmount = (remainingAmount > internalCount) ? internalCount : static_cast(remainingAmount); const ItemType &iType = Item::items[itemId]; - Item* item; + std::shared_ptr item; if (iType.isWrappable()) { item = Item::CreateItem(ITEM_DECORATION_KIT, subType); item->setAttribute(ItemAttribute_t::DESCRIPTION, "Unwrap this item in your own house to create a <" + iType.name + ">."); @@ -589,7 +589,7 @@ int NpcFunctions::luaNpcSellItem(lua_State* L) { while (remainingAmount > 0) { if (g_game().internalPlayerAddItem(player, item, ignoreCap, CONST_SLOT_WHEREEVER) != RETURNVALUE_NOERROR) { - delete item; + break; } @@ -669,14 +669,14 @@ int NpcFunctions::luaNpcSellItem(lua_State* L) { int NpcFunctions::luaNpcGetDistanceTo(lua_State* L) { // npc:getDistanceTo(uid) - Npc* npc = getUserdata(L, 1); + std::shared_ptr npc = getUserdataShared(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_NOT_FOUND)); pushBoolean(L, false); return 1; } - Thing* thing = getScriptEnv()->getThingByUID(getNumber(L, -1)); + std::shared_ptr thing = getScriptEnv()->getThingByUID(getNumber(L, -1)); pushBoolean(L, thing && thing->isPushable()); if (!thing) { reportErrorFunc(getErrorDesc(LUA_ERROR_THING_NOT_FOUND)); diff --git a/src/lua/functions/creatures/npc/npc_functions.hpp b/src/lua/functions/creatures/npc/npc_functions.hpp index 80b102754..7671780e7 100644 --- a/src/lua/functions/creatures/npc/npc_functions.hpp +++ b/src/lua/functions/creatures/npc/npc_functions.hpp @@ -16,7 +16,7 @@ class NpcFunctions final : LuaScriptInterface { private: static void init(lua_State* L) { - registerClass(L, "Npc", "Creature", NpcFunctions::luaNpcCreate); + registerSharedClass(L, "Npc", "Creature", NpcFunctions::luaNpcCreate); registerMetaMethod(L, "Npc", "__eq", NpcFunctions::luaUserdataCompare); registerMethod(L, "Npc", "isNpc", NpcFunctions::luaNpcIsNpc); registerMethod(L, "Npc", "setMasterPos", NpcFunctions::luaNpcSetMasterPos); diff --git a/src/lua/functions/creatures/npc/npc_type_functions.cpp b/src/lua/functions/creatures/npc/npc_type_functions.cpp index 6f1d553ea..f38032e4a 100644 --- a/src/lua/functions/creatures/npc/npc_type_functions.cpp +++ b/src/lua/functions/creatures/npc/npc_type_functions.cpp @@ -37,7 +37,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); + const auto &npcType = g_npcs().getNpcType(getString(L, 1), true); pushUserdata(L, npcType); setMetatable(L, -1, "NpcType"); return 1; @@ -45,7 +45,7 @@ int NpcTypeFunctions::luaNpcTypeCreate(lua_State* L) { int NpcTypeFunctions::luaNpcTypeIsPushable(lua_State* L) { // get: npcType:isPushable() set: npcType:isPushable(bool) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { pushBoolean(L, npcType->info.pushable); @@ -61,7 +61,7 @@ int NpcTypeFunctions::luaNpcTypeIsPushable(lua_State* L) { int NpcTypeFunctions::luaNpcTypeFloorChange(lua_State* L) { // get: npcType:floorChange() set: npcType:floorChange(bool) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { pushBoolean(L, npcType->info.floorChange); @@ -77,7 +77,7 @@ int NpcTypeFunctions::luaNpcTypeFloorChange(lua_State* L) { int NpcTypeFunctions::luaNpcTypeCanSpawn(lua_State* L) { // monsterType:canSpawn(pos) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); const Position &position = getPosition(L, 2); if (npcType) { pushBoolean(L, npcType->canSpawn(position)); @@ -89,7 +89,7 @@ int NpcTypeFunctions::luaNpcTypeCanSpawn(lua_State* L) { int NpcTypeFunctions::luaNpcTypeCanPushItems(lua_State* L) { // get: npcType:canPushItems() set: npcType:canPushItems(bool) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { pushBoolean(L, npcType->info.canPushItems); @@ -105,7 +105,7 @@ int NpcTypeFunctions::luaNpcTypeCanPushItems(lua_State* L) { int NpcTypeFunctions::luaNpcTypeCanPushCreatures(lua_State* L) { // get: npcType:canPushCreatures() set: npcType:canPushCreatures(bool) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { pushBoolean(L, npcType->info.canPushCreatures); @@ -121,7 +121,7 @@ int NpcTypeFunctions::luaNpcTypeCanPushCreatures(lua_State* L) { int32_t NpcTypeFunctions::luaNpcTypeName(lua_State* L) { // get: npcType:name() set: npcType:name(name) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { pushString(L, npcType->name); @@ -137,7 +137,7 @@ int32_t NpcTypeFunctions::luaNpcTypeName(lua_State* L) { int NpcTypeFunctions::luaNpcTypeNameDescription(lua_State* L) { // get: npcType:nameDescription() set: npcType:nameDescription(desc) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { pushString(L, npcType->nameDescription); @@ -153,7 +153,7 @@ int NpcTypeFunctions::luaNpcTypeNameDescription(lua_State* L) { int NpcTypeFunctions::luaNpcTypeHealth(lua_State* L) { // get: npcType:health() set: npcType:health(health) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { lua_pushnumber(L, npcType->info.health); @@ -169,7 +169,7 @@ int NpcTypeFunctions::luaNpcTypeHealth(lua_State* L) { int NpcTypeFunctions::luaNpcTypeMaxHealth(lua_State* L) { // get: npcType:maxHealth() set: npcType:maxHealth(health) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { lua_pushnumber(L, npcType->info.healthMax); @@ -185,13 +185,13 @@ int NpcTypeFunctions::luaNpcTypeMaxHealth(lua_State* L) { int NpcTypeFunctions::luaNpcTypeAddShopItem(lua_State* L) { // npcType:addShopItem(shop) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { lua_pushnil(L); return 1; } - Shop* shop = getUserdata(L, 2); + auto shop = getUserdataShared(L, 2); if (shop) { npcType->loadShop(npcType, shop->shopBlock); pushBoolean(L, true); @@ -203,7 +203,7 @@ int NpcTypeFunctions::luaNpcTypeAddShopItem(lua_State* L) { int NpcTypeFunctions::luaNpcTypeAddVoice(lua_State* L) { // npcType:addVoice(sentence, interval, chance, yell) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { voiceBlock_t voice; voice.text = getString(L, 2); @@ -220,7 +220,7 @@ int NpcTypeFunctions::luaNpcTypeAddVoice(lua_State* L) { int NpcTypeFunctions::luaNpcTypeGetVoices(lua_State* L) { // npcType:getVoices() - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { lua_pushnil(L); return 1; @@ -239,7 +239,7 @@ int NpcTypeFunctions::luaNpcTypeGetVoices(lua_State* L) { int NpcTypeFunctions::luaNpcTypeGetCreatureEvents(lua_State* L) { // npcType:getCreatureEvents() - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { lua_pushnil(L); return 1; @@ -256,7 +256,7 @@ int NpcTypeFunctions::luaNpcTypeGetCreatureEvents(lua_State* L) { int NpcTypeFunctions::luaNpcTypeRegisterEvent(lua_State* L) { // npcType:registerEvent(name) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { npcType->info.scripts.push_back(getString(L, 2)); pushBoolean(L, true); @@ -275,7 +275,7 @@ int NpcTypeFunctions::luaNpcTypeEventOnCallback(lua_State* L) { // npcType:onBuyItem(callback) // npcType:onSellItem(callback) // npcType:onCheckItem(callback) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (npcType->loadCallback(&g_scripts().getScriptInterface())) { pushBoolean(L, true); @@ -290,7 +290,7 @@ int NpcTypeFunctions::luaNpcTypeEventOnCallback(lua_State* L) { int NpcTypeFunctions::luaNpcTypeEventType(lua_State* L) { // npcType:eventType(event) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { npcType->info.eventType = getNumber(L, 2); pushBoolean(L, true); @@ -302,7 +302,7 @@ int NpcTypeFunctions::luaNpcTypeEventType(lua_State* L) { int NpcTypeFunctions::luaNpcTypeOutfit(lua_State* L) { // get: npcType:outfit() set: npcType:outfit(outfit) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { pushOutfit(L, npcType->info.outfit); @@ -324,7 +324,7 @@ int NpcTypeFunctions::luaNpcTypeOutfit(lua_State* L) { int NpcTypeFunctions::luaNpcTypeBaseSpeed(lua_State* L) { // npcType:getBaseSpeed() - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { lua_pushnumber(L, npcType->info.baseSpeed); @@ -340,7 +340,7 @@ int NpcTypeFunctions::luaNpcTypeBaseSpeed(lua_State* L) { int NpcTypeFunctions::luaNpcTypeWalkInterval(lua_State* L) { // get: npcType:walkInterval() set: npcType:walkInterval(interval) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { lua_pushnumber(L, npcType->info.walkInterval); @@ -356,7 +356,7 @@ int NpcTypeFunctions::luaNpcTypeWalkInterval(lua_State* L) { int NpcTypeFunctions::luaNpcTypeWalkRadius(lua_State* L) { // get: npcType:walkRadius() set: npcType:walkRadius(id) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { lua_pushnumber(L, npcType->info.walkRadius); @@ -372,7 +372,7 @@ int NpcTypeFunctions::luaNpcTypeWalkRadius(lua_State* L) { int NpcTypeFunctions::luaNpcTypeLight(lua_State* L) { // get: npcType:light() set: npcType:light(color, level) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { lua_pushnil(L); return 1; @@ -392,7 +392,7 @@ int NpcTypeFunctions::luaNpcTypeLight(lua_State* L) { int NpcTypeFunctions::luaNpcTypeYellChance(lua_State* L) { // get: npcType:yellChance() set: npcType:yellChance(chance) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { if (lua_gettop(L) == 1) { @@ -413,7 +413,7 @@ int NpcTypeFunctions::luaNpcTypeYellChance(lua_State* L) { int NpcTypeFunctions::luaNpcTypeYellSpeedTicks(lua_State* L) { // get: npcType:yellSpeedTicks() set: npcType:yellSpeedTicks(rate) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { lua_pushnumber(L, npcType->info.yellSpeedTicks); @@ -433,7 +433,7 @@ int NpcTypeFunctions::luaNpcTypeYellSpeedTicks(lua_State* L) { int NpcTypeFunctions::luaNpcTypeRespawnTypePeriod(lua_State* L) { // npcType:respawnTypePeriod() - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { lua_pushnumber(L, npcType->info.respawnType.period); @@ -449,7 +449,7 @@ int NpcTypeFunctions::luaNpcTypeRespawnTypePeriod(lua_State* L) { int NpcTypeFunctions::luaNpcTypeRespawnTypeIsUnderground(lua_State* L) { // npcType:respawnTypeIsUnderground() - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { lua_pushnumber(L, npcType->info.respawnType.underground); @@ -466,7 +466,7 @@ int NpcTypeFunctions::luaNpcTypeRespawnTypeIsUnderground(lua_State* L) { int NpcTypeFunctions::luaNpcTypeSpeechBubble(lua_State* L) { // get = npcType:speechBubble() // set = npcType:speechBubble(newSpeechBubble) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_TYPE_NOT_FOUND)); pushBoolean(L, false); @@ -485,7 +485,7 @@ int NpcTypeFunctions::luaNpcTypeSpeechBubble(lua_State* L) { int NpcTypeFunctions::luaNpcTypeCurrency(lua_State* L) { // get = npcType:currency() // set = npcType:currency(newCurrency) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_TYPE_NOT_FOUND)); pushBoolean(L, false); @@ -503,7 +503,7 @@ int NpcTypeFunctions::luaNpcTypeCurrency(lua_State* L) { int NpcTypeFunctions::luaNpcTypeSoundChance(lua_State* L) { // get: npcType:soundChance() set: npcType:soundChance(chance) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_TYPE_NOT_FOUND)); pushBoolean(L, false); @@ -521,7 +521,7 @@ int NpcTypeFunctions::luaNpcTypeSoundChance(lua_State* L) { int NpcTypeFunctions::luaNpcTypeSoundSpeedTicks(lua_State* L) { // get: npcType:soundSpeedTicks() set: npcType:soundSpeedTicks(ticks) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_TYPE_NOT_FOUND)); pushBoolean(L, false); @@ -539,7 +539,7 @@ int NpcTypeFunctions::luaNpcTypeSoundSpeedTicks(lua_State* L) { int NpcTypeFunctions::luaNpcTypeAddSound(lua_State* L) { // npcType:addSound(soundId) - NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { reportErrorFunc(getErrorDesc(LUA_ERROR_NPC_TYPE_NOT_FOUND)); pushBoolean(L, false); @@ -553,7 +553,7 @@ int NpcTypeFunctions::luaNpcTypeAddSound(lua_State* L) { int NpcTypeFunctions::luaNpcTypeGetSounds(lua_State* L) { // npcType:getSounds() - const NpcType* npcType = getUserdata(L, 1); + const auto &npcType = getUserdataShared(L, 1); if (!npcType) { lua_pushnil(L); return 1; diff --git a/src/lua/functions/creatures/npc/npc_type_functions.hpp b/src/lua/functions/creatures/npc/npc_type_functions.hpp index 4a3a44e5d..a6646b7b2 100644 --- a/src/lua/functions/creatures/npc/npc_type_functions.hpp +++ b/src/lua/functions/creatures/npc/npc_type_functions.hpp @@ -14,7 +14,7 @@ class NpcTypeFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "NpcType", "", NpcTypeFunctions::luaNpcTypeCreate); + registerSharedClass(L, "NpcType", "", NpcTypeFunctions::luaNpcTypeCreate); registerMetaMethod(L, "NpcType", "__eq", NpcTypeFunctions::luaUserdataCompare); registerMethod(L, "NpcType", "isPushable", NpcTypeFunctions::luaNpcTypeIsPushable); diff --git a/src/lua/functions/creatures/npc/shop_functions.cpp b/src/lua/functions/creatures/npc/shop_functions.cpp index 61330ba5a..66de7afd9 100644 --- a/src/lua/functions/creatures/npc/shop_functions.cpp +++ b/src/lua/functions/creatures/npc/shop_functions.cpp @@ -14,30 +14,15 @@ int ShopFunctions::luaCreateShop(lua_State* L) { // Shop() will create a new shop item - Shop* shop = new Shop(); - if (shop) { - pushUserdata(L, shop); - setMetatable(L, -1, "Shop"); - } else { - lua_pushnil(L); - } + pushUserdata(L, std::make_shared()); + setMetatable(L, -1, "Shop"); return 1; } -int ShopFunctions::luaDeleteShop(lua_State* L) { - // shop:delete() shop:__gc() - Shop** shopPtr = getRawUserdata(L, 1); - if (shopPtr && *shopPtr) { - delete *shopPtr; - *shopPtr = nullptr; - } - return 0; -} - int ShopFunctions::luaShopSetId(lua_State* L) { // shop:setId(id) - Shop* shop = getUserdata(L, 1); - if (shop) { + + if (const auto &shop = getUserdataShared(L, 1)) { if (isNumber(L, 2)) { shop->shopBlock.itemId = getNumber(L, 2); pushBoolean(L, true); @@ -54,7 +39,7 @@ int ShopFunctions::luaShopSetId(lua_State* L) { int ShopFunctions::luaShopSetIdFromName(lua_State* L) { // shop:setIdFromName(name) - Shop* shop = getUserdata(L, 1); + const auto &shop = getUserdataShared(L, 1); if (shop && isString(L, 2)) { auto name = getString(L, 2); auto ids = Item::items.nameToItems.equal_range(asLowerCaseString(name)); @@ -87,8 +72,7 @@ int ShopFunctions::luaShopSetIdFromName(lua_State* L) { int ShopFunctions::luaShopSetNameItem(lua_State* L) { // shop:setNameItem(name) - Shop* shop = getUserdata(L, 1); - if (shop) { + if (const auto &shop = getUserdataShared(L, 1)) { shop->shopBlock.itemName = getString(L, 2); pushBoolean(L, true); } else { @@ -99,8 +83,7 @@ int ShopFunctions::luaShopSetNameItem(lua_State* L) { int ShopFunctions::luaShopSetCount(lua_State* L) { // shop:setCount(count) - Shop* shop = getUserdata(L, 1); - if (shop) { + if (const auto &shop = getUserdataShared(L, 1)) { shop->shopBlock.itemSubType = getNumber(L, 2); pushBoolean(L, true); } else { @@ -111,8 +94,7 @@ int ShopFunctions::luaShopSetCount(lua_State* L) { int ShopFunctions::luaShopSetBuyPrice(lua_State* L) { // shop:setBuyPrice(price) - Shop* shop = getUserdata(L, 1); - if (shop) { + if (const auto &shop = getUserdataShared(L, 1)) { shop->shopBlock.itemBuyPrice = getNumber(L, 2); pushBoolean(L, true); } else { @@ -123,8 +105,7 @@ int ShopFunctions::luaShopSetBuyPrice(lua_State* L) { int ShopFunctions::luaShopSetSellPrice(lua_State* L) { // shop:setSellPrice(chance) - Shop* shop = getUserdata(L, 1); - if (shop) { + if (const auto &shop = getUserdataShared(L, 1)) { shop->shopBlock.itemSellPrice = getNumber(L, 2); pushBoolean(L, true); } else { @@ -135,8 +116,7 @@ int ShopFunctions::luaShopSetSellPrice(lua_State* L) { int ShopFunctions::luaShopSetStorageKey(lua_State* L) { // shop:setStorageKey(storage) - Shop* shop = getUserdata(L, 1); - if (shop) { + if (const auto &shop = getUserdataShared(L, 1)) { shop->shopBlock.itemStorageKey = getNumber(L, 2); pushBoolean(L, true); } else { @@ -147,8 +127,7 @@ int ShopFunctions::luaShopSetStorageKey(lua_State* L) { int ShopFunctions::luaShopSetStorageValue(lua_State* L) { // shop:setStorageValue(value) - Shop* shop = getUserdata(L, 1); - if (shop) { + if (const auto &shop = getUserdataShared(L, 1)) { shop->shopBlock.itemStorageValue = getNumber(L, 2); pushBoolean(L, true); } else { @@ -159,9 +138,8 @@ int ShopFunctions::luaShopSetStorageValue(lua_State* L) { int ShopFunctions::luaShopAddChildShop(lua_State* L) { // shop:addChildShop(shop) - Shop* shop = getUserdata(L, 1); - if (shop) { - shop->shopBlock.childShop.push_back(getUserdata(L, 2)->shopBlock); + if (const auto &shop = getUserdataShared(L, 1)) { + shop->shopBlock.childShop.push_back(getUserdataShared(L, 2)->shopBlock); } else { lua_pushnil(L); } diff --git a/src/lua/functions/creatures/npc/shop_functions.hpp b/src/lua/functions/creatures/npc/shop_functions.hpp index 0ec0cefb5..1ffb53c92 100644 --- a/src/lua/functions/creatures/npc/shop_functions.hpp +++ b/src/lua/functions/creatures/npc/shop_functions.hpp @@ -14,10 +14,7 @@ class ShopFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Shop", "", ShopFunctions::luaCreateShop); - registerMetaMethod(L, "Shop", "__gc", ShopFunctions::luaDeleteShop); - registerMethod(L, "Shop", "delete", ShopFunctions::luaDeleteShop); - + registerSharedClass(L, "Shop", "", ShopFunctions::luaCreateShop); registerMethod(L, "Shop", "setId", ShopFunctions::luaShopSetId); registerMethod(L, "Shop", "setIdFromName", ShopFunctions::luaShopSetIdFromName); registerMethod(L, "Shop", "setNameItem", ShopFunctions::luaShopSetNameItem); @@ -31,7 +28,6 @@ class ShopFunctions final : LuaScriptInterface { private: static int luaCreateShop(lua_State* L); - static int luaDeleteShop(lua_State* L); static int luaShopSetId(lua_State* L); static int luaShopSetIdFromName(lua_State* L); static int luaShopSetNameItem(lua_State* L); diff --git a/src/lua/functions/creatures/player/guild_functions.cpp b/src/lua/functions/creatures/player/guild_functions.cpp index ff9e54cf8..81464483f 100644 --- a/src/lua/functions/creatures/player/guild_functions.cpp +++ b/src/lua/functions/creatures/player/guild_functions.cpp @@ -54,11 +54,11 @@ int GuildFunctions::luaGuildGetMembersOnline(lua_State* L) { return 1; } - const auto &members = guild->getMembersOnline(); + const auto members = guild->getMembersOnline(); lua_createtable(L, members.size(), 0); int index = 0; - for (Player* player : members) { + for (std::shared_ptr player : members) { pushUserdata(L, player); setMetatable(L, -1, "Player"); lua_rawseti(L, -2, ++index); diff --git a/src/lua/functions/creatures/player/party_functions.cpp b/src/lua/functions/creatures/player/party_functions.cpp index 25feb5abb..6b5872d83 100644 --- a/src/lua/functions/creatures/player/party_functions.cpp +++ b/src/lua/functions/creatures/player/party_functions.cpp @@ -16,15 +16,15 @@ int32_t PartyFunctions::luaPartyCreate(lua_State* L) { // Party(userdata) - Player* player = getUserdata(L, 2); + std::shared_ptr player = getUserdataShared(L, 2); if (!player) { lua_pushnil(L); return 1; } - Party* party = player->getParty(); + std::shared_ptr party = player->getParty(); if (!party) { - party = new Party(player); + party = Party::create(player); g_game().updatePlayerShield(player); player->sendCreatureSkull(player); pushUserdata(L, party); @@ -37,9 +37,9 @@ int32_t PartyFunctions::luaPartyCreate(lua_State* L) { int PartyFunctions::luaPartyDisband(lua_State* L) { // party:disband() - Party** partyPtr = getRawUserdata(L, 1); + std::shared_ptr* partyPtr = getRawUserDataShared(L, 1); if (partyPtr && *partyPtr) { - Party*&party = *partyPtr; + std::shared_ptr &party = *partyPtr; party->disband(); party = nullptr; pushBoolean(L, true); @@ -51,13 +51,13 @@ int PartyFunctions::luaPartyDisband(lua_State* L) { int PartyFunctions::luaPartyGetLeader(lua_State* L) { // party:getLeader() - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (!party) { lua_pushnil(L); return 1; } - Player* leader = party->getLeader(); + std::shared_ptr leader = party->getLeader(); if (leader) { pushUserdata(L, leader); setMetatable(L, -1, "Player"); @@ -69,8 +69,8 @@ int PartyFunctions::luaPartyGetLeader(lua_State* L) { int PartyFunctions::luaPartySetLeader(lua_State* L) { // party:setLeader(player) - Player* player = getPlayer(L, 2); - Party* party = getUserdata(L, 1); + std::shared_ptr player = getPlayer(L, 2); + std::shared_ptr party = getUserdataShared(L, 1); if (party && player) { pushBoolean(L, party->passPartyLeadership(player)); } else { @@ -81,7 +81,7 @@ int PartyFunctions::luaPartySetLeader(lua_State* L) { int PartyFunctions::luaPartyGetMembers(lua_State* L) { // party:getMembers() - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (!party) { lua_pushnil(L); return 1; @@ -89,7 +89,7 @@ int PartyFunctions::luaPartyGetMembers(lua_State* L) { int index = 0; lua_createtable(L, party->getMemberCount(), 0); - for (Player* player : party->getMembers()) { + for (std::shared_ptr player : party->getMembers()) { pushUserdata(L, player); setMetatable(L, -1, "Player"); lua_rawseti(L, -2, ++index); @@ -99,7 +99,7 @@ int PartyFunctions::luaPartyGetMembers(lua_State* L) { int PartyFunctions::luaPartyGetMemberCount(lua_State* L) { // party:getMemberCount() - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (party) { lua_pushnumber(L, party->getMemberCount()); } else { @@ -110,12 +110,12 @@ int PartyFunctions::luaPartyGetMemberCount(lua_State* L) { int PartyFunctions::luaPartyGetInvitees(lua_State* L) { // party:getInvitees() - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (party) { lua_createtable(L, party->getInvitationCount(), 0); int index = 0; - for (Player* player : party->getInvitees()) { + for (std::shared_ptr player : party->getInvitees()) { pushUserdata(L, player); setMetatable(L, -1, "Player"); lua_rawseti(L, -2, ++index); @@ -128,7 +128,7 @@ int PartyFunctions::luaPartyGetInvitees(lua_State* L) { int PartyFunctions::luaPartyGetInviteeCount(lua_State* L) { // party:getInviteeCount() - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (party) { lua_pushnumber(L, party->getInvitationCount()); } else { @@ -139,10 +139,10 @@ int PartyFunctions::luaPartyGetInviteeCount(lua_State* L) { int PartyFunctions::luaPartyAddInvite(lua_State* L) { // party:addInvite(player) - Player* player = getPlayer(L, 2); - Party* party = getUserdata(L, 1); + std::shared_ptr player = getPlayer(L, 2); + std::shared_ptr party = getUserdataShared(L, 1); if (party && player) { - pushBoolean(L, party->invitePlayer(*player)); + pushBoolean(L, party->invitePlayer(player)); } else { lua_pushnil(L); } @@ -151,10 +151,10 @@ int PartyFunctions::luaPartyAddInvite(lua_State* L) { int PartyFunctions::luaPartyRemoveInvite(lua_State* L) { // party:removeInvite(player) - Player* player = getPlayer(L, 2); - Party* party = getUserdata(L, 1); + std::shared_ptr player = getPlayer(L, 2); + std::shared_ptr party = getUserdataShared(L, 1); if (party && player) { - pushBoolean(L, party->removeInvite(*player)); + pushBoolean(L, party->removeInvite(player)); } else { lua_pushnil(L); } @@ -163,10 +163,10 @@ int PartyFunctions::luaPartyRemoveInvite(lua_State* L) { int PartyFunctions::luaPartyAddMember(lua_State* L) { // party:addMember(player) - Player* player = getPlayer(L, 2); - Party* party = getUserdata(L, 1); + std::shared_ptr player = getPlayer(L, 2); + std::shared_ptr party = getUserdataShared(L, 1); if (party && player) { - pushBoolean(L, party->joinParty(*player)); + pushBoolean(L, party->joinParty(player)); } else { lua_pushnil(L); } @@ -175,8 +175,8 @@ int PartyFunctions::luaPartyAddMember(lua_State* L) { int PartyFunctions::luaPartyRemoveMember(lua_State* L) { // party:removeMember(player) - Player* player = getPlayer(L, 2); - Party* party = getUserdata(L, 1); + std::shared_ptr player = getPlayer(L, 2); + std::shared_ptr party = getUserdataShared(L, 1); if (party && player) { pushBoolean(L, party->leaveParty(player)); } else { @@ -187,7 +187,7 @@ int PartyFunctions::luaPartyRemoveMember(lua_State* L) { int PartyFunctions::luaPartyIsSharedExperienceActive(lua_State* L) { // party:isSharedExperienceActive() - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (party) { pushBoolean(L, party->isSharedExperienceActive()); } else { @@ -198,7 +198,7 @@ int PartyFunctions::luaPartyIsSharedExperienceActive(lua_State* L) { int PartyFunctions::luaPartyIsSharedExperienceEnabled(lua_State* L) { // party:isSharedExperienceEnabled() - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (party) { pushBoolean(L, party->isSharedExperienceEnabled()); } else { @@ -210,7 +210,7 @@ int PartyFunctions::luaPartyIsSharedExperienceEnabled(lua_State* L) { int PartyFunctions::luaPartyShareExperience(lua_State* L) { // party:shareExperience(experience) uint64_t experience = getNumber(L, 2); - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (party) { party->shareExperience(experience); pushBoolean(L, true); @@ -223,7 +223,7 @@ int PartyFunctions::luaPartyShareExperience(lua_State* L) { int PartyFunctions::luaPartySetSharedExperience(lua_State* L) { // party:setSharedExperience(active) bool active = getBoolean(L, 2); - Party* party = getUserdata(L, 1); + std::shared_ptr party = getUserdataShared(L, 1); if (party) { pushBoolean(L, party->setSharedExperience(party->getLeader(), active)); } else { diff --git a/src/lua/functions/creatures/player/party_functions.hpp b/src/lua/functions/creatures/player/party_functions.hpp index 4c9a1463f..30ff51720 100644 --- a/src/lua/functions/creatures/player/party_functions.hpp +++ b/src/lua/functions/creatures/player/party_functions.hpp @@ -14,7 +14,7 @@ class PartyFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Party", "", PartyFunctions::luaPartyCreate); + registerSharedClass(L, "Party", "", PartyFunctions::luaPartyCreate); registerMetaMethod(L, "Party", "__eq", PartyFunctions::luaUserdataCompare); registerMethod(L, "Party", "disband", PartyFunctions::luaPartyDisband); registerMethod(L, "Party", "getLeader", PartyFunctions::luaPartyGetLeader); diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index 4b72347b2..a69891a93 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -22,7 +22,7 @@ int PlayerFunctions::luaPlayerSendInventory(lua_State* L) { // player:sendInventory() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -36,13 +36,13 @@ int PlayerFunctions::luaPlayerSendInventory(lua_State* L) { int PlayerFunctions::luaPlayerSendLootStats(lua_State* L) { // player:sendLootStats(item, count) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Item* item = getUserdata(L, 2); + std::shared_ptr item = getUserdataShared(L, 2); if (!item) { lua_pushnil(L); return 1; @@ -62,13 +62,13 @@ int PlayerFunctions::luaPlayerSendLootStats(lua_State* L) { int PlayerFunctions::luaPlayerUpdateSupplyTracker(lua_State* L) { // player:updateSupplyTracker(item) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Item* item = getUserdata(L, 2); + std::shared_ptr item = getUserdataShared(L, 2); if (!item) { lua_pushnil(L); return 1; @@ -82,19 +82,19 @@ int PlayerFunctions::luaPlayerUpdateSupplyTracker(lua_State* L) { int PlayerFunctions::luaPlayerUpdateKillTracker(lua_State* L) { // player:updateKillTracker(creature, corpse) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Creature* monster = getUserdata(L, 2); + std::shared_ptr monster = getUserdataShared(L, 2); if (!monster) { lua_pushnil(L); return 1; } - Container* corpse = getUserdata(L, 3); + std::shared_ptr corpse = getUserdataShared(L, 3); if (!corpse) { lua_pushnil(L); return 1; @@ -109,7 +109,7 @@ int PlayerFunctions::luaPlayerUpdateKillTracker(lua_State* L) { // Player int PlayerFunctions::luaPlayerCreate(lua_State* L) { // Player(id or guid or name or userdata) - Player* player; + std::shared_ptr player; if (isNumber(L, 2)) { uint32_t id = getNumber(L, 2); if (id >= Player::getFirstID() && id <= Player::getLastID()) { @@ -129,7 +129,7 @@ int PlayerFunctions::luaPlayerCreate(lua_State* L) { lua_pushnil(L); return 1; } - player = getUserdata(L, 2); + player = getUserdataShared(L, 2); } else { player = nullptr; } @@ -145,7 +145,7 @@ int PlayerFunctions::luaPlayerCreate(lua_State* L) { int PlayerFunctions::luaPlayerResetCharmsMonsters(lua_State* L) { // player:resetCharmsBestiary() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setCharmPoints(0); player->setCharmExpansion(false); @@ -163,7 +163,7 @@ int PlayerFunctions::luaPlayerResetCharmsMonsters(lua_State* L) { int PlayerFunctions::luaPlayerUnlockAllCharmRunes(lua_State* L) { // player:unlockAllCharmRunes() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { for (int8_t i = CHARM_WOUND; i <= CHARM_LAST; i++) { const auto charm = g_iobestiary().getBestiaryCharm(static_cast(i)); @@ -181,7 +181,7 @@ int PlayerFunctions::luaPlayerUnlockAllCharmRunes(lua_State* L) { int PlayerFunctions::luaPlayeraddCharmPoints(lua_State* L) { // player:addCharmPoints() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { int16_t charms = getNumber(L, 2); if (charms >= 0) { @@ -199,13 +199,13 @@ int PlayerFunctions::luaPlayeraddCharmPoints(lua_State* L) { int PlayerFunctions::luaPlayerIsPlayer(lua_State* L) { // player:isPlayer() - pushBoolean(L, getUserdata(L, 1) != nullptr); + pushBoolean(L, getUserdataShared(L, 1) != nullptr); return 1; } int PlayerFunctions::luaPlayerGetGuid(lua_State* L) { // player:getGuid() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getGUID()); } else { @@ -216,7 +216,7 @@ int PlayerFunctions::luaPlayerGetGuid(lua_State* L) { int PlayerFunctions::luaPlayerGetIp(lua_State* L) { // player:getIp() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getIP()); } else { @@ -227,7 +227,7 @@ int PlayerFunctions::luaPlayerGetIp(lua_State* L) { int PlayerFunctions::luaPlayerGetAccountId(lua_State* L) { // player:getAccountId() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || player->getAccountId() == 0) { lua_pushnil(L); return 1; @@ -240,7 +240,7 @@ int PlayerFunctions::luaPlayerGetAccountId(lua_State* L) { int PlayerFunctions::luaPlayerGetLastLoginSaved(lua_State* L) { // player:getLastLoginSaved() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getLastLoginSaved()); } else { @@ -251,7 +251,7 @@ int PlayerFunctions::luaPlayerGetLastLoginSaved(lua_State* L) { int PlayerFunctions::luaPlayerGetLastLogout(lua_State* L) { // player:getLastLogout() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getLastLogout()); } else { @@ -262,7 +262,7 @@ int PlayerFunctions::luaPlayerGetLastLogout(lua_State* L) { int PlayerFunctions::luaPlayerGetAccountType(lua_State* L) { // player:getAccountType() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getAccountType()); } else { @@ -273,7 +273,7 @@ int PlayerFunctions::luaPlayerGetAccountType(lua_State* L) { int PlayerFunctions::luaPlayerSetAccountType(lua_State* L) { // player:setAccountType(accountType) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { lua_pushnil(L); return 1; @@ -295,7 +295,7 @@ int PlayerFunctions::luaPlayerSetAccountType(lua_State* L) { int PlayerFunctions::luaPlayerAddBestiaryKill(lua_State* L) { // player:addBestiaryKill(name[, amount = 1]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { const auto mtype = g_monsters().getMonsterType(getString(L, 2)); if (mtype) { @@ -312,7 +312,7 @@ int PlayerFunctions::luaPlayerAddBestiaryKill(lua_State* L) { int PlayerFunctions::luaPlayerIsMonsterBestiaryUnlocked(lua_State* L) { // player:isMonsterBestiaryUnlocked(raceId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player == nullptr) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -340,7 +340,7 @@ int PlayerFunctions::luaPlayerIsMonsterBestiaryUnlocked(lua_State* L) { int PlayerFunctions::luaPlayergetCharmMonsterType(lua_State* L) { // player:getCharmMonsterType(charmRune_t) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { charmRune_t charmid = getNumber(L, 2); uint16_t raceid = player->parseRacebyCharm(charmid, false, 0); @@ -363,9 +363,9 @@ int PlayerFunctions::luaPlayergetCharmMonsterType(lua_State* L) { int PlayerFunctions::luaPlayerRemovePreyStamina(lua_State* L) { // player:removePreyStamina(amount) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { - g_ioprey().CheckPlayerPreys(player, getNumber(L, 2, 1)); + g_ioprey().checkPlayerPreys(player, getNumber(L, 2, 1)); pushBoolean(L, true); } else { lua_pushnil(L); @@ -375,7 +375,7 @@ int PlayerFunctions::luaPlayerRemovePreyStamina(lua_State* L) { int PlayerFunctions::luaPlayerAddPreyCards(lua_State* L) { // player:addPreyCards(amount) - if (Player* player = getUserdata(L, 1)) { + if (std::shared_ptr player = getUserdataShared(L, 1)) { player->addPreyCards(getNumber(L, 2, 0)); pushBoolean(L, true); } else { @@ -386,7 +386,7 @@ int PlayerFunctions::luaPlayerAddPreyCards(lua_State* L) { int PlayerFunctions::luaPlayerGetPreyCards(lua_State* L) { // player:getPreyCards() - if (const Player* player = getUserdata(L, 1)) { + if (std::shared_ptr player = getUserdataShared(L, 1)) { lua_pushnumber(L, static_cast(player->getPreyCards())); } else { lua_pushnil(L); @@ -396,8 +396,8 @@ int PlayerFunctions::luaPlayerGetPreyCards(lua_State* L) { int PlayerFunctions::luaPlayerGetPreyExperiencePercentage(lua_State* L) { // player:getPreyExperiencePercentage(raceId) - if (const Player* player = getUserdata(L, 1)) { - if (const PreySlot* slot = player->getPreyWithMonster(getNumber(L, 2, 0)); + if (std::shared_ptr player = getUserdataShared(L, 1)) { + if (const std::unique_ptr &slot = player->getPreyWithMonster(getNumber(L, 2, 0)); slot && slot->isOccupied() && slot->bonus == PreyBonus_Experience && slot->bonusTimeLeft > 0) { lua_pushnumber(L, static_cast(100 + slot->bonusPercentage)); } else { @@ -411,7 +411,7 @@ int PlayerFunctions::luaPlayerGetPreyExperiencePercentage(lua_State* L) { int PlayerFunctions::luaPlayerRemoveTaskHuntingPoints(lua_State* L) { // player:removeTaskHuntingPoints(amount) - if (Player* player = getUserdata(L, 1)) { + if (std::shared_ptr player = getUserdataShared(L, 1)) { pushBoolean(L, player->useTaskHuntingPoints(getNumber(L, 2, 0))); } else { lua_pushnil(L); @@ -421,7 +421,7 @@ int PlayerFunctions::luaPlayerRemoveTaskHuntingPoints(lua_State* L) { int PlayerFunctions::luaPlayerGetTaskHuntingPoints(lua_State* L) { // player:getTaskHuntingPoints() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player == nullptr) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -434,7 +434,7 @@ int PlayerFunctions::luaPlayerGetTaskHuntingPoints(lua_State* L) { int PlayerFunctions::luaPlayerAddTaskHuntingPoints(lua_State* L) { // player:addTaskHuntingPoints(amount) - if (Player* player = getUserdata(L, 1)) { + if (std::shared_ptr player = getUserdataShared(L, 1)) { auto points = getNumber(L, 2); player->addTaskHuntingPoints(getNumber(L, 2)); lua_pushnumber(L, static_cast(points)); @@ -446,8 +446,8 @@ int PlayerFunctions::luaPlayerAddTaskHuntingPoints(lua_State* L) { int PlayerFunctions::luaPlayerGetPreyLootPercentage(lua_State* L) { // player:getPreyLootPercentage(raceid) - if (const Player* player = getUserdata(L, 1)) { - if (const PreySlot* slot = player->getPreyWithMonster(getNumber(L, 2, 0)); + if (std::shared_ptr player = getUserdataShared(L, 1)) { + if (const std::unique_ptr &slot = player->getPreyWithMonster(getNumber(L, 2, 0)); slot && slot->isOccupied() && slot->bonus == PreyBonus_Loot) { lua_pushnumber(L, slot->bonusPercentage); } else { @@ -461,9 +461,11 @@ int PlayerFunctions::luaPlayerGetPreyLootPercentage(lua_State* L) { int PlayerFunctions::luaPlayerPreyThirdSlot(lua_State* L) { // get: player:preyThirdSlot() set: player:preyThirdSlot(bool) - if (Player* player = getUserdata(L, 1); - PreySlot* slot = player->getPreySlotById(PreySlot_Three)) { - if (lua_gettop(L) == 1) { + if (const auto &player = getUserdataShared(L, 1)) { + const auto &slot = player->getPreySlotById(PreySlot_Three); + if (!slot) { + lua_pushnil(L); + } else if (lua_gettop(L) == 1) { pushBoolean(L, slot->state != PreyDataState_Locked); } else { if (getBoolean(L, 2, false)) { @@ -480,13 +482,14 @@ int PlayerFunctions::luaPlayerPreyThirdSlot(lua_State* L) { } else { lua_pushnil(L); } + return 1; } int PlayerFunctions::luaPlayerTaskThirdSlot(lua_State* L) { // get: player:taskHuntingThirdSlot() set: player:taskHuntingThirdSlot(bool) - if (Player* player = getUserdata(L, 1); - TaskHuntingSlot* slot = player->getTaskHuntingSlotById(PreySlot_Three)) { + if (std::shared_ptr player = getUserdataShared(L, 1); + const auto &slot = player->getTaskHuntingSlotById(PreySlot_Three)) { if (lua_gettop(L) == 1) { pushBoolean(L, slot->state != PreyTaskDataState_Locked); } else { @@ -510,7 +513,7 @@ int PlayerFunctions::luaPlayerTaskThirdSlot(lua_State* L) { int PlayerFunctions::luaPlayercharmExpansion(lua_State* L) { // get: player:charmExpansion() set: player:charmExpansion(bool) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { if (lua_gettop(L) == 1) { pushBoolean(L, player->hasCharmExpansion()); @@ -526,7 +529,7 @@ int PlayerFunctions::luaPlayercharmExpansion(lua_State* L) { int PlayerFunctions::luaPlayerGetCapacity(lua_State* L) { // player:getCapacity() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getCapacity()); } else { @@ -537,7 +540,7 @@ int PlayerFunctions::luaPlayerGetCapacity(lua_State* L) { int PlayerFunctions::luaPlayerSetCapacity(lua_State* L) { // player:setCapacity(capacity) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->capacity = getNumber(L, 2); player->sendStats(); @@ -550,7 +553,7 @@ int PlayerFunctions::luaPlayerSetCapacity(lua_State* L) { int PlayerFunctions::luaPlayerSetTraining(lua_State* L) { // player:setTraining(value) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { bool value = getBoolean(L, 2, false); player->setTraining(value); @@ -563,7 +566,7 @@ int PlayerFunctions::luaPlayerSetTraining(lua_State* L) { int PlayerFunctions::luaPlayerGetIsTraining(lua_State* L) { // player:isTraining() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { pushBoolean(L, false); reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); @@ -576,7 +579,7 @@ int PlayerFunctions::luaPlayerGetIsTraining(lua_State* L) { int PlayerFunctions::luaPlayerGetFreeCapacity(lua_State* L) { // player:getFreeCapacity() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getFreeCapacity()); } else { @@ -587,7 +590,7 @@ int PlayerFunctions::luaPlayerGetFreeCapacity(lua_State* L) { int PlayerFunctions::luaPlayerGetKills(lua_State* L) { // player:getKills() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -611,7 +614,7 @@ int PlayerFunctions::luaPlayerGetKills(lua_State* L) { int PlayerFunctions::luaPlayerSetKills(lua_State* L) { // player:setKills(kills) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -639,7 +642,7 @@ int PlayerFunctions::luaPlayerSetKills(lua_State* L) { int PlayerFunctions::luaPlayerGetReward(lua_State* L) { // player:getReward(rewardId[, autoCreate = false]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -658,7 +661,7 @@ int PlayerFunctions::luaPlayerGetReward(lua_State* L) { int PlayerFunctions::luaPlayerRemoveReward(lua_State* L) { // player:removeReward(rewardId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -672,7 +675,7 @@ int PlayerFunctions::luaPlayerRemoveReward(lua_State* L) { int PlayerFunctions::luaPlayerGetRewardList(lua_State* L) { // player:getRewardList() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -692,7 +695,7 @@ int PlayerFunctions::luaPlayerGetRewardList(lua_State* L) { int PlayerFunctions::luaPlayerSetDailyReward(lua_State* L) { // player:setDailyReward(value) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setDailyReward(getNumber(L, 2)); pushBoolean(L, true); @@ -704,14 +707,14 @@ int PlayerFunctions::luaPlayerSetDailyReward(lua_State* L) { int PlayerFunctions::luaPlayerGetDepotLocker(lua_State* L) { // player:getDepotLocker(depotId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } uint32_t depotId = getNumber(L, 2); - DepotLocker* depotLocker = player->getDepotLocker(depotId); + std::shared_ptr depotLocker = player->getDepotLocker(depotId); if (depotLocker) { depotLocker->setParent(player); pushUserdata(L, depotLocker); @@ -724,7 +727,7 @@ int PlayerFunctions::luaPlayerGetDepotLocker(lua_State* L) { int PlayerFunctions::luaPlayerGetStashCounter(lua_State* L) { // player:getStashCount() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t sizeStash = getStashSize(player->getStashItems()); lua_pushnumber(L, sizeStash); @@ -736,7 +739,7 @@ int PlayerFunctions::luaPlayerGetStashCounter(lua_State* L) { int PlayerFunctions::luaPlayerGetDepotChest(lua_State* L) { // player:getDepotChest(depotId[, autoCreate = false]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -744,7 +747,7 @@ int PlayerFunctions::luaPlayerGetDepotChest(lua_State* L) { uint32_t depotId = getNumber(L, 2); bool autoCreate = getBoolean(L, 3, false); - DepotChest* depotChest = player->getDepotChest(depotId, autoCreate); + std::shared_ptr depotChest = player->getDepotChest(depotId, autoCreate); if (depotChest) { player->setLastDepotId(depotId); pushUserdata(L, depotChest); @@ -757,13 +760,13 @@ int PlayerFunctions::luaPlayerGetDepotChest(lua_State* L) { int PlayerFunctions::luaPlayerGetInbox(lua_State* L) { // player:getInbox() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Inbox* inbox = player->getInbox(); + std::shared_ptr inbox = player->getInbox(); if (inbox) { pushUserdata(L, inbox); setItemMetatable(L, -1, inbox); @@ -775,7 +778,7 @@ int PlayerFunctions::luaPlayerGetInbox(lua_State* L) { int PlayerFunctions::luaPlayerGetSkullTime(lua_State* L) { // player:getSkullTime() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getSkullTicks()); } else { @@ -786,7 +789,7 @@ int PlayerFunctions::luaPlayerGetSkullTime(lua_State* L) { int PlayerFunctions::luaPlayerSetSkullTime(lua_State* L) { // player:setSkullTime(skullTime) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setSkullTicks(getNumber(L, 2)); pushBoolean(L, true); @@ -798,7 +801,7 @@ int PlayerFunctions::luaPlayerSetSkullTime(lua_State* L) { int PlayerFunctions::luaPlayerGetDeathPenalty(lua_State* L) { // player:getDeathPenalty() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, static_cast(player->getLostPercent() * 100)); } else { @@ -809,7 +812,7 @@ int PlayerFunctions::luaPlayerGetDeathPenalty(lua_State* L) { int PlayerFunctions::luaPlayerGetExperience(lua_State* L) { // player:getExperience() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getExperience()); } else { @@ -820,7 +823,7 @@ int PlayerFunctions::luaPlayerGetExperience(lua_State* L) { int PlayerFunctions::luaPlayerAddExperience(lua_State* L) { // player:addExperience(experience[, sendText = false]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { int64_t experience = getNumber(L, 2); bool sendText = getBoolean(L, 3, false); @@ -834,7 +837,7 @@ int PlayerFunctions::luaPlayerAddExperience(lua_State* L) { int PlayerFunctions::luaPlayerRemoveExperience(lua_State* L) { // player:removeExperience(experience[, sendText = false]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { int64_t experience = getNumber(L, 2); bool sendText = getBoolean(L, 3, false); @@ -848,7 +851,7 @@ int PlayerFunctions::luaPlayerRemoveExperience(lua_State* L) { int PlayerFunctions::luaPlayerGetLevel(lua_State* L) { // player:getLevel() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getLevel()); } else { @@ -859,7 +862,7 @@ int PlayerFunctions::luaPlayerGetLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetMagicShieldCapacityFlat(lua_State* L) { // player:getMagicShieldCapacityFlat(useCharges) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getMagicShieldCapacityFlat(getBoolean(L, 2, false))); } else { @@ -870,7 +873,7 @@ int PlayerFunctions::luaPlayerGetMagicShieldCapacityFlat(lua_State* L) { int PlayerFunctions::luaPlayerGetMagicShieldCapacityPercent(lua_State* L) { // player:getMagicShieldCapacityPercent(useCharges) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getMagicShieldCapacityPercent(getBoolean(L, 2, false))); } else { @@ -881,7 +884,7 @@ int PlayerFunctions::luaPlayerGetMagicShieldCapacityPercent(lua_State* L) { int PlayerFunctions::luaPlayerSendSpellCooldown(lua_State* L) { // player:sendSpellCooldown(spellId, time) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -897,7 +900,7 @@ int PlayerFunctions::luaPlayerSendSpellCooldown(lua_State* L) { int PlayerFunctions::luaPlayerSendSpellGroupCooldown(lua_State* L) { // player:sendSpellGroupCooldown(groupId, time) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -913,7 +916,7 @@ int PlayerFunctions::luaPlayerSendSpellGroupCooldown(lua_State* L) { int PlayerFunctions::luaPlayerGetMagicLevel(lua_State* L) { // player:getMagicLevel() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getMagicLevel()); } else { @@ -924,7 +927,7 @@ int PlayerFunctions::luaPlayerGetMagicLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetBaseMagicLevel(lua_State* L) { // player:getBaseMagicLevel() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getBaseMagicLevel()); } else { @@ -935,7 +938,7 @@ int PlayerFunctions::luaPlayerGetBaseMagicLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetMana(lua_State* L) { // player:getMana() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getMana()); } else { @@ -946,7 +949,7 @@ int PlayerFunctions::luaPlayerGetMana(lua_State* L) { int PlayerFunctions::luaPlayerAddMana(lua_State* L) { // player:addMana(manaChange[, animationOnLoss = false]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -968,7 +971,7 @@ int PlayerFunctions::luaPlayerAddMana(lua_State* L) { int PlayerFunctions::luaPlayerGetMaxMana(lua_State* L) { // player:getMaxMana() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getMaxMana()); } else { @@ -979,7 +982,7 @@ int PlayerFunctions::luaPlayerGetMaxMana(lua_State* L) { int PlayerFunctions::luaPlayerSetMaxMana(lua_State* L) { // player:setMaxMana(maxMana) - Player* player = getPlayer(L, 1); + std::shared_ptr player = getPlayer(L, 1); if (player) { player->manaMax = getNumber(L, 2); player->mana = std::min(player->mana, player->manaMax); @@ -994,7 +997,7 @@ int PlayerFunctions::luaPlayerSetMaxMana(lua_State* L) { int PlayerFunctions::luaPlayerGetManaSpent(lua_State* L) { // player:getManaSpent() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getSpentMana()); } else { @@ -1005,7 +1008,7 @@ int PlayerFunctions::luaPlayerGetManaSpent(lua_State* L) { int PlayerFunctions::luaPlayerAddManaSpent(lua_State* L) { // player:addManaSpent(amount) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->addManaSpent(getNumber(L, 2)); pushBoolean(L, true); @@ -1017,7 +1020,7 @@ int PlayerFunctions::luaPlayerAddManaSpent(lua_State* L) { int PlayerFunctions::luaPlayerGetBaseMaxHealth(lua_State* L) { // player:getBaseMaxHealth() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->healthMax); } else { @@ -1028,7 +1031,7 @@ int PlayerFunctions::luaPlayerGetBaseMaxHealth(lua_State* L) { int PlayerFunctions::luaPlayerGetBaseMaxMana(lua_State* L) { // player:getBaseMaxMana() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->manaMax); } else { @@ -1040,7 +1043,7 @@ int PlayerFunctions::luaPlayerGetBaseMaxMana(lua_State* L) { int PlayerFunctions::luaPlayerGetSkillLevel(lua_State* L) { // player:getSkillLevel(skillType) skills_t skillType = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player && skillType <= SKILL_LAST) { lua_pushnumber(L, player->skills[skillType].level); } else { @@ -1052,7 +1055,7 @@ int PlayerFunctions::luaPlayerGetSkillLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetEffectiveSkillLevel(lua_State* L) { // player:getEffectiveSkillLevel(skillType) skills_t skillType = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player && skillType <= SKILL_LAST) { lua_pushnumber(L, player->getSkillLevel(skillType)); } else { @@ -1064,7 +1067,7 @@ int PlayerFunctions::luaPlayerGetEffectiveSkillLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetSkillPercent(lua_State* L) { // player:getSkillPercent(skillType) skills_t skillType = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player && skillType <= SKILL_LAST) { lua_pushnumber(L, player->skills[skillType].percent); } else { @@ -1076,7 +1079,7 @@ int PlayerFunctions::luaPlayerGetSkillPercent(lua_State* L) { int PlayerFunctions::luaPlayerGetSkillTries(lua_State* L) { // player:getSkillTries(skillType) skills_t skillType = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player && skillType <= SKILL_LAST) { lua_pushnumber(L, player->skills[skillType].tries); } else { @@ -1087,7 +1090,7 @@ int PlayerFunctions::luaPlayerGetSkillTries(lua_State* L) { int PlayerFunctions::luaPlayerAddSkillTries(lua_State* L) { // player:addSkillTries(skillType, tries) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { skills_t skillType = getNumber(L, 2); uint64_t tries = getNumber(L, 3); @@ -1101,7 +1104,7 @@ int PlayerFunctions::luaPlayerAddSkillTries(lua_State* L) { int PlayerFunctions::luaPlayerSetLevel(lua_State* L) { // player:setLevel(level) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t level = getNumber(L, 2); player->level = level; @@ -1117,7 +1120,7 @@ int PlayerFunctions::luaPlayerSetLevel(lua_State* L) { int PlayerFunctions::luaPlayerSetMagicLevel(lua_State* L) { // player:setMagicLevel(level[, manaSpent]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t level = getNumber(L, 2); player->magLevel = level; @@ -1141,7 +1144,7 @@ int PlayerFunctions::luaPlayerSetMagicLevel(lua_State* L) { int PlayerFunctions::luaPlayerSetSkillLevel(lua_State* L) { // player:setSkillLevel(skillType, level[, tries]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { skills_t skillType = getNumber(L, 2); uint16_t level = getNumber(L, 3); @@ -1166,7 +1169,7 @@ int PlayerFunctions::luaPlayerSetSkillLevel(lua_State* L) { int PlayerFunctions::luaPlayerAddOfflineTrainingTime(lua_State* L) { // player:addOfflineTrainingTime(time) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { int32_t time = getNumber(L, 2); player->addOfflineTrainingTime(time); @@ -1180,7 +1183,7 @@ int PlayerFunctions::luaPlayerAddOfflineTrainingTime(lua_State* L) { int PlayerFunctions::luaPlayerGetOfflineTrainingTime(lua_State* L) { // player:getOfflineTrainingTime() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getOfflineTrainingTime()); } else { @@ -1191,7 +1194,7 @@ int PlayerFunctions::luaPlayerGetOfflineTrainingTime(lua_State* L) { int PlayerFunctions::luaPlayerRemoveOfflineTrainingTime(lua_State* L) { // player:removeOfflineTrainingTime(time) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { int32_t time = getNumber(L, 2); player->removeOfflineTrainingTime(time); @@ -1205,7 +1208,7 @@ int PlayerFunctions::luaPlayerRemoveOfflineTrainingTime(lua_State* L) { int PlayerFunctions::luaPlayerAddOfflineTrainingTries(lua_State* L) { // player:addOfflineTrainingTries(skillType, tries) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { skills_t skillType = getNumber(L, 2); uint64_t tries = getNumber(L, 3); @@ -1218,7 +1221,7 @@ int PlayerFunctions::luaPlayerAddOfflineTrainingTries(lua_State* L) { int PlayerFunctions::luaPlayerGetOfflineTrainingSkill(lua_State* L) { // player:getOfflineTrainingSkill() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getOfflineTrainingSkill()); } else { @@ -1229,7 +1232,7 @@ int PlayerFunctions::luaPlayerGetOfflineTrainingSkill(lua_State* L) { int PlayerFunctions::luaPlayerSetOfflineTrainingSkill(lua_State* L) { // player:setOfflineTrainingSkill(skillId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { int8_t skillId = getNumber(L, 2); player->setOfflineTrainingSkill(skillId); @@ -1242,7 +1245,7 @@ int PlayerFunctions::luaPlayerSetOfflineTrainingSkill(lua_State* L) { int PlayerFunctions::luaPlayerOpenStash(lua_State* L) { // player:openStash(isNpc) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); bool isNpc = getBoolean(L, 2, false); if (player) { player->sendOpenStash(isNpc); @@ -1256,7 +1259,7 @@ int PlayerFunctions::luaPlayerOpenStash(lua_State* L) { int PlayerFunctions::luaPlayerGetItemCount(lua_State* L) { // player:getItemCount(itemId[, subType = -1]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1280,7 +1283,7 @@ int PlayerFunctions::luaPlayerGetItemCount(lua_State* L) { int PlayerFunctions::luaPlayerGetStashItemCount(lua_State* L) { // player:getStashItemCount(itemId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1309,7 +1312,7 @@ int PlayerFunctions::luaPlayerGetStashItemCount(lua_State* L) { int PlayerFunctions::luaPlayerGetItemById(lua_State* L) { // player:getItemById(itemId, deepSearch[, subType = -1]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1328,7 +1331,7 @@ int PlayerFunctions::luaPlayerGetItemById(lua_State* L) { bool deepSearch = getBoolean(L, 3); int32_t subType = getNumber(L, 4, -1); - Item* item = g_game().findItemOfType(player, itemId, deepSearch, subType); + std::shared_ptr item = g_game().findItemOfType(player, itemId, deepSearch, subType); if (item) { pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -1340,7 +1343,7 @@ int PlayerFunctions::luaPlayerGetItemById(lua_State* L) { int PlayerFunctions::luaPlayerGetVocation(lua_State* L) { // player:getVocation() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushUserdata(L, player->getVocation()); setMetatable(L, -1, "Vocation"); @@ -1352,7 +1355,7 @@ int PlayerFunctions::luaPlayerGetVocation(lua_State* L) { int PlayerFunctions::luaPlayerSetVocation(lua_State* L) { // player:setVocation(id or name or userdata) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1381,7 +1384,7 @@ int PlayerFunctions::luaPlayerSetVocation(lua_State* L) { int PlayerFunctions::luaPlayerGetSex(lua_State* L) { // player:getSex() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getSex()); } else { @@ -1392,7 +1395,7 @@ int PlayerFunctions::luaPlayerGetSex(lua_State* L) { int PlayerFunctions::luaPlayerSetSex(lua_State* L) { // player:setSex(newSex) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { PlayerSex_t newSex = getNumber(L, 2); player->setSex(newSex); @@ -1405,7 +1408,7 @@ int PlayerFunctions::luaPlayerSetSex(lua_State* L) { int PlayerFunctions::luaPlayerGetPronoun(lua_State* L) { // player:getPronoun() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getPronoun()); } else { @@ -1416,7 +1419,7 @@ int PlayerFunctions::luaPlayerGetPronoun(lua_State* L) { int PlayerFunctions::luaPlayerSetPronoun(lua_State* L) { // player:setPronoun(newPronoun) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { PlayerPronoun_t newPronoun = getNumber(L, 2); player->setPronoun(newPronoun); @@ -1429,7 +1432,7 @@ int PlayerFunctions::luaPlayerSetPronoun(lua_State* L) { int PlayerFunctions::luaPlayerGetTown(lua_State* L) { // player:getTown() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushUserdata(L, player->getTown()); setMetatable(L, -1, "Town"); @@ -1441,13 +1444,13 @@ int PlayerFunctions::luaPlayerGetTown(lua_State* L) { int PlayerFunctions::luaPlayerSetTown(lua_State* L) { // player:setTown(town) - Town* town = getUserdata(L, 2); + const auto &town = getUserdataShared(L, 2); if (!town) { pushBoolean(L, false); return 1; } - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setTown(town); pushBoolean(L, true); @@ -1459,7 +1462,7 @@ int PlayerFunctions::luaPlayerSetTown(lua_State* L) { int PlayerFunctions::luaPlayerGetGuild(lua_State* L) { // player:getGuild() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1478,7 +1481,7 @@ int PlayerFunctions::luaPlayerGetGuild(lua_State* L) { int PlayerFunctions::luaPlayerSetGuild(lua_State* L) { // player:setGuild(guild) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1493,7 +1496,7 @@ int PlayerFunctions::luaPlayerSetGuild(lua_State* L) { int PlayerFunctions::luaPlayerGetGuildLevel(lua_State* L) { // player:getGuildLevel() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player && player->getGuild()) { lua_pushnumber(L, player->getGuildRank()->level); } else { @@ -1505,7 +1508,7 @@ int PlayerFunctions::luaPlayerGetGuildLevel(lua_State* L) { int PlayerFunctions::luaPlayerSetGuildLevel(lua_State* L) { // player:setGuildLevel(level) uint8_t level = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getGuild()) { lua_pushnil(L); return 1; @@ -1524,7 +1527,7 @@ int PlayerFunctions::luaPlayerSetGuildLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetGuildNick(lua_State* L) { // player:getGuildNick() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushString(L, player->getGuildNick()); } else { @@ -1536,7 +1539,7 @@ int PlayerFunctions::luaPlayerGetGuildNick(lua_State* L) { int PlayerFunctions::luaPlayerSetGuildNick(lua_State* L) { // player:setGuildNick(nick) const std::string &nick = getString(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setGuildNick(nick); pushBoolean(L, true); @@ -1548,7 +1551,7 @@ int PlayerFunctions::luaPlayerSetGuildNick(lua_State* L) { int PlayerFunctions::luaPlayerGetGroup(lua_State* L) { // player:getGroup() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushUserdata(L, player->getGroup()); setMetatable(L, -1, "Group"); @@ -1566,7 +1569,7 @@ int PlayerFunctions::luaPlayerSetGroup(lua_State* L) { return 1; } - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setGroup(group); pushBoolean(L, true); @@ -1581,7 +1584,7 @@ int PlayerFunctions::luaPlayerSetSpecialContainersAvailable(lua_State* L) { bool supplyStashMenu = getBoolean(L, 2, false); bool marketMenu = getBoolean(L, 3, false); bool depotSearchMenu = getBoolean(L, 4, false); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setSpecialMenuAvailable(supplyStashMenu, marketMenu, depotSearchMenu); pushBoolean(L, true); @@ -1593,7 +1596,7 @@ int PlayerFunctions::luaPlayerSetSpecialContainersAvailable(lua_State* L) { int PlayerFunctions::luaPlayerGetStamina(lua_State* L) { // player:getStamina() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getStaminaMinutes()); } else { @@ -1605,7 +1608,7 @@ int PlayerFunctions::luaPlayerGetStamina(lua_State* L) { int PlayerFunctions::luaPlayerSetStamina(lua_State* L) { // player:setStamina(stamina) uint16_t stamina = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->staminaMinutes = std::min(2520, stamina); player->sendStats(); @@ -1617,7 +1620,7 @@ int PlayerFunctions::luaPlayerSetStamina(lua_State* L) { int PlayerFunctions::luaPlayerGetSoul(lua_State* L) { // player:getSoul() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getSoul()); } else { @@ -1629,7 +1632,7 @@ int PlayerFunctions::luaPlayerGetSoul(lua_State* L) { int PlayerFunctions::luaPlayerAddSoul(lua_State* L) { // player:addSoul(soulChange) int32_t soulChange = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->changeSoul(soulChange); pushBoolean(L, true); @@ -1641,7 +1644,7 @@ int PlayerFunctions::luaPlayerAddSoul(lua_State* L) { int PlayerFunctions::luaPlayerGetMaxSoul(lua_State* L) { // player:getMaxSoul() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player && player->vocation) { lua_pushnumber(L, player->vocation->getSoulMax()); } else { @@ -1652,7 +1655,7 @@ int PlayerFunctions::luaPlayerGetMaxSoul(lua_State* L) { int PlayerFunctions::luaPlayerGetBankBalance(lua_State* L) { // player:getBankBalance() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getBankBalance()); } else { @@ -1663,7 +1666,7 @@ int PlayerFunctions::luaPlayerGetBankBalance(lua_State* L) { int PlayerFunctions::luaPlayerSetBankBalance(lua_State* L) { // player:setBankBalance(bankBalance) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1676,7 +1679,7 @@ int PlayerFunctions::luaPlayerSetBankBalance(lua_State* L) { int PlayerFunctions::luaPlayerGetStorageValue(lua_State* L) { // player:getStorageValue(key) - const auto &player = getUserdata(L, 1); + const auto player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1691,7 +1694,7 @@ int PlayerFunctions::luaPlayerSetStorageValue(lua_State* L) { // player:setStorageValue(key, value) int32_t value = getNumber(L, 3); uint32_t key = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (IS_IN_KEYRANGE(key, RESERVED_RANGE)) { std::ostringstream ss; ss << "Accessing reserved range: " << key; @@ -1711,7 +1714,7 @@ int PlayerFunctions::luaPlayerSetStorageValue(lua_State* L) { int PlayerFunctions::luaPlayerGetStorageValueByName(lua_State* L) { // player:getStorageValueByName(name) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -1725,7 +1728,7 @@ int PlayerFunctions::luaPlayerGetStorageValueByName(lua_State* L) { int PlayerFunctions::luaPlayerSetStorageValueByName(lua_State* L) { // player:setStorageValueByName(storageName, value) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -1742,7 +1745,7 @@ int PlayerFunctions::luaPlayerSetStorageValueByName(lua_State* L) { int PlayerFunctions::luaPlayerAddItem(lua_State* L) { // player:addItem(itemId, count = 1, canDropOnMap = true, subType = 1, slot = CONST_SLOT_WHEREEVER, tier = 0) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { pushBoolean(L, false); return 1; @@ -1796,7 +1799,7 @@ int PlayerFunctions::luaPlayerAddItem(lua_State* L) { subType -= stackCount; } - Item* item = Item::CreateItem(itemId, stackCount); + std::shared_ptr item = Item::CreateItem(itemId, stackCount); if (!item) { if (!hasTable) { lua_pushnil(L); @@ -1810,7 +1813,6 @@ int PlayerFunctions::luaPlayerAddItem(lua_State* L) { ReturnValue ret = g_game().internalPlayerAddItem(player, item, canDropOnMap, slot); if (ret != RETURNVALUE_NOERROR) { - delete item; if (!hasTable) { lua_pushnil(L); } @@ -1833,14 +1835,14 @@ int PlayerFunctions::luaPlayerAddItem(lua_State* L) { int PlayerFunctions::luaPlayerAddItemEx(lua_State* L) { // player:addItemEx(item[, canDropOnMap = false[, index = INDEX_WHEREEVER[, flags = 0]]]) // player:addItemEx(item[, canDropOnMap = true[, slot = CONST_SLOT_WHEREEVER]]) - Item* item = getUserdata(L, 2); + std::shared_ptr item = getUserdataShared(L, 2); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); return 1; } - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1872,7 +1874,7 @@ int PlayerFunctions::luaPlayerAddItemEx(lua_State* L) { int PlayerFunctions::luaPlayerRemoveStashItem(lua_State* L) { // player:removeStashItem(itemId, count) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1902,7 +1904,7 @@ int PlayerFunctions::luaPlayerRemoveStashItem(lua_State* L) { int PlayerFunctions::luaPlayerRemoveItem(lua_State* L) { // player:removeItem(itemId, count[, subType = -1[, ignoreEquipped = false]]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -1928,13 +1930,13 @@ int PlayerFunctions::luaPlayerRemoveItem(lua_State* L) { int PlayerFunctions::luaPlayerSendContainer(lua_State* L) { // player:sendContainer(container) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Container* container = getUserdata(L, 2); + std::shared_ptr container = getUserdataShared(L, 2); if (!container) { lua_pushnil(L); return 1; @@ -1947,13 +1949,13 @@ int PlayerFunctions::luaPlayerSendContainer(lua_State* L) { int PlayerFunctions::luaPlayerSendUpdateContainer(lua_State* L) { // player:sendUpdateContainer(container) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - const auto container = getUserdata(L, 2); + const auto container = getUserdataShared(L, 2); if (!container) { reportErrorFunc("Container is nullptr"); return 1; @@ -1966,7 +1968,7 @@ int PlayerFunctions::luaPlayerSendUpdateContainer(lua_State* L) { int PlayerFunctions::luaPlayerGetMoney(lua_State* L) { // player:getMoney() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getMoney()); } else { @@ -1978,7 +1980,7 @@ int PlayerFunctions::luaPlayerGetMoney(lua_State* L) { int PlayerFunctions::luaPlayerAddMoney(lua_State* L) { // player:addMoney(money) uint64_t money = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { g_game().addMoney(player, money); pushBoolean(L, true); @@ -1990,7 +1992,7 @@ int PlayerFunctions::luaPlayerAddMoney(lua_State* L) { int PlayerFunctions::luaPlayerRemoveMoney(lua_State* L) { // player:removeMoney(money[, flags = 0[, useBank = true]]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint64_t money = getNumber(L, 2); int32_t flags = getNumber(L, 3, 0); @@ -2004,7 +2006,7 @@ int PlayerFunctions::luaPlayerRemoveMoney(lua_State* L) { int PlayerFunctions::luaPlayerShowTextDialog(lua_State* L) { // player:showTextDialog(id or name or userdata[, text[, canWrite[, length]]]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2019,7 +2021,7 @@ int PlayerFunctions::luaPlayerShowTextDialog(lua_State* L) { text = getString(L, 3); } - Item* item; + std::shared_ptr item; if (isNumber(L, 2)) { item = Item::CreateItem(getNumber(L, 2)); } else if (isString(L, 2)) { @@ -2030,7 +2032,7 @@ int PlayerFunctions::luaPlayerShowTextDialog(lua_State* L) { return 1; } - item = getUserdata(L, 2); + item = getUserdataShared(L, 2); } else { item = nullptr; } @@ -2061,7 +2063,7 @@ int PlayerFunctions::luaPlayerSendTextMessage(lua_State* L) { // player:sendTextMessage(type, text[, position, primaryValue = 0, primaryColor = TEXTCOLOR_NONE[, secondaryValue = 0, secondaryColor = TEXTCOLOR_NONE]]) // player:sendTextMessage(type, text, channelId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2072,8 +2074,8 @@ 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); - if (!channel || !channel->hasUser(*player)) { + ChatChannel* channel = g_chat().getChannel(player, channelId); + if (!channel || !channel->hasUser(player)) { pushBoolean(L, false); return 1; } @@ -2099,7 +2101,7 @@ int PlayerFunctions::luaPlayerSendTextMessage(lua_State* L) { int PlayerFunctions::luaPlayerSendChannelMessage(lua_State* L) { // player:sendChannelMessage(author, text, type, channelId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2116,13 +2118,13 @@ int PlayerFunctions::luaPlayerSendChannelMessage(lua_State* L) { int PlayerFunctions::luaPlayerSendPrivateMessage(lua_State* L) { // player:sendPrivateMessage(speaker, text[, type]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - const Player* speaker = getUserdata(L, 2); + std::shared_ptr speaker = getUserdataShared(L, 2); const std::string &text = getString(L, 3); SpeakClasses type = getNumber(L, 4, TALKTYPE_PRIVATE_FROM); player->sendPrivateMessage(speaker, type, text); @@ -2132,13 +2134,13 @@ int PlayerFunctions::luaPlayerSendPrivateMessage(lua_State* L) { int PlayerFunctions::luaPlayerChannelSay(lua_State* L) { // player:channelSay(speaker, type, text, channelId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Creature* speaker = getCreature(L, 2); + std::shared_ptr speaker = getCreature(L, 2); SpeakClasses type = getNumber(L, 3); const std::string &text = getString(L, 4); uint16_t channelId = getNumber(L, 5); @@ -2150,7 +2152,7 @@ int PlayerFunctions::luaPlayerChannelSay(lua_State* L) { int PlayerFunctions::luaPlayerOpenChannel(lua_State* L) { // player:openChannel(channelId) uint16_t channelId = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { g_game().playerOpenChannel(player->getID(), channelId); pushBoolean(L, true); @@ -2162,20 +2164,20 @@ int PlayerFunctions::luaPlayerOpenChannel(lua_State* L) { int PlayerFunctions::luaPlayerGetSlotItem(lua_State* L) { // player:getSlotItem(slot) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } uint32_t slot = getNumber(L, 2); - Thing* thing = player->getThing(slot); + std::shared_ptr thing = player->getThing(slot); if (!thing) { lua_pushnil(L); return 1; } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item) { pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -2187,13 +2189,13 @@ int PlayerFunctions::luaPlayerGetSlotItem(lua_State* L) { int PlayerFunctions::luaPlayerGetParty(lua_State* L) { // player:getParty() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Party* party = player->getParty(); + std::shared_ptr party = player->getParty(); if (party) { pushUserdata(L, party); setMetatable(L, -1, "Party"); @@ -2205,7 +2207,7 @@ int PlayerFunctions::luaPlayerGetParty(lua_State* L) { int PlayerFunctions::luaPlayerAddOutfit(lua_State* L) { // player:addOutfit(lookType) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->addOutfit(getNumber(L, 2), 0); pushBoolean(L, true); @@ -2217,7 +2219,7 @@ int PlayerFunctions::luaPlayerAddOutfit(lua_State* L) { int PlayerFunctions::luaPlayerAddOutfitAddon(lua_State* L) { // player:addOutfitAddon(lookType, addon) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t lookType = getNumber(L, 2); uint8_t addon = getNumber(L, 3); @@ -2231,7 +2233,7 @@ int PlayerFunctions::luaPlayerAddOutfitAddon(lua_State* L) { int PlayerFunctions::luaPlayerRemoveOutfit(lua_State* L) { // player:removeOutfit(lookType) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t lookType = getNumber(L, 2); pushBoolean(L, player->removeOutfit(lookType)); @@ -2243,7 +2245,7 @@ int PlayerFunctions::luaPlayerRemoveOutfit(lua_State* L) { int PlayerFunctions::luaPlayerRemoveOutfitAddon(lua_State* L) { // player:removeOutfitAddon(lookType, addon) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t lookType = getNumber(L, 2); uint8_t addon = getNumber(L, 3); @@ -2256,7 +2258,7 @@ int PlayerFunctions::luaPlayerRemoveOutfitAddon(lua_State* L) { int PlayerFunctions::luaPlayerHasOutfit(lua_State* L) { // player:hasOutfit(lookType[, addon = 0]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t lookType = getNumber(L, 2); uint8_t addon = getNumber(L, 3, 0); @@ -2269,7 +2271,7 @@ int PlayerFunctions::luaPlayerHasOutfit(lua_State* L) { int PlayerFunctions::luaPlayerSendOutfitWindow(lua_State* L) { // player:sendOutfitWindow() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->sendOutfitWindow(); pushBoolean(L, true); @@ -2281,7 +2283,7 @@ int PlayerFunctions::luaPlayerSendOutfitWindow(lua_State* L) { int PlayerFunctions::luaPlayerAddMount(lua_State* L) { // player:addMount(mountId or mountName) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2304,7 +2306,7 @@ int PlayerFunctions::luaPlayerAddMount(lua_State* L) { int PlayerFunctions::luaPlayerRemoveMount(lua_State* L) { // player:removeMount(mountId or mountName) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2327,7 +2329,7 @@ int PlayerFunctions::luaPlayerRemoveMount(lua_State* L) { int PlayerFunctions::luaPlayerHasMount(lua_State* L) { // player:hasMount(mountId or mountName) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2350,7 +2352,7 @@ int PlayerFunctions::luaPlayerHasMount(lua_State* L) { int PlayerFunctions::luaPlayerAddFamiliar(lua_State* L) { // player:addFamiliar(lookType) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->addFamiliar(getNumber(L, 2)); pushBoolean(L, true); @@ -2362,7 +2364,7 @@ int PlayerFunctions::luaPlayerAddFamiliar(lua_State* L) { int PlayerFunctions::luaPlayerRemoveFamiliar(lua_State* L) { // player:removeFamiliar(lookType) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t lookType = getNumber(L, 2); pushBoolean(L, player->removeFamiliar(lookType)); @@ -2374,7 +2376,7 @@ int PlayerFunctions::luaPlayerRemoveFamiliar(lua_State* L) { int PlayerFunctions::luaPlayerHasFamiliar(lua_State* L) { // player:hasFamiliar(lookType) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t lookType = getNumber(L, 2); pushBoolean(L, player->canFamiliar(lookType)); @@ -2386,7 +2388,7 @@ int PlayerFunctions::luaPlayerHasFamiliar(lua_State* L) { int PlayerFunctions::luaPlayerSetFamiliarLooktype(lua_State* L) { // player:setFamiliarLooktype(lookType) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setFamiliarLooktype(getNumber(L, 2)); pushBoolean(L, true); @@ -2398,7 +2400,7 @@ int PlayerFunctions::luaPlayerSetFamiliarLooktype(lua_State* L) { int PlayerFunctions::luaPlayerGetFamiliarLooktype(lua_State* L) { // player:getFamiliarLooktype() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->defaultOutfit.lookFamiliarsType); } else { @@ -2409,7 +2411,7 @@ int PlayerFunctions::luaPlayerGetFamiliarLooktype(lua_State* L) { int PlayerFunctions::luaPlayerGetPremiumDays(lua_State* L) { // player:getPremiumDays() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player && player->getAccount()) { lua_pushnumber(L, player->getAccount()->getPremiumRemainingDays()); } else { @@ -2420,7 +2422,7 @@ int PlayerFunctions::luaPlayerGetPremiumDays(lua_State* L) { int PlayerFunctions::luaPlayerAddPremiumDays(lua_State* L) { // player:addPremiumDays(days) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { lua_pushnil(L); return 1; @@ -2449,7 +2451,7 @@ int PlayerFunctions::luaPlayerAddPremiumDays(lua_State* L) { int PlayerFunctions::luaPlayerRemovePremiumDays(lua_State* L) { // player:removePremiumDays(days) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { lua_pushnil(L); return 1; @@ -2478,7 +2480,7 @@ int PlayerFunctions::luaPlayerRemovePremiumDays(lua_State* L) { int PlayerFunctions::luaPlayerGetTibiaCoins(lua_State* L) { // player:getTibiaCoins() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushnil(L); @@ -2496,7 +2498,7 @@ int PlayerFunctions::luaPlayerGetTibiaCoins(lua_State* L) { int PlayerFunctions::luaPlayerAddTibiaCoins(lua_State* L) { // player:addTibiaCoins(coins) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushnil(L); @@ -2522,7 +2524,7 @@ int PlayerFunctions::luaPlayerAddTibiaCoins(lua_State* L) { int PlayerFunctions::luaPlayerRemoveTibiaCoins(lua_State* L) { // player:removeTibiaCoins(coins) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushnil(L); @@ -2547,7 +2549,7 @@ int PlayerFunctions::luaPlayerRemoveTibiaCoins(lua_State* L) { int PlayerFunctions::luaPlayerGetTransferableCoins(lua_State* L) { // player:getTransferableCoins() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushnil(L); @@ -2565,7 +2567,7 @@ int PlayerFunctions::luaPlayerGetTransferableCoins(lua_State* L) { int PlayerFunctions::luaPlayerAddTransferableCoins(lua_State* L) { // player:addTransferableCoins(coins) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushnil(L); @@ -2591,7 +2593,7 @@ int PlayerFunctions::luaPlayerAddTransferableCoins(lua_State* L) { int PlayerFunctions::luaPlayerRemoveTransferableCoins(lua_State* L) { // player:removeTransferableCoins(coins) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushnil(L); @@ -2618,7 +2620,7 @@ int PlayerFunctions::luaPlayerRemoveTransferableCoins(lua_State* L) { int PlayerFunctions::luaPlayerHasBlessing(lua_State* L) { // player:hasBlessing(blessing) uint8_t blessing = getNumber(L, 2); - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushBoolean(L, player->hasBlessing(blessing)); } else { @@ -2629,7 +2631,7 @@ int PlayerFunctions::luaPlayerHasBlessing(lua_State* L) { int PlayerFunctions::luaPlayerAddBlessing(lua_State* L) { // player:addBlessing(blessing) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2646,7 +2648,7 @@ int PlayerFunctions::luaPlayerAddBlessing(lua_State* L) { int PlayerFunctions::luaPlayerRemoveBlessing(lua_State* L) { // player:removeBlessing(blessing) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2667,7 +2669,7 @@ int PlayerFunctions::luaPlayerRemoveBlessing(lua_State* L) { int PlayerFunctions::luaPlayerGetBlessingCount(lua_State* L) { // player:getBlessingCount(index) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); uint8_t index = getNumber(L, 2); if (index == 0) { index = 1; @@ -2683,7 +2685,7 @@ int PlayerFunctions::luaPlayerGetBlessingCount(lua_State* L) { int PlayerFunctions::luaPlayerCanLearnSpell(lua_State* L) { // player:canLearnSpell(spellName) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2702,7 +2704,7 @@ int PlayerFunctions::luaPlayerCanLearnSpell(lua_State* L) { return 1; } - const auto &vocMap = spell->getVocMap(); + const auto vocMap = spell->getVocMap(); if (vocMap.count(player->getVocationId()) == 0) { pushBoolean(L, false); } else if (player->getLevel() < spell->getLevel()) { @@ -2717,7 +2719,7 @@ int PlayerFunctions::luaPlayerCanLearnSpell(lua_State* L) { int PlayerFunctions::luaPlayerLearnSpell(lua_State* L) { // player:learnSpell(spellName) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { const std::string &spellName = getString(L, 2); player->learnInstantSpell(spellName); @@ -2730,7 +2732,7 @@ int PlayerFunctions::luaPlayerLearnSpell(lua_State* L) { int PlayerFunctions::luaPlayerForgetSpell(lua_State* L) { // player:forgetSpell(spellName) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { const std::string &spellName = getString(L, 2); player->forgetInstantSpell(spellName); @@ -2743,7 +2745,7 @@ int PlayerFunctions::luaPlayerForgetSpell(lua_State* L) { int PlayerFunctions::luaPlayerHasLearnedSpell(lua_State* L) { // player:hasLearnedSpell(spellName) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { const std::string &spellName = getString(L, 2); pushBoolean(L, player->hasLearnedInstantSpell(spellName)); @@ -2755,7 +2757,7 @@ int PlayerFunctions::luaPlayerHasLearnedSpell(lua_State* L) { int PlayerFunctions::luaPlayerSendTutorial(lua_State* L) { // player:sendTutorial(tutorialId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint8_t tutorialId = getNumber(L, 2); player->sendTutorial(tutorialId); @@ -2768,14 +2770,14 @@ int PlayerFunctions::luaPlayerSendTutorial(lua_State* L) { int PlayerFunctions::luaPlayerOpenImbuementWindow(lua_State* L) { // player:openImbuementWindow(item) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } - Item* item = getUserdata(L, 2); + std::shared_ptr item = getUserdataShared(L, 2); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -2788,7 +2790,7 @@ int PlayerFunctions::luaPlayerOpenImbuementWindow(lua_State* L) { int PlayerFunctions::luaPlayerCloseImbuementWindow(lua_State* L) { // player:closeImbuementWindow() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -2801,7 +2803,7 @@ int PlayerFunctions::luaPlayerCloseImbuementWindow(lua_State* L) { int PlayerFunctions::luaPlayerAddMapMark(lua_State* L) { // player:addMapMark(position, type, description) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { const Position &position = getPosition(L, 2); uint8_t type = getNumber(L, 3); @@ -2816,14 +2818,14 @@ int PlayerFunctions::luaPlayerAddMapMark(lua_State* L) { int PlayerFunctions::luaPlayerSave(lua_State* L) { // player:save() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { if (!player->isOffline()) { player->loginPosition = player->getPosition(); } pushBoolean(L, IOLoginData::savePlayer(player)); if (player->isOffline()) { - delete player; // avoiding memory leak + // avoiding memory leak } } else { lua_pushnil(L); @@ -2833,7 +2835,7 @@ int PlayerFunctions::luaPlayerSave(lua_State* L) { int PlayerFunctions::luaPlayerPopupFYI(lua_State* L) { // player:popupFYI(message) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { const std::string &message = getString(L, 2); player->sendFYIBox(message); @@ -2846,7 +2848,7 @@ int PlayerFunctions::luaPlayerPopupFYI(lua_State* L) { int PlayerFunctions::luaPlayerIsPzLocked(lua_State* L) { // player:isPzLocked() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushBoolean(L, player->isPzLocked()); } else { @@ -2857,7 +2859,7 @@ int PlayerFunctions::luaPlayerIsPzLocked(lua_State* L) { int PlayerFunctions::luaPlayerGetClient(lua_State* L) { // player:getClient() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_createtable(L, 0, 2); setField(L, "version", player->getProtocolVersion()); @@ -2870,13 +2872,13 @@ int PlayerFunctions::luaPlayerGetClient(lua_State* L) { int PlayerFunctions::luaPlayerGetHouse(lua_State* L) { // player:getHouse() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - House* house = g_game().map.houses.getHouseByPlayerId(player->getGUID()); + const auto &house = g_game().map.houses.getHouseByPlayerId(player->getGUID()); if (house) { pushUserdata(L, house); setMetatable(L, -1, "House"); @@ -2888,13 +2890,13 @@ int PlayerFunctions::luaPlayerGetHouse(lua_State* L) { int PlayerFunctions::luaPlayerSendHouseWindow(lua_State* L) { // player:sendHouseWindow(house, listId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - House* house = getUserdata(L, 2); + const auto &house = getUserdataShared(L, 2); if (!house) { lua_pushnil(L); return 1; @@ -2908,13 +2910,13 @@ int PlayerFunctions::luaPlayerSendHouseWindow(lua_State* L) { int PlayerFunctions::luaPlayerSetEditHouse(lua_State* L) { // player:setEditHouse(house, listId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - House* house = getUserdata(L, 2); + const auto &house = getUserdataShared(L, 2); if (!house) { lua_pushnil(L); return 1; @@ -2928,7 +2930,7 @@ int PlayerFunctions::luaPlayerSetEditHouse(lua_State* L) { int PlayerFunctions::luaPlayerSetGhostMode(lua_State* L) { // player:setGhostMode(enabled) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -2942,13 +2944,13 @@ int PlayerFunctions::luaPlayerSetGhostMode(lua_State* L) { player->switchGhostMode(); - Tile* tile = player->getTile(); + std::shared_ptr tile = player->getTile(); const Position &position = player->getPosition(); SpectatorHashSet spectators; g_game().map.getSpectators(spectators, position, true, true); - for (Creature* spectator : spectators) { - Player* tmpPlayer = spectator->getPlayer(); + for (auto spectator : spectators) { + auto tmpPlayer = spectator->getPlayer(); if (tmpPlayer != player && !tmpPlayer->isAccessPlayer()) { if (enabled) { tmpPlayer->sendRemoveTileThing(position, tile->getStackposOfCreature(tmpPlayer, player)); @@ -2981,13 +2983,13 @@ int PlayerFunctions::luaPlayerSetGhostMode(lua_State* L) { int PlayerFunctions::luaPlayerGetContainerId(lua_State* L) { // player:getContainerId(container) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Container* container = getUserdata(L, 2); + std::shared_ptr container = getUserdataShared(L, 2); if (container) { lua_pushnumber(L, player->getContainerID(container)); } else { @@ -2998,13 +3000,13 @@ int PlayerFunctions::luaPlayerGetContainerId(lua_State* L) { int PlayerFunctions::luaPlayerGetContainerById(lua_State* L) { // player:getContainerById(id) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; } - Container* container = player->getContainerByID(getNumber(L, 2)); + std::shared_ptr container = player->getContainerByID(getNumber(L, 2)); if (container) { pushUserdata(L, container); setMetatable(L, -1, "Container"); @@ -3016,7 +3018,7 @@ int PlayerFunctions::luaPlayerGetContainerById(lua_State* L) { int PlayerFunctions::luaPlayerGetContainerIndex(lua_State* L) { // player:getContainerIndex(id) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getContainerIndex(getNumber(L, 2))); } else { @@ -3027,7 +3029,7 @@ int PlayerFunctions::luaPlayerGetContainerIndex(lua_State* L) { int PlayerFunctions::luaPlayerGetInstantSpells(lua_State* L) { // player:getInstantSpells() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3052,7 +3054,7 @@ int PlayerFunctions::luaPlayerGetInstantSpells(lua_State* L) { int PlayerFunctions::luaPlayerCanCast(lua_State* L) { // player:canCast(spell) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); const auto spell = getUserdataShared(L, 2); if (player && spell) { pushBoolean(L, spell->canCast(player)); @@ -3064,7 +3066,7 @@ int PlayerFunctions::luaPlayerCanCast(lua_State* L) { int PlayerFunctions::luaPlayerHasChaseMode(lua_State* L) { // player:hasChaseMode() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushBoolean(L, player->chaseMode); } else { @@ -3075,7 +3077,7 @@ int PlayerFunctions::luaPlayerHasChaseMode(lua_State* L) { int PlayerFunctions::luaPlayerHasSecureMode(lua_State* L) { // player:hasSecureMode() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushBoolean(L, player->secureMode); } else { @@ -3086,7 +3088,7 @@ int PlayerFunctions::luaPlayerHasSecureMode(lua_State* L) { int PlayerFunctions::luaPlayerGetFightMode(lua_State* L) { // player:getFightMode() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->fightMode); } else { @@ -3097,7 +3099,7 @@ int PlayerFunctions::luaPlayerGetFightMode(lua_State* L) { int PlayerFunctions::luaPlayerGetBaseXpGain(lua_State* L) { // player:getBaseXpGain() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getBaseXpGain()); } else { @@ -3108,7 +3110,7 @@ int PlayerFunctions::luaPlayerGetBaseXpGain(lua_State* L) { int PlayerFunctions::luaPlayerSetBaseXpGain(lua_State* L) { // player:setBaseXpGain(value) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setBaseXpGain(getNumber(L, 2)); player->sendStats(); @@ -3121,7 +3123,7 @@ int PlayerFunctions::luaPlayerSetBaseXpGain(lua_State* L) { int PlayerFunctions::luaPlayerGetVoucherXpBoost(lua_State* L) { // player:getVoucherXpBoost() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getVoucherXpBoost()); } else { @@ -3132,7 +3134,7 @@ int PlayerFunctions::luaPlayerGetVoucherXpBoost(lua_State* L) { int PlayerFunctions::luaPlayerSetVoucherXpBoost(lua_State* L) { // player:setVoucherXpBoost(value) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setVoucherXpBoost(getNumber(L, 2)); player->sendStats(); @@ -3145,7 +3147,7 @@ int PlayerFunctions::luaPlayerSetVoucherXpBoost(lua_State* L) { int PlayerFunctions::luaPlayerGetGrindingXpBoost(lua_State* L) { // player:getGrindingXpBoost() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getGrindingXpBoost()); } else { @@ -3156,7 +3158,7 @@ int PlayerFunctions::luaPlayerGetGrindingXpBoost(lua_State* L) { int PlayerFunctions::luaPlayerSetGrindingXpBoost(lua_State* L) { // player:setGrindingXpBoost(value) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setGrindingXpBoost(getNumber(L, 2)); player->sendStats(); @@ -3169,7 +3171,7 @@ int PlayerFunctions::luaPlayerSetGrindingXpBoost(lua_State* L) { int PlayerFunctions::luaPlayerGetStoreXpBoost(lua_State* L) { // player:getStoreXpBoost() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getStoreXpBoost()); } else { @@ -3180,7 +3182,7 @@ int PlayerFunctions::luaPlayerGetStoreXpBoost(lua_State* L) { int PlayerFunctions::luaPlayerSetStoreXpBoost(lua_State* L) { // player:setStoreXpBoost(value) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t experience = getNumber(L, 2); player->setStoreXpBoost(experience); @@ -3193,7 +3195,7 @@ int PlayerFunctions::luaPlayerSetStoreXpBoost(lua_State* L) { int PlayerFunctions::luaPlayerGetStaminaXpBoost(lua_State* L) { // player:getStaminaXpBoost() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getStaminaXpBoost()); } else { @@ -3204,7 +3206,7 @@ int PlayerFunctions::luaPlayerGetStaminaXpBoost(lua_State* L) { int PlayerFunctions::luaPlayerSetStaminaXpBoost(lua_State* L) { // player:setStaminaXpBoost(value) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { player->setStaminaXpBoost(getNumber(L, 2)); player->sendStats(); @@ -3217,7 +3219,7 @@ int PlayerFunctions::luaPlayerSetStaminaXpBoost(lua_State* L) { int PlayerFunctions::luaPlayerSetExpBoostStamina(lua_State* L) { // player:setExpBoostStamina(percent) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { uint16_t stamina = getNumber(L, 2); player->setExpBoostStamina(stamina); @@ -3231,7 +3233,7 @@ int PlayerFunctions::luaPlayerSetExpBoostStamina(lua_State* L) { int PlayerFunctions::luaPlayerGetExpBoostStamina(lua_State* L) { // player:getExpBoostStamina() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getExpBoostStamina()); } else { @@ -3242,7 +3244,7 @@ int PlayerFunctions::luaPlayerGetExpBoostStamina(lua_State* L) { int PlayerFunctions::luaPlayerGetIdleTime(lua_State* L) { // player:getIdleTime() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { lua_pushnumber(L, player->getIdleTime()); } else { @@ -3253,7 +3255,7 @@ int PlayerFunctions::luaPlayerGetIdleTime(lua_State* L) { int PlayerFunctions::luaPlayerGetFreeBackpackSlots(lua_State* L) { // player:getFreeBackpackSlots() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); } @@ -3263,7 +3265,7 @@ int PlayerFunctions::luaPlayerGetFreeBackpackSlots(lua_State* L) { } int PlayerFunctions::luaPlayerIsOffline(lua_State* L) { - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player) { pushBoolean(L, player->isOffline()); } else { @@ -3275,7 +3277,7 @@ int PlayerFunctions::luaPlayerIsOffline(lua_State* L) { int PlayerFunctions::luaPlayerOpenMarket(lua_State* L) { // player:openMarket() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3289,7 +3291,7 @@ int PlayerFunctions::luaPlayerOpenMarket(lua_State* L) { // Forge int PlayerFunctions::luaPlayerOpenForge(lua_State* L) { // player:openForge() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3303,7 +3305,7 @@ int PlayerFunctions::luaPlayerOpenForge(lua_State* L) { int PlayerFunctions::luaPlayerCloseForge(lua_State* L) { // player:closeForge() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3317,7 +3319,7 @@ int PlayerFunctions::luaPlayerCloseForge(lua_State* L) { int PlayerFunctions::luaPlayerAddForgeDusts(lua_State* L) { // player:addForgeDusts(amount) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3331,7 +3333,7 @@ int PlayerFunctions::luaPlayerAddForgeDusts(lua_State* L) { int PlayerFunctions::luaPlayerRemoveForgeDusts(lua_State* L) { // player:removeForgeDusts(amount) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3345,7 +3347,7 @@ int PlayerFunctions::luaPlayerRemoveForgeDusts(lua_State* L) { int PlayerFunctions::luaPlayerGetForgeDusts(lua_State* L) { // player:getForgeDusts() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3358,7 +3360,7 @@ int PlayerFunctions::luaPlayerGetForgeDusts(lua_State* L) { int PlayerFunctions::luaPlayerSetForgeDusts(lua_State* L) { // player:setForgeDusts() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3372,7 +3374,7 @@ int PlayerFunctions::luaPlayerSetForgeDusts(lua_State* L) { int PlayerFunctions::luaPlayerAddForgeDustLevel(lua_State* L) { // player:addForgeDustLevel(amount) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3386,7 +3388,7 @@ int PlayerFunctions::luaPlayerAddForgeDustLevel(lua_State* L) { int PlayerFunctions::luaPlayerRemoveForgeDustLevel(lua_State* L) { // player:removeForgeDustLevel(amount) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3400,7 +3402,7 @@ int PlayerFunctions::luaPlayerRemoveForgeDustLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetForgeDustLevel(lua_State* L) { // player:getForgeDustLevel() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3413,7 +3415,7 @@ int PlayerFunctions::luaPlayerGetForgeDustLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetForgeSlivers(lua_State* L) { // player:getForgeSlivers() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3427,7 +3429,7 @@ int PlayerFunctions::luaPlayerGetForgeSlivers(lua_State* L) { int PlayerFunctions::luaPlayerGetForgeCores(lua_State* L) { // player:getForgeCores() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3441,7 +3443,7 @@ int PlayerFunctions::luaPlayerGetForgeCores(lua_State* L) { int PlayerFunctions::luaPlayerSetFaction(lua_State* L) { // player:setFaction(factionId) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player == nullptr) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3456,7 +3458,7 @@ int PlayerFunctions::luaPlayerSetFaction(lua_State* L) { int PlayerFunctions::luaPlayerGetFaction(lua_State* L) { // player:getFaction() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (player == nullptr) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3469,7 +3471,7 @@ int PlayerFunctions::luaPlayerGetFaction(lua_State* L) { int PlayerFunctions::luaPlayerIsUIExhausted(lua_State* L) { // player:isUIExhausted() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3483,7 +3485,7 @@ int PlayerFunctions::luaPlayerIsUIExhausted(lua_State* L) { int PlayerFunctions::luaPlayerUpdateUIExhausted(lua_State* L) { // player:updateUIExhausted(exhaustionTime = 250) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3498,7 +3500,7 @@ int PlayerFunctions::luaPlayerUpdateUIExhausted(lua_State* L) { // Bosstiary Cooldown Timer int PlayerFunctions::luaPlayerBosstiaryCooldownTimer(lua_State* L) { // player:sendBosstiaryCooldownTimer() - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3512,7 +3514,7 @@ int PlayerFunctions::luaPlayerBosstiaryCooldownTimer(lua_State* L) { int PlayerFunctions::luaPlayerGetBosstiaryLevel(lua_State* L) { // player:getBosstiaryLevel(name) - if (Player* player = getUserdata(L, 1); + if (std::shared_ptr player = getUserdataShared(L, 1); player) { const auto mtype = g_monsters().getMonsterType(getString(L, 2)); if (mtype) { @@ -3534,7 +3536,7 @@ int PlayerFunctions::luaPlayerGetBosstiaryLevel(lua_State* L) { int PlayerFunctions::luaPlayerGetBosstiaryKills(lua_State* L) { // player:getBosstiaryKills(name) - if (Player* player = getUserdata(L, 1); + if (std::shared_ptr player = getUserdataShared(L, 1); player) { const auto mtype = g_monsters().getMonsterType(getString(L, 2)); if (mtype) { @@ -3556,7 +3558,7 @@ int PlayerFunctions::luaPlayerGetBosstiaryKills(lua_State* L) { int PlayerFunctions::luaPlayerAddBosstiaryKill(lua_State* L) { // player:addBosstiaryKill(name[, amount = 1]) - if (Player* player = getUserdata(L, 1); + if (std::shared_ptr player = getUserdataShared(L, 1); player) { const auto mtype = g_monsters().getMonsterType(getString(L, 2)); if (mtype) { @@ -3573,7 +3575,7 @@ int PlayerFunctions::luaPlayerAddBosstiaryKill(lua_State* L) { int PlayerFunctions::luaPlayerSetBossPoints(lua_State* L) { // player:setBossPoints() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3587,7 +3589,7 @@ int PlayerFunctions::luaPlayerSetBossPoints(lua_State* L) { int PlayerFunctions::luaPlayerSetRemoveBossTime(lua_State* L) { // player:setRemoveBossTime() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3601,7 +3603,7 @@ int PlayerFunctions::luaPlayerSetRemoveBossTime(lua_State* L) { int PlayerFunctions::luaPlayerGetSlotBossId(lua_State* L) { // player:getSlotBossId(slotId) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3616,7 +3618,7 @@ int PlayerFunctions::luaPlayerGetSlotBossId(lua_State* L) { int PlayerFunctions::luaPlayerGetBossBonus(lua_State* L) { // player:getBossBonus(slotId) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3638,7 +3640,7 @@ int PlayerFunctions::luaPlayerGetBossBonus(lua_State* L) { int PlayerFunctions::luaPlayerSendSingleSoundEffect(lua_State* L) { // player:sendSingleSoundEffect(soundId[, actor = true]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3655,7 +3657,7 @@ int PlayerFunctions::luaPlayerSendSingleSoundEffect(lua_State* L) { int PlayerFunctions::luaPlayerSendDoubleSoundEffect(lua_State* L) { // player:sendDoubleSoundEffect(mainSoundId, secondarySoundId[, actor = true]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3673,7 +3675,7 @@ int PlayerFunctions::luaPlayerSendDoubleSoundEffect(lua_State* L) { int PlayerFunctions::luaPlayerGetName(lua_State* L) { // player:getName() - const auto player = getUserdata(L, 1); + const auto player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3686,7 +3688,7 @@ int PlayerFunctions::luaPlayerGetName(lua_State* L) { int PlayerFunctions::luaPlayerHasGroupFlag(lua_State* L) { // player:hasGroupFlag(flag) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3699,7 +3701,7 @@ int PlayerFunctions::luaPlayerHasGroupFlag(lua_State* L) { int PlayerFunctions::luaPlayerSetGroupFlag(lua_State* L) { // player:setGroupFlag(flag) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3712,7 +3714,7 @@ int PlayerFunctions::luaPlayerSetGroupFlag(lua_State* L) { int PlayerFunctions::luaPlayerRemoveGroupFlag(lua_State* L) { // player:removeGroupFlag(flag) - const Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3726,7 +3728,7 @@ int PlayerFunctions::luaPlayerRemoveGroupFlag(lua_State* L) { // Hazard system int PlayerFunctions::luaPlayerAddHazardSystemPoints(lua_State* L) { // player:setHazardSystemPoints(amount) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { pushBoolean(L, false); reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); @@ -3740,7 +3742,7 @@ int PlayerFunctions::luaPlayerAddHazardSystemPoints(lua_State* L) { int PlayerFunctions::luaPlayerGetHazardSystemPoints(lua_State* L) { // player:getHazardSystemPoints() - const auto player = getUserdata(L, 1); + const auto player = getUserdataShared(L, 1); if (!player) { pushBoolean(L, false); reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); @@ -3753,7 +3755,7 @@ int PlayerFunctions::luaPlayerGetHazardSystemPoints(lua_State* L) { int PlayerFunctions::luaPlayerSetLoyaltyBonus(lua_State* L) { // player:setLoyaltyBonus(amount) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3766,7 +3768,7 @@ int PlayerFunctions::luaPlayerSetLoyaltyBonus(lua_State* L) { int PlayerFunctions::luaPlayerGetLoyaltyBonus(lua_State* L) { // player:getLoyaltyBonus() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3778,7 +3780,7 @@ int PlayerFunctions::luaPlayerGetLoyaltyBonus(lua_State* L) { int PlayerFunctions::luaPlayerGetLoyaltyPoints(lua_State* L) { // player:getLoyaltyPoints() - const auto &player = getUserdata(L, 1); + const auto player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3790,7 +3792,7 @@ int PlayerFunctions::luaPlayerGetLoyaltyPoints(lua_State* L) { int PlayerFunctions::luaPlayerGetLoyaltyTitle(lua_State* L) { // player:getLoyaltyTitle() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3802,7 +3804,7 @@ int PlayerFunctions::luaPlayerGetLoyaltyTitle(lua_State* L) { int PlayerFunctions::luaPlayerSetLoyaltyTitle(lua_State* L) { // player:setLoyaltyTitle(name) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3816,7 +3818,7 @@ int PlayerFunctions::luaPlayerSetLoyaltyTitle(lua_State* L) { // Wheel of destiny system int PlayerFunctions::luaPlayerInstantSkillWOD(lua_State* L) { // player:instantSkillWOD(name[, value]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3834,7 +3836,7 @@ int PlayerFunctions::luaPlayerInstantSkillWOD(lua_State* L) { int PlayerFunctions::luaPlayerUpgradeSpellWOD(lua_State* L) { // player:upgradeSpellsWOD([name[, add]]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3864,7 +3866,7 @@ int PlayerFunctions::luaPlayerUpgradeSpellWOD(lua_State* L) { int PlayerFunctions::luaPlayerRevelationStageWOD(lua_State* L) { // player:revelationStagesWOD([name[, set]]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3890,7 +3892,7 @@ int PlayerFunctions::luaPlayerRevelationStageWOD(lua_State* L) { int PlayerFunctions::luaPlayerReloadData(lua_State* L) { // player:reloadData() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3907,7 +3909,7 @@ int PlayerFunctions::luaPlayerReloadData(lua_State* L) { int PlayerFunctions::luaPlayerOnThinkWheelOfDestiny(lua_State* L) { // player:onThinkWheelOfDestiny([force = false]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3920,7 +3922,7 @@ int PlayerFunctions::luaPlayerOnThinkWheelOfDestiny(lua_State* L) { int PlayerFunctions::luaPlayerAvatarTimer(lua_State* L) { // player:avatarTimer([value]) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -3937,7 +3939,7 @@ int PlayerFunctions::luaPlayerAvatarTimer(lua_State* L) { int PlayerFunctions::luaPlayerGetWheelSpellAdditionalArea(lua_State* L) { // player:getWheelSpellAdditionalArea(spellname) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3964,7 +3966,7 @@ int PlayerFunctions::luaPlayerGetWheelSpellAdditionalArea(lua_State* L) { int PlayerFunctions::luaPlayerGetWheelSpellAdditionalTarget(lua_State* L) { // player:getWheelSpellAdditionalTarget(spellname) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -3991,7 +3993,7 @@ int PlayerFunctions::luaPlayerGetWheelSpellAdditionalTarget(lua_State* L) { int PlayerFunctions::luaPlayerGetWheelSpellAdditionalDuration(lua_State* L) { // player:getWheelSpellAdditionalDuration(spellname) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -4018,7 +4020,7 @@ int PlayerFunctions::luaPlayerGetWheelSpellAdditionalDuration(lua_State* L) { int PlayerFunctions::luaPlayerUpdateConcoction(lua_State* L) { // player:updateConcoction(itemid, timeLeft) - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -4030,7 +4032,7 @@ int PlayerFunctions::luaPlayerUpdateConcoction(lua_State* L) { int PlayerFunctions::luaPlayerClearSpellCooldowns(lua_State* L) { // player:clearSpellCooldowns() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { lua_pushnil(L); return 1; @@ -4042,7 +4044,7 @@ int PlayerFunctions::luaPlayerClearSpellCooldowns(lua_State* L) { int PlayerFunctions::luaPlayerIsVip(lua_State* L) { // player:isVip() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -4054,7 +4056,7 @@ int PlayerFunctions::luaPlayerIsVip(lua_State* L) { int PlayerFunctions::luaPlayerGetVipDays(lua_State* L) { // player:getVipDays() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -4067,7 +4069,7 @@ int PlayerFunctions::luaPlayerGetVipDays(lua_State* L) { int PlayerFunctions::luaPlayerGetVipTime(lua_State* L) { // player:getVipTime() - Player* player = getUserdata(L, 1); + std::shared_ptr player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); @@ -4080,7 +4082,7 @@ int PlayerFunctions::luaPlayerGetVipTime(lua_State* L) { int PlayerFunctions::luaPlayerKV(lua_State* L) { // player:kv() - auto player = getUserdata(L, 1); + auto player = getUserdataShared(L, 1); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); diff --git a/src/lua/functions/creatures/player/player_functions.hpp b/src/lua/functions/creatures/player/player_functions.hpp index ff047fb12..14075cb69 100644 --- a/src/lua/functions/creatures/player/player_functions.hpp +++ b/src/lua/functions/creatures/player/player_functions.hpp @@ -19,7 +19,7 @@ class PlayerFunctions final : LuaScriptInterface { private: static void init(lua_State* L) { - registerClass(L, "Player", "Creature", PlayerFunctions::luaPlayerCreate); + registerSharedClass(L, "Player", "Creature", PlayerFunctions::luaPlayerCreate); registerMetaMethod(L, "Player", "__eq", PlayerFunctions::luaUserdataCompare); registerMethod(L, "Player", "resetCharmsBestiary", PlayerFunctions::luaPlayerResetCharmsMonsters); diff --git a/src/lua/functions/events/creature_event_functions.cpp b/src/lua/functions/events/creature_event_functions.cpp index 4ed08aa79..2c5da7661 100644 --- a/src/lua/functions/events/creature_event_functions.cpp +++ b/src/lua/functions/events/creature_event_functions.cpp @@ -24,7 +24,7 @@ int CreatureEventFunctions::luaCreateCreatureEvent(lua_State* L) { int CreatureEventFunctions::luaCreatureEventType(lua_State* L) { // creatureevent:type(callback) - const auto &creatureEvent = getUserdataShared(L, 1); + const auto creatureEvent = getUserdataShared(L, 1); if (creatureEvent) { std::string typeName = getString(L, 2); std::string tmpStr = asLowerCaseString(typeName); diff --git a/src/lua/functions/events/global_event_functions.cpp b/src/lua/functions/events/global_event_functions.cpp index cab8b4f66..955f477bc 100644 --- a/src/lua/functions/events/global_event_functions.cpp +++ b/src/lua/functions/events/global_event_functions.cpp @@ -26,7 +26,7 @@ int GlobalEventFunctions::luaCreateGlobalEvent(lua_State* L) { int GlobalEventFunctions::luaGlobalEventType(lua_State* L) { // globalevent:type(callback) - const auto &global = getUserdataShared(L, 1); + const auto global = getUserdataShared(L, 1); if (global) { std::string typeName = getString(L, 2); std::string tmpStr = asLowerCaseString(typeName); @@ -54,7 +54,7 @@ int GlobalEventFunctions::luaGlobalEventType(lua_State* L) { int GlobalEventFunctions::luaGlobalEventRegister(lua_State* L) { // globalevent:register() - const auto &globalevent = getUserdataShared(L, 1); + const auto globalevent = getUserdataShared(L, 1); if (globalevent) { if (!globalevent->isLoadedCallback()) { pushBoolean(L, false); @@ -74,7 +74,7 @@ int GlobalEventFunctions::luaGlobalEventRegister(lua_State* L) { int GlobalEventFunctions::luaGlobalEventOnCallback(lua_State* L) { // globalevent:onThink / record / etc. (callback) - const auto &globalevent = getUserdataShared(L, 1); + const auto globalevent = getUserdataShared(L, 1); if (globalevent) { if (!globalevent->loadCallback()) { pushBoolean(L, false); @@ -89,7 +89,7 @@ int GlobalEventFunctions::luaGlobalEventOnCallback(lua_State* L) { int GlobalEventFunctions::luaGlobalEventTime(lua_State* L) { // globalevent:time(time) - const auto &globalevent = getUserdataShared(L, 1); + const auto globalevent = getUserdataShared(L, 1); if (globalevent) { std::string timer = getString(L, 2); std::vector params = vectorAtoi(explodeString(timer, ":")); @@ -152,7 +152,7 @@ int GlobalEventFunctions::luaGlobalEventTime(lua_State* L) { int GlobalEventFunctions::luaGlobalEventInterval(lua_State* L) { // globalevent:interval(interval) - const auto &globalevent = getUserdataShared(L, 1); + const auto globalevent = getUserdataShared(L, 1); if (globalevent) { globalevent->setInterval(getNumber(L, 2)); globalevent->setNextExecution(OTSYS_TIME() + getNumber(L, 2)); diff --git a/src/lua/functions/items/container_functions.cpp b/src/lua/functions/items/container_functions.cpp index 9bdc958b3..b3503b662 100644 --- a/src/lua/functions/items/container_functions.cpp +++ b/src/lua/functions/items/container_functions.cpp @@ -17,7 +17,7 @@ int ContainerFunctions::luaContainerCreate(lua_State* L) { // Container(uid) uint32_t id = getNumber(L, 2); - Container* container = getScriptEnv()->getContainerByUID(id); + std::shared_ptr container = getScriptEnv()->getContainerByUID(id); if (container) { pushUserdata(L, container); setMetatable(L, -1, "Container"); @@ -29,7 +29,7 @@ int ContainerFunctions::luaContainerCreate(lua_State* L) { int ContainerFunctions::luaContainerGetSize(lua_State* L) { // container:getSize() - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (container) { lua_pushnumber(L, container->size()); } else { @@ -40,7 +40,7 @@ int ContainerFunctions::luaContainerGetSize(lua_State* L) { int ContainerFunctions::luaContainerGetCapacity(lua_State* L) { // container:getCapacity() - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (container) { lua_pushnumber(L, container->capacity()); } else { @@ -51,7 +51,7 @@ int ContainerFunctions::luaContainerGetCapacity(lua_State* L) { int ContainerFunctions::luaContainerGetEmptySlots(lua_State* L) { // container:getEmptySlots([recursive = false]) - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (!container) { lua_pushnil(L); return 1; @@ -61,7 +61,7 @@ int ContainerFunctions::luaContainerGetEmptySlots(lua_State* L) { bool recursive = getBoolean(L, 2, false); if (recursive) { for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) { - if (Container* tmpContainer = (*it)->getContainer()) { + if (std::shared_ptr tmpContainer = (*it)->getContainer()) { slots += tmpContainer->capacity() - tmpContainer->size(); } } @@ -72,7 +72,7 @@ int ContainerFunctions::luaContainerGetEmptySlots(lua_State* L) { int ContainerFunctions::luaContainerGetItemHoldingCount(lua_State* L) { // container:getItemHoldingCount() - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (container) { lua_pushnumber(L, container->getItemHoldingCount()); } else { @@ -83,14 +83,14 @@ int ContainerFunctions::luaContainerGetItemHoldingCount(lua_State* L) { int ContainerFunctions::luaContainerGetItem(lua_State* L) { // container:getItem(index) - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (!container) { lua_pushnil(L); return 1; } uint32_t index = getNumber(L, 2); - Item* item = container->getItemByIndex(index); + std::shared_ptr item = container->getItemByIndex(index); if (item) { pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -102,8 +102,8 @@ int ContainerFunctions::luaContainerGetItem(lua_State* L) { int ContainerFunctions::luaContainerHasItem(lua_State* L) { // container:hasItem(item) - Item* item = getUserdata(L, 2); - Container* container = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 2); + std::shared_ptr container = getUserdataShared(L, 1); if (container) { pushBoolean(L, container->isHoldingItem(item)); } else { @@ -114,9 +114,10 @@ int ContainerFunctions::luaContainerHasItem(lua_State* L) { int ContainerFunctions::luaContainerAddItem(lua_State* L) { // container:addItem(itemId[, count/subType = 1[, index = INDEX_WHEREEVER[, flags = 0]]]) - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (!container) { lua_pushnil(L); + reportErrorFunc("Container is nullptr"); return 1; } @@ -127,6 +128,7 @@ int ContainerFunctions::luaContainerAddItem(lua_State* L) { itemId = Item::items.getItemIdByName(getString(L, 2)); if (itemId == 0) { lua_pushnil(L); + reportErrorFunc("Item id is wrong"); return 1; } } @@ -137,9 +139,10 @@ int ContainerFunctions::luaContainerAddItem(lua_State* L) { count = std::min(count, it.stackSize); } - Item* item = Item::CreateItem(itemId, count); + std::shared_ptr item = Item::CreateItem(itemId, count); if (!item) { lua_pushnil(L); + reportErrorFunc("Item is nullptr"); return 1; } @@ -151,21 +154,20 @@ int ContainerFunctions::luaContainerAddItem(lua_State* L) { pushUserdata(L, item); setItemMetatable(L, -1, item); } else { - delete item; - lua_pushnil(L); + reportErrorFunc(fmt::format("Cannot add item to container, error code: '{}'", getReturnMessage(ret))); } return 1; } int ContainerFunctions::luaContainerAddItemEx(lua_State* L) { // container:addItemEx(item[, index = INDEX_WHEREEVER[, flags = 0]]) - Item* item = getUserdata(L, 2); + std::shared_ptr item = getUserdataShared(L, 2); if (!item) { lua_pushnil(L); return 1; } - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (!container) { lua_pushnil(L); return 1; @@ -189,7 +191,7 @@ int ContainerFunctions::luaContainerAddItemEx(lua_State* L) { int ContainerFunctions::luaContainerGetCorpseOwner(lua_State* L) { // container:getCorpseOwner() - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (container) { lua_pushnumber(L, container->getCorpseOwner()); } else { @@ -200,7 +202,7 @@ int ContainerFunctions::luaContainerGetCorpseOwner(lua_State* L) { int ContainerFunctions::luaContainerGetItemCountById(lua_State* L) { // container:getItemCountById(itemId[, subType = -1]) - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (!container) { lua_pushnil(L); return 1; @@ -224,7 +226,7 @@ int ContainerFunctions::luaContainerGetItemCountById(lua_State* L) { int ContainerFunctions::luaContainerGetContentDescription(lua_State* L) { // container:getContentDescription([oldProtocol]) - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (container) { pushString(L, container->getContentDescription(getBoolean(L, 2, false))); } else { @@ -235,19 +237,19 @@ int ContainerFunctions::luaContainerGetContentDescription(lua_State* L) { int ContainerFunctions::luaContainerGetItems(lua_State* L) { // container:getItems([recursive = false]) - const Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (!container) { lua_pushnil(L); return 1; } bool recursive = getBoolean(L, 2, false); - std::vector items = container->getItems(recursive); + std::vector> items = container->getItems(recursive); lua_createtable(L, static_cast(items.size()), 0); int index = 0; - for (Item* item : items) { + for (std::shared_ptr item : items) { index++; pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -258,14 +260,14 @@ int ContainerFunctions::luaContainerGetItems(lua_State* L) { int ContainerFunctions::luaContainerRegisterReward(lua_State* L) { // container:registerReward() - Container* container = getUserdata(L, 1); + std::shared_ptr container = getUserdataShared(L, 1); if (!container) { lua_pushnil(L); return 1; } int64_t rewardId = getTimeMsNow(); - Item* rewardContainer = Item::CreateItem(ITEM_REWARD_CONTAINER); + std::shared_ptr rewardContainer = Item::CreateItem(ITEM_REWARD_CONTAINER); rewardContainer->setAttribute(ItemAttribute_t::DATE, rewardId); container->setAttribute(ItemAttribute_t::DATE, rewardId); container->internalAddThing(rewardContainer); diff --git a/src/lua/functions/items/container_functions.hpp b/src/lua/functions/items/container_functions.hpp index a716f31c1..ce1823267 100644 --- a/src/lua/functions/items/container_functions.hpp +++ b/src/lua/functions/items/container_functions.hpp @@ -15,7 +15,7 @@ class ContainerFunctions final : LuaScriptInterface { public: private: static void init(lua_State* L) { - registerClass(L, "Container", "Item", ContainerFunctions::luaContainerCreate); + registerSharedClass(L, "Container", "Item", ContainerFunctions::luaContainerCreate); registerMetaMethod(L, "Container", "__eq", ContainerFunctions::luaUserdataCompare); registerMethod(L, "Container", "getSize", ContainerFunctions::luaContainerGetSize); diff --git a/src/lua/functions/items/imbuement_functions.cpp b/src/lua/functions/items/imbuement_functions.cpp index dcb89ca86..f512e56a6 100644 --- a/src/lua/functions/items/imbuement_functions.cpp +++ b/src/lua/functions/items/imbuement_functions.cpp @@ -58,7 +58,7 @@ int ImbuementFunctions::luaImbuementGetItems(lua_State* L) { return 1; } - const auto &items = imbuement->getItems(); + const auto items = imbuement->getItems(); lua_createtable(L, items.size(), 0); for (const auto &itm : items) { diff --git a/src/lua/functions/items/item_functions.cpp b/src/lua/functions/items/item_functions.cpp index 5b3802377..f943c52c8 100644 --- a/src/lua/functions/items/item_functions.cpp +++ b/src/lua/functions/items/item_functions.cpp @@ -22,7 +22,7 @@ int ItemFunctions::luaItemCreate(lua_State* L) { // Item(uid) uint32_t id = getNumber(L, 2); - Item* item = getScriptEnv()->getItemByUID(id); + std::shared_ptr item = getScriptEnv()->getItemByUID(id); if (item) { pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -34,19 +34,19 @@ int ItemFunctions::luaItemCreate(lua_State* L) { int ItemFunctions::luaItemIsItem(lua_State* L) { // item:isItem() - pushBoolean(L, getUserdata(L, 1) != nullptr); + pushBoolean(L, getUserdataShared(L, 1) != nullptr); return 1; } int ItemFunctions::luaItemGetParent(lua_State* L) { // item:getParent() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; } - Cylinder* parent = item->getParent(); + std::shared_ptr parent = item->getParent(); if (!parent) { lua_pushnil(L); return 1; @@ -58,13 +58,13 @@ int ItemFunctions::luaItemGetParent(lua_State* L) { int ItemFunctions::luaItemGetTopParent(lua_State* L) { // item:getTopParent() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; } - Cylinder* topParent = item->getTopParent(); + std::shared_ptr topParent = item->getTopParent(); if (!topParent) { lua_pushnil(L); return 1; @@ -76,7 +76,7 @@ int ItemFunctions::luaItemGetTopParent(lua_State* L) { int ItemFunctions::luaItemGetId(lua_State* L) { // item:getId() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { lua_pushnumber(L, item->getID()); } else { @@ -87,13 +87,13 @@ int ItemFunctions::luaItemGetId(lua_State* L) { int ItemFunctions::luaItemClone(lua_State* L) { // item:clone() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; } - Item* clone = item->clone(); + std::shared_ptr clone = item->clone(); if (!clone) { lua_pushnil(L); return 1; @@ -109,13 +109,13 @@ int ItemFunctions::luaItemClone(lua_State* L) { int ItemFunctions::luaItemSplit(lua_State* L) { // item:split([count = 1]) - Item** itemPtr = getRawUserdata(L, 1); + std::shared_ptr* itemPtr = getRawUserDataShared(L, 1); if (!itemPtr) { lua_pushnil(L); return 1; } - Item* item = *itemPtr; + std::shared_ptr item = *itemPtr; if (!item || !item->isStackable() || item->isRemoved()) { lua_pushnil(L); return 1; @@ -124,7 +124,7 @@ int ItemFunctions::luaItemSplit(lua_State* L) { uint16_t count = std::min(getNumber(L, 2, 1), item->getItemCount()); uint16_t diff = item->getItemCount() - count; - Item* splitItem = item->clone(); + std::shared_ptr splitItem = item->clone(); if (!splitItem) { lua_pushnil(L); return 1; @@ -135,7 +135,7 @@ int ItemFunctions::luaItemSplit(lua_State* L) { ScriptEnvironment* env = getScriptEnv(); uint32_t uid = env->addThing(item); - Item* newItem = g_game().transformItem(item, item->getID(), diff); + std::shared_ptr newItem = g_game().transformItem(item, item->getID(), diff); if (item->isRemoved()) { env->removeItemByUID(uid); } @@ -156,7 +156,7 @@ int ItemFunctions::luaItemSplit(lua_State* L) { int ItemFunctions::luaItemRemove(lua_State* L) { // item:remove([count = -1]) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { int32_t count = getNumber(L, 2, -1); pushBoolean(L, g_game().internalRemoveItem(item, count) == RETURNVALUE_NOERROR); @@ -168,7 +168,7 @@ int ItemFunctions::luaItemRemove(lua_State* L) { int ItemFunctions::luaItemGetUniqueId(lua_State* L) { // item:getUniqueId() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { uint32_t uniqueId = item->getAttribute(ItemAttribute_t::UNIQUEID); if (uniqueId == 0) { @@ -183,7 +183,7 @@ int ItemFunctions::luaItemGetUniqueId(lua_State* L) { int ItemFunctions::luaItemGetActionId(lua_State* L) { // item:getActionId() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { auto actionId = item->getAttribute(ItemAttribute_t::ACTIONID); lua_pushnumber(L, actionId); @@ -196,7 +196,7 @@ int ItemFunctions::luaItemGetActionId(lua_State* L) { int ItemFunctions::luaItemSetActionId(lua_State* L) { // item:setActionId(actionId) uint16_t actionId = getNumber(L, 2); - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { item->setAttribute(ItemAttribute_t::ACTIONID, actionId); pushBoolean(L, true); @@ -208,7 +208,7 @@ int ItemFunctions::luaItemSetActionId(lua_State* L) { int ItemFunctions::luaItemGetCount(lua_State* L) { // item:getCount() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { lua_pushnumber(L, item->getItemCount()); } else { @@ -219,7 +219,7 @@ int ItemFunctions::luaItemGetCount(lua_State* L) { int ItemFunctions::luaItemGetCharges(lua_State* L) { // item:getCharges() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { lua_pushnumber(L, item->getCharges()); } else { @@ -230,7 +230,7 @@ int ItemFunctions::luaItemGetCharges(lua_State* L) { int ItemFunctions::luaItemGetFluidType(lua_State* L) { // item:getFluidType() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { lua_pushnumber(L, static_cast(item->getAttribute(ItemAttribute_t::FLUIDTYPE))); } else { @@ -241,7 +241,7 @@ int ItemFunctions::luaItemGetFluidType(lua_State* L) { int ItemFunctions::luaItemGetWeight(lua_State* L) { // item:getWeight() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { lua_pushnumber(L, item->getWeight()); } else { @@ -252,7 +252,7 @@ int ItemFunctions::luaItemGetWeight(lua_State* L) { int ItemFunctions::luaItemGetSubType(lua_State* L) { // item:getSubType() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { lua_pushnumber(L, item->getSubType()); } else { @@ -263,7 +263,7 @@ int ItemFunctions::luaItemGetSubType(lua_State* L) { int ItemFunctions::luaItemGetName(lua_State* L) { // item:getName() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { pushString(L, item->getName()); } else { @@ -274,7 +274,7 @@ int ItemFunctions::luaItemGetName(lua_State* L) { int ItemFunctions::luaItemGetPluralName(lua_State* L) { // item:getPluralName() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { pushString(L, item->getPluralName()); } else { @@ -285,7 +285,7 @@ int ItemFunctions::luaItemGetPluralName(lua_State* L) { int ItemFunctions::luaItemGetArticle(lua_State* L) { // item:getArticle() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { pushString(L, item->getArticle()); } else { @@ -296,7 +296,7 @@ int ItemFunctions::luaItemGetArticle(lua_State* L) { int ItemFunctions::luaItemGetPosition(lua_State* L) { // item:getPosition() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { pushPosition(L, item->getPosition()); } else { @@ -307,13 +307,13 @@ int ItemFunctions::luaItemGetPosition(lua_State* L) { int ItemFunctions::luaItemGetTile(lua_State* L) { // item:getTile() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; } - Tile* tile = item->getTile(); + std::shared_ptr tile = item->getTile(); if (tile) { pushUserdata(L, tile); setMetatable(L, -1, "Tile"); @@ -325,7 +325,7 @@ int ItemFunctions::luaItemGetTile(lua_State* L) { int ItemFunctions::luaItemHasAttribute(lua_State* L) { // item:hasAttribute(key) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; @@ -346,7 +346,7 @@ int ItemFunctions::luaItemHasAttribute(lua_State* L) { int ItemFunctions::luaItemGetAttribute(lua_State* L) { // item:getAttribute(key) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; @@ -378,7 +378,7 @@ int ItemFunctions::luaItemGetAttribute(lua_State* L) { int ItemFunctions::luaItemSetAttribute(lua_State* L) { // item:setAttribute(key, value) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; @@ -437,7 +437,7 @@ int ItemFunctions::luaItemSetAttribute(lua_State* L) { int ItemFunctions::luaItemRemoveAttribute(lua_State* L) { // item:removeAttribute(key) - const Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; @@ -456,11 +456,7 @@ int ItemFunctions::luaItemRemoveAttribute(lua_State* L) { if (ret) { ret = (attribute != ItemAttribute_t::DURATION_TIMESTAMP); if (ret) { - // We will convert the item to non-const in order to use it to set values - auto noConstItem = std::bit_cast(item); - if (noConstItem) { - noConstItem->removeAttribute(attribute); - } + item->removeAttribute(attribute); } else { reportErrorFunc("Attempt to erase protected key \"duration timestamp\""); } @@ -473,7 +469,7 @@ int ItemFunctions::luaItemRemoveAttribute(lua_State* L) { int ItemFunctions::luaItemGetCustomAttribute(lua_State* L) { // item:getCustomAttribute(key) - const Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; @@ -499,7 +495,7 @@ int ItemFunctions::luaItemGetCustomAttribute(lua_State* L) { int ItemFunctions::luaItemSetCustomAttribute(lua_State* L) { // item:setCustomAttribute(key, value) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; @@ -540,7 +536,7 @@ int ItemFunctions::luaItemSetCustomAttribute(lua_State* L) { int ItemFunctions::luaItemRemoveCustomAttribute(lua_State* L) { // item:removeCustomAttribute(key) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; @@ -558,7 +554,7 @@ int ItemFunctions::luaItemRemoveCustomAttribute(lua_State* L) { int ItemFunctions::luaItemSerializeAttributes(lua_State* L) { // item:serializeAttributes() - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { lua_pushnil(L); return 1; @@ -575,30 +571,30 @@ int ItemFunctions::luaItemSerializeAttributes(lua_State* L) { int ItemFunctions::luaItemMoveTo(lua_State* L) { // item:moveTo(position or cylinder[, flags]) - Item** itemPtr = getRawUserdata(L, 1); + std::shared_ptr* itemPtr = getRawUserDataShared(L, 1); if (!itemPtr) { lua_pushnil(L); return 1; } - Item* item = *itemPtr; + std::shared_ptr item = *itemPtr; if (!item || item->isRemoved()) { lua_pushnil(L); return 1; } - Cylinder* toCylinder; + std::shared_ptr toCylinder; if (isUserdata(L, 2)) { const LuaData_t type = getUserdataType(L, 2); switch (type) { case LuaData_t::Container: - toCylinder = getUserdata(L, 2); + toCylinder = getUserdataShared(L, 2); break; case LuaData_t::Player: - toCylinder = getUserdata(L, 2); + toCylinder = getUserdataShared(L, 2); break; case LuaData_t::Tile: - toCylinder = getUserdata(L, 2); + toCylinder = getUserdataShared(L, 2); break; default: toCylinder = nullptr; @@ -623,7 +619,7 @@ int ItemFunctions::luaItemMoveTo(lua_State* L) { if (item->getParent() == VirtualCylinder::virtualCylinder) { pushBoolean(L, g_game().internalAddItem(toCylinder, item, INDEX_WHEREEVER, flags) == RETURNVALUE_NOERROR); } else { - Item* moveItem = nullptr; + std::shared_ptr moveItem = nullptr; ReturnValue ret = g_game().internalMoveItem(item->getParent(), toCylinder, INDEX_WHEREEVER, item, item->getItemCount(), &moveItem, flags); if (moveItem) { *itemPtr = moveItem; @@ -635,13 +631,13 @@ int ItemFunctions::luaItemMoveTo(lua_State* L) { int ItemFunctions::luaItemTransform(lua_State* L) { // item:transform(itemId[, count/subType = -1]) - Item** itemPtr = getRawUserdata(L, 1); + std::shared_ptr* itemPtr = getRawUserDataShared(L, 1); if (!itemPtr) { lua_pushnil(L); return 1; } - Item*&item = *itemPtr; + std::shared_ptr &item = *itemPtr; if (!item) { lua_pushnil(L); return 1; @@ -672,7 +668,7 @@ int ItemFunctions::luaItemTransform(lua_State* L) { ScriptEnvironment* env = getScriptEnv(); uint32_t uid = env->addThing(item); - Item* newItem = g_game().transformItem(item, itemId, subType); + std::shared_ptr newItem = g_game().transformItem(item, itemId, subType); if (item->isRemoved()) { env->removeItemByUID(uid); } @@ -688,7 +684,7 @@ int ItemFunctions::luaItemTransform(lua_State* L) { int ItemFunctions::luaItemDecay(lua_State* L) { // item:decay(decayId) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { if (isNumber(L, 2)) { ItemType &it = Item::items.getItemType(item->getID()); @@ -705,13 +701,13 @@ int ItemFunctions::luaItemDecay(lua_State* L) { int ItemFunctions::luaItemMoveToSlot(lua_State* L) { // item:moveToSlot(player, slot) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item || item->isRemoved()) { lua_pushnil(L); return 1; } - Player* player = getUserdata(L, 2); + std::shared_ptr player = getUserdataShared(L, 2); if (!player) { lua_pushnil(L); return 1; @@ -719,7 +715,7 @@ int ItemFunctions::luaItemMoveToSlot(lua_State* L) { Slots_t slot = getNumber(L, 3, CONST_SLOT_WHEREEVER); - Item* moveItem = nullptr; + std::shared_ptr moveItem = nullptr; ReturnValue ret = g_game().internalMoveItem(item->getParent(), player, slot, item, item->getItemCount(), nullptr); if (moveItem) { item = moveItem; @@ -731,7 +727,7 @@ int ItemFunctions::luaItemMoveToSlot(lua_State* L) { int ItemFunctions::luaItemGetDescription(lua_State* L) { // item:getDescription(distance) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { int32_t distance = getNumber(L, 2); pushString(L, item->getDescription(distance)); @@ -743,7 +739,7 @@ int ItemFunctions::luaItemGetDescription(lua_State* L) { int ItemFunctions::luaItemHasProperty(lua_State* L) { // item:hasProperty(property) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (item) { ItemProperty property = getNumber(L, 2); pushBoolean(L, item->hasProperty(property)); @@ -755,7 +751,7 @@ int ItemFunctions::luaItemHasProperty(lua_State* L) { int ItemFunctions::luaItemGetImbuement(lua_State* L) { // item:getImbuement() - const Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -786,7 +782,7 @@ int ItemFunctions::luaItemGetImbuement(lua_State* L) { int ItemFunctions::luaItemGetImbuementSlot(lua_State* L) { // item:getImbuementSlot() - const Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -800,7 +796,7 @@ int ItemFunctions::luaItemGetImbuementSlot(lua_State* L) { int ItemFunctions::luaItemSetDuration(lua_State* L) { // item:setDuration(minDuration, maxDuration = 0, decayTo = 0, showDuration = true) // Example: item:setDuration(10000, 20000, 2129, false) = random duration from range 10000/20000 - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -837,7 +833,7 @@ int ItemFunctions::luaItemSetDuration(lua_State* L) { int ItemFunctions::luaItemIsInsideDepot(lua_State* L) { // item:isInsideDepot([includeInbox = false]) - const Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -848,9 +844,23 @@ int ItemFunctions::luaItemIsInsideDepot(lua_State* L) { return 1; } +int ItemFunctions::luaItemIsContainer(lua_State* L) { + // item:isContainer() + const auto item = getUserdataShared(L, 1); + if (!item) { + reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); + pushBoolean(L, false); + return 1; + } + + const auto &it = Item::items[item->getID()]; + pushBoolean(L, it.isContainer()); + return 1; +} + int ItemFunctions::luaItemGetTier(lua_State* L) { // item:getTier() - const Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -863,7 +873,7 @@ int ItemFunctions::luaItemGetTier(lua_State* L) { int ItemFunctions::luaItemSetTier(lua_State* L) { // item:setTier(tier) - Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -877,7 +887,7 @@ int ItemFunctions::luaItemSetTier(lua_State* L) { int ItemFunctions::luaItemGetClassification(lua_State* L) { // item:getClassification() - const Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); @@ -890,7 +900,7 @@ int ItemFunctions::luaItemGetClassification(lua_State* L) { int ItemFunctions::luaItemCanReceiveAutoCarpet(lua_State* L) { // item:canReceiveAutoCarpet() - const Item* item = getUserdata(L, 1); + std::shared_ptr item = getUserdataShared(L, 1); if (!item) { reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); pushBoolean(L, false); diff --git a/src/lua/functions/items/item_functions.hpp b/src/lua/functions/items/item_functions.hpp index e890f2df1..b5b3b62eb 100644 --- a/src/lua/functions/items/item_functions.hpp +++ b/src/lua/functions/items/item_functions.hpp @@ -18,7 +18,7 @@ class ItemFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Item", "", ItemFunctions::luaItemCreate); + registerSharedClass(L, "Item", "", ItemFunctions::luaItemCreate); registerMetaMethod(L, "Item", "__eq", ItemFunctions::luaUserdataCompare); registerMethod(L, "Item", "isItem", ItemFunctions::luaItemIsItem); @@ -75,6 +75,7 @@ class ItemFunctions final : LuaScriptInterface { registerMethod(L, "Item", "setDuration", ItemFunctions::luaItemSetDuration); registerMethod(L, "Item", "isInsideDepot", ItemFunctions::luaItemIsInsideDepot); + registerMethod(L, "Item", "isContainer", ItemFunctions::luaItemIsContainer); registerMethod(L, "Item", "getTier", ItemFunctions::luaItemGetTier); registerMethod(L, "Item", "setTier", ItemFunctions::luaItemSetTier); @@ -145,6 +146,7 @@ class ItemFunctions final : LuaScriptInterface { static int luaItemSetDuration(lua_State* L); static int luaItemIsInsideDepot(lua_State* L); + static int luaItemIsContainer(lua_State* L); static int luaItemGetTier(lua_State* L); static int luaItemSetTier(lua_State* L); diff --git a/src/lua/functions/lua_functions_loader.cpp b/src/lua/functions/lua_functions_loader.cpp index 2f1d526bc..944849b1e 100644 --- a/src/lua/functions/lua_functions_loader.cpp +++ b/src/lua/functions/lua_functions_loader.cpp @@ -145,7 +145,7 @@ void LuaFunctionsLoader::pushVariant(lua_State* L, const LuaVariant &var) { setMetatable(L, -1, "Variant"); } -void LuaFunctionsLoader::pushThing(lua_State* L, Thing* thing) { +void LuaFunctionsLoader::pushThing(lua_State* L, std::shared_ptr thing) { if (!thing) { lua_createtable(L, 0, 4); setField(L, "uid", 0); @@ -155,10 +155,10 @@ void LuaFunctionsLoader::pushThing(lua_State* L, Thing* thing) { return; } - if (Item* item = thing->getItem()) { + if (std::shared_ptr item = thing->getItem()) { pushUserdata(L, item); setItemMetatable(L, -1, item); - } else if (Creature* creature = thing->getCreature()) { + } else if (std::shared_ptr creature = thing->getCreature()) { pushUserdata(L, creature); setCreatureMetatable(L, -1, creature); } else { @@ -166,14 +166,14 @@ void LuaFunctionsLoader::pushThing(lua_State* L, Thing* thing) { } } -void LuaFunctionsLoader::pushCylinder(lua_State* L, Cylinder* cylinder) { - if (Creature* creature = cylinder->getCreature()) { +void LuaFunctionsLoader::pushCylinder(lua_State* L, std::shared_ptr cylinder) { + if (std::shared_ptr creature = cylinder->getCreature()) { pushUserdata(L, creature); setCreatureMetatable(L, -1, creature); - } else if (Item* parentItem = cylinder->getItem()) { + } else if (std::shared_ptr parentItem = cylinder->getItem()) { pushUserdata(L, parentItem); setItemMetatable(L, -1, parentItem); - } else if (Tile* tile = cylinder->getTile()) { + } else if (std::shared_ptr tile = cylinder->getTile()) { pushUserdata(L, tile); setMetatable(L, -1, "Tile"); } else if (cylinder == VirtualCylinder::virtualCylinder) { @@ -245,7 +245,7 @@ void LuaFunctionsLoader::setWeakMetatable(lua_State* L, int32_t index, const std lua_setmetatable(L, index - 1); } -void LuaFunctionsLoader::setItemMetatable(lua_State* L, int32_t index, const Item* item) { +void LuaFunctionsLoader::setItemMetatable(lua_State* L, int32_t index, std::shared_ptr item) { if (item && item->getContainer()) { luaL_getmetatable(L, "Container"); } else if (item && item->getTeleport()) { @@ -256,7 +256,7 @@ void LuaFunctionsLoader::setItemMetatable(lua_State* L, int32_t index, const Ite lua_setmetatable(L, index - 1); } -void LuaFunctionsLoader::setCreatureMetatable(lua_State* L, int32_t index, const Creature* creature) { +void LuaFunctionsLoader::setCreatureMetatable(lua_State* L, int32_t index, std::shared_ptr creature) { if (creature && creature->getPlayer()) { luaL_getmetatable(L, "Player"); } else if (creature && creature->getMonster()) { @@ -406,28 +406,28 @@ LuaVariant LuaFunctionsLoader::getVariant(lua_State* L, int32_t arg) { return var; } -Thing* LuaFunctionsLoader::getThing(lua_State* L, int32_t arg) { - Thing* thing; +std::shared_ptr LuaFunctionsLoader::getThing(lua_State* L, int32_t arg) { + std::shared_ptr thing; if (lua_getmetatable(L, arg) != 0) { lua_rawgeti(L, -1, 't'); switch (getNumber(L, -1)) { case LuaData_t::Item: - thing = getUserdata(L, arg); + thing = getUserdataShared(L, arg); break; case LuaData_t::Container: - thing = getUserdata(L, arg); + thing = getUserdataShared(L, arg); break; case LuaData_t::Teleport: - thing = getUserdata(L, arg); + thing = getUserdataShared(L, arg); break; case LuaData_t::Player: - thing = getUserdata(L, arg); + thing = getUserdataShared(L, arg); break; case LuaData_t::Monster: - thing = getUserdata(L, arg); + thing = getUserdataShared(L, arg); break; case LuaData_t::Npc: - thing = getUserdata(L, arg); + thing = getUserdataShared(L, arg); break; default: thing = nullptr; @@ -440,16 +440,16 @@ Thing* LuaFunctionsLoader::getThing(lua_State* L, int32_t arg) { return thing; } -Creature* LuaFunctionsLoader::getCreature(lua_State* L, int32_t arg) { +std::shared_ptr LuaFunctionsLoader::getCreature(lua_State* L, int32_t arg) { if (isUserdata(L, arg)) { - return getUserdata(L, arg); + return getUserdataShared(L, arg); } return g_game().getCreatureByID(getNumber(L, arg)); } -Player* LuaFunctionsLoader::getPlayer(lua_State* L, int32_t arg, bool allowOffline /* = false */) { +std::shared_ptr LuaFunctionsLoader::getPlayer(lua_State* L, int32_t arg, bool allowOffline /* = false */) { if (isUserdata(L, arg)) { - return getUserdata(L, arg); + return getUserdataShared(L, arg); } else if (isNumber(L, arg)) { return g_game().getPlayerByID(getNumber(L, arg), allowOffline); } else if (isString(L, arg)) { diff --git a/src/lua/functions/lua_functions_loader.hpp b/src/lua/functions/lua_functions_loader.hpp index 3eca065cd..3ae8e3ec1 100644 --- a/src/lua/functions/lua_functions_loader.hpp +++ b/src/lua/functions/lua_functions_loader.hpp @@ -37,11 +37,11 @@ class LuaFunctionsLoader { static void reportError(const char* function, const std::string &error_desc, bool stack_trace = false); static int luaErrorHandler(lua_State* L); - static void pushThing(lua_State* L, Thing* thing); + static void pushThing(lua_State* L, std::shared_ptr thing); static void pushVariant(lua_State* L, const LuaVariant &var); static void pushString(lua_State* L, const std::string &value); static void pushCallback(lua_State* L, int32_t callback); - static void pushCylinder(lua_State* L, Cylinder* cylinder); + static void pushCylinder(lua_State* L, std::shared_ptr cylinder); static std::string popString(lua_State* L); static int32_t popCallback(lua_State* L); @@ -54,8 +54,8 @@ class LuaFunctionsLoader { static void setMetatable(lua_State* L, int32_t index, const std::string &name); static void setWeakMetatable(lua_State* L, int32_t index, const std::string &name); - static void setItemMetatable(lua_State* L, int32_t index, const Item* item); - static void setCreatureMetatable(lua_State* L, int32_t index, const Creature* creature); + static void setItemMetatable(lua_State* L, int32_t index, std::shared_ptr item); + static void setCreatureMetatable(lua_State* L, int32_t index, std::shared_ptr creature); template static typename std::enable_if::value, T>::type @@ -107,9 +107,9 @@ class LuaFunctionsLoader { static Outfit_t getOutfit(lua_State* L, int32_t arg); static LuaVariant getVariant(lua_State* L, int32_t arg); - static Thing* getThing(lua_State* L, int32_t arg); - static Creature* getCreature(lua_State* L, int32_t arg); - static Player* getPlayer(lua_State* L, int32_t arg, bool allowOffline = false); + static std::shared_ptr getThing(lua_State* L, int32_t arg); + static std::shared_ptr getCreature(lua_State* L, int32_t arg); + static std::shared_ptr getPlayer(lua_State* L, int32_t arg, bool allowOffline = false); static std::shared_ptr getGuild(lua_State* L, int32_t arg, bool allowOffline = false); template @@ -215,10 +215,8 @@ class LuaFunctionsLoader { static void registerGlobalString(lua_State* L, const std::string &variable, const std::string &name); static int luaUserdataCompare(lua_State* L); + static int luaGarbageCollection(lua_State* L); static ScriptEnvironment scriptEnv[16]; static int32_t scriptEnvIndex; - -private: - static int luaGarbageCollection(lua_State* L); }; diff --git a/src/lua/functions/map/house_functions.cpp b/src/lua/functions/map/house_functions.cpp index 72129001c..b012a367d 100644 --- a/src/lua/functions/map/house_functions.cpp +++ b/src/lua/functions/map/house_functions.cpp @@ -18,8 +18,7 @@ int HouseFunctions::luaHouseCreate(lua_State* L) { // House(id) - House* house = g_game().map.houses.getHouse(getNumber(L, 2)); - if (house) { + if (const auto &house = g_game().map.houses.getHouse(getNumber(L, 2))) { pushUserdata(L, house); setMetatable(L, -1, "House"); } else { @@ -30,8 +29,7 @@ int HouseFunctions::luaHouseCreate(lua_State* L) { int HouseFunctions::luaHouseGetId(lua_State* L) { // house:getId() - House* house = getUserdata(L, 1); - if (house) { + if (const auto &house = getUserdataShared(L, 1)) { lua_pushnumber(L, house->getId()); } else { lua_pushnil(L); @@ -41,8 +39,7 @@ int HouseFunctions::luaHouseGetId(lua_State* L) { int HouseFunctions::luaHouseGetName(lua_State* L) { // house:getName() - House* house = getUserdata(L, 1); - if (house) { + if (const auto &house = getUserdataShared(L, 1)) { pushString(L, house->getName()); } else { lua_pushnil(L); @@ -52,14 +49,13 @@ int HouseFunctions::luaHouseGetName(lua_State* L) { int HouseFunctions::luaHouseGetTown(lua_State* L) { // house:getTown() - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; } - Town* town = g_game().map.towns.getTown(house->getTownId()); - if (town) { + if (const auto &town = g_game().map.towns.getTown(house->getTownId())) { pushUserdata(L, town); setMetatable(L, -1, "Town"); } else { @@ -70,8 +66,7 @@ int HouseFunctions::luaHouseGetTown(lua_State* L) { int HouseFunctions::luaHouseGetExitPosition(lua_State* L) { // house:getExitPosition() - House* house = getUserdata(L, 1); - if (house) { + if (const auto &house = getUserdataShared(L, 1)) { pushPosition(L, house->getEntryPosition()); } else { lua_pushnil(L); @@ -81,8 +76,7 @@ int HouseFunctions::luaHouseGetExitPosition(lua_State* L) { int HouseFunctions::luaHouseGetRent(lua_State* L) { // house:getRent() - House* house = getUserdata(L, 1); - if (house) { + if (const auto &house = getUserdataShared(L, 1)) { lua_pushnumber(L, house->getRent()); } else { lua_pushnil(L); @@ -92,7 +86,7 @@ int HouseFunctions::luaHouseGetRent(lua_State* L) { int HouseFunctions::luaHouseGetPrice(lua_State* L) { // house:getPrice() - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { reportErrorFunc("House not found"); lua_pushnumber(L, 0); @@ -105,8 +99,7 @@ int HouseFunctions::luaHouseGetPrice(lua_State* L) { int HouseFunctions::luaHouseGetOwnerGuid(lua_State* L) { // house:getOwnerGuid() - const House* house = getUserdata(L, 1); - if (house) { + if (const auto &house = getUserdataShared(L, 1)) { lua_pushnumber(L, house->getOwner()); } else { lua_pushnil(L); @@ -114,13 +107,38 @@ int HouseFunctions::luaHouseGetOwnerGuid(lua_State* L) { return 1; } -int HouseFunctions::luaHouseSetOwnerGuid(lua_State* L) { - // house:setOwnerGuid(guid[, updateDatabase = true]) - House* house = getUserdata(L, 1); +int HouseFunctions::luaHouseSetHouseOwner(lua_State* L) { + // house:setHouseOwner(guid[, updateDatabase = true]) + const auto &house = getUserdataShared(L, 1); + if (!house) { + reportErrorFunc("House not found"); + lua_pushnil(L); + return 1; + } + + uint32_t guid = getNumber(L, 2); + bool updateDatabase = getBoolean(L, 3, true); + house->setOwner(guid, updateDatabase); + pushBoolean(L, true); + return 1; +} + +int HouseFunctions::luaHouseSetNewOwnerGuid(lua_State* L) { + // house:setNewOwnerGuid(guid[, updateDatabase = true]) + auto house = getUserdataShared(L, 1); if (house) { - uint32_t guid = getNumber(L, 2); - bool updateDatabase = getBoolean(L, 3, true); - house->setOwner(guid, updateDatabase); + auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART); + if (isTransferOnRestart && house->hasNewOwnership()) { + const auto player = g_game().getPlayerByGUID(house->getOwner()); + if (player) { + player->sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot leave this house. Ownership is already scheduled to be transferred upon the next server restart."); + } + lua_pushnil(L); + return 1; + } + + uint32_t guid = getNumber(L, 2, 0); + house->setNewOwnerGuid(guid, false); pushBoolean(L, true); } else { lua_pushnil(L); @@ -128,11 +146,38 @@ int HouseFunctions::luaHouseSetOwnerGuid(lua_State* L) { return 1; } +int HouseFunctions::luaHouseHasItemOnTile(lua_State* L) { + // house:hasItemOnTile() + auto house = getUserdataShared(L, 1); + if (!house) { + reportErrorFunc("House not found"); + lua_pushnil(L); + return 1; + } + + pushBoolean(L, house->hasItemOnTile()); + return 1; +} + +int HouseFunctions::luaHouseHasNewOwnership(lua_State* L) { + // house:hasNewOwnership(guid) + auto house = getUserdataShared(L, 1); + if (!house) { + reportErrorFunc("House not found"); + lua_pushnil(L); + return 1; + } + + auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART); + pushBoolean(L, isTransferOnRestart && house->hasNewOwnership()); + return 1; +} + int HouseFunctions::luaHouseStartTrade(lua_State* L) { // house:startTrade(player, tradePartner) - House* house = getUserdata(L, 1); - Player* player = getUserdata(L, 2); - Player* tradePartner = getUserdata(L, 3); + const auto &house = getUserdataShared(L, 1); + std::shared_ptr player = getUserdataShared(L, 2); + std::shared_ptr tradePartner = getUserdataShared(L, 3); if (!player || !tradePartner || !house) { lua_pushnil(L); @@ -159,12 +204,20 @@ int HouseFunctions::luaHouseStartTrade(lua_State* L) { return 1; } - Item* transferItem = house->getTransferItem(); + std::shared_ptr transferItem = house->getTransferItem(); if (!transferItem) { lua_pushnumber(L, RETURNVALUE_YOUCANNOTTRADETHISHOUSE); return 1; } + auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART); + if (isTransferOnRestart && house->hasNewOwnership()) { + tradePartner->sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot buy this house. Ownership is already scheduled to be transferred upon the next server restart."); + player->sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot sell this house. Ownership is already scheduled to be transferred upon the next server restart."); + lua_pushnumber(L, RETURNVALUE_YOUCANNOTTRADETHISHOUSE); + return 1; + } + transferItem->getParent()->setParent(player); if (!g_game().internalStartTrade(player, tradePartner, transferItem)) { house->resetTransferItem(); @@ -176,17 +229,17 @@ int HouseFunctions::luaHouseStartTrade(lua_State* L) { int HouseFunctions::luaHouseGetBeds(lua_State* L) { // house:getBeds() - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; } - const auto &beds = house->getBeds(); + const auto beds = house->getBeds(); lua_createtable(L, beds.size(), 0); int index = 0; - for (BedItem* bedItem : beds) { + for (std::shared_ptr bedItem : beds) { pushUserdata(L, bedItem); setItemMetatable(L, -1, bedItem); lua_rawseti(L, -2, ++index); @@ -196,8 +249,7 @@ int HouseFunctions::luaHouseGetBeds(lua_State* L) { int HouseFunctions::luaHouseGetBedCount(lua_State* L) { // house:getBedCount() - House* house = getUserdata(L, 1); - if (house) { + if (const auto &house = getUserdataShared(L, 1)) { lua_pushnumber(L, house->getBedCount()); } else { lua_pushnil(L); @@ -207,17 +259,17 @@ int HouseFunctions::luaHouseGetBedCount(lua_State* L) { int HouseFunctions::luaHouseGetDoors(lua_State* L) { // house:getDoors() - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; } - const auto &doors = house->getDoors(); + const auto doors = house->getDoors(); lua_createtable(L, doors.size(), 0); int index = 0; - for (Door* door : doors) { + for (std::shared_ptr door : doors) { pushUserdata(L, door); setItemMetatable(L, -1, door); lua_rawseti(L, -2, ++index); @@ -227,8 +279,7 @@ int HouseFunctions::luaHouseGetDoors(lua_State* L) { int HouseFunctions::luaHouseGetDoorCount(lua_State* L) { // house:getDoorCount() - House* house = getUserdata(L, 1); - if (house) { + if (const auto &house = getUserdataShared(L, 1)) { lua_pushnumber(L, house->getDoors().size()); } else { lua_pushnil(L); @@ -238,13 +289,13 @@ int HouseFunctions::luaHouseGetDoorCount(lua_State* L) { int HouseFunctions::luaHouseGetDoorIdByPosition(lua_State* L) { // house:getDoorIdByPosition(position) - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; } - Door* door = house->getDoorByPosition(getPosition(L, 2)); + std::shared_ptr door = house->getDoorByPosition(getPosition(L, 2)); if (door) { lua_pushnumber(L, door->getDoorId()); } else { @@ -255,17 +306,17 @@ int HouseFunctions::luaHouseGetDoorIdByPosition(lua_State* L) { int HouseFunctions::luaHouseGetTiles(lua_State* L) { // house:getTiles() - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; } - const auto &tiles = house->getTiles(); + const auto tiles = house->getTiles(); lua_newtable(L); int index = 0; - for (Tile* tile : tiles) { + for (std::shared_ptr tile : tiles) { pushUserdata(L, tile); setMetatable(L, -1, "Tile"); lua_rawseti(L, -2, ++index); @@ -275,20 +326,20 @@ int HouseFunctions::luaHouseGetTiles(lua_State* L) { int HouseFunctions::luaHouseGetItems(lua_State* L) { // house:getItems() - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; } - const auto &tiles = house->getTiles(); + const auto tiles = house->getTiles(); lua_newtable(L); int index = 0; - for (Tile* tile : tiles) { + for (std::shared_ptr tile : tiles) { TileItemVector* itemVector = tile->getItemList(); if (itemVector) { - for (Item* item : *itemVector) { + for (auto &item : *itemVector) { pushUserdata(L, item); setItemMetatable(L, -1, item); lua_rawseti(L, -2, ++index); @@ -300,8 +351,7 @@ int HouseFunctions::luaHouseGetItems(lua_State* L) { int HouseFunctions::luaHouseGetTileCount(lua_State* L) { // house:getTileCount() - House* house = getUserdata(L, 1); - if (house) { + if (const auto &house = getUserdataShared(L, 1)) { lua_pushnumber(L, house->getTiles().size()); } else { lua_pushnil(L); @@ -311,14 +361,14 @@ int HouseFunctions::luaHouseGetTileCount(lua_State* L) { int HouseFunctions::luaHouseCanEditAccessList(lua_State* L) { // house:canEditAccessList(listId, player) - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; } uint32_t listId = getNumber(L, 2); - Player* player = getPlayer(L, 3); + std::shared_ptr player = getPlayer(L, 3); pushBoolean(L, house->canEditAccessList(listId, player)); return 1; @@ -326,7 +376,7 @@ int HouseFunctions::luaHouseCanEditAccessList(lua_State* L) { int HouseFunctions::luaHouseGetAccessList(lua_State* L) { // house:getAccessList(listId) - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; @@ -344,7 +394,7 @@ int HouseFunctions::luaHouseGetAccessList(lua_State* L) { int HouseFunctions::luaHouseSetAccessList(lua_State* L) { // house:setAccessList(listId, list) - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; @@ -359,7 +409,7 @@ int HouseFunctions::luaHouseSetAccessList(lua_State* L) { int HouseFunctions::luaHouseKickPlayer(lua_State* L) { // house:kickPlayer(player, targetPlayer) - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; @@ -371,13 +421,13 @@ int HouseFunctions::luaHouseKickPlayer(lua_State* L) { int HouseFunctions::luaHouseIsInvited(lua_State* L) { // house:isInvited(player) - House* house = getUserdata(L, 1); + const auto &house = getUserdataShared(L, 1); if (!house) { lua_pushnil(L); return 1; } - Player* player = getPlayer(L, 2); + std::shared_ptr player = getPlayer(L, 2); if (!player) { lua_pushnil(L); return 1; diff --git a/src/lua/functions/map/house_functions.hpp b/src/lua/functions/map/house_functions.hpp index 31ef31eb3..b5419ad5e 100644 --- a/src/lua/functions/map/house_functions.hpp +++ b/src/lua/functions/map/house_functions.hpp @@ -14,7 +14,7 @@ class HouseFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "House", "", HouseFunctions::luaHouseCreate); + registerSharedClass(L, "House", "", HouseFunctions::luaHouseCreate); registerMetaMethod(L, "House", "__eq", HouseFunctions::luaUserdataCompare); registerMethod(L, "House", "getId", HouseFunctions::luaHouseGetId); @@ -25,7 +25,10 @@ class HouseFunctions final : LuaScriptInterface { registerMethod(L, "House", "getPrice", HouseFunctions::luaHouseGetPrice); registerMethod(L, "House", "getOwnerGuid", HouseFunctions::luaHouseGetOwnerGuid); - registerMethod(L, "House", "setOwnerGuid", HouseFunctions::luaHouseSetOwnerGuid); + registerMethod(L, "House", "setHouseOwner", HouseFunctions::luaHouseSetHouseOwner); + registerMethod(L, "House", "setNewOwnerGuid", HouseFunctions::luaHouseSetNewOwnerGuid); + registerMethod(L, "House", "hasItemOnTile", HouseFunctions::luaHouseHasItemOnTile); + registerMethod(L, "House", "hasNewOwnership", HouseFunctions::luaHouseHasNewOwnership); registerMethod(L, "House", "startTrade", HouseFunctions::luaHouseStartTrade); registerMethod(L, "House", "getBeds", HouseFunctions::luaHouseGetBeds); @@ -58,7 +61,10 @@ class HouseFunctions final : LuaScriptInterface { static int luaHouseGetPrice(lua_State* L); static int luaHouseGetOwnerGuid(lua_State* L); - static int luaHouseSetOwnerGuid(lua_State* L); + static int luaHouseSetHouseOwner(lua_State* L); + static int luaHouseSetNewOwnerGuid(lua_State* L); + static int luaHouseHasItemOnTile(lua_State* L); + static int luaHouseHasNewOwnership(lua_State* L); static int luaHouseStartTrade(lua_State* L); static int luaHouseGetBeds(lua_State* L); diff --git a/src/lua/functions/map/position_functions.cpp b/src/lua/functions/map/position_functions.cpp index 7636e87d7..ba0633a81 100644 --- a/src/lua/functions/map/position_functions.cpp +++ b/src/lua/functions/map/position_functions.cpp @@ -149,7 +149,7 @@ int PositionFunctions::luaPositionSendMagicEffect(lua_State* L) { // position:sendMagicEffect(magicEffect[, player = nullptr]) SpectatorHashSet spectators; if (lua_gettop(L) >= 3) { - Player* player = getPlayer(L, 3); + std::shared_ptr player = getPlayer(L, 3); if (player) { spectators.insert(player); } @@ -177,7 +177,7 @@ int PositionFunctions::luaPositionRemoveMagicEffect(lua_State* L) { // position:removeMagicEffect(magicEffect[, player = nullptr]) SpectatorHashSet spectators; if (lua_gettop(L) >= 3) { - Player* player = getPlayer(L, 3); + std::shared_ptr player = getPlayer(L, 3); if (player) { spectators.insert(player); } @@ -205,7 +205,7 @@ int PositionFunctions::luaPositionSendDistanceEffect(lua_State* L) { // position:sendDistanceEffect(positionEx, distanceEffect[, player = nullptr]) SpectatorHashSet spectators; if (lua_gettop(L) >= 4) { - Player* player = getPlayer(L, 4); + std::shared_ptr player = getPlayer(L, 4); if (player) { spectators.insert(player); } @@ -233,7 +233,7 @@ int PositionFunctions::luaPositionSendSingleSoundEffect(lua_State* L) { // position:sendSingleSoundEffect(soundId[, actor = nullptr]) const Position &position = getPosition(L, 1); SoundEffect_t soundEffect = getNumber(L, 2); - Creature* actor = getCreature(L, 3); + std::shared_ptr actor = getCreature(L, 3); g_game().sendSingleSoundEffect(position, soundEffect, actor); pushBoolean(L, true); @@ -245,7 +245,7 @@ int PositionFunctions::luaPositionSendDoubleSoundEffect(lua_State* L) { const Position &position = getPosition(L, 1); SoundEffect_t mainSoundEffect = getNumber(L, 2); SoundEffect_t secondarySoundEffect = getNumber(L, 3); - Creature* actor = getCreature(L, 4); + std::shared_ptr actor = getCreature(L, 4); g_game().sendDoubleSoundEffect(position, mainSoundEffect, secondarySoundEffect, actor); pushBoolean(L, true); diff --git a/src/lua/functions/map/teleport_functions.cpp b/src/lua/functions/map/teleport_functions.cpp index edb93a4dc..05a4b408f 100644 --- a/src/lua/functions/map/teleport_functions.cpp +++ b/src/lua/functions/map/teleport_functions.cpp @@ -18,7 +18,7 @@ int TeleportFunctions::luaTeleportCreate(lua_State* L) { // Teleport(uid) uint32_t id = getNumber(L, 2); - Item* item = getScriptEnv()->getItemByUID(id); + std::shared_ptr item = getScriptEnv()->getItemByUID(id); if (item && item->getTeleport()) { pushUserdata(L, item); setMetatable(L, -1, "Teleport"); @@ -30,7 +30,7 @@ int TeleportFunctions::luaTeleportCreate(lua_State* L) { int TeleportFunctions::luaTeleportGetDestination(lua_State* L) { // teleport:getDestination() - Teleport* teleport = getUserdata(L, 1); + std::shared_ptr teleport = getUserdataShared(L, 1); if (teleport) { pushPosition(L, teleport->getDestPos()); } else { @@ -41,7 +41,7 @@ int TeleportFunctions::luaTeleportGetDestination(lua_State* L) { int TeleportFunctions::luaTeleportSetDestination(lua_State* L) { // teleport:setDestination(position) - Teleport* teleport = getUserdata(L, 1); + std::shared_ptr teleport = getUserdataShared(L, 1); if (teleport) { teleport->setDestPos(getPosition(L, 2)); pushBoolean(L, true); diff --git a/src/lua/functions/map/teleport_functions.hpp b/src/lua/functions/map/teleport_functions.hpp index e1e35f265..6c02c1620 100644 --- a/src/lua/functions/map/teleport_functions.hpp +++ b/src/lua/functions/map/teleport_functions.hpp @@ -14,7 +14,7 @@ class TeleportFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Teleport", "Item", TeleportFunctions::luaTeleportCreate); + registerSharedClass(L, "Teleport", "Item", TeleportFunctions::luaTeleportCreate); registerMetaMethod(L, "Teleport", "__eq", TeleportFunctions::luaUserdataCompare); registerMethod(L, "Teleport", "getDestination", TeleportFunctions::luaTeleportGetDestination); diff --git a/src/lua/functions/map/tile_functions.cpp b/src/lua/functions/map/tile_functions.cpp index 625b9ffe6..1081014ab 100644 --- a/src/lua/functions/map/tile_functions.cpp +++ b/src/lua/functions/map/tile_functions.cpp @@ -15,7 +15,7 @@ int TileFunctions::luaTileCreate(lua_State* L) { // Tile(x, y, z) // Tile(position) - Tile* tile; + std::shared_ptr tile; if (isTable(L, 2)) { tile = g_game().map.getTile(getPosition(L, 2)); } else { @@ -36,7 +36,7 @@ int TileFunctions::luaTileCreate(lua_State* L) { int TileFunctions::luaTileGetPosition(lua_State* L) { // tile:getPosition() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (tile) { pushPosition(L, tile->getPosition()); } else { @@ -47,7 +47,7 @@ int TileFunctions::luaTileGetPosition(lua_State* L) { int TileFunctions::luaTileGetGround(lua_State* L) { // tile:getGround() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (tile && tile->getGround()) { pushUserdata(L, tile->getGround()); setItemMetatable(L, -1, tile->getGround()); @@ -60,22 +60,22 @@ int TileFunctions::luaTileGetGround(lua_State* L) { int TileFunctions::luaTileGetThing(lua_State* L) { // tile:getThing(index) int32_t index = getNumber(L, 2); - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Thing* thing = tile->getThing(index); + std::shared_ptr thing = tile->getThing(index); if (!thing) { lua_pushnil(L); return 1; } - if (Creature* creature = thing->getCreature()) { + if (std::shared_ptr creature = thing->getCreature()) { pushUserdata(L, creature); setCreatureMetatable(L, -1, creature); - } else if (Item* item = thing->getItem()) { + } else if (std::shared_ptr item = thing->getItem()) { pushUserdata(L, item); setItemMetatable(L, -1, item); } else { @@ -86,7 +86,7 @@ int TileFunctions::luaTileGetThing(lua_State* L) { int TileFunctions::luaTileGetThingCount(lua_State* L) { // tile:getThingCount() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (tile) { lua_pushnumber(L, tile->getThingCount()); } else { @@ -97,23 +97,23 @@ int TileFunctions::luaTileGetThingCount(lua_State* L) { int TileFunctions::luaTileGetTopVisibleThing(lua_State* L) { // tile:getTopVisibleThing(creature) - Creature* creature = getCreature(L, 2); - Tile* tile = getUserdata(L, 1); + std::shared_ptr creature = getCreature(L, 2); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Thing* thing = tile->getTopVisibleThing(creature); + std::shared_ptr thing = tile->getTopVisibleThing(creature); if (!thing) { lua_pushnil(L); return 1; } - if (Creature* visibleCreature = thing->getCreature()) { + if (std::shared_ptr visibleCreature = thing->getCreature()) { pushUserdata(L, visibleCreature); setCreatureMetatable(L, -1, visibleCreature); - } else if (Item* visibleItem = thing->getItem()) { + } else if (std::shared_ptr visibleItem = thing->getItem()) { pushUserdata(L, visibleItem); setItemMetatable(L, -1, visibleItem); } else { @@ -124,13 +124,13 @@ int TileFunctions::luaTileGetTopVisibleThing(lua_State* L) { int TileFunctions::luaTileGetTopTopItem(lua_State* L) { // tile:getTopTopItem() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Item* item = tile->getTopTopItem(); + std::shared_ptr item = tile->getTopTopItem(); if (item) { pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -142,13 +142,13 @@ int TileFunctions::luaTileGetTopTopItem(lua_State* L) { int TileFunctions::luaTileGetTopDownItem(lua_State* L) { // tile:getTopDownItem() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Item* item = tile->getTopDownItem(); + std::shared_ptr item = tile->getTopDownItem(); if (item) { pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -160,13 +160,13 @@ int TileFunctions::luaTileGetTopDownItem(lua_State* L) { int TileFunctions::luaTileGetFieldItem(lua_State* L) { // tile:getFieldItem() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Item* item = tile->getFieldItem(); + std::shared_ptr item = tile->getFieldItem(); if (item) { pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -178,7 +178,7 @@ int TileFunctions::luaTileGetFieldItem(lua_State* L) { int TileFunctions::luaTileGetItemById(lua_State* L) { // tile:getItemById(itemId[, subType = -1]) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -196,7 +196,7 @@ int TileFunctions::luaTileGetItemById(lua_State* L) { } int32_t subType = getNumber(L, 3, -1); - Item* item = g_game().findItemOfType(tile, itemId, false, subType); + std::shared_ptr item = g_game().findItemOfType(tile, itemId, false, subType); if (item) { pushUserdata(L, item); setItemMetatable(L, -1, item); @@ -208,7 +208,7 @@ int TileFunctions::luaTileGetItemById(lua_State* L) { int TileFunctions::luaTileGetItemByType(lua_State* L) { // tile:getItemByType(itemType) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -246,7 +246,7 @@ int TileFunctions::luaTileGetItemByType(lua_State* L) { return 1; } - if (Item* item = tile->getGround()) { + if (std::shared_ptr item = tile->getGround()) { const ItemType &it = Item::items[item->getID()]; if (it.type == itemType) { pushUserdata(L, item); @@ -256,7 +256,7 @@ int TileFunctions::luaTileGetItemByType(lua_State* L) { } if (const TileItemVector* items = tile->getItemList()) { - for (Item* item : *items) { + for (auto &item : *items) { const ItemType &it = Item::items[item->getID()]; if (it.type == itemType) { pushUserdata(L, item); @@ -272,7 +272,7 @@ int TileFunctions::luaTileGetItemByType(lua_State* L) { int TileFunctions::luaTileGetItemByTopOrder(lua_State* L) { // tile:getItemByTopOrder(topOrder) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -280,7 +280,7 @@ int TileFunctions::luaTileGetItemByTopOrder(lua_State* L) { int32_t topOrder = getNumber(L, 2); - Item* item = tile->getItemByTopOrder(topOrder); + std::shared_ptr item = tile->getItemByTopOrder(topOrder); if (!item) { lua_pushnil(L); return 1; @@ -293,7 +293,7 @@ int TileFunctions::luaTileGetItemByTopOrder(lua_State* L) { int TileFunctions::luaTileGetItemCountById(lua_State* L) { // tile:getItemCountById(itemId[, subType = -1]) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -318,13 +318,13 @@ int TileFunctions::luaTileGetItemCountById(lua_State* L) { int TileFunctions::luaTileGetBottomCreature(lua_State* L) { // tile:getBottomCreature() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - const Creature* creature = tile->getBottomCreature(); + std::shared_ptr creature = tile->getBottomCreature(); if (!creature) { lua_pushnil(L); return 1; @@ -337,13 +337,13 @@ int TileFunctions::luaTileGetBottomCreature(lua_State* L) { int TileFunctions::luaTileGetTopCreature(lua_State* L) { // tile:getTopCreature() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Creature* creature = tile->getTopCreature(); + std::shared_ptr creature = tile->getTopCreature(); if (!creature) { lua_pushnil(L); return 1; @@ -356,19 +356,19 @@ int TileFunctions::luaTileGetTopCreature(lua_State* L) { int TileFunctions::luaTileGetBottomVisibleCreature(lua_State* L) { // tile:getBottomVisibleCreature(creature) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); if (!creature) { lua_pushnil(L); return 1; } - const Creature* visibleCreature = tile->getBottomVisibleCreature(creature); + std::shared_ptr visibleCreature = tile->getBottomVisibleCreature(creature); if (visibleCreature) { pushUserdata(L, visibleCreature); setCreatureMetatable(L, -1, visibleCreature); @@ -380,19 +380,19 @@ int TileFunctions::luaTileGetBottomVisibleCreature(lua_State* L) { int TileFunctions::luaTileGetTopVisibleCreature(lua_State* L) { // tile:getTopVisibleCreature(creature) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Creature* creature = getCreature(L, 2); + std::shared_ptr creature = getCreature(L, 2); if (!creature) { lua_pushnil(L); return 1; } - Creature* visibleCreature = tile->getTopVisibleCreature(creature); + std::shared_ptr visibleCreature = tile->getTopVisibleCreature(creature); if (visibleCreature) { pushUserdata(L, visibleCreature); setCreatureMetatable(L, -1, visibleCreature); @@ -404,7 +404,7 @@ int TileFunctions::luaTileGetTopVisibleCreature(lua_State* L) { int TileFunctions::luaTileGetItems(lua_State* L) { // tile:getItems() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -419,7 +419,7 @@ int TileFunctions::luaTileGetItems(lua_State* L) { lua_createtable(L, itemVector->size(), 0); int index = 0; - for (Item* item : *itemVector) { + for (auto &item : *itemVector) { pushUserdata(L, item); setItemMetatable(L, -1, item); lua_rawseti(L, -2, ++index); @@ -429,7 +429,7 @@ int TileFunctions::luaTileGetItems(lua_State* L) { int TileFunctions::luaTileGetItemCount(lua_State* L) { // tile:getItemCount() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -441,7 +441,7 @@ int TileFunctions::luaTileGetItemCount(lua_State* L) { int TileFunctions::luaTileGetDownItemCount(lua_State* L) { // tile:getDownItemCount() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (tile) { lua_pushnumber(L, tile->getDownItemCount()); } else { @@ -452,7 +452,7 @@ int TileFunctions::luaTileGetDownItemCount(lua_State* L) { int TileFunctions::luaTileGetTopItemCount(lua_State* L) { // tile:getTopItemCount() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -464,7 +464,7 @@ int TileFunctions::luaTileGetTopItemCount(lua_State* L) { int TileFunctions::luaTileGetCreatures(lua_State* L) { // tile:getCreatures() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -479,7 +479,7 @@ int TileFunctions::luaTileGetCreatures(lua_State* L) { lua_createtable(L, creatureVector->size(), 0); int index = 0; - for (Creature* creature : *creatureVector) { + for (auto &creature : *creatureVector) { pushUserdata(L, creature); setCreatureMetatable(L, -1, creature); lua_rawseti(L, -2, ++index); @@ -489,7 +489,7 @@ int TileFunctions::luaTileGetCreatures(lua_State* L) { int TileFunctions::luaTileGetCreatureCount(lua_State* L) { // tile:getCreatureCount() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -501,15 +501,15 @@ int TileFunctions::luaTileGetCreatureCount(lua_State* L) { int TileFunctions::luaTileHasProperty(lua_State* L) { // tile:hasProperty(property[, item]) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Item* item; + std::shared_ptr item; if (lua_gettop(L) >= 3) { - item = getUserdata(L, 3); + item = getUserdataShared(L, 3); } else { item = nullptr; } @@ -525,13 +525,13 @@ int TileFunctions::luaTileHasProperty(lua_State* L) { int TileFunctions::luaTileGetThingIndex(lua_State* L) { // tile:getThingIndex(thing) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Thing* thing = getThing(L, 2); + std::shared_ptr thing = getThing(L, 2); if (thing) { lua_pushnumber(L, tile->getThingIndex(thing)); } else { @@ -542,7 +542,7 @@ int TileFunctions::luaTileGetThingIndex(lua_State* L) { int TileFunctions::luaTileHasFlag(lua_State* L) { // tile:hasFlag(flag) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (tile) { TileFlags_t flag = getNumber(L, 2); pushBoolean(L, tile->hasFlag(flag)); @@ -554,16 +554,16 @@ int TileFunctions::luaTileHasFlag(lua_State* L) { int TileFunctions::luaTileQueryAdd(lua_State* L) { // tile:queryAdd(thing[, flags]) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - Thing* thing = getThing(L, 2); + std::shared_ptr thing = getThing(L, 2); if (thing) { uint32_t flags = getNumber(L, 3, 0); - lua_pushnumber(L, tile->queryAdd(0, *thing, 1, flags)); + lua_pushnumber(L, tile->queryAdd(0, thing, 1, flags)); } else { lua_pushnil(L); } @@ -572,7 +572,7 @@ int TileFunctions::luaTileQueryAdd(lua_State* L) { int TileFunctions::luaTileAddItem(lua_State* L) { // tile:addItem(itemId[, count/subType = 1[, flags = 0]]) - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -591,7 +591,7 @@ int TileFunctions::luaTileAddItem(lua_State* L) { uint32_t subType = getNumber(L, 3, 1); - Item* item = Item::CreateItem(itemId, std::min(subType, Item::items[itemId].stackSize)); + std::shared_ptr item = Item::CreateItem(itemId, std::min(subType, Item::items[itemId].stackSize)); if (!item) { lua_pushnil(L); return 1; @@ -604,7 +604,7 @@ int TileFunctions::luaTileAddItem(lua_State* L) { pushUserdata(L, item); setItemMetatable(L, -1, item); } else { - delete item; + lua_pushnil(L); } return 1; @@ -612,13 +612,13 @@ int TileFunctions::luaTileAddItem(lua_State* L) { int TileFunctions::luaTileAddItemEx(lua_State* L) { // tile:addItemEx(item[, flags = 0]) - Item* item = getUserdata(L, 2); + std::shared_ptr item = getUserdataShared(L, 2); if (!item) { lua_pushnil(L); return 1; } - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; @@ -641,13 +641,13 @@ int TileFunctions::luaTileAddItemEx(lua_State* L) { int TileFunctions::luaTileGetHouse(lua_State* L) { // tile:getHouse() - Tile* tile = getUserdata(L, 1); + std::shared_ptr tile = getUserdataShared(L, 1); if (!tile) { lua_pushnil(L); return 1; } - if (HouseTile* houseTile = dynamic_cast(tile)) { + if (std::shared_ptr houseTile = std::dynamic_pointer_cast(tile)) { pushUserdata(L, houseTile->getHouse()); setMetatable(L, -1, "House"); } else { diff --git a/src/lua/functions/map/tile_functions.hpp b/src/lua/functions/map/tile_functions.hpp index 149a09e21..24e0a87d8 100644 --- a/src/lua/functions/map/tile_functions.hpp +++ b/src/lua/functions/map/tile_functions.hpp @@ -14,7 +14,7 @@ class TileFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Tile", "", TileFunctions::luaTileCreate); + registerSharedClass(L, "Tile", "", TileFunctions::luaTileCreate); registerMetaMethod(L, "Tile", "__eq", TileFunctions::luaUserdataCompare); registerMethod(L, "Tile", "getPosition", TileFunctions::luaTileGetPosition); diff --git a/src/lua/functions/map/town_functions.cpp b/src/lua/functions/map/town_functions.cpp index 44dfc4934..f50042c15 100644 --- a/src/lua/functions/map/town_functions.cpp +++ b/src/lua/functions/map/town_functions.cpp @@ -15,7 +15,7 @@ int TownFunctions::luaTownCreate(lua_State* L) { // Town(id or name) - Town* town; + std::shared_ptr town; if (isNumber(L, 2)) { town = g_game().map.towns.getTown(getNumber(L, 2)); } else if (isString(L, 2)) { @@ -35,8 +35,7 @@ int TownFunctions::luaTownCreate(lua_State* L) { int TownFunctions::luaTownGetId(lua_State* L) { // town:getId() - Town* town = getUserdata(L, 1); - if (town) { + if (const auto &town = getUserdataShared(L, 1)) { lua_pushnumber(L, town->getID()); } else { lua_pushnil(L); @@ -46,8 +45,7 @@ int TownFunctions::luaTownGetId(lua_State* L) { int TownFunctions::luaTownGetName(lua_State* L) { // town:getName() - Town* town = getUserdata(L, 1); - if (town) { + if (const auto &town = getUserdataShared(L, 1)) { pushString(L, town->getName()); } else { lua_pushnil(L); @@ -57,8 +55,7 @@ int TownFunctions::luaTownGetName(lua_State* L) { int TownFunctions::luaTownGetTemplePosition(lua_State* L) { // town:getTemplePosition() - Town* town = getUserdata(L, 1); - if (town) { + if (const auto &town = getUserdataShared(L, 1)) { pushPosition(L, town->getTemplePosition()); } else { lua_pushnil(L); diff --git a/src/lua/functions/map/town_functions.hpp b/src/lua/functions/map/town_functions.hpp index 68be86689..4f60eeab2 100644 --- a/src/lua/functions/map/town_functions.hpp +++ b/src/lua/functions/map/town_functions.hpp @@ -14,7 +14,7 @@ class TownFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { - registerClass(L, "Town", "", TownFunctions::luaTownCreate); + registerSharedClass(L, "Town", "", TownFunctions::luaTownCreate); registerMetaMethod(L, "Town", "__eq", TownFunctions::luaUserdataCompare); registerMethod(L, "Town", "getId", TownFunctions::luaTownGetId); diff --git a/src/lua/global/globalevent.cpp b/src/lua/global/globalevent.cpp index 2366ef261..a8acb01bb 100644 --- a/src/lua/global/globalevent.cpp +++ b/src/lua/global/globalevent.cpp @@ -71,7 +71,7 @@ void GlobalEvents::timer() { auto it = timerMap.begin(); while (it != timerMap.end()) { - const auto &globalEvent = it->second; + const auto globalEvent = it->second; int64_t nextExecutionTime = globalEvent->getNextExecution() - now; if (nextExecutionTime > 0) { @@ -108,7 +108,7 @@ void GlobalEvents::think() { int64_t nextScheduledTime = std::numeric_limits::max(); for (auto &it : thinkMap) { - const auto &globalEvent = it.second; + const auto globalEvent = it.second; int64_t nextExecutionTime = globalEvent->getNextExecution() - now; if (nextExecutionTime > 0) { @@ -142,7 +142,7 @@ void GlobalEvents::think() { void GlobalEvents::execute(GlobalEvent_t type) const { for (const auto &it : serverMap) { - const auto &globalEvent = it.second; + const auto globalEvent = it.second; if (globalEvent->getEventType() == type) { globalEvent->executeEvent(); } diff --git a/src/lua/global/shared_object.hpp b/src/lua/global/shared_object.hpp index 571fdf171..62cc26b33 100644 --- a/src/lua/global/shared_object.hpp +++ b/src/lua/global/shared_object.hpp @@ -9,6 +9,8 @@ #pragma once +#include + class SharedObject; using SharedObjectPtr = std::shared_ptr; diff --git a/src/lua/modules/modules.cpp b/src/lua/modules/modules.cpp index 402095bb4..5e1565251 100644 --- a/src/lua/modules/modules.cpp +++ b/src/lua/modules/modules.cpp @@ -78,7 +78,7 @@ Module* Modules::getEventByRecvbyte(uint8_t recvbyte, bool force) { } void Modules::executeOnRecvbyte(uint32_t playerId, NetworkMessage &msg, uint8_t byte) const { - Player* player = g_game().getPlayerByID(playerId); + std::shared_ptr player = g_game().getPlayerByID(playerId); if (!player) { return; } @@ -152,7 +152,7 @@ void Module::clearEvent() { loaded = false; } -void Module::executeOnRecvbyte(Player* player, NetworkMessage &msg) { +void Module::executeOnRecvbyte(std::shared_ptr player, NetworkMessage &msg) { // onRecvbyte(player, msg, recvbyte) if (!scriptInterface->reserveScriptEnv()) { g_logger().error("Call stack overflow. Too many lua script calls being nested {}", player->getName()); @@ -168,7 +168,7 @@ void Module::executeOnRecvbyte(Player* player, NetworkMessage &msg) { LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); - LuaScriptInterface::pushUserdata(L, &msg); + LuaScriptInterface::pushUserdata(L, std::shared_ptr(&msg)); LuaScriptInterface::setWeakMetatable(L, -1, "NetworkMessage"); lua_pushnumber(L, recvbyte); diff --git a/src/lua/modules/modules.hpp b/src/lua/modules/modules.hpp index 222c88826..f72baf94f 100644 --- a/src/lua/modules/modules.hpp +++ b/src/lua/modules/modules.hpp @@ -35,7 +35,7 @@ class Module final : public Event { void copyEvent(Module* creatureEvent); // scripting - void executeOnRecvbyte(Player* player, NetworkMessage &msg); + void executeOnRecvbyte(std::shared_ptr player, NetworkMessage &msg); // uint8_t getRecvbyte() { diff --git a/src/lua/scripts/lua_environment.cpp b/src/lua/scripts/lua_environment.cpp index 605e7d864..717ce36ae 100644 --- a/src/lua/scripts/lua_environment.cpp +++ b/src/lua/scripts/lua_environment.cpp @@ -16,12 +16,13 @@ bool LuaEnvironment::shuttingDown = false; +static const std::unique_ptr &AreaCombatNull {}; + LuaEnvironment::LuaEnvironment() : LuaScriptInterface("Main Interface") { } LuaEnvironment::~LuaEnvironment() { if (!testInterface) { - delete testInterface; } LuaEnvironment::shuttingDown = true; @@ -118,16 +119,16 @@ void LuaEnvironment::clearCombatObjects(LuaScriptInterface* interface) { combatMap.clear(); } -AreaCombat* LuaEnvironment::getAreaObject(uint32_t id) const { +const std::unique_ptr &LuaEnvironment::getAreaObject(uint32_t id) const { auto it = areaMap.find(id); if (it == areaMap.end()) { - return nullptr; + return AreaCombatNull; } return it->second; } uint32_t LuaEnvironment::createAreaObject(LuaScriptInterface* interface) { - areaMap[++lastAreaId] = new AreaCombat; + areaMap[++lastAreaId] = std::make_unique(); areaIdMap[interface].push_back(lastAreaId); return lastAreaId; } @@ -141,7 +142,6 @@ void LuaEnvironment::clearAreaObjects(LuaScriptInterface* interface) { for (uint32_t id : it->second) { auto itt = areaMap.find(id); if (itt != areaMap.end()) { - delete itt->second; areaMap.erase(itt); } } @@ -183,3 +183,19 @@ void LuaEnvironment::executeTimerEvent(uint32_t eventIndex) { luaL_unref(luaState, LUA_REGISTRYINDEX, parameter); } } + +void LuaEnvironment::collectGarbage() const { + // prevents recursive collects + static bool collecting = false; + if (!collecting) { + collecting = true; + + // we must collect two times because __gc metamethod + // is called on uservalues only the second time + for (int i = -1; ++i < 2;) { + lua_gc(luaState, LUA_GCCOLLECT, 0); + } + + collecting = false; + } +} diff --git a/src/lua/scripts/lua_environment.hpp b/src/lua/scripts/lua_environment.hpp index 752a07123..216abb8ec 100644 --- a/src/lua/scripts/lua_environment.hpp +++ b/src/lua/scripts/lua_environment.hpp @@ -75,20 +75,22 @@ class LuaEnvironment : public LuaScriptInterface { weaponMap.clear(); } - AreaCombat* getAreaObject(uint32_t id) const; + const std::unique_ptr &getAreaObject(uint32_t id) const; uint32_t createAreaObject(LuaScriptInterface* interface); void clearAreaObjects(LuaScriptInterface* interface); static bool isShuttingDown() { return shuttingDown; } + void collectGarbage() const; + private: void executeTimerEvent(uint32_t eventIndex); phmap::flat_hash_map timerEvents; uint32_t lastEventTimerId = 1; - phmap::flat_hash_map areaMap; + phmap::flat_hash_map> areaMap; phmap::flat_hash_map> areaIdMap; uint32_t lastAreaId = 0; diff --git a/src/lua/scripts/luascript.cpp b/src/lua/scripts/luascript.cpp index 469805e8a..d7d12dfe2 100644 --- a/src/lua/scripts/luascript.cpp +++ b/src/lua/scripts/luascript.cpp @@ -14,7 +14,7 @@ ScriptEnvironment::DBResultMap ScriptEnvironment::tempResults; uint32_t ScriptEnvironment::lastResultId = 0; -std::multimap ScriptEnvironment::tempItems; +std::multimap> ScriptEnvironment::tempItems; ScriptEnvironment LuaFunctionsLoader::scriptEnv[16]; int32_t LuaFunctionsLoader::scriptEnvIndex = -1; diff --git a/src/lua/scripts/script_environment.cpp b/src/lua/scripts/script_environment.cpp index 50718cd84..8899a954f 100644 --- a/src/lua/scripts/script_environment.cpp +++ b/src/lua/scripts/script_environment.cpp @@ -33,10 +33,7 @@ void ScriptEnvironment::resetEnv() { auto pair = tempItems.equal_range(this); auto it = pair.first; while (it != pair.second) { - Item* item = it->second; - if (item->getParent() == VirtualCylinder::virtualCylinder) { - g_game().ReleaseItem(item); - } + std::shared_ptr item = it->second; it = tempItems.erase(it); } } @@ -62,17 +59,17 @@ void ScriptEnvironment::getEventInfo(int32_t &retScriptId, LuaScriptInterface*&r retTimerEvent = this->timerEvent; } -uint32_t ScriptEnvironment::addThing(Thing* thing) { +uint32_t ScriptEnvironment::addThing(std::shared_ptr thing) { if (!thing || thing->isRemoved()) { return 0; } - Creature* creature = thing->getCreature(); + std::shared_ptr creature = thing->getCreature(); if (creature) { return creature->getID(); } - Item* item = thing->getItem(); + std::shared_ptr item = thing->getItem(); if (item && item->hasAttribute(ItemAttribute_t::UNIQUEID)) { return item->getAttribute(ItemAttribute_t::UNIQUEID); } @@ -87,20 +84,20 @@ uint32_t ScriptEnvironment::addThing(Thing* thing) { return lastUID; } -void ScriptEnvironment::insertItem(uint32_t uid, Item* item) { +void ScriptEnvironment::insertItem(uint32_t uid, std::shared_ptr item) { auto result = localMap.emplace(uid, item); if (!result.second) { g_logger().error("Thing uid already taken: {}", uid); } } -Thing* ScriptEnvironment::getThingByUID(uint32_t uid) { +std::shared_ptr ScriptEnvironment::getThingByUID(uint32_t uid) { if (uid >= 0x10000000) { return g_game().getCreatureByID(uid); } if (uid <= std::numeric_limits::max()) { - Item* item = g_game().getUniqueItem(static_cast(uid)); + std::shared_ptr item = g_game().getUniqueItem(static_cast(uid)); if (item && !item->isRemoved()) { return item; } @@ -109,7 +106,7 @@ Thing* ScriptEnvironment::getThingByUID(uint32_t uid) { auto it = localMap.find(uid); if (it != localMap.end()) { - Item* item = it->second; + std::shared_ptr item = it->second; if (!item->isRemoved()) { return item; } @@ -117,16 +114,16 @@ Thing* ScriptEnvironment::getThingByUID(uint32_t uid) { return nullptr; } -Item* ScriptEnvironment::getItemByUID(uint32_t uid) { - Thing* thing = getThingByUID(uid); +std::shared_ptr ScriptEnvironment::getItemByUID(uint32_t uid) { + std::shared_ptr thing = getThingByUID(uid); if (!thing) { return nullptr; } return thing->getItem(); } -Container* ScriptEnvironment::getContainerByUID(uint32_t uid) { - Item* item = getItemByUID(uid); +std::shared_ptr ScriptEnvironment::getContainerByUID(uint32_t uid) { + std::shared_ptr item = getItemByUID(uid); if (!item) { return nullptr; } @@ -145,11 +142,11 @@ void ScriptEnvironment::removeItemByUID(uint32_t uid) { } } -void ScriptEnvironment::addTempItem(Item* item) { +void ScriptEnvironment::addTempItem(std::shared_ptr item) { tempItems.emplace(this, item); } -void ScriptEnvironment::removeTempItem(Item* item) { +void ScriptEnvironment::removeTempItem(std::shared_ptr item) { for (auto it = tempItems.begin(), end = tempItems.end(); it != end; ++it) { if (it->second == item) { tempItems.erase(it); diff --git a/src/lua/scripts/script_environment.hpp b/src/lua/scripts/script_environment.hpp index ac3fedf9c..4c219b0a0 100644 --- a/src/lua/scripts/script_environment.hpp +++ b/src/lua/scripts/script_environment.hpp @@ -52,25 +52,25 @@ class ScriptEnvironment { void getEventInfo(int32_t &scriptId, LuaScriptInterface*&scriptInterface, int32_t &callbackId, bool &timerEvent) const; - void addTempItem(Item* item); - static void removeTempItem(Item* item); - uint32_t addThing(Thing* thing); - void insertItem(uint32_t uid, Item* item); + void addTempItem(std::shared_ptr item); + static void removeTempItem(std::shared_ptr item); + uint32_t addThing(std::shared_ptr thing); + void insertItem(uint32_t uid, std::shared_ptr item); static DBResult_ptr getResultByID(uint32_t id); static uint32_t addResult(DBResult_ptr res); static bool removeResult(uint32_t id); - void setNpc(Npc* npc) { + void setNpc(std::shared_ptr npc) { curNpc = npc; } - Npc* getNpc() const { + std::shared_ptr getNpc() const { return curNpc; } - Thing* getThingByUID(uint32_t uid); - Item* getItemByUID(uint32_t uid); - Container* getContainerByUID(uint32_t uid); + std::shared_ptr getThingByUID(uint32_t uid); + std::shared_ptr getItemByUID(uint32_t uid); + std::shared_ptr getContainerByUID(uint32_t uid); void removeItemByUID(uint32_t uid); private: @@ -81,13 +81,13 @@ class ScriptEnvironment { LuaScriptInterface* interface; // for npc scripts - Npc* curNpc = nullptr; + std::shared_ptr curNpc = nullptr; // temporary item list - static std::multimap tempItems; + static std::multimap> tempItems; // local item map - phmap::flat_hash_map localMap; + phmap::flat_hash_map> localMap; uint32_t lastUID = std::numeric_limits::max(); // script file id diff --git a/src/lua/scripts/scripts.cpp b/src/lua/scripts/scripts.cpp index 5a9627af1..bb7c5a6a6 100644 --- a/src/lua/scripts/scripts.cpp +++ b/src/lua/scripts/scripts.cpp @@ -72,7 +72,7 @@ bool Scripts::loadScripts(std::string loadPath, bool isLib, bool reload) { // Recursive iterate through all entries in the directory for (const auto &entry : std::filesystem::recursive_directory_iterator(dir)) { // Get the filename of the entry as a string - const auto &realPath = entry.path(); + const auto realPath = entry.path(); std::string fileFolder = realPath.parent_path().filename().string(); // Script folder, example: "actions" std::string scriptFolder = realPath.parent_path().string(); diff --git a/src/map/house/house.cpp b/src/map/house/house.cpp index 0ee5a5946..a623a3e52 100644 --- a/src/map/house/house.cpp +++ b/src/map/house/house.cpp @@ -18,18 +18,74 @@ House::House(uint32_t houseId) : id(houseId) { } -void House::addTile(HouseTile* tile) { +void House::addTile(std::shared_ptr tile) { tile->setFlag(TILESTATE_PROTECTIONZONE); houseTiles.push_back(tile); updateDoorDescription(); } -void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, Player* player /* = nullptr*/) { +void House::setNewOwnerGuid(int32_t newOwnerGuid, bool serverStartup) { + auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART); + if (!isTransferOnRestart) { + setOwner(newOwnerGuid, true); + return; + } + + std::ostringstream query; + query << "UPDATE `houses` SET `new_owner` = " << newOwnerGuid << " WHERE `id` = " << id; + + Database &db = Database::getInstance(); + db.executeQuery(query.str()); + if (!serverStartup) { + setNewOwnership(); + } +} + +bool House::tryTransferOwnership(std::shared_ptr player, bool serverStartup) { + bool transferSuccess = false; + if (player) { + transferSuccess = transferToDepot(player); + } else { + transferSuccess = transferToDepot(); + } + + for (auto tile : houseTiles) { + if (const CreatureVector* creatures = tile->getCreatures()) { + for (int32_t i = creatures->size(); --i >= 0;) { + const auto creature = (*creatures)[i]; + kickPlayer(nullptr, creature->getPlayer()); + } + } + } + + // Remove players from beds + for (auto bed : bedsList) { + if (bed->getSleeper() != 0) { + bed->wakeUp(nullptr); + } + } + + // Clean access lists + if (!serverStartup) { + owner = 0; + ownerAccountId = 0; + } + setAccessList(SUBOWNER_LIST, ""); + setAccessList(GUEST_LIST, ""); + + for (auto door : doorList) { + door->setAccessList(""); + } + + return transferSuccess; +} + +void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, std::shared_ptr player /* = nullptr*/) { if (updateDatabase && owner != guid) { Database &db = Database::getInstance(); std::ostringstream query; - query << "UPDATE `houses` SET `owner` = " << guid << ", `bid` = 0, `bid_end` = 0, `last_bid` = 0, `highest_bidder` = 0 WHERE `id` = " << id; + query << "UPDATE `houses` SET `owner` = " << guid << ", `new_owner` = -1, `bid` = 0, `bid_end` = 0, `last_bid` = 0, `highest_bidder` = 0 WHERE `id` = " << id; db.executeQuery(query.str()); } @@ -40,37 +96,7 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, Player* pla isLoaded = true; if (owner != 0) { - // Send items to depot - if (player) { - transferToDepot(player); - } else { - transferToDepot(); - } - - for (HouseTile* tile : houseTiles) { - if (const CreatureVector* creatures = tile->getCreatures()) { - for (int32_t i = creatures->size(); --i >= 0;) { - kickPlayer(nullptr, (*creatures)[i]->getPlayer()); - } - } - } - - // Remove players from beds - for (BedItem* bed : bedsList) { - if (bed->getSleeper() != 0) { - bed->wakeUp(nullptr); - } - } - - // clean access lists - owner = 0; - ownerAccountId = 0; - setAccessList(SUBOWNER_LIST, ""); - setAccessList(GUEST_LIST, ""); - - for (Door* door : doorList) { - door->setAccessList(""); - } + tryTransferOwnership(player, false); } else { std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD)); time_t currentTime = time(nullptr); @@ -119,7 +145,7 @@ void House::updateDoorDescription() const { ss << "It belongs to house '" << houseName << "'. Nobody owns this house."; } - ss << " It is " << houseTiles.size() << " square meters."; + ss << " It is " << getSize() << " square meters."; const int32_t housePrice = getPrice(); if (housePrice != -1) { if (g_configManager().getBoolean(HOUSE_PURSHASED_SHOW_PRICE) || owner == 0) { @@ -136,7 +162,7 @@ void House::updateDoorDescription() const { } } -AccessHouseLevel_t House::getHouseAccessLevel(const Player* player) { +AccessHouseLevel_t House::getHouseAccessLevel(std::shared_ptr player) { if (!player) { return HOUSE_OWNER; } @@ -166,13 +192,13 @@ AccessHouseLevel_t House::getHouseAccessLevel(const Player* player) { return HOUSE_NOT_INVITED; } -bool House::kickPlayer(Player* player, Player* target) { +bool House::kickPlayer(std::shared_ptr player, std::shared_ptr target) { if (!target) { return false; } - HouseTile* houseTile = dynamic_cast(target->getTile()); - if (!houseTile || houseTile->getHouse() != this) { + std::shared_ptr houseTile = std::dynamic_pointer_cast(target->getTile()); + if (!houseTile || houseTile->getHouse() != static_self_cast()) { return false; } @@ -194,7 +220,7 @@ void House::setAccessList(uint32_t listId, const std::string &textlist) { } else if (listId == SUBOWNER_LIST) { subOwnerList.parseList(textlist); } else { - Door* door = getDoorByNumber(listId); + std::shared_ptr door = getDoorByNumber(listId); if (door) { door->setAccessList(textlist); } @@ -204,10 +230,10 @@ void House::setAccessList(uint32_t listId, const std::string &textlist) { } // kick uninvited players - for (HouseTile* tile : houseTiles) { + for (std::shared_ptr tile : houseTiles) { if (CreatureVector* creatures = tile->getCreatures()) { for (int32_t i = creatures->size(); --i >= 0;) { - Player* player = (*creatures)[i]->getPlayer(); + std::shared_ptr player = (*creatures)[i]->getPlayer(); if (player && !isInvited(player)) { kickPlayer(nullptr, player); } @@ -217,33 +243,33 @@ void House::setAccessList(uint32_t listId, const std::string &textlist) { } bool House::transferToDepot() const { - if (townId == 0 || owner == 0) { + if (townId == 0) { return false; } - Player* player = g_game().getPlayerByGUID(owner); + std::shared_ptr player = g_game().getPlayerByGUID(owner); if (player) { transferToDepot(player); } else { - Player tmpPlayer(nullptr); - if (!IOLoginData::loadPlayerById(&tmpPlayer, owner)) { + std::shared_ptr tmpPlayer = std::make_shared(nullptr); + if (!IOLoginData::loadPlayerById(tmpPlayer, owner)) { return false; } - transferToDepot(&tmpPlayer); - IOLoginData::savePlayer(&tmpPlayer); + transferToDepot(tmpPlayer); } return true; } -bool House::transferToDepot(Player* player) const { - if (townId == 0 || owner == 0) { +bool House::transferToDepot(std::shared_ptr player) const { + if (townId == 0 || !player) { return false; } + ItemList moveItemList; - for (HouseTile* tile : houseTiles) { + for (std::shared_ptr tile : houseTiles) { if (const TileItemVector* items = tile->getItemList()) { - for (Item* item : *items) { + for (const std::shared_ptr &item : *items) { if (item->isWrapable()) { handleWrapableItem(moveItemList, item, player, tile); } else if (item->isPickupable()) { @@ -255,18 +281,60 @@ bool House::transferToDepot(Player* player) const { } } - for (Item* item : moveItemList) { + for (std::shared_ptr item : moveItemList) { + g_logger().debug("[{}] moving item '{}' to depot", __FUNCTION__, item->getName()); g_game().internalMoveItem(item->getParent(), player->getInbox(), INDEX_WHEREEVER, item, item->getItemCount(), nullptr, FLAG_NOLIMIT); } + IOLoginData::savePlayer(player); return true; } -void House::handleWrapableItem(ItemList &moveItemList, Item* item, Player* player, HouseTile* houseTile) const { +bool House::hasItemOnTile() const { + bool foundItem = false; + for (const std::shared_ptr &tile : houseTiles) { + if (const auto &items = tile->getItemList()) { + for (const std::shared_ptr &item : *items) { + if (!item) { + continue; + } + + if (item->isWrapable()) { + foundItem = true; + g_logger().error("It is not possible to purchase a house with wrap item inside: id '{}', name '{}'", item->getID(), item->getName()); + break; + } else if (item->isPickupable()) { + foundItem = true; + g_logger().error("It is not possible to purchase a house with pickupable item inside: id '{}', name '{}'", item->getID(), item->getName()); + break; + } else { + if (item->getContainer() && (item->isPickupable() || item->isWrapable())) { + foundItem = true; + g_logger().error("It is not possible to purchase a house with container item inside: id '{}', name '{}'", item->getID(), item->getName()); + break; + } + } + } + } + } + + return foundItem; +} + +bool House::hasNewOwnership() const { + return hasNewOwnerOnStartup; +} + +void House::setNewOwnership() { + hasNewOwnerOnStartup = true; +} + +void House::handleWrapableItem(ItemList &moveItemList, std::shared_ptr item, std::shared_ptr player, std::shared_ptr houseTile) const { if (item->isWrapContainer()) { + g_logger().debug("[{}] found wrapable item '{}'", __FUNCTION__, item->getName()); handleContainer(moveItemList, item); } - Item* newItem = g_game().wrapItem(item, houseTile->getHouse()); + std::shared_ptr newItem = g_game().wrapItem(item, houseTile->getHouse()); if (newItem->isRemoved() && !newItem->getParent()) { g_logger().warn("[{}] item removed during wrapping - check ground type - player name: {} item id: {} position: {}", __FUNCTION__, player->getName(), item->getID(), houseTile->getPosition().toString()); return; @@ -275,9 +343,9 @@ void House::handleWrapableItem(ItemList &moveItemList, Item* item, Player* playe moveItemList.push_back(newItem); } -void House::handleContainer(ItemList &moveItemList, Item* item) const { +void House::handleContainer(ItemList &moveItemList, std::shared_ptr item) const { if (const auto container = item->getContainer()) { - for (Item* containerItem : container->getItemList()) { + for (std::shared_ptr containerItem : container->getItemList()) { moveItemList.push_back(containerItem); } } @@ -292,7 +360,7 @@ bool House::getAccessList(uint32_t listId, std::string &list) const { return true; } - Door* door = getDoorByNumber(listId); + std::shared_ptr door = getDoorByNumber(listId); if (!door) { return false; } @@ -300,37 +368,35 @@ bool House::getAccessList(uint32_t listId, std::string &list) const { return door->getAccessList(list); } -bool House::isInvited(const Player* player) { +bool House::isInvited(std::shared_ptr player) { return getHouseAccessLevel(player) != HOUSE_NOT_INVITED; } -void House::addDoor(Door* door) { - door->incrementReferenceCounter(); +void House::addDoor(std::shared_ptr door) { doorList.push_back(door); - door->setHouse(this); + door->setHouse(static_self_cast()); updateDoorDescription(); } -void House::removeDoor(Door* door) { +void House::removeDoor(std::shared_ptr door) { auto it = std::find(doorList.begin(), doorList.end(), door); if (it != doorList.end()) { - door->decrementReferenceCounter(); doorList.erase(it); } } -void House::addBed(BedItem* bed) { +void House::addBed(std::shared_ptr bed) { bedsList.push_back(bed); - bed->setHouse(this); + bed->setHouse(static_self_cast()); } -void House::removeBed(BedItem* bed) { +void House::removeBed(std::shared_ptr bed) { bed->setHouse(nullptr); bedsList.remove(bed); } -Door* House::getDoorByNumber(uint32_t doorId) const { - for (Door* door : doorList) { +std::shared_ptr House::getDoorByNumber(uint32_t doorId) const { + for (std::shared_ptr door : doorList) { if (door->getDoorId() == doorId) { return door; } @@ -338,8 +404,8 @@ Door* House::getDoorByNumber(uint32_t doorId) const { return nullptr; } -Door* House::getDoorByPosition(const Position &pos) { - for (Door* door : doorList) { +std::shared_ptr House::getDoorByPosition(const Position &pos) { + for (std::shared_ptr door : doorList) { if (door->getPosition() == pos) { return door; } @@ -347,7 +413,7 @@ Door* House::getDoorByPosition(const Position &pos) { return nullptr; } -bool House::canEditAccessList(uint32_t listId, const Player* player) { +bool House::canEditAccessList(uint32_t listId, std::shared_ptr player) { switch (getHouseAccessLevel(player)) { case HOUSE_OWNER: return true; @@ -360,31 +426,28 @@ bool House::canEditAccessList(uint32_t listId, const Player* player) { } } -HouseTransferItem* House::getTransferItem() { +std::shared_ptr House::getTransferItem() { if (transferItem != nullptr) { return nullptr; } - transfer_container.setParent(nullptr); - transferItem = HouseTransferItem::createHouseTransferItem(this); - transfer_container.addThing(transferItem); + transfer_container->resetParent(); + transferItem = HouseTransferItem::createHouseTransferItem(static_self_cast()); + transfer_container->addThing(transferItem); return transferItem; } void House::resetTransferItem() { if (transferItem) { - Item* tmpItem = transferItem; + std::shared_ptr tmpItem = transferItem; transferItem = nullptr; - transfer_container.setParent(nullptr); - - transfer_container.removeThing(tmpItem, tmpItem->getItemCount()); - g_game().ReleaseItem(tmpItem); + transfer_container->resetParent(); + transfer_container->removeThing(tmpItem, tmpItem->getItemCount()); } } -HouseTransferItem* HouseTransferItem::createHouseTransferItem(House* house) { - HouseTransferItem* transferItem = new HouseTransferItem(house); - transferItem->incrementReferenceCounter(); +std::shared_ptr HouseTransferItem::createHouseTransferItem(std::shared_ptr house) { + std::shared_ptr transferItem = std::make_shared(house); transferItem->setID(ITEM_DOCUMENT_RO); transferItem->setSubType(1); std::ostringstream ss; @@ -393,13 +456,24 @@ HouseTransferItem* HouseTransferItem::createHouseTransferItem(House* house) { return transferItem; } -void HouseTransferItem::onTradeEvent(TradeEvents_t event, Player* owner) { +void HouseTransferItem::onTradeEvent(TradeEvents_t event, std::shared_ptr owner) { if (event == ON_TRADE_TRANSFER) { if (house) { - house->executeTransfer(this, owner); + auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART); + auto ownershipTransferMessage = " The ownership will be transferred upon server restart."; + auto boughtMessage = fmt::format("You have successfully bought the house.{}", isTransferOnRestart ? ownershipTransferMessage : ""); + auto soldMessage = fmt::format("You have successfully sold your house.{}", isTransferOnRestart ? ownershipTransferMessage : ""); + + owner->sendTextMessage(MESSAGE_EVENT_ADVANCE, boughtMessage); + + auto oldOwner = g_game().getPlayerByGUID(house->getOwner()); + if (oldOwner) { + oldOwner->sendTextMessage(MESSAGE_EVENT_ADVANCE, soldMessage); + } + house->executeTransfer(static_self_cast(), owner); } - g_game().internalRemoveItem(this, 1); + g_game().internalRemoveItem(static_self_cast(), 1); } else if (event == ON_TRADE_CANCEL) { if (house) { house->resetTransferItem(); @@ -407,12 +481,21 @@ void HouseTransferItem::onTradeEvent(TradeEvents_t event, Player* owner) { } } -bool House::executeTransfer(HouseTransferItem* item, Player* newOwner) { +bool House::executeTransfer(std::shared_ptr item, std::shared_ptr newOwner) { if (transferItem != item) { return false; } - setOwner(newOwner->getGUID()); + auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART); + if (isTransferOnRestart) { + if (hasNewOwnerOnStartup) { + return false; + } + + setNewOwnerGuid(newOwner->getGUID(), false); + } else { + setOwner(newOwner->getGUID()); + } transferItem = nullptr; return true; } @@ -459,7 +542,7 @@ void AccessList::parseList(const std::string &list) { } void AccessList::addPlayer(const std::string &name) { - const Player* player = g_game().getPlayerByName(name); + std::shared_ptr player = g_game().getPlayerByName(name); if (player) { playerList.insert(player->getGUID()); } else { @@ -471,7 +554,6 @@ void AccessList::addPlayer(const std::string &name) { } namespace { - std::shared_ptr getGuildByName(const std::string &name) { uint32_t guildId = IOGuild::getGuildIdByName(name); if (guildId == 0) { @@ -485,7 +567,6 @@ namespace { return IOGuild::loadGuild(guildId); } - } void AccessList::addGuild(const std::string &name) { @@ -507,7 +588,7 @@ void AccessList::addGuildRank(const std::string &name, const std::string &guildN } } -bool AccessList::isInList(const Player* player) { +bool AccessList::isInList(std::shared_ptr player) { if (allowEveryone) { return true; } @@ -541,7 +622,7 @@ Attr_ReadValue Door::readAttr(AttrTypes_t attr, PropStream &propStream) { return Item::readAttr(attr, propStream); } -void Door::setHouse(House* newHouse) { +void Door::setHouse(std::shared_ptr newHouse) { if (this->house != nullptr) { return; } @@ -549,11 +630,11 @@ void Door::setHouse(House* newHouse) { this->house = newHouse; if (!accessList) { - accessList.reset(new AccessList()); + accessList = std::make_unique(); } } -bool Door::canUse(const Player* player) { +bool Door::canUse(std::shared_ptr player) { if (!house) { return true; } @@ -567,7 +648,7 @@ bool Door::canUse(const Player* player) { void Door::setAccessList(const std::string &textlist) { if (!accessList) { - accessList.reset(new AccessList()); + accessList = std::make_unique(); } accessList->parseList(textlist); @@ -586,11 +667,11 @@ void Door::onRemoved() { Item::onRemoved(); if (house) { - house->removeDoor(this); + house->removeDoor(static_self_cast()); } } -House* Houses::getHouseByPlayerId(uint32_t playerId) { +std::shared_ptr Houses::getHouseByPlayerId(uint32_t playerId) { for (const auto &it : houseMap) { if (it.second->getOwner() == playerId) { return it.second; @@ -615,7 +696,7 @@ bool Houses::loadHousesXML(const std::string &filename) { int32_t houseId = pugi::cast(houseIdAttribute.value()); - House* house = getHouse(houseId); + std::shared_ptr house = getHouse(houseId); if (!house) { g_logger().error("[Houses::loadHousesXML] - Unknown house, id: {}", houseId); return false; @@ -636,6 +717,7 @@ bool Houses::loadHousesXML(const std::string &filename) { house->setEntryPos(entryPos); house->setRent(pugi::cast(houseNode.attribute("rent").value())); + house->setSize(pugi::cast(houseNode.attribute("size").value())); house->setTownId(pugi::cast(houseNode.attribute("townid").value())); auto maxBedsAttr = houseNode.attribute("beds"); int32_t maxBeds = -1; @@ -656,7 +738,7 @@ void Houses::payHouses(RentPeriod_t rentPeriod) const { time_t currentTime = time(nullptr); for (const auto &it : houseMap) { - House* house = it.second; + std::shared_ptr house = it.second; if (house->getOwner() == 0) { continue; } @@ -667,20 +749,20 @@ void Houses::payHouses(RentPeriod_t rentPeriod) const { } const uint32_t ownerId = house->getOwner(); - const Town* town = g_game().map.towns.getTown(house->getTownId()); + const auto &town = g_game().map.towns.getTown(house->getTownId()); if (!town) { continue; } - Player player(nullptr); - if (!IOLoginData::loadPlayerById(&player, ownerId)) { + std::shared_ptr player = std::make_shared(nullptr); + if (!IOLoginData::loadPlayerById(player, ownerId)) { // Player doesn't exist, reset house owner house->setOwner(0); continue; } - if (player.getBankBalance() >= rent) { - player.setBankBalance(player.getBankBalance() - rent); + if (player->getBankBalance() >= rent) { + player->setBankBalance(player->getBankBalance() - rent); time_t paidUntil = currentTime; switch (rentPeriod) { @@ -705,7 +787,7 @@ void Houses::payHouses(RentPeriod_t rentPeriod) const { if (house->getPayRentWarnings() < 7) { int32_t daysLeft = 7 - house->getPayRentWarnings(); - Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED); + std::shared_ptr letter = Item::CreateItem(ITEM_LETTER_STAMPED); std::string period; switch (rentPeriod) { @@ -730,16 +812,16 @@ void Houses::payHouses(RentPeriod_t rentPeriod) const { } std::ostringstream ss; - ss << "Warning! \nThe " << period << " rent of " << house->getRent() << " gold for your house \"" << house->getName() << "\" is payable. Have it within " << daysLeft << " days or you will lose this house."; + ss << "Warning! \nThe " << period << " rent of " << house->getRent() << " gold for your house \"" << house->getName() << "\" is payable. Have it within " << daysLeft << " days or you will lose static_self_cast() house."; letter->setAttribute(ItemAttribute_t::TEXT, ss.str()); - g_game().internalAddItem(player.getInbox(), letter, INDEX_WHEREEVER, FLAG_NOLIMIT); + g_game().internalAddItem(player->getInbox(), letter, INDEX_WHEREEVER, FLAG_NOLIMIT); house->setPayRentWarnings(house->getPayRentWarnings() + 1); } else { - house->setOwner(0, true, &player); + house->setOwner(0, true, player); } } - IOLoginData::savePlayer(&player); + IOLoginData::savePlayer(player); } } @@ -748,7 +830,7 @@ uint32_t House::getRent() const { } uint32_t House::getPrice() const { - uint32_t sqmPrice = static_cast(g_configManager().getNumber(HOUSE_PRICE_PER_SQM)) * getSize(); - uint32_t rentPrice = static_cast(static_cast(getRent()) * g_configManager().getFloat(HOUSE_PRICE_RENT_MULTIPLIER)); + auto sqmPrice = static_cast(g_configManager().getNumber(HOUSE_PRICE_PER_SQM)) * getSize(); + auto rentPrice = static_cast(static_cast(getRent()) * g_configManager().getFloat(HOUSE_PRICE_RENT_MULTIPLIER)); return sqmPrice + rentPrice; } diff --git a/src/map/house/house.hpp b/src/map/house/house.hpp index 16c24d7ac..845693e30 100644 --- a/src/map/house/house.hpp +++ b/src/map/house/house.hpp @@ -25,7 +25,7 @@ class AccessList { void addGuild(const std::string &name); void addGuildRank(const std::string &name, const std::string &rankName); - bool isInList(const Player* player); + bool isInList(std::shared_ptr player); void getList(std::string &list) const; @@ -44,14 +44,11 @@ class Door final : public Item { Door(const Door &) = delete; Door &operator=(const Door &) = delete; - Door* getDoor() override { - return this; - } - const Door* getDoor() const override { - return this; + std::shared_ptr getDoor() override { + return static_self_cast(); } - House* getHouse() { + std::shared_ptr getHouse() { return house; } @@ -66,7 +63,7 @@ class Door final : public Item { return getAttribute(ItemAttribute_t::DOORID); } - bool canUse(const Player* player); + bool canUse(std::shared_ptr player); void setAccessList(const std::string &textlist); bool getAccessList(std::string &list) const; @@ -74,50 +71,50 @@ class Door final : public Item { void onRemoved() override; private: - void setHouse(House* house); + void setHouse(std::shared_ptr house); - House* house = nullptr; + std::shared_ptr house = nullptr; std::unique_ptr accessList; friend class House; }; -using HouseTileList = std::list; -using HouseBedItemList = std::list; +using HouseTileList = std::list>; +using HouseBedItemList = std::list>; class HouseTransferItem final : public Item { public: - static HouseTransferItem* createHouseTransferItem(House* house); + static std::shared_ptr createHouseTransferItem(std::shared_ptr house); - explicit HouseTransferItem(House* newHouse) : + explicit HouseTransferItem(std::shared_ptr newHouse) : Item(0), house(newHouse) { } - void onTradeEvent(TradeEvents_t event, Player* owner) override; + void onTradeEvent(TradeEvents_t event, std::shared_ptr owner) override; bool canTransform() const override { return false; } private: - House* house; + std::shared_ptr house; }; -class House { +class House : public SharedObject { public: explicit House(uint32_t houseId); - void addTile(HouseTile* tile); + void addTile(std::shared_ptr tile); void updateDoorDescription() const; - bool canEditAccessList(uint32_t listId, const Player* player); + bool canEditAccessList(uint32_t listId, std::shared_ptr player); // listId special = values: // GUEST_LIST = guest list // SUBOWNER_LIST = subowner list void setAccessList(uint32_t listId, const std::string &textlist); bool getAccessList(uint32_t listId, std::string &list) const; - bool isInvited(const Player* player); + bool isInvited(std::shared_ptr player); - AccessHouseLevel_t getHouseAccessLevel(const Player* player); - bool kickPlayer(Player* player, Player* target); + AccessHouseLevel_t getHouseAccessLevel(std::shared_ptr player); + bool kickPlayer(std::shared_ptr player, std::shared_ptr target); void setEntryPos(Position pos) { posEntry = pos; @@ -133,7 +130,23 @@ class House { return houseName; } - void setOwner(uint32_t guid, bool updateDatabase = true, Player* player = nullptr); + /** + * @brief Set the new owner's GUID for the house. + * + * This function updates the new owner's GUID in the database. + * It also sets the `hasNewOwnerOnStartup` flag if the given guid is positive. + * + * @param guid The new owner's GUID. Default value is 0. + * @param serverStartup If set to false, further changes to ownership will be blocked. + * + * @note The guid "0" is used when the player uses the "leavehouse" command, + * indicating that the house is not being transferred to anyone. + * @note The guid "-1" represents the default value and will not execute any actions. + * @note The actual transfer of ownership will occur upon server restart if `serverStartup` is set to false. + */ + void setNewOwnerGuid(int32_t newOwnerGuid, bool serverStartup); + bool tryTransferOwnership(std::shared_ptr player, bool serverStartup); + void setOwner(uint32_t guid, bool updateDatabase = true, std::shared_ptr player = nullptr); uint32_t getOwner() const { return owner; } @@ -145,8 +158,11 @@ class House { return paidUntil; } - size_t getSize() const { - return houseTiles.size(); + void setSize(uint32_t newSize) { + this->size = newSize; + } + uint32_t getSize() const { + return size; } uint32_t getPrice() const; @@ -173,25 +189,25 @@ class House { return id; } - void addDoor(Door* door); - void removeDoor(Door* door); - Door* getDoorByNumber(uint32_t doorId) const; - Door* getDoorByPosition(const Position &pos); + void addDoor(std::shared_ptr door); + void removeDoor(std::shared_ptr door); + std::shared_ptr getDoorByNumber(uint32_t doorId) const; + std::shared_ptr getDoorByPosition(const Position &pos); - HouseTransferItem* getTransferItem(); + std::shared_ptr getTransferItem(); void resetTransferItem(); - bool executeTransfer(HouseTransferItem* item, Player* player); + bool executeTransfer(std::shared_ptr item, std::shared_ptr player); const HouseTileList &getTiles() const { return houseTiles; } - const std::list &getDoors() const { + const std::list> &getDoors() const { return doorList; } - void addBed(BedItem* bed); - void removeBed(BedItem* bed); + void addBed(std::shared_ptr bed); + void removeBed(std::shared_ptr bed); const HouseBedItemList &getBeds() const { return bedsList; } @@ -207,23 +223,30 @@ class House { return maxBeds; } + bool transferToDepot(std::shared_ptr player) const; + + bool hasItemOnTile() const; + bool hasNewOwnership() const; + void setNewOwnership(); + private: bool transferToDepot() const; - bool transferToDepot(Player* player) const; AccessList guestList; AccessList subOwnerList; - Container transfer_container { ITEM_LOCKER }; + std::shared_ptr transfer_container = std::make_shared(ITEM_LOCKER); HouseTileList houseTiles; - std::list doorList; + std::list> doorList; HouseBedItemList bedsList; std::string houseName; std::string ownerName; - HouseTransferItem* transferItem = nullptr; + bool hasNewOwnerOnStartup = false; + + std::shared_ptr transferItem = nullptr; time_t paidUntil = 0; @@ -232,6 +255,7 @@ class House { uint32_t ownerAccountId = 0; uint32_t rentWarnings = 0; uint32_t rent = 0; + uint32_t size = 0; uint32_t townId = 0; uint32_t maxBeds = 4; int32_t bedsCount = -1; @@ -240,36 +264,30 @@ class House { bool isLoaded = false; - void handleContainer(ItemList &moveItemList, Item* item) const; - void handleWrapableItem(ItemList &moveItemList, Item* item, Player* player, HouseTile* houseTile) const; + void handleContainer(ItemList &moveItemList, std::shared_ptr item) const; + void handleWrapableItem(ItemList &moveItemList, std::shared_ptr item, std::shared_ptr player, std::shared_ptr houseTile) const; }; -using HouseMap = std::map; +using HouseMap = std::map>; class Houses { public: Houses() = default; - ~Houses() { - for (const auto &it : houseMap) { - delete it.second; - } - } + ~Houses() = default; // non-copyable Houses(const Houses &) = delete; Houses &operator=(const Houses &) = delete; - House* addHouse(uint32_t id) { + std::shared_ptr addHouse(uint32_t id) { if (auto it = houseMap.find(id); it != houseMap.end()) { return it->second; } - auto house = new House(id); - houseMap[id] = house; - return house; + return houseMap[id] = std::make_shared(id); } - House* getHouse(uint32_t houseId) { + std::shared_ptr getHouse(uint32_t houseId) { auto it = houseMap.find(houseId); if (it == houseMap.end()) { return nullptr; @@ -277,7 +295,7 @@ class Houses { return it->second; } - House* getHouseByPlayerId(uint32_t playerId); + std::shared_ptr getHouseByPlayerId(uint32_t playerId); bool loadHousesXML(const std::string &filename); diff --git a/src/map/house/housetile.cpp b/src/map/house/housetile.cpp index 9a3368e75..f67e16868 100644 --- a/src/map/house/housetile.cpp +++ b/src/map/house/housetile.cpp @@ -15,58 +15,58 @@ #include "map/house/house.hpp" #include "game/game.hpp" -HouseTile::HouseTile(int32_t initX, int32_t initY, int32_t initZ, House* initHouse) : +HouseTile::HouseTile(int32_t initX, int32_t initY, int32_t initZ, std::shared_ptr initHouse) : DynamicTile(initX, initY, initZ), house(initHouse) { } -void HouseTile::addThing(int32_t index, Thing* thing) { +void HouseTile::addThing(int32_t index, std::shared_ptr thing) { Tile::addThing(index, thing); if (!thing || !thing->getParent()) { return; } - if (Item* item = thing->getItem()) { + if (std::shared_ptr item = thing->getItem()) { updateHouse(item); } } -void HouseTile::internalAddThing(uint32_t index, Thing* thing) { +void HouseTile::internalAddThing(uint32_t index, std::shared_ptr thing) { Tile::internalAddThing(index, thing); if (!thing || !thing->getParent()) { return; } - if (Item* item = thing->getItem()) { + if (std::shared_ptr item = thing->getItem()) { updateHouse(item); } } -void HouseTile::updateHouse(Item* item) { - if (item->getParent() != this) { +void HouseTile::updateHouse(std::shared_ptr item) { + if (item->getParent().get() != this) { return; } - Door* door = item->getDoor(); + std::shared_ptr door = item->getDoor(); if (door) { if (door->getDoorId() != 0) { house->addDoor(door); } } else { - BedItem* bed = item->getBed(); + std::shared_ptr bed = item->getBed(); if (bed) { house->addBed(bed); } } } -ReturnValue HouseTile::queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t tileFlags, Creature* actor /* = nullptr*/) const { - if (const Creature* creature = thing.getCreature()) { - if (const Player* player = creature->getPlayer()) { +ReturnValue HouseTile::queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t tileFlags, std::shared_ptr actor /* = nullptr*/) { + if (std::shared_ptr creature = thing->getCreature()) { + if (std::shared_ptr player = creature->getPlayer()) { if (!house->isInvited(player)) { return RETURNVALUE_PLAYERISNOTINVITED; } - } else if (const Monster* monster = creature->getMonster()) { + } else if (std::shared_ptr monster = creature->getMonster()) { if (monster->isSummon()) { if (!house->isInvited(monster->getMaster()->getPlayer())) { return RETURNVALUE_NOTPOSSIBLE; @@ -78,8 +78,8 @@ ReturnValue HouseTile::queryAdd(int32_t index, const Thing &thing, uint32_t coun } } } - } else if (thing.getItem() && actor) { - Player* actorPlayer = actor->getPlayer(); + } else if (thing->getItem() && actor) { + std::shared_ptr actorPlayer = actor->getPlayer(); if (house && (!house->isInvited(actorPlayer) || house->getHouseAccessLevel(actorPlayer) == HOUSE_GUEST) && g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) { return RETURNVALUE_CANNOTTHROW; } @@ -87,12 +87,12 @@ ReturnValue HouseTile::queryAdd(int32_t index, const Thing &thing, uint32_t coun return Tile::queryAdd(index, thing, count, tileFlags, actor); } -Tile* HouseTile::queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &tileFlags) { - if (const Creature* creature = thing.getCreature()) { - if (const Player* player = creature->getPlayer()) { +std::shared_ptr HouseTile::queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &tileFlags) { + if (std::shared_ptr creature = thing->getCreature()) { + if (std::shared_ptr player = creature->getPlayer()) { if (!house->isInvited(player)) { const Position &entryPos = house->getEntryPosition(); - Tile* destTile = g_game().map.getTile(entryPos); + std::shared_ptr destTile = g_game().map.getTile(entryPos); if (!destTile) { g_logger().error("[HouseTile::queryDestination] - " "Entry not correct for house name: {} " @@ -100,7 +100,7 @@ Tile* HouseTile::queryDestination(int32_t &index, const Thing &thing, Item** des house->getName(), house->getId(), entryPos.toString()); destTile = g_game().map.getTile(player->getTemplePosition()); if (!destTile) { - destTile = &(Tile::nullptr_tile); + destTile = Tile::nullptr_tile; } } @@ -114,14 +114,14 @@ Tile* HouseTile::queryDestination(int32_t &index, const Thing &thing, Item** des return Tile::queryDestination(index, thing, destItem, tileFlags); } -ReturnValue HouseTile::queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* actor /*= nullptr*/) const { - const Item* item = thing.getItem(); +ReturnValue HouseTile::queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor /*= nullptr*/) { + std::shared_ptr item = thing->getItem(); if (!item) { return RETURNVALUE_NOTPOSSIBLE; } if (actor && g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) { - Player* actorPlayer = actor->getPlayer(); + std::shared_ptr actorPlayer = actor->getPlayer(); if (house && !house->isInvited(actorPlayer)) { return RETURNVALUE_NOTPOSSIBLE; } else if (house && house->getHouseAccessLevel(actorPlayer) == HOUSE_GUEST) { diff --git a/src/map/house/housetile.hpp b/src/map/house/housetile.hpp index 05aa5ba1a..04da8a4e7 100644 --- a/src/map/house/housetile.hpp +++ b/src/map/house/housetile.hpp @@ -15,24 +15,24 @@ class House; class HouseTile final : public DynamicTile { public: - HouseTile(int32_t x, int32_t y, int32_t z, House* house); + HouseTile(int32_t x, int32_t y, int32_t z, std::shared_ptr house); // cylinder implementations - ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; + ReturnValue queryAdd(int32_t index, const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; - Tile* queryDestination(int32_t &index, const Thing &thing, Item** destItem, uint32_t &flags) override; + std::shared_ptr queryDestination(int32_t &index, const std::shared_ptr &thing, std::shared_ptr* destItem, uint32_t &flags) override; - ReturnValue queryRemove(const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override; + ReturnValue queryRemove(const std::shared_ptr &thing, uint32_t count, uint32_t flags, std::shared_ptr actor = nullptr) override; - void addThing(int32_t index, Thing* thing) override; - void virtual internalAddThing(uint32_t index, Thing* thing) override; + void addThing(int32_t index, std::shared_ptr thing) override; + void virtual internalAddThing(uint32_t index, std::shared_ptr thing) override; - House* getHouse() override { + std::shared_ptr getHouse() override { return house; } private: - void updateHouse(Item* item); + void updateHouse(std::shared_ptr item); - House* house; + std::shared_ptr house; }; diff --git a/src/map/map.cpp b/src/map/map.cpp index b9458a3fb..17e678e73 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -133,13 +133,13 @@ bool Map::save() { return false; } -Tile* Map::getOrCreateTile(uint16_t x, uint16_t y, uint8_t z, bool isDynamic) { +std::shared_ptr Map::getOrCreateTile(uint16_t x, uint16_t y, uint8_t z, bool isDynamic) { auto tile = getTile(x, y, z); if (!tile) { if (isDynamic) { - tile = new DynamicTile(x, y, z); + tile = std::make_shared(x, y, z); } else { - tile = new StaticTile(x, y, z); + tile = std::make_shared(x, y, z); } setTile(x, y, z, tile); @@ -148,7 +148,7 @@ Tile* Map::getOrCreateTile(uint16_t x, uint16_t y, uint8_t z, bool isDynamic) { return tile; } -Tile* Map::getTile(uint16_t x, uint16_t y, uint8_t z) { +std::shared_ptr Map::getTile(uint16_t x, uint16_t y, uint8_t z) { if (z >= MAP_MAX_LAYERS) { return nullptr; } @@ -167,7 +167,7 @@ Tile* Map::getTile(uint16_t x, uint16_t y, uint8_t z) { return tile ? tile : getOrCreateTileFromCache(floor, x, y); } -void Map::setTile(uint16_t x, uint16_t y, uint8_t z, Tile* newTile) { +void Map::setTile(uint16_t x, uint16_t y, uint8_t z, std::shared_ptr newTile) { if (z >= MAP_MAX_LAYERS) { g_logger().error("Attempt to set tile on invalid coordinate: {}", Position(x, y, z).toString()); return; @@ -180,8 +180,8 @@ void Map::setTile(uint16_t x, uint16_t y, uint8_t z, Tile* newTile) { } } -bool Map::placeCreature(const Position ¢erPos, Creature* creature, bool extendedPos /* = false*/, bool forceLogin /* = false*/) { - Monster* monster = creature->getMonster(); +bool Map::placeCreature(const Position ¢erPos, std::shared_ptr creature, bool extendedPos /* = false*/, bool forceLogin /* = false*/) { + auto monster = creature->getMonster(); if (monster) { monster->ignoreFieldDamage = true; } @@ -189,10 +189,10 @@ bool Map::placeCreature(const Position ¢erPos, Creature* creature, bool exte bool foundTile; bool placeInPZ; - Tile* tile = getTile(centerPos.x, centerPos.y, centerPos.z); + std::shared_ptr tile = getTile(centerPos.x, centerPos.y, centerPos.z); if (tile) { placeInPZ = tile->hasFlag(TILESTATE_PROTECTIONZONE); - ReturnValue ret = tile->queryAdd(0, *creature, 1, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREFIELDDAMAGE); + ReturnValue ret = tile->queryAdd(0, creature, 1, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREFIELDDAMAGE); foundTile = forceLogin || ret == RETURNVALUE_NOERROR || ret == RETURNVALUE_PLAYERISNOTINVITED; if (monster) { monster->ignoreFieldDamage = false; @@ -248,7 +248,7 @@ bool Map::placeCreature(const Position ¢erPos, Creature* creature, bool exte monster->ignoreFieldDamage = true; } - if (tile->queryAdd(0, *creature, 1, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREFIELDDAMAGE) == RETURNVALUE_NOERROR) { + if (tile->queryAdd(0, creature, 1, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREFIELDDAMAGE) == RETURNVALUE_NOERROR) { if (!extendedPos || isSightClear(centerPos, tryPos, false)) { foundTile = true; break; @@ -267,9 +267,9 @@ bool Map::placeCreature(const Position ¢erPos, Creature* creature, bool exte int32_t index = 0; uint32_t flags = 0; - Item* toItem = nullptr; + std::shared_ptr toItem = nullptr; - Cylinder* toCylinder = tile->queryDestination(index, *creature, &toItem, flags); + auto toCylinder = tile->queryDestination(index, creature, &toItem, flags); toCylinder->internalAddThing(creature); const Position &dest = toCylinder->getPosition(); @@ -277,29 +277,29 @@ bool Map::placeCreature(const Position ¢erPos, Creature* creature, bool exte return true; } -void Map::moveCreature(Creature &creature, Tile &newTile, bool forceTeleport /* = false*/) { - Tile &oldTile = *creature.getTile(); +void Map::moveCreature(const std::shared_ptr &creature, const std::shared_ptr &newTile, bool forceTeleport /* = false*/) { + auto oldTile = creature->getTile(); - Position oldPos = oldTile.getPosition(); - Position newPos = newTile.getPosition(); + Position oldPos = oldTile->getPosition(); + Position newPos = newTile->getPosition(); - auto fromZones = oldTile.getZones(); - auto toZones = newTile.getZones(); - if (auto ret = g_game().beforeCreatureZoneChange(&creature, fromZones, toZones); ret != RETURNVALUE_NOERROR) { + auto fromZones = oldTile->getZones(); + auto toZones = newTile->getZones(); + if (auto ret = g_game().beforeCreatureZoneChange(creature, fromZones, toZones); ret != RETURNVALUE_NOERROR) { return; } - bool teleport = forceTeleport || !newTile.getGround() || !Position::areInRange<1, 1, 0>(oldPos, newPos); + bool teleport = forceTeleport || !newTile->getGround() || !Position::areInRange<1, 1, 0>(oldPos, newPos); SpectatorHashSet spectators; getSpectators(spectators, oldPos, true); getSpectators(spectators, newPos, true); std::vector oldStackPosVector; - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { - if (tmpPlayer->canSeeCreature(&creature)) { - oldStackPosVector.push_back(oldTile.getClientIndexOfCreature(tmpPlayer, &creature)); + for (std::shared_ptr spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { + if (tmpPlayer->canSeeCreature(creature)) { + oldStackPosVector.push_back(oldTile->getClientIndexOfCreature(tmpPlayer, creature)); } else { oldStackPosVector.push_back(-1); } @@ -307,54 +307,54 @@ void Map::moveCreature(Creature &creature, Tile &newTile, bool forceTeleport /* } // remove the creature - oldTile.removeThing(&creature, 0); + oldTile->removeThing(creature, 0); auto leaf = getQTNode(oldPos.x, oldPos.y); auto new_leaf = getQTNode(newPos.x, newPos.y); // Switch the node ownership if (leaf != new_leaf) { - leaf->removeCreature(&creature); - new_leaf->addCreature(&creature); + leaf->removeCreature(creature); + new_leaf->addCreature(creature); } // add the creature - newTile.addThing(&creature); + newTile->addThing(creature); if (!teleport) { if (oldPos.y > newPos.y) { - creature.setDirection(DIRECTION_NORTH); + creature->setDirection(DIRECTION_NORTH); } else if (oldPos.y < newPos.y) { - creature.setDirection(DIRECTION_SOUTH); + creature->setDirection(DIRECTION_SOUTH); } if (oldPos.x < newPos.x) { - creature.setDirection(DIRECTION_EAST); + creature->setDirection(DIRECTION_EAST); } else if (oldPos.x > newPos.x) { - creature.setDirection(DIRECTION_WEST); + creature->setDirection(DIRECTION_WEST); } } // send to client size_t i = 0; - for (Creature* spectator : spectators) { - if (Player* tmpPlayer = spectator->getPlayer()) { + for (auto spectator : spectators) { + if (auto tmpPlayer = spectator->getPlayer()) { // Use the correct stackpos int32_t stackpos = oldStackPosVector[i++]; if (stackpos != -1) { - tmpPlayer->sendCreatureMove(&creature, newPos, newTile.getStackposOfCreature(tmpPlayer, &creature), oldPos, stackpos, teleport); + tmpPlayer->sendCreatureMove(creature, newPos, newTile->getStackposOfCreature(tmpPlayer, creature), oldPos, stackpos, teleport); } } } // event method - for (Creature* spectator : spectators) { - spectator->onCreatureMove(&creature, &newTile, newPos, &oldTile, oldPos, teleport); + for (std::shared_ptr spectator : spectators) { + spectator->onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport); } - oldTile.postRemoveNotification(&creature, &newTile, 0); - newTile.postAddNotification(&creature, &oldTile, 0); - g_game().afterCreatureZoneChange(&creature, fromZones, toZones); + oldTile->postRemoveNotification(creature, newTile, 0); + newTile->postAddNotification(creature, oldTile, 0); + g_game().afterCreatureZoneChange(creature, fromZones, toZones); } void Map::getSpectatorsInternal(SpectatorHashSet &spectators, const Position ¢erPos, int32_t minRangeX, int32_t maxRangeX, int32_t minRangeY, int32_t maxRangeY, int32_t minRangeZ, int32_t maxRangeZ, bool onlyPlayers) const { @@ -384,8 +384,8 @@ void Map::getSpectatorsInternal(SpectatorHashSet &spectators, const Position &ce leafE = leafS; for (int_fast32_t nx = startx1; nx <= endx2; nx += FLOOR_SIZE) { if (leafE) { - const auto &node_list = (onlyPlayers ? leafE->player_list : leafE->creature_list); - for (Creature* creature : node_list) { + const auto node_list = (onlyPlayers ? leafE->player_list : leafE->creature_list); + for (std::shared_ptr creature : node_list) { const Position &cpos = creature->getPosition(); if (minRangeZ > cpos.z || maxRangeZ < cpos.z) { continue; @@ -452,7 +452,7 @@ void Map::getSpectators(SpectatorHashSet &spectators, const Position ¢erPos, } } else { const SpectatorHashSet &cachedSpectators = it->second; - for (Creature* spectator : cachedSpectators) { + for (std::shared_ptr spectator : cachedSpectators) { if (spectator->getPlayer()) { spectators.insert(spectator); } @@ -567,7 +567,7 @@ bool Map::checkSightLine(const Position &fromPos, const Position &toPos) { start.x += mx; } - const Tile* tile = getTile(start.x, start.y, start.z); + const std::shared_ptr tile = getTile(start.x, start.y, start.z); if (tile && tile->hasProperty(CONST_PROP_BLOCKPROJECTILE)) { return false; } @@ -575,7 +575,7 @@ bool Map::checkSightLine(const Position &fromPos, const Position &toPos) { // now we need to perform a jump between floors to see if everything is clear (literally) while (start.z != destination.z) { - const Tile* tile = getTile(start.x, start.y, start.z); + const std::shared_ptr tile = getTile(start.x, start.y, start.z); if (tile && tile->getThingCount() > 0) { return false; } @@ -595,8 +595,8 @@ bool Map::isSightClear(const Position &fromPos, const Position &toPos, bool floo return checkSightLine(fromPos, toPos) || checkSightLine(toPos, fromPos); } -const Tile* Map::canWalkTo(const Creature &creature, const Position &pos) { - int32_t walkCache = creature.getWalkCache(pos); +std::shared_ptr Map::canWalkTo(const std::shared_ptr &creature, const Position &pos) { + int32_t walkCache = creature->getWalkCache(pos); if (walkCache == 0) { return nullptr; } else if (walkCache == 1) { @@ -604,8 +604,8 @@ const Tile* Map::canWalkTo(const Creature &creature, const Position &pos) { } // used for non-cached tiles - Tile* tile = getTile(pos.x, pos.y, pos.z); - if (creature.getTile() != tile) { + std::shared_ptr tile = getTile(pos.x, pos.y, pos.z); + if (creature->getTile() != tile) { if (!tile || tile->queryAdd(0, creature, 1, FLAG_PATHFINDING | FLAG_IGNOREFIELDDAMAGE) != RETURNVALUE_NOERROR) { return nullptr; } @@ -613,8 +613,8 @@ const Tile* Map::canWalkTo(const Creature &creature, const Position &pos) { return tile; } -bool Map::getPathMatching(const Creature &creature, std::forward_list &dirList, const FrozenPathingConditionCall &pathCondition, const FindPathParams &fpp) { - Position pos = creature.getPosition(); +bool Map::getPathMatching(const std::shared_ptr &creature, std::forward_list &dirList, const FrozenPathingConditionCall &pathCondition, const FindPathParams &fpp) { + Position pos = creature->getPosition(); Position endPos; AStarNodes nodes(pos.x, pos.y); @@ -706,7 +706,7 @@ bool Map::getPathMatching(const Creature &creature, std::forward_list continue; } - const Tile* tile; + std::shared_ptr tile; AStarNode* neighborNode = nodes.getNodeByPosition(pos.x, pos.y); if (neighborNode) { tile = getTile(pos.x, pos.y, pos.z); @@ -732,7 +732,7 @@ bool Map::getPathMatching(const Creature &creature, std::forward_list neighborNode->parent = n; nodes.openNode(neighborNode); } else { - // Does not exist in the open/closed list, create a new node + // Does not exist in the open/closed list, create a std::make_shared neighborNode = nodes.createOpenNode(n, pos.x, pos.y, newf); if (!neighborNode) { if (found) { @@ -880,7 +880,7 @@ bool Map::getPathMatching(const Position &start, std::forward_list &d continue; } - const Tile* tile; + std::shared_ptr tile; AStarNode* neighborNode = nodes.getNodeByPosition(pos.x, pos.y); if (neighborNode) { tile = getTile(pos.x, pos.y, pos.z); @@ -906,7 +906,7 @@ bool Map::getPathMatching(const Position &start, std::forward_list &d neighborNode->parent = n; nodes.openNode(neighborNode); } else { - // Does not exist in the open/closed list, create a new node + // Does not exist in the open/closed list, create a std::make_shared neighborNode = nodes.createOpenNode(n, pos.x, pos.y, newf); if (!neighborNode) { if (found) { @@ -969,7 +969,7 @@ uint32_t Map::clean() { g_game().setGameState(GAME_STATE_MAINTAIN); } - std::vector toRemove; + std::vector> toRemove; for (auto tile : g_game().getTilesToClean()) { if (!tile) { continue; diff --git a/src/map/map.hpp b/src/map/map.hpp index 7e7d3a2f6..0a98fc23a 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -75,13 +75,13 @@ class Map : protected MapCache { * Get a single tile. * \returns A pointer to that tile. */ - Tile* getTile(uint16_t x, uint16_t y, uint8_t z); - Tile* getTile(const Position &pos) { + std::shared_ptr getTile(uint16_t x, uint16_t y, uint8_t z); + std::shared_ptr getTile(const Position &pos) { return getTile(pos.x, pos.y, pos.z); } - Tile* getOrCreateTile(uint16_t x, uint16_t y, uint8_t z, bool isDynamic = false); - Tile* getOrCreateTile(const Position &pos, bool isDynamic = false) { + std::shared_ptr getOrCreateTile(uint16_t x, uint16_t y, uint8_t z, bool isDynamic = false); + std::shared_ptr getOrCreateTile(const Position &pos, bool isDynamic = false) { return getOrCreateTile(pos.x, pos.y, pos.z, isDynamic); } @@ -92,9 +92,9 @@ class Map : protected MapCache { * \param extendedPos If true, the creature will in first-hand be placed 2 tiles away * \param forceLogin If true, placing the creature will not fail becase of obstacles (creatures/chests) */ - bool placeCreature(const Position ¢erPos, Creature* creature, bool extendedPos = false, bool forceLogin = false); + bool placeCreature(const Position ¢erPos, std::shared_ptr creature, bool extendedPos = false, bool forceLogin = false); - void moveCreature(Creature &creature, Tile &newTile, bool forceTeleport = false); + void moveCreature(const std::shared_ptr &creature, const std::shared_ptr &newTile, bool forceTeleport = false); void getSpectators(SpectatorHashSet &spectators, const Position ¢erPos, bool multifloor = false, bool onlyPlayers = false, int32_t minRangeX = 0, int32_t maxRangeX = 0, int32_t minRangeY = 0, int32_t maxRangeY = 0); @@ -122,9 +122,9 @@ class Map : protected MapCache { bool isSightClear(const Position &fromPos, const Position &toPos, bool floorCheck); bool checkSightLine(const Position &fromPos, const Position &toPos); - const Tile* canWalkTo(const Creature &creature, const Position &pos); + std::shared_ptr canWalkTo(const std::shared_ptr &creature, const Position &pos); - bool getPathMatching(const Creature &creature, std::forward_list &dirList, const FrozenPathingConditionCall &pathCondition, const FindPathParams &fpp); + bool getPathMatching(const std::shared_ptr &creature, std::forward_list &dirList, const FrozenPathingConditionCall &pathCondition, const FindPathParams &fpp); bool getPathMatching(const Position &startPos, std::forward_list &dirList, const FrozenPathingConditionCall &pathCondition, const FindPathParams &fpp); @@ -149,8 +149,8 @@ class Map : protected MapCache { /** * Set a single tile. */ - void setTile(uint16_t x, uint16_t y, uint8_t z, Tile* newTile); - void setTile(const Position &pos, Tile* newTile) { + void setTile(uint16_t x, uint16_t y, uint8_t z, std::shared_ptr newTile); + void setTile(const Position &pos, std::shared_ptr newTile) { setTile(pos.x, pos.y, pos.z, newTile); } diff --git a/src/map/mapcache.cpp b/src/map/mapcache.cpp index 7660b7629..dfbbc58c3 100644 --- a/src/map/mapcache.cpp +++ b/src/map/mapcache.cpp @@ -22,14 +22,14 @@ #include "io/iomap.hpp" -static phmap::flat_hash_map items; -static phmap::flat_hash_map tiles; +static phmap::flat_hash_map> items; +static phmap::flat_hash_map> tiles; -BasicItemPtr static_tryGetItemFromCache(const BasicItemPtr &ref) { +std::shared_ptr static_tryGetItemFromCache(const std::shared_ptr &ref) { return ref ? items.try_emplace(ref->hash(), ref).first->second : nullptr; } -BasicTilePtr static_tryGetTileFromCache(const BasicTilePtr &ref) { +std::shared_ptr static_tryGetTileFromCache(const std::shared_ptr &ref) { return ref ? tiles.try_emplace(ref->hash(), ref).first->second : nullptr; } @@ -38,7 +38,7 @@ void MapCache::flush() { tiles.clear(); } -void MapCache::parseItemAttr(const BasicItemPtr &BasicItem, Item* item) { +void MapCache::parseItemAttr(const std::shared_ptr &BasicItem, std::shared_ptr item) { if (BasicItem->charges > 0) { item->setSubType(BasicItem->charges); } @@ -72,7 +72,7 @@ void MapCache::parseItemAttr(const BasicItemPtr &BasicItem, Item* item) { item->setAttribute(ItemAttribute_t::DESCRIPTION, STRING_CACHE[BasicItem.description]);*/ } -Item* MapCache::createItem(const BasicItemPtr &BasicItem, Position position) { +std::shared_ptr MapCache::createItem(const std::shared_ptr &BasicItem, Position position) { auto item = Item::CreateItem(BasicItem->id, position); if (!item) { return nullptr; @@ -100,8 +100,8 @@ Item* MapCache::createItem(const BasicItemPtr &BasicItem, Position position) { return item; } -Tile* MapCache::getOrCreateTileFromCache(const std::unique_ptr &floor, uint16_t x, uint16_t y) { - const auto &cachedTile = floor->getTileCache(x, y); +std::shared_ptr MapCache::getOrCreateTileFromCache(const std::unique_ptr &floor, uint16_t x, uint16_t y) { + const auto cachedTile = floor->getTileCache(x, y); if (!cachedTile) { return floor->getTile(x, y); } @@ -110,15 +110,15 @@ Tile* MapCache::getOrCreateTileFromCache(const std::unique_ptr &floor, ui auto map = static_cast(this); - Tile* tile = nullptr; + std::shared_ptr tile = nullptr; if (cachedTile->isHouse()) { const auto house = map->houses.getHouse(cachedTile->houseId); - tile = new HouseTile(x, y, z, house); - house->addTile(static_cast(tile)); + tile = std::make_shared(x, y, z, house); + house->addTile(std::static_pointer_cast(tile)); } else if (cachedTile->isStatic) { - tile = new StaticTile(x, y, z); + tile = std::make_shared(x, y, z); } else { - tile = new DynamicTile(x, y, z); + tile = std::make_shared(x, y, z); } auto pos = Position(x, y, z); @@ -141,13 +141,13 @@ Tile* MapCache::getOrCreateTileFromCache(const std::unique_ptr &floor, ui return tile; } -void MapCache::setBasicTile(uint16_t x, uint16_t y, uint8_t z, const BasicTilePtr &newTile) { +void MapCache::setBasicTile(uint16_t x, uint16_t y, uint8_t z, const std::shared_ptr &newTile) { if (z >= MAP_MAX_LAYERS) { g_logger().error("Attempt to set tile on invalid coordinate: {}", Position(x, y, z).toString()); return; } - const auto &tile = static_tryGetTileFromCache(newTile); + const auto tile = static_tryGetTileFromCache(newTile); if (const auto leaf = QTreeNode::getLeafStatic(&root, x, y)) { leaf->createFloor(z)->setTileCache(x, y, tile); } else { @@ -155,7 +155,7 @@ void MapCache::setBasicTile(uint16_t x, uint16_t y, uint8_t z, const BasicTilePt } } -BasicItemPtr MapCache::tryReplaceItemFromCache(const BasicItemPtr &ref) { +std::shared_ptr MapCache::tryReplaceItemFromCache(const std::shared_ptr &ref) { return static_tryGetItemFromCache(ref); } @@ -267,14 +267,14 @@ void BasicItem::readAttr(FileStream &stream) { } break; case ATTR_TEXT: { - const auto &str = stream.getString(); + const auto str = stream.getString(); if (!str.empty()) { text = str; } } break; case ATTR_DESC: { - const auto &str = stream.getString(); + const auto str = stream.getString(); // if (!str.empty()) // text = str; } break; diff --git a/src/map/mapcache.hpp b/src/map/mapcache.hpp index 2de994e7b..7dda032b7 100644 --- a/src/map/mapcache.hpp +++ b/src/map/mapcache.hpp @@ -20,10 +20,6 @@ class Item; class Position; class FileStream; -using TilePtr = std::unique_ptr; -using BasicItemPtr = std::shared_ptr; -using BasicTilePtr = std::shared_ptr; - #pragma pack(1) struct BasicItem { std::string text; @@ -39,7 +35,7 @@ struct BasicItem { uint8_t destZ { 0 }; - std::vector items; + std::vector> items; bool unserializeItemNode(FileStream &propStream, uint16_t x, uint16_t y, uint8_t z); void readAttr(FileStream &propStream); @@ -57,8 +53,8 @@ struct BasicItem { }; struct BasicTile { - BasicItemPtr ground { nullptr }; - std::vector items; + std::shared_ptr ground { nullptr }; + std::vector> items; uint32_t flags { 0 }, houseId { 0 }; uint8_t type { TILESTATE_NONE }; @@ -89,19 +85,19 @@ struct Floor { explicit Floor(uint8_t z) : z(z) {}; - Tile* getTile(uint16_t x, uint16_t y) const { - return tiles[x & FLOOR_MASK][y & FLOOR_MASK].first.get(); + std::shared_ptr getTile(uint16_t x, uint16_t y) const { + return tiles[x & FLOOR_MASK][y & FLOOR_MASK].first; } - void setTile(uint16_t x, uint16_t y, Tile* tile) { - tiles[x & FLOOR_MASK][y & FLOOR_MASK].first.reset(tile); + void setTile(uint16_t x, uint16_t y, std::shared_ptr tile) { + tiles[x & FLOOR_MASK][y & FLOOR_MASK].first = tile; } - BasicTilePtr getTileCache(uint16_t x, uint16_t y) const { + std::shared_ptr getTileCache(uint16_t x, uint16_t y) const { return tiles[x & FLOOR_MASK][y & FLOOR_MASK].second; } - void setTileCache(uint16_t x, uint16_t y, const BasicTilePtr &newTile) { + void setTileCache(uint16_t x, uint16_t y, const std::shared_ptr &newTile) { tiles[x & FLOOR_MASK][y & FLOOR_MASK].second = newTile; } @@ -110,7 +106,7 @@ struct Floor { } private: - std::pair tiles[FLOOR_SIZE][FLOOR_SIZE] = {}; + std::pair, std::shared_ptr> tiles[FLOOR_SIZE][FLOOR_SIZE] = {}; uint8_t z { 0 }; }; @@ -118,18 +114,18 @@ class MapCache { public: virtual ~MapCache() = default; - void setBasicTile(uint16_t x, uint16_t y, uint8_t z, const BasicTilePtr &BasicTile); + void setBasicTile(uint16_t x, uint16_t y, uint8_t z, const std::shared_ptr &BasicTile); - BasicItemPtr tryReplaceItemFromCache(const BasicItemPtr &ref); + std::shared_ptr tryReplaceItemFromCache(const std::shared_ptr &ref); void flush(); protected: - Tile* getOrCreateTileFromCache(const std::unique_ptr &floor, uint16_t x, uint16_t y); + std::shared_ptr getOrCreateTileFromCache(const std::unique_ptr &floor, uint16_t x, uint16_t y); QTreeNode root; private: - void parseItemAttr(const BasicItemPtr &BasicItem, Item* item); - Item* createItem(const BasicItemPtr &BasicItem, Position position); + void parseItemAttr(const std::shared_ptr &BasicItem, std::shared_ptr item); + std::shared_ptr createItem(const std::shared_ptr &BasicItem, Position position); }; diff --git a/src/map/town.hpp b/src/map/town.hpp index 8e56308ce..f6ab241b5 100644 --- a/src/map/town.hpp +++ b/src/map/town.hpp @@ -39,26 +39,22 @@ class Town { Position templePosition; }; -using TownMap = std::map; +using TownMap = std::map>; class Towns { public: Towns() = default; - ~Towns() { - for (const auto &it : townMap) { - delete it.second; - } - } + ~Towns() = default; // non-copyable Towns(const Towns &) = delete; Towns &operator=(const Towns &) = delete; - bool addTown(uint32_t townId, Town* town) { + bool addTown(uint32_t townId, const std::shared_ptr &town) { return townMap.emplace(townId, town).second; } - Town* getTown(const std::string &townName) const { + std::shared_ptr getTown(const std::string &townName) const { for (const auto &it : townMap) { if (strcasecmp(townName.c_str(), it.second->getName().c_str()) == 0) { return it.second; @@ -67,7 +63,7 @@ class Towns { return nullptr; } - Town* getTown(uint32_t townId) const { + std::shared_ptr getTown(uint32_t townId) const { auto it = townMap.find(townId); if (it == townMap.end()) { return nullptr; @@ -75,11 +71,10 @@ class Towns { return it->second; } - Town* getOrCreateTown(uint32_t townId) { + std::shared_ptr getOrCreateTown(uint32_t townId) { auto town = getTown(townId); if (!town) { - town = new Town(townId); - addTown(townId, town); + addTown(townId, town = std::make_shared(townId)); } return town; } diff --git a/src/map/utils/astarnodes.cpp b/src/map/utils/astarnodes.cpp index 969a89967..36265dd7f 100644 --- a/src/map/utils/astarnodes.cpp +++ b/src/map/utils/astarnodes.cpp @@ -104,23 +104,23 @@ int_fast32_t AStarNodes::getMapWalkCost(AStarNode* node, const Position &neighbo return MAP_NORMALWALKCOST; } -int_fast32_t AStarNodes::getTileWalkCost(const Creature &creature, const Tile* tile) { +int_fast32_t AStarNodes::getTileWalkCost(const std::shared_ptr &creature, std::shared_ptr tile) { int_fast32_t cost = 0; - if (tile->getTopVisibleCreature(&creature) != nullptr) { + if (tile->getTopVisibleCreature(creature) != nullptr) { // destroy creature cost cost += MAP_NORMALWALKCOST * 3; } - if (const MagicField* field = tile->getFieldItem()) { + if (std::shared_ptr field = tile->getFieldItem()) { CombatType_t combatType = field->getCombatType(); - const Monster* monster = creature.getMonster(); - if (!creature.isImmune(combatType) && !creature.hasCondition(Combat::DamageToConditionType(combatType)) && (monster && !monster->canWalkOnFieldType(combatType))) { + std::shared_ptr monster = creature->getMonster(); + if (!creature->isImmune(combatType) && !creature->hasCondition(Combat::DamageToConditionType(combatType)) && (monster && !monster->canWalkOnFieldType(combatType))) { cost += MAP_NORMALWALKCOST * 18; } /** * Make player try to avoid magic fields, when calculating pathing */ - const Player* player = creature.getPlayer(); + std::shared_ptr player = creature->getPlayer(); if (player && !field->isBlocking() && field->getDamage() != 0) { cost += MAP_NORMALWALKCOST * 18; } diff --git a/src/map/utils/astarnodes.hpp b/src/map/utils/astarnodes.hpp index e7cd421cc..eba694de2 100644 --- a/src/map/utils/astarnodes.hpp +++ b/src/map/utils/astarnodes.hpp @@ -31,7 +31,7 @@ class AStarNodes { AStarNode* getNodeByPosition(uint32_t x, uint32_t y); static int_fast32_t getMapWalkCost(AStarNode* node, const Position &neighborPos, bool preferDiagonal = false); - static int_fast32_t getTileWalkCost(const Creature &creature, const Tile* tile); + static int_fast32_t getTileWalkCost(const std::shared_ptr &creature, std::shared_ptr tile); private: static constexpr int32_t MAX_NODES = 512; diff --git a/src/map/utils/qtreenode.cpp b/src/map/utils/qtreenode.cpp index 5351c0cb1..06cfef62f 100644 --- a/src/map/utils/qtreenode.cpp +++ b/src/map/utils/qtreenode.cpp @@ -71,7 +71,7 @@ QTreeLeafNode* QTreeNode::getBestLeaf(uint32_t x, uint32_t y, uint32_t level) { return tempLeaf; } -void QTreeLeafNode::addCreature(Creature* c) { +void QTreeLeafNode::addCreature(std::shared_ptr c) { creature_list.push_back(c); if (c->getPlayer()) { @@ -79,7 +79,7 @@ void QTreeLeafNode::addCreature(Creature* c) { } } -void QTreeLeafNode::removeCreature(Creature* c) { +void QTreeLeafNode::removeCreature(std::shared_ptr c) { auto iter = std::find(creature_list.begin(), creature_list.end(), c); assert(iter != creature_list.end()); *iter = creature_list.back(); diff --git a/src/map/utils/qtreenode.hpp b/src/map/utils/qtreenode.hpp index 95d3ed189..aefa5fcd2 100644 --- a/src/map/utils/qtreenode.hpp +++ b/src/map/utils/qtreenode.hpp @@ -76,8 +76,8 @@ class QTreeLeafNode final : public QTreeNode { return array[z]; } - void addCreature(Creature* c); - void removeCreature(Creature* c); + void addCreature(std::shared_ptr c); + void removeCreature(std::shared_ptr c); private: static bool newLeaf; @@ -86,8 +86,8 @@ class QTreeLeafNode final : public QTreeNode { std::unique_ptr array[MAP_MAX_LAYERS] = {}; - std::vector creature_list; - std::vector player_list; + std::vector> creature_list; + std::vector> player_list; friend class Map; friend class MapCache; diff --git a/src/server/network/protocol/protocol.cpp b/src/server/network/protocol/protocol.cpp index 735e06c94..895780b3f 100644 --- a/src/server/network/protocol/protocol.cpp +++ b/src/server/network/protocol/protocol.cpp @@ -14,7 +14,11 @@ #include "security/rsa.hpp" #include "game/scheduling/dispatcher.hpp" -Protocol::~Protocol() = default; +Protocol::~Protocol() { + if (compreesionEnabled) { + deflateEnd(defStream.get()); + } +} void Protocol::onSendMessage(const OutputMessage_ptr &msg) { if (!rawMessages) { @@ -205,20 +209,25 @@ uint32_t Protocol::getIP() const { } void Protocol::enableCompression() { + if (compreesionEnabled) { + return; + } + + int32_t compressionLevel = g_configManager().getNumber(COMPRESSION_LEVEL); + if (compressionLevel <= 0) { + return; + } + + defStream = std::make_unique(); + defStream->zalloc = nullptr; + defStream->zfree = nullptr; + defStream->opaque = nullptr; + + compreesionEnabled = deflateInit2(defStream.get(), compressionLevel, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY) == Z_OK; + if (!compreesionEnabled) { - int32_t compressionLevel = g_configManager().getNumber(COMPRESSION_LEVEL); - if (compressionLevel != 0) { - defStream.reset(new z_stream); - defStream->zalloc = Z_NULL; - defStream->zfree = Z_NULL; - defStream->opaque = Z_NULL; - if (deflateInit2(defStream.get(), compressionLevel, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY) != Z_OK) { - defStream.reset(); - g_logger().error("[Protocol::enableCompression()] - Zlib deflateInit2 error: {}", (defStream->msg ? defStream->msg : " unknown error")); - } else { - compreesionEnabled = true; - } - } + defStream.reset(); + g_logger().error("[Protocol::enableCompression()] - Zlib deflateInit2 error: {}", (defStream->msg ? defStream->msg : " unknown error")); } } diff --git a/src/server/network/protocol/protocol.hpp b/src/server/network/protocol/protocol.hpp index f736c8964..b209c3069 100644 --- a/src/server/network/protocol/protocol.hpp +++ b/src/server/network/protocol/protocol.hpp @@ -16,6 +16,7 @@ class Protocol : public std::enable_shared_from_this { public: explicit Protocol(Connection_ptr initConnection) : connectionPtr(initConnection) { } + virtual ~Protocol(); // non-copyable diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index f4b70f31d..ac3d2e979 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -61,7 +61,7 @@ namespace { return totalIterationCount; } - void addOutfitAndMountBytes(NetworkMessage &msg, const Item* item, const CustomAttribute* attribute, const std::string &head, const std::string &body, const std::string &legs, const std::string &feet, bool addAddon = false, bool addByte = false) { + void addOutfitAndMountBytes(NetworkMessage &msg, std::shared_ptr item, const CustomAttribute* attribute, const std::string &head, const std::string &body, const std::string &legs, const std::string &feet, bool addAddon = false, bool addByte = false) { auto look = attribute->getAttribute(); msg.add(look); if (look != 0) { @@ -106,9 +106,9 @@ namespace { * @param msg The network message to which the imbuement damage should be added. * @param player Pointer to the player for whom the imbuement damage should be handled. */ - void handleImbuementDamage(NetworkMessage &msg, Player* player) { + void handleImbuementDamage(NetworkMessage &msg, std::shared_ptr player) { bool imbueDmg = false; - Item* weapon = player->getWeapon(); + std::shared_ptr weapon = player->getWeapon(); if (weapon) { uint8_t slots = Item::items[weapon->getID()].imbuementSlot; if (slots > 0) { @@ -144,7 +144,7 @@ namespace { * * @param[in] player The pointer to the player whose equipped items are considered. */ - void calculateAbsorbValues(Player* player, NetworkMessage &msg, uint8_t &combats) { + void calculateAbsorbValues(std::shared_ptr player, NetworkMessage &msg, uint8_t &combats) { alignas(16) uint16_t damageReduction[COMBAT_COUNT] = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }; for (int32_t slot = CONST_SLOT_FIRST; slot <= CONST_SLOT_LAST; ++slot) { @@ -152,7 +152,7 @@ namespace { continue; } - Item* item = player->getInventoryItem(static_cast(slot)); + std::shared_ptr item = player->getInventoryItem(static_cast(slot)); if (!item) { continue; } @@ -232,7 +232,6 @@ namespace { msg.addString(toStartCaseWithSpace(magic_enum::enum_name(value).data())); } } - } // namespace ProtocolGame::ProtocolGame(Connection_ptr initConnection) : @@ -309,7 +308,7 @@ void ProtocolGame::AddItem(NetworkMessage &msg, uint16_t id, uint8_t count, uint } } -void ProtocolGame::AddItem(NetworkMessage &msg, const Item* item) { +void ProtocolGame::AddItem(NetworkMessage &msg, std::shared_ptr item) { if (!item) { return; } @@ -343,7 +342,7 @@ void ProtocolGame::AddItem(NetworkMessage &msg, const Item* item) { if (it.isContainer()) { uint8_t containerType = 0; - const Container* container = item->getContainer(); + std::shared_ptr container = item->getContainer(); if (container && containerType == 0 && container->getHoldingPlayer() == player) { uint32_t lootFlags = 0; for (auto itt : player->quickLootContainers) { @@ -362,7 +361,7 @@ void ProtocolGame::AddItem(NetworkMessage &msg, const Item* item) { // Quiver ammo count if (container && containerType == 0 && item->isQuiver() && player->getThing(CONST_SLOT_RIGHT) == item) { uint16_t ammoTotal = 0; - for (Item* listItem : container->getItemList()) { + for (std::shared_ptr listItem : container->getItemList()) { if (player->getLevel() >= Item::items[listItem->getID()].minReqLevel) { ammoTotal += listItem->getItemCount(); } @@ -449,7 +448,6 @@ void ProtocolGame::release() { // dispatcher thread if (player && player->client == shared_from_this()) { player->client.reset(); - player->decrementReferenceCounter(); player = nullptr; } @@ -473,13 +471,12 @@ void ProtocolGame::login(const std::string &name, uint32_t accountId, OperatingS } // dispatcher thread - Player* foundPlayer = g_game().getPlayerUniqueLogin(name); + std::shared_ptr foundPlayer = g_game().getPlayerUniqueLogin(name); if (!foundPlayer) { - player = new Player(getThis()); + player = std::make_shared(getThis()); player->setName(name); g_game().addPlayerUniqueLogin(player); - player->incrementReferenceCounter(); player->setID(); if (!IOLoginDataLoad::preLoadPlayer(player, name)) { @@ -600,7 +597,7 @@ void ProtocolGame::login(const std::string &name, uint32_t accountId, OperatingS void ProtocolGame::connect(const std::string &playerName, OperatingSystem_t operatingSystem) { eventConnect = 0; - Player* foundPlayer = g_game().getPlayerUniqueLogin(playerName); + std::shared_ptr foundPlayer = g_game().getPlayerUniqueLogin(playerName); if (!foundPlayer) { disconnectClient("You are already logged in."); return; @@ -613,10 +610,9 @@ void ProtocolGame::connect(const std::string &playerName, OperatingSystem_t oper } player = foundPlayer; - player->incrementReferenceCounter(); g_game().addPlayerUniqueLogin(player); - g_chat().removeUserFromAllChannels(*player); + g_chat().removeUserFromAllChannels(player); player->clearModalWindows(); player->setOperatingSystem(operatingSystem); player->isConnecting = false; @@ -733,7 +729,7 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg) { std::string characterName = msg.getString(); - const Player* foundPlayer = g_game().getPlayerUniqueLogin(characterName); + std::shared_ptr foundPlayer = g_game().getPlayerUniqueLogin(characterName); if (foundPlayer && foundPlayer->client) { foundPlayer->client->disconnectClient("You are already connected through another client. Please use only one client at a time!"); } @@ -1330,13 +1326,13 @@ void ProtocolGame::parseHotkeyEquip(NetworkMessage &msg) { addGameTask(&Game::playerEquipItem, player->getID(), itemId, Item::items[itemId].upgradeClassification > 0, tier); } -void ProtocolGame::GetTileDescription(const Tile* tile, NetworkMessage &msg) { +void ProtocolGame::GetTileDescription(std::shared_ptr tile, NetworkMessage &msg) { if (oldProtocol) { msg.add(0x00); // Env effects } int32_t count; - Item* ground = tile->getGround(); + std::shared_ptr ground = tile->getGround(); if (ground) { AddItem(msg, ground); count = 1; @@ -1362,7 +1358,7 @@ void ProtocolGame::GetTileDescription(const Tile* tile, NetworkMessage &msg) { if (creatures) { bool playerAdded = false; for (auto it = creatures->rbegin(); it != creatures->rend(); ++it) { - const Creature* creature = *it; + std::shared_ptr creature = *it; if (!player->canSeeCreature(creature)) { continue; } @@ -1424,7 +1420,7 @@ void ProtocolGame::GetMapDescription(int32_t x, int32_t y, int32_t z, int32_t wi void ProtocolGame::GetFloorDescription(NetworkMessage &msg, int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, int32_t offset, int32_t &skip) { for (int32_t nx = 0; nx < width; nx++) { for (int32_t ny = 0; ny < height; ny++) { - const Tile* tile = g_game().map.getTile(static_cast(x + nx + offset), static_cast(y + ny + offset), static_cast(z)); + std::shared_ptr tile = g_game().map.getTile(static_cast(x + nx + offset), static_cast(y + ny + offset), static_cast(z)); if (tile) { if (skip >= 0) { msg.addByte(skip); @@ -1458,8 +1454,8 @@ void ProtocolGame::checkCreatureAsKnown(uint32_t id, bool &known, uint32_t &remo continue; } // We need to protect party players from removing - Creature* creature = g_game().getCreatureByID(*it); - if (const Player * checkPlayer; + std::shared_ptr creature = g_game().getCreatureByID(*it); + if (std::shared_ptr checkPlayer; creature && (checkPlayer = creature->getPlayer()) != nullptr) { if (player->getParty() != checkPlayer->getParty() && !canSee(creature)) { removedKnown = *it; @@ -1486,7 +1482,7 @@ void ProtocolGame::checkCreatureAsKnown(uint32_t id, bool &known, uint32_t &remo } } -bool ProtocolGame::canSee(const Creature* c) const { +bool ProtocolGame::canSee(std::shared_ptr c) const { if (!c || !player || c->isRemoved()) { return false; } @@ -1973,7 +1969,7 @@ void ProtocolGame::sendSessionEndInformation(SessionEndInformations information) disconnect(); } -void ProtocolGame::sendItemInspection(uint16_t itemId, uint8_t itemCount, const Item* item, bool cyclopedia) { +void ProtocolGame::sendItemInspection(uint16_t itemId, uint8_t itemCount, std::shared_ptr item, bool cyclopedia) { if (oldProtocol) { return; } @@ -2096,7 +2092,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; if (vocation.getFromVocation() == static_cast(vocation.getId())) { @@ -2370,7 +2366,7 @@ void ProtocolGame::parseCyclopediaMonsterTracker(NetworkMessage &msg) { } // Bestiary tracker logic - const auto &bestiaryMonsters = g_game().getBestiaryList(); + const auto bestiaryMonsters = g_game().getBestiaryList(); auto it = bestiaryMonsters.find(monsterRaceId); if (it != bestiaryMonsters.end()) { const auto mtype = g_monsters().getMonsterType(it->second); @@ -2395,15 +2391,15 @@ void ProtocolGame::sendTeamFinderList() { NetworkMessage msg; msg.addByte(0x2D); msg.addByte(0x00); // Bool value, with 'true' the player exceed packets for second. - std::map teamFinder = g_game().getTeamFinderList(); + const auto &teamFinder = g_game().getTeamFinderList(); msg.add(teamFinder.size()); - for (auto it : teamFinder) { - const Player* leader = g_game().getPlayerByGUID(it.first); + for (const auto &it : teamFinder) { + const auto &leader = g_game().getPlayerByGUID(it.first); if (!leader) { return; } - TeamFinder* teamAssemble = it.second; + const auto &teamAssemble = it.second; if (!teamAssemble) { return; } @@ -2417,7 +2413,7 @@ void ProtocolGame::sendTeamFinderList() { msg.addByte(teamAssemble->vocationIDs); msg.add(teamAssemble->teamSlots); for (auto itt : teamAssemble->membersMap) { - const Player* member = g_game().getPlayerByGUID(it.first); + std::shared_ptr member = g_game().getPlayerByGUID(it.first); if (member) { if (itt.first == player->getGUID()) { status = itt.second; @@ -2462,13 +2458,7 @@ void ProtocolGame::sendLeaderTeamFinder(bool reset) { return; } - TeamFinder* teamAssemble = nullptr; - std::map teamFinder = g_game().getTeamFinderList(); - auto it = teamFinder.find(player->getGUID()); - if (it != teamFinder.end()) { - teamAssemble = it->second; - } - + const auto &teamAssemble = g_game().getTeamFinder(player); if (!teamAssemble) { return; } @@ -2480,6 +2470,7 @@ void ProtocolGame::sendLeaderTeamFinder(bool reset) { g_game().removeTeamFinderListed(player->getGUID()); return; } + msg.add(teamAssemble->minLevel); msg.add(teamAssemble->maxLevel); msg.addByte(teamAssemble->vocationIDs); @@ -2509,14 +2500,14 @@ void ProtocolGame::sendLeaderTeamFinder(bool reset) { uint16_t membersSize = 1; for (auto memberPair : teamAssemble->membersMap) { - const Player* member = g_game().getPlayerByGUID(memberPair.first); + std::shared_ptr member = g_game().getPlayerByGUID(memberPair.first); if (member) { membersSize += 1; } } msg.add(membersSize); - const Player* leader = g_game().getPlayerByGUID(teamAssemble->leaderGuid); + std::shared_ptr leader = g_game().getPlayerByGUID(teamAssemble->leaderGuid); if (!leader) { return; } @@ -2528,7 +2519,7 @@ void ProtocolGame::sendLeaderTeamFinder(bool reset) { msg.addByte(3); for (auto memberPair : teamAssemble->membersMap) { - const Player* member = g_game().getPlayerByGUID(memberPair.first); + std::shared_ptr member = g_game().getPlayerByGUID(memberPair.first); if (!member) { continue; } @@ -2547,19 +2538,7 @@ void ProtocolGame::createLeaderTeamFinder(NetworkMessage &msg) { return; } - std::map members; - std::map teamFinder = g_game().getTeamFinderList(); - TeamFinder* teamAssemble = nullptr; - auto it = teamFinder.find(player->getGUID()); - if (it != teamFinder.end()) { - members = it->second->membersMap; - teamAssemble = it->second; - } - - if (!teamAssemble) { - teamAssemble = new TeamFinder(); - } - + const auto &teamAssemble = g_game().getOrCreateTeamFinder(player); teamAssemble->minLevel = msg.get(); teamAssemble->maxLevel = msg.get(); teamAssemble->vocationIDs = msg.getByte(); @@ -2600,18 +2579,18 @@ void ProtocolGame::createLeaderTeamFinder(NetworkMessage &msg) { teamAssemble->questID = questID; teamAssemble->leaderGuid = player->getGUID(); - if (teamAssemble->partyBool && player->getParty()) { - for (Player* member : player->getParty()->getMembers()) { + auto party = player->getParty(); + if (teamAssemble->partyBool && party) { + for (std::shared_ptr member : party->getMembers()) { if (member && member->getGUID() != player->getGUID()) { - members.insert({ member->getGUID(), 3 }); + teamAssemble->membersMap.insert({ member->getGUID(), 3 }); } } - if (player->getParty()->getLeader()->getGUID() != player->getGUID()) { - members.insert({ player->getParty()->getLeader()->getGUID(), 3 }); + auto partyLeader = party->getLeader(); + if (partyLeader && partyLeader->getGUID() != player->getGUID()) { + teamAssemble->membersMap.insert({ partyLeader->getGUID(), 3 }); } } - teamAssemble->membersMap = members; - g_game().registerTeamFinderAssemble(player->getGUID(), teamAssemble); } void ProtocolGame::parsePartyAnalyzerAction(NetworkMessage &msg) const { @@ -2619,7 +2598,7 @@ void ProtocolGame::parsePartyAnalyzerAction(NetworkMessage &msg) const { return; } - Party* party = player->getParty(); + std::shared_ptr party = player->getParty(); if (!party || !party->getLeader() || party->getLeader()->getID() != player->getID()) { return; } @@ -2658,18 +2637,12 @@ void ProtocolGame::parseLeaderFinderWindow(NetworkMessage &msg) { } case 2: { uint32_t memberID = msg.get(); - const Player* member = g_game().getPlayerByGUID(memberID); + std::shared_ptr member = g_game().getPlayerByGUID(memberID); if (!member) { return; } - std::map teamFinder = g_game().getTeamFinderList(); - TeamFinder* teamAssemble = nullptr; - auto it = teamFinder.find(player->getGUID()); - if (it != teamFinder.end()) { - teamAssemble = it->second; - } - + const auto &teamAssemble = g_game().getTeamFinder(player); if (!teamAssemble) { return; } @@ -2722,18 +2695,12 @@ void ProtocolGame::parseMemberFinderWindow(NetworkMessage &msg) { player->sendTeamFinderList(); } else { uint32_t leaderID = msg.get(); - const Player* leader = g_game().getPlayerByGUID(leaderID); + std::shared_ptr leader = g_game().getPlayerByGUID(leaderID); if (!leader) { return; } - std::map teamFinder = g_game().getTeamFinderList(); - TeamFinder* teamAssemble = nullptr; - auto it = teamFinder.find(leaderID); - if (it != teamFinder.end()) { - teamAssemble = it->second; - } - + const auto &teamAssemble = g_game().getTeamFinder(player); if (!teamAssemble) { return; } @@ -2775,7 +2742,7 @@ void ProtocolGame::refreshCyclopediaMonsterTracker(const phmap::parallel_flat_ha msg.addByte(trackerSet.size()); for (const auto mtype : trackerSet) { auto raceId = mtype->info.raceid; - const auto &stages = g_ioBosstiary().getBossRaceKillStages(mtype->info.bosstiaryRace); + const auto stages = g_ioBosstiary().getBossRaceKillStages(mtype->info.bosstiaryRace); if (isBoss && (stages.empty() || stages.size() != 3)) { return; } @@ -3142,7 +3109,7 @@ void ProtocolGame::sendChannelEvent(uint16_t channelId, const std::string &playe writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureOutfit(const Creature* creature, const Outfit_t &outfit) { +void ProtocolGame::sendCreatureOutfit(std::shared_ptr creature, const Outfit_t &outfit) { if (!canSee(creature)) { return; } @@ -3160,7 +3127,7 @@ void ProtocolGame::sendCreatureOutfit(const Creature* creature, const Outfit_t & writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureLight(const Creature* creature) { +void ProtocolGame::sendCreatureLight(std::shared_ptr creature) { if (!canSee(creature)) { return; } @@ -3170,7 +3137,7 @@ void ProtocolGame::sendCreatureLight(const Creature* creature) { writeToOutputBuffer(msg); } -void ProtocolGame::addCreatureIcon(NetworkMessage &msg, const Creature* creature) { +void ProtocolGame::addCreatureIcon(NetworkMessage &msg, std::shared_ptr creature) { if (!creature || !player || oldProtocol) { return; } @@ -3180,14 +3147,14 @@ void ProtocolGame::addCreatureIcon(NetworkMessage &msg, const Creature* creature const auto count = icons.size() > 3 ? 3 : icons.size(); msg.addByte(count); for (uint8_t i = 0; i < count; ++i) { - const auto &icon = icons[i]; + const auto icon = icons[i]; msg.addByte(icon.serialize()); msg.addByte(static_cast(icon.category)); msg.add(icon.count); } } -void ProtocolGame::sendCreatureIcon(const Creature* creature) { +void ProtocolGame::sendCreatureIcon(std::shared_ptr creature) { if (!creature || !player || oldProtocol) { return; } @@ -3219,7 +3186,7 @@ void ProtocolGame::sendTibiaTime(int32_t time) { writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureWalkthrough(const Creature* creature, bool walkthrough) { +void ProtocolGame::sendCreatureWalkthrough(std::shared_ptr creature, bool walkthrough) { if (!canSee(creature)) { return; } @@ -3231,7 +3198,7 @@ void ProtocolGame::sendCreatureWalkthrough(const Creature* creature, bool walkth writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureShield(const Creature* creature) { +void ProtocolGame::sendCreatureShield(std::shared_ptr creature) { if (!canSee(creature)) { return; } @@ -3243,7 +3210,7 @@ void ProtocolGame::sendCreatureShield(const Creature* creature) { writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureEmblem(const Creature* creature) { +void ProtocolGame::sendCreatureEmblem(std::shared_ptr creature) { if (!creature || !canSee(creature) || oldProtocol) { return; } @@ -3265,7 +3232,7 @@ void ProtocolGame::sendCreatureEmblem(const Creature* creature) { writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureSkull(const Creature* creature) { +void ProtocolGame::sendCreatureSkull(std::shared_ptr creature) { if (g_game().getWorldType() != WORLD_TYPE_PVP) { return; } @@ -3281,7 +3248,7 @@ void ProtocolGame::sendCreatureSkull(const Creature* creature) { writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureType(const Creature* creature, uint8_t creatureType) { +void ProtocolGame::sendCreatureType(std::shared_ptr creature, uint8_t creatureType) { NetworkMessage msg; msg.addByte(0x95); msg.add(creature->getID()); @@ -3290,7 +3257,7 @@ void ProtocolGame::sendCreatureType(const Creature* creature, uint8_t creatureTy } msg.addByte(creatureType); // type or any byte idk if (!oldProtocol && creatureType == CREATURETYPE_SUMMON_PLAYER) { - const Creature* master = creature->getMaster(); + std::shared_ptr master = creature->getMaster(); if (master) { msg.add(master->getID()); } else { @@ -3301,7 +3268,7 @@ void ProtocolGame::sendCreatureType(const Creature* creature, uint8_t creatureTy writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureSquare(const Creature* creature, SquareColor_t color) { +void ProtocolGame::sendCreatureSquare(std::shared_ptr creature, SquareColor_t color) { if (!canSee(creature)) { return; } @@ -3395,7 +3362,7 @@ void ProtocolGame::sendCyclopediaCharacterGeneralStats() { msg.addByte(player->getSoul()); msg.add(player->getStaminaMinutes()); - Condition* condition = player->getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT); + std::shared_ptr condition = player->getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT); msg.add(condition ? condition->getTicks() / 1000 : 0x00); msg.add(player->getOfflineTrainingTime() / 60 / 1000); msg.add(player->getSpeed()); @@ -3485,7 +3452,7 @@ void ProtocolGame::sendCyclopediaCharacterCombatStats() { msg.addByte(haveBlesses); msg.addByte(blessings); - const Item* weapon = player->getWeapon(); + std::shared_ptr weapon = player->getWeapon(); if (weapon) { const ItemType &it = Item::items[weapon->getID()]; if (it.weaponType == WEAPON_WAND) { @@ -3496,7 +3463,7 @@ void ProtocolGame::sendCyclopediaCharacterCombatStats() { } else if (it.weaponType == WEAPON_DISTANCE || it.weaponType == WEAPON_AMMO || it.weaponType == WEAPON_MISSILE) { int32_t attackValue = weapon->getAttack(); if (it.weaponType == WEAPON_AMMO) { - const Item* weaponItem = player->getWeapon(true); + std::shared_ptr weaponItem = player->getWeapon(true); if (weaponItem) { attackValue += weaponItem->getAttack(); } @@ -3676,7 +3643,7 @@ void ProtocolGame::sendCyclopediaCharacterOutfitsMounts() { auto startOutfits = msg.getBufferPosition(); msg.skipBytes(2); - const auto &outfits = Outfits::getInstance().getOutfits(player->getSex()); + const auto outfits = Outfits::getInstance().getOutfits(player->getSex()); for (const auto &outfit : outfits) { uint8_t addons; if (!player->getOutfitAddons(outfit, addons)) { @@ -3738,7 +3705,7 @@ void ProtocolGame::sendCyclopediaCharacterOutfitsMounts() { uint16_t familiarsSize = 0; auto startFamiliars = msg.getBufferPosition(); msg.skipBytes(2); - const auto &familiars = Familiars::getInstance().getFamiliars(player->getVocationId()); + const auto familiars = Familiars::getInstance().getFamiliars(player->getVocationId()); for (const Familiar &familiar : familiars) { const std::string type = familiar.type; if (!player->getFamiliar(familiar)) { @@ -3802,7 +3769,7 @@ void ProtocolGame::sendCyclopediaCharacterInspection() { auto startInventory = msg.getBufferPosition(); msg.skipBytes(1); for (std::underlying_type::type slot = CONST_SLOT_FIRST; slot <= CONST_SLOT_LAST; slot++) { - Item* inventoryItem = player->getInventoryItem(static_cast(slot)); + std::shared_ptr inventoryItem = player->getInventoryItem(static_cast(slot)); if (inventoryItem) { ++inventoryItems; @@ -3847,7 +3814,7 @@ void ProtocolGame::sendCyclopediaCharacterInspection() { // Outfit description playerDescriptionSize++; msg.addString("Outfit"); - if (const auto &outfit = Outfits::getInstance().getOutfitByLookType(player->getSex(), player->getDefaultOutfit().lookType)) { + if (const auto outfit = Outfits::getInstance().getOutfitByLookType(player->getSex(), player->getDefaultOutfit().lookType)) { msg.addString(outfit->name); } else { msg.addString("unknown"); @@ -4152,7 +4119,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) { msg.add(channel->getId()); @@ -4226,7 +4193,7 @@ void ProtocolGame::sendUnjustifiedPoints(const uint8_t &dayProgress, const uint8 writeToOutputBuffer(msg); } -void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool hasParent, uint16_t firstIndex) { +void ProtocolGame::sendContainer(uint8_t cid, std::shared_ptr container, bool hasParent, uint16_t firstIndex) { if (!player) { return; } @@ -4311,7 +4278,7 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h } if (!toSendCategory) { - Container* container = player->getContainerByID(cid); + std::shared_ptr container = player->getContainerByID(cid); if (container) { container->removeAttribute(ItemAttribute_t::STORE_INBOX_CATEGORY); } @@ -4336,7 +4303,7 @@ void ProtocolGame::sendLootContainers() { NetworkMessage msg; msg.addByte(0xC0); msg.addByte(player->quickLootFallbackToMainContainer ? 1 : 0); - std::map quickLoot; + std::map> quickLoot; for (auto it : player->quickLootContainers) { if (it.second && !it.second->isRemoved()) { quickLoot[it.first] = it.second; @@ -4351,7 +4318,7 @@ void ProtocolGame::sendLootContainers() { writeToOutputBuffer(msg); } -void ProtocolGame::sendLootStats(Item* item, uint8_t count) { +void ProtocolGame::sendLootStats(std::shared_ptr item, uint8_t count) { if (!item) { return; } @@ -4361,7 +4328,7 @@ void ProtocolGame::sendLootStats(Item* item, uint8_t count) { return; } - Item* lootedItem = nullptr; + std::shared_ptr lootedItem = nullptr; lootedItem = item->clone(); lootedItem->setItemCount(count); @@ -4375,7 +4342,7 @@ void ProtocolGame::sendLootStats(Item* item, uint8_t count) { lootedItem = nullptr; } -void ProtocolGame::sendShop(Npc* npc) { +void ProtocolGame::sendShop(std::shared_ptr npc) { NetworkMessage msg; msg.addByte(0x7A); msg.addString(npc->getName()); @@ -4532,7 +4499,7 @@ void ProtocolGame::sendMarketEnter(uint32_t depotId) { msg.addByte(static_cast(std::min(IOMarket::getPlayerOfferCount(player->getGUID()), std::numeric_limits::max()))); - DepotLocker* depotLocker = player->getDepotLocker(depotId); + std::shared_ptr depotLocker = player->getDepotLocker(depotId); if (!depotLocker) { msg.add(0x00); writeToOutputBuffer(msg); @@ -4600,19 +4567,20 @@ void ProtocolGame::updateCoinBalance() { } g_dispatcher().addTask( - std::bind([](uint32_t playerId) { - Player* threadPlayer = g_game().getPlayerByID(playerId); - if (threadPlayer && threadPlayer->getAccount()) { - - auto [coins, errCoin] = threadPlayer->getAccount()->getCoins(account::CoinType::COIN); - auto [transferCoins, errTCoin] = threadPlayer->getAccount()->getCoins(account::CoinType::TRANSFERABLE); - - threadPlayer->coinBalance = coins; - threadPlayer->coinTransferableBalance = transferCoins; - threadPlayer->sendCoinBalance(); - } - }, - player->getID()), + std::bind( + [](uint32_t playerId) { + auto threadPlayer = g_game().getPlayerByID(playerId); + if (threadPlayer && threadPlayer->getAccount()) { + auto [coins, errCoin] = threadPlayer->getAccount()->getCoins(account::CoinType::COIN); + auto [transferCoins, errTCoin] = threadPlayer->getAccount()->getCoins(account::CoinType::TRANSFERABLE); + + threadPlayer->coinBalance = coins; + threadPlayer->coinTransferableBalance = transferCoins; + threadPlayer->sendCoinBalance(); + } + }, + player->getID() + ), "ProtocolGame::updateCoinBalance" ); } @@ -4855,7 +4823,7 @@ void ProtocolGame::sendForgingData() { std::map tierCorePrices; - const auto &classifications = g_game().getItemsClassifications(); + const auto classifications = g_game().getItemsClassifications(); msg.addByte(classifications.size()); for (const auto &classification : classifications) { msg.addByte(classification->id); @@ -5503,7 +5471,7 @@ void ProtocolGame::sendMarketDetail(uint16_t itemId, uint8_t tier) { writeToOutputBuffer(msg); } -void ProtocolGame::sendTradeItemRequest(const std::string &traderName, const Item* item, bool ack) { +void ProtocolGame::sendTradeItemRequest(const std::string &traderName, std::shared_ptr item, bool ack) { NetworkMessage msg; if (ack) { @@ -5514,15 +5482,15 @@ void ProtocolGame::sendTradeItemRequest(const std::string &traderName, const Ite msg.addString(traderName); - if (const Container* tradeContainer = item->getContainer()) { - std::list listContainer { tradeContainer }; - std::list itemList { tradeContainer }; + if (std::shared_ptr tradeContainer = item->getContainer()) { + std::list> listContainer { tradeContainer }; + std::list> itemList { tradeContainer }; while (!listContainer.empty()) { - const Container* container = listContainer.front(); + std::shared_ptr container = listContainer.front(); listContainer.pop_front(); - for (Item* containerItem : container->getItemList()) { - Container* tmpContainer = containerItem->getContainer(); + for (std::shared_ptr containerItem : container->getItemList()) { + std::shared_ptr tmpContainer = containerItem->getContainer(); if (tmpContainer) { listContainer.push_back(tmpContainer); } @@ -5531,7 +5499,7 @@ void ProtocolGame::sendTradeItemRequest(const std::string &traderName, const Ite } msg.addByte(itemList.size()); - for (const Item* listItem : itemList) { + for (std::shared_ptr listItem : itemList) { AddItem(msg, listItem); } } else { @@ -5554,7 +5522,7 @@ void ProtocolGame::sendCloseContainer(uint8_t cid) { writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureTurn(const Creature* creature, uint32_t stackPos) { +void ProtocolGame::sendCreatureTurn(std::shared_ptr creature, uint32_t stackPos) { if (!canSee(creature)) { return; } @@ -5570,7 +5538,7 @@ void ProtocolGame::sendCreatureTurn(const Creature* creature, uint32_t stackPos) writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string &text, const Position* pos /* = nullptr*/) { +void ProtocolGame::sendCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text, const Position* pos /* = nullptr*/) { NetworkMessage msg; msg.addByte(0xAA); @@ -5584,7 +5552,7 @@ void ProtocolGame::sendCreatureSay(const Creature* creature, SpeakClasses type, } // Add level only for players - if (const Player* speaker = creature->getPlayer()) { + if (std::shared_ptr speaker = creature->getPlayer()) { msg.add(speaker->getLevel()); } else { msg.add(0x00); @@ -5606,7 +5574,7 @@ void ProtocolGame::sendCreatureSay(const Creature* creature, SpeakClasses type, writeToOutputBuffer(msg); } -void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, const std::string &text, uint16_t channelId) { +void ProtocolGame::sendToChannel(std::shared_ptr creature, SpeakClasses type, const std::string &text, uint16_t channelId) { NetworkMessage msg; msg.addByte(0xAA); @@ -5630,7 +5598,7 @@ void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, co } // Add level only for players - if (const Player* speaker = creature->getPlayer()) { + if (std::shared_ptr speaker = creature->getPlayer()) { msg.add(speaker->getLevel()); } else { msg.add(0x00); @@ -5648,7 +5616,7 @@ void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, co writeToOutputBuffer(msg); } -void ProtocolGame::sendPrivateMessage(const Player* speaker, SpeakClasses type, const std::string &text) { +void ProtocolGame::sendPrivateMessage(std::shared_ptr speaker, SpeakClasses type, const std::string &text) { NetworkMessage msg; msg.addByte(0xAA); static uint32_t statementId = 0; @@ -5683,7 +5651,7 @@ void ProtocolGame::sendCancelTarget() { writeToOutputBuffer(msg); } -void ProtocolGame::sendChangeSpeed(const Creature* creature, uint16_t speed) { +void ProtocolGame::sendChangeSpeed(std::shared_ptr creature, uint16_t speed) { NetworkMessage msg; msg.addByte(0x8F); msg.add(creature->getID()); @@ -5817,7 +5785,7 @@ void ProtocolGame::removeMagicEffect(const Position &pos, uint16_t type) { writeToOutputBuffer(msg); } -void ProtocolGame::sendCreatureHealth(const Creature* creature) { +void ProtocolGame::sendCreatureHealth(std::shared_ptr creature) { if (creature->isHealthHidden()) { return; } @@ -5834,7 +5802,7 @@ void ProtocolGame::sendCreatureHealth(const Creature* creature) { writeToOutputBuffer(msg); } -void ProtocolGame::sendPartyCreatureUpdate(const Creature* target) { +void ProtocolGame::sendPartyCreatureUpdate(std::shared_ptr target) { if (!player || oldProtocol) { return; } @@ -5852,7 +5820,7 @@ void ProtocolGame::sendPartyCreatureUpdate(const Creature* target) { writeToOutputBuffer(msg); } -void ProtocolGame::sendPartyCreatureShield(const Creature* target) { +void ProtocolGame::sendPartyCreatureShield(std::shared_ptr target) { uint32_t cid = target->getID(); if (knownCreatureSet.find(cid) == knownCreatureSet.end()) { sendPartyCreatureUpdate(target); @@ -5866,7 +5834,7 @@ void ProtocolGame::sendPartyCreatureShield(const Creature* target) { writeToOutputBuffer(msg); } -void ProtocolGame::sendPartyCreatureSkull(const Creature* target) { +void ProtocolGame::sendPartyCreatureSkull(std::shared_ptr target) { if (g_game().getWorldType() != WORLD_TYPE_PVP) { return; } @@ -5884,7 +5852,7 @@ void ProtocolGame::sendPartyCreatureSkull(const Creature* target) { writeToOutputBuffer(msg); } -void ProtocolGame::sendPartyCreatureHealth(const Creature* target, uint8_t healthPercent) { +void ProtocolGame::sendPartyCreatureHealth(std::shared_ptr target, uint8_t healthPercent) { uint32_t cid = target->getID(); if (knownCreatureSet.find(cid) == knownCreatureSet.end()) { sendPartyCreatureUpdate(target); @@ -5898,7 +5866,7 @@ void ProtocolGame::sendPartyCreatureHealth(const Creature* target, uint8_t healt writeToOutputBuffer(msg); } -void ProtocolGame::sendPartyPlayerMana(const Player* target, uint8_t manaPercent) { +void ProtocolGame::sendPartyPlayerMana(std::shared_ptr target, uint8_t manaPercent) { uint32_t cid = target->getID(); if (knownCreatureSet.find(cid) == knownCreatureSet.end()) { sendPartyCreatureUpdate(target); @@ -5916,7 +5884,7 @@ void ProtocolGame::sendPartyPlayerMana(const Player* target, uint8_t manaPercent writeToOutputBuffer(msg); } -void ProtocolGame::sendPartyCreatureShowStatus(const Creature* target, bool showStatus) { +void ProtocolGame::sendPartyCreatureShowStatus(std::shared_ptr target, bool showStatus) { uint32_t cid = target->getID(); if (knownCreatureSet.find(cid) == knownCreatureSet.end()) { sendPartyCreatureUpdate(target); @@ -5934,7 +5902,7 @@ void ProtocolGame::sendPartyCreatureShowStatus(const Creature* target, bool show writeToOutputBuffer(msg); } -void ProtocolGame::sendPartyPlayerVocation(const Player* target) { +void ProtocolGame::sendPartyPlayerVocation(std::shared_ptr target) { uint32_t cid = target->getID(); if (knownCreatureSet.find(cid) == knownCreatureSet.end()) { sendPartyCreatureUpdate(target); @@ -5953,7 +5921,7 @@ void ProtocolGame::sendPartyPlayerVocation(const Player* target) { writeToOutputBuffer(msg); } -void ProtocolGame::sendPlayerVocation(const Player* target) { +void ProtocolGame::sendPlayerVocation(std::shared_ptr target) { if (!player || oldProtocol) { return; } @@ -5982,7 +5950,7 @@ void ProtocolGame::sendMapDescription(const Position &pos) { writeToOutputBuffer(msg); } -void ProtocolGame::sendAddTileItem(const Position &pos, uint32_t stackpos, const Item* item) { +void ProtocolGame::sendAddTileItem(const Position &pos, uint32_t stackpos, std::shared_ptr item) { if (!canSee(pos)) { return; } @@ -5995,7 +5963,7 @@ void ProtocolGame::sendAddTileItem(const Position &pos, uint32_t stackpos, const writeToOutputBuffer(msg); } -void ProtocolGame::sendUpdateTileItem(const Position &pos, uint32_t stackpos, const Item* item) { +void ProtocolGame::sendUpdateTileItem(const Position &pos, uint32_t stackpos, std::shared_ptr item) { if (!canSee(pos)) { return; } @@ -6018,7 +5986,7 @@ void ProtocolGame::sendRemoveTileThing(const Position &pos, uint32_t stackpos) { writeToOutputBuffer(msg); } -void ProtocolGame::sendUpdateTile(const Tile* tile, const Position &pos) { +void ProtocolGame::sendUpdateTile(std::shared_ptr tile, const Position &pos) { if (!canSee(pos)) { return; } @@ -6080,7 +6048,7 @@ void ProtocolGame::sendAllowBugReport() { writeToOutputBuffer(msg); } -void ProtocolGame::sendAddCreature(const Creature* creature, const Position &pos, int32_t stackpos, bool isLogin) { +void ProtocolGame::sendAddCreature(std::shared_ptr creature, const Position &pos, int32_t stackpos, bool isLogin) { if (!canSee(pos)) { return; } @@ -6102,7 +6070,7 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position &pos writeToOutputBuffer(msg); if (isLogin) { - if (const Player* creaturePlayer = creature->getPlayer()) { + if (std::shared_ptr creaturePlayer = creature->getPlayer()) { if (!creaturePlayer->isAccessPlayer() || creaturePlayer->getAccountType() == account::ACCOUNT_TYPE_NORMAL) { sendMagicEffect(pos, CONST_ME_TELEPORT); } @@ -6184,7 +6152,7 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position &pos for (const VIPEntry &entry : vipEntries) { VipStatus_t vipStatus; - const Player* vipPlayer = g_game().getPlayerByGUID(entry.guid); + std::shared_ptr vipPlayer = g_game().getPlayerByGUID(entry.guid); if (!vipPlayer) { vipStatus = VIPSTATUS_OFFLINE; } else { @@ -6197,7 +6165,7 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position &pos for (const VIPEntry &entry : vipEntries) { VipStatus_t vipStatus; - const Player* vipPlayer = g_game().getPlayerByGUID(entry.guid); + std::shared_ptr vipPlayer = g_game().getPlayerByGUID(entry.guid); if (!vipPlayer || vipPlayer->isInGhostMode()) { vipStatus = VIPSTATUS_OFFLINE; } else { @@ -6209,10 +6177,10 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position &pos } sendInventoryIds(); - Item* slotItem = player->getInventoryItem(CONST_SLOT_BACKPACK); + std::shared_ptr slotItem = player->getInventoryItem(CONST_SLOT_BACKPACK); if (slotItem) { - Container* mainBackpack = slotItem->getContainer(); - Container* hasQuickLootContainer = player->getLootContainer(OBJECTCATEGORY_DEFAULT); + std::shared_ptr mainBackpack = slotItem->getContainer(); + std::shared_ptr hasQuickLootContainer = player->getLootContainer(OBJECTCATEGORY_DEFAULT); if (mainBackpack && !hasQuickLootContainer) { player->setLootContainer(OBJECTCATEGORY_DEFAULT, mainBackpack); sendInventoryItem(CONST_SLOT_BACKPACK, player->getInventoryItem(CONST_SLOT_BACKPACK)); @@ -6236,7 +6204,7 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position &pos } } -void ProtocolGame::sendMoveCreature(const Creature* creature, const Position &newPos, int32_t newStackPos, const Position &oldPos, int32_t oldStackPos, bool teleport) { +void ProtocolGame::sendMoveCreature(std::shared_ptr creature, const Position &newPos, int32_t newStackPos, const Position &oldPos, int32_t oldStackPos, bool teleport) { if (creature == player) { if (oldStackPos >= 10) { sendMapDescription(newPos); @@ -6298,7 +6266,7 @@ void ProtocolGame::sendMoveCreature(const Creature* creature, const Position &ne } } -void ProtocolGame::sendInventoryItem(Slots_t slot, const Item* item) { +void ProtocolGame::sendInventoryItem(Slots_t slot, std::shared_ptr item) { NetworkMessage msg; if (item) { msg.addByte(0x78); @@ -6340,7 +6308,7 @@ void ProtocolGame::sendInventoryIds() { writeToOutputBuffer(msg); } -void ProtocolGame::sendAddContainerItem(uint8_t cid, uint16_t slot, const Item* item) { +void ProtocolGame::sendAddContainerItem(uint8_t cid, uint16_t slot, std::shared_ptr item) { NetworkMessage msg; msg.addByte(0x70); msg.addByte(cid); @@ -6349,7 +6317,7 @@ void ProtocolGame::sendAddContainerItem(uint8_t cid, uint16_t slot, const Item* writeToOutputBuffer(msg); } -void ProtocolGame::sendUpdateContainerItem(uint8_t cid, uint16_t slot, const Item* item) { +void ProtocolGame::sendUpdateContainerItem(uint8_t cid, uint16_t slot, std::shared_ptr item) { NetworkMessage msg; msg.addByte(0x71); msg.addByte(cid); @@ -6358,7 +6326,7 @@ void ProtocolGame::sendUpdateContainerItem(uint8_t cid, uint16_t slot, const Ite writeToOutputBuffer(msg); } -void ProtocolGame::sendRemoveContainerItem(uint8_t cid, uint16_t slot, const Item* lastItem) { +void ProtocolGame::sendRemoveContainerItem(uint8_t cid, uint16_t slot, std::shared_ptr lastItem) { NetworkMessage msg; msg.addByte(0x72); msg.addByte(cid); @@ -6371,7 +6339,7 @@ void ProtocolGame::sendRemoveContainerItem(uint8_t cid, uint16_t slot, const Ite writeToOutputBuffer(msg); } -void ProtocolGame::sendTextWindow(uint32_t windowTextId, Item* item, uint16_t maxlen, bool canWrite) { +void ProtocolGame::sendTextWindow(uint32_t windowTextId, std::shared_ptr item, uint16_t maxlen, bool canWrite) { NetworkMessage msg; msg.addByte(0x96); msg.add(windowTextId); @@ -6458,7 +6426,7 @@ void ProtocolGame::sendOutfitWindow() { protocolOutfits.emplace_back(communityManager, 302, 0); } - const auto &outfits = Outfits::getInstance().getOutfits(player->getSex()); + const auto outfits = Outfits::getInstance().getOutfits(player->getSex()); protocolOutfits.reserve(outfits.size()); for (const auto &outfit : outfits) { uint8_t addons; @@ -6539,7 +6507,7 @@ void ProtocolGame::sendOutfitWindow() { ++outfitSize; } - const auto &outfits = Outfits::getInstance().getOutfits(player->getSex()); + const auto outfits = Outfits::getInstance().getOutfits(player->getSex()); for (const auto &outfit : outfits) { uint8_t addons; @@ -6615,7 +6583,7 @@ void ProtocolGame::sendOutfitWindow() { uint16_t familiarSize = 0; msg.skipBytes(2); - const auto &familiars = Familiars::getInstance().getFamiliars(player->getVocationId()); + const auto familiars = Familiars::getInstance().getFamiliars(player->getVocationId()); for (const Familiar &familiar : familiars) { if (!player->getFamiliar(familiar)) { @@ -6644,7 +6612,7 @@ void ProtocolGame::sendOutfitWindow() { writeToOutputBuffer(msg); } -void ProtocolGame::sendPodiumWindow(const Item* podium, const Position &position, uint16_t itemId, uint8_t stackpos) { +void ProtocolGame::sendPodiumWindow(std::shared_ptr podium, const Position &position, uint16_t itemId, uint8_t stackpos) { if (!podium || oldProtocol) { g_logger().error("[{}] item is nullptr", __FUNCTION__); return; @@ -6679,7 +6647,7 @@ void ProtocolGame::sendPodiumWindow(const Item* podium, const Position &position uint16_t outfitSize = 0; msg.skipBytes(2); - const auto &outfits = Outfits::getInstance().getOutfits(player->getSex()); + const auto outfits = Outfits::getInstance().getOutfits(player->getSex()); for (const auto &outfit : outfits) { uint8_t addons; if (!player->getOutfitAddons(outfit, addons)) { @@ -6809,7 +6777,7 @@ void ProtocolGame::sendUseItemCooldown(uint32_t time) { writeToOutputBuffer(msg); } -void ProtocolGame::sendPreyTimeLeft(const PreySlot* slot) { +void ProtocolGame::sendPreyTimeLeft(const std::unique_ptr &slot) { if (!player || !slot) { return; } @@ -6823,24 +6791,31 @@ void ProtocolGame::sendPreyTimeLeft(const PreySlot* slot) { writeToOutputBuffer(msg); } -void ProtocolGame::sendPreyData(const PreySlot* slot) { +void ProtocolGame::sendPreyData(const std::unique_ptr &slot) { if (!player) { return; } + NetworkMessage msg; + msg.addByte(0xE8); std::vector validRaceIds; for (auto raceId : slot->raceIdList) { if (g_monsters().getMonsterTypeByRaceId(raceId)) { validRaceIds.push_back(raceId); } else { g_logger().error("[ProtocolGame::sendPreyData] - Unknown monster type raceid: {}, removing prey slot from player {}", raceId, player->getName()); - g_logger().warn("[ProtocolGame::sendPreyData] - Remove the prey monster from player"); + // Remove wrong raceid from slot + slot->removeMonsterType(raceId); + // Send empty bytes (do not debug client) + msg.addByte(0); + msg.addByte(1); + msg.add(0); + msg.addByte(0); + writeToOutputBuffer(msg); return; } } - NetworkMessage msg; - msg.addByte(0xE8); msg.addByte(static_cast(slot->id)); msg.addByte(static_cast(slot->state)); @@ -6989,9 +6964,9 @@ void ProtocolGame::sendModalWindow(const ModalWindow &modalWindow) { } ////////////// Add common messages -void ProtocolGame::AddCreature(NetworkMessage &msg, const Creature* creature, bool known, uint32_t remove) { +void ProtocolGame::AddCreature(NetworkMessage &msg, std::shared_ptr creature, bool known, uint32_t remove) { CreatureType_t creatureType = creature->getType(); - const Player* otherPlayer = creature->getPlayer(); + std::shared_ptr otherPlayer = creature->getPlayer(); if (known) { msg.add(0x62); @@ -7007,7 +6982,7 @@ void ProtocolGame::AddCreature(NetworkMessage &msg, const Creature* creature, bo } if (!oldProtocol && creatureType == CREATURETYPE_SUMMON_PLAYER) { - if (const Creature* master = creature->getMaster()) { + if (std::shared_ptr master = creature->getMaster()) { msg.add(master->getID()); } else { msg.add(0x00); @@ -7059,8 +7034,8 @@ void ProtocolGame::AddCreature(NetworkMessage &msg, const Creature* creature, bo } if (!oldProtocol && creatureType == CREATURETYPE_MONSTER) { - if (const Creature* master = creature->getMaster()) { - if (const Player* masterPlayer = master->getPlayer()) { + if (std::shared_ptr master = creature->getMaster()) { + if (std::shared_ptr masterPlayer = master->getPlayer()) { creatureType = CREATURETYPE_SUMMON_PLAYER; } } @@ -7073,7 +7048,7 @@ void ProtocolGame::AddCreature(NetworkMessage &msg, const Creature* creature, bo } if (!oldProtocol && creatureType == CREATURETYPE_SUMMON_PLAYER) { - if (const Creature* master = creature->getMaster()) { + if (std::shared_ptr master = creature->getMaster()) { msg.add(master->getID()); } else { msg.add(0x00); @@ -7081,7 +7056,7 @@ void ProtocolGame::AddCreature(NetworkMessage &msg, const Creature* creature, bo } if (!oldProtocol && creatureType == CREATURETYPE_PLAYER) { - if (const Player* otherCreature = creature->getPlayer()) { + if (std::shared_ptr otherCreature = creature->getPlayer()) { msg.addByte(otherCreature->getVocation()->getClientId()); } else { msg.addByte(0); @@ -7153,7 +7128,7 @@ void ProtocolGame::AddPlayerStats(NetworkMessage &msg) { msg.add(player->getBaseSpeed()); - Condition* condition = player->getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT); + std::shared_ptr condition = player->getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT); msg.add(condition ? condition->getTicks() / 1000 : 0x00); msg.add(player->getOfflineTrainingTime() / 60 / 1000); @@ -7245,7 +7220,7 @@ void ProtocolGame::addImbuementInfo(NetworkMessage &msg, uint16_t imbuementId) c msg.addByte(imbuement->isPremium() ? 0x01 : 0x00); - const auto &items = imbuement->getItems(); + const auto items = imbuement->getItems(); msg.addByte(items.size()); for (const auto &itm : items) { @@ -7260,7 +7235,7 @@ void ProtocolGame::addImbuementInfo(NetworkMessage &msg, uint16_t imbuementId) c msg.add(baseImbuement->protectionPrice); } -void ProtocolGame::openImbuementWindow(Item* item) { +void ProtocolGame::openImbuementWindow(std::shared_ptr item) { if (!item || item->isRemoved()) { return; } @@ -7296,7 +7271,7 @@ void ProtocolGame::openImbuementWindow(Item* item) { for (const Imbuement* imbuement : imbuements) { addImbuementInfo(msg, imbuement->getID()); - const auto &items = imbuement->getItems(); + const auto items = imbuement->getItems(); for (const auto &itm : items) { if (!needItems.count(itm.first)) { needItems[itm.first] = player->getItemTypeCount(itm.first); @@ -7359,7 +7334,7 @@ void ProtocolGame::sendSpecialContainersAvailable() { writeToOutputBuffer(msg); } -void ProtocolGame::updatePartyTrackerAnalyzer(const Party* party) { +void ProtocolGame::updatePartyTrackerAnalyzer(const std::shared_ptr party) { if (oldProtocol || !player || !party || !party->getLeader()) { return; } @@ -7371,9 +7346,9 @@ void ProtocolGame::updatePartyTrackerAnalyzer(const Party* party) { msg.addByte(static_cast(party->priceType)); msg.addByte(static_cast(party->membersData.size())); - for (const PartyAnalyzer* analyzer : party->membersData) { + for (const std::shared_ptr analyzer : party->membersData) { msg.add(analyzer->id); - if (const Player* member = g_game().getPlayerByID(analyzer->id); + if (std::shared_ptr member = g_game().getPlayerByID(analyzer->id); !member || !member->getParty() || member->getParty() != party) { msg.addByte(0); } else { @@ -7390,7 +7365,7 @@ void ProtocolGame::updatePartyTrackerAnalyzer(const Party* party) { msg.addByte(showNames ? 0x01 : 0x00); if (showNames) { msg.addByte(static_cast(party->membersData.size())); - for (const PartyAnalyzer* analyzer : party->membersData) { + for (const std::shared_ptr analyzer : party->membersData) { msg.add(analyzer->id); msg.addString(analyzer->name); } @@ -7399,7 +7374,7 @@ void ProtocolGame::updatePartyTrackerAnalyzer(const Party* party) { writeToOutputBuffer(msg); } -void ProtocolGame::AddCreatureLight(NetworkMessage &msg, const Creature* creature) { +void ProtocolGame::AddCreatureLight(NetworkMessage &msg, std::shared_ptr creature) { LightInfo lightInfo = creature->getCreatureLight(); msg.addByte(0x8D); @@ -7419,7 +7394,7 @@ void ProtocolGame::RemoveTileThing(NetworkMessage &msg, const Position &pos, uin msg.addByte(stackpos); } -void ProtocolGame::sendKillTrackerUpdate(Container* corpse, const std::string &name, const Outfit_t creatureOutfit) { +void ProtocolGame::sendKillTrackerUpdate(std::shared_ptr corpse, const std::string &name, const Outfit_t creatureOutfit) { if (oldProtocol) { return; } @@ -7446,7 +7421,7 @@ void ProtocolGame::sendKillTrackerUpdate(Container* corpse, const std::string &n writeToOutputBuffer(msg); } -void ProtocolGame::sendUpdateSupplyTracker(const Item* item) { +void ProtocolGame::sendUpdateSupplyTracker(std::shared_ptr item) { if (oldProtocol || !player || !item) { return; } @@ -7500,7 +7475,7 @@ void ProtocolGame::sendUpdateInputAnalyzer(CombatType_t type, int32_t amount, st writeToOutputBuffer(msg); } -void ProtocolGame::sendTaskHuntingData(const TaskHuntingSlot* slot) { +void ProtocolGame::sendTaskHuntingData(const std::unique_ptr &slot) { if (!player || oldProtocol) { return; } @@ -7514,14 +7489,14 @@ void ProtocolGame::sendTaskHuntingData(const TaskHuntingSlot* slot) { } else if (slot->state == PreyTaskDataState_Inactive) { // Empty } else if (slot->state == PreyTaskDataState_Selection) { - const Player* user = player; + std::shared_ptr user = player; msg.add(static_cast(slot->raceIdList.size())); std::for_each(slot->raceIdList.begin(), slot->raceIdList.end(), [&msg, user](uint16_t raceid) { msg.add(raceid); msg.addByte(user->isCreatureUnlockedOnTaskHunting(g_monsters().getMonsterTypeByRaceId(raceid)) ? 0x01 : 0x00); }); } else if (slot->state == PreyTaskDataState_ListSelection) { - const Player* user = player; + std::shared_ptr user = player; const std::map bestiaryList = g_game().getBestiaryList(); msg.add(static_cast(bestiaryList.size())); std::for_each(bestiaryList.begin(), bestiaryList.end(), [&msg, user](auto mType) { @@ -7529,7 +7504,7 @@ void ProtocolGame::sendTaskHuntingData(const TaskHuntingSlot* slot) { msg.addByte(user->isCreatureUnlockedOnTaskHunting(g_monsters().getMonsterType(mType.second)) ? 0x01 : 0x00); }); } else if (slot->state == PreyTaskDataState_Active) { - if (const TaskHuntingOption* option = g_ioprey().GetTaskRewardOption(slot)) { + if (const auto &option = g_ioprey().getTaskRewardOption(slot)) { msg.add(slot->selectedRaceId); if (slot->upgrade) { msg.addByte(0x01); @@ -7545,7 +7520,7 @@ void ProtocolGame::sendTaskHuntingData(const TaskHuntingSlot* slot) { return; } } else if (slot->state == PreyTaskDataState_Completed) { - if (const TaskHuntingOption* option = g_ioprey().GetTaskRewardOption(slot)) { + if (const auto &option = g_ioprey().getTaskRewardOption(slot)) { msg.add(slot->selectedRaceId); if (slot->upgrade) { msg.addByte(0x01); @@ -7570,7 +7545,7 @@ void ProtocolGame::sendTaskHuntingData(const TaskHuntingSlot* slot) { writeToOutputBuffer(msg); } -void ProtocolGame::MoveUpCreature(NetworkMessage &msg, const Creature* creature, const Position &newPos, const Position &oldPos) { +void ProtocolGame::MoveUpCreature(NetworkMessage &msg, std::shared_ptr creature, const Position &newPos, const Position &oldPos) { if (creature != player) { return; } @@ -7614,7 +7589,7 @@ void ProtocolGame::MoveUpCreature(NetworkMessage &msg, const Creature* creature, GetMapDescription(oldPos.x - MAP_MAX_CLIENT_VIEW_PORT_X, oldPos.y - MAP_MAX_CLIENT_VIEW_PORT_Y, newPos.z, (MAP_MAX_CLIENT_VIEW_PORT_X + 1) * 2, 1, msg); } -void ProtocolGame::MoveDownCreature(NetworkMessage &msg, const Creature* creature, const Position &newPos, const Position &oldPos) { +void ProtocolGame::MoveDownCreature(NetworkMessage &msg, std::shared_ptr creature, const Position &newPos, const Position &oldPos) { if (creature != player) { return; } @@ -7733,7 +7708,7 @@ void ProtocolGame::parseInventoryImbuements(NetworkMessage &msg) { addGameTask(&Game::playerRequestInventoryImbuements, player->getID(), isTrackerOpen); } -void ProtocolGame::sendInventoryImbuements(const std::map items) { +void ProtocolGame::sendInventoryImbuements(const std::map> items) { if (oldProtocol) { return; } @@ -7771,7 +7746,7 @@ void ProtocolGame::sendInventoryImbuements(const std::map items) msg.add(imbuement->getIconID()); msg.add(imbuementInfo.duration); - const Tile* playerTile = player->getTile(); + std::shared_ptr playerTile = player->getTile(); // Check if the player is in a protection zone bool isInProtectionZone = playerTile && playerTile->hasFlag(TILESTATE_PROTECTIONZONE); // Check if the player is in fight mode @@ -7822,7 +7797,7 @@ void ProtocolGame::sendItemsPrice() { writeToOutputBuffer(msg); } -void ProtocolGame::reloadCreature(const Creature* creature) { +void ProtocolGame::reloadCreature(std::shared_ptr creature) { if (!creature || !canSee(creature)) { return; } @@ -8055,7 +8030,7 @@ void ProtocolGame::parseOpenParentContainer(NetworkMessage &msg) { addGameTask(&Game::playerRequestOpenContainerFromDepotSearch, player->getID(), pos); } -void ProtocolGame::sendUpdateCreature(const Creature* creature) { +void ProtocolGame::sendUpdateCreature(std::shared_ptr creature) { if (oldProtocol || !creature || !player) { return; } @@ -8082,7 +8057,7 @@ void ProtocolGame::sendUpdateCreature(const Creature* creature) { writeToOutputBuffer(msg); } -void ProtocolGame::getForgeInfoMap(const Item* item, std::map> &itemsMap) const { +void ProtocolGame::getForgeInfoMap(std::shared_ptr item, std::map> &itemsMap) const { std::map itemInfo; itemInfo.insert({ item->getTier(), item->getItemCount() }); auto [first, inserted] = itemsMap.try_emplace(item->getID(), itemInfo); @@ -8102,7 +8077,7 @@ void ProtocolGame::sendForgeSkillStats(NetworkMessage &msg) const { std::vector slots { CONST_SLOT_LEFT, CONST_SLOT_ARMOR, CONST_SLOT_HEAD }; for (const auto &slot : slots) { double_t skill = 0; - if (const Item* item = player->getInventoryItem(slot); item) { + if (std::shared_ptr item = player->getInventoryItem(slot); item) { const ItemType &it = Item::items[item->getID()]; if (it.isWeapon()) { skill = item->getFatalChance() * 100; @@ -8378,7 +8353,7 @@ void ProtocolGame::sendPodiumDetails(NetworkMessage &msg, const phmap::parallel_ } } -void ProtocolGame::sendMonsterPodiumWindow(const Item* podium, const Position &position, uint16_t itemId, uint8_t stackPos) { +void ProtocolGame::sendMonsterPodiumWindow(std::shared_ptr podium, const Position &position, uint16_t itemId, uint8_t stackPos) { if (!podium || oldProtocol) { g_logger().error("[{}] item is nullptr", __FUNCTION__); return; @@ -8420,10 +8395,10 @@ void ProtocolGame::sendMonsterPodiumWindow(const Item* podium, const Position &p bool isBossPodium = podium->getID() == ITEM_PODIUM_OF_VIGOUR; msg.addByte(isBossPodium ? 0x01 : 0x00); // Bosstiary or bestiary if (isBossPodium) { - const auto &unlockedBosses = g_ioBosstiary().getBosstiaryFinished(player, 2); + const auto unlockedBosses = g_ioBosstiary().getBosstiaryFinished(player, 2); sendPodiumDetails(msg, unlockedBosses, true); } else { - const auto &unlockedMonsters = g_iobestiary().getBestiaryFinished(player); + const auto unlockedMonsters = g_iobestiary().getBestiaryFinished(player); sendPodiumDetails(msg, unlockedMonsters, false); } diff --git a/src/server/network/protocol/protocolgame.hpp b/src/server/network/protocol/protocolgame.hpp index 1b57e3c13..60eac6f18 100644 --- a/src/server/network/protocol/protocolgame.hpp +++ b/src/server/network/protocol/protocolgame.hpp @@ -60,7 +60,7 @@ class ProtocolGame final : public Protocol { void login(const std::string &name, uint32_t accnumber, OperatingSystem_t operatingSystem); void logout(bool displayEffect, bool forced); - void AddItem(NetworkMessage &msg, const Item* item); + void AddItem(NetworkMessage &msg, std::shared_ptr item); void AddItem(NetworkMessage &msg, uint16_t id, uint8_t count, uint8_t tier); uint16_t getVersion() const { @@ -86,7 +86,7 @@ class ProtocolGame final : public Protocol { void checkCreatureAsKnown(uint32_t id, bool &known, uint32_t &removedKnown); bool canSee(int32_t x, int32_t y, int32_t z) const; - bool canSee(const Creature*) const; + bool canSee(std::shared_ptr) const; bool canSee(const Position &pos) const; // we have all the parse methods @@ -124,7 +124,7 @@ class ProtocolGame final : public Protocol { void sendSessionEndInformation(SessionEndInformations information); - void sendItemInspection(uint16_t itemId, uint8_t itemCount, const Item* item, bool cyclopedia); + void sendItemInspection(uint16_t itemId, uint8_t itemCount, std::shared_ptr item, bool cyclopedia); void parseInspectionObject(NetworkMessage &msg); void parseCyclopediaCharacterInfo(NetworkMessage &msg); @@ -232,12 +232,12 @@ class ProtocolGame final : public Protocol { void sendChannel(uint16_t channelId, const std::string &channelName, const UsersMap* channelUsers, const InvitedMap* invitedUsers); void sendOpenPrivateChannel(const std::string &receiver); void sendExperienceTracker(int64_t rawExp, int64_t finalExp); - void sendToChannel(const Creature* creature, SpeakClasses type, const std::string &text, uint16_t channelId); - void sendPrivateMessage(const Player* speaker, SpeakClasses type, const std::string &text); + void sendToChannel(std::shared_ptr creature, SpeakClasses type, const std::string &text, uint16_t channelId); + void sendPrivateMessage(std::shared_ptr speaker, SpeakClasses type, const std::string &text); void sendIcons(uint32_t icons); void sendFYIBox(const std::string &message); - void openImbuementWindow(Item* item); + void openImbuementWindow(std::shared_ptr item); void sendImbuementResult(const std::string message); void closeImbuementWindow(); @@ -266,7 +266,7 @@ class ProtocolGame final : public Protocol { void parseSendBosstiarySlots(); void parseBosstiarySlot(NetworkMessage &msg); void sendPodiumDetails(NetworkMessage &msg, const phmap::parallel_flat_hash_set &toSendMonsters, bool isBoss) const; - void sendMonsterPodiumWindow(const Item* podium, const Position &position, uint16_t itemId, uint8_t stackPos); + void sendMonsterPodiumWindow(std::shared_ptr podium, const Position &position, uint16_t itemId, uint8_t stackPos); void parseSetMonsterPodium(NetworkMessage &msg) const; void sendBosstiaryCooldownTimer(); void sendBosstiaryEntryChanged(uint32_t bossid); @@ -276,28 +276,28 @@ class ProtocolGame final : public Protocol { void sendMagicEffect(const Position &pos, uint16_t type); void removeMagicEffect(const Position &pos, uint16_t type); void sendRestingStatus(uint8_t protection); - void sendCreatureHealth(const Creature* creature); - void sendPartyCreatureUpdate(const Creature* target); - void sendPartyCreatureShield(const Creature* target); - void sendPartyCreatureSkull(const Creature* target); - void sendPartyCreatureHealth(const Creature* target, uint8_t healthPercent); - void sendPartyPlayerMana(const Player* target, uint8_t manaPercent); - void sendPartyCreatureShowStatus(const Creature* target, bool showStatus); - void sendPartyPlayerVocation(const Player* target); - void sendPlayerVocation(const Player* target); + void sendCreatureHealth(std::shared_ptr creature); + void sendPartyCreatureUpdate(std::shared_ptr target); + void sendPartyCreatureShield(std::shared_ptr target); + void sendPartyCreatureSkull(std::shared_ptr target); + void sendPartyCreatureHealth(std::shared_ptr target, uint8_t healthPercent); + void sendPartyPlayerMana(std::shared_ptr target, uint8_t manaPercent); + void sendPartyCreatureShowStatus(std::shared_ptr target, bool showStatus); + void sendPartyPlayerVocation(std::shared_ptr target); + void sendPlayerVocation(std::shared_ptr target); void sendSkills(); void sendPing(); void sendPingBack(); - void sendCreatureTurn(const Creature* creature, uint32_t stackpos); - void sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string &text, const Position* pos = nullptr); + void sendCreatureTurn(std::shared_ptr creature, uint32_t stackpos); + void sendCreatureSay(std::shared_ptr creature, SpeakClasses type, const std::string &text, const Position* pos = nullptr); // Unjust Panel void sendUnjustifiedPoints(const uint8_t &dayProgress, const uint8_t &dayLeft, const uint8_t &weekProgress, const uint8_t &weekLeft, const uint8_t &monthProgress, const uint8_t &monthLeft, const uint8_t &skullDuration); void sendCancelWalk(); - void sendChangeSpeed(const Creature* creature, uint16_t speed); + void sendChangeSpeed(std::shared_ptr creature, uint16_t speed); void sendCancelTarget(); - void sendCreatureOutfit(const Creature* creature, const Outfit_t &outfit); + void sendCreatureOutfit(std::shared_ptr creature, const Outfit_t &outfit); void sendStats(); void sendBasicData(); void sendTextMessage(const TextMessage &message); @@ -320,13 +320,13 @@ class ProtocolGame final : public Protocol { void sendCyclopediaCharacterBadges(); void sendCyclopediaCharacterTitles(); - void sendCreatureWalkthrough(const Creature* creature, bool walkthrough); - void sendCreatureShield(const Creature* creature); - void sendCreatureEmblem(const Creature* creature); - void sendCreatureSkull(const Creature* creature); - void sendCreatureType(const Creature* creature, uint8_t creatureType); + void sendCreatureWalkthrough(std::shared_ptr creature, bool walkthrough); + void sendCreatureShield(std::shared_ptr creature); + void sendCreatureEmblem(std::shared_ptr creature); + void sendCreatureSkull(std::shared_ptr creature); + void sendCreatureType(std::shared_ptr creature, uint8_t creatureType); - void sendShop(Npc* npc); + void sendShop(std::shared_ptr npc); void sendCloseShop(); void sendClientCheck(); void sendGameNews(); @@ -342,15 +342,15 @@ class ProtocolGame final : public Protocol { void sendMarketCancelOffer(const MarketOfferEx &offer); void sendMarketBrowseOwnHistory(const HistoryMarketOfferList &buyOffers, const HistoryMarketOfferList &sellOffers); void sendMarketDetail(uint16_t itemId, uint8_t tier); - void sendTradeItemRequest(const std::string &traderName, const Item* item, bool ack); + void sendTradeItemRequest(const std::string &traderName, std::shared_ptr item, bool ack); void sendCloseTrade(); - void updatePartyTrackerAnalyzer(const Party* party); + void updatePartyTrackerAnalyzer(const std::shared_ptr party); void sendTextWindow(uint32_t windowTextId, uint32_t itemId, const std::string &text); - void sendTextWindow(uint32_t windowTextId, Item* item, uint16_t maxlen, bool canWrite); + void sendTextWindow(uint32_t windowTextId, std::shared_ptr item, uint16_t maxlen, bool canWrite); void sendHouseWindow(uint32_t windowTextId, const std::string &text); void sendOutfitWindow(); - void sendPodiumWindow(const Item* podium, const Position &position, uint16_t itemId, uint8_t stackpos); + void sendPodiumWindow(std::shared_ptr podium, const Position &position, uint16_t itemId, uint8_t stackpos); void sendUpdatedVIPStatus(uint32_t guid, VipStatus_t newStatus); void sendVIP(uint32_t guid, const std::string &name, const std::string &description, uint32_t icon, bool notify, VipStatus_t status); @@ -360,13 +360,13 @@ class ProtocolGame final : public Protocol { void sendFightModes(); - void sendCreatureLight(const Creature* creature); - void sendCreatureIcon(const Creature* creature); - void sendUpdateCreature(const Creature* creature); + void sendCreatureLight(std::shared_ptr creature); + void sendCreatureIcon(std::shared_ptr creature); + void sendUpdateCreature(std::shared_ptr creature); void sendWorldLight(const LightInfo &lightInfo); void sendTibiaTime(int32_t time); - void sendCreatureSquare(const Creature* creature, SquareColor_t color); + void sendCreatureSquare(std::shared_ptr creature, SquareColor_t color); void sendSpellCooldown(uint16_t spellId, uint32_t time); void sendSpellGroupCooldown(SpellGroup_t groupId, uint32_t time); @@ -374,43 +374,43 @@ class ProtocolGame final : public Protocol { void sendCoinBalance(); - void sendPreyTimeLeft(const PreySlot* slot); - void sendPreyData(const PreySlot* slot); + void sendPreyTimeLeft(const std::unique_ptr &slot); + void sendPreyData(const std::unique_ptr &slot); void sendPreyPrices(); // tiles void sendMapDescription(const Position &pos); - void sendAddTileItem(const Position &pos, uint32_t stackpos, const Item* item); - void sendUpdateTileItem(const Position &pos, uint32_t stackpos, const Item* item); + void sendAddTileItem(const Position &pos, uint32_t stackpos, std::shared_ptr item); + void sendUpdateTileItem(const Position &pos, uint32_t stackpos, std::shared_ptr item); void sendRemoveTileThing(const Position &pos, uint32_t stackpos); - void sendUpdateTile(const Tile* tile, const Position &pos); + void sendUpdateTile(std::shared_ptr tile, const Position &pos); - void sendAddCreature(const Creature* creature, const Position &pos, int32_t stackpos, bool isLogin); - void sendMoveCreature(const Creature* creature, const Position &newPos, int32_t newStackPos, const Position &oldPos, int32_t oldStackPos, bool teleport); + void sendAddCreature(std::shared_ptr creature, const Position &pos, int32_t stackpos, bool isLogin); + void sendMoveCreature(std::shared_ptr creature, const Position &newPos, int32_t newStackPos, const Position &oldPos, int32_t oldStackPos, bool teleport); // containers - void sendAddContainerItem(uint8_t cid, uint16_t slot, const Item* item); - void sendUpdateContainerItem(uint8_t cid, uint16_t slot, const Item* item); - void sendRemoveContainerItem(uint8_t cid, uint16_t slot, const Item* lastItem); + void sendAddContainerItem(uint8_t cid, uint16_t slot, std::shared_ptr item); + void sendUpdateContainerItem(uint8_t cid, uint16_t slot, std::shared_ptr item); + void sendRemoveContainerItem(uint8_t cid, uint16_t slot, std::shared_ptr lastItem); - void sendContainer(uint8_t cid, const Container* container, bool hasParent, uint16_t firstIndex); + void sendContainer(uint8_t cid, std::shared_ptr container, bool hasParent, uint16_t firstIndex); void sendCloseContainer(uint8_t cid); // quickloot void sendLootContainers(); - void sendLootStats(Item* item, uint8_t count); + void sendLootStats(std::shared_ptr item, uint8_t count); // inventory - void sendInventoryItem(Slots_t slot, const Item* item); + void sendInventoryItem(Slots_t slot, std::shared_ptr item); void sendInventoryIds(); // messages void sendModalWindow(const ModalWindow &modalWindow); // analyzers - void sendKillTrackerUpdate(Container* corpse, const std::string &name, const Outfit_t creatureOutfit); - void sendUpdateSupplyTracker(const Item* item); + void sendKillTrackerUpdate(std::shared_ptr corpse, const std::string &name, const Outfit_t creatureOutfit); + void sendUpdateSupplyTracker(std::shared_ptr item); void sendUpdateImpactTracker(CombatType_t type, int32_t amount); void sendUpdateInputAnalyzer(CombatType_t type, int32_t amount, std::string target); @@ -419,7 +419,7 @@ class ProtocolGame final : public Protocol { // Help functions // translate a tile to clientreadable format - void GetTileDescription(const Tile* tile, NetworkMessage &msg); + void GetTileDescription(std::shared_ptr tile, NetworkMessage &msg); // translate a floor to clientreadable format void GetFloorDescription(NetworkMessage &msg, int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, int32_t offset, int32_t &skip); @@ -427,7 +427,7 @@ class ProtocolGame final : public Protocol { // translate a map area to clientreadable format void GetMapDescription(int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, NetworkMessage &msg); - void AddCreature(NetworkMessage &msg, const Creature* creature, bool known, uint32_t remove); + void AddCreature(NetworkMessage &msg, std::shared_ptr creature, bool known, uint32_t remove); void AddPlayerStats(NetworkMessage &msg); void AddOutfit(NetworkMessage &msg, const Outfit_t &outfit, bool addMount = true); void AddPlayerSkills(NetworkMessage &msg); @@ -435,15 +435,15 @@ class ProtocolGame final : public Protocol { void sendPremiumTrigger(); void sendMessageDialog(const std::string &message); void AddWorldLight(NetworkMessage &msg, LightInfo lightInfo); - void AddCreatureLight(NetworkMessage &msg, const Creature* creature); + void AddCreatureLight(NetworkMessage &msg, std::shared_ptr creature); // tiles static void RemoveTileThing(NetworkMessage &msg, const Position &pos, uint32_t stackpos); - void sendTaskHuntingData(const TaskHuntingSlot* slot); + void sendTaskHuntingData(const std::unique_ptr &slot); - void MoveUpCreature(NetworkMessage &msg, const Creature* creature, const Position &newPos, const Position &oldPos); - void MoveDownCreature(NetworkMessage &msg, const Creature* creature, const Position &newPos, const Position &oldPos); + void MoveUpCreature(NetworkMessage &msg, std::shared_ptr creature, const Position &newPos, const Position &oldPos); + void MoveDownCreature(NetworkMessage &msg, std::shared_ptr creature, const Position &newPos, const Position &oldPos); // shop void AddHiddenShopItem(NetworkMessage &msg); @@ -456,12 +456,12 @@ class ProtocolGame final : public Protocol { void sendFeatures(); void parseInventoryImbuements(NetworkMessage &msg); - void sendInventoryImbuements(const std::map items); + void sendInventoryImbuements(const std::map> items); // reloadCreature - void reloadCreature(const Creature* creature); + void reloadCreature(std::shared_ptr creature); - void getForgeInfoMap(const Item* item, std::map> &itemsMap) const; + void getForgeInfoMap(std::shared_ptr item, std::map> &itemsMap) const; // Wheel void parseOpenWheel(NetworkMessage &msg); @@ -472,7 +472,7 @@ class ProtocolGame final : public Protocol { friend class PlayerWheel; phmap::flat_hash_set knownCreatureSet; - Player* player = nullptr; + std::shared_ptr player = nullptr; uint32_t eventConnect = 0; uint32_t challengeTimestamp = 0; @@ -497,7 +497,7 @@ class ProtocolGame final : public Protocol { void sendSpecialContainersAvailable(); void addBless(); void parsePacketDead(uint8_t recvbyte); - void addCreatureIcon(NetworkMessage &msg, const Creature* creature); + void addCreatureIcon(NetworkMessage &msg, std::shared_ptr creature); void sendSingleSoundEffect(const Position &pos, SoundEffect_t id, SourceEffect_t source); void sendDoubleSoundEffect(const Position &pos, SoundEffect_t mainSoundId, SourceEffect_t mainSource, SoundEffect_t secondarySoundId, SourceEffect_t secondarySource); diff --git a/src/server/network/protocol/protocolstatus.cpp b/src/server/network/protocol/protocolstatus.cpp index 9ca24df82..3d2ce459c 100644 --- a/src/server/network/protocol/protocolstatus.cpp +++ b/src/server/network/protocol/protocolstatus.cpp @@ -189,7 +189,7 @@ void ProtocolStatus::sendInfo(uint16_t requestedInfo, const std::string &charact if (requestedInfo & REQUEST_EXT_PLAYERS_INFO) { output->addByte(0x21); // players info - online players list - const auto &players = g_game().getPlayers(); + const auto players = g_game().getPlayers(); output->add(players.size()); for (const auto &it : players) { output->addString(it.second->getName()); diff --git a/src/utils/tools.cpp b/src/utils/tools.cpp index f7f0a7251..f6b5d9ff1 100644 --- a/src/utils/tools.cpp +++ b/src/utils/tools.cpp @@ -476,6 +476,11 @@ std::time_t getTimeMsNow() { return std::chrono::duration_cast(duration).count(); } +std::time_t getTimeUsNow() { + auto duration = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(duration).count(); +} + BedItemPart_t getBedPart(const std::string_view string) { if (string == "pillow" || string == "1") { return BED_PILLOW_PART; diff --git a/src/utils/tools.hpp b/src/utils/tools.hpp index e6f709733..636aa365e 100644 --- a/src/utils/tools.hpp +++ b/src/utils/tools.hpp @@ -71,6 +71,7 @@ std::string formatTime(time_t time); std::string formatEnumName(std::string_view name); std::time_t getTimeNow(); std::time_t getTimeMsNow(); +std::time_t getTimeUsNow(); std::string convertIPToString(uint32_t ip); void trimString(std::string &str); diff --git a/src/utils/utils_definitions.hpp b/src/utils/utils_definitions.hpp index 7334d7098..ee6b8da2f 100644 --- a/src/utils/utils_definitions.hpp +++ b/src/utils/utils_definitions.hpp @@ -745,3 +745,17 @@ enum BedItemPart_t : uint8_t { BED_PILLOW_PART, BED_BLANKET_PART, }; + +enum class AttrSubId_t { + None, + TrainParty, + ProtectParty, + EnchantParty, + JeanPierreMagic, + JeanPierreMelee, + JeanPierreDistance, + JeanPierreDefense, + JeanPierreFishing, + BloodRageProtector, + Sharpshooter, +}; diff --git a/tests/fixture/lib/logging/in_memory_logger.hpp b/tests/fixture/lib/logging/in_memory_logger.hpp index 581a453ee..0b1f99728 100644 --- a/tests/fixture/lib/logging/in_memory_logger.hpp +++ b/tests/fixture/lib/logging/in_memory_logger.hpp @@ -18,67 +18,67 @@ namespace di = boost::di; class InMemoryLogger : public Logger { - private: - struct LogEntry { - std::string level; - std::string message; - }; - - public: - mutable std::vector logs; - - InMemoryLogger() = default; - InMemoryLogger(const InMemoryLogger &) {} - InMemoryLogger(const InMemoryLogger &&) {} - - static di::extension::injector<> & install(di::extension::injector<> &injector) { - injector.install(di::bind.to().in(di::singleton)); - return injector; - } - - InMemoryLogger &reset() { - logs.clear(); - return *this; - } - - bool hasLogEntry(const std::string& lvl, const std::string& expectedMsg) const { - for (const auto& entry : logs) { - if (entry.level == lvl && entry.message == expectedMsg) { - return true; - } +private: + struct LogEntry { + std::string level; + std::string message; + }; + +public: + mutable std::vector logs; + + InMemoryLogger() = default; + InMemoryLogger(const InMemoryLogger &) { } + InMemoryLogger(const InMemoryLogger &&) { } + + static di::extension::injector<> &install(di::extension::injector<> &injector) { + injector.install(di::bind.to().in(di::singleton)); + return injector; + } + + InMemoryLogger &reset() { + logs.clear(); + return *this; + } + + bool hasLogEntry(const std::string &lvl, const std::string &expectedMsg) const { + for (const auto &entry : logs) { + if (entry.level == lvl && entry.message == expectedMsg) { + return true; } - - return false; } - void setLevel(const std::string &name) override { - // For the stub, setting a level might not have any behavior. - // But you can implement level filtering if you like. - } + return false; + } - [[nodiscard]] std::string getLevel() const override { - // For simplicity, let's just return a default level. You can adjust as needed. - return "DEBUG"; - } + void setLevel(const std::string &name) override { + // For the stub, setting a level might not have any behavior. + // But you can implement level filtering if you like. + } - virtual void log(std::string lvl, fmt::basic_string_view msg) const override { - logs.push_back({lvl, {msg.data(), msg.size()}}); - } + [[nodiscard]] std::string getLevel() const override { + // For simplicity, let's just return a default level. You can adjust as needed. + return "DEBUG"; + } - // Helper methods for testing - size_t logCount() const { - return logs.size(); - } + virtual void log(std::string lvl, fmt::basic_string_view msg) const override { + logs.push_back({ lvl, { msg.data(), msg.size() } }); + } - std::pair getLogEntry(size_t index) const { - if (index < logs.size()) { - return {logs[index].level, logs[index].message}; - } - return {"", ""}; // Return empty pair for out-of-bounds. Alternatively, you could throw an exception. + // Helper methods for testing + size_t logCount() const { + return logs.size(); + } + + std::pair getLogEntry(size_t index) const { + if (index < logs.size()) { + return { logs[index].level, logs[index].message }; } + return { "", "" }; // Return empty pair for out-of-bounds. Alternatively, you could throw an exception. + } }; template <> struct TestInjection { - using type = InMemoryLogger; -}; \ No newline at end of file + using type = InMemoryLogger; +}; diff --git a/tests/fixture/test_injection.hpp b/tests/fixture/test_injection.hpp index 31a64acf7..f69ede1e2 100644 --- a/tests/fixture/test_injection.hpp +++ b/tests/fixture/test_injection.hpp @@ -1,12 +1,12 @@ /** -* Canary - A free and open-source MMORPG server emulator -* Copyright (©) 2019-2023 OpenTibiaBR -* Repository: https://github.com/opentibiabr/canary -* License: https://github.com/opentibiabr/canary/blob/main/LICENSE -* Contributors: https://github.com/opentibiabr/canary/graphs/contributors -* Website: https://docs.opentibiabr.com/ + * Canary - A free and open-source MMORPG server emulator + * Copyright (©) 2019-2023 OpenTibiaBR + * Repository: https://github.com/opentibiabr/canary + * License: https://github.com/opentibiabr/canary/blob/main/LICENSE + * Contributors: https://github.com/opentibiabr/canary/graphs/contributors + * Website: https://docs.opentibiabr.com/ */ #pragma once template -struct TestInjection {}; \ No newline at end of file +struct TestInjection { }; diff --git a/tests/unit/lib/di/soft_singleton_test.cpp b/tests/unit/lib/di/soft_singleton_test.cpp index 99bb194e7..6a2bb97f1 100644 --- a/tests/unit/lib/di/soft_singleton_test.cpp +++ b/tests/unit/lib/di/soft_singleton_test.cpp @@ -1,11 +1,11 @@ /** -* Canary - A free and open-source MMORPG server emulator -* Copyright (©) 2019-2023 OpenTibiaBR -* Repository: https://github.com/opentibiabr/canary -* License: https://github.com/opentibiabr/canary/blob/main/LICENSE -* Contributors: https://github.com/opentibiabr/canary/graphs/contributors -* Website: https://docs.opentibiabr.com/ -*/ + * Canary - A free and open-source MMORPG server emulator + * Copyright (©) 2019-2023 OpenTibiaBR + * Repository: https://github.com/opentibiabr/canary + * License: https://github.com/opentibiabr/canary/blob/main/LICENSE + * Contributors: https://github.com/opentibiabr/canary/graphs/contributors + * Website: https://docs.opentibiabr.com/ + */ #include "pch.hpp" #include @@ -18,35 +18,33 @@ using namespace boost::ut; suite<"lib"> softSingletonTest = [] { test("SoftSingleton warns about multiple instances") = [] { - di::extension::injector<> injector{}; + di::extension::injector<> injector {}; DI::setTestContainer(&InMemoryLogger::install(injector)); - SoftSingleton softSingleton{"Test"}; - SoftSingletonGuard guard{softSingleton}; - SoftSingletonGuard guard2{softSingleton}; + SoftSingleton softSingleton { "Test" }; + SoftSingletonGuard guard { softSingleton }; + SoftSingletonGuard guard2 { softSingleton }; softSingleton.increment(); auto &logger = dynamic_cast(injector.create()); expect(eq(2, logger.logCount()) >> fatal); expect( - eq(std::string{"warning"}, logger.logs[0].level) and - eq(std::string{"2 instances created for Test. This is a soft singleton, you probably want to use g_test instead."}, logger.logs[0].message) - ); + eq(std::string { "warning" }, logger.logs[0].level) and eq(std::string { "2 instances created for Test. This is a soft singleton, you probably want to use g_test instead." }, logger.logs[0].message) + ); expect( - eq(std::string{"warning"}, logger.logs[1].level) and - eq(std::string{"3 instances created for Test. This is a soft singleton, you probably want to use g_test instead."}, logger.logs[1].message) - ); + eq(std::string { "warning" }, logger.logs[1].level) and eq(std::string { "3 instances created for Test. This is a soft singleton, you probably want to use g_test instead." }, logger.logs[1].message) + ); }; test("SoftSingleton doesn't warn if instance was released") = [] { - di::extension::injector<> injector{}; + di::extension::injector<> injector {}; DI::setTestContainer(&InMemoryLogger::install(injector)); - SoftSingleton softSingleton{"Test"}; + SoftSingleton softSingleton { "Test" }; - [&softSingleton] { SoftSingletonGuard guard{softSingleton}; }(); + [&softSingleton] { SoftSingletonGuard guard { softSingleton }; }(); // Lambda scope, guard was destructed. - [&softSingleton] { SoftSingletonGuard guard{softSingleton}; }(); + [&softSingleton] { SoftSingletonGuard guard { softSingleton }; }(); // Lambda scope, guard2 was destructed. softSingleton.increment(); diff --git a/tests/unit/lib/logging/in_memory_logger.hpp b/tests/unit/lib/logging/in_memory_logger.hpp index 581a453ee..0b1f99728 100644 --- a/tests/unit/lib/logging/in_memory_logger.hpp +++ b/tests/unit/lib/logging/in_memory_logger.hpp @@ -18,67 +18,67 @@ namespace di = boost::di; class InMemoryLogger : public Logger { - private: - struct LogEntry { - std::string level; - std::string message; - }; - - public: - mutable std::vector logs; - - InMemoryLogger() = default; - InMemoryLogger(const InMemoryLogger &) {} - InMemoryLogger(const InMemoryLogger &&) {} - - static di::extension::injector<> & install(di::extension::injector<> &injector) { - injector.install(di::bind.to().in(di::singleton)); - return injector; - } - - InMemoryLogger &reset() { - logs.clear(); - return *this; - } - - bool hasLogEntry(const std::string& lvl, const std::string& expectedMsg) const { - for (const auto& entry : logs) { - if (entry.level == lvl && entry.message == expectedMsg) { - return true; - } +private: + struct LogEntry { + std::string level; + std::string message; + }; + +public: + mutable std::vector logs; + + InMemoryLogger() = default; + InMemoryLogger(const InMemoryLogger &) { } + InMemoryLogger(const InMemoryLogger &&) { } + + static di::extension::injector<> &install(di::extension::injector<> &injector) { + injector.install(di::bind.to().in(di::singleton)); + return injector; + } + + InMemoryLogger &reset() { + logs.clear(); + return *this; + } + + bool hasLogEntry(const std::string &lvl, const std::string &expectedMsg) const { + for (const auto &entry : logs) { + if (entry.level == lvl && entry.message == expectedMsg) { + return true; } - - return false; } - void setLevel(const std::string &name) override { - // For the stub, setting a level might not have any behavior. - // But you can implement level filtering if you like. - } + return false; + } - [[nodiscard]] std::string getLevel() const override { - // For simplicity, let's just return a default level. You can adjust as needed. - return "DEBUG"; - } + void setLevel(const std::string &name) override { + // For the stub, setting a level might not have any behavior. + // But you can implement level filtering if you like. + } - virtual void log(std::string lvl, fmt::basic_string_view msg) const override { - logs.push_back({lvl, {msg.data(), msg.size()}}); - } + [[nodiscard]] std::string getLevel() const override { + // For simplicity, let's just return a default level. You can adjust as needed. + return "DEBUG"; + } - // Helper methods for testing - size_t logCount() const { - return logs.size(); - } + virtual void log(std::string lvl, fmt::basic_string_view msg) const override { + logs.push_back({ lvl, { msg.data(), msg.size() } }); + } - std::pair getLogEntry(size_t index) const { - if (index < logs.size()) { - return {logs[index].level, logs[index].message}; - } - return {"", ""}; // Return empty pair for out-of-bounds. Alternatively, you could throw an exception. + // Helper methods for testing + size_t logCount() const { + return logs.size(); + } + + std::pair getLogEntry(size_t index) const { + if (index < logs.size()) { + return { logs[index].level, logs[index].message }; } + return { "", "" }; // Return empty pair for out-of-bounds. Alternatively, you could throw an exception. + } }; template <> struct TestInjection { - using type = InMemoryLogger; -}; \ No newline at end of file + using type = InMemoryLogger; +}; diff --git a/tests/unit/main.cpp b/tests/unit/main.cpp index 5cf3982af..0f8a83d00 100644 --- a/tests/unit/main.cpp +++ b/tests/unit/main.cpp @@ -2,4 +2,4 @@ using namespace boost::ut; -int main() {} +int main() { } diff --git a/tests/unit/security/rsa_test.cpp b/tests/unit/security/rsa_test.cpp index 710ea45d2..a613fc465 100644 --- a/tests/unit/security/rsa_test.cpp +++ b/tests/unit/security/rsa_test.cpp @@ -1,11 +1,11 @@ /** -* Canary - A free and open-source MMORPG server emulator -* Copyright (©) 2019-2023 OpenTibiaBR -* Repository: https://github.com/opentibiabr/canary -* License: https://github.com/opentibiabr/canary/blob/main/LICENSE -* Contributors: https://github.com/opentibiabr/canary/graphs/contributors -* Website: https://docs.opentibiabr.com/ -*/ + * Canary - A free and open-source MMORPG server emulator + * Copyright (©) 2019-2023 OpenTibiaBR + * Repository: https://github.com/opentibiabr/canary + * License: https://github.com/opentibiabr/canary/blob/main/LICENSE + * Contributors: https://github.com/opentibiabr/canary/graphs/contributors + * Website: https://docs.opentibiabr.com/ + */ #include "pch.hpp" #include @@ -17,17 +17,16 @@ using namespace boost::ut; suite<"security"> rsaTest = [] { test("RSA::start logs error for missing .pem file") = [] { - di::extension::injector<> injector{}; + di::extension::injector<> injector {}; DI::setTestContainer(&InMemoryLogger::install(injector)); DI::create().start(); auto &logger = dynamic_cast(injector.create()); - expect(eq(1, logger.logs.size()) >> fatal); + expect(eq(1, logger.logs.size()) >> fatal); expect( - eq(std::string{"error"}, logger.logs[0].level) and - eq(std::string{"File key.pem not found or have problem on loading... Setting standard rsa key\n"}, logger.logs[0].message) - ); + eq(std::string { "error" }, logger.logs[0].level) and eq(std::string { "File key.pem not found or have problem on loading... Setting standard rsa key\n" }, logger.logs[0].message) + ); }; }; diff --git a/tests/unit/utils/position_functions_test.cpp b/tests/unit/utils/position_functions_test.cpp index 52341fd8d..82e269632 100644 --- a/tests/unit/utils/position_functions_test.cpp +++ b/tests/unit/utils/position_functions_test.cpp @@ -8,35 +8,35 @@ using namespace boost::ut; suite<"utils"> getDirectionToTest = [] { struct GetDirectionToTestCase { - Position from, to; - Direction expected, expectedForExactDiagonal; + Position from, to; + Direction expected, expectedForExactDiagonal; - [[nodiscard]] std::string toString() const { - return fmt::format("from {} to {}", from.toString(), to.toString()); - } + [[nodiscard]] std::string toString() const { + return fmt::format("from {} to {}", from.toString(), to.toString()); + } }; - std::vector getDirectionToTestCases{ - GetDirectionToTestCase{ Position{}, Position{}, DIRECTION_SOUTH, DIRECTION_SOUTH }, - GetDirectionToTestCase{ Position{0,0,0}, Position{0,0,0}, DIRECTION_SOUTH, DIRECTION_SOUTH }, - GetDirectionToTestCase{ Position{100,100,100}, Position{100,100,100}, DIRECTION_SOUTH, DIRECTION_SOUTH }, - GetDirectionToTestCase{ Position{125,1123,5}, Position{125,1153,5}, DIRECTION_SOUTH, DIRECTION_SOUTH }, - GetDirectionToTestCase{ Position{5555,3212,15}, Position{5555,3211,15}, DIRECTION_NORTH, DIRECTION_NORTH }, - GetDirectionToTestCase{ Position{32132,65000,11}, Position{31512,65000,11}, DIRECTION_WEST, DIRECTION_WEST }, - GetDirectionToTestCase{ Position{5123,6554,7}, Position{40000,6554,7}, DIRECTION_EAST, DIRECTION_EAST }, - GetDirectionToTestCase{ Position{25200,33173,8}, Position{5200,13173,7}, DIRECTION_NORTHWEST, DIRECTION_NORTHWEST }, - GetDirectionToTestCase{ Position{22137,6,9}, Position{22141,2,15}, DIRECTION_NORTHEAST, DIRECTION_NORTHEAST }, - GetDirectionToTestCase{ Position{32011,2197,1}, Position{32135,2321,13}, DIRECTION_SOUTHEAST, DIRECTION_SOUTHEAST }, - GetDirectionToTestCase{ Position{13121,5213,5}, Position{5213,13121,5}, DIRECTION_SOUTHWEST, DIRECTION_SOUTHWEST }, - - GetDirectionToTestCase{ Position{123,122,0}, Position{0,0,0}, DIRECTION_NORTHWEST, DIRECTION_WEST }, - GetDirectionToTestCase{ Position{122,123,0}, Position{0,0,0}, DIRECTION_NORTHWEST, DIRECTION_NORTH }, - GetDirectionToTestCase{ Position{0,122,0}, Position{123,0,0}, DIRECTION_NORTHEAST, DIRECTION_EAST }, - GetDirectionToTestCase{ Position{0,123,0}, Position{122,0,0}, DIRECTION_NORTHEAST, DIRECTION_NORTH }, - GetDirectionToTestCase{ Position{0,0,0}, Position{123,122,0}, DIRECTION_SOUTHEAST, DIRECTION_EAST }, - GetDirectionToTestCase{ Position{0,0,0}, Position{122,123,0}, DIRECTION_SOUTHEAST, DIRECTION_SOUTH }, - GetDirectionToTestCase{ Position{123,0,0}, Position{0,122,0}, DIRECTION_SOUTHWEST, DIRECTION_WEST }, - GetDirectionToTestCase{ Position{122,0,0}, Position{0,123,0}, DIRECTION_SOUTHWEST, DIRECTION_SOUTH }, + std::vector getDirectionToTestCases { + GetDirectionToTestCase { Position {}, Position {}, DIRECTION_SOUTH, DIRECTION_SOUTH }, + GetDirectionToTestCase { Position { 0, 0, 0 }, Position { 0, 0, 0 }, DIRECTION_SOUTH, DIRECTION_SOUTH }, + GetDirectionToTestCase { Position { 100, 100, 100 }, Position { 100, 100, 100 }, DIRECTION_SOUTH, DIRECTION_SOUTH }, + GetDirectionToTestCase { Position { 125, 1123, 5 }, Position { 125, 1153, 5 }, DIRECTION_SOUTH, DIRECTION_SOUTH }, + GetDirectionToTestCase { Position { 5555, 3212, 15 }, Position { 5555, 3211, 15 }, DIRECTION_NORTH, DIRECTION_NORTH }, + GetDirectionToTestCase { Position { 32132, 65000, 11 }, Position { 31512, 65000, 11 }, DIRECTION_WEST, DIRECTION_WEST }, + GetDirectionToTestCase { Position { 5123, 6554, 7 }, Position { 40000, 6554, 7 }, DIRECTION_EAST, DIRECTION_EAST }, + GetDirectionToTestCase { Position { 25200, 33173, 8 }, Position { 5200, 13173, 7 }, DIRECTION_NORTHWEST, DIRECTION_NORTHWEST }, + GetDirectionToTestCase { Position { 22137, 6, 9 }, Position { 22141, 2, 15 }, DIRECTION_NORTHEAST, DIRECTION_NORTHEAST }, + GetDirectionToTestCase { Position { 32011, 2197, 1 }, Position { 32135, 2321, 13 }, DIRECTION_SOUTHEAST, DIRECTION_SOUTHEAST }, + GetDirectionToTestCase { Position { 13121, 5213, 5 }, Position { 5213, 13121, 5 }, DIRECTION_SOUTHWEST, DIRECTION_SOUTHWEST }, + + GetDirectionToTestCase { Position { 123, 122, 0 }, Position { 0, 0, 0 }, DIRECTION_NORTHWEST, DIRECTION_WEST }, + GetDirectionToTestCase { Position { 122, 123, 0 }, Position { 0, 0, 0 }, DIRECTION_NORTHWEST, DIRECTION_NORTH }, + GetDirectionToTestCase { Position { 0, 122, 0 }, Position { 123, 0, 0 }, DIRECTION_NORTHEAST, DIRECTION_EAST }, + GetDirectionToTestCase { Position { 0, 123, 0 }, Position { 122, 0, 0 }, DIRECTION_NORTHEAST, DIRECTION_NORTH }, + GetDirectionToTestCase { Position { 0, 0, 0 }, Position { 123, 122, 0 }, DIRECTION_SOUTHEAST, DIRECTION_EAST }, + GetDirectionToTestCase { Position { 0, 0, 0 }, Position { 122, 123, 0 }, DIRECTION_SOUTHEAST, DIRECTION_SOUTH }, + GetDirectionToTestCase { Position { 123, 0, 0 }, Position { 0, 122, 0 }, DIRECTION_SOUTHWEST, DIRECTION_WEST }, + GetDirectionToTestCase { Position { 122, 0, 0 }, Position { 0, 123, 0 }, DIRECTION_SOUTHWEST, DIRECTION_SOUTH }, }; for (auto getDirectionToTestCase : getDirectionToTestCases) { diff --git a/tests/unit/utils/string_functions_test.cpp b/tests/unit/utils/string_functions_test.cpp index 659f4b195..aa4860b26 100644 --- a/tests/unit/utils/string_functions_test.cpp +++ b/tests/unit/utils/string_functions_test.cpp @@ -8,14 +8,14 @@ using namespace boost::ut; suite<"utils"> replaceStringTest = [] { struct ReplaceStringTestCase { - std::string subject, search, replace, expected; + std::string subject, search, replace, expected; - [[nodiscard]] std::string toString() const { - return fmt::format("replace {} in {} by {}", search, subject, replace); - } + [[nodiscard]] std::string toString() const { + return fmt::format("replace {} in {} by {}", search, subject, replace); + } }; - std::vector replaceStringTestCases{ + std::vector replaceStringTestCases { ReplaceStringTestCase { "", "", "", "" }, ReplaceStringTestCase { "all together", " ", "_", "all_together" }, ReplaceStringTestCase { "beautiful", "u", "", "beatifl" }, @@ -26,7 +26,7 @@ suite<"utils"> replaceStringTest = [] { for (const auto &replaceStringTestCase : replaceStringTestCases) { test(replaceStringTestCase.toString()) = [&replaceStringTestCase] { - auto [subject, search, replace, expected] = replaceStringTestCase; + auto [subject, search, replace, expected] = replaceStringTestCase; replaceString(subject, search, replace); expect(eq(expected, subject)) << fmt::format("{} != {}", expected, subject); };