diff --git a/src/combat.cpp b/src/combat.cpp index 057aafcd28..5e6e8b7edf 100644 --- a/src/combat.cpp +++ b/src/combat.cpp @@ -609,9 +609,9 @@ void Combat::doCombat(const std::shared_ptr& caster, const std::shared if (params.origin != ORIGIN_MELEE) { for (const auto& condition : params.conditionList) { if (caster == target || !target->isImmune(condition->getType())) { - Condition* conditionCopy = condition->clone(); + auto conditionCopy = condition->clone(); conditionCopy->setParam(CONDITION_PARAM_OWNER, caster->getID()); - target->addCombatCondition(conditionCopy); + target->addCombatCondition(std::move(conditionCopy)); } } } @@ -693,13 +693,13 @@ void Combat::doCombat(const std::shared_ptr& caster, const Position& p (caster != creature && Combat::canDoCombat(caster, creature) == RETURNVALUE_NOERROR)) { for (const auto& condition : params.conditionList) { if (caster == creature || !creature->isImmune(condition->getType())) { - Condition* conditionCopy = condition->clone(); + auto conditionCopy = condition->clone(); if (caster) { conditionCopy->setParam(CONDITION_PARAM_OWNER, caster->getID()); } // TODO: infight condition until all aggressive conditions has ended - creature->addCombatCondition(conditionCopy); + creature->addCombatCondition(std::move(conditionCopy)); } } } @@ -767,13 +767,13 @@ void Combat::doTargetCombat(const std::shared_ptr& caster, const std:: if (damage.blockType == BLOCK_NONE || damage.blockType == BLOCK_ARMOR) { for (const auto& condition : params.conditionList) { if (caster == target || !target->isImmune(condition->getType())) { - Condition* conditionCopy = condition->clone(); + auto conditionCopy = condition->clone(); if (caster) { conditionCopy->setParam(CONDITION_PARAM_OWNER, caster->getID()); } // TODO: infight condition until all aggressive conditions has ended - target->addCombatCondition(conditionCopy); + target->addCombatCondition(std::move(conditionCopy)); } } } @@ -935,13 +935,13 @@ void Combat::doAreaCombat(const std::shared_ptr& caster, const Positio if (damage.blockType == BLOCK_NONE || damage.blockType == BLOCK_ARMOR) { for (const auto& condition : params.conditionList) { if (caster == creature || !creature->isImmune(condition->getType())) { - Condition* conditionCopy = condition->clone(); + auto conditionCopy = condition->clone(); if (caster) { conditionCopy->setParam(CONDITION_PARAM_OWNER, caster->getID()); } // TODO: infight condition until all aggressive conditions has ended - creature->addCombatCondition(conditionCopy); + creature->addCombatCondition(std::move(conditionCopy)); } } } @@ -1334,7 +1334,7 @@ void MagicField::onStepInField(const std::shared_ptr& creature) } if (const ItemType& it = items[getID()]; it.conditionDamage) { - Condition* conditionCopy = it.conditionDamage->clone(); + auto conditionCopy = it.conditionDamage->clone(); if (uint32_t ownerId = getOwner()) { bool harmfulField = true; @@ -1360,6 +1360,6 @@ void MagicField::onStepInField(const std::shared_ptr& creature) } } - creature->addCondition(conditionCopy); + creature->addCondition(std::move(conditionCopy)); } } diff --git a/src/combat.h b/src/combat.h index 62f53a42d2..cd7877781d 100644 --- a/src/combat.h +++ b/src/combat.h @@ -118,7 +118,7 @@ class Combat void setArea(AreaCombat* area); bool hasArea() const { return area != nullptr; } - void addCondition(const Condition* condition) { params.conditionList.emplace_back(condition); } + void addCondition(std::unique_ptr condition) { params.conditionList.emplace_back(std::move(condition)); } void clearConditions() { params.conditionList.clear(); } void setPlayerCombatValues(formulaType_t formulaType, double mina, double minb, double maxa, double maxb); void postCombatEffects(const std::shared_ptr& caster, const Position& pos) const diff --git a/src/condition.cpp b/src/condition.cpp index 53f8f9e432..26edba99d7 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -164,8 +164,9 @@ bool Condition::executeCondition(const std::shared_ptr&, int32_t inter return getEndTime() >= OTSYS_TIME(); } -Condition* Condition::createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, int32_t param /* = 0*/, - bool buff /* = false*/, uint32_t subId /* = 0*/, bool aggressive /* = false */) +std::unique_ptr Condition::createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, + int32_t param /* = 0*/, bool buff /* = false*/, + uint32_t subId /* = 0*/, bool aggressive /* = false */) { switch (type) { case CONDITION_POISON: @@ -176,38 +177,39 @@ 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, aggressive); + return std::make_unique(id, type, buff, subId, aggressive); case CONDITION_HASTE: case CONDITION_PARALYZE: - return new ConditionSpeed(id, type, ticks, buff, subId, param, aggressive); + return std::make_unique(id, type, ticks, buff, subId, param, aggressive); case CONDITION_INVISIBLE: - return new ConditionInvisible(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_OUTFIT: - return new ConditionOutfit(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_LIGHT: - return new ConditionLight(id, type, ticks, buff, subId, param & 0xFF, (param & 0xFF00) >> 8, aggressive); + return std::make_unique(id, type, ticks, buff, subId, param & 0xFF, (param & 0xFF00) >> 8, + aggressive); case CONDITION_REGENERATION: - return new ConditionRegeneration(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_SOUL: - return new ConditionSoul(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_ATTRIBUTES: - return new ConditionAttributes(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_SPELLCOOLDOWN: - return new ConditionSpellCooldown(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_SPELLGROUPCOOLDOWN: - return new ConditionSpellGroupCooldown(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_DRUNK: - return new ConditionDrunk(id, type, ticks, buff, subId, param, aggressive); + return std::make_unique(id, type, ticks, buff, subId, param, aggressive); case CONDITION_INFIGHT: case CONDITION_EXHAUST_WEAPON: @@ -218,18 +220,18 @@ Condition* Condition::createCondition(ConditionId_t id, ConditionType_t type, in case CONDITION_YELLTICKS: case CONDITION_PACIFIED: case CONDITION_MANASHIELD: - return new ConditionGeneric(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_ROOT: - return new ConditionGeneric(id, type, ticks, buff, subId, aggressive); + return std::make_unique(id, type, ticks, buff, subId, aggressive); case CONDITION_MANASHIELD_BREAKABLE: - return new ConditionManaShield(id, type, ticks, buff, subId); + return std::make_unique(id, type, ticks, buff, subId); default: return nullptr; } } -Condition* Condition::createCondition(PropStream& propStream) +std::unique_ptr Condition::createCondition(PropStream& propStream) { uint8_t attr; if (!propStream.read(attr) || attr != CONDITIONATTR_TYPE) { diff --git a/src/condition.h b/src/condition.h index 6657460559..4574602fbb 100644 --- a/src/condition.h +++ b/src/condition.h @@ -81,7 +81,7 @@ class Condition ConditionId_t getId() const { return id; } uint32_t getSubId() const { return subId; } - virtual Condition* clone() const = 0; + virtual std::unique_ptr clone() const = 0; ConditionType_t getType() const { return conditionType; } int64_t getEndTime() const { return endTime; } @@ -89,9 +89,10 @@ class Condition void setTicks(int32_t newTicks); bool isAggressive() const { return aggressive; } - static Condition* createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, int32_t param = 0, - bool buff = false, uint32_t subId = 0, bool aggressive = false); - static Condition* createCondition(PropStream& propStream); + static std::unique_ptr createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, + int32_t param = 0, bool buff = false, uint32_t subId = 0, + bool aggressive = false); + static std::unique_ptr createCondition(PropStream& propStream); virtual bool setParam(ConditionParam_t param, int32_t value); virtual int32_t getParam(ConditionParam_t param); @@ -131,7 +132,7 @@ class ConditionGeneric : public Condition void addCondition(const std::shared_ptr& creature, const Condition* condition) override; uint32_t getIcons() const override; - ConditionGeneric* clone() const override { return new ConditionGeneric(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } }; class ConditionAttributes final : public ConditionGeneric @@ -150,7 +151,7 @@ class ConditionAttributes final : public ConditionGeneric bool setParam(ConditionParam_t param, int32_t value) override; int32_t getParam(ConditionParam_t param) override; - ConditionAttributes* clone() const override { return new ConditionAttributes(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } // serialization void serialize(PropWriteStream& propWriteStream) override; @@ -188,7 +189,7 @@ class ConditionRegeneration final : public ConditionGeneric bool setParam(ConditionParam_t param, int32_t value) override; int32_t getParam(ConditionParam_t param) override; - ConditionRegeneration* clone() const override { return new ConditionRegeneration(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } // serialization void serialize(PropWriteStream& propWriteStream) override; @@ -218,7 +219,7 @@ class ConditionSoul final : public ConditionGeneric bool setParam(ConditionParam_t param, int32_t value) override; int32_t getParam(ConditionParam_t param) override; - ConditionSoul* clone() const override { return new ConditionSoul(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } // serialization void serialize(PropWriteStream& propWriteStream) override; @@ -241,7 +242,7 @@ class ConditionInvisible final : public ConditionGeneric bool startCondition(const std::shared_ptr& creature) override; void endCondition(const std::shared_ptr& creature) override; - ConditionInvisible* clone() const override { return new ConditionInvisible(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } }; class ConditionDamage final : public Condition @@ -261,7 +262,7 @@ class ConditionDamage final : public Condition void addCondition(const std::shared_ptr& creature, const Condition* condition) override; uint32_t getIcons() const override; - ConditionDamage* clone() const override { return new ConditionDamage(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } bool setParam(ConditionParam_t param, int32_t value) override; int32_t getParam(ConditionParam_t param) override; @@ -314,7 +315,7 @@ class ConditionSpeed final : public Condition void addCondition(const std::shared_ptr& creature, const Condition* condition) override; uint32_t getIcons() const override; - ConditionSpeed* clone() const override { return new ConditionSpeed(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } bool setParam(ConditionParam_t param, int32_t value) override; int32_t getParam(ConditionParam_t param) override; @@ -348,7 +349,7 @@ class ConditionOutfit final : public Condition void endCondition(const std::shared_ptr& creature) override; void addCondition(const std::shared_ptr& creature, const Condition* condition) override; - ConditionOutfit* clone() const override { return new ConditionOutfit(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } void setOutfit(const Outfit_t& outfit); @@ -373,7 +374,7 @@ class ConditionLight final : public Condition void endCondition(const std::shared_ptr& creature) override; void addCondition(const std::shared_ptr& creature, const Condition* condition) override; - ConditionLight* clone() const override { return new ConditionLight(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } bool setParam(ConditionParam_t param, int32_t value) override; int32_t getParam(ConditionParam_t param) override; @@ -399,7 +400,7 @@ class ConditionSpellCooldown final : public ConditionGeneric bool startCondition(const std::shared_ptr& creature) override; void addCondition(const std::shared_ptr& creature, const Condition* condition) override; - ConditionSpellCooldown* clone() const override { return new ConditionSpellCooldown(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } }; class ConditionSpellGroupCooldown final : public ConditionGeneric @@ -413,7 +414,7 @@ class ConditionSpellGroupCooldown final : public ConditionGeneric bool startCondition(const std::shared_ptr& creature) override; void addCondition(const std::shared_ptr& creature, const Condition* condition) override; - ConditionSpellGroupCooldown* clone() const override { return new ConditionSpellGroupCooldown(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } }; class ConditionDrunk final : public Condition @@ -434,7 +435,7 @@ class ConditionDrunk final : public Condition bool setParam(ConditionParam_t param, int32_t value) override; void addCondition(const std::shared_ptr& creature, const Condition* condition) override; - ConditionDrunk* clone() const override { return new ConditionDrunk(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } private: uint8_t drunkenness = 25; @@ -457,7 +458,7 @@ class ConditionManaShield final : public Condition bool setParam(ConditionParam_t param, int32_t value) override; - ConditionManaShield* clone() const override { return new ConditionManaShield(*this); } + std::unique_ptr clone() const override { return std::make_unique(*this); } // serialization void serialize(PropWriteStream& propWriteStream) override; diff --git a/src/creature.cpp b/src/creature.cpp index 3ce8653c51..0e3acb183a 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1073,7 +1073,7 @@ bool Creature::setMaster(const std::shared_ptr& newMaster) return true; } -bool Creature::addCondition(Condition* condition, bool force /* = false*/) +bool Creature::addCondition(std::unique_ptr condition, bool force /* = false*/) { if (!condition) { return false; @@ -1083,34 +1083,33 @@ bool Creature::addCondition(Condition* condition, bool force /* = false*/) int64_t walkDelay = getWalkDelay(); if (walkDelay > 0) { g_scheduler.addEvent( - createSchedulerTask(walkDelay, [=, id = getID()]() { g_game.forceAddCondition(id, condition); })); + createSchedulerTask(walkDelay, [id = getID(), condition = std::move(condition)]() mutable { + g_game.forceAddCondition(id, std::move(condition)); + })); return false; } } Condition* prevCond = getCondition(condition->getType(), condition->getId(), condition->getSubId()); if (prevCond) { - prevCond->addCondition(asCreature(), condition); - delete condition; + prevCond->addCondition(asCreature(), condition.get()); return true; } if (condition->startCondition(asCreature())) { - conditions.push_back(condition); onAddCondition(condition->getType()); + conditions.push_back(std::move(condition)); return true; } - delete condition; return false; } -bool Creature::addCombatCondition(Condition* condition) +bool Creature::addCombatCondition(std::unique_ptr condition) { - // Caution: condition variable could be deleted after the call to addCondition ConditionType_t type = condition->getType(); - if (!addCondition(condition)) { + if (!addCondition(std::move(condition))) { return false; } @@ -1122,7 +1121,7 @@ void Creature::removeCondition(ConditionType_t type, bool force /* = false*/) { auto it = conditions.begin(); while (it != conditions.end()) { - Condition* condition = *it; + auto& condition = *it; if (condition->getType() != type) { ++it; continue; @@ -1137,10 +1136,8 @@ void Creature::removeCondition(ConditionType_t type, bool force /* = false*/) } } - it = conditions.erase(it); - condition->endCondition(asCreature()); - delete condition; + it = conditions.erase(it); onEndCondition(type); } @@ -1150,7 +1147,7 @@ void Creature::removeCondition(ConditionType_t type, ConditionId_t conditionId, { auto it = conditions.begin(); while (it != conditions.end()) { - Condition* condition = *it; + auto& condition = *it; if (condition->getType() != type || condition->getId() != conditionId) { ++it; continue; @@ -1165,10 +1162,8 @@ void Creature::removeCondition(ConditionType_t type, ConditionId_t conditionId, } } - it = conditions.erase(it); - condition->endCondition(asCreature()); - delete condition; + it = conditions.erase(it); onEndCondition(type); } @@ -1177,9 +1172,9 @@ void Creature::removeCondition(ConditionType_t type, ConditionId_t conditionId, void Creature::removeCombatCondition(ConditionType_t type) { std::vector removeConditions; - for (Condition* condition : conditions) { + for (const auto& condition : conditions) { if (condition->getType() == type) { - removeConditions.push_back(condition); + removeConditions.push_back(condition.get()); } } @@ -1190,7 +1185,8 @@ void Creature::removeCombatCondition(ConditionType_t type) void Creature::removeCondition(Condition* condition, bool force /* = false*/) { - auto it = std::find(conditions.begin(), conditions.end(), condition); + auto it = std::find_if(conditions.begin(), conditions.end(), + [condition](const std::unique_ptr& c) { return c.get() == condition; }); if (it == conditions.end()) { return; } @@ -1204,18 +1200,16 @@ void Creature::removeCondition(Condition* condition, bool force /* = false*/) } } - conditions.erase(it); - condition->endCondition(asCreature()); onEndCondition(condition->getType()); - delete condition; + conditions.erase(it); } Condition* Creature::getCondition(ConditionType_t type) const { - for (Condition* condition : conditions) { + for (const auto& condition : conditions) { if (condition->getType() == type) { - return condition; + return condition.get(); } } return nullptr; @@ -1223,9 +1217,9 @@ Condition* Creature::getCondition(ConditionType_t type) const Condition* Creature::getCondition(ConditionType_t type, ConditionId_t conditionId, uint32_t subId /* = 0*/) const { - for (Condition* condition : conditions) { + for (const auto& condition : conditions) { if (condition->getType() == type && condition->getId() == conditionId && condition->getSubId() == subId) { - return condition; + return condition.get(); } } return nullptr; @@ -1233,20 +1227,26 @@ Condition* Creature::getCondition(ConditionType_t type, ConditionId_t conditionI void Creature::executeConditions(uint32_t interval) { - auto tempConditions = conditions; + std::vector tempConditions; + tempConditions.reserve(conditions.size()); + for (const auto& condition : conditions) { + tempConditions.push_back(condition.get()); + } + for (Condition* condition : tempConditions) { - auto it = std::find(conditions.begin(), conditions.end(), condition); + auto it = std::find_if(conditions.begin(), conditions.end(), + [condition](const std::unique_ptr& c) { return c.get() == condition; }); if (it == conditions.end()) { continue; } if (!condition->executeCondition(asCreature(), interval)) { - it = std::find(conditions.begin(), conditions.end(), condition); + it = std::find_if(conditions.begin(), conditions.end(), + [condition](const std::unique_ptr& c) { return c.get() == condition; }); if (it != conditions.end()) { - conditions.erase(it); condition->endCondition(asCreature()); onEndCondition(condition->getType()); - delete condition; + conditions.erase(it); } } } @@ -1259,7 +1259,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; } @@ -1436,7 +1436,7 @@ 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::unique_ptr& condition) { return condition->getType() == CONDITION_INVISIBLE; }) != conditions.end(); } diff --git a/src/creature.h b/src/creature.h index 532c745023..48e9ef37e4 100644 --- a/src/creature.h +++ b/src/creature.h @@ -238,8 +238,8 @@ class Creature : public Thing virtual float getAttackFactor() const { return 1.0f; } virtual float getDefenseFactor() const { return 1.0f; } - bool addCondition(Condition* condition, bool force = false); - bool addCombatCondition(Condition* condition); + bool addCondition(std::unique_ptr condition, bool force = false); + bool addCombatCondition(std::unique_ptr condition); void removeCondition(ConditionType_t type, ConditionId_t conditionId, bool force = false); void removeCondition(ConditionType_t type, bool force = false); void removeCondition(Condition* condition, bool force = false); @@ -365,7 +365,7 @@ class Creature : public Thing int64_t ticks; }; - std::vector conditions; + std::vector> conditions; CreatureIconHashMap creatureIcons; std::vector listWalkDir; diff --git a/src/game.cpp b/src/game.cpp index 189ed9d628..04713f84e2 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3552,8 +3552,8 @@ bool Game::playerYell(const std::shared_ptr& player, const std::string& } } - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_YELLTICKS, 30000, 0); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_YELLTICKS, 30000, 0); + player->addCondition(std::move(condition)); } internalCreatureSay(player, TALKTYPE_YELL, boost::algorithm::to_upper_copy(text), false); @@ -5374,15 +5374,14 @@ std::vector> Game::getMarketItemList(uint16_t wareId, uint return {}; } -void Game::forceAddCondition(uint32_t creatureId, Condition* condition) +void Game::forceAddCondition(uint32_t creatureId, std::unique_ptr condition) { const auto& creature = getCreatureByID(creatureId); if (!creature) { - delete condition; return; } - creature->addCondition(condition, true); + creature->addCondition(std::move(condition), true); } void Game::forceRemoveCondition(uint32_t creatureId, ConditionType_t type) diff --git a/src/game.h b/src/game.h index c9926e32ac..f426150c49 100644 --- a/src/game.h +++ b/src/game.h @@ -80,7 +80,7 @@ class Game void start(ServiceManager* manager); - void forceAddCondition(uint32_t creatureId, Condition* condition); + void forceAddCondition(uint32_t creatureId, std::unique_ptr condition); void forceRemoveCondition(uint32_t creatureId, ConditionType_t type); void loadMainMap(const std::string& filename); diff --git a/src/iologindata.cpp b/src/iologindata.cpp index f834747f9f..56aa759829 100644 --- a/src/iologindata.cpp +++ b/src/iologindata.cpp @@ -191,12 +191,10 @@ bool IOLoginData::loadPlayer(const std::shared_ptr& player, std::shared_ PropStream propStream; propStream.init(conditions.data(), conditions.size()); - Condition* condition = Condition::createCondition(propStream); + auto condition = Condition::createCondition(propStream); while (condition) { if (condition->unserialize(propStream)) { - player->storedConditionList.push_front(condition); - } else { - delete condition; + player->storedConditionList.push_front(std::move(condition)); } condition = Condition::createCondition(propStream); } diff --git a/src/lua/modules/condition.cpp b/src/lua/modules/condition.cpp index 9573e28116..ff664fdc8f 100644 --- a/src/lua/modules/condition.cpp +++ b/src/lua/modules/condition.cpp @@ -15,9 +15,9 @@ int luaConditionCreate(lua_State* L) ConditionType_t conditionType = tfs::lua::getNumber(L, 2); ConditionId_t conditionId = tfs::lua::getNumber(L, 3, CONDITIONID_COMBAT); - Condition* condition = Condition::createCondition(conditionId, conditionType, 0, 0); + auto condition = Condition::createCondition(conditionId, conditionType, 0, 0); if (condition) { - tfs::lua::pushUserdata(L, condition); + tfs::lua::pushUserdata(L, condition.release()); tfs::lua::setMetatable(L, -1, "Condition"); } else { lua_pushnil(L); @@ -101,7 +101,7 @@ int luaConditionClone(lua_State* L) // condition:clone() Condition* condition = tfs::lua::getUserdata(L, 1); if (condition) { - tfs::lua::pushUserdata(L, condition->clone()); + tfs::lua::pushUserdata(L, condition->clone().release()); tfs::lua::setMetatable(L, -1, "Condition"); } else { lua_pushnil(L); diff --git a/src/monsters.cpp b/src/monsters.cpp index 9155108699..25ea6e1d71 100644 --- a/src/monsters.cpp +++ b/src/monsters.cpp @@ -67,11 +67,11 @@ bool Monsters::reload() return loadFromXml(true); } -ConditionDamage* Monsters::getDamageCondition(ConditionType_t conditionType, int32_t maxDamage, int32_t minDamage, - int32_t startDamage, uint32_t tickInterval) +std::unique_ptr 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)); + auto condition = std::make_unique(CONDITIONID_COMBAT, conditionType); condition->setParam(CONDITION_PARAM_TICKINTERVAL, tickInterval); condition->setParam(CONDITION_PARAM_MINVALUE, minDamage); condition->setParam(CONDITION_PARAM_MAXVALUE, maxDamage); @@ -291,8 +291,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co } if (conditionType != CONDITION_NONE) { - Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, 0, tickInterval); - combat->addCondition(condition); + combat->addCondition(getDamageCondition(conditionType, maxDamage, minDamage, 0, tickInterval)); } sb.range = 1; @@ -370,10 +369,9 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co conditionType = CONDITION_PARALYZE; } - ConditionSpeed* condition = static_cast( - Condition::createCondition(CONDITIONID_COMBAT, conditionType, duration, 0)); + auto condition = std::make_unique(CONDITIONID_COMBAT, conditionType, duration, false, 0, 0); condition->setFormulaVars(minSpeedChange / 1000.0, 0, maxSpeedChange / 1000.0, 0); - combat->addCondition(condition); + combat->addCondition(std::move(condition)); } else if (tmpName == "outfit") { int32_t duration = 10000; @@ -384,21 +382,19 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co if ((attr = node.attribute("monster"))) { MonsterType* mType = g_monsters.getMonsterType(attr.as_string()); if (mType) { - ConditionOutfit* condition = static_cast( - Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); + auto condition = std::make_unique(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration); condition->setOutfit(mType->info.outfit); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); - combat->addCondition(condition); + combat->addCondition(std::move(condition)); } } else if ((attr = node.attribute("item"))) { Outfit_t outfit; outfit.lookTypeEx = pugi::cast(attr.value()); - ConditionOutfit* condition = static_cast( - Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); + auto condition = std::make_unique(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration); condition->setOutfit(outfit); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); - combat->addCondition(condition); + combat->addCondition(std::move(condition)); } } else if (tmpName == "invisible") { int32_t duration = 10000; @@ -407,9 +403,9 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co duration = pugi::cast(attr.value()); } - Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0); + auto condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); - combat->addCondition(condition); + combat->addCondition(std::move(condition)); } else if (tmpName == "drunk") { int32_t duration = 10000; uint8_t drunkenness = 25; @@ -422,9 +418,8 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co drunkenness = pugi::cast(attr.value()); } - Condition* condition = - Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, drunkenness); - combat->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, drunkenness); + combat->addCondition(std::move(condition)); } else if (tmpName == "firefield") { combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL); } else if (tmpName == "poisonfield") { @@ -483,8 +478,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co } } - Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval); - combat->addCondition(condition); + combat->addCondition(getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval)); } else if (tmpName == "strength") { // } else if (tmpName == "effect") { @@ -629,9 +623,8 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std int32_t conMaxDamage = std::abs(spell->conditionMaxDamage); int32_t startDamage = std::abs(spell->conditionStartDamage); - Condition* condition = - getDamageCondition(conditionType, conMaxDamage, conMinDamage, startDamage, tickInterval); - combat->addCondition(condition); + combat->addCondition( + getDamageCondition(conditionType, conMaxDamage, conMinDamage, startDamage, tickInterval)); } std::string tmpName = boost::algorithm::to_lower_copy(spell->name); @@ -701,10 +694,9 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std conditionType = CONDITION_PARALYZE; } - ConditionSpeed* condition = static_cast( - Condition::createCondition(CONDITIONID_COMBAT, conditionType, duration, 0)); + auto condition = std::make_unique(CONDITIONID_COMBAT, conditionType, duration, false, 0, 0); condition->setFormulaVars(minSpeedChange / 1000.0, 0, maxSpeedChange / 1000.0, 0); - combat->addCondition(condition); + combat->addCondition(std::move(condition)); } else if (tmpName == "outfit") { int32_t duration = 10000; @@ -712,11 +704,10 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std duration = spell->duration; } - ConditionOutfit* condition = static_cast( - Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); + auto condition = std::make_unique(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration); condition->setOutfit(spell->outfit); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); - combat->addCondition(condition); + combat->addCondition(std::move(condition)); } else if (tmpName == "invisible") { int32_t duration = 10000; @@ -724,9 +715,9 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std duration = spell->duration; } - Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0); + auto condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); - combat->addCondition(condition); + combat->addCondition(std::move(condition)); } else if (tmpName == "drunk") { int32_t duration = 10000; uint8_t drunkenness = 25; @@ -739,9 +730,8 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std drunkenness = spell->drunkenness; } - Condition* condition = - Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, drunkenness); - combat->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, drunkenness); + combat->addCondition(std::move(condition)); } else if (tmpName == "firefield") { combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL); } else if (tmpName == "poisonfield") { diff --git a/src/monsters.h b/src/monsters.h index 7eac47e19a..738e92d78c 100644 --- a/src/monsters.h +++ b/src/monsters.h @@ -264,8 +264,8 @@ class Monsters std::map> bestiary; private: - ConditionDamage* getDamageCondition(ConditionType_t conditionType, int32_t maxDamage, int32_t minDamage, - int32_t startDamage, uint32_t tickInterval); + std::unique_ptr getDamageCondition(ConditionType_t conditionType, int32_t maxDamage, + int32_t minDamage, int32_t startDamage, uint32_t tickInterval); bool deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, const std::string& description = ""); MonsterType* loadMonster(const std::string& file, const std::string& monsterName, bool reloading = false); diff --git a/src/movement.cpp b/src/movement.cpp index 9b633758a3..4fa27aa2d0 100644 --- a/src/movement.cpp +++ b/src/movement.cpp @@ -713,14 +713,13 @@ ReturnValue MoveEvent::EquipItem(MoveEvent* moveEvent, const std::shared_ptrinvisible) { - Condition* condition = Condition::createCondition(static_cast(slot), CONDITION_INVISIBLE, -1, 0); - player->addCondition(condition); + auto condition = Condition::createCondition(static_cast(slot), CONDITION_INVISIBLE, -1, 0); + player->addCondition(std::move(condition)); } if (it.abilities->manaShield) { - Condition* condition = - Condition::createCondition(static_cast(slot), CONDITION_MANASHIELD, -1, 0); - player->addCondition(condition); + auto condition = Condition::createCondition(static_cast(slot), CONDITION_MANASHIELD, -1, 0); + player->addCondition(std::move(condition)); } if (it.abilities->speed != 0) { @@ -733,8 +732,7 @@ ReturnValue MoveEvent::EquipItem(MoveEvent* moveEvent, const std::shared_ptrregeneration) { - Condition* condition = - Condition::createCondition(static_cast(slot), CONDITION_REGENERATION, -1, 0); + auto condition = Condition::createCondition(static_cast(slot), CONDITION_REGENERATION, -1, 0); if (it.abilities->healthGain != 0) { condition->setParam(CONDITION_PARAM_HEALTHGAIN, it.abilities->healthGain); @@ -752,7 +750,7 @@ ReturnValue MoveEvent::EquipItem(MoveEvent* moveEvent, const std::shared_ptrsetParam(CONDITION_PARAM_MANATICKS, it.abilities->manaTicks); } - player->addCondition(condition); + player->addCondition(std::move(condition)); } // skill modifiers diff --git a/src/player.cpp b/src/player.cpp index 08668c982f..52c561d67a 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1007,8 +1007,8 @@ void Player::onCreatureAppear(const std::shared_ptr& creature, bool is if (isLogin) { // Restore conditions stored during previous logout - for (Condition* condition : storedConditionList) { - addCondition(condition); + for (auto& condition : storedConditionList) { + addCondition(std::move(condition)); } storedConditionList.clear(); @@ -1271,8 +1271,8 @@ void Player::onCreatureMove(const std::shared_ptr& creature, const std if (teleport || oldPos.z != newPos.z) { int32_t ticks = getNumber(ConfigManager::STAIRHOP_DELAY); if (ticks > 0) { - if (Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_PACIFIED, ticks, 0)) { - addCondition(condition); + if (auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_PACIFIED, ticks, 0)) { + addCondition(std::move(condition)); } } } @@ -1524,8 +1524,8 @@ void Player::removeMessageBuffer() uint32_t muteTime = 5 * muteCount * muteCount; muteCountMap[guid] = muteCount + 1; - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_MUTED, muteTime * 1000, 0); - addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_MUTED, muteTime * 1000, 0); + addCondition(std::move(condition)); sendTextMessage(MESSAGE_STATUS_SMALL, std::format("You are muted for {:d} seconds.", muteTime)); } @@ -2068,13 +2068,11 @@ void Player::death(const std::shared_ptr& lastHitCreature) auto it = conditions.begin(); while (it != conditions.end()) { - Condition* condition = *it; + auto& condition = *it; if (condition->isPersistent()) { - it = conditions.erase(it); - condition->endCondition(asPlayer()); onEndCondition(condition->getType()); - delete condition; + it = conditions.erase(it); } else { ++it; } @@ -2084,13 +2082,11 @@ void Player::death(const std::shared_ptr& lastHitCreature) auto it = conditions.begin(); while (it != conditions.end()) { - Condition* condition = *it; + auto& condition = *it; if (condition->isPersistent()) { - it = conditions.erase(it); - condition->endCondition(asPlayer()); onEndCondition(condition->getType()); - delete condition; + it = conditions.erase(it); } else { ++it; } @@ -2174,9 +2170,9 @@ void Player::addInFightTicks(bool pzlock /*= false*/) pzLocked = true; } - Condition* condition = + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, getNumber(ConfigManager::PZ_LOCKED), 0); - addCondition(condition); + addCondition(std::move(condition)); } void Player::kickPlayer(bool displayEffect) @@ -3548,9 +3544,9 @@ bool Player::onKilledCreature(const std::shared_ptr& target, bool last if (lastHit && hasCondition(CONDITION_INFIGHT)) { pzLocked = true; - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, - getNumber(ConfigManager::WHITE_SKULL_TIME) * 1000, 0); - addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, + getNumber(ConfigManager::WHITE_SKULL_TIME) * 1000, 0); + addCondition(std::move(condition)); } } } diff --git a/src/player.h b/src/player.h index dd051c01af..02eb5a2dbf 100644 --- a/src/player.h +++ b/src/player.h @@ -1258,7 +1258,7 @@ class Player final : public Creature std::forward_list> invitePartyList; std::forward_list modalWindows; std::forward_list learnedInstantSpellList; - std::forward_list + std::forward_list> storedConditionList; // TODO: This variable is only temporarily used when logging in, get rid of it somehow std::string name; diff --git a/src/spells.cpp b/src/spells.cpp index 6bcc69039b..2666552a97 100644 --- a/src/spells.cpp +++ b/src/spells.cpp @@ -741,21 +741,21 @@ void Spell::postCastSpell(const std::shared_ptr& player, bool finishedCa if (finishedCast) { if (!player->hasFlag(PlayerFlag_HasNoExhaustion)) { if (cooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLCOOLDOWN, - cooldown, 0, false, spellId); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLCOOLDOWN, cooldown, 0, + false, spellId); + player->addCondition(std::move(condition)); } if (groupCooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, - groupCooldown, 0, false, group); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, + groupCooldown, 0, false, group); + player->addCondition(std::move(condition)); } if (secondaryGroupCooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, - secondaryGroupCooldown, 0, false, secondaryGroup); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, + secondaryGroupCooldown, 0, false, secondaryGroup); + player->addCondition(std::move(condition)); } } @@ -865,22 +865,21 @@ bool InstantSpell::playerCastInstant(const std::shared_ptr& player, std: if (!target || target->isRemoved() || target->isDead()) { if (!casterTargetOrDirection) { if (cooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLCOOLDOWN, - cooldown, 0, false, spellId); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLCOOLDOWN, + cooldown, 0, false, spellId); + player->addCondition(std::move(condition)); } if (groupCooldown > 0) { - Condition* condition = Condition::createCondition( - CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, groupCooldown, 0, false, group); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, + groupCooldown, 0, false, group); + player->addCondition(std::move(condition)); } if (secondaryGroupCooldown > 0) { - Condition* condition = - Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, - secondaryGroupCooldown, 0, false, secondaryGroup); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, + secondaryGroupCooldown, 0, false, secondaryGroup); + player->addCondition(std::move(condition)); } player->sendCancelMessage(ret); @@ -929,21 +928,21 @@ bool InstantSpell::playerCastInstant(const std::shared_ptr& player, std: if (ret != RETURNVALUE_NOERROR) { if (cooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLCOOLDOWN, - cooldown, 0, false, spellId); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLCOOLDOWN, cooldown, + 0, false, spellId); + player->addCondition(std::move(condition)); } if (groupCooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, - groupCooldown, 0, false, group); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, + groupCooldown, 0, false, group); + player->addCondition(std::move(condition)); } if (secondaryGroupCooldown > 0) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, - secondaryGroupCooldown, 0, false, secondaryGroup); - player->addCondition(condition); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_SPELLGROUPCOOLDOWN, + secondaryGroupCooldown, 0, false, secondaryGroup); + player->addCondition(std::move(condition)); } player->sendCancelMessage(ret);