diff options
| -rw-r--r-- | sql/updates/world/3.3.5/2018_02_12_00_world_335.sql | 1 | ||||
| -rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 9 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.h | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellDefines.h | 3 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 31 |
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))) |
