diff options
| author | megamage <none@none> | 2008-12-25 17:39:46 -0600 | 
|---|---|---|
| committer | megamage <none@none> | 2008-12-25 17:39:46 -0600 | 
| commit | 6e784a14fdd298216969f7726645d474bc5c4151 (patch) | |
| tree | cea423e29f4cebe1c0335f9c3c17cb2b31207696 | |
| parent | 59ed3f9d2fbb401dfc9b9d92ea948cb99ba961ea (diff) | |
*Calculate base spell damage/healing when casting but not hitting.
*Fix the bug that conflagrate consumes other players' immolate.
--HG--
branch : trunk
| -rw-r--r-- | src/game/Spell.cpp | 151 | ||||
| -rw-r--r-- | src/game/Spell.h | 7 | ||||
| -rw-r--r-- | src/game/SpellEffects.cpp | 97 | 
3 files changed, 160 insertions, 95 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index c4a73950381..b6fca5a0597 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -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)) @@ -721,7 +715,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) @@ -942,13 +936,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; @@ -963,8 +950,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; @@ -991,7 +978,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; @@ -1017,7 +1004,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); @@ -1170,8 +1157,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]; @@ -1180,7 +1168,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; -            } +            }*/          }      } @@ -1450,6 +1438,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; @@ -1462,6 +1451,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: @@ -2203,23 +2199,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) @@ -2250,13 +2229,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)) @@ -2398,17 +2374,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 @@ -3287,7 +3252,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; @@ -3296,14 +3261,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); @@ -5152,7 +5118,7 @@ Unit* Spell::SelectMagnetTarget()                      {                          if (targetGUID == ihit->targetGUID)                 // Found in list                          { -                            (*ihit).killTarget = true; +                            (*ihit).damage = target->GetHealth();                              break;                          }                      } @@ -5330,4 +5296,73 @@ 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) +            return; + +        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)) +        { +            damage = CalculateDamage(i, NULL) * m_damageMultipliers[i]; +            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; +            } +            if ( m_applyMultiplierMask & (1 << i) ) +                m_damageMultipliers[i] *= multiplier[i]; +        } +    } +    return m_damage;  }
\ No newline at end of file diff --git a/src/game/Spell.h b/src/game/Spell.h index 284e0b88fb1..17a103ad0c5 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -505,7 +505,7 @@ class Spell              SpellMissInfo reflectResult:8;              uint8  effectMask:8;              bool   processed:1; -            bool   killTarget:1; +            int32  damage;          };          std::list<TargetInfo> m_UniqueTargetInfo;          uint8 m_needAliveTargetMask;                        // Mask req. alive targets @@ -542,6 +542,11 @@ class Spell          void SearchChainTarget(std::list<Unit*> &data, Unit* pUnitTarget, float max_range, uint32 unMaxTargets);          bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;          bool IsValidSingleTargetSpell(Unit const* target) const; +        void CalculateDamageDoneForAllTargets(); +        int32 CalculateDamageDone(Unit *unit, const uint32 effectMask, float *multiplier); +        void SpellDamageSchoolDmg(uint32 i); +        void SpellDamageWeaponDmg(uint32 i); +        void SpellDamageHeal(uint32 i);          // -------------------------------------------          //List For Triggered Spells diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 04a93bfb77c..7b591306c89 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -302,6 +302,10 @@ void Spell::EffectEnvirinmentalDMG(uint32 i)  void Spell::EffectSchoolDMG(uint32 effect_idx)  { +} + +void Spell::SpellDamageSchoolDmg(uint32 effect_idx) +{      if( unitTarget && unitTarget->isAlive())      {          switch(m_spellInfo->SpellFamilyName) @@ -395,6 +399,22 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)                      if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE))                          damage += int32(damage*0.25);                  } + +                // Conflagrate - consumes immolate +                if (m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE) +                { +                    // for caster applied auras only +                    Unit::AuraList const &mPeriodic = unitTarget->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() ) +                        { +                            unitTarget->RemoveAurasDueToCasterSpell((*i)->GetId(), m_caster->GetGUID()); +                            break; +                        } +                    } +                }                  break;              }              case SPELLFAMILY_DRUID: @@ -532,6 +552,23 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)                  {                      int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),(int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE));                      damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2f); + +                    bool found = false; + +                    // check dazed affect +                    Unit::AuraList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); +                    for(Unit::AuraList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter) +                    { +                        if((*iter)->GetSpellProto()->SpellIconID==15 && (*iter)->GetSpellProto()->Dispel==0) +                        { +                            found = true; +                            break; +                        } +                    } + +                    //TODO: should this be put on taken but not done? +                    if(found) +                        m_damage += m_spellInfo->EffectBasePoints[1];                  }                  //Explosive Trap Effect                  else if(m_spellInfo->SpellFamilyFlags & 0x00000004) @@ -1258,7 +1295,7 @@ void Spell::EffectDummy(uint32 i)              //Life Tap (only it have this with dummy effect)              if (m_spellInfo->SpellFamilyFlags == 0x40000)              { -                float cost = m_currentBasePoints[0];//+1; +                float cost = damage;                  if(Player* modOwner = m_caster->GetSpellModOwner())                      modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost,this); @@ -1378,29 +1415,6 @@ void Spell::EffectDummy(uint32 i)              }              break;          case SPELLFAMILY_HUNTER: -            // Steady Shot -            if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) -            { -                if( !unitTarget || !unitTarget->isAlive()) -                    return; - -                bool found = false; - -                // check dazed affect -                Unit::AuraList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); -                for(Unit::AuraList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter) -                { -                    if((*iter)->GetSpellProto()->SpellIconID==15 && (*iter)->GetSpellProto()->Dispel==0) -                    { -                        found = true; -                        break; -                    } -                } - -                if(found) -                    m_damage+= damage; -                return; -            }              // Kill command              if(m_spellInfo->SpellFamilyFlags & 0x00080000000000LL)              { @@ -2077,7 +2091,7 @@ void Spell::EffectApplyAura(uint32 i)      sLog.outDebug("Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[i]); -    Aura* Aur = CreateAura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget, caster, m_CastItem); +    Aura* Aur = CreateAura(m_spellInfo, i, &damage, unitTarget, caster, m_CastItem);      // Now Reduce spell duration using data received at spell hit      int32 duration = Aur->GetAuraMaxDuration(); @@ -2127,7 +2141,7 @@ void Spell::EffectApplyAura(uint32 i)          if (AdditionalSpellInfo)          {              // applied at target by target -            Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, &m_currentBasePoints[0], unitTarget,unitTarget, 0); +            Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, NULL, unitTarget,unitTarget, 0);              unitTarget->AddAura(AdditionalAura);              sLog.outDebug("Spell: Additional Aura is: %u", AdditionalSpellInfo->EffectApplyAuraName[0]);          } @@ -2294,11 +2308,17 @@ void Spell::EffectPowerBurn(uint32 i)          modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);      new_damage = int32(new_damage*multiplier); -    m_damage+=new_damage; +    //m_damage+=new_damage; should not apply spell bonus +    //TODO: no log +    unitTarget->ModifyHealth(-new_damage);  }  void Spell::EffectHeal( uint32 /*i*/ )  { +} + +void Spell::SpellDamageHeal(uint32 /*i*/) +{      if( unitTarget && unitTarget->isAlive() && damage >= 0)      {          // Try to get original caster @@ -2369,7 +2389,7 @@ void Spell::EffectHeal( uint32 /*i*/ )          else              addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget); -        m_healing+=addhealth; +        m_damage -= addhealth;      }  } @@ -2470,7 +2490,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)      // TODO: maybe all this can be replaced by using correct calculated `damage` value      if(pProto->Class != ITEM_CLASS_CONSUMABLE || m_spellInfo->SpellFamilyName != SPELLFAMILY_MAGE)      { -        num_to_add = m_currentBasePoints[i]; +        num_to_add = damage;          /*int32 basePoints = m_currentBasePoints[i];          int32 randomPoints = m_spellInfo->EffectDieSides[i];          if (randomPoints) @@ -2482,7 +2502,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)          num_to_add = 1;      else if(player->getLevel() >= m_spellInfo->spellLevel)      { -        num_to_add = m_currentBasePoints[i]; +        num_to_add = damage;          /*int32 basePoints = m_currentBasePoints[i];          float pointPerLevel = m_spellInfo->EffectRealPointsPerLevel[i];          num_to_add = basePoints + 1 + uint32((player->getLevel() - m_spellInfo->spellLevel)*pointPerLevel);*/ @@ -3076,7 +3096,7 @@ void Spell::EffectApplyAreaAura(uint32 i)      if(!unitTarget->isAlive())          return; -    AreaAura* Aur = new AreaAura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget, m_caster, m_CastItem); +    AreaAura* Aur = new AreaAura(m_spellInfo, i, &damage, unitTarget, m_caster, m_CastItem);      unitTarget->AddAura(Aur);  } @@ -4179,6 +4199,10 @@ void Spell::EffectTaunt(uint32 /*i*/)  void Spell::EffectWeaponDmg(uint32 i)  { +} + +void Spell::SpellDamageWeaponDmg(uint32 i) +{      if(!unitTarget)          return;      if(!unitTarget->isAlive()) @@ -4464,9 +4488,10 @@ void Spell::EffectHealMaxHealth(uint32 /*i*/)      if(!unitTarget->isAlive())          return; -    uint32 heal = m_caster->GetMaxHealth(); - -    m_healing+=heal; +    uint32 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth(); +    unitTarget->SetHealth(unitTarget->GetMaxHealth()); +    if(m_originalCaster) +        m_originalCaster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);  }  void Spell::EffectInterruptCast(uint32 i) @@ -5306,7 +5331,7 @@ void Spell::EffectEnchantHeldItem(uint32 i)          uint32 enchant_id = m_spellInfo->EffectMiscValue[i];          int32 duration = GetSpellDuration(m_spellInfo);          //Try duration index first ..          if(!duration) -            duration = m_currentBasePoints[i];//+1;            //Base points after .. +            duration = damage;//+1;            //Base points after ..          if(!duration)              duration = 10;                                  //10 seconds for enchants which don't have listed duration @@ -5612,7 +5637,7 @@ void Spell::EffectReputation(uint32 i)      Player *_player = (Player*)unitTarget; -    int32  rep_change = m_currentBasePoints[i];//+1;           // field store reputation change -1 +    int32  rep_change = damage;//+1;           // field store reputation change -1      uint32 faction_id = m_spellInfo->EffectMiscValue[i];  | 
