diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 25 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 15 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 29 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 3 | ||||
| -rw-r--r-- | src/server/game/Groups/Group.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 7 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 10 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellHistory.cpp | 13 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellHistory.h | 6 | ||||
| -rw-r--r-- | src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h | 2 | ||||
| -rw-r--r-- | src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp | 5 | ||||
| -rw-r--r-- | src/server/scripts/Pet/pet_mage.cpp | 6 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_paladin.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/World/duel_reset.cpp | 43 | 
16 files changed, 112 insertions, 60 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 69a0f684a84..808491495a9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2305,6 +2305,31 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u              }              break;          } +        case SMART_ACTION_RANDOM_SOUND: +        { +            std::vector<uint32> sounds; +            std::copy_if(e.action.randomSound.sounds.begin(), e.action.randomSound.sounds.end(), +                std::back_inserter(sounds), [](uint32 sound) { return sound != 0; }); + +            bool onlySelf = e.action.randomSound.onlySelf != 0; + +            if (ObjectList* targets = GetTargets(e, unit)) +            { +                for (WorldObject* const obj : *targets) +                { +                    if (IsUnit(obj)) +                    { +                        uint32 sound = Trinity::Containers::SelectRandomContainerElement(sounds); +                        obj->PlayDirectSound(sound, onlySelf ? obj->ToPlayer() : nullptr); +                        TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_SOUND: target: %s (%s), sound: %u, onlyself: %s", +                            obj->GetName().c_str(), obj->GetGUID().ToString().c_str(), sound, onlySelf ? "true" : "false"); +                    } +                } + +                delete targets; +                break; +            } +        }          default:              TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());              break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index d56983924b4..977847e60c9 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -827,6 +827,21 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)              if (e.action.randomEmote.emote6 && !IsEmoteValid(e, e.action.randomEmote.emote6))                  return false;              break; +        case SMART_ACTION_RANDOM_SOUND: +        { +            if (std::all_of(e.action.randomSound.sounds.begin(), e.action.randomSound.sounds.end(), [](uint32 sound) { return sound == 0; })) +            { +                TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u does not have any non-zero sound", +                    e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); +                return false; +            } + +            for (uint32 sound : e.action.randomSound.sounds) +                if (sound && !IsSoundValid(e, sound)) +                    return false; + +            break; +        }          case SMART_ACTION_CAST:          {              if (!IsSpellValid(e, e.action.cast.spell)) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 91ee0a1d1e0..c0ea648462d 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -43,6 +43,16 @@ struct WayPoint      float z;  }; +enum eSmartAI +{ +    SMART_EVENT_PARAM_COUNT = 4, +    SMART_ACTION_PARAM_COUNT = 6, +    SMART_SUMMON_COUNTER = 0xFFFFFF, +    SMART_ESCORT_LAST_OOC_POINT = 0xFFFFFF, +    SMART_RANDOM_POINT = 0xFFFFFE, +    SMART_ESCORT_TARGETS = 0xFFFFFF +}; +  enum SMART_EVENT_PHASE  {      SMART_EVENT_PHASE_ALWAYS  = 0, @@ -540,8 +550,9 @@ enum SMART_ACTION      SMART_ACTION_GAME_EVENT_START                   = 112,    // GameEventId      SMART_ACTION_START_CLOSEST_WAYPOINT             = 113,    // wp1, wp2, wp3, wp4, wp5, wp6, wp7      SMART_ACTION_RISE_UP                            = 114,    // distance +    SMART_ACTION_RANDOM_SOUND                       = 115,    // soundId1, soundId2, soundId3, soundId4, soundId5, onlySelf -    SMART_ACTION_END                                = 115 +    SMART_ACTION_END                                = 116  };  struct SmartAction @@ -1017,6 +1028,12 @@ struct SmartAction              uint32 wp6;          } closestWaypointFromList; +        struct +        { +            std::array<uint32, SMART_ACTION_PARAM_COUNT - 1> sounds; +            uint32 onlySelf; +        } randomSound; +          //! Note for any new future actions          //! All parameters must have type uint32 @@ -1180,16 +1197,6 @@ struct SmartTarget      };  }; -enum eSmartAI -{ -    SMART_EVENT_PARAM_COUNT     = 4, -    SMART_ACTION_PARAM_COUNT    = 6, -    SMART_SUMMON_COUNTER        = 0xFFFFFF, -    SMART_ESCORT_LAST_OOC_POINT = 0xFFFFFF, -    SMART_RANDOM_POINT          = 0xFFFFFE, -    SMART_ESCORT_TARGETS        = 0xFFFFFF -}; -  enum SmartScriptType  {      SMART_SCRIPT_TYPE_CREATURE = 0, //done diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index a826f841058..30ba95eb174 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -7099,9 +7099,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere                      float chance = 100.0f / procSpell->Effects[effIndex].ChainTarget;                      if (!roll_chance_f(chance))                          return false; - -                    // Remove cooldown (Chain Lightning - has Category Recovery time) -                    GetSpellHistory()->ResetCooldown(spellId);                  }                  CastSpell(victim, spellId, true, castItem, triggeredByAura); diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 8ebc71b0146..43159828a3c 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -2274,6 +2274,8 @@ LootMethod Group::GetLootMethod() const  ObjectGuid Group::GetLooterGuid() const  { +    if (GetLootMethod() == FREE_FOR_ALL) +        return ObjectGuid::Empty;      return m_looterGuid;  } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index a4e7f61d83c..6a10d113553 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1103,18 +1103,11 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const      if (apply)      { -        // Remove cooldown of spells triggered on stance change - they may share cooldown with stance spell          if (spellId) -        { -            target->GetSpellHistory()->ResetCooldown(spellId);              target->CastSpell(target, spellId, true, NULL, this); -        }          if (spellId2) -        { -            target->GetSpellHistory()->ResetCooldown(spellId2);              target->CastSpell(target, spellId2, true, NULL, this); -        }          if (target->GetTypeId() == TYPEID_PLAYER)          { diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 84bff4a69d6..63fe148dd93 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4701,7 +4701,7 @@ SpellCastResult Spell::CheckCast(bool strict)                  return SPELL_FAILED_NOT_READY;          } -        if (!m_caster->GetSpellHistory()->IsReady(m_spellInfo, m_castItemEntry)) +        if (!m_caster->GetSpellHistory()->IsReady(m_spellInfo, m_castItemEntry, IsIgnoringCooldowns()))          {              if (m_triggeredByAuraSpell)                  return SPELL_FAILED_DONT_REPORT; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 40bd4e3c263..f961654f279 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -877,11 +877,6 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)          values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);      } -    // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category -    if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime -        && m_spellInfo->GetCategory() == spellInfo->GetCategory()) -        m_caster->GetSpellHistory()->ResetCooldown(spellInfo->Id); -      // original caster guid only for GO cast      m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID);  } @@ -930,11 +925,6 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)          values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);      } -    // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category -    if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime -        && m_spellInfo->GetCategory() == spellInfo->GetCategory()) -        m_caster->GetSpellHistory()->ResetCooldown(spellInfo->Id); -      // original caster guid only for GO cast      m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID);  } diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index ac08f681933..adf5fc47c77 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -182,13 +182,13 @@ void SpellHistory::HandleCooldowns(SpellInfo const* spellInfo, uint32 itemID, Sp      StartCooldown(spellInfo, itemID, spell);  } -bool SpellHistory::IsReady(SpellInfo const* spellInfo, uint32 itemId /*= 0*/) const +bool SpellHistory::IsReady(SpellInfo const* spellInfo, uint32 itemId /*= 0*/, bool ignoreCategoryCooldown /*= false*/) const  {      if (spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)          if (IsSchoolLocked(spellInfo->GetSchoolMask()))              return false; -    if (HasCooldown(spellInfo->Id, itemId)) +    if (HasCooldown(spellInfo->Id, itemId, ignoreCategoryCooldown))          return false;      return true; @@ -465,11 +465,14 @@ void SpellHistory::ResetAllCooldowns()      _spellCooldowns.clear();  } -bool SpellHistory::HasCooldown(SpellInfo const* spellInfo, uint32 itemId /*= 0*/) const +bool SpellHistory::HasCooldown(SpellInfo const* spellInfo, uint32 itemId /*= 0*/, bool ignoreCategoryCooldown /*= false*/) const  {      if (_spellCooldowns.count(spellInfo->Id) != 0)          return true; +    if (ignoreCategoryCooldown) +        return false; +      uint32 category = 0;      GetCooldownDurations(spellInfo, itemId, nullptr, &category, nullptr);      if (!category) @@ -478,9 +481,9 @@ bool SpellHistory::HasCooldown(SpellInfo const* spellInfo, uint32 itemId /*= 0*/      return _categoryCooldowns.count(category) != 0;  } -bool SpellHistory::HasCooldown(uint32 spellId, uint32 itemId /*= 0*/) const +bool SpellHistory::HasCooldown(uint32 spellId, uint32 itemId /*= 0*/, bool ignoreCategoryCooldown /*= false*/) const  { -    return HasCooldown(sSpellMgr->EnsureSpellInfo(spellId), itemId); +    return HasCooldown(sSpellMgr->EnsureSpellInfo(spellId), itemId, ignoreCategoryCooldown);  }  uint32 SpellHistory::GetRemainingCooldown(SpellInfo const* spellInfo) const diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index 00c790a670d..f0a53fe130d 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -62,7 +62,7 @@ public:      void HandleCooldowns(SpellInfo const* spellInfo, Item const* item, Spell* spell = nullptr);      void HandleCooldowns(SpellInfo const* spellInfo, uint32 itemID, Spell* spell = nullptr); -    bool IsReady(SpellInfo const* spellInfo, uint32 itemId = 0) const; +    bool IsReady(SpellInfo const* spellInfo, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const;      template<class OwnerType>      void WritePacket(WorldPacket& packet) const; @@ -105,8 +105,8 @@ public:      }      void ResetAllCooldowns(); -    bool HasCooldown(SpellInfo const* spellInfo, uint32 itemId = 0) const; -    bool HasCooldown(uint32 spellId, uint32 itemId = 0) const; +    bool HasCooldown(SpellInfo const* spellInfo, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const; +    bool HasCooldown(uint32 spellId, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const;      uint32 GetRemainingCooldown(SpellInfo const* spellInfo) const;      // School lockouts diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h index 39c9d9a79a7..9fce132ea7e 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h @@ -59,7 +59,7 @@ enum CreatureIds  enum GameObjectIds  {      GO_BLACK_DRAGON_EGG         = 177807, -    GO_BOSSGATE01               = 175946, +    GO_PORTCULLIS               = 176965,      GO_DRAKE_RIDER_PORTCULLIS   = 175185,      GO_ALTERAC_VALLEY_GATE      = 180424,      GO_GATE                     = 185483, diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp index 83b2b45851c..a4241b16f8d 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp @@ -22,7 +22,7 @@  DoorData const doorData[] =  { -    { GO_BOSSGATE01,             DATA_RAZORGORE_THE_UNTAMED,  DOOR_TYPE_PASSAGE }, +    { GO_PORTCULLIS,             DATA_RAZORGORE_THE_UNTAMED,  DOOR_TYPE_PASSAGE },      { GO_DRAKE_RIDER_PORTCULLIS, DATA_VAELASTRAZ_THE_CORRUPT, DOOR_TYPE_PASSAGE },      { GO_ALTERAC_VALLEY_GATE,    DATA_BROODLORD_LASHLAYER,    DOOR_TYPE_PASSAGE },      { GO_GATE,                   DATA_FIREMAW,                DOOR_TYPE_PASSAGE }, diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index 869a3ec3921..a7a89f44d81 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -67,7 +67,8 @@ enum Actions  enum HorsemenData  { -    DATA_MOVEMENT_FINISHED = DATA_HORSEMEN_CHECK_ACHIEVEMENT_CREDIT + 1, // make sure we don't conflict with the one from naxxramas.h +    DATA_HORSEMEN_IS_TIMED_KILL = Data::DATA_HORSEMEN_CHECK_ACHIEVEMENT_CREDIT, // inherit from naxxramas.h - this needs to be the first entry to ensure that there are no conflicts +    DATA_MOVEMENT_FINISHED,      DATA_DEATH_TIME  }; @@ -130,7 +131,7 @@ struct boss_four_horsemen_baseAI : public BossAI                      return _myMovementFinished ? 1 : 0;                  case DATA_DEATH_TIME:                      return _timeDied; -                case DATA_HORSEMEN_CHECK_ACHIEVEMENT_CREDIT: +                case DATA_HORSEMEN_IS_TIMED_KILL:                  {                      uint32 minTime = 0, maxTime = 0;                      for (Horseman boss : horsemen) diff --git a/src/server/scripts/Pet/pet_mage.cpp b/src/server/scripts/Pet/pet_mage.cpp index fee47aa1fa2..37584bda2ae 100644 --- a/src/server/scripts/Pet/pet_mage.cpp +++ b/src/server/scripts/Pet/pet_mage.cpp @@ -178,6 +178,9 @@ class npc_pet_mage_mirror_image : public CreatureScript              void UpdateAI(uint32 diff) override              {                  Unit* owner = me->GetCharmerOrOwner(); +                if (!owner) +                    return; +                  Unit* target = owner->getAttackerForHelper();                  events.Update(diff); @@ -192,9 +195,6 @@ class npc_pet_mage_mirror_image : public CreatureScript                  if (me->HasUnitState(UNIT_STATE_CASTING))                      return; -                if (!owner) -                    return; -                  // assign target if image doesnt have any or the target is not actual                  if (!target || me->GetVictim() != target)                  { diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 13e7697910b..8bd4b3eb070 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -1195,7 +1195,7 @@ class spell_pal_light_s_beacon : public SpellScriptLoader                  if (!procSpell)                      return; -                uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(SPELL_PALADIN_HOLY_LIGHT)) ? SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_1 : SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_3; +                uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->EnsureSpellInfo(SPELL_PALADIN_HOLY_LIGHT)) ? SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_1 : SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_3;                  uint32 heal = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount());                  Unit* beaconTarget = GetCaster(); diff --git a/src/server/scripts/World/duel_reset.cpp b/src/server/scripts/World/duel_reset.cpp index c5b53368bc8..3c46255a1bf 100644 --- a/src/server/scripts/World/duel_reset.cpp +++ b/src/server/scripts/World/duel_reset.cpp @@ -34,9 +34,8 @@ class DuelResetScript : public PlayerScript                  player1->GetSpellHistory()->SaveCooldownStateBeforeDuel();                  player2->GetSpellHistory()->SaveCooldownStateBeforeDuel(); - -                ResetSpellCooldowns(player1); -                ResetSpellCooldowns(player2); +                ResetSpellCooldowns(player1, true); +                ResetSpellCooldowns(player2, true);              }              // Health and mana reset @@ -73,9 +72,8 @@ class DuelResetScript : public PlayerScript                  // Cooldown restore                  if (sWorld->getBoolConfig(CONFIG_RESET_DUEL_COOLDOWNS))                  { - -                    ResetSpellCooldowns(winner); -                    ResetSpellCooldowns(loser); +                    ResetSpellCooldowns(winner, false); +                    ResetSpellCooldowns(loser, false);                      winner->GetSpellHistory()->RestoreCooldownStateAfterDuel();                      loser->GetSpellHistory()->RestoreCooldownStateAfterDuel(); @@ -98,14 +96,35 @@ class DuelResetScript : public PlayerScript              }          } -        static void ResetSpellCooldowns(Player* player) +        static void ResetSpellCooldowns(Player* player, bool onStartDuel)          { -            // remove cooldowns on spells that have < 10 min CD and has no onHold -            player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool +            if (onStartDuel)               { -                SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); -                return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS && !itr->second.OnHold; -            }, true); +                // remove cooldowns on spells that have < 10 min CD > 30 sec and has no onHold +                player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool +                { +                    SpellHistory::Clock::time_point now = SpellHistory::Clock::now(); +                    uint32 cooldownDuration = itr->second.CooldownEnd > now ? std::chrono::duration_cast<std::chrono::milliseconds>(itr->second.CooldownEnd - now).count() : 0; +                    SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); +                    return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS  +                           && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS  +                           && !itr->second.OnHold +                           && cooldownDuration > 0 +                           && ( spellInfo->RecoveryTime - cooldownDuration ) > (MINUTE / 2) * IN_MILLISECONDS +                           && ( spellInfo->CategoryRecoveryTime - cooldownDuration ) > (MINUTE / 2) * IN_MILLISECONDS; +                }, true); +            } +            else +            { +                // remove cooldowns on spells that have < 10 min CD and has no onHold +                player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool +                { +                    SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); +                    return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS  +                           && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS  +                           && !itr->second.OnHold; +                }, true);   +            }              // pet cooldowns              if (Pet* pet = player->GetPet())  | 
