From 5bd86e66ae934fb6c350bc85f0585e560b4b4e4d Mon Sep 17 00:00:00 2001 From: Beats <61994374+beats-dh@users.noreply.github.com> Date: Tue, 19 Jul 2022 01:23:41 -0300 Subject: [PATCH] [Fix] remove summon bug and added new config tag for teleport summon (#428) Added new config.lua tag: teleportSummons = false Usage: if false, the summon will not teleport when the player goes up/down stairs and moves far away, if true, it will teleport the summon Fixed the bug that did not remove the summon when the player leaves the summon range, thus preventing the player from summoning a new monster --- config.lua.dist | 3 +++ src/config/config_definitions.hpp | 1 + src/config/configmanager.cpp | 1 + src/creatures/creature.cpp | 31 ++++++++++++++++++++----------- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/config.lua.dist b/config.lua.dist index e4014c2b13b..f9891123e9d 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -98,6 +98,9 @@ autoLoot = false -- autoBank = true, the dropped coins from monsters will be automatically -- deposited to your bank account. autoBank = false +-- teleporte summon +-- true will never remove the summon +teleportSummons = false -- Stamina in Trainers staminaTrainer = false diff --git a/src/config/config_definitions.hpp b/src/config/config_definitions.hpp index 471446edeb4..f7982695d4e 100644 --- a/src/config/config_definitions.hpp +++ b/src/config/config_definitions.hpp @@ -75,6 +75,7 @@ enum booleanConfig_t { AUTOBANK, RATE_USE_STAGES, INVENTORY_GLOW, + TELEPORT_SUMMONS, TOGGLE_DOWNLOAD_MAP, LAST_BOOLEAN_CONFIG diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 3b53065c1b1..7654d431175 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -183,6 +183,7 @@ bool ConfigManager::load() boolean[SORT_LOOT_BY_CHANCE] = getGlobalBoolean(L, "sortLootByChance", false); boolean[TOGGLE_SAVE_INTERVAL] = getGlobalBoolean(L, "toggleSaveInterval", false); boolean[TOGGLE_SAVE_INTERVAL_CLEAN_MAP] = getGlobalBoolean(L, "toggleSaveIntervalCleanMap", false); + boolean[TELEPORT_SUMMONS] = getGlobalBoolean(L, "teleportSummons", false); boolean[ONLY_PREMIUM_ACCOUNT] = getGlobalBoolean(L, "onlyPremiumAccount", false); boolean[RATE_USE_STAGES] = getGlobalBoolean(L, "rateUseStages", false); diff --git a/src/creatures/creature.cpp b/src/creatures/creature.cpp index de5074ff12d..360c27899e4 100644 --- a/src/creatures/creature.cpp +++ b/src/creatures/creature.cpp @@ -447,29 +447,38 @@ void Creature::onAttackedCreatureChangeZone(ZoneType_t zone) void Creature::checkSummonMove(const Position& newPos, bool teleportSummon) const { if (hasSummons()) { - // Check if any of our summons is out of range (+/- 2 floors or 30 tiles away) - std::forward_list despawnMonsterList; + std::vector despawnMonsterList; for (Creature* creature : getSummons()) { if (!creature) { continue; } - const Monster* monster = creature->getMonster(); - // Check is is familiar for teleport to the master, if "teleportSummon" is true, this is not executed const Position& pos = creature->getPosition(); - if (!teleportSummon && !monster->isFamiliar()) { - SPDLOG_DEBUG("[Creature::checkSummonMove] - Creature name {}", creature->getName()); + const Monster* monster = creature->getMonster(); + bool protectionZoneCheck = this->getTile()->hasFlag(TILESTATE_PROTECTIONZONE); + // 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); + // Check if any of our summons is out of range (+/- 2 floors or 30 tiles away) + bool checkRemoveDist = Position::getDistanceZ(newPos, pos) > 2 || + (std::max(Position::getDistanceX(newPos, pos), + Position::getDistanceY(newPos, pos)) > 30); + + if (monster->isFamiliar() && checkSummonDist || teleportSummon && !protectionZoneCheck && checkSummonDist) { + g_game().internalTeleport(creature, creature->getMaster()->getPosition(), true); continue; } - if (Position::getDistanceZ(newPos, pos) > 0 || (std::max(Position::getDistanceX(newPos, pos), Position::getDistanceY(newPos, pos)) > 15)) - { - g_game().internalTeleport(creature, creature->getMaster()->getPosition(), true); + if (monster->isSummon() && !monster->isFamiliar() && !teleportSummon && checkRemoveDist) { + despawnMonsterList.push_back(creature); } } for (Creature* despawnCreature : despawnMonsterList) { - g_game().removeCreature(despawnCreature, true); + if (!despawnMonsterList.empty()) { + g_game().removeCreature(despawnCreature, true); + } } } } @@ -493,7 +502,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos stopEventWalk(); } - checkSummonMove(newPos, false); + checkSummonMove(newPos, g_configManager().getBoolean(TELEPORT_SUMMONS)); if (Player* player = creature->getPlayer()) { if (player->isExerciseTraining()){