mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-21 07:22:02 -04:00
*Merge to Trinity 673.
--HG-- branch : trunk
This commit is contained in:
+110
-67
@@ -174,14 +174,8 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
|
||||
*data >> m_targetMask;
|
||||
|
||||
if(m_targetMask == TARGET_FLAG_SELF)
|
||||
{
|
||||
//m_destX = caster->GetPositionX();
|
||||
//m_destY = caster->GetPositionY();
|
||||
//m_destZ = caster->GetPositionZ();
|
||||
//m_unitTarget = caster;
|
||||
//m_unitTargetGUID = caster->GetGUID();
|
||||
return true;
|
||||
}
|
||||
|
||||
// TARGET_FLAG_UNK2 is used for non-combat pets, maybe other?
|
||||
if( m_targetMask & (TARGET_FLAG_UNIT|TARGET_FLAG_UNK2) )
|
||||
if(!readGUID(*data, m_unitTargetGUID))
|
||||
@@ -411,10 +405,11 @@ void Spell::FillTargetMap()
|
||||
if(!m_spellInfo->Effect[i])
|
||||
continue;
|
||||
|
||||
// TODO: find a way so this is not needed?
|
||||
// for area auras always add caster as target (needed for totems for example)
|
||||
if(IsAreaAuraEffect(m_spellInfo->Effect[i]))
|
||||
AddUnitTarget(m_caster, i);
|
||||
uint32 effectTargetType = spellmgr.EffectTargetType[m_spellInfo->Effect[i]];
|
||||
|
||||
// is it possible that areaaura is not applied to caster?
|
||||
if(effectTargetType == SPELL_REQUIRE_NONE)
|
||||
continue;
|
||||
|
||||
std::list<Unit*> tmpUnitMap;
|
||||
uint32 targetA = m_spellInfo->EffectImplicitTargetA[i];
|
||||
@@ -425,9 +420,11 @@ void Spell::FillTargetMap()
|
||||
if(targetB) // In very rare case !A && B
|
||||
SetTargetMap(i, targetB, tmpUnitMap);
|
||||
|
||||
if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] != SPELL_REQUIRE_UNIT)
|
||||
if(effectTargetType != SPELL_REQUIRE_UNIT)
|
||||
{
|
||||
if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_DEST)
|
||||
if(effectTargetType == SPELL_REQUIRE_CASTER)
|
||||
AddUnitTarget(m_caster, i);
|
||||
if(effectTargetType == SPELL_REQUIRE_DEST)
|
||||
{
|
||||
if(m_targets.HasDest() && m_spellInfo->speed > 0.0f)
|
||||
{
|
||||
@@ -436,7 +433,7 @@ void Spell::FillTargetMap()
|
||||
m_delayMoment = (uint64) floor(dist / m_spellInfo->speed * 1000.0f);
|
||||
}
|
||||
}
|
||||
else if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_ITEM)
|
||||
else if(effectTargetType == SPELL_REQUIRE_ITEM)
|
||||
{
|
||||
if(m_targets.getItemTarget())
|
||||
AddItemTarget(m_targets.getItemTarget(), i);
|
||||
@@ -726,7 +723,7 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
|
||||
target.targetGUID = targetGUID; // Store target GUID
|
||||
target.effectMask = 1<<effIndex; // Store index of effect
|
||||
target.processed = false; // Effects not apply on target
|
||||
target.killTarget = false;
|
||||
target.damage = 0;
|
||||
|
||||
// Calculate hit result
|
||||
if(m_originalCaster)
|
||||
@@ -947,13 +944,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||
if (!unit)
|
||||
return;
|
||||
|
||||
if(target->killTarget)
|
||||
{
|
||||
// remove spell_magnet aura after first spell redirect and destroy target if its totem
|
||||
if(unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->isTotem())
|
||||
unit->Kill(unit);
|
||||
}
|
||||
|
||||
// Get original caster (if exist) and calculate damage/healing from him data
|
||||
Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
|
||||
|
||||
@@ -968,8 +958,8 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||
unitTarget = unit;
|
||||
|
||||
// Reset damage/healing counter
|
||||
m_damage = 0;
|
||||
m_healing = 0;
|
||||
m_damage = target->damage;
|
||||
m_healing = -target->damage;
|
||||
|
||||
// Fill base trigger info
|
||||
uint32 procAttacker = m_procAttacker;
|
||||
@@ -996,7 +986,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||
|
||||
// All calculated do it!
|
||||
// Do healing and triggers
|
||||
if (m_healing)
|
||||
if (m_healing > 0)
|
||||
{
|
||||
bool crit = caster->isSpellCrit(NULL, m_spellInfo, m_spellSchoolMask);
|
||||
uint32 addhealth = m_healing;
|
||||
@@ -1022,7 +1012,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||
bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain);
|
||||
}
|
||||
// Do damage and triggers
|
||||
else if (m_damage)
|
||||
else if (m_damage > 0)
|
||||
{
|
||||
// Fill base damage struct (unitTarget - is real spell target)
|
||||
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
|
||||
@@ -1186,8 +1176,9 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
||||
{
|
||||
if (effectMask & (1<<effectNumber))
|
||||
{
|
||||
HandleEffects(unit,NULL,NULL,effectNumber,m_damageMultipliers[effectNumber]);
|
||||
if ( m_applyMultiplierMask & (1 << effectNumber) )
|
||||
HandleEffects(unit,NULL,NULL,effectNumber/*,m_damageMultipliers[effectNumber]*/);
|
||||
//Only damage and heal spells need this
|
||||
/*if ( m_applyMultiplierMask & (1 << effectNumber) )
|
||||
{
|
||||
// Get multiplier
|
||||
float multiplier = m_spellInfo->DmgMultiplier[effectNumber];
|
||||
@@ -1196,7 +1187,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
||||
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier,this);
|
||||
m_damageMultipliers[effectNumber] *= multiplier;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1476,6 +1467,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
||||
else
|
||||
radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
|
||||
|
||||
//Chain: 2, 6, 22, 25, 45, 77
|
||||
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i];
|
||||
uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
|
||||
|
||||
@@ -1488,6 +1480,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
||||
}
|
||||
}
|
||||
|
||||
if(EffectChainTarget > 1)
|
||||
{
|
||||
//otherwise, this multiplier is used for something else
|
||||
m_damageMultipliers[i] = 1.0f;
|
||||
m_applyMultiplierMask |= 1 << i;
|
||||
}
|
||||
|
||||
switch(spellmgr.SpellTargetType[cur])
|
||||
{
|
||||
case TARGET_TYPE_UNIT_CASTER:
|
||||
@@ -1595,7 +1594,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
||||
switch(cur)
|
||||
{
|
||||
case TARGET_UNIT_AREA_ENEMY_GROUND:
|
||||
case TARGET_UNIT_AREA_ENEMY_CHANNEL:
|
||||
m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
|
||||
case TARGET_UNIT_AREA_ENEMY:
|
||||
SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
|
||||
@@ -2229,23 +2227,6 @@ void Spell::cast(bool skipCheck)
|
||||
|
||||
FillTargetMap();
|
||||
|
||||
// who did this hack?
|
||||
// Conflagrate - consumes immolate
|
||||
if ((m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE) && m_targets.getUnitTarget())
|
||||
{
|
||||
// for caster applied auras only
|
||||
Unit::AuraList const &mPeriodic = m_targets.getUnitTarget()->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
|
||||
{
|
||||
if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4) &&
|
||||
(*i)->GetCasterGUID()==m_caster->GetGUID() )
|
||||
{
|
||||
m_targets.getUnitTarget()->RemoveAura((*i)->GetId(), (*i)->GetEffIndex());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id))
|
||||
{
|
||||
for(std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
|
||||
@@ -2284,13 +2265,10 @@ void Spell::cast(bool skipCheck)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SendCastResult(castResult);
|
||||
SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
|
||||
|
||||
for(int i = 0; i < 3; ++i)
|
||||
m_currentBasePoints[i] = CalculateDamage(i, NULL);
|
||||
CalculateDamageDoneForAllTargets();
|
||||
|
||||
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
|
||||
if (m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo))
|
||||
@@ -2432,17 +2410,6 @@ void Spell::_handle_immediate_phase()
|
||||
// Don't do spell log, if is school damage spell
|
||||
if(m_spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || m_spellInfo->Effect[j] == 0)
|
||||
m_needSpellLog = false;
|
||||
|
||||
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[j];
|
||||
if(m_originalCaster)
|
||||
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this);
|
||||
|
||||
// initialize multipliers
|
||||
m_damageMultipliers[j] = 1.0f;
|
||||
if( (m_spellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_HEAL) &&
|
||||
(EffectChainTarget > 1) )
|
||||
m_applyMultiplierMask |= 1 << j;
|
||||
}
|
||||
|
||||
// initialize Diminishing Returns Data
|
||||
@@ -3500,7 +3467,7 @@ void Spell::HandleThreatSpells(uint32 spellId)
|
||||
DEBUG_LOG("Spell %u, rank %u, added an additional %i threat", spellId, spellmgr.GetSpellRank(spellId), threatSpell->threat);
|
||||
}
|
||||
|
||||
void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i, float DamageMultiplier)
|
||||
void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i, float /*DamageMultiplier*/)
|
||||
{
|
||||
unitTarget = pUnitTarget;
|
||||
itemTarget = pItemTarget;
|
||||
@@ -3509,14 +3476,15 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar
|
||||
uint8 eff = m_spellInfo->Effect[i];
|
||||
uint32 mechanic = m_spellInfo->EffectMechanic[i];
|
||||
|
||||
damage = int32(m_currentBasePoints[i] * DamageMultiplier);
|
||||
|
||||
sLog.outDebug( "Spell: Effect : %u", eff);
|
||||
|
||||
//Simply return. Do not display "immune" in red text on client
|
||||
if(unitTarget && unitTarget->IsImmunedToSpellEffect(eff, mechanic))
|
||||
return;
|
||||
|
||||
//we do not need DamageMultiplier here.
|
||||
damage = CalculateDamage(i, NULL);
|
||||
|
||||
if(eff<TOTAL_SPELL_EFFECTS)
|
||||
{
|
||||
//sLog.outDebug( "WORLD: Spell FX %d < TOTAL_SPELL_EFFECTS ", eff);
|
||||
@@ -4138,7 +4106,8 @@ uint8 Spell::CanCast(bool strict)
|
||||
SkillValue = 0;
|
||||
|
||||
// add the damage modifier from the spell casted (cheat lock / skeleton key etc.) (use m_currentBasePoints, CalculateDamage returns wrong value)
|
||||
SkillValue += m_currentBasePoints[i]/*+1*/;
|
||||
// TODO: is this a hack?
|
||||
SkillValue += m_currentBasePoints[i]+1;
|
||||
|
||||
// get the required lock value
|
||||
int32 ReqValue=0;
|
||||
@@ -5395,7 +5364,7 @@ Unit* Spell::SelectMagnetTarget()
|
||||
{
|
||||
if (targetGUID == ihit->targetGUID) // Found in list
|
||||
{
|
||||
(*ihit).killTarget = true;
|
||||
(*ihit).damage = target->GetHealth();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -5573,4 +5542,78 @@ bool Spell::IsValidSingleTargetSpell(Unit const* target) const
|
||||
// return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Spell::CalculateDamageDoneForAllTargets()
|
||||
{
|
||||
float multiplier[3];
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
if ( m_applyMultiplierMask & (1 << i) )
|
||||
{
|
||||
// Get multiplier
|
||||
multiplier[i] = m_spellInfo->DmgMultiplier[i];
|
||||
// Apply multiplier mods
|
||||
if(m_originalCaster)
|
||||
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier[i], this);
|
||||
}
|
||||
}
|
||||
|
||||
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
{
|
||||
TargetInfo &target = *ihit;
|
||||
|
||||
uint32 mask = target.effectMask;
|
||||
if(!mask)
|
||||
continue;
|
||||
|
||||
Unit* unit = m_caster->GetGUID()==target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
|
||||
if (!unit)
|
||||
continue;
|
||||
|
||||
if (target.missCondition==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
|
||||
target.damage += CalculateDamageDone(unit, mask, multiplier);
|
||||
else if (target.missCondition == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
|
||||
{
|
||||
if (target.reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
|
||||
target.damage += CalculateDamageDone(m_caster, mask, multiplier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 Spell::CalculateDamageDone(Unit *unit, const uint32 effectMask, float *multiplier)
|
||||
{
|
||||
m_damage = 0;
|
||||
unitTarget = unit;
|
||||
for(uint32 i = 0; i < 3; ++i)
|
||||
{
|
||||
if (effectMask & (1<<i))
|
||||
{
|
||||
if(m_applyMultiplierMask & (1 << i))
|
||||
{
|
||||
damage = CalculateDamage(i, NULL) * m_damageMultipliers[i];
|
||||
m_damageMultipliers[i] *= multiplier[i];
|
||||
}
|
||||
else
|
||||
damage = CalculateDamage(i, NULL);
|
||||
|
||||
switch(m_spellInfo->Effect[i])
|
||||
{
|
||||
case SPELL_EFFECT_SCHOOL_DAMAGE:
|
||||
SpellDamageSchoolDmg(i);
|
||||
break;
|
||||
case SPELL_EFFECT_WEAPON_DAMAGE:
|
||||
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
|
||||
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
|
||||
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
|
||||
SpellDamageWeaponDmg(i);
|
||||
break;
|
||||
case SPELL_EFFECT_HEAL:
|
||||
SpellDamageHeal(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_damage;
|
||||
}
|
||||
Reference in New Issue
Block a user