diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 7eacacb97c4..41ea6d14ec7 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -269,17 +269,38 @@ bool Player::isSuppress(ConditionType_t conditionType, bool attackerPlayer) cons return true; } - return m_conditionSuppressions[static_cast(conditionType)]; + auto conditionId = static_cast(conditionType); + return (m_conditionSuppressionCount[conditionId] > 0); } void Player::addConditionSuppressions(const std::array &addConditions) { - for (const auto &conditionType : addConditions) { - m_conditionSuppressions[static_cast(conditionType)] = true; + for (auto conditionType : addConditions) { + auto conditionId = static_cast(conditionType); + if (conditionId >= ConditionType_t::CONDITION_COUNT) { + continue; + } + if (m_conditionSuppressionCount[conditionId] < UINT8_MAX) { + m_conditionSuppressionCount[conditionId]++; + } } } -void Player::removeConditionSuppressions() { - m_conditionSuppressions.reset(); +void Player::removeConditionSuppressions(const std::vector &toRemoveConditions) { + for (auto conditionType : toRemoveConditions) { + if (conditionType == ConditionType_t::CONDITION_NONE) { + continue; + } + auto conditionSize = static_cast(conditionType); + if (conditionSize >= ConditionType_t::CONDITION_COUNT) { + continue; + } + if (m_conditionSuppressionCount[conditionSize] > 0) { + m_conditionSuppressionCount[conditionSize]--; + if (m_conditionSuppressionCount[conditionSize] == 0) { + sendIcons(); + } + } + } } std::shared_ptr Player::getWeapon(Slots_t slot, bool ignoreAmmo) const { diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index 536755fc687..030ffd2dd4d 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -561,7 +561,7 @@ class Player final : public Creature, public Cylinder, public Bankable { int32_t getDefaultStats(stats_t stat) const; void addConditionSuppressions(const std::array &addCondition); - void removeConditionSuppressions(); + void removeConditionSuppressions(const std::vector &toRemoveConditions); std::shared_ptr getReward(uint64_t rewardId, bool autoCreate); void removeReward(uint64_t rewardId); @@ -1500,7 +1500,7 @@ class Player final : public Creature, public Cylinder, public Bankable { std::bitset m_damageImmunities; std::bitset m_conditionImmunities; - std::bitset m_conditionSuppressions; + std::array m_conditionSuppressionCount {}; uint32_t level = 1; uint32_t magLevel = 0; diff --git a/src/lua/creature/movement.cpp b/src/lua/creature/movement.cpp index ee3c968473e..253f02e58bc 100644 --- a/src/lua/creature/movement.cpp +++ b/src/lua/creature/movement.cpp @@ -691,8 +691,17 @@ uint32_t MoveEvent::DeEquipItem(const std::shared_ptr &, const std::s g_game().changePlayerSpeed(player, -item->getSpeed()); } - player->removeConditionSuppressions(); - player->sendIcons(); + std::vector toRemove; + for (auto cond : it.abilities->conditionSuppressions) { + if (cond == ConditionType_t::CONDITION_NONE) { + continue; + } + toRemove.emplace_back(cond); + } + if (!toRemove.empty()) { + player->removeConditionSuppressions(toRemove); + player->sendIcons(); + } if (it.transformDeEquipTo != 0) { g_game().transformItem(item, it.transformDeEquipTo);