Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4

Conflicts:
	src/server/game/Entities/Unit/Unit.cpp
	src/server/game/Handlers/MovementHandler.cpp
	src/server/game/Spells/Auras/SpellAuraEffects.cpp
	src/server/scripts/Spells/spell_hunter.cpp
	src/server/scripts/Spells/spell_warlock.cpp
This commit is contained in:
Vincent-Michael
2014-06-09 03:27:53 +02:00
19 changed files with 563 additions and 236 deletions
@@ -0,0 +1,17 @@
UPDATE `gameobject` SET `phaseMask`=1 WHERE `id` IN (192161, 192162);
UPDATE `gameobject` SET `phaseMask`=9 WHERE `id`=193985;
UPDATE `gameobject` SET `phaseMask`=12 WHERE `id` IN (190791, 190792, 190793, 190919, 190920, 190921, 190922, 190923, 190924, 190925, 190926, 190927, 190928, 190929);
UPDATE `gameobject` SET `phaseMask`=19 WHERE `id` IN (190799, 190859, 190860, 190861, 190862, 190863, 190864, 190865, 190866, 190867, 190868, 190869, 190870, 190871, 190872, 190873, 190874, 190875, 190876, 190877, 190878, 190879, 190880, 190881, 190882, 190883, 190884, 190885, 190886, 190887, 190888, 190889, 190890, 190891, 190892, 190893, 190898, 190899, 190900, 190901, 190902, 190903, 190904, 190905, 190906, 190907, 190908, 190909, 190910, 190911, 190930, 190931, 190932, 190933, 190934);
UPDATE `gameobject` SET `phaseMask`=32 WHERE `id` IN (192273, 192274, 192406, 192407, 192416, 192417, 192418, 192433);
UPDATE `gameobject` SET `phaseMask`=35 WHERE `id` IN (190800, 191166, 191167, 191169, 191171, 191172, 191173, 191178, 191191);
UPDATE `gameobject` SET `phaseMask`=51 WHERE `id`=190789;
UPDATE `gameobject` SET `phaseMask`=64 WHERE `id` IN (192269, 192277, 192278, 192414, 192429, 193110, 193111, 193112, 193113, 193114, 193115, 193116, 193117, 193118, 193119, 193120, 193121, 193122, 193123);
UPDATE `gameobject` SET `phaseMask`=66 WHERE `id`=192579;
UPDATE `gameobject` SET `phaseMask`=128 WHERE `id` IN (191261, 191262, 191263, 191264, 191265, 191266, 191267, 191268, 191269, 191270, 191271);
UPDATE `gameobject` SET `phaseMask`=129 WHERE `id` IN (192575, 192578);
UPDATE `gameobject` SET `phaseMask`=193 WHERE `id` IN (192576, 192577);
UPDATE `gameobject` SET `phaseMask`=198 WHERE `id` IN (192934, 192935, 192936, 192937, 192938, 192953, 192954, 192955, 192956, 192957, 192981);
UPDATE `gameobject` SET `phaseMask`=204 WHERE `id` IN (190801, 190802, 190804, 190805, 190806, 190807, 190808, 190809, 190810, 190811, 190812, 190813, 190814, 190815, 190894, 190895, 190896, 190912, 190913, 190935, 191165, 191168, 191170, 191174, 191175, 191176, 191177, 191190);
UPDATE `gameobject` SET `phaseMask`=257 WHERE `id`=192038;
UPDATE `gameobject` SET `phaseMask`=510 WHERE `id` IN (192958, 192959, 192960, 192961, 192962, 192963, 192964, 192965, 192966, 192967, 192968, 192969, 192970, 192971, 192972, 192973, 192974, 192975, 192976, 192977, 192978, 192979, 192980, 192982, 192983, 192985, 192986, 192987, 192988, 192989, 192990, 192991, 192992, 192993, 192994, 192995, 192996, 192997, 192999, 193000, 193001, 193002);
UPDATE `gameobject` SET `phaseMask`=511 WHERE `id` IN (192522, 192787);
@@ -0,0 +1,40 @@
SET @OGUID := 75166;
DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+28;
INSERT INTO `gameobject` (`guid`, `id`, `map`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`) VALUES
(@OGUID+0, 192252, 571, 128, 5154.37, 2853.23, 409.183, 3.14159, 0, 0, 1, 0), -- Alliance Banner
(@OGUID+1, 192253, 571, 128, 5154.42, 2828.93, 409.189, 3.14159, 0, 0, 1, 0), -- Alliance Banner
(@OGUID+2, 192266, 571, 64, 4452.8, 2639, 358.552, 1.4748, 0, 0, -0.672366, 0.740219), -- Alliance Banner
(@OGUID+3, 192267, 571, 128, 4452.76, 2639.14, 358.444, 1.67552, 0, 0, 0.743145, 0.66913), -- Horde Banner
(@OGUID+4, 192268, 571, 128, 4526.51, 2810.18, 390.986, 3.26377, 0, 0, 0.998135, -0.061049), -- Horde Banner
(@OGUID+5, 192270, 571, 64, 4424.71, 2975.6, 367.387, 1.69297, 0, 0, 0.748955, 0.662621), -- Alliance Banner
(@OGUID+6, 192271, 571, 128, 4424.74, 2975.6, 367.227, 1.7017, 0, 0, 0.75184, 0.659346), -- Horde Banner
(@OGUID+7, 192272, 571, 16, 4417.93, 2324.81, 371.219, 3.09796, 0, 0, 0.999762, 0.021815), -- Horde Banner
(@OGUID+8, 192275, 571, 16, 4424.03, 3286.61, 371.418, 3.14159, 0, 0, 1, 0), -- Horde Banner
(@OGUID+9, 192276, 571, 128, 4572.94, 3475.42, 362.805, 1.37881, 0, 0, 0.636078, 0.771625), -- Horde Banner
(@OGUID+10, 192279, 571, 128, 4433.92, 3534.2, 359.942, 1.91113, 0, 0, -0.816641, 0.577146), -- Horde Banner
(@OGUID+11, 192408, 571, 16, 4399.64, 3231.54, 368.898, 1.49226, 0, 0, 0.678801, 0.734322), -- Horde Banner
(@OGUID+12, 192409, 571, 32, 4399.59, 3231.43, 369.216, 1.67552, 0, 0, -0.743145, 0.66913), -- Alliance Banner
(@OGUID+13, 192415, 571, 64, 4517.79, 2716.99, 387.57, 1.53589, 0, 0, -0.694658, 0.71934), -- Alliance Banner
(@OGUID+14, 192423, 571, 64, 4563.73, 2171.15, 367.68, 1.30027, 0, 0, 0.605294, 0.796002), -- Alliance Banner
(@OGUID+15, 192424, 571, 128, 4563.7, 2171.03, 367.607, 1.82387, 0, 0, -0.79069, 0.612217), -- Horde Banner
(@OGUID+16, 192430, 571, 64, 4434.56, 2883.45, 406.025, 0.759216, 0, 0, 0.370557, 0.92881), -- Alliance Banner
(@OGUID+17, 192431, 571, 64, 4349.9, 2885.56, 406.105, 1.6057, 0, 0, 0.71934, 0.694658), -- Alliance Banner
(@OGUID+18, 192432, 571, 16, 4401.62, 3377.48, 363.12, 1.53589, 0, 0, 0.694658, 0.71934), -- Horde Banner
(@OGUID+19, 192440, 571, 128, 4438.38, 3361.01, 371.814, 0.0348707, 0, 0, -0.017452, 0.999848), -- Horde Banner
(@OGUID+20, 192441, 571, 16, 4448.15, 3235.61, 370.617, 1.56207, 0, 0, -0.704015, 0.710185), -- Horde Banner
(@OGUID+21, 192442, 571, 128, 4350.04, 2885.61, 406.329, 1.58825, 0, 0, 0.713251, 0.700909), -- Horde Banner
(@OGUID+22, 192443, 571, 128, 4434.33, 2883.24, 406.346, 0.767944, 0, 0, 0.374607, 0.927184), -- Horde Banner
(@OGUID+23, 192444, 571, 128, 4464.17, 2855.32, 406.391, 0.802851, 0, 0, 0.390731, 0.920505), -- Horde Banner
(@OGUID+24, 192449, 571, 128, 4517.75, 2717.23, 387.812, 1.53589, 0, 0, -0.694658, 0.71934), -- Horde Banner
(@OGUID+25, 192450, 571, 128, 4387.59, 2719.9, 390.201, 1.51843, 0, 0, -0.688354, 0.725375), -- Horde Banner
(@OGUID+26, 192451, 571, 16, 4408.65, 2422.67, 377.454, 1.58825, 0, 0, 0.713251, 0.700909), -- Horde Banner
(@OGUID+27, 192452, 571, 128, 4416.8, 2414.04, 377.487, 0.00895035, 0, 0, 0.004363, 0.99999), -- Horde Banner
(@OGUID+28, 192453, 571, 16, 4417.56, 2301.07, 377.43, 0.017442, 0, 0, 0.008727, 0.999962); -- Horde Banner
UPDATE `gameobject` SET `position_x`=4526.46, `position_y`=2810.18, `position_z`=391.2, `orientation`=3.28995 WHERE `id`=192269; -- Horde Banner
UPDATE `gameobject` SET `position_x`=4991.04, `position_y`=2525.72, `position_z`=340.366, `orientation`=4.04916 WHERE `id`=192290; -- Horde Banner
UPDATE `gameobject` SET `position_x`=4991.08, `position_y`=2525.76, `position_z`=340.918, `orientation`=4.04044 WHERE `id`=192291; -- Alliance Banner
UPDATE `gameobject` SET `position_x`=5352.15, `position_y`=3054.77, `position_z`=444.61, `orientation`=1.57952 WHERE `id`=192376; -- Horde Banner
UPDATE `gameobject` SET `position_x`=4408.57, `position_y`=2422.61, `position_z`=377.179, `orientation`=1.58825 WHERE `id`=192416; -- Alliance Banner
@@ -0,0 +1 @@
DELETE FROM `gameobject` WHERE `guid` IN (66459, 66460, 66461, 66462, 66463, 66464, 66465, 66466, 66467, 66468, 66469, 66470, 66478, 66479, 66516, 66518, 66520, 66600, 66601, 66602, 66603, 66604, 66605, 66606, 66607, 66608, 66609, 66610, 74688, 74690, 74696, 74698, 74702, 74704, 74706, 74712, 74714, 74720, 74722, 74724, 74726, 74728, 74730, 74732, 74734, 74736, 74738, 74740, 74742, 74744, 74746, 74748, 74750, 74752, 74754, 74756, 74758, 74760, 74762, 74764, 74766, 74768, 74770, 74772);
+2 -1
View File
@@ -7809,7 +7809,8 @@ void Player::UpdateArea(uint32 newArea)
{
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
pvpInfo.IsInNoPvPArea = true;
CombatStopWithPets();
if (!duel)
CombatStopWithPets();
}
else
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
+253 -140
View File
@@ -3158,6 +3158,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask)
return;
aura->HandleAuraSpecificMods(aurApp, caster, true, false);
aura->HandleAuraSpecificPeriodics(aurApp, caster);
// apply effects of the aura
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
@@ -6922,23 +6923,14 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
if (GetTypeId() != TYPEID_PLAYER)
return false;
float averageDmg = 0;
// now compute approximate weapon damage by formula from wowwiki.com
Item* item = NULL;
if (procFlags & PROC_FLAG_DONE_OFFHAND_ATTACK)
item = ToPlayer()->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
averageDmg = (GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE)) / 2;
else
item = ToPlayer()->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
averageDmg = (GetFloatValue(UNIT_FIELD_MINDAMAGE) + GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2;
// dunno if it's really needed but will prevent any possible crashes
if (!item)
return false;
ItemTemplate const* weapon = item->GetTemplate();
float weaponDPS = weapon->DPS;
float attackPower = GetTotalAttackPowerValue(BASE_ATTACK) / 14.0f;
float weaponSpeed = float(weapon->Delay) / 1000.0f;
basepoints0 = int32((weaponDPS + attackPower) * weaponSpeed);
basepoints0 = int32(averageDmg);
break;
}
// Persistent Shield (Scarab Brooch trinket)
@@ -8420,39 +8412,162 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
if (Unit* owner = GetOwner())
return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype);
// Done total percent damage auras
float DoneTotalMod = 1.0f;
float ApCoeffMod = 1.0f;
int32 DoneTotal = 0;
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
if (!(*i)->IsAffectingSpell(spellProto))
continue;
switch ((*i)->GetMiscValue())
{
case 4418: // Increased Shock Damage
case 4554: // Increased Lightning Damage
case 4555: // Improved Moonfire
case 5142: // Increased Lightning Damage
case 5147: // Improved Consecration / Libram of Resurgence
case 5148: // Idol of the Shooting Star
case 6008: // Increased Lightning Damage
case 8627: // Totem of Hex
{
DoneTotal += (*i)->GetAmount();
break;
}
}
}
// Custom scripted damage
switch (spellProto->SpellFamilyName)
{
case SPELLFAMILY_DEATHKNIGHT:
// Impurity (dummy effect)
if (GetTypeId() == TYPEID_PLAYER)
{
PlayerSpellMap playerSpells = ToPlayer()->GetSpellMap();
for (PlayerSpellMap::const_iterator itr = playerSpells.begin(); itr != playerSpells.end(); ++itr)
{
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)
continue;
switch (itr->first)
{
case 49220:
case 49633:
case 49635:
case 49636:
case 49638:
if (SpellInfo const* proto = sSpellMgr->GetSpellInfo(itr->first))
AddPct(ApCoeffMod, proto->Effects[0].CalcValue());
break;
}
}
}
break;
}
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
// Pets just add their bonus damage to their spell damage
// note that their spell damage is just gain of their own auras
if (HasUnitTypeMask(UNIT_MASK_GUARDIAN))
DoneAdvertisedBenefit += ((Guardian*)this)->GetBonusDamage();
// Check for table values
float coeff = 0;
SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
if (bonus)
{
if (damagetype == DOT)
{
coeff = bonus->dot_damage;
if (bonus->ap_dot_bonus > 0)
{
WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
APbonus += GetTotalAttackPowerValue(attType);
DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus);
}
}
else
{
coeff = bonus->direct_damage;
if (bonus->ap_bonus > 0)
{
WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
APbonus += GetTotalAttackPowerValue(attType);
DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);
}
}
}
// Default calculation
if (DoneAdvertisedBenefit)
{
if (!bonus || coeff < 0)
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
float factorMod = CalculateLevelPenalty(spellProto) * stack;
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
coeff /= 100.0f;
}
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
// Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods.
float tmpDamage = (int32(pdamage) + DoneTotal) * (damagetype == DOT ? 1.0f : SpellDamagePctDone(victim, spellProto, damagetype));
// apply spellmod to Done damage (flat and pct)
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
return uint32(std::max(tmpDamage, 0.0f));
}
float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const
{
if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
return 1.0f;
// Some spells don't benefit from pct done mods
if (spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)
return 1.0f;
// For totems pct done mods are calculated when its calculation is run on the player in SpellDamageBonusDone.
if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem())
return 1.0f;
// Done total percent damage auras
float DoneTotalMod = 1.0f;
// Pet damage?
if (GetTypeId() == TYPEID_UNIT && !ToCreature()->IsPet())
DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank);
// Some spells don't benefit from pct done mods
if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS))
AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
{
AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
{
if (spellProto->EquippedItemClass == -1 && (*i)->GetSpellInfo()->EquippedItemClass != -1) //prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization)
continue;
if (spellProto->EquippedItemClass == -1 && (*i)->GetSpellInfo()->EquippedItemClass != -1) //prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization)
continue;
if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
{
if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
AddPct(DoneTotalMod, (*i)->GetAmount());
else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0))
AddPct(DoneTotalMod, (*i)->GetAmount());
else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo()))
AddPct(DoneTotalMod, (*i)->GetAmount());
}
if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
{
if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
AddPct(DoneTotalMod, (*i)->GetAmount());
else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0))
AddPct(DoneTotalMod, (*i)->GetAmount());
else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo()))
AddPct(DoneTotalMod, (*i)->GetAmount());
}
}
uint32 creatureTypeMask = victim->GetCreatureTypeMask();
// Add flat bonus from spell damage versus
DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask);
AuraEffectList const& mDamageDoneVersus = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
@@ -8469,7 +8584,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
if (!(*i)->IsAffectingSpell(spellProto))
@@ -8531,18 +8646,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
AddPct(DoneTotalMod, (*i)->GetAmount());
break;
}
case 4418: // Increased Shock Damage
case 4554: // Increased Lightning Damage
case 4555: // Improved Moonfire
case 5142: // Increased Lightning Damage
case 5147: // Improved Consecration / Libram of Resurgence
case 5148: // Idol of the Shooting Star
case 6008: // Increased Lightning Damage
case 8627: // Totem of Hex
{
DoneTotal += (*i)->GetAmount();
break;
}
}
}
@@ -8595,81 +8698,26 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
break;
}
}
// Drain Soul - increased damage for targets under 25 % HP
if (spellProto->SpellFamilyFlags[0] & 0x00004000)
if (HasAura(100001))
DoneTotalMod *= 2;
// Shadow Bite (30% increase from each dot)
if (spellProto->SpellFamilyFlags[1] & 0x00400000 && IsPet())
if (uint8 count = victim->GetDoTsByCaster(GetOwnerGUID()))
AddPct(DoneTotalMod, 30 * count);
// Drain Soul - increased damage for targets under 25 % HP
if (spellProto->SpellFamilyFlags[0] & 0x00004000)
if (HasAura(100001))
DoneTotalMod *= 2;
break;
case SPELLFAMILY_DEATHKNIGHT:
// Sigil of the Vengeful Heart
if (spellProto->SpellFamilyFlags[0] & 0x2000)
if (AuraEffect* aurEff = GetAuraEffect(64962, EFFECT_1))
DoneTotal += aurEff->GetAmount();
DoneTotalMod += aurEff->GetAmount();
break;
}
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
// Pets just add their bonus damage to their spell damage
// note that their spell damage is just gain of their own auras
if (HasUnitTypeMask(UNIT_MASK_GUARDIAN))
DoneAdvertisedBenefit += ((Guardian*)this)->GetBonusDamage();
// Check for table values
float coeff = 0;
SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
if (bonus)
{
if (damagetype == DOT)
{
coeff = bonus->dot_damage;
if (bonus->ap_dot_bonus > 0)
{
WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
APbonus += GetTotalAttackPowerValue(attType);
DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus);
}
}
else
{
coeff = bonus->direct_damage;
if (bonus->ap_bonus > 0)
{
WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
APbonus += GetTotalAttackPowerValue(attType);
DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);
}
}
}
// Default calculation
if (DoneAdvertisedBenefit)
{
if (!bonus || coeff < 0)
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
float factorMod = CalculateLevelPenalty(spellProto) * stack;
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
coeff /= 100.0f;
}
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
float tmpDamage = (int32(pdamage) + DoneTotal) * DoneTotalMod;
// apply spellmod to Done damage (flat and pct)
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
return uint32(std::max(tmpDamage, 0.0f));
return DoneTotalMod;
}
uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) const
@@ -8699,11 +8747,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
// Cheat Death
case 2109:
if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
{
if (GetTypeId() != TYPEID_PLAYER)
continue;
AddPct(TakenTotalMod, (*i)->GetAmount());
}
break;
}
}
@@ -8825,16 +8869,21 @@ int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const
return TakenAdvertisedBenefit;
}
bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const
bool Unit::IsSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const
{
return roll_chance_f(GetUnitSpellCriticalChance(victim, spellProto, schoolMask, attackType));
}
float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const
{
//! Mobs can't crit with spells. Player Totems can
//! Fire Elemental (from totem) can too - but this part is a hack and needs more research
if (IS_CREATURE_GUID(GetGUID()) && !(IsTotem() && IS_PLAYER_GUID(GetOwnerGUID())) && GetEntry() != 15438)
return false;
if (IS_CRE_OR_VEH_GUID(GetGUID()) && !(IsTotem() && IS_PLAYER_GUID(GetOwnerGUID())) && GetEntry() != 15438)
return 0.0f;
// not critting spell
if ((spellProto->AttributesEx2 & SPELL_ATTR2_CANT_CRIT))
return false;
return 0.0f;
float crit_chance = 0.0f;
switch (spellProto->DmgClass)
@@ -8850,7 +8899,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
case 71646: // Item - Bauble of True Blood 25m
break;
default:
return false;
return 0.0f;
}
// Do not add a break here, case fallthrough is intentional! Adding a break will make above spells unable to crit.
case SPELL_DAMAGE_CLASS_MAGIC:
@@ -8949,7 +8998,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
else if (spellProto->GetCategory() == 19)
{
if (victim->GetCreatureTypeMask() & CREATURE_TYPEMASK_DEMON_OR_UNDEAD)
return true;
return 100.0f;
break;
}
break;
@@ -8959,7 +9008,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
{
if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0, 0, GetGUID()))
if (victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE) > -100)
return true;
return 100.0f;
break;
}
break;
@@ -8997,7 +9046,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
break;
}
default:
return false;
return 0.0f;
}
// percent done
// only players use intelligence for critical chance computations
@@ -9009,10 +9058,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectingSpell(spellProto))
crit_chance += (*i)->GetAmount();
crit_chance = crit_chance > 0.0f ? crit_chance : 0.0f;
if (roll_chance_f(crit_chance))
return true;
return false;
return crit_chance > 0.0f ? crit_chance : 0.0f;
}
uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* /*victim*/)
@@ -9075,14 +9121,8 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
if (spellProto->SpellFamilyName == SPELLFAMILY_POTION)
return healamount;
float DoneTotalMod = 1.0f;
int32 DoneTotal = 0;
// Healing done percent
AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
for (AuraEffectList::const_iterator i = mHealingDonePct.begin(); i != mHealingDonePct.end(); ++i)
AddPct(DoneTotalMod, (*i)->GetAmount());
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
@@ -9101,7 +9141,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
case 6935:
case 6918:
if (victim->HealthBelowPct(50))
AddPct(DoneTotalMod, (*i)->GetAmount());
AddPct(DoneTotal, (*i)->GetAmount());
break;
case 8477: // Nourish Heal Boost
{
@@ -9119,7 +9159,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
continue;
modPercent += stepPercent * aura->GetStackAmount();
}
AddPct(DoneTotalMod, modPercent);
AddPct(DoneTotal, modPercent);
break;
}
default:
@@ -9190,8 +9230,8 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal = 0;
}
// use float as more appropriate for negative values and percent applying
float heal = float(int32(healamount) + DoneTotal) * DoneTotalMod;
// Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods.
float heal = float(int32(healamount) + DoneTotal) * (damagetype == DOT ? 1.0f : SpellHealingPctDone(victim, spellProto));
// apply spellmod to Done amount
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal);
@@ -9199,6 +9239,78 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
return uint32(std::max(heal, 0.0f));
}
float Unit::SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const
{
// For totems pct done mods are calculated when its calculation is run on the player in SpellHealingBonusDone.
if (GetTypeId() == TYPEID_UNIT && IsTotem())
return 1.0f;
// No bonus healing for potion spells
if (spellProto->SpellFamilyName == SPELLFAMILY_POTION)
return 1.0f;
float DoneTotalMod = 1.0f;
// Healing done percent
AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
for (AuraEffectList::const_iterator i = mHealingDonePct.begin(); i != mHealingDonePct.end(); ++i)
AddPct(DoneTotalMod, (*i)->GetAmount());
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
if (!(*i)->IsAffectingSpell(spellProto))
continue;
switch ((*i)->GetMiscValue())
{
case 21: // Test of Faith
case 6935:
case 6918:
if (victim->HealthBelowPct(50))
AddPct(DoneTotalMod, (*i)->GetAmount());
break;
case 7798: // Glyph of Regrowth
{
if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x40, 0, 0))
AddPct(DoneTotalMod, (*i)->GetAmount());
break;
}
case 8477: // Nourish Heal Boost
{
int32 stepPercent = (*i)->GetAmount();
int32 modPercent = 0;
AuraApplicationMap const& victimAuras = victim->GetAppliedAuras();
for (AuraApplicationMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
{
Aura const* aura = itr->second->GetBase();
if (aura->GetCasterGUID() != GetGUID())
continue;
SpellInfo const* m_spell = aura->GetSpellInfo();
if (m_spell->SpellFamilyName != SPELLFAMILY_DRUID ||
!(m_spell->SpellFamilyFlags[1] & 0x00000010 || m_spell->SpellFamilyFlags[0] & 0x50))
continue;
modPercent += stepPercent * aura->GetStackAmount();
}
AddPct(DoneTotalMod, modPercent);
break;
}
case 7871: // Glyph of Lesser Healing Wave
{
if (victim->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0, 0x00000400, 0, GetGUID()))
AddPct(DoneTotalMod, (*i)->GetAmount());
break;
}
default:
break;
}
}
return DoneTotalMod;
}
uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) const
{
float TakenTotalMod = 1.0f;
@@ -9542,7 +9654,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType
// Some spells don't benefit from pct done mods
if (spellProto)
if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && !spellProto->IsRankOf(sSpellMgr->GetSpellInfo(12162)))
if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS))
{
AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
@@ -9658,10 +9770,11 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
case 2109:
if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
{
if (GetTypeId() != TYPEID_PLAYER)
continue;
float mod = ToPlayer()->GetRatingBonusValue(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN) * (-8.0f);
AddPct(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
if (Player* player = ToPlayer())
{
float mod = player->GetRatingBonusValue(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN) * (-8.0f);
AddPct(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
}
}
break;
}
+8 -5
View File
@@ -1983,13 +1983,15 @@ class Unit : public WorldObject
Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo);
Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = NULL);
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const;
int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const;
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const;
int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const;
uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1) const;
float SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const;
uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1) const;
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const;
int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const;
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const;
int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const;
uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const;
float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const;
uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const;
uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = NULL);
@@ -1997,7 +1999,8 @@ class Unit : public WorldObject
bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK);
bool isBlockCritical();
bool isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
bool IsSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
float GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
uint32 SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim);
uint32 SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim);
+37 -13
View File
@@ -239,20 +239,28 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
recvData.ReadPackedTime(unkPackedTime);
recvData >> flags;
CalendarEvent calendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
// prevent events in the past
// To Do: properly handle timezones and remove the "- time_t(86400L)" hack
if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L)))
{
recvData.rfinish();
return;
}
CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
if (Player* creator = ObjectAccessor::FindPlayer(guid))
calendarEvent.SetGuildId(creator->GetGuildId());
calendarEvent->SetGuildId(creator->GetGuildId());
if (calendarEvent.IsGuildAnnouncement())
if (calendarEvent->IsGuildAnnouncement())
{
// 946684800 is 01/01/2000 00:00:00 - default response time
CalendarInvite invite(0, calendarEvent.GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
CalendarInvite invite(0, calendarEvent->GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
// WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind
// of storage of the pointer as it will lead to memory corruption
sCalendarMgr->AddInvite(&calendarEvent, &invite);
sCalendarMgr->AddInvite(calendarEvent, &invite);
}
else
{
@@ -275,15 +283,15 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
recvData >> status >> rank;
// 946684800 is 01/01/2000 00:00:00 - default response time
CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent.GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), "");
sCalendarMgr->AddInvite(&calendarEvent, invite, trans);
CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), "");
sCalendarMgr->AddInvite(calendarEvent, invite, trans);
}
if (inviteCount > 1)
CharacterDatabase.CommitTransaction(trans);
}
sCalendarMgr->AddEvent(new CalendarEvent(calendarEvent, calendarEvent.GetEventId()), CALENDAR_SENDTYPE_ADD);
sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
}
void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData)
@@ -308,6 +316,14 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData)
recvData.ReadPackedTime(timeZoneTime);
recvData >> flags;
// prevent events in the past
// To Do: properly handle timezones and remove the "- time_t(86400L)" hack
if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L)))
{
recvData.rfinish();
return;
}
TC_LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [" UI64FMTD "] EventId [" UI64FMTD
"], InviteId [" UI64FMTD "] Title %s, Description %s, type %u "
"Repeatable %u, MaxInvites %u, Dungeon ID %d, Time %u "
@@ -350,17 +366,25 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData)
uint64 guid = _player->GetGUID();
uint64 eventId;
uint64 inviteId;
uint32 time;
uint32 eventTime;
recvData >> eventId >> inviteId;
recvData.ReadPackedTime(time);
recvData.ReadPackedTime(eventTime);
TC_LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [" UI64FMTD "], EventId [" UI64FMTD
"] inviteId [" UI64FMTD "] Time: %u", guid, eventId, inviteId, time);
"] inviteId [" UI64FMTD "] Time: %u", guid, eventId, inviteId, eventTime);
// prevent events in the past
// To Do: properly handle timezones and remove the "- time_t(86400L)" hack
if (time_t(eventTime) < (time(NULL) - time_t(86400L)))
{
recvData.rfinish();
return;
}
if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
{
CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
newEvent->SetEventTime(time_t(time));
newEvent->SetEventTime(time_t(eventTime));
sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId);
+1 -1
View File
@@ -530,7 +530,7 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket& recvPacket)
if (GetPlayer()->IsInWorld())
{
if (_player->m_mover->GetGUID() != guid)
TC_LOG_ERROR("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is " UI64FMTD " (%s - Entry: %u) and should be " UI64FMTD, uint64(guid), GetLogNameForGuid(guid), GUID_ENPART(guid), _player->m_mover->GetGUID());
TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is " UI64FMTD " (%s - Entry: %u) and should be " UI64FMTD, uint64(guid), GetLogNameForGuid(guid), GUID_ENPART(guid), _player->m_mover->GetGUID());
}
}
+3 -3
View File
@@ -79,13 +79,13 @@ void WorldSession::HandlePetAction(WorldPacket& recvData)
if (!pet)
{
TC_LOG_ERROR("network", "HandlePetAction: Pet (GUID: %u) doesn't exist for player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
TC_LOG_DEBUG("network", "HandlePetAction: Pet (GUID: %u) doesn't exist for player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
return;
}
if (pet != GetPlayer()->GetFirstControlled())
{
TC_LOG_ERROR("network", "HandlePetAction: Pet (GUID: %u) does not belong to player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
TC_LOG_DEBUG("network", "HandlePetAction: Pet (GUID: %u) does not belong to player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
return;
}
@@ -149,7 +149,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint32 spellid
CharmInfo* charmInfo = pet->GetCharmInfo();
if (!charmInfo)
{
TC_LOG_ERROR("network", "WorldSession::HandlePetAction(petGuid: " UI64FMTD ", tagGuid: " UI64FMTD ", spellId: %u, flag: %u): object (GUID: %u Entry: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!",
TC_LOG_DEBUG("network", "WorldSession::HandlePetAction(petGuid: " UI64FMTD ", tagGuid: " UI64FMTD ", spellId: %u, flag: %u): object (GUID: %u Entry: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!",
guid1, guid2, spellid, flag, pet->GetGUIDLow(), pet->GetEntry(), pet->GetTypeId());
return;
}
@@ -435,7 +435,7 @@ AuraEffect::AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* cast
m_base(base), m_spellInfo(base->GetSpellInfo()),
m_baseAmount(baseAmount ? *baseAmount : m_spellInfo->Effects[effIndex].BasePoints),
m_spellmod(NULL), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex),
m_canBeRecalculated(true), m_isPeriodic(false)
m_canBeRecalculated(true), m_damage(0), m_critChance(0.0f), m_donePct(1.0f), m_isPeriodic(false)
{
CalculatePeriodic(caster, true, false);
@@ -995,10 +995,11 @@ void AuraEffect::UpdatePeriodic(Unit* caster)
GetBase()->CallScriptEffectUpdatePeriodicHandlers(this);
}
bool AuraEffect::IsPeriodicTickCrit(Unit* target, Unit const* caster) const
bool AuraEffect::CanPeriodicTickCrit(Unit const* caster) const
{
ASSERT(caster);
return caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask());
return caster->HasAuraTypeWithAffectMask(SPELL_AURA_ABILITY_PERIODIC_CRIT, m_spellInfo);
}
bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const
@@ -5766,15 +5767,19 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
uint32 resist = 0;
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
// ignore non positive values (can be result apply spellmods to aura damage
uint32 damage = std::max(GetAmount(), 0);
// AOE spells are not affected by the new periodic system.
bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
if (isAreaAura)
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE)
{
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
if (isAreaAura)
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
// Calculate armor mitigation
@@ -5821,14 +5826,19 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
else
damage = uint32(target->CountPctFromMaxHealth(damage));
if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
{
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (caster->GetTypeId() != TYPEID_PLAYER)
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
}
if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
{
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (caster->GetTypeId() != TYPEID_PLAYER)
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
}
bool crit = false;
if (CanPeriodicTickCrit(caster))
crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()) : m_critChance);
bool crit = IsPeriodicTickCrit(target, caster);
if (crit)
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
@@ -5884,23 +5894,42 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
uint32 resist = 0;
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
uint32 damage = std::max(GetAmount(), 0);
bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
if (isAreaAura)
{
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
}
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
bool crit = IsPeriodicTickCrit(target, caster);
if (crit)
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
// Calculate armor mitigation
if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), m_effIndex))
if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellInfo());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
damage = damageReductedArmor;
}
if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
{
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (caster->GetTypeId() != TYPEID_PLAYER)
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
}
bool crit = false;
if (CanPeriodicTickCrit(caster))
crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()) : m_critChance);
if (crit)
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
int32 dmg = damage;
if (!(GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
caster->ApplyResilience(target, &dmg);
@@ -5985,8 +6014,9 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
if (GetBase()->IsPermanent() && target->IsFullHealth())
return;
bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
int32 damage = std::max(m_amount, 0);
int32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
if (GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH)
{
@@ -6025,12 +6055,16 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
damage += addition;
}
damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
if (isAreaAura)
damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellHealingPctDone(target, m_spellInfo);
damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
}
bool crit = IsPeriodicTickCrit(target, caster);
bool crit = false;
if (CanPeriodicTickCrit(caster))
crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()) : m_critChance);
if (crit)
damage = caster->SpellCriticalHealingBonus(m_spellInfo, damage, target);
@@ -70,6 +70,13 @@ class AuraEffect
void HandleEffect(Unit* target, uint8 mode, bool apply);
void ApplySpellMod(Unit* target, bool apply);
void SetDamage(int32 val) { m_damage = val; }
int32 GetDamage() const { return m_damage; }
void SetCritChance(float val) { m_critChance = val; }
float GetCritChance() const { return m_critChance; }
void SetDonePct(float val) { m_donePct = val; }
float GetDonePct() const { return m_donePct; }
void Update(uint32 diff, Unit* caster);
void UpdatePeriodic(Unit* caster);
@@ -98,6 +105,9 @@ class AuraEffect
int32 const m_baseAmount;
int32 m_amount;
int32 m_damage;
float m_critChance;
float m_donePct;
SpellModifier* m_spellmod;
@@ -109,7 +119,7 @@ class AuraEffect
bool m_canBeRecalculated;
bool m_isPeriodic;
private:
bool IsPeriodicTickCrit(Unit* target, Unit const* caster) const;
bool CanPeriodicTickCrit(Unit const* caster) const;
public:
// aura effect apply/remove handlers
+70 -20
View File
@@ -755,9 +755,20 @@ void Aura::SetDuration(int32 duration, bool withMods)
SetNeedClientUpdateForTargets();
}
void Aura::RefreshDuration()
void Aura::RefreshDuration(bool withMods)
{
SetDuration(GetMaxDuration());
if (withMods)
{
int32 duration = m_spellInfo->GetMaxDuration();
// Calculate duration of periodics affected by haste.
if (GetCaster()->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, m_spellInfo) || m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
duration = int32(duration * GetCaster()->GetFloatValue(UNIT_MOD_CAST_SPEED));
SetMaxDuration(duration);
SetDuration(duration);
}
else
SetDuration(GetMaxDuration());
if (m_spellInfo->ManaPerSecond)
m_timeCla = 1 * IN_MILLISECONDS;
@@ -851,7 +862,10 @@ void Aura::SetStackAmount(uint8 stackAmount)
for (std::list<AuraApplication*>::const_iterator apptItr = applications.begin(); apptItr != applications.end(); ++apptItr)
if (!(*apptItr)->GetRemoveMode())
{
HandleAuraSpecificMods(*apptItr, caster, true, true);
HandleAuraSpecificPeriodics(*apptItr, caster);
}
SetNeedClientUpdateForTargets();
}
@@ -1459,26 +1473,62 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
break;
}
break;
case SPELLFAMILY_WARLOCK:
// Drain Soul - If the target is at or below 25% health, Drain Soul causes four times the normal damage
if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000)
}
}
void Aura::HandleAuraSpecificPeriodics(AuraApplication const* aurApp, Unit* caster)
{
Unit* target = aurApp->GetTarget();
if (!caster || aurApp->GetRemoveMode())
return;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (!HasEffect(i))
continue;
if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
continue;
switch (m_spellInfo->Effects[i].ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
case SPELL_AURA_PERIODIC_LEECH:
{
if (!caster)
break;
if (apply)
{
if (target != caster && !target->HealthAbovePct(25))
caster->CastSpell(caster, 100001, true);
}
else
{
if (target != caster)
caster->RemoveAurasDueToSpell(GetId());
else
caster->RemoveAurasDueToSpell(100001);
}
AuraEffect* aurEff = GetEffect(i);
// ignore non positive values (can be result apply spellmods to aura damage
uint32 damage = std::max(aurEff->GetAmount(), 0);
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
aurEff->SetDonePct(caster->SpellDamagePctDone(target, m_spellInfo, DOT)); // Calculate done percentage first!
aurEff->SetDamage(caster->SpellDamageBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * aurEff->GetDonePct());
aurEff->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
break;
}
break;
case SPELL_AURA_PERIODIC_HEAL:
case SPELL_AURA_OBS_MOD_HEALTH:
{
AuraEffect* aurEff = GetEffect(i);
// ignore non positive values (can be result apply spellmods to aura damage
uint32 damage = std::max(aurEff->GetAmount(), 0);
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
aurEff->SetDonePct(caster->SpellHealingPctDone(target, m_spellInfo)); // Calculate done percentage first!
aurEff->SetDamage(caster->SpellHealingBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * aurEff->GetDonePct());
aurEff->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
break;
}
default:
break;
}
}
}
+2 -1
View File
@@ -129,7 +129,7 @@ class Aura
int32 CalcMaxDuration(Unit* caster) const;
int32 GetDuration() const { return m_duration; }
void SetDuration(int32 duration, bool withMods = false);
void RefreshDuration();
void RefreshDuration(bool withMods = false);
void RefreshTimers();
bool IsExpired() const { return !GetDuration();}
bool IsPermanent() const { return GetMaxDuration() == -1; }
@@ -190,6 +190,7 @@ class Aura
void SetNeedClientUpdateForTargets() const;
void HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, bool apply, bool onReapply);
void HandleAuraSpecificPeriodics(AuraApplication const* aurApp, Unit* caster);
bool CanBeAppliedOn(Unit* target);
bool CheckAreaTarget(Unit* target);
bool CanStackWith(Aura const* existingAura) const;
+2 -2
View File
@@ -2346,7 +2346,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// Do healing and triggers
if (m_healing > 0)
{
bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
bool crit = caster->IsSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
uint32 addhealth = m_healing;
if (crit)
{
@@ -6758,7 +6758,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
}
}
targetInfo.crit = m_caster->isSpellCrit(unit, m_spellInfo, m_spellSchoolMask, m_attackType);
targetInfo.crit = m_caster->IsSpellCrit(unit, m_spellInfo, m_spellSchoolMask, m_attackType);
}
SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue)
+29 -4
View File
@@ -960,7 +960,7 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/)
TC_LOG_DEBUG("spells", "Spell::EffectTeleportUnits - teleport unit to %u %f %f %f %f\n", mapid, x, y, z, orientation);
if (unitTarget->GetTypeId() == TYPEID_PLAYER)
unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL | TELE_TO_NOT_LEAVE_COMBAT : 0);
else if (mapid == unitTarget->GetMapId())
unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster);
else
@@ -3755,15 +3755,40 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
{
// Get diseases on target of spell
if (m_targets.GetUnitTarget() && // Glyph of Disease - cast on unit target too to refresh aura
(m_targets.GetUnitTarget() != unitTarget || m_caster->GetAura(63334)))
(m_targets.GetUnitTarget() != unitTarget || m_caster->HasAura(63334)))
{
// And spread them on target
// Blood Plague
if (m_targets.GetUnitTarget()->GetAura(55078))
if (m_targets.GetUnitTarget()->HasAura(55078))
{
AuraEffect* aurEffOld = m_targets.GetUnitTarget()->GetAura(55078)->GetEffect(0);
float donePct = aurEffOld->GetDonePct();
float critChance = aurEffOld->GetCritChance();
m_caster->CastSpell(unitTarget, 55078, true);
if (unitTarget->HasAura(55078))
if (AuraEffect* aurEffNew = unitTarget->GetAura(55078)->GetEffect(0))
{
aurEffNew->SetCritChance(critChance); // Blood Plague can crit if caster has T9.
aurEffNew->SetDonePct(donePct);
aurEffNew->SetDamage(m_caster->SpellDamageBonusDone(unitTarget, aurEffNew->GetSpellInfo(), std::max(aurEffNew->GetAmount(), 0), DOT) * donePct);
}
}
// Frost Fever
if (m_targets.GetUnitTarget()->GetAura(55095))
if (m_targets.GetUnitTarget()->HasAura(55095))
{
float donePct = m_targets.GetUnitTarget()->GetAura(55095)->GetEffect(0)->GetDonePct();
m_caster->CastSpell(unitTarget, 55095, true);
if (unitTarget->HasAura(55095))
if (AuraEffect* aurEffNew = unitTarget->GetAura(55095)->GetEffect(0))
{
aurEffNew->SetDonePct(donePct);
aurEffNew->SetDamage(m_caster->SpellDamageBonusDone(unitTarget, aurEffNew->GetSpellInfo(), std::max(aurEffNew->GetAmount(), 0), DOT) * donePct);
}
}
}
}
break;
@@ -1813,7 +1813,6 @@ public:
enum ZuluhedChains
{
QUEST_ZULUHED = 10866,
NPC_KARYNAKU = 22112,
};
@@ -1828,9 +1827,9 @@ class spell_unlocking_zuluheds_chains : public SpellScriptLoader
void HandleAfterHit()
{
if (GetCaster()->GetTypeId() == TYPEID_PLAYER)
if (Creature* karynaku = GetCaster()->FindNearestCreature(NPC_KARYNAKU, 15.0f))
GetCaster()->ToPlayer()->KilledMonsterCredit(NPC_KARYNAKU, karynaku->GetGUID());
if (Player* caster = GetCaster()->ToPlayer())
if (Creature* karynaku = caster->FindNearestCreature(NPC_KARYNAKU, 15.0f))
caster->KilledMonsterCredit(NPC_KARYNAKU, karynaku->GetGUID());
}
void Register() override
+9 -2
View File
@@ -737,10 +737,17 @@ class spell_pri_pain_and_suffering_proc : public SpellScriptLoader
void HandleEffectScriptEffect(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
// Refresh Shadow Word: Pain on target
if (Unit* unitTarget = GetHitUnit())
if (AuraEffect* aur = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, GetCaster()->GetGUID()))
if (Unit* target = GetHitUnit())
if (AuraEffect* aur = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, caster->GetGUID()))
{
uint32 damage = std::max(aur->GetAmount(), 0);
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
aur->SetDamage(caster->SpellDamageBonusDone(target, aur->GetSpellInfo(), damage, DOT) * aur->GetDonePct());
aur->CalculatePeriodic(caster, false, false);
aur->GetBase()->RefreshDuration();
}
}
void Register() override
+10 -3
View File
@@ -537,10 +537,17 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Unit* unitTarget = GetHitUnit())
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
// Refresh corruption on target
if (AuraEffect* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, GetCaster()->GetGUID()))
aurEff->GetBase()->RefreshDuration();
if (AuraEffect* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, caster->GetGUID()))
{
uint32 damage = std::max(aurEff->GetAmount(), 0);
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
aurEff->SetDamage(caster->SpellDamageBonusDone(target, aurEff->GetSpellInfo(), damage, DOT) * aurEff->GetDonePct());
aurEff->CalculatePeriodic(caster, false, false);
aurEff->GetBase()->RefreshDuration(true);
}
}
void Register() override
+6 -11
View File
@@ -36,7 +36,7 @@ enum WarriorSpells
SPELL_WARRIOR_DEEP_WOUNDS_RANK_1 = 12162,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_2 = 12850,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_3 = 12868,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC = 12721,
SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC = 12721,
SPELL_WARRIOR_EXECUTE = 20647,
SPELL_WARRIOR_GLYPH_OF_EXECUTION = 58367,
SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156,
@@ -231,7 +231,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader
if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_1) ||
!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_2) ||
!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_3) ||
!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC))
!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC))
return false;
return true;
}
@@ -242,23 +242,18 @@ class spell_warr_deep_wounds : public SpellScriptLoader
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
{
// apply percent damage mods
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
ApplyPct(damage, 16 * GetSpellInfo()->GetRank());
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC);
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC);
uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude;
// Add remaining ticks to damage done
if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC, EFFECT_0, caster->GetGUID()))
damage += aurEff->GetAmount() * (ticks - aurEff->GetTickNumber());
if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC, EFFECT_0, caster->GetGUID()))
damage += aurEff->GetDamage() * (ticks - aurEff->GetTickNumber());
damage /= ticks;
caster->CastCustomSpell(target, SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC, &damage, NULL, NULL, true);
caster->CastCustomSpell(target, SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC, &damage, NULL, NULL, true);
}
}