aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/SpellInfo.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-05-02 18:52:15 +0200
committerShauren <shauren.trinity@gmail.com>2016-05-02 18:52:15 +0200
commit110ae3e6261694cd5a9ad1687ee209ef42a55c3e (patch)
tree77310f66c1d1d703ae9b8723d8aa0b6e2ce3dfe0 /src/server/game/Spells/SpellInfo.cpp
parente8730061530cba48703508297dedc8aeb49681b1 (diff)
Core/Spells: Implemented RPPM proc effects
Closes #17001
Diffstat (limited to 'src/server/game/Spells/SpellInfo.cpp')
-rw-r--r--src/server/game/Spells/SpellInfo.cpp129
1 files changed, 128 insertions, 1 deletions
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index bc16ad62075..a91c94b63c8 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -995,7 +995,6 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& ef
}
SpellName = spellEntry->Name_lang;
- Rank = nullptr;
RuneCostID = spellEntry->RuneCostID;
SpellDifficultyId = 0;
SpellScalingId = spellEntry->ScalingID;
@@ -1054,9 +1053,14 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& ef
// SpellAuraOptionsEntry
SpellAuraOptionsEntry const* _options = GetSpellAuraOptions();
+ SpellProcsPerMinuteEntry const* _ppm = _options ? sSpellProcsPerMinuteStore.LookupEntry(_options->SpellProcsPerMinuteID) : nullptr;
ProcFlags = _options ? _options->ProcTypeMask : 0;
ProcChance = _options ? _options->ProcChance : 0;
ProcCharges = _options ? _options->ProcCharges : 0;
+ ProcCooldown = _options ? _options->ProcCategoryRecovery : 0;
+ ProcBasePPM = _ppm ? _ppm->BaseProcRate : 0.0f;
+ if (_options)
+ ProcPPMMods = sDB2Manager.GetSpellProcsPerMinuteMods(_options->SpellProcsPerMinuteID);
StackAmount = _options ? _options->CumulativeAura : 0;
// SpellAuraRestrictionsEntry
@@ -2748,6 +2752,126 @@ std::vector<SpellInfo::CostData> SpellInfo::CalcPowerCost(Unit const* caster, Sp
return costs;
}
+inline float CalcPPMHasteMod(SpellProcsPerMinuteModEntry const* mod, Unit* caster)
+{
+ float haste = caster->GetFloatValue(UNIT_FIELD_MOD_HASTE);
+ float rangedHaste = caster->GetFloatValue(UNIT_FIELD_MOD_RANGED_HASTE);
+ float spellHaste = caster->GetFloatValue(UNIT_MOD_CAST_HASTE);
+ float regenHaste = caster->GetFloatValue(UNIT_FIELD_MOD_HASTE_REGEN);
+
+ switch (mod->Param)
+ {
+ case 1:
+ return (1.0f / haste - 1.0f) * mod->Coeff;
+ case 2:
+ return (1.0f / rangedHaste - 1.0f) * mod->Coeff;
+ case 3:
+ return (1.0f / spellHaste - 1.0f) * mod->Coeff;
+ case 4:
+ return (1.0f / regenHaste - 1.0f) * mod->Coeff;
+ case 5:
+ return (1.0f / std::min(std::min(std::min(haste, rangedHaste), spellHaste), regenHaste) - 1.0f) * mod->Coeff;
+ default:
+ break;
+ }
+
+ return 0.0f;
+}
+
+inline float CalcPPMCritMod(SpellProcsPerMinuteModEntry const* mod, Unit* caster)
+{
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return 0.0f;
+
+ float crit = caster->GetFloatValue(PLAYER_CRIT_PERCENTAGE);
+ float rangedCrit = caster->GetFloatValue(PLAYER_RANGED_CRIT_PERCENTAGE);
+ float spellCrit = caster->GetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1);
+
+ switch (mod->Param)
+ {
+ case 1:
+ return crit * mod->Coeff * 0.01f;
+ case 2:
+ return rangedCrit * mod->Coeff * 0.01f;
+ case 3:
+ return spellCrit * mod->Coeff * 0.01f;
+ case 4:
+ return std::min(std::min(crit, rangedCrit), spellCrit) * mod->Coeff * 0.01f;
+ default:
+ break;
+ }
+
+ return 0.0f;
+}
+
+inline float CalcPPMItemLevelMod(SpellProcsPerMinuteModEntry const* mod, int32 itemLevel)
+{
+ if (uint32(itemLevel) == mod->Param)
+ return 0.0f;
+
+ float itemLevelPoints = GetRandomPropertyPoints(itemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
+ float basePoints = GetRandomPropertyPoints(mod->Param, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
+ if (itemLevelPoints != basePoints)
+ return 0.0f;
+
+ return ((itemLevelPoints / basePoints) - 1.0f) * mod->Coeff;
+}
+
+float SpellInfo::CalcProcPPM(Unit* caster, int32 itemLevel) const
+{
+ float ppm = ProcBasePPM;
+ for (SpellProcsPerMinuteModEntry const* mod : ProcPPMMods)
+ {
+ switch (mod->Type)
+ {
+ case SPELL_PPM_MOD_HASTE:
+ {
+ ppm *= 1.0f + CalcPPMHasteMod(mod, caster);
+ break;
+ }
+ case SPELL_PPM_MOD_CRIT:
+ {
+ ppm *= 1.0f + CalcPPMCritMod(mod, caster);
+ break;
+ }
+ case SPELL_PPM_MOD_CLASS:
+ {
+ if (caster->getClassMask() & mod->Param)
+ ppm *= 1.0f + mod->Coeff;
+ break;
+ }
+ case SPELL_PPM_MOD_SPEC:
+ {
+ if (Player* plrCaster = caster->ToPlayer())
+ if (plrCaster->GetSpecId(plrCaster->GetActiveTalentGroup()) == mod->Param)
+ ppm *= 1.0f + mod->Coeff;
+ break;
+ }
+ case SPELL_PPM_MOD_RACE:
+ {
+ if (caster->getRaceMask() & mod->Param)
+ ppm *= 1.0f + mod->Coeff;
+ break;
+ }
+ case SPELL_PPM_MOD_ITEM_LEVEL:
+ {
+ ppm *= 1.0f + CalcPPMItemLevelMod(mod, itemLevel);
+ break;
+ }
+ case SPELL_PPM_MOD_BATTLEGROUND:
+ {
+ if (caster->GetMap()->IsBattlegroundOrArena())
+ ppm *= 1.0f + mod->Coeff;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return ppm;
+}
+
bool SpellInfo::IsRanked() const
{
return ChainEntry != NULL;
@@ -2766,18 +2890,21 @@ SpellInfo const* SpellInfo::GetFirstRankSpell() const
return this;
return ChainEntry->first;
}
+
SpellInfo const* SpellInfo::GetLastRankSpell() const
{
if (!ChainEntry)
return NULL;
return ChainEntry->last;
}
+
SpellInfo const* SpellInfo::GetNextRankSpell() const
{
if (!ChainEntry)
return NULL;
return ChainEntry->next;
}
+
SpellInfo const* SpellInfo::GetPrevRankSpell() const
{
if (!ChainEntry)