diff options
| author | megamage <none@none> | 2008-12-26 16:27:41 -0600 |
|---|---|---|
| committer | megamage <none@none> | 2008-12-26 16:27:41 -0600 |
| commit | 7346ed5951822d5b8f61817ff1ad95d2c4e2cd73 (patch) | |
| tree | 3a6c59366f445379b9709df26afd05173eed1531 /src/game | |
| parent | 8d79395783e6dfb59777ce5fcedf722a99580765 (diff) | |
| parent | 07e2410ed830a620a0749e4039e0e544278267d7 (diff) | |
*Merge to Trinity 673.
--HG--
branch : trunk
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/Creature.cpp | 1 | ||||
| -rw-r--r-- | src/game/OutdoorPvP.cpp | 5 | ||||
| -rw-r--r-- | src/game/Pet.cpp | 21 | ||||
| -rw-r--r-- | src/game/SharedDefines.h | 4 | ||||
| -rw-r--r-- | src/game/Spell.cpp | 177 | ||||
| -rw-r--r-- | src/game/Spell.h | 7 | ||||
| -rw-r--r-- | src/game/SpellEffects.cpp | 103 | ||||
| -rw-r--r-- | src/game/SpellMgr.cpp | 40 | ||||
| -rw-r--r-- | src/game/SpellMgr.h | 33 | ||||
| -rw-r--r-- | src/game/StatSystem.cpp | 17 | ||||
| -rw-r--r-- | src/game/Unit.cpp | 6 | ||||
| -rw-r--r-- | src/game/WaypointMovementGenerator.cpp | 12 | ||||
| -rw-r--r-- | src/game/WaypointMovementGenerator.h | 2 |
13 files changed, 282 insertions, 146 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index e4d4eec9ef5..5c5ccef3897 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1514,7 +1514,6 @@ void Creature::DeleteFromDB() WorldDatabase.BeginTransaction(); WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid); WorldDatabase.PExecuteLog("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid); - WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id = '%u'", m_DBTableGuid); WorldDatabase.PExecuteLog("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid); WorldDatabase.PExecuteLog("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid); WorldDatabase.CommitTransaction(); diff --git a/src/game/OutdoorPvP.cpp b/src/game/OutdoorPvP.cpp index f2310aa4e0c..06d56897f1e 100644 --- a/src/game/OutdoorPvP.cpp +++ b/src/game/OutdoorPvP.cpp @@ -446,8 +446,11 @@ void OutdoorPvPObjective::UpdateActivePlayerProximityCheck() { for(int team = 0; team < 2; ++team) { - for(std::set<uint64>::iterator itr = m_ActivePlayerGuids[team].begin(); itr != m_ActivePlayerGuids[team].end(); ++ itr) + std::set<uint64>::iterator itr, next; + for(itr = m_ActivePlayerGuids[team].begin(); itr != m_ActivePlayerGuids[team].end(); itr = next) { + next = itr; + ++next; // if the player is online if(Player * pl = objmgr.GetPlayer(*itr)) { diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index d56ae59158e..5df1726f4f4 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -957,6 +957,25 @@ bool Pet::InitStatsForLevel(uint32 petlevel) SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000); + switch(GetEntry()) + { + case 1964: //force of nature + SetCreateHealth(30 + 30*petlevel); + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2))); + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2))); + break; + case 15352: //earth elemental 36213 + SetCreateHealth(100 + 120*petlevel); + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); + break; + case 15438: //fire elemental + SetCreateHealth(40*petlevel); + SetCreateMana(28 + 10*petlevel); + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel)); + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel)); + break; + default: SetCreateMana(28 + 10*petlevel); SetCreateHealth(28 + 30*petlevel); @@ -966,6 +985,8 @@ bool Pet::InitStatsForLevel(uint32 petlevel) SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); //damage range is then petlevel / 2 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); + break; + } break; default: sLog.outError("Pet have incorrect type (%u) for levelup.", getPetType()); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index efd3f0100f8..b8a0f135ab7 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -833,7 +833,7 @@ enum Targets TARGET_GAMEOBJECT = 23, //TARGET_OBJECT_OPEN TARGET_IN_FRONT_OF_CASTER = 24, - //TARGET_UNIT_CONE_ENEMY + TARGET_UNIT_CONE_ENEMY = 24, TARGET_DUELVSPLAYER = 25, TARGET_UNIT_TARGET_ANY = 25, TARGET_GAMEOBJECT_ITEM = 26, @@ -886,7 +886,7 @@ enum Targets TARGET_UNIT_CONE_ALLY = 59, TARGET_UNIT_AREA_SCRIPT = 60, TARGET_AREAEFFECT_PARTY_AND_CLASS = 61, - //TARGET_UNIT_CLASS_TARGET + TARGET_UNIT_CLASS_TARGET = 61, TARGET_TEST = 62, // for a test spell TARGET_DUELVSPLAYER_COORDINATES = 63, TARGET_DEST_TARGET_ENEMY_UNKNOWN = 63, diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 576deea558e..f1466566ff1 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)) @@ -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; }
\ No newline at end of file diff --git a/src/game/Spell.h b/src/game/Spell.h index 3d8dffef86b..588d5cf01a8 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -538,7 +538,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 @@ -575,6 +575,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 9758529f56d..7ae64d2129f 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -308,6 +308,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) @@ -414,6 +418,22 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE)) damage += int32(damage*0.25f); } + + // 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: @@ -574,6 +594,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) + damage += m_spellInfo->EffectBasePoints[1]; } // Explosive Trap Effect else if(m_spellInfo->SpellFamilyFlags & 0x00000004) @@ -1338,7 +1375,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); @@ -1458,29 +1495,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) { @@ -2155,7 +2169,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(); @@ -2205,7 +2219,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]); } @@ -2372,11 +2386,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 @@ -2447,7 +2467,7 @@ void Spell::EffectHeal( uint32 /*i*/ ) else addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget); - m_healing+=addhealth; + m_damage -= addhealth; } } @@ -2548,7 +2568,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) @@ -2560,7 +2580,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);*/ @@ -2974,7 +2994,7 @@ void Spell::EffectOpenLock(uint32 /*i*/) SkillId = SKILL_LOCKPICKING; // skill bonus provided by casting spell (mostly item spells) - uint32 spellSkillBonus = uint32(m_currentBasePoints[0]/*+1*/); + uint32 spellSkillBonus = uint32(damage/*m_currentBasePoints[0]+1*/); uint32 reqSkillValue = lockInfo->Skill[0]; @@ -3154,7 +3174,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); } @@ -4258,6 +4278,10 @@ void Spell::EffectTaunt(uint32 /*i*/) void Spell::EffectWeaponDmg(uint32 i) { +} + +void Spell::SpellDamageWeaponDmg(uint32 i) +{ if(!unitTarget) return; if(!unitTarget->isAlive()) @@ -4543,9 +4567,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) @@ -5199,8 +5224,8 @@ void Spell::EffectDuel(uint32 i) // Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities) // Don't have to check the target's map since you cannot challenge someone across maps - uint32 mapid = caster->GetMapId(); - if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609) + if(caster->GetMap()->Instanceable()) + //if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609) { SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here return; @@ -5485,7 +5510,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 @@ -5787,7 +5812,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]; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 89cc4105bc6..641a08f9e60 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -73,6 +73,14 @@ SpellMgr::SpellMgr() case SPELL_EFFECT_PROSPECTING: EffectTargetType[i] = SPELL_REQUIRE_ITEM; break; + //caster must be pushed otherwise no sound + case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: + case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: + case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: + case SPELL_EFFECT_APPLY_AREA_AURA_PET: + case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: + EffectTargetType[i] = SPELL_REQUIRE_CASTER; + break; default: EffectTargetType[i] = SPELL_REQUIRE_UNIT; break; @@ -113,7 +121,8 @@ SpellMgr::SpellMgr() case TARGET_UNIT_AREA_ENTRY: case TARGET_UNIT_AREA_PARTY_GROUND: case TARGET_UNIT_AREA_PARTY: - case TARGET_UNIT_AREA_ENEMY_CHANNEL: + //case TARGET_UNIT_AREA_ENEMY_CHANNEL: + //case TARGET_UNIT_AREA_ALLY_CHANNEL: SpellTargetType[i] = TARGET_TYPE_AREA_DEST; break; case TARGET_DEST_TARGET_ENEMY: @@ -151,6 +160,35 @@ SpellMgr::SpellMgr() SpellTargetType[i] = TARGET_TYPE_DEFAULT; } } + + for(int i = 0; i < TOTAL_SPELL_TARGETS; ++i) + { + switch(i) + { + case TARGET_UNIT_AREA_ENEMY_GROUND: + case TARGET_UNIT_AREA_ENEMY: + case TARGET_UNIT_AREA_ALLY_GROUND: + case TARGET_UNIT_AREA_ALLY: + case TARGET_UNIT_AREA_ENTRY_GROUND: + case TARGET_UNIT_AREA_ENTRY: + case TARGET_UNIT_AREA_PARTY_GROUND: + case TARGET_UNIT_AREA_PARTY: + //Check persistant aura seperately + //case TARGET_UNIT_AREA_ENEMY_CHANNEL: + //case TARGET_UNIT_AREA_ALLY_CHANNEL: + case TARGET_UNIT_PARTY_TARGET: + case TARGET_UNIT_PARTY_CASTER: + case TARGET_UNIT_CONE_ENEMY: + case TARGET_UNIT_CONE_ALLY: + case TARGET_UNIT_CONE_ENEMY_UNKNOWN: + case TARGET_UNIT_RAID: + IsAreaEffectTarget[i] = true; + break; + default: + IsAreaEffectTarget[i] = false; + break; + } + } } SpellMgr::~SpellMgr() diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index b085a90158f..5322f3fa16d 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -259,6 +259,7 @@ enum SpellEffectTargetTypes SPELL_REQUIRE_UNIT, SPELL_REQUIRE_DEST, SPELL_REQUIRE_ITEM, + SPELL_REQUIRE_CASTER, }; enum SpellSelectTargetTypes @@ -379,38 +380,14 @@ bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId); bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id); -inline bool IsAreaEffectTarget( Targets target ) -{ - switch (target ) - { - case TARGET_AREAEFFECT_CUSTOM: - case TARGET_ALL_ENEMY_IN_AREA: - case TARGET_ALL_ENEMY_IN_AREA_INSTANT: - case TARGET_ALL_PARTY_AROUND_CASTER: - case TARGET_ALL_AROUND_CASTER: - case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: - case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: - case TARGET_ALL_PARTY: - case TARGET_ALL_PARTY_AROUND_CASTER_2: - case TARGET_AREAEFFECT_PARTY: - case TARGET_AREAEFFECT_CUSTOM_2: - case TARGET_AREAEFFECT_PARTY_AND_CLASS: - case TARGET_IN_FRONT_OF_CASTER: - case TARGET_ALL_FRIENDLY_UNITS_IN_AREA: - return true; - default: - break; - } - return false; -} - +static bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS]; inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo) { - if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[0])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[0]))) + if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[0]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[0]]) return true; - if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[1])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[1]))) + if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[1]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[1]]) return true; - if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[2])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[2]))) + if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[2]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[2]]) return true; return false; } diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index df666d4c71e..43faf9b3654 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -982,6 +982,23 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged) frost = 0; SetBonusDamage( int32(frost * 0.4f)); } + //force of nature + else if(GetEntry() == 1964) + { + int32 spellDmg = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE); + if(spellDmg > 0) + SetBonusDamage(int32(spellDmg * 0.09f)); + } + //greater fire elemental + else if(GetEntry() == 15438) + { + if(Unit* shaman = owner->GetOwner()) + { + int32 spellDmg = int32(shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); + if(spellDmg > 0) + SetBonusDamage(int32(spellDmg * 0.4f)); + } + } } SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 80d6ea39227..d5765b2bcf0 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2997,7 +2997,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack } } - if(GetTypeId()!=TYPEID_PLAYER && !(((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH) && !((Creature*)this)->isPet() ) + if(GetTypeId()!=TYPEID_PLAYER && !(((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH) && !((Creature*)this)->isPet() && !SpellCasted /*Only autoattack can be crushing blow*/ ) { // mobs can score crushing blows if they're 3 or more levels above victim // or when their weapon skill is 15 or more above victim's defense skill @@ -8695,8 +8695,10 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 TakenTotalMod *= (mod+100.0f)/100.0f; } break; + //This is changed in WLK, using aura 255 //Mangle case 2312: + case 44955: for(int j=0;j<3;j++) { if(GetEffectMechanic(spellProto, j)==MECHANIC_BLEED) @@ -12352,7 +12354,7 @@ uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectT break; } - if(IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetA[i])) || IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetB[i]))) + if(IsAreaEffectTarget[spellProto->EffectImplicitTargetA[i]] || IsAreaEffectTarget[spellProto->EffectImplicitTargetB[i]]) AreaEffect = true; } diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 85ef44b51be..67c56d763bc 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -36,11 +36,17 @@ void WaypointMovementGenerator<Creature>::Initialize(Creature &u) { u.StopMoving(); - i_nextMoveTime.Reset(0); - i_currentNode = -1; if(!path_id) path_id = u.GetWaypointPath(); - waypoints = WaypointMgr.GetPath(path_id); + waypoints = WaypointMgr.GetPath(path_id); + if(waypoints && waypoints->size()) + { + Traveller<Creature> traveller(unit); + node = *(waypoints->at(i_currentNode)); + InitTraveller(u,node); + i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); + i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); + } } template<> diff --git a/src/game/WaypointMovementGenerator.h b/src/game/WaypointMovementGenerator.h index 5e01984d42c..99d111063de 100644 --- a/src/game/WaypointMovementGenerator.h +++ b/src/game/WaypointMovementGenerator.h @@ -81,7 +81,7 @@ class TRINITY_DLL_SPEC WaypointMovementGenerator private: WaypointData node; - uint32 i_currentNode, path_id; + uint32 path_id; TimeTrackerSmall i_nextMoveTime; WaypointPath *waypoints; bool repeating, StopedByPlayer; |
