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 | 11 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 13 |
3 files changed, 49 insertions, 14 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 4c4f89c493f..b461cbb2704 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7997,10 +7997,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 @@ -8011,6 +8011,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->EffectArg[s]); if (!spellInfo) { @@ -8023,10 +8027,10 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT if (entry) { - if (entry->PPMChance) - chance = GetPPMProcChance(proto->GetDelay(), entry->PPMChance, spellInfo); - else if (entry->customChance) - chance = (float)entry->customChance; + if (entry->ProcsPerMinute) + chance = GetPPMProcChance(proto->GetDelay(), entry->ProcsPerMinute, spellInfo); + else if (entry->Chance) + chance = (float)entry->Chance; } // Apply spell mods @@ -8043,6 +8047,29 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT else CastSpell(damageInfo.GetVictim(), spellInfo, true, item); } + + if (roll_chance_f(chance)) + { + 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->GetLevelForTarget(this) > 60) + { + int32 const lvlDifference = target->GetLevelForTarget(this) - 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->GetEffect(DIFFICULTY_NONE, i)->IsEffect()) + values.AddSpellMod(static_cast<SpellValueMod>(SPELLVALUE_BASE_POINT0 + i), CalculatePct(spellInfo->GetEffect(DIFFICULTY_NONE, 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 190eee167dc..a9dda0332fa 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1791,8 +1791,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."); @@ -1815,9 +1815,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 3b393033ec2..60a13702f94 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -282,11 +282,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; |