aboutsummaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
authormegamage <none@none>2008-12-26 16:27:41 -0600
committermegamage <none@none>2008-12-26 16:27:41 -0600
commit7346ed5951822d5b8f61817ff1ad95d2c4e2cd73 (patch)
tree3a6c59366f445379b9709df26afd05173eed1531 /src/game
parent8d79395783e6dfb59777ce5fcedf722a99580765 (diff)
parent07e2410ed830a620a0749e4039e0e544278267d7 (diff)
*Merge to Trinity 673.
--HG-- branch : trunk
Diffstat (limited to 'src/game')
-rw-r--r--src/game/Creature.cpp1
-rw-r--r--src/game/OutdoorPvP.cpp5
-rw-r--r--src/game/Pet.cpp21
-rw-r--r--src/game/SharedDefines.h4
-rw-r--r--src/game/Spell.cpp177
-rw-r--r--src/game/Spell.h7
-rw-r--r--src/game/SpellEffects.cpp103
-rw-r--r--src/game/SpellMgr.cpp40
-rw-r--r--src/game/SpellMgr.h33
-rw-r--r--src/game/StatSystem.cpp17
-rw-r--r--src/game/Unit.cpp6
-rw-r--r--src/game/WaypointMovementGenerator.cpp12
-rw-r--r--src/game/WaypointMovementGenerator.h2
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;