diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 14 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.h | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellScript.cpp | 16 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellScript.h | 18 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_rogue.cpp | 519 | 
7 files changed, 497 insertions, 81 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index bda27e52492..534162b131c 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2118,16 +2118,20 @@ float WorldObject::ApplyEffectModifiers(SpellInfo const* spellInfo, uint8 effInd  int32 WorldObject::CalcSpellDuration(SpellInfo const* spellInfo) const  { -    uint8 comboPoints = 0; +    int32 comboPoints = 0; +    int32 maxComboPoints = 5;      if (Unit const* unit = ToUnit()) +    {          comboPoints = unit->GetPower(POWER_COMBO_POINTS); +        maxComboPoints = unit->GetMaxPower(POWER_COMBO_POINTS); +    }      int32 minduration = spellInfo->GetDuration();      int32 maxduration = spellInfo->GetMaxDuration();      int32 duration;      if (comboPoints && minduration != -1 && minduration != maxduration) -        duration = minduration + int32((maxduration - minduration) * comboPoints / 5); +        duration = minduration + int32((maxduration - minduration) * comboPoints / maxComboPoints);      else          duration = minduration; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 0e730fc83eb..5139d05c562 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -407,7 +407,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=      &AuraEffect::HandleMountRestrictions,                         //336 SPELL_AURA_MOUNT_RESTRICTIONS implemented in Unit::GetMountCapability      &AuraEffect::HandleNoImmediateEffect,                         //337 SPELL_AURA_MOD_VENDOR_ITEMS_PRICES      &AuraEffect::HandleNoImmediateEffect,                         //338 SPELL_AURA_MOD_DURABILITY_LOSS -    &AuraEffect::HandleNoImmediateEffect,                         //339 SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER implemented in Unit::GetUnitCriticalChance and Unit::GetUnitSpellCriticalChance +    &AuraEffect::HandleNoImmediateEffect,                         //339 SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_PET implemented in Unit::GetUnitCriticalChance and Unit::GetUnitSpellCriticalChance      &AuraEffect::HandleNULL,                                      //340 SPELL_AURA_MOD_RESURRECTED_HEALTH_BY_GUILD_MEMBER      &AuraEffect::HandleModSpellCategoryCooldown,                  //341 SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN      &AuraEffect::HandleModMeleeRangedSpeedPct,                    //342 SPELL_AURA_MOD_MELEE_RANGED_HASTE_2 diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 6e7dc569cc1..5953cab5b56 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -7338,10 +7338,20 @@ void Spell::DelayedChannel()  bool Spell::HasPowerTypeCost(Powers power) const  { -    return std::find_if(m_powerCost.cbegin(), m_powerCost.cend(), [power](SpellPowerCost const& cost) +    return GetPowerTypeCostAmount(power).has_value(); +} + +Optional<int32> Spell::GetPowerTypeCostAmount(Powers power) const +{ +    auto itr = std::find_if(m_powerCost.cbegin(), m_powerCost.cend(), [power](SpellPowerCost const& cost)      {          return cost.Power == power; -    }) != m_powerCost.cend(); +    }); + +    if (itr == m_powerCost.cend()) +        return { }; + +    return itr->Amount;  }  bool Spell::UpdatePointers() diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index a904844c6c9..045b3e1cedf 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -609,6 +609,7 @@ class TC_GAME_API Spell          Difficulty GetCastDifficulty() const;          std::vector<SpellPowerCost> const& GetPowerCost() const { return m_powerCost; }          bool HasPowerTypeCost(Powers power) const; +        Optional<int32> GetPowerTypeCostAmount(Powers power) const;          bool UpdatePointers();                              // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 73452dca696..6313668eed6 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -35,20 +35,14 @@ bool _SpellScript::_Validate(SpellInfo const* entry)      return true;  } -bool _SpellScript::_ValidateSpellInfo(uint32 const* begin, uint32 const* end) +bool _SpellScript::_ValidateSpellInfo(uint32 spellId)  { -    bool allValid = true; -    while (begin != end) +    if (!sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE))      { -        if (!sSpellMgr->GetSpellInfo(*begin, DIFFICULTY_NONE)) -        { -            TC_LOG_ERROR("scripts.spells", "_SpellScript::ValidateSpellInfo: Spell %u does not exist.", *begin); -            allValid = false; -        } - -        ++begin; +        TC_LOG_ERROR("scripts.spells", "_SpellScript::ValidateSpellInfo: Spell %u does not exist.", spellId); +        return false;      } -    return allValid; +    return true;  }  void _SpellScript::_Register() diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 00397833b18..665be327fbc 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -151,11 +151,25 @@ class TC_GAME_API _SpellScript          template <class T>          static bool ValidateSpellInfo(T const& spellIds)          { -            return _ValidateSpellInfo(std::begin(spellIds), std::end(spellIds)); +            return _ValidateSpellInfo(std::cbegin(spellIds), std::cend(spellIds));          }      private: -        static bool _ValidateSpellInfo(uint32 const* begin, uint32 const* end); +        template <class InputIt> +        static bool _ValidateSpellInfo(InputIt first, InputIt last) +        { +            bool allValid = true; +            while (first != last) +            { +                if (!_ValidateSpellInfo(*first)) +                    allValid = false; + +                ++first; +            } +            return allValid; +        } + +        static bool _ValidateSpellInfo(uint32 spellId);  };  // SpellScript interface - enum used for runtime checks of script function calls diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index f1871303adc..a50a6b468ca 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -36,25 +36,93 @@  enum RogueSpells  { +    SPELL_ROGUE_ADRENALINE_RUSH                     = 13750, +    SPELL_ROGUE_BETWEEN_THE_EYES                    = 199804,      SPELL_ROGUE_BLADE_FLURRY                        = 13877,      SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK           = 22482, +    SPELL_ROGUE_BROADSIDE                           = 193356, +    SPELL_ROGUE_BURIED_TREASURE                     = 199600, +    SPELL_ROGUE_DEATH_FROM_ABOVE                    = 152150, +    SPELL_ROGUE_GRAND_MELEE                         = 193358, +    SPELL_ROGUE_GRAPPLING_HOOK                      = 195457,      SPELL_ROGUE_KILLING_SPREE                       = 51690,      SPELL_ROGUE_KILLING_SPREE_TELEPORT              = 57840,      SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG            = 57841,      SPELL_ROGUE_KILLING_SPREE_DMG_BUFF              = 61851, +    SPELL_ROGUE_MARKED_FOR_DEATH                    = 137619,      SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT   = 31665,      SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE          = 31223, +    SPELL_ROGUE_MAIN_GAUCHE                         = 86392, +    SPELL_ROGUE_PREMEDITATION_PASSIVE               = 343160, +    SPELL_ROGUE_PREMEDITATION_AURA                  = 343173, +    SPELL_ROGUE_RUTHLESS_PRECISION                  = 193357,      SPELL_ROGUE_SANCTUARY                           = 98877, +    SPELL_ROGUE_SKULL_AND_CROSSBONES                = 199603,      SPELL_ROGUE_SHADOW_FOCUS                        = 108209,      SPELL_ROGUE_SHADOW_FOCUS_EFFECT                 = 112942, +    SPELL_ROGUE_SLICE_AND_DICE                      = 315496, +    SPELL_ROGUE_SPRINT                              = 2983,      SPELL_ROGUE_STEALTH                             = 1784,      SPELL_ROGUE_STEALTH_STEALTH_AURA                = 158185,      SPELL_ROGUE_STEALTH_SHAPESHIFT_AURA             = 158188, +    SPELL_ROGUE_SYMBOLS_OF_DEATH_CRIT_AURA          = 227151, +    SPELL_ROGUE_SYMBOLS_OF_DEATH_RANK2              = 328077, +    SPELL_ROGUE_TRUE_BEARING                        = 193359, +    SPELL_ROGUE_VANISH                              = 1856,      SPELL_ROGUE_VANISH_AURA                         = 11327,      SPELL_ROGUE_TRICKS_OF_THE_TRADE                 = 57934,      SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC            = 59628,      SPELL_ROGUE_HONOR_AMONG_THIEVES_ENERGIZE        = 51699, -    SPELL_ROGUE_T5_2P_SET_BONUS                     = 37169 +    SPELL_ROGUE_T5_2P_SET_BONUS                     = 37169, +    SPELL_ROGUE_VENOMOUS_WOUNDS                     = 79134, +}; + +/* Returns true if the spell is a finishing move. + * A finishing move is a spell that cost combo points */ +Optional<int32> GetFinishingMoveCPCost(Spell const* spell) +{ +    if (!spell) +        return { }; + +    return spell->GetPowerTypeCostAmount(POWER_COMBO_POINTS); +} + +/* Return true if the spell is a finishing move. + * A finishing move is a spell that cost combo points */ +bool IsFinishingMove(Spell const* spell) +{ +    return GetFinishingMoveCPCost(spell).has_value(); +} + +// 53 - Backstab +class spell_rog_backstab : public SpellScript +{ +    PrepareSpellScript(spell_rog_backstab); + +    bool Validate(SpellInfo const* spellInfo) override +    { +        return spellInfo->GetEffects().size() > EFFECT_3; +    } + +    void HandleHitDamage(SpellEffIndex /*effIndex*/) +    { +        Unit* hitUnit = GetHitUnit(); +        if (!hitUnit) +            return; + +        Unit* caster = GetCaster(); +        if (hitUnit->isInBack(caster)) +        { +            float currDamage = float(GetHitDamage()); +            float newDamage = AddPct(currDamage, float(GetEffectInfo(EFFECT_3).CalcValue(caster))); +            SetHitDamage(newDamage); +        } +    } + +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_rog_backstab::HandleHitDamage, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); +    }  };  // 13877, 33735, (check 51211, 65956) - Blade Flurry @@ -204,6 +272,48 @@ class spell_rog_deadly_poison : public SpellScriptLoader          }  }; +// 193358 - Grand Melee +class spell_rog_grand_melee : public AuraScript +{ +    PrepareAuraScript(spell_rog_grand_melee); + +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_ROGUE_SLICE_AND_DICE }); +    } + +    bool HandleCheckProc(ProcEventInfo& eventInfo) +    { +        Spell const* procSpell = eventInfo.GetProcSpell(); +        return procSpell && procSpell->HasPowerTypeCost(POWER_COMBO_POINTS); +    } + +    void HandleProc(AuraEffect* aurEff, ProcEventInfo& procInfo) +    { +        Spell const* procSpell = procInfo.GetProcSpell(); +        int32 amount = aurEff->GetAmount() * *procSpell->GetPowerTypeCostAmount(POWER_COMBO_POINTS) * 1000; + +        if (Unit* target = GetTarget()) +        { +            if (Aura* aura = target->GetAura(SPELL_ROGUE_SLICE_AND_DICE)) +                aura->SetDuration(aura->GetDuration() + amount); +            else +            { +                CastSpellExtraArgs args; +                args.TriggerFlags = TRIGGERED_FULL_MASK; +                args.AddSpellMod(SPELLVALUE_DURATION, amount); +                target->CastSpell(target, SPELL_ROGUE_SLICE_AND_DICE, args); +            } +        } +    } + +    void Register() override +    { +        DoCheckProc += AuraCheckProcFn(spell_rog_grand_melee::HandleCheckProc); +        OnEffectProc += AuraEffectProcFn(spell_rog_grand_melee::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); +    } +}; +  // 51690 - Killing Spree  class spell_rog_killing_spree : public SpellScriptLoader  { @@ -302,6 +412,120 @@ class spell_rog_killing_spree : public SpellScriptLoader          }  }; +// 76806 - Mastery: Main Gauche +class spell_rog_mastery_main_gauche : public AuraScript +{ +    PrepareAuraScript(spell_rog_mastery_main_gauche); + +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_ROGUE_MAIN_GAUCHE }); +    } + +    bool HandleCheckProc(ProcEventInfo& eventInfo) +    { +        return eventInfo.GetDamageInfo() && eventInfo.GetDamageInfo()->GetVictim(); +    } + +    void HandleProc(AuraEffect* aurEff, ProcEventInfo& procInfo) +    { +        if (Unit* target = GetTarget()) +            target->CastSpell(procInfo.GetDamageInfo()->GetVictim(), SPELL_ROGUE_MAIN_GAUCHE, aurEff); +    } + +    void Register() override +    { +        DoCheckProc += AuraCheckProcFn(spell_rog_mastery_main_gauche::HandleCheckProc); +        OnEffectProc += AuraEffectProcFn(spell_rog_mastery_main_gauche::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); +    } +}; + +// 79096 - Restless Blades +class spell_rog_restless_blades : public AuraScript +{ +    PrepareAuraScript(spell_rog_restless_blades); + +    static uint32 constexpr Spells[] = { SPELL_ROGUE_ADRENALINE_RUSH, SPELL_ROGUE_BETWEEN_THE_EYES, SPELL_ROGUE_SPRINT, +        SPELL_ROGUE_GRAPPLING_HOOK, SPELL_ROGUE_VANISH, SPELL_ROGUE_KILLING_SPREE, SPELL_ROGUE_MARKED_FOR_DEATH, SPELL_ROGUE_DEATH_FROM_ABOVE }; + +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo(Spells); +    } + +    void HandleProc(AuraEffect* aurEff, ProcEventInfo& procInfo) +    { +        if (Optional<int32> spentCP = GetFinishingMoveCPCost(procInfo.GetProcSpell())) +        { +            int32 cdExtra = -(float(aurEff->GetAmount() * *spentCP) * 0.1f); + +            SpellHistory* history = GetTarget()->GetSpellHistory(); +            for (uint32 spellId : Spells) +                history->ModifyCooldown(spellId, Seconds(cdExtra), true); +        } +    } + +    void Register() override +    { +        OnEffectProc += AuraEffectProcFn(spell_rog_restless_blades::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); +    } +}; + +// 315508 - Roll the Bones +class spell_rog_roll_the_bones : public SpellScript +{ +    PrepareSpellScript(spell_rog_roll_the_bones); + +    static uint32 constexpr Spells[] = { SPELL_ROGUE_SKULL_AND_CROSSBONES, SPELL_ROGUE_GRAND_MELEE, SPELL_ROGUE_RUTHLESS_PRECISION, +        SPELL_ROGUE_TRUE_BEARING, SPELL_ROGUE_BURIED_TREASURE, SPELL_ROGUE_BROADSIDE }; + +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo(Spells); +    } + +    void HandleDummy(SpellEffIndex /*effIndex*/) +    { +        int32 currentDuration = 0; +        for (uint32 spellId : Spells) +        { +            if (Aura* aura = GetCaster()->GetAura(spellId)) +            { +                currentDuration = aura->GetDuration(); +                GetCaster()->RemoveAura(aura); +            } +        } + +        std::vector<uint32> possibleBuffs(std::begin(Spells), std::end(Spells)); +        Trinity::Containers::RandomShuffle(possibleBuffs); + +        // https://www.icy-veins.com/wow/outlaw-rogue-pve-dps-rotation-cooldowns-abilities +        // 1 Roll the Bones buff  : 100.0 % chance; +        // 2 Roll the Bones buffs : 19 % chance; +        // 5 Roll the Bones buffs : 1 % chance. +        int32 chance = irand(1, 100); +        int32 numBuffs = 1; +        if (chance <= 1) +            numBuffs = 5; +        else if (chance <= 20) +            numBuffs = 2; + +        for (int32 i = 0; i < numBuffs; ++i) +        { +            uint32 spellId = possibleBuffs[i]; +            CastSpellExtraArgs args; +            args.TriggerFlags = TRIGGERED_FULL_MASK; +            args.AddSpellMod(SPELLVALUE_DURATION, GetSpellInfo()->GetDuration() + currentDuration); +            GetCaster()->CastSpell(GetCaster(), spellId, args); +        } +    } + +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_rog_roll_the_bones::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA); +    } +}; +  // 1943 - Rupture  class spell_rog_rupture : public SpellScriptLoader  { @@ -312,10 +536,9 @@ class spell_rog_rupture : public SpellScriptLoader          {              PrepareAuraScript(spell_rog_rupture_AuraScript); -            bool Load() override +            bool Validate(SpellInfo const* /*spellInfo*/) override              { -                Unit* caster = GetCaster(); -                return caster && caster->GetTypeId() == TYPEID_PLAYER; +                return ValidateSpellInfo({ SPELL_ROGUE_VENOMOUS_WOUNDS });              }              void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) @@ -334,7 +557,7 @@ class spell_rog_rupture : public SpellScriptLoader                          0.0375f         // 5 points: ${($m1 + $b1*5 + 0.0375 * $AP) * 8} damage over 16 secs                      }; -                    uint32 cp = caster->ToPlayer()->GetComboPoints(); +                    uint32 cp = caster->GetComboPoints();                      if (cp > 5)                          cp = 5; @@ -342,9 +565,34 @@ class spell_rog_rupture : public SpellScriptLoader                  }              } +            void OnEffectRemoved(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +            { +                if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH) +                    return; + +                Aura* aura = GetAura(); +                Unit* caster = aura->GetCaster(); +                if (!caster) +                    return; + +                Aura* auraVenomousWounds = caster->GetAura(SPELL_ROGUE_VENOMOUS_WOUNDS); +                if (!auraVenomousWounds) +                    return; + +                // Venomous Wounds: if unit dies while being affected by rupture, regain energy based on remaining duration +                Optional<SpellPowerCost> cost = GetSpellInfo()->CalcPowerCost(POWER_ENERGY, false, caster, GetSpellInfo()->GetSchoolMask(), nullptr); +                if (!cost.has_value()) +                    return; + +                float pct = float(aura->GetDuration()) / float(aura->GetMaxDuration()); +                int32 extraAmount = float(cost->Amount) * pct; +                caster->ModifyPower(POWER_ENERGY, extraAmount); +            } +              void Register() override              {                  DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_rog_rupture_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); +                OnEffectRemove += AuraEffectRemoveFn(spell_rog_rupture_AuraScript::OnEffectRemoved, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);              }          }; @@ -354,80 +602,198 @@ class spell_rog_rupture : public SpellScriptLoader          }  }; -// 1784 - Stealth -class spell_rog_stealth : public SpellScriptLoader +// 14161 - Ruthlessness +class spell_rog_ruthlessness : public AuraScript  { -    public: -        spell_rog_stealth() : SpellScriptLoader("spell_rog_stealth") { } +    PrepareAuraScript(spell_rog_ruthlessness); + +    void HandleProc(AuraEffect* aurEff, ProcEventInfo& procInfo) +    { +        Unit* target = GetTarget(); + +        if (Optional<int32> cost = GetFinishingMoveCPCost(procInfo.GetProcSpell())) +            if (roll_chance_i(aurEff->GetSpellEffectInfo().PointsPerResource * (*cost))) +                target->ModifyPower(POWER_COMBO_POINTS, 1); +    } + +    void Register() override +    { +        OnEffectProc += AuraEffectProcFn(spell_rog_ruthlessness::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); +    } +}; + +// 185438 - Shadowstrike +class spell_rog_shadowstrike : public SpellScript +{ +    PrepareSpellScript(spell_rog_shadowstrike); + +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_ROGUE_PREMEDITATION_AURA, SPELL_ROGUE_SLICE_AND_DICE, SPELL_ROGUE_PREMEDITATION_PASSIVE }) +            && sSpellMgr->AssertSpellInfo(SPELL_ROGUE_PREMEDITATION_PASSIVE, DIFFICULTY_NONE)->GetEffects().size() > EFFECT_0; +    } -        class spell_rog_stealth_AuraScript : public AuraScript +    SpellCastResult HandleCheckCast() +    { +        // Because the premeditation aura is removed when we're out of stealth, +        // when we reach HandleEnergize the aura won't be there, even if it was when player launched the spell +        _hasPremeditationAura = GetCaster()->HasAura(SPELL_ROGUE_PREMEDITATION_AURA); +        return SPELL_FAILED_SUCCESS; +    } + +    void HandleEnergize(SpellEffIndex /*effIndex*/) +    { +        Unit* caster = GetCaster(); +        if (_hasPremeditationAura)          { -            PrepareAuraScript(spell_rog_stealth_AuraScript); +            if (caster->HasAura(SPELL_ROGUE_SLICE_AND_DICE)) +                if (Aura* premeditationPassive = caster->GetAura(SPELL_ROGUE_PREMEDITATION_PASSIVE)) +                    if (AuraEffect const* auraEff = premeditationPassive->GetEffect(EFFECT_1)) +                        SetHitDamage(GetHitDamage() + auraEff->GetAmount()); + +            // Grant 10 seconds of slice and dice +            int32 duration = sSpellMgr->AssertSpellInfo(SPELL_ROGUE_PREMEDITATION_PASSIVE, DIFFICULTY_NONE)->GetEffect(EFFECT_0).CalcValue(GetCaster()); + +            CastSpellExtraArgs args; +            args.TriggerFlags = TRIGGERED_FULL_MASK; +            args.AddSpellMod(SPELLVALUE_DURATION, duration * IN_MILLISECONDS); +            caster->CastSpell(caster, SPELL_ROGUE_SLICE_AND_DICE, args); +        } +    } -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo( -                { -                    SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE, -                    SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT, -                    SPELL_ROGUE_SANCTUARY, -                    SPELL_ROGUE_SHADOW_FOCUS, -                    SPELL_ROGUE_SHADOW_FOCUS_EFFECT, -                    SPELL_ROGUE_STEALTH_STEALTH_AURA, -                    SPELL_ROGUE_STEALTH_SHAPESHIFT_AURA -                }); -            } +    void Register() override +    { +        OnCheckCast += SpellCheckCastFn(spell_rog_shadowstrike::HandleCheckCast); +        OnEffectHitTarget += SpellEffectFn(spell_rog_shadowstrike::HandleEnergize, EFFECT_1, SPELL_EFFECT_ENERGIZE); +    } -            void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                Unit* target = GetTarget(); +private: +    bool _hasPremeditationAura = false; +}; -                // Master of Subtlety -                if (target->HasAura(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE)) -                    target->CastSpell(target, SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT, TRIGGERED_FULL_MASK); +// 193315 - Sinister Strike +class spell_rog_sinister_strike : public SpellScript +{ +    PrepareSpellScript(spell_rog_sinister_strike); -                // Shadow Focus -                if (target->HasAura(SPELL_ROGUE_SHADOW_FOCUS)) -                    target->CastSpell(target, SPELL_ROGUE_SHADOW_FOCUS_EFFECT, TRIGGERED_FULL_MASK); +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_ROGUE_T5_2P_SET_BONUS }); +    } -                target->CastSpell(target, SPELL_ROGUE_SANCTUARY, TRIGGERED_FULL_MASK); -                target->CastSpell(target, SPELL_ROGUE_STEALTH_STEALTH_AURA, TRIGGERED_FULL_MASK); -                target->CastSpell(target, SPELL_ROGUE_STEALTH_SHAPESHIFT_AURA, TRIGGERED_FULL_MASK); -            } +    void HandleDummy(SpellEffIndex /*effIndex*/) +    { +        int32 damagePerCombo = GetHitDamage(); +        if (AuraEffect const* t5 = GetCaster()->GetAuraEffect(SPELL_ROGUE_T5_2P_SET_BONUS, EFFECT_0)) +            damagePerCombo += t5->GetAmount(); -            void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                Unit* target = GetTarget(); +        int32 finalDamage = damagePerCombo; +        std::vector<SpellPowerCost> const& costs = GetSpell()->GetPowerCost(); +        auto c = std::find_if(costs.begin(), costs.end(), [](SpellPowerCost const& cost) { return cost.Power == POWER_COMBO_POINTS; }); +        if (c != costs.end()) +            finalDamage *= c->Amount; -                // Master of Subtlety -                if (AuraEffect* masterOfSubtletyPassive = GetTarget()->GetAuraEffect(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE, EFFECT_0)) -                { -                    if (Aura* masterOfSubtletyAura = GetTarget()->GetAura(SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT)) -                    { -                        masterOfSubtletyAura->SetMaxDuration(masterOfSubtletyPassive->GetAmount()); -                        masterOfSubtletyAura->RefreshDuration(); -                    } -                } +        SetHitDamage(finalDamage); +    } -                target->RemoveAurasDueToSpell(SPELL_ROGUE_SHADOW_FOCUS_EFFECT); -                target->RemoveAurasDueToSpell(SPELL_ROGUE_STEALTH_STEALTH_AURA); -                target->RemoveAurasDueToSpell(SPELL_ROGUE_STEALTH_SHAPESHIFT_AURA); -            } +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_rog_sinister_strike::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); +    } +}; -            void Register() override -            { -                AfterEffectApply += AuraEffectApplyFn(spell_rog_stealth_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); -                AfterEffectRemove += AuraEffectRemoveFn(spell_rog_stealth_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); -            } -        }; +// 1784 - Stealth +class spell_rog_stealth : public AuraScript +{ +    PrepareAuraScript(spell_rog_stealth); -        AuraScript* GetAuraScript() const override +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo( +        { +            SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE, +            SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT, +            SPELL_ROGUE_SANCTUARY, +            SPELL_ROGUE_SHADOW_FOCUS, +            SPELL_ROGUE_SHADOW_FOCUS_EFFECT, +            SPELL_ROGUE_STEALTH_STEALTH_AURA, +            SPELL_ROGUE_STEALTH_SHAPESHIFT_AURA +        }); +    } + +    void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        Unit* target = GetTarget(); + +        // Master of Subtlety +        if (target->HasAura(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE)) +            target->CastSpell(target, SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT, TRIGGERED_FULL_MASK); + +        // Shadow Focus +        if (target->HasAura(SPELL_ROGUE_SHADOW_FOCUS)) +            target->CastSpell(target, SPELL_ROGUE_SHADOW_FOCUS_EFFECT, TRIGGERED_FULL_MASK); + +        // Premeditation +        if (target->HasAura(SPELL_ROGUE_PREMEDITATION_PASSIVE)) +            target->CastSpell(target, SPELL_ROGUE_PREMEDITATION_AURA, true); + +        target->CastSpell(target, SPELL_ROGUE_SANCTUARY, TRIGGERED_FULL_MASK); +        target->CastSpell(target, SPELL_ROGUE_STEALTH_STEALTH_AURA, TRIGGERED_FULL_MASK); +        target->CastSpell(target, SPELL_ROGUE_STEALTH_SHAPESHIFT_AURA, TRIGGERED_FULL_MASK); +    } + +    void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        Unit* target = GetTarget(); + +        // Master of Subtlety +        if (AuraEffect* masterOfSubtletyPassive = GetTarget()->GetAuraEffect(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE, EFFECT_0))          { -            return new spell_rog_stealth_AuraScript(); +            if (Aura* masterOfSubtletyAura = GetTarget()->GetAura(SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT)) +            { +                masterOfSubtletyAura->SetMaxDuration(masterOfSubtletyPassive->GetAmount()); +                masterOfSubtletyAura->RefreshDuration(); +            }          } + +        // Premeditation +        target->RemoveAura(SPELL_ROGUE_PREMEDITATION_AURA); + +        target->RemoveAurasDueToSpell(SPELL_ROGUE_SHADOW_FOCUS_EFFECT); +        target->RemoveAurasDueToSpell(SPELL_ROGUE_STEALTH_STEALTH_AURA); +        target->RemoveAurasDueToSpell(SPELL_ROGUE_STEALTH_SHAPESHIFT_AURA); +    } + +    void Register() override +    { +        AfterEffectApply += AuraEffectApplyFn(spell_rog_stealth::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +        AfterEffectRemove += AuraEffectRemoveFn(spell_rog_stealth::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +    } +}; + +// 212283 - Symbols of Death +class spell_rog_symbols_of_death : public SpellScript +{ +    PrepareSpellScript(spell_rog_symbols_of_death); + +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_ROGUE_SYMBOLS_OF_DEATH_RANK2, SPELL_ROGUE_SYMBOLS_OF_DEATH_CRIT_AURA }); +    } + +    void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) +    { +        if (GetCaster()->HasAura(SPELL_ROGUE_SYMBOLS_OF_DEATH_RANK2)) +            GetCaster()->CastSpell(GetCaster(), SPELL_ROGUE_SYMBOLS_OF_DEATH_CRIT_AURA, true); +    } + +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_rog_symbols_of_death::HandleEffectHitTarget, EFFECT_0, SPELL_EFFECT_APPLY_AURA); +    }  }; -// 1856 - Vanish +// 1856 - Vanish - SPELL_ROGUE_VANISH  class spell_rog_vanish : public SpellScript  {      PrepareSpellScript(spell_rog_vanish); @@ -666,13 +1032,39 @@ public:      }  }; +// 79134 - Venomous Wounds - SPELL_ROGUE_VENOMOUS_WOUNDS +class spell_rog_venomous_wounds : public AuraScript +{ +    PrepareAuraScript(spell_rog_venomous_wounds); + +    void HandleProc(AuraEffect* aurEff, ProcEventInfo& /*eventInfo*/) +    { +        int32 extraEnergy = aurEff->GetAmount(); +        GetTarget()->ModifyPower(POWER_ENERGY, extraEnergy); +    } + +    void Register() override +    { +        OnEffectProc += AuraEffectProcFn(spell_rog_venomous_wounds::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); +    } +}; +  void AddSC_rogue_spell_scripts()  { +    RegisterSpellScript(spell_rog_backstab);      new spell_rog_blade_flurry();      new spell_rog_deadly_poison(); +    RegisterAuraScript(spell_rog_grand_melee);      new spell_rog_killing_spree(); +    RegisterAuraScript(spell_rog_mastery_main_gauche); +    RegisterAuraScript(spell_rog_restless_blades); +    RegisterSpellScript(spell_rog_roll_the_bones);      new spell_rog_rupture(); -    new spell_rog_stealth(); +    RegisterAuraScript(spell_rog_ruthlessness); +    RegisterSpellScript(spell_rog_shadowstrike); +    RegisterSpellScript(spell_rog_sinister_strike); +    RegisterAuraScript(spell_rog_stealth); +    RegisterSpellScript(spell_rog_symbols_of_death);      RegisterSpellScript(spell_rog_vanish);      RegisterAuraScript(spell_rog_vanish_aura);      RegisterSpellAndAuraScriptPair(spell_rog_tricks_of_the_trade, spell_rog_tricks_of_the_trade_aura); @@ -680,4 +1072,5 @@ void AddSC_rogue_spell_scripts()      new spell_rog_honor_among_thieves();      new spell_rog_eviscerate();      new spell_rog_envenom(); +    RegisterAuraScript(spell_rog_venomous_wounds);  }  | 
