diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/SharedDefines.h | 42 | ||||
-rw-r--r-- | src/game/Spell.cpp | 348 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 71 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 19 |
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: |