diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 39 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 13 |
3 files changed, 45 insertions, 19 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 971e365a6bf..322e21c73e2 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7989,10 +7989,10 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT continue; SpellEnchantProcEntry const* entry = sSpellMgr->GetSpellEnchantProcEvent(enchant_id); - if (entry && entry->procEx) + if (entry && entry->HitMask) { // Check hit/crit/dodge/parry requirement - if ((entry->procEx & damageInfo.GetHitMask()) == 0) + if ((entry->HitMask & damageInfo.GetHitMask()) == 0) continue; } else @@ -8003,6 +8003,10 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT continue; } + // check if enchant procs only on white hits + if (entry && (entry->AttributesMask & ENCHANT_PROC_ATTR_WHITE_HIT) && damageInfo.GetSpellInfo()) + continue; + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pEnchant->spellid[s]); if (!spellInfo) { @@ -8014,10 +8018,10 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT float chance = pEnchant->amount[s] != 0 ? float(pEnchant->amount[s]) : GetWeaponProcChance(); if (entry) { - if (entry->PPMChance) - chance = GetPPMProcChance(proto->Delay, entry->PPMChance, spellInfo); - else if (entry->customChance) - chance = (float)entry->customChance; + if (entry->ProcsPerMinute) + chance = GetPPMProcChance(proto->Delay, entry->ProcsPerMinute, spellInfo); + else if (entry->Chance) + chance = entry->Chance; } // Apply spell mods @@ -8029,10 +8033,25 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT if (roll_chance_f(chance)) { - if (spellInfo->IsPositive()) - CastSpell(this, spellInfo, true, item); - else - CastSpell(damageInfo.GetVictim(), spellInfo, true, item); + Unit* target = spellInfo->IsPositive() ? this : damageInfo.GetVictim(); + + // reduce effect values if enchant is limited + CustomSpellValues values; + if ((entry->AttributesMask & ENCHANT_PROC_ATTR_LIMIT_60) && target->getLevel() > 60) + { + int32 const lvlDifference = target->getLevel() - 60; + int32 const lvlPenaltyFactor = 4; // 4% lost effectiveness per level + + int32 const effectPct = std::max(0, 100 - (lvlDifference * lvlPenaltyFactor)); + + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (spellInfo->Effects[i].IsEffect()) + values.AddSpellMod(static_cast<SpellValueMod>(SPELLVALUE_BASE_POINT0 + i), CalculatePct(spellInfo->Effects[i].CalcValue(this), effectPct)); + } + } + + CastCustomSpell(spellInfo->Id, values, target, TRIGGERED_FULL_MASK, item); } } } diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index b7405cbc906..24d7c516388 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1945,8 +1945,8 @@ void SpellMgr::LoadSpellEnchantProcData() mSpellEnchantProcEventMap.clear(); // need for reload case - // 0 1 2 3 - QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx FROM spell_enchant_proc_data"); + // 0 1 2 3 4 + QueryResult result = WorldDatabase.Query("SELECT EnchantID, Chance, ProcsPerMinute, HitMask, AttributesMask FROM spell_enchant_proc_data"); if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty."); @@ -1968,10 +1968,10 @@ void SpellMgr::LoadSpellEnchantProcData() } SpellEnchantProcEntry spe; - - spe.customChance = fields[1].GetUInt32(); - spe.PPMChance = fields[2].GetFloat(); - spe.procEx = fields[3].GetUInt32(); + spe.Chance = fields[1].GetFloat(); + spe.ProcsPerMinute = fields[2].GetFloat(); + spe.HitMask = fields[3].GetUInt32(); + spe.AttributesMask = fields[4].GetUInt32(); mSpellEnchantProcEventMap[enchantId] = spe; diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 112a0897349..30559cc0023 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -265,11 +265,18 @@ struct SpellProcEntry typedef std::unordered_map<uint32, SpellProcEntry> SpellProcMap; +enum EnchantProcAttributes +{ + ENCHANT_PROC_ATTR_WHITE_HIT = 0x0000001, // enchant shall only proc off white hits (not abilities) + ENCHANT_PROC_ATTR_LIMIT_60 = 0x0000002 // enchant effects shall be reduced past lvl 60 +}; + struct SpellEnchantProcEntry { - uint32 customChance; - float PPMChance; - uint32 procEx; + float Chance; // if nonzero - overwrite SpellItemEnchantment value + float ProcsPerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60 + uint32 HitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit + uint32 AttributesMask; // bitmask, see EnchantProcAttributes }; typedef std::unordered_map<uint32, SpellEnchantProcEntry> SpellEnchantProcEventMap; |