diff options
author | ariel- <ariel-@users.noreply.github.com> | 2017-02-22 00:11:49 -0300 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2019-08-17 20:04:14 +0200 |
commit | 420f2e8ec2c5f19db313492c52a730c87fa2dab6 (patch) | |
tree | 470354aabdaefdf3c4ffb2a6a4eb91b78f68ea6f | |
parent | 5f70be050f971ee70da8953c4f094cb2adc233f8 (diff) |
Core/Spells: refactor spell_enchant_proc_data table
- Renamed fields to mimic those in spell_proc
- Added Enchant proc attributes for controlling specific enchant features
Ref #7789
(cherrypicked from f609e7a08b3b4d2d9642e5ec252e1eedad836f0f)
-rw-r--r-- | sql/updates/world/master/2019_07_28_02_world_2017_02_21_02_world.sql | 6 | ||||
-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 |
4 files changed, 55 insertions, 14 deletions
diff --git a/sql/updates/world/master/2019_07_28_02_world_2017_02_21_02_world.sql b/sql/updates/world/master/2019_07_28_02_world_2017_02_21_02_world.sql new file mode 100644 index 00000000000..fa0f11d7f80 --- /dev/null +++ b/sql/updates/world/master/2019_07_28_02_world_2017_02_21_02_world.sql @@ -0,0 +1,6 @@ +ALTER TABLE `spell_enchant_proc_data` + CHANGE `entry` `EnchantID` int(10) UNSIGNED NOT NULL, + CHANGE `customChance` `Chance` float DEFAULT '0' NOT NULL, + CHANGE `PPMChance` `ProcsPerMinute` float DEFAULT '0' NOT NULL, + CHANGE `procEx` `HitMask` int(10) UNSIGNED DEFAULT '0' NOT NULL, + ADD COLUMN `AttributesMask` int(10) UNSIGNED DEFAULT '0' NOT NULL AFTER `HitMask`; 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; |