aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/SharedDefines.h42
-rw-r--r--src/game/Spell.cpp348
-rw-r--r--src/game/SpellMgr.cpp71
-rw-r--r--src/game/SpellMgr.h19
4 files changed, 278 insertions, 202 deletions
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 1045c511bb4..469fa9dddd2 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -789,52 +789,51 @@ enum SpellImmunity
enum Targets
{
TARGET_SELF = 1,
- //TARGET_UNIT_CASTER
+ TARGET_UNIT_CASTER = 1,
TARGET_RANDOM_ENEMY_CHAIN_IN_AREA = 2, // only one spell has that, but regardless, it's a target type after all
//TARGET_UNIT_NEARBY_ENEMY
TARGET_UNIT_SINGLE_UNKNOWN = 3,
TARGET_UNIT_NEARBY_ALLY = 4,
TARGET_PET = 5,
- //TARGET_UNIT_PET
+ TARGET_UNIT_PET = 5,
TARGET_CHAIN_DAMAGE = 6,
TARGET_UNIT_TARGET_ENEMY = 6,
TARGET_UNIT_AREA_ENTRY = 7,
TARGET_AREAEFFECT_CUSTOM = 8,
- //TARGET_UNIT_AREA_ENTRY_GROUND
+ TARGET_UNIT_AREA_ENTRY_GROUND = 8,
TARGET_INNKEEPER_COORDINATES = 9, // uses in teleport to innkeeper spells
//TARGET_DEST_HOME
TARGET_UNIT_TARGET_DEST_CASTER = 11, // teleport target to caster
TARGET_ALL_ENEMY_IN_AREA = 15,
- //TARGET_UNIT_AREA_ENEMY
+ TARGET_UNIT_AREA_ENEMY = 15,
TARGET_ALL_ENEMY_IN_AREA_INSTANT = 16,
- //TARGET_UNIT_AREA_ENEMY_GROUND
+ TARGET_UNIT_AREA_ENEMY_GROUND = 16,
TARGET_TABLE_X_Y_Z_COORDINATES = 17, // uses in teleport spells and some other
//TARGET_DEST_TABLE
TARGET_EFFECT_SELECT = 18, // highly depends on the spell effect
- //TARGET_DEST_CASTER_GROUND
+ TARGET_DEST_CASTER_GROUND = 18,
TARGET_ALL_PARTY_AROUND_CASTER = 20,
//TARGET_UNIT_PARTY_CASTER
TARGET_SINGLE_FRIEND = 21,
TARGET_UNIT_TARGET_ALLY = 21,
TARGET_ALL_AROUND_CASTER = 22, // used only in TargetA, target selection dependent from TargetB
- //TARGET_DEST_CASTER
+ TARGET_DEST_CASTER = 22,
TARGET_GAMEOBJECT = 23,
//TARGET_OBJECT_OPEN
TARGET_IN_FRONT_OF_CASTER = 24,
//TARGET_UNIT_CONE_ENEMY
TARGET_DUELVSPLAYER = 25,
- //TARGET_UNIT_TARGET
+ TARGET_UNIT_TARGET_ANY = 25,
TARGET_GAMEOBJECT_ITEM = 26,
//TARGET_OBJECT_ITEM_PICKLOCK
- TARGET_MASTER = 27,
- //TARGET_UNIT_MASTER
+ TARGET_UNIT_MASTER = 27,
TARGET_ALL_ENEMY_IN_AREA_CHANNELED = 28,
- //TARGET_UNIT_AREA_ENEMY_CHANNEL
+ TARGET_UNIT_AREA_ENEMY_CHANNEL = 28,
TARGET_UNIT_AREA_ALLY_CHANNEL = 29, // 28,29 only used for effect 27, if interrupt channel, pstAA cancel
TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER = 30, // in TargetB used only with TARGET_ALL_AROUND_CASTER and in self casting range in TargetA
- //TARGET_UNIT_AREA_ALLY
+ TARGET_UNIT_AREA_ALLY = 30,
TARGET_ALL_FRIENDLY_UNITS_IN_AREA = 31,
- //TARGET_UNIT_AREA_ALLY_GROUND
+ TARGET_UNIT_AREA_ALLY_GROUND = 31,
TARGET_MINION = 32,
//TARGET_DEST_SUMMON
TARGET_ALL_PARTY = 33,
@@ -848,8 +847,7 @@ enum Targets
//TARGET_UNIT_PARTY_TARGET
TARGET_SCRIPT = 38,
//TARGET_UNIT_NEARBY_ENTRY
- TARGET_SELF_FISHING = 39,
- //TARGET_UNIT_CASTER_FISHING
+ TARGET_UNIT_CASTER_FISHING = 39,
TARGET_OBJECT_USE = 40,
TARGET_DEST_CASTER_FRONT_LEFT = 41, //earth totem
TARGET_DEST_CASTER_BACK_LEFT = 42, //water totem
@@ -867,7 +865,7 @@ enum Targets
TARGET_AREAEFFECT_CUSTOM_2 = 52,
//TARGET_DUMMY
TARGET_CURRENT_ENEMY_COORDINATES = 53, // set unit coordinates as dest, only 16 target B imlemented
- //TARGET_DEST_TARGET_ENEMY
+ TARGET_DEST_TARGET_ENEMY = 53,
TARGET_UNIT_CONE_ENEMY_UNKNOWN = 54,
TARGET_DEST_CASTER_FRONT_LEAP = 55, // for a leap spell
TARGET_RANDOM_RAID_MEMBER = 56,
@@ -880,7 +878,7 @@ enum Targets
//TARGET_UNIT_CLASS_TARGET
TARGET_TEST = 62, // for a test spell
TARGET_DUELVSPLAYER_COORDINATES = 63,
- //TARGET_DEST_TARGET_ENEMY_UNKNOWN
+ TARGET_DEST_TARGET_ENEMY_UNKNOWN = 63,
TARGET_DEST_TARGET_FRONT = 64,
TARGET_DEST_TARGET_BACK = 65, // uses in teleport behind spells
TARGET_DEST_TARGET_RIGHT = 66,
@@ -892,17 +890,17 @@ enum Targets
TARGET_DEST_TARGET_RADIUS = 75,
TARGET_DEST_CHANNEL = 76,
TARGET_SINGLE_ENEMY = 77,
- //TARGET_UNIT_CHANNEL
+ TARGET_UNIT_CHANNEL = 77,
TARGET_DEST_CASTER_FRONT_UNKNOWN = 78,
TARGET_DEST_TABLE_UNKNOWN2 = 80,
TARGET_DEST_DEST_RANDOM = 86,
- TARGET_SELF2 = 87,
- //TARGET_DEST_DEST
+ TARGET_DEST_DEST = 87,
TARGET_UNIT_AREA_ALL_CHANNEL = 88,
- TARGET_NONCOMBAT_PET = 90,
- //TARGET_UNIT_MINIPET
+ TARGET_UNIT_MINIPET = 90,
};
+#define TOTAL_SPELL_TARGETS 91
+
enum SpellMissInfo
{
SPELL_MISS_NONE = 0,
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;
}
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 0032f9f7e67..7a67018fc3c 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -1729,7 +1729,7 @@ void SpellMgr::LoadSpellScriptTarget()
}
}
- mSpellScriptTarget.insert(SpellScriptTarget::value_type(spellId,SpellTargetEntry(SpellTargetType(type),targetEntry)));
+ mSpellScriptTarget.insert(SpellScriptTarget::value_type(spellId,SpellTargetEntry(SpellScriptTargetType(type),targetEntry)));
++count;
} while (result->NextRow());
@@ -1953,6 +1953,7 @@ void SpellMgr::LoadSpellCustomAttr()
case SPELL_EFFECT_ADD_FARSIGHT:
case SPELL_EFFECT_TRIGGER_SPELL_2: //ritual of summon
case SPELL_EFFECT_TRIGGER_MISSILE:
+ case SPELL_EFFECT_PERSISTENT_AREA_AURA:
EffectTargetType[i] = SPELL_REQUIRE_DEST;
break;
case SPELL_EFFECT_PARRY: // 0
@@ -1968,6 +1969,74 @@ void SpellMgr::LoadSpellCustomAttr()
break;
}
}
+
+ for(int i = 0; i < TOTAL_SPELL_TARGETS; ++i)
+ {
+ switch(i)
+ {
+ case TARGET_UNIT_CASTER:
+ case TARGET_UNIT_CASTER_FISHING:
+ case TARGET_UNIT_MASTER:
+ case TARGET_UNIT_PET:
+ SpellTargetType[i] = TARGET_TYPE_UNIT_CASTER;
+ break;
+ case TARGET_UNIT_MINIPET:
+ case TARGET_UNIT_TARGET_ALLY:
+ case TARGET_UNIT_TARGET_RAID:
+ case TARGET_UNIT_TARGET_ANY:
+ case TARGET_UNIT_SINGLE_UNKNOWN:
+ case TARGET_UNIT_TARGET_ENEMY:
+ SpellTargetType[i] = TARGET_TYPE_UNIT_TARGET;
+ break;
+ case TARGET_UNIT_CHANNEL:
+ case TARGET_DEST_CHANNEL:
+ SpellTargetType[i] = TARGET_TYPE_CHANNEL;
+ break;
+ 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_ENEMY_CHANNEL:
+ SpellTargetType[i] = TARGET_TYPE_AREA_DEST;
+ break;
+ case TARGET_DEST_TARGET_ENEMY:
+ case TARGET_DEST_TARGET_ENEMY_UNKNOWN:
+ 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:
+ SpellTargetType[i] = TARGET_TYPE_DEST_TARGET;
+ break;
+ case TARGET_DEST_CASTER_GROUND:
+ case TARGET_DEST_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:
+ SpellTargetType[i] = TARGET_TYPE_DEST_CASTER;
+ break;
+ case TARGET_DEST_DEST_RANDOM:
+ case TARGET_DEST_DEST:
+ SpellTargetType[i] = TARGET_TYPE_DEST_DEST;
+ break;
+ default:
+ SpellTargetType[i] = TARGET_TYPE_DEFAULT;
+
+ }
+ }
}
void SpellMgr::LoadSpellLinked()
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 8bd43e81030..e3bc4c55b99 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -240,6 +240,18 @@ enum SpellEffectTargetTypes
SPELL_REQUIRE_DEST,
};
+enum SpellSelectTargetTypes
+{
+ TARGET_TYPE_DEFAULT,
+ TARGET_TYPE_UNIT_CASTER,
+ TARGET_TYPE_UNIT_TARGET,
+ TARGET_TYPE_CHANNEL,
+ TARGET_TYPE_AREA_DEST,
+ TARGET_TYPE_DEST_CASTER,
+ TARGET_TYPE_DEST_TARGET,
+ TARGET_TYPE_DEST_DEST,
+};
+
//Some SpellFamilyFlags
#define SPELLFAMILYFLAG_ROGUE_VANISH 0x000000800LL
#define SPELLFAMILYFLAG_ROGUE_STEALTH 0x000400000LL
@@ -556,7 +568,7 @@ typedef UNORDERED_MAP<uint32, SpellProcEventEntry> SpellProcEventMap;
typedef std::map<uint32, uint8> SpellElixirMap;
// Spell script target related declarations (accessed using SpellMgr functions)
-enum SpellTargetType
+enum SpellScriptTargetType
{
SPELL_TARGET_TYPE_GAMEOBJECT = 0,
SPELL_TARGET_TYPE_CREATURE = 1,
@@ -567,8 +579,8 @@ enum SpellTargetType
struct SpellTargetEntry
{
- SpellTargetEntry(SpellTargetType type_,uint32 targetEntry_) : type(type_), targetEntry(targetEntry_) {}
- SpellTargetType type;
+ SpellTargetEntry(SpellScriptTargetType type_,uint32 targetEntry_) : type(type_), targetEntry(targetEntry_) {}
+ SpellScriptTargetType type;
uint32 targetEntry;
};
@@ -927,6 +939,7 @@ class SpellMgr
}
SpellEffectTargetTypes EffectTargetType[TOTAL_SPELL_EFFECTS];
+ SpellSelectTargetTypes SpellTargetType[TOTAL_SPELL_TARGETS];
// Modifiers
public: