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

(cherry picked from commit f609e7a08b3b4d2d9642e5ec252e1eedad836f0f)
This commit is contained in:
ariel- authored and funjoker committed 2022-02-16 04:49:24 +01:00
1 parent 5e57ad6fa8
commit b8d1bab8de
4 files changed
+51 -18

No files matched your search

@@ -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`;
+29 -10
View File
@@ -8005,10 +8005,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
@@ -8019,6 +8019,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)
{
@@ -8030,10 +8034,10 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
float chance = pEnchant->EffectPointsMin[s] != 0 ? float(pEnchant->EffectPointsMin[s]) : GetWeaponProcChance();
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
@@ -8045,10 +8049,25 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
if (roll_chance_f(chance))
{
if (spellInfo->IsPositive())
CastSpell(this, spellInfo->Id, item);
else
CastSpell(damageInfo.GetVictim(), spellInfo->Id, item);
Unit* target = spellInfo->IsPositive() ? this : damageInfo.GetVictim();
// reduce effect values if enchant is limited
CastSpellExtraArgs args(item);
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())
args.AddSpellMod(static_cast<SpellValueMod>(SPELLVALUE_BASE_POINT0 + i), CalculatePct(spellInfo->Effects[i].CalcValue(this), effectPct));
}
}
CastSpell(target, spellInfo->Id, args);
}
}
}
+6 -5
View File
@@ -2091,8 +2091,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.");
@@ -2115,9 +2115,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;
+10 -3
View File
@@ -269,11 +269,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;