mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-13 11:43:18 -04:00
*Update spell target selection code.
--HG-- branch : trunk
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}break;
|
||||
case TARGET_NONCOMBAT_PET:
|
||||
{
|
||||
if(Unit* target = m_targets.getUnitTarget())
|
||||
if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET)
|
||||
TagUnitMap.push_back(target);
|
||||
}break;
|
||||
case TARGET_SINGLE_FRIEND: // ally
|
||||
case TARGET_SINGLE_FRIEND_2: // raid member
|
||||
case TARGET_DUELVSPLAYER: // all (SelectMagnetTarget()?)
|
||||
case TARGET_UNIT_SINGLE_UNKNOWN:
|
||||
{
|
||||
if(m_targets.getUnitTarget())
|
||||
TagUnitMap.push_back(m_targets.getUnitTarget());
|
||||
}break;
|
||||
case TARGET_CHAIN_DAMAGE:
|
||||
{
|
||||
if(Unit* pUnitTarget = SelectMagnetTarget())
|
||||
switch(cur)
|
||||
{
|
||||
if(EffectChainTarget <= 1)
|
||||
TagUnitMap.push_back(pUnitTarget);
|
||||
else //TODO: chain target should also use magnet target
|
||||
SearchChainTarget(TagUnitMap, pUnitTarget, radius, EffectChainTarget);
|
||||
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_TYPE_UNIT_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_TYPE_CHANNEL:
|
||||
{
|
||||
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_TYPE_AREA_DEST:
|
||||
{
|
||||
if(!m_targets.HasDest())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user