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 f609e7a08b)
This commit is contained in:
ariel-
2017-02-22 00:11:49 -03:00
committed by Shauren
parent 5f70be050f
commit 420f2e8ec2
4 changed files with 55 additions and 14 deletions

View File

@@ -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`;

View File

@@ -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);
}
}
}
}

View File

@@ -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;

View File

@@ -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;