diff options
| author | joschiwald <joschiwald@online.de> | 2012-05-28 04:27:51 +0200 |
|---|---|---|
| committer | joschiwald <joschiwald@online.de> | 2012-05-28 04:27:51 +0200 |
| commit | cd7ab6f3a5e86e51d19621ce5ab5560cd7eb62bc (patch) | |
| tree | 3e13fd8e4472a3dece8e6691df794f87bfe3e59d /src/server/game/Entities/Unit | |
| parent | ca07f30d0359bf5a6eecba8b9cc68702eca4071b (diff) | |
| parent | 9c417ff931a98a2ba35b30e76f8967c7f841e868 (diff) | |
Merge branch 'master' of github.com:joschiwald/TrinityCore into spellscripts
Conflicts:
src/server/game/Entities/Unit/Unit.cpp
src/server/game/Spells/Auras/SpellAuraEffects.cpp
src/server/game/Spells/Spell.cpp
src/server/game/Spells/SpellEffects.cpp
src/server/scripts/Spells/spell_paladin.cpp
Diffstat (limited to 'src/server/game/Entities/Unit')
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 290 | ||||
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 10 |
2 files changed, 147 insertions, 153 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8e2738783dc..a624170ef91 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -954,7 +954,7 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit* victim, uint32 spellID, uint32 damage) SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID); SpellNonMeleeDamage damageInfo(this, victim, spellInfo->Id, spellInfo->SchoolMask); damage = SpellDamageBonusDone(victim, spellInfo, damage, SPELL_DIRECT_DAMAGE); - damage = victim->SpellDamageBonusTaken(spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = victim->SpellDamageBonusTaken(this, spellInfo, damage, SPELL_DIRECT_DAMAGE); CalculateSpellDamageTaken(&damageInfo, damage, spellInfo); DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); @@ -1151,7 +1151,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damage += CalculateDamage(damageInfo->attackType, false, true); // Add melee damage bonus damage = MeleeDamageBonusDone(damageInfo->target, damage, damageInfo->attackType); - damage = MeleeDamageBonusTaken(damage, damageInfo->attackType); + damage = damageInfo->target->MeleeDamageBonusTaken(this, damage, damageInfo->attackType); // Calculate armor reduction if (IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damageSchoolMask))) @@ -1405,7 +1405,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) if (Unit* caster = (*dmgShieldItr)->GetCaster()) { damage = caster->SpellDamageBonusDone(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE); - damage = this->SpellDamageBonusTaken(i_spellProto, damage, SPELL_DIRECT_DAMAGE); + damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE); } // No Unit::CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that @@ -5789,7 +5789,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere if (AuraEffect* aurEff = victim->GetAuraEffect(64413, 0, GetGUID())) { // The shield can grow to a maximum size of 20, 000 damage absorbtion - aurEff->SetAmount(std::max<int32>(aurEff->GetAmount() + basepoints0, 20000)); + aurEff->SetAmount(std::min<int32>(aurEff->GetAmount() + basepoints0, 20000)); // Refresh and return to prevent replacing the aura aurEff->GetBase()->RefreshDuration(); @@ -7285,30 +7285,16 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere if (procSpell->SpellIconID != 2019) return false; - AuraEffect* aurEffA = NULL; - AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); - for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) + if (Creature* totem = GetMap()->GetCreature(m_SummonSlot[1])) // Fire totem summon slot { - SpellInfo const* spell = (*i)->GetSpellInfo(); - if (spell->SpellFamilyName == uint32(SPELLFAMILY_SHAMAN) && spell->SpellFamilyFlags.HasFlag(0, 0x02000000, 0)) + if (SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(totem->m_spells[0])) { - if ((*i)->GetCasterGUID() != GetGUID()) - continue; - if (spell->Id == 63283) - continue; - aurEffA = (*i); - break; + int32 bp0 = CalculatePctN(totemSpell->Effects[EFFECT_0].CalcValue(), triggerAmount); + int32 bp1 = CalculatePctN(totemSpell->Effects[EFFECT_1].CalcValue(), triggerAmount); + CastCustomSpell(this, 63283, &bp0, &bp1, NULL, true); + return true; } } - if (aurEffA) - { - int32 bp0 = 0, bp1 = 0; - bp0 = CalculatePctN(triggerAmount, aurEffA->GetAmount()); - if (AuraEffect* aurEffB = aurEffA->GetBase()->GetEffect(EFFECT_1)) - bp1 = CalculatePctN(triggerAmount, aurEffB->GetAmount()); - CastCustomSpell(this, 63283, &bp0, &bp1, NULL, true, NULL, triggeredByAura); - return true; - } return false; } break; @@ -7705,17 +7691,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } } } - // Item - Death Knight T10 Melee 4P Bonus - if (dummySpell->Id == 70656) - { - Player* player = ToPlayer(); - if (!player) - return false; - - for (uint32 i = 0; i < MAX_RUNES; ++i) - if (player->GetRuneCooldown(i) == 0) - return false; - } break; } case SPELLFAMILY_POTION: @@ -7983,7 +7958,7 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp *handled = true; if (victim && victim->HasAura(53601)) { - int32 bp0 = CalculatePctN(int32(damage / 12), dummySpell->Effects[EFFECT_2]. CalcValue()); + int32 bp0 = CalculatePctN(int32(damage / 12), dummySpell->Effects[EFFECT_2].CalcValue()); // Item - Paladin T9 Holy 4P Bonus if (AuraEffect const* aurEff = GetAuraEffect(67191, 0)) AddPctN(bp0, aurEff->GetAmount()); @@ -8643,6 +8618,16 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg trigger_spell_id = 50475; basepoints0 = CalculatePctN(int32(damage), triggerAmount); } + // Item - Death Knight T10 Melee 4P Bonus + else if (auraSpellInfo->Id == 70656) + { + if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT) + return false; + + for (uint8 i = 0; i < MAX_RUNES; ++i) + if (ToPlayer()->GetRuneCooldown(i) == 0) + return false; + } break; } case SPELLFAMILY_ROGUE: @@ -10125,7 +10110,7 @@ Unit* Unit::GetFirstControlled() const // Sequence: charmed, pet, other guardians Unit* unit = GetCharm(); if (!unit) - if (uint64 guid = GetUInt64Value(UNIT_FIELD_SUMMON)) + if (uint64 guid = GetMinionGUID()) unit = ObjectAccessor::GetUnit(*this, guid); return unit; @@ -10326,20 +10311,24 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (GetTypeId() == TYPEID_UNIT && !ToCreature()->isPet()) DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank); - AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) + // Some spells don't benefit from pct done mods + if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && !spellProto->IsRankOf(sSpellMgr->GetSpellInfo(12162))) { - 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()) + AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) { - if ((*i)->GetSpellInfo()->EquippedItemClass == -1) - AddPctN(DoneTotalMod, (*i)->GetAmount()); - else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) - AddPctN(DoneTotalMod, (*i)->GetAmount()); - else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) - AddPctN(DoneTotalMod, (*i)->GetAmount()); + 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) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + } } } @@ -10519,7 +10508,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin break; } } - break; + break; case SPELLFAMILY_PRIEST: // Mind Flay if (spellProto->SpellFamilyFlags[0] & 0x800000) @@ -10552,7 +10541,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT)) AddPctN(DoneTotalMod, aurEff->GetAmount()); } - break; + break; case SPELLFAMILY_PALADIN: // Judgement of Vengeance/Judgement of Corruption if ((spellProto->SpellFamilyFlags[1] & 0x400000) && spellProto->SpellIconID == 2292) @@ -10570,7 +10559,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (stacks) AddPctU(DoneTotalMod, 10 * stacks); } - break; + break; case SPELLFAMILY_DRUID: // Thorns if (spellProto->SpellFamilyFlags[0] & 0x100) @@ -10579,7 +10568,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (AuraEffect* aurEff = GetAuraEffectOfRankedSpell(16836, 0)) AddPctN(DoneTotalMod, aurEff->GetAmount()); } - break; + break; case SPELLFAMILY_WARLOCK: // Fire and Brimstone if (spellProto->SpellFamilyFlags[1] & 0x00020040) @@ -10601,14 +10590,14 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (spellProto->SpellFamilyFlags[1] & 0x00400000 && isPet()) if (uint8 count = victim->GetDoTsByCaster(GetOwnerGUID())) AddPctN(DoneTotalMod, 15 * count); - break; + break; case SPELLFAMILY_HUNTER: // Steady Shot if (spellProto->SpellFamilyFlags[1] & 0x1) if (AuraEffect* aurEff = GetAuraEffect(56826, 0)) // Glyph of Steady Shot if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_HUNTER, 0x00004000, 0, 0, GetGUID())) AddPctN(DoneTotalMod, aurEff->GetAmount()); - break; + break; case SPELLFAMILY_DEATHKNIGHT: // Improved Icy Touch if (spellProto->SpellFamilyFlags[0] & 0x2) @@ -10649,7 +10638,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin } } } - break; + break; } // Done fixed damage bonus auras @@ -10670,7 +10659,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin 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); + 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); } @@ -10681,7 +10670,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin 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); + 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); } @@ -10711,12 +10700,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin DoneTotalMod = 1.0f; } - // Some spells don't benefit from pct done mods - // maybe should be implemented like SPELL_ATTR3_NO_DONE_BONUS, - // but then it may break spell power coeffs work on spell 31117 - if (spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) - DoneTotalMod = 1.0f; - float tmpDamage = (int32(pdamage) + DoneTotal) * DoneTotalMod; // apply spellmod to Done damage (flat and pct) if (Player* modOwner = GetSpellModOwner()) @@ -10725,7 +10708,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin return uint32(std::max(tmpDamage, 0.0f)); } -uint32 Unit::SpellDamageBonusTaken(SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) +uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) { if (!spellProto || damagetype == DIRECT_DAMAGE) return pdamage; @@ -10733,11 +10716,11 @@ uint32 Unit::SpellDamageBonusTaken(SpellInfo const* spellProto, uint32 pdamage, int32 TakenTotal = 0; float TakenTotalMod = 1.0f; - //from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN - //multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085) + // from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN + // multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085) TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, spellProto->GetSchoolMask()); - //.. taken pct: dummy auras + //.. taken pct: dummy auras AuraEffectList const& mDummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY); for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) { @@ -10759,7 +10742,7 @@ uint32 Unit::SpellDamageBonusTaken(SpellInfo const* spellProto, uint32 pdamage, // From caster spells AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) - if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) + if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) AddPctN(TakenTotalMod, (*i)->GetAmount()); // Mod damage from spell mechanic @@ -10796,7 +10779,7 @@ uint32 Unit::SpellDamageBonusTaken(SpellInfo const* spellProto, uint32 pdamage, TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod); } - float tmpDamage = (pdamage + TakenTotal) * TakenTotalMod; + float tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod; return uint32(std::max(tmpDamage, 0.0f)); } @@ -10837,7 +10820,7 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) DoneAdvertisedBenefit += int32(CalculatePctN(GetTotalAttackPowerValue(BASE_ATTACK), (*i)->GetAmount())); } - return DoneAdvertisedBenefit > 0 ? DoneAdvertisedBenefit : 0; + return DoneAdvertisedBenefit; } int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) @@ -10849,7 +10832,7 @@ int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) if (((*i)->GetMiscValue() & schoolMask) != 0) TakenAdvertisedBenefit += (*i)->GetAmount(); - return TakenAdvertisedBenefit > 0 ? TakenAdvertisedBenefit : 0; + return TakenAdvertisedBenefit; } bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const @@ -11116,16 +11099,16 @@ uint32 Unit::SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damag uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) { // For totems get healing bonus from owner (statue isn't totem in fact) - if (GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem()) + if (GetTypeId() == TYPEID_UNIT && isTotem()) if (Unit* owner = GetOwner()) return owner->SpellHealingBonusDone(victim, spellProto, healamount, damagetype, stack); - // no bonus for heal potions/bandages + // No bonus healing for potion spells if (spellProto->SpellFamilyName == SPELLFAMILY_POTION) return healamount; - float DoneTotalMod = 1.0f; - int32 DoneTotal = 0; + float DoneTotalMod = 1.0f; + int32 DoneTotal = 0; // Healing done percent AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT); @@ -11189,7 +11172,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui } // Done fixed damage bonus auras - int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask()); + int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask()); // Check for table values SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id); @@ -11202,16 +11185,22 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui coeff = bonus->dot_damage; if (bonus->ap_dot_bonus > 0) DoneTotal += int32(bonus->ap_dot_bonus * stack * GetTotalAttackPowerValue( - (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE)? RANGED_ATTACK : BASE_ATTACK)); + (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK)); } else { coeff = bonus->direct_damage; if (bonus->ap_bonus > 0) DoneTotal += int32(bonus->ap_bonus * stack * GetTotalAttackPowerValue( - (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE)? RANGED_ATTACK : BASE_ATTACK)); + (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK)); } } + else + { + // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default + if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) + return healamount; + } // Default calculation if (DoneAdvertisedBenefit) @@ -11228,23 +11217,21 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui coeff /= 100.0f; } - // Gift of the Naaru - if (spellProto->SpellFamilyFlags[2] & 0x80000000 && spellProto->SpellIconID == 329) - { - int32 apBonus = int32(std::max(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAttackPowerValue(RANGED_ATTACK))); - if (apBonus > DoneAdvertisedBenefit) - DoneTotal += int32(apBonus * 0.22f); // 22% of AP per tick - else - DoneTotal += int32(DoneAdvertisedBenefit * 0.377f); // 37.7% of BH per tick - } - else - { - // Earthliving - 0.45% of normal hot coeff - if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000) + // Earthliving - 0.45% of normal hot coeff + if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000) factorMod *= 0.45f; - DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod); - } + DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod); + } + + // Gift of the Naaru + if (spellProto->SpellFamilyFlags[2] & 0x80000000 && spellProto->SpellIconID == 329) + { + int32 apBonus = int32(std::max(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAttackPowerValue(RANGED_ATTACK))); + if (apBonus > DoneAdvertisedBenefit) + DoneTotal += int32(apBonus * 0.22f); // 22% of AP per tick + else + DoneTotal += int32(DoneAdvertisedBenefit * 0.377f); // 37.7% of BH per tick } for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) @@ -11258,11 +11245,11 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui break; } if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH) - DoneTotal = 0; + DoneTotal = 0; } // use float as more appropriate for negative values and percent applying - float heal = (int32(healamount) + DoneTotal) * DoneTotalMod; + float heal = float(int32(healamount) + DoneTotal) * DoneTotalMod; // apply spellmod to Done amount if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal); @@ -11270,16 +11257,16 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui return uint32(std::max(heal, 0.0f)); } -uint32 Unit::SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) +uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) { - float TakenTotalMod = 1.0f; + float TakenTotalMod = 1.0f; // Healing taken percent - float minval = (float)GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT); + float minval = float(GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT)); if (minval) AddPctF(TakenTotalMod, minval); - float maxval = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT); + float maxval = float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT)); if (maxval) AddPctF(TakenTotalMod, maxval); @@ -11288,7 +11275,7 @@ uint32 Unit::SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamou AddPctN(TakenTotalMod, Tenacity->GetAmount()); // Healing Done - int32 TakenTotal = 0; + int32 TakenTotal = 0; // Taken fixed damage bonus auras int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(spellProto->GetSchoolMask()); @@ -11305,11 +11292,11 @@ uint32 Unit::SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamou if (damagetype == DOT) { // Healing over time taken percent - float minval_hot = (float)GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT); + float minval_hot = float(GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT)); if (minval_hot) AddPctF(TakenTotalMod, minval_hot); - float maxval_hot = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT); + float maxval_hot = float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT)); if (maxval_hot) AddPctF(TakenTotalMod, maxval_hot); } @@ -11320,6 +11307,15 @@ uint32 Unit::SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamou float factorMod = 1.0f; if (bonus) coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage; + else + { + // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default + if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) + { + healamount = uint32(std::max((float(healamount) * TakenTotalMod), 0.0f)); + return healamount; + } + } // Default calculation if (TakenAdvertisedBenefit) @@ -11344,7 +11340,7 @@ uint32 Unit::SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamou AuraEffectList const& mHealingGet= GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_RECEIVED); for (AuraEffectList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i) - if (GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto)) + if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto)) AddPctN(TakenTotalMod, (*i)->GetAmount()); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) @@ -11358,10 +11354,10 @@ uint32 Unit::SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamou break; } if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH) - TakenTotal = 0; + TakenTotal = 0; } - float heal = (int32(healamount) + TakenTotal) * TakenTotalMod; + float heal = float(int32(healamount) + TakenTotal) * TakenTotalMod; return uint32(std::max(heal, 0.0f)); } @@ -11434,7 +11430,7 @@ bool Unit::IsImmunedToDamage(SpellInfo const* spellInfo) return false; uint32 shoolMask = spellInfo->GetSchoolMask(); - if (spellInfo->Id != 42292 && spellInfo->Id !=59752) + if (spellInfo->Id != 42292 && spellInfo->Id != 59752) { // If m_immuneToSchool type contain this school type, IMMUNE damage. SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; @@ -11475,7 +11471,7 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) } // Spells that don't have effectMechanics. - if (!spellInfo->HasAnyEffectMechanic() && spellInfo->Mechanic) + if (spellInfo->Mechanic) { SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) @@ -11488,16 +11484,17 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) { // State/effect immunities applied by aura expect full spell immunity // Ignore effects with mechanic, they are supposed to be checked separately - if (spellInfo->Effects[i].Mechanic || !IsImmunedToSpellEffect(spellInfo, i)) + if (!IsImmunedToSpellEffect(spellInfo, i)) { immuneToAllEffects = false; break; } } + if (immuneToAllEffects) //Return immune only if the target is immune to all spell effects. return true; - if (spellInfo->Id != 42292 && spellInfo->Id !=59752) + if (spellInfo->Id != 42292 && spellInfo->Id != 59752) { SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) @@ -11515,8 +11512,9 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const { - if (!spellInfo) + if (!spellInfo || !spellInfo->Effects[index].IsEffect()) return false; + // If m_immuneToEffect type contain this effect type, IMMUNE effect. uint32 effect = spellInfo->Effects[index].Effect; SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; @@ -11552,10 +11550,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto) { - if (!victim) - return 0; - - if (pdamage == 0) + if (!victim || pdamage == 0) return 0; uint32 creatureTypeMask = victim->GetCreatureTypeMask(); @@ -11612,23 +11607,24 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType // Done total percent damage auras float DoneTotalMod = 1.0f; - // ..done - AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) - { - if (spellProto) + // 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 ((*i)->GetMiscValue() & spellProto->GetSchoolMask() && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_NORMAL)) + AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) { - if ((*i)->GetSpellInfo()->EquippedItemClass == -1) - AddPctN(DoneTotalMod, (*i)->GetAmount()); - else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) - AddPctN(DoneTotalMod, (*i)->GetAmount()); - else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) - AddPctN(DoneTotalMod, (*i)->GetAmount()); + if ((*i)->GetMiscValue() & spellProto->GetSchoolMask() && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_NORMAL)) + { + if ((*i)->GetSpellInfo()->EquippedItemClass == -1) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + } } } - } AuraEffectList const& mDamageDoneVersus = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i) @@ -11727,7 +11723,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType return uint32(std::max(tmpDamage, 0.0f)); } -uint32 Unit::MeleeDamageBonusTaken(uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto) +uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto) { if (pdamage == 0) return 0; @@ -11751,15 +11747,15 @@ uint32 Unit::MeleeDamageBonusTaken(uint32 pdamage, WeaponAttackType attType, Spe // ..taken TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, GetMeleeDamageSchoolMask()); - // From caster spells - AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); - for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) - if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) - AddPctN(TakenTotalMod, (*i)->GetAmount()); - // .. taken pct (special attacks) if (spellProto) { + // From caster spells + AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); + for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) + if ((*i)->GetCasterGUID() == attacker->GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) + AddPctN(TakenTotalMod, (*i)->GetAmount()); + // Mod damage from spell mechanic uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask(); @@ -12160,7 +12156,7 @@ bool Unit::IsValidAttackTarget(Unit const* target) const } // function based on function Unit::CanAttack from 13850 client -bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) const +bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj) const { ASSERT(target); @@ -12178,8 +12174,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target)) return false; - // can't attack invisible (ignore stealth for aoe spells) - if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !canSeeOrDetect(target, bySpell && bySpell->IsAffectingArea())) + // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit. + if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->canSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !canSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))) return false; // can't attack dead @@ -12740,11 +12736,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) void Unit::setDeathState(DeathState s) { - // death state needs to be updated before RemoveAllAurasOnDeath() calls HandleChannelDeathItem(..) so that - // it can be used to check creation of death items (such as soul shards). - m_deathState = s; - - if (s != ALIVE && s != JUST_ALIVED) + if (s != ALIVE && s != JUST_RESPAWNED) { CombatStop(); DeleteThreatList(); @@ -12787,8 +12779,10 @@ void Unit::setDeathState(DeathState s) if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : (ZoneScript*)GetInstanceScript()) zoneScript->OnUnitDeath(this); } - else if (s == JUST_ALIVED) - RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) + else if (s == JUST_RESPAWNED) + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) + + m_deathState = s; } /*######################################## @@ -14402,7 +14396,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask); uint32 newDamage = SpellDamageBonusDone(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE); - newDamage = target->SpellDamageBonusTaken(spellInfo, newDamage, SPELL_DIRECT_DAMAGE); + newDamage = target->SpellDamageBonusTaken(this, spellInfo, newDamage, SPELL_DIRECT_DAMAGE); CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo); DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); SendSpellNonMeleeDamageLog(&damageInfo); @@ -16943,7 +16937,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) } if (IsInMap(caster)) - caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, true, NULL, NULL, origCasterGUID); + caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, false, NULL, NULL, origCasterGUID); else // This can happen during Player::_LoadAuras { int32 bp0 = seatId; @@ -16953,7 +16947,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) else { if (IsInMap(caster)) - caster->CastSpell(target, spellEntry, true, NULL, NULL, origCasterGUID); + caster->CastSpell(target, spellEntry, false, NULL, NULL, origCasterGUID); else Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID); } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index e7ea70dc290..f246f595dec 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -465,7 +465,7 @@ enum DeathState JUST_DIED = 1, CORPSE = 2, DEAD = 3, - JUST_ALIVED = 4, + JUST_RESPAWNED = 4, }; enum UnitState @@ -1573,7 +1573,7 @@ class Unit : public WorldObject bool isTargetableForAttack(bool checkFakeDeath = true) const; bool IsValidAttackTarget(Unit const* target) const; - bool _IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) const; + bool _IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj = NULL) const; bool IsValidAssistTarget(Unit const* target) const; bool _IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) const; @@ -2038,14 +2038,14 @@ class Unit : public WorldObject int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask); int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask); uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); - uint32 SpellDamageBonusTaken(SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask); int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask); uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1); - uint32 SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1); uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto = NULL); - uint32 MeleeDamageBonusTaken(uint32 pdamage,WeaponAttackType attType, SpellInfo const *spellProto = NULL); + uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage,WeaponAttackType attType, SpellInfo const *spellProto = NULL); bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK); |
