aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2018-02-11 22:52:28 -0300
committerariel- <ariel-@users.noreply.github.com>2018-02-12 00:21:26 -0300
commit546a605bd0cd0e828def81e26697f1c116a3f1b7 (patch)
tree92a8b481bd8e2615c54ea6242fd611e0dd42f3e9
parent52873a7072ceb1f88d9caeefdda6084e6bb1d4af (diff)
Core/Spells: implement SPELLVALUE_CRIT_CHANCE and SPELL_ATTR4_INHERIT_CRIT_FROM_AURA
Closes #18813
-rw-r--r--sql/updates/world/3.3.5/2018_02_12_00_world_335.sql1
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp9
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp4
-rw-r--r--src/server/game/Spells/Spell.cpp8
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellDefines.h3
-rw-r--r--src/server/game/Spells/SpellMgr.cpp31
8 files changed, 51 insertions, 8 deletions
diff --git a/sql/updates/world/3.3.5/2018_02_12_00_world_335.sql b/sql/updates/world/3.3.5/2018_02_12_00_world_335.sql
new file mode 100644
index 00000000000..23a2a78c801
--- /dev/null
+++ b/sql/updates/world/3.3.5/2018_02_12_00_world_335.sql
@@ -0,0 +1 @@
+UPDATE `spell_proc` SET `SpellFamilyMask0`=0, `SpellFamilyMask1`=0, `SpellFamilyMask2`=0, `AttributesMask`=(`AttributesMask` & ~0x8) WHERE `SpellId` IN (57529, 57531);
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index f2d82b9c9b2..adf7605def2 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -492,7 +492,7 @@ enum SpellAttr4
SPELL_ATTR4_UNK24 = 0x01000000, // 24 some shoot spell
SPELL_ATTR4_IS_PET_SCALING = 0x02000000, // 25 pet scaling auras
SPELL_ATTR4_CAST_ONLY_IN_OUTLAND = 0x04000000, // 26 Can only be used in Outland.
- SPELL_ATTR4_UNK27 = 0x08000000, // 27
+ SPELL_ATTR4_INHERIT_CRIT_FROM_AURA = 0x08000000, // 27 Volley, Arcane Missiles, Penance -> related to critical on channeled periodical damage spell
SPELL_ATTR4_UNK28 = 0x10000000, // 28 Aimed Shot
SPELL_ATTR4_UNK29 = 0x20000000, // 29
SPELL_ATTR4_UNK30 = 0x40000000, // 30
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index b7ced522b18..92a8d1ce47c 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -5043,7 +5043,11 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
{
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
{
- triggerCaster->CastSpell(target, triggerSpellId, this);
+ CastSpellExtraArgs args(this);
+ if (GetSpellInfo()->HasAttribute(SPELL_ATTR4_INHERIT_CRIT_FROM_AURA))
+ args.AddSpellMod(SPELLVALUE_CRIT_CHANCE, int32(GetBase()->GetCritChance() * 100.0f)); // @todo: ugly x100 remove when basepoints are double
+
+ triggerCaster->CastSpell(target, triggerSpellId, args);
TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
}
}
@@ -5061,6 +5065,9 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit*
CastSpellExtraArgs args(this);
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
args.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), GetAmount());
+ if (GetSpellInfo()->HasAttribute(SPELL_ATTR4_INHERIT_CRIT_FROM_AURA))
+ args.AddSpellMod(SPELLVALUE_CRIT_CHANCE, int32(GetBase()->GetCritChance() * 100.0f)); // @todo: ugly x100 remove when basepoints are double
+
triggerCaster->CastSpell(target, triggerSpellId, args);
TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index f59c19360c8..66a1eaa7f11 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -392,6 +392,10 @@ bool Aura::CanPeriodicTickCrit(Unit const* caster) const
if (GetSpellInfo()->HasAttribute(SPELL_ATTR2_CANT_CRIT))
return false;
+ // need to check this attribute because it's the triggered spell that'll receive the crit chance
+ if (GetSpellInfo()->HasAttribute(SPELL_ATTR4_INHERIT_CRIT_FROM_AURA))
+ return true;
+
if (caster->HasAuraTypeWithAffectMask(SPELL_AURA_ABILITY_PERIODIC_CRIT, GetSpellInfo()))
return true;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 8c186064fff..dcf0bc5b1dc 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -522,6 +522,7 @@ SpellValue::SpellValue(SpellInfo const* proto)
MaxAffectedTargets = proto->MaxAffectedTargets;
RadiusMod = 1.0f;
AuraStackAmount = 1;
+ CriticalChance = 0.0f;
}
class TC_GAME_API SpellEvent : public BasicEvent
@@ -7316,7 +7317,9 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
}
}
- float critChance = m_caster->SpellCritChanceDone(m_spellInfo, m_spellSchoolMask, m_attackType);
+ float critChance = m_spellValue->CriticalChance;
+ if (!critChance)
+ critChance = m_caster->SpellCritChanceDone(m_spellInfo, m_spellSchoolMask, m_attackType);
targetInfo.crit = roll_chance_f(unit->SpellCritChanceTaken(m_caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType));
}
@@ -7404,6 +7407,9 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value)
case SPELLVALUE_AURA_STACK:
m_spellValue->AuraStackAmount = uint8(value);
break;
+ case SPELLVALUE_CRIT_CHANCE:
+ m_spellValue->CriticalChance = value / 100.0f; // @todo ugly /100 remove when basepoints are double
+ break;
}
}
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 9e627b02452..e376d648184 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -217,6 +217,7 @@ struct SpellValue
uint32 MaxAffectedTargets;
float RadiusMod;
uint8 AuraStackAmount;
+ float CriticalChance;
};
enum SpellState
diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h
index 6261fc0594b..14eb0cc31cf 100644
--- a/src/server/game/Spells/SpellDefines.h
+++ b/src/server/game/Spells/SpellDefines.h
@@ -118,7 +118,8 @@ enum SpellValueMod : uint8
SPELLVALUE_BASE_POINT2,
SPELLVALUE_RADIUS_MOD,
SPELLVALUE_MAX_TARGETS,
- SPELLVALUE_AURA_STACK
+ SPELLVALUE_AURA_STACK,
+ SPELLVALUE_CRIT_CHANCE
};
enum SpellFacingFlags
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index a1e47697481..ec66d537640 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2841,7 +2841,7 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
spellInfo->_InitializeExplicitTargetMask();
}
- // addition for binary spells, ommit spells triggering other spells
+ // addition for binary spells, omit spells triggering other spells
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
{
spellInfo = mSpellInfoMap[i];
@@ -2879,17 +2879,36 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
}
// remove attribute from spells that can't crit
+ // and mark triggering spell (instead of triggered spell) for spells with SPELL_ATTR4_INHERIT_CRIT_FROM_AURA
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
{
spellInfo = mSpellInfoMap[i];
if (!spellInfo)
continue;
- if (!spellInfo->HasAttribute(SPELL_ATTR0_CU_CAN_CRIT))
- continue;
-
if (spellInfo->HasAttribute(SPELL_ATTR2_CANT_CRIT))
spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_CAN_CRIT;
+ else if (spellInfo->HasAttribute(SPELL_ATTR4_INHERIT_CRIT_FROM_AURA))
+ {
+ bool found = false;
+ for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ {
+ switch (spellInfo->Effects[j].ApplyAuraName)
+ {
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
+ if (SpellInfo* triggerSpell = const_cast<SpellInfo*>(sSpellMgr->GetSpellInfo(spellInfo->Effects[j].TriggerSpell)))
+ if (triggerSpell->HasAttribute(SPELL_ATTR0_CU_CAN_CRIT))
+ found = true;
+ break;
+ default:
+ continue;
+ }
+ }
+
+ if (found)
+ spellInfo->AttributesCu |= SPELL_ATTR0_CU_CAN_CRIT;
+ }
}
TC_LOG_INFO("server.loading", ">> Loaded SpellInfo custom attributes in %u ms", GetMSTimeDiffToNow(oldMSTime));
@@ -4764,6 +4783,10 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->SpellFamilyFlags[0] |= 0x40;
break;
}
+
+ // allows those to calculate proper crit chance, that needs to be passed on to triggered spell
+ if (spellInfo->HasAttribute(SPELL_ATTR4_INHERIT_CRIT_FROM_AURA) && spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE)
+ spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
}
if (SummonPropertiesEntry* properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(121)))