aboutsummaryrefslogtreecommitdiff
path: root/src/game/Spell.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Spell.cpp')
-rw-r--r--src/game/Spell.cpp348
1 files changed, 172 insertions, 176 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 15b4ae78d5e..b216bc10389 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1453,48 +1453,142 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
}
}
- switch(cur)
+ switch(spellmgr.SpellTargetType[cur])
{
- // specific unit
- case TARGET_SELF:
- case TARGET_SELF_FISHING:
+ case TARGET_TYPE_UNIT_CASTER:
{
- TagUnitMap.push_back(m_caster);
- }break;
- case TARGET_MASTER:
- {
- if(Unit* owner = m_caster->GetCharmerOrOwner())
- TagUnitMap.push_back(owner);
- }break;
- case TARGET_PET:
- {
- if(Pet* tmpUnit = m_caster->GetPet())
- TagUnitMap.push_back(tmpUnit);
+ switch(cur)
+ {
+ case TARGET_UNIT_CASTER:
+ case TARGET_UNIT_CASTER_FISHING:
+ TagUnitMap.push_back(m_caster);
+ break;
+ case TARGET_UNIT_MASTER:
+ if(Unit* owner = m_caster->GetCharmerOrOwner())
+ TagUnitMap.push_back(owner);
+ break;
+ case TARGET_UNIT_PET:
+ if(Pet* tmpUnit = m_caster->GetPet())
+ TagUnitMap.push_back(tmpUnit);
+ break;
+ }
}break;
- case TARGET_NONCOMBAT_PET:
+
+ case TARGET_TYPE_UNIT_TARGET:
{
- if(Unit* target = m_targets.getUnitTarget())
- if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET)
- TagUnitMap.push_back(target);
+ Unit *target = m_targets.getUnitTarget();
+ if(!target)
+ {
+ sLog.outError("SPELL: no unit target for spell ID %u\n", m_spellInfo->Id);
+ break;
+ }
+
+ switch(cur)
+ {
+ case TARGET_UNIT_MINIPET:
+ if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET)
+ TagUnitMap.push_back(target);
+ break;
+ case TARGET_UNIT_TARGET_ALLY:
+ case TARGET_UNIT_TARGET_RAID:
+ case TARGET_UNIT_TARGET_ANY: // SelectMagnetTarget()?
+ case TARGET_UNIT_SINGLE_UNKNOWN:
+ TagUnitMap.push_back(m_targets.getUnitTarget());
+ break;
+ case TARGET_UNIT_TARGET_ENEMY:
+ if(Unit* pUnitTarget = SelectMagnetTarget())
+ {
+ if(EffectChainTarget <= 1)
+ TagUnitMap.push_back(pUnitTarget);
+ else //TODO: chain target should also use magnet target
+ SearchChainTarget(TagUnitMap, pUnitTarget, radius, EffectChainTarget);
+ }
+ break;
+ }
}break;
- case TARGET_SINGLE_FRIEND: // ally
- case TARGET_SINGLE_FRIEND_2: // raid member
- case TARGET_DUELVSPLAYER: // all (SelectMagnetTarget()?)
- case TARGET_UNIT_SINGLE_UNKNOWN:
+
+ case TARGET_TYPE_CHANNEL:
{
- if(m_targets.getUnitTarget())
- TagUnitMap.push_back(m_targets.getUnitTarget());
+ if(!m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL])
+ {
+ sLog.outError( "SPELL: no current channeled spell for spell ID %u\n", m_spellInfo->Id );
+ break;
+ }
+
+ switch(cur)
+ {
+ case TARGET_UNIT_CHANNEL:
+ if(Unit* target = m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets.getUnitTarget())
+ TagUnitMap.push_back(target);
+ else
+ sLog.outError( "SPELL: cannot find channel spell target for spell ID %u\n", m_spellInfo->Id );
+ break;
+ case TARGET_DEST_CHANNEL:
+ if(m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets.HasDest())
+ m_targets = m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets;
+ else
+ sLog.outError( "SPELL: cannot find channel spell destination for spell ID %u\n", m_spellInfo->Id );
+ break;
+ }
}break;
- case TARGET_CHAIN_DAMAGE:
+
+ case TARGET_TYPE_AREA_DEST:
{
- if(Unit* pUnitTarget = SelectMagnetTarget())
+ if(!m_targets.HasDest())
{
- if(EffectChainTarget <= 1)
- TagUnitMap.push_back(pUnitTarget);
- else //TODO: chain target should also use magnet target
- SearchChainTarget(TagUnitMap, pUnitTarget, radius, EffectChainTarget);
+ sLog.outError( "SPELL: cannot find destination for spell ID %u\n", m_spellInfo->Id );
+ return;
+ }
+
+ // Dummy for client
+ if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_DEST)
+ break;
+
+ 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);
+ break;
+ case TARGET_UNIT_AREA_ALLY_GROUND:
+ m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
+ case TARGET_UNIT_AREA_ALLY:
+ SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_FRIENDLY);
+ break;
+ case TARGET_UNIT_AREA_ENTRY_GROUND:
+ m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
+ case TARGET_UNIT_AREA_ENTRY:
+ {
+ SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id);
+ SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
+ if(lower==upper)
+ {
+ SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
+ sLog.outErrorDb("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
+ break;
+ }
+ // let it be done in one check?
+ for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST)
+ {
+ if(i_spellST->second.type != SPELL_TARGET_TYPE_CREATURE)
+ {
+ sLog.outError( "SPELL: spell ID %u requires non-creature target\n", m_spellInfo->Id );
+ continue;
+ }
+ SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ENTRY, i_spellST->second.targetEntry);
+ }
+ }
+ break;
}
}break;
+
+ case TARGET_TYPE_DEFAULT:
+ {
+ switch(cur)
+ {
+
case TARGET_GAMEOBJECT:
{
if(m_targets.getGOTarget())
@@ -1508,43 +1602,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
AddItemTarget(m_targets.getItemTarget(), i);
}break;
- // channel
- case TARGET_SINGLE_ENEMY:
- if(m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL])
- {
- if(Unit* target = m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets.getUnitTarget())
- TagUnitMap.push_back(target);
- else
- sLog.outError( "SPELL: cannot find channel spell target for spell ID %u\n", m_spellInfo->Id );
- }
- else
- sLog.outError( "SPELL: no current channeled spell for spell ID %u\n", m_spellInfo->Id );
- break;
- case TARGET_DEST_CHANNEL:
- if(m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL])
- {
- if(m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets.HasDest())
- m_targets = m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets;
- else
- sLog.outError( "SPELL: cannot find channel spell destination for spell ID %u\n", m_spellInfo->Id );
- }
- else
- sLog.outError( "SPELL: no current channeled spell for spell ID %u\n", m_spellInfo->Id );
- break;
-
- // reference dest
- case TARGET_EFFECT_SELECT:
- m_targets.setDestination(m_caster, true);
- break;
- case TARGET_ALL_AROUND_CASTER:
- m_targets.setDestination(m_caster, false);
- break;
- case TARGET_CURRENT_ENEMY_COORDINATES:
- m_targets.setDestination(m_targets.getUnitTarget(), true);
- break;
- case TARGET_DUELVSPLAYER_COORDINATES: // no ground?
- m_targets.setDestination(m_targets.getUnitTarget(), false);
- break;
case TARGET_DEST_TABLE_UNKNOWN2:
case TARGET_TABLE_X_Y_Z_COORDINATES:
if(SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id))
@@ -1565,42 +1622,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
m_targets.setDestination(((Player*)m_caster)->m_homebindX,((Player*)m_caster)->m_homebindY,((Player*)m_caster)->m_homebindZ, true, ((Player*)m_caster)->m_homebindMapId);
break;
- // area targets
- case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
- if(m_spellInfo->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
- break;
- m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- case TARGET_ALL_ENEMY_IN_AREA:
- SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
- break;
- case TARGET_ALL_FRIENDLY_UNITS_IN_AREA:
- m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
- SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_FRIENDLY);
- break;
- case TARGET_AREAEFFECT_CUSTOM:
- m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- case TARGET_UNIT_AREA_ENTRY:
- {
- SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id);
- SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
- if(lower==upper)
- {
- SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
- sLog.outErrorDb("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
- break;
- }
- // let it be done in one check?
- for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST)
- {
- if(i_spellST->second.type != SPELL_TARGET_TYPE_CREATURE)
- {
- sLog.outError( "SPELL: spell ID %u requires non-creature target\n", m_spellInfo->Id );
- continue;
- }
- SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ENTRY, i_spellST->second.targetEntry);
- }
- }break;
+
case TARGET_IN_FRONT_OF_CASTER:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_CONE_BACK)
@@ -1825,26 +1847,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
}
}
}break;
- case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
- {
- // targets the ground, not the units in the area
- if (m_spellInfo->Effect[i]!=SPELL_EFFECT_PERSISTENT_AREA_AURA)
- {
- CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE);
-
- TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier);
- TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_object_notifier(notifier);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
- cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
- }
- }break;
case TARGET_AREAEFFECT_PARTY:
{
Unit* owner = m_caster->GetCharmerOrOwner();
@@ -1925,23 +1927,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
float max_range = radius + unMaxTargets * CHAIN_SPELL_JUMP_RADIUS;
std::list<Unit *> tempUnitMap;
-
- {
- CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- Trinity::SpellNotifierCreatureAndPlayer notifier(*this, tempUnitMap, max_range, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY);
-
- TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier);
- TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_object_notifier(notifier);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
- cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
-
- }
+ Trinity::SpellNotifierCreatureAndPlayer notifier(*this, tempUnitMap, max_range, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY);
+ m_caster->VisitNearbyObject(max_range, notifier);
if(m_caster != pUnitTarget && std::find(tempUnitMap.begin(),tempUnitMap.end(),m_caster) == tempUnitMap.end() )
tempUnitMap.push_front(m_caster);
@@ -2011,22 +1998,22 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
TagUnitMap.push_back(m_targets.getUnitTarget());
break;
}
+ }
+ }break;
- // destination around caster
- case TARGET_DEST_CASTER_FRONT_LEFT:
- case TARGET_DEST_CASTER_BACK_LEFT:
- case TARGET_DEST_CASTER_BACK_RIGHT:
- case TARGET_DEST_CASTER_FRONT_RIGHT:
- case TARGET_DEST_CASTER_FRONT:
- case TARGET_MINION:
- case TARGET_DEST_CASTER_FRONT_LEAP:
- case TARGET_DEST_CASTER_FRONT_UNKNOWN:
- case TARGET_DEST_CASTER_BACK:
- case TARGET_DEST_CASTER_RIGHT:
- case TARGET_DEST_CASTER_LEFT:
- case TARGET_DEST_CASTER_RANDOM:
- case TARGET_DEST_CASTER_RADIUS:
+ case TARGET_TYPE_DEST_CASTER:
{
+ if(cur == TARGET_DEST_CASTER_GROUND)
+ {
+ m_targets.setDestination(m_caster, true);
+ break;
+ }
+ else if(cur == TARGET_DEST_CASTER)
+ {
+ m_targets.setDestination(m_caster, false);
+ break;
+ }
+
float x, y, z, angle, dist;
if (m_spellInfo->EffectRadiusIndex[i])
@@ -2059,13 +2046,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
m_targets.setDestination(x, y, z); // do not know if has ground visual
}break;
- // destination around target
- case TARGET_DEST_TARGET_FRONT:
- case TARGET_DEST_TARGET_BACK:
- case TARGET_DEST_TARGET_RIGHT:
- case TARGET_DEST_TARGET_LEFT:
- case TARGET_DEST_TARGET_RANDOM:
- case TARGET_DEST_TARGET_RADIUS:
+ case TARGET_TYPE_DEST_TARGET:
{
Unit *target = m_targets.getUnitTarget();
if(!target)
@@ -2074,6 +2055,17 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
}
+ if(cur == TARGET_DEST_TARGET_ENEMY)
+ {
+ m_targets.setDestination(target, true);
+ break;
+ }
+ else if(cur == TARGET_DEST_TARGET_ENEMY_UNKNOWN) // no ground?
+ {
+ m_targets.setDestination(target, false);
+ break;
+ }
+
float x, y, z, angle, dist;
if (m_spellInfo->EffectRadiusIndex[i])
@@ -2099,29 +2091,33 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
m_targets.setDestination(x, y, z); // do not know if has ground visual
}break;
- // destination around destination
- case TARGET_DEST_DEST_RANDOM:
+ case TARGET_TYPE_DEST_DEST:
{
if(!m_targets.HasDest())
{
sLog.outError("SPELL: no destination for spell ID %u\n", m_spellInfo->Id);
break;
}
- float x, y, z, dist, px, py, pz;
- dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
- x = m_targets.m_destX;
- y = m_targets.m_destY;
- z = m_targets.m_destZ;
- m_caster->GetRandomPoint(x, y, z, dist, px, py, pz);
- m_targets.setDestination(px, py, pz);
- }break;
- case TARGET_SELF2:
- if(!m_targets.HasDest())
+
+ switch(cur)
{
- sLog.outError("SPELL: no destination for spell ID %u\n", m_spellInfo->Id);
+ case TARGET_DEST_DEST_RANDOM:
+ {
+
+ float x, y, z, dist, px, py, pz;
+ dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ x = m_targets.m_destX;
+ y = m_targets.m_destY;
+ z = m_targets.m_destZ;
+ m_caster->GetRandomPoint(x, y, z, dist, px, py, pz);
+ m_targets.setDestination(px, py, pz);
+ }
break;
+ case TARGET_DEST_DEST:
+ break;
}
- break;
+ }break;
+
default:
break;
}