mirror of
https://github.com/araxiaonline/TrinityCore2.git
synced 2026-06-20 14:51:34 -04:00
* Added the option to specify target entry in conditions table for spells with AoE GO targets.
* A few examples where this is desirable are posted on the forum. --HG-- branch : trunk
This commit is contained in:
@@ -770,6 +770,10 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
spellProto->EffectImplicitTargetB[i] == TARGET_UNIT_NEARBY_ENTRY ||
|
||||
spellProto->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT_NEARBY_ENTRY ||
|
||||
spellProto->EffectImplicitTargetB[i] == TARGET_GAMEOBJECT_NEARBY_ENTRY ||
|
||||
spellProto->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT_AREA_SRC ||
|
||||
spellProto->EffectImplicitTargetB[i] == TARGET_GAMEOBJECT_AREA_SRC ||
|
||||
spellProto->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT_AREA_DST ||
|
||||
spellProto->EffectImplicitTargetB[i] == TARGET_GAMEOBJECT_AREA_DST ||
|
||||
spellProto->EffectImplicitTargetA[i] == TARGET_DST_NEARBY_ENTRY ||
|
||||
spellProto->EffectImplicitTargetB[i] == TARGET_DST_NEARBY_ENTRY ||
|
||||
spellProto->EffectImplicitTargetA[i] == TARGET_UNIT_CONE_ENTRY ||
|
||||
@@ -781,8 +785,9 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
}
|
||||
if (!targetfound)
|
||||
{
|
||||
sLog.outErrorDb("SourceEntry %u in `condition` table does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DST_NEARBY_ENTRY (46)\
|
||||
,TARGET_UNIT_AREA_ENTRY_SRC(7), TARGET_UNIT_AREA_ENTRY_DST(8), TARGET_UNIT_CONE_ENTRY(60), TARGET_GAMEOBJECT_NEARBY_ENTRY(40)",cond->mSourceEntry);
|
||||
sLog.outErrorDb("SourceEntry %u in `condition` table does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DST_NEARBY_ENTRY (46)"
|
||||
",TARGET_UNIT_AREA_ENTRY_SRC(7), TARGET_UNIT_AREA_ENTRY_DST(8), TARGET_UNIT_CONE_ENTRY(60), TARGET_GAMEOBJECT_NEARBY_ENTRY(40)"
|
||||
"TARGET_GAMEOBJECT_AREA_SRC(51), TARGET_GAMEOBJECT_AREA_DST(52)", cond->mSourceEntry);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1177,13 +1177,17 @@ namespace Trinity
|
||||
class GameObjectInRangeCheck
|
||||
{
|
||||
public:
|
||||
GameObjectInRangeCheck(float _x, float _y, float _z, float _range) : x(_x), y(_y), z(_z), range(_range) {}
|
||||
GameObjectInRangeCheck(float _x, float _y, float _z, float _range, uint32 _entry = 0) :
|
||||
x(_x), y(_y), z(_z), range(_range), entry(_entry) {}
|
||||
bool operator() (GameObject* go)
|
||||
{
|
||||
return go->IsInRange(x, y, z, range);
|
||||
if (!entry || go->GetGOInfo() && go->GetGOInfo()->id == entry)
|
||||
return go->IsInRange(x, y, z, range);
|
||||
else return false;
|
||||
}
|
||||
private:
|
||||
float x, y, z, range;
|
||||
uint32 entry;
|
||||
};
|
||||
|
||||
// Player checks and do
|
||||
|
||||
@@ -1148,8 +1148,8 @@ enum Targets
|
||||
TARGET_DEST_CASTER_BACK = 48,
|
||||
TARGET_DEST_CASTER_RIGHT = 49,
|
||||
TARGET_DEST_CASTER_LEFT = 50,
|
||||
TARGET_OBJECT_AREA_SRC = 51,
|
||||
TARGET_OBJECT_AREA_DST = 52,
|
||||
TARGET_GAMEOBJECT_AREA_SRC = 51, // If used with SPELL_EFFECT_ACTIVATE_OBJECT, appliccable GO entries should be specified in conditions table
|
||||
TARGET_GAMEOBJECT_AREA_DST = 52, // If used with SPELL_EFFECT_ACTIVATE_OBJECT, appliccable GO entries should be specified in conditions table
|
||||
TARGET_DST_TARGET_ENEMY = 53, // set unit coordinates as dest, only 16 target B imlemented
|
||||
TARGET_UNIT_CONE_ENEMY_UNKNOWN = 54, // 180 degree, or different angle
|
||||
TARGET_DEST_CASTER_FRONT_LEAP = 55, // for a leap spell
|
||||
|
||||
+190
-140
@@ -1729,6 +1729,9 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
|
||||
|
||||
void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry)
|
||||
{
|
||||
if (TargetType == SPELL_TARGETS_GO)
|
||||
return;
|
||||
|
||||
Position *pos;
|
||||
switch(type)
|
||||
{
|
||||
@@ -1767,6 +1770,32 @@ void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNo
|
||||
TagUnitMap.remove(m_caster);
|
||||
}
|
||||
|
||||
void Spell::SearchGOAreaTarget(std::list<GameObject*> &TagGOMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry)
|
||||
{
|
||||
if (TargetType != SPELL_TARGETS_GO)
|
||||
return;
|
||||
|
||||
Position *pos;
|
||||
switch (type)
|
||||
{
|
||||
case PUSH_DST_CENTER:
|
||||
CheckDst();
|
||||
pos = &m_targets.m_dstPos;
|
||||
break;
|
||||
case PUSH_SRC_CENTER:
|
||||
CheckSrc();
|
||||
pos = &m_targets.m_srcPos;
|
||||
break;
|
||||
default:
|
||||
pos = m_caster;
|
||||
break;
|
||||
}
|
||||
|
||||
Trinity::GameObjectInRangeCheck check(pos->m_positionX, pos->m_positionY, pos->m_positionZ, radius + 50, entry);
|
||||
Trinity::GameObjectListSearcher<Trinity::GameObjectInRangeCheck> searcher(m_caster, TagGOMap, check);
|
||||
m_caster->GetMap()->VisitGrid(pos->m_positionX, pos->m_positionY, radius, searcher);
|
||||
}
|
||||
|
||||
WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType)
|
||||
{
|
||||
switch(TargetType)
|
||||
@@ -2328,6 +2357,11 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
||||
radius = GetSpellRadius(m_spellInfo, i, IsPositiveSpell(m_spellInfo->Id));
|
||||
targetType = SPELL_TARGETS_ENTRY;
|
||||
break;
|
||||
case TARGET_GAMEOBJECT_AREA_SRC:
|
||||
case TARGET_GAMEOBJECT_AREA_DST:
|
||||
radius = GetSpellRadius(m_spellInfo, i, true);
|
||||
targetType = SPELL_TARGETS_GO;
|
||||
break;
|
||||
default:
|
||||
radius = GetSpellRadius(m_spellInfo, i, true);
|
||||
targetType = SPELL_TARGETS_NONE;
|
||||
@@ -2339,169 +2373,170 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
||||
radius *= m_spellValue->RadiusMod;
|
||||
|
||||
std::list<Unit*> unitList;
|
||||
if (targetType == SPELL_TARGETS_ENTRY)
|
||||
std::list<GameObject*> gobjectList;
|
||||
switch (targetType)
|
||||
{
|
||||
ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
|
||||
if (conditions.empty())
|
||||
case SPELL_TARGETS_ENTRY:
|
||||
{
|
||||
// Custom entries
|
||||
// TODO: move these to sql
|
||||
switch (m_spellInfo->Id)
|
||||
ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
|
||||
if (!conditions.empty())
|
||||
{
|
||||
case 46584: // Raise Dead
|
||||
for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
|
||||
{
|
||||
if (WorldObject* result = FindCorpseUsing<Trinity::RaiseDeadObjectCheck> ())
|
||||
if ((*i_spellST)->mConditionType != CONDITION_SPELL_SCRIPT_TARGET)
|
||||
continue;
|
||||
if ((*i_spellST)->mConditionValue1 == SPELL_TARGET_TYPE_CREATURE)
|
||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, (*i_spellST)->mConditionValue2);
|
||||
else if ((*i_spellST)->mConditionValue1 == SPELL_TARGET_TYPE_CONTROLLED)
|
||||
{
|
||||
switch(result->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
m_targets.setDst(result);
|
||||
}
|
||||
for (Unit::ControlList::iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
|
||||
if ((*itr)->GetEntry() == (*i_spellST)->mConditionValue2 &&
|
||||
/*(*itr)->IsWithinDistInMap(m_caster, radius)*/ (*itr)->IsInMap(m_caster)) // For 60243 and 52173 need skip radius check or use range (no radius entry for effect)
|
||||
unitList.push_back(*itr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Corpse Explosion
|
||||
case 49158:
|
||||
case 51325:
|
||||
case 51326:
|
||||
case 51327:
|
||||
case 51328:
|
||||
// Search for ghoul if our ghoul or dead body not valid unit target
|
||||
if (!(m_targets.getUnitTarget() && (m_targets.getUnitTarget()->GetEntry() == 26125 && m_targets.getUnitTarget()->GetOwnerGUID() == m_caster->GetGUID()
|
||||
|| (m_targets.getUnitTarget()->getDeathState() == CORPSE
|
||||
&& m_targets.getUnitTarget()->GetDisplayId() == m_targets.getUnitTarget()->GetNativeDisplayId()
|
||||
&& m_targets.getUnitTarget()->GetTypeId() == TYPEID_UNIT
|
||||
&& !m_targets.getUnitTarget()->ToCreature()->isDeadByDefault()
|
||||
&& !(m_targets.getUnitTarget()->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL))
|
||||
&& m_targets.getUnitTarget()->GetDisplayId() == m_targets.getUnitTarget()->GetNativeDisplayId())))
|
||||
}
|
||||
else
|
||||
{
|
||||
// Custom entries
|
||||
// TODO: move these to sql
|
||||
switch (m_spellInfo->Id)
|
||||
{
|
||||
case 46584: // Raise Dead
|
||||
{
|
||||
CleanupTargetList();
|
||||
|
||||
WorldObject* result = FindCorpseUsing <Trinity::ExplodeCorpseObjectCheck> ();
|
||||
|
||||
if (result)
|
||||
if (WorldObject* result = FindCorpseUsing<Trinity::RaiseDeadObjectCheck> ())
|
||||
{
|
||||
switch (result->GetTypeId())
|
||||
switch(result->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
case TYPEID_PLAYER:
|
||||
m_targets.setUnitTarget((Unit*)result);
|
||||
break;
|
||||
m_targets.setDst(result);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Corpse Explosion
|
||||
case 49158:
|
||||
case 51325:
|
||||
case 51326:
|
||||
case 51327:
|
||||
case 51328:
|
||||
// Search for ghoul if our ghoul or dead body not valid unit target
|
||||
if (!(m_targets.getUnitTarget() && (m_targets.getUnitTarget()->GetEntry() == 26125 && m_targets.getUnitTarget()->GetOwnerGUID() == m_caster->GetGUID()
|
||||
|| (m_targets.getUnitTarget()->getDeathState() == CORPSE
|
||||
&& m_targets.getUnitTarget()->GetDisplayId() == m_targets.getUnitTarget()->GetNativeDisplayId()
|
||||
&& m_targets.getUnitTarget()->GetTypeId() == TYPEID_UNIT
|
||||
&& !m_targets.getUnitTarget()->ToCreature()->isDeadByDefault()
|
||||
&& !(m_targets.getUnitTarget()->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL))
|
||||
&& m_targets.getUnitTarget()->GetDisplayId() == m_targets.getUnitTarget()->GetNativeDisplayId())))
|
||||
{
|
||||
CleanupTargetList();
|
||||
|
||||
WorldObject* result = FindCorpseUsing <Trinity::ExplodeCorpseObjectCheck> ();
|
||||
|
||||
if (result)
|
||||
{
|
||||
switch (result->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
case TYPEID_PLAYER:
|
||||
m_targets.setUnitTarget((Unit*)result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id,true);
|
||||
SendCastResult(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sLog.outDebug("Spell (ID: %u) (caster Entry: %u) does not have type CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET record in `conditions` table.", m_spellInfo->Id, m_caster->GetEntry());
|
||||
|
||||
if (m_spellInfo->Effect[i] == SPELL_EFFECT_TELEPORT_UNITS)
|
||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, 0);
|
||||
else if (IsPositiveEffect(m_spellInfo->Id, i))
|
||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ALLY);
|
||||
else
|
||||
{
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id,true);
|
||||
SendCastResult(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELL_TARGETS_GO:
|
||||
{
|
||||
ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
|
||||
if (!conditions.empty())
|
||||
{
|
||||
for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
|
||||
{
|
||||
if ((*i_spellST)->mConditionType != CONDITION_SPELL_SCRIPT_TARGET)
|
||||
continue;
|
||||
if ((*i_spellST)->mConditionValue1 == SPELL_TARGET_TYPE_GAMEOBJECT)
|
||||
SearchGOAreaTarget(gobjectList, radius, pushType, SPELL_TARGETS_GO, (*i_spellST)->mConditionValue2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_spellInfo->Effect[i] == SPELL_EFFECT_ACTIVATE_OBJECT)
|
||||
sLog.outDebug("Spell (ID: %u) (caster Entry: %u) with SPELL_EFFECT_ACTIVATE_OBJECT does not have type CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET record in `conditions` table.", m_spellInfo->Id, m_caster->GetEntry());
|
||||
SearchGOAreaTarget(gobjectList, radius, pushType, SPELL_TARGETS_GO);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELL_TARGETS_ALLY:
|
||||
case SPELL_TARGETS_ENEMY:
|
||||
case SPELL_TARGETS_CHAINHEAL:
|
||||
case SPELL_TARGETS_ANY:
|
||||
SearchAreaTarget(unitList, radius, pushType, targetType);
|
||||
break;
|
||||
default:
|
||||
switch (cur)
|
||||
{
|
||||
case TARGET_UNIT_AREA_PARTY_SRC:
|
||||
case TARGET_UNIT_AREA_PARTY_DST:
|
||||
m_caster->GetPartyMemberInDist(unitList, radius); //fix me
|
||||
break;
|
||||
|
||||
default:
|
||||
sLog.outDebug("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
|
||||
|
||||
if (m_spellInfo->Effect[i] == SPELL_EFFECT_TELEPORT_UNITS)
|
||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, 0);
|
||||
else if (IsPositiveEffect(m_spellInfo->Id, i))
|
||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ALLY);
|
||||
else
|
||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
|
||||
}
|
||||
}
|
||||
// let it be done in one check?
|
||||
else
|
||||
{
|
||||
for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
|
||||
{
|
||||
if ((*i_spellST)->mConditionType != CONDITION_SPELL_SCRIPT_TARGET)
|
||||
continue;
|
||||
if ((*i_spellST)->mConditionValue1 == SPELL_TARGET_TYPE_CREATURE)
|
||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, (*i_spellST)->mConditionValue2);
|
||||
else if ((*i_spellST)->mConditionValue1 == SPELL_TARGET_TYPE_CONTROLLED)
|
||||
case TARGET_UNIT_PARTY_TARGET:
|
||||
m_targets.getUnitTarget()->GetPartyMemberInDist(unitList, radius);
|
||||
break;
|
||||
case TARGET_UNIT_PARTY_CASTER:
|
||||
m_caster->GetPartyMemberInDist(unitList, radius);
|
||||
break;
|
||||
case TARGET_UNIT_RAID_CASTER:
|
||||
m_caster->GetRaidMember(unitList, radius);
|
||||
break;
|
||||
case TARGET_UNIT_CLASS_TARGET:
|
||||
{
|
||||
for (Unit::ControlList::iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
|
||||
if ((*itr)->GetEntry() == (*i_spellST)->mConditionValue2 &&
|
||||
/*(*itr)->IsWithinDistInMap(m_caster, radius)*/ (*itr)->IsInMap(m_caster)) // For 60243 and 52173 need skip radius check or use range (no radius entry for effect)
|
||||
unitList.push_back(*itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targetType)
|
||||
SearchAreaTarget(unitList, radius, pushType, targetType);
|
||||
else
|
||||
{
|
||||
switch (cur)
|
||||
{
|
||||
case TARGET_UNIT_AREA_PARTY_SRC:
|
||||
case TARGET_UNIT_AREA_PARTY_DST:
|
||||
m_caster->GetPartyMemberInDist(unitList, radius); //fix me
|
||||
break;
|
||||
case TARGET_OBJECT_AREA_SRC: // fix me
|
||||
case TARGET_OBJECT_AREA_DST:
|
||||
{
|
||||
float x, y, z;
|
||||
if (cur == TARGET_OBJECT_AREA_SRC)
|
||||
{
|
||||
if (m_targets.HasSrc())
|
||||
m_targets.m_srcPos.GetPosition(x, y, z);
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_targets.HasDst())
|
||||
m_targets.m_dstPos.GetPosition(x, y, z);
|
||||
else
|
||||
break;
|
||||
}
|
||||
Player* targetPlayer = m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER
|
||||
? (Player*)m_targets.getUnitTarget() : NULL;
|
||||
|
||||
Trinity::GameObjectInRangeCheck check(x, y, z, radius + 50);
|
||||
std::list<GameObject*> goList;
|
||||
Trinity::GameObjectListSearcher<Trinity::GameObjectInRangeCheck> searcher(m_caster, goList, check);
|
||||
m_caster->GetMap()->VisitGrid(x, y, radius, searcher);
|
||||
for (std::list<GameObject*>::iterator itr = goList.begin(); itr != goList.end(); ++itr)
|
||||
AddGOTarget(*itr, i);
|
||||
break;
|
||||
}
|
||||
case TARGET_UNIT_PARTY_TARGET:
|
||||
m_targets.getUnitTarget()->GetPartyMemberInDist(unitList, radius);
|
||||
break;
|
||||
case TARGET_UNIT_PARTY_CASTER:
|
||||
m_caster->GetPartyMemberInDist(unitList, radius);
|
||||
break;
|
||||
case TARGET_UNIT_RAID_CASTER:
|
||||
m_caster->GetRaidMember(unitList, radius);
|
||||
break;
|
||||
case TARGET_UNIT_CLASS_TARGET:
|
||||
{
|
||||
Player* targetPlayer = m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER
|
||||
? (Player*)m_targets.getUnitTarget() : NULL;
|
||||
|
||||
Group* pGroup = targetPlayer ? targetPlayer->GetGroup() : NULL;
|
||||
if (pGroup)
|
||||
{
|
||||
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
Group* pGroup = targetPlayer ? targetPlayer->GetGroup() : NULL;
|
||||
if (pGroup)
|
||||
{
|
||||
Player* Target = itr->getSource();
|
||||
|
||||
// IsHostileTo check duel and controlled by enemy
|
||||
if (Target && targetPlayer->IsWithinDistInMap(Target, radius) &&
|
||||
targetPlayer->getClass() == Target->getClass() &&
|
||||
!m_caster->IsHostileTo(Target))
|
||||
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
AddUnitTarget(Target, i);
|
||||
Player* Target = itr->getSource();
|
||||
|
||||
// IsHostileTo check duel and controlled by enemy
|
||||
if (Target && targetPlayer->IsWithinDistInMap(Target, radius) &&
|
||||
targetPlayer->getClass() == Target->getClass() &&
|
||||
!m_caster->IsHostileTo(Target))
|
||||
{
|
||||
AddUnitTarget(Target, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_targets.getUnitTarget())
|
||||
AddUnitTarget(m_targets.getUnitTarget(), i);
|
||||
break;
|
||||
}
|
||||
else if (m_targets.getUnitTarget())
|
||||
AddUnitTarget(m_targets.getUnitTarget(), i);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!unitList.empty())
|
||||
{
|
||||
@@ -2625,7 +2660,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
||||
|
||||
if (m_spellInfo->Id == 5246) //Intimidating Shout
|
||||
unitList.remove(m_targets.getUnitTarget());
|
||||
Trinity::RandomResizeList(unitList, m_spellValue->MaxAffectedTargets);
|
||||
Trinity::RandomResizeList(unitList, maxTargets);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2671,6 +2706,21 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
||||
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
|
||||
AddUnitTarget(*itr, i);
|
||||
}
|
||||
|
||||
if (!gobjectList.empty())
|
||||
{
|
||||
if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
|
||||
{
|
||||
Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
|
||||
for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
|
||||
if ((*j)->IsAffectedOnSpell(m_spellInfo))
|
||||
maxTargets += (*j)->GetAmount();
|
||||
|
||||
Trinity::RandomResizeList(gobjectList, maxTargets);
|
||||
}
|
||||
for (std::list<GameObject*>::iterator itr = gobjectList.begin(); itr != gobjectList.end(); ++itr)
|
||||
AddGOTarget(*itr, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -265,6 +265,7 @@ enum SpellTargets
|
||||
SPELL_TARGETS_ENTRY,
|
||||
SPELL_TARGETS_CHAINHEAL,
|
||||
SPELL_TARGETS_ANY,
|
||||
SPELL_TARGETS_GO
|
||||
};
|
||||
|
||||
class Spell
|
||||
@@ -645,6 +646,7 @@ class Spell
|
||||
void DoAllEffectOnTarget(ItemTargetInfo *target);
|
||||
bool UpdateChanneledTargetList();
|
||||
void SearchAreaTarget(std::list<Unit*> &unitList, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry = 0);
|
||||
void SearchGOAreaTarget(std::list<GameObject*> &gobjectList, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry = 0);
|
||||
void SearchChainTarget(std::list<Unit*> &unitList, float radius, uint32 unMaxTargets, SpellTargets TargetType);
|
||||
WorldObject* SearchNearbyTarget(float range, SpellTargets TargetType);
|
||||
bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;
|
||||
|
||||
@@ -145,14 +145,14 @@ SpellMgr::SpellMgr()
|
||||
case TARGET_UNIT_AREA_ALLY_SRC:
|
||||
case TARGET_UNIT_AREA_ENTRY_SRC:
|
||||
case TARGET_UNIT_AREA_PARTY_SRC:
|
||||
case TARGET_OBJECT_AREA_SRC:
|
||||
case TARGET_GAMEOBJECT_AREA_SRC:
|
||||
SpellTargetType[i] = TARGET_TYPE_AREA_SRC;
|
||||
break;
|
||||
case TARGET_UNIT_AREA_ENEMY_DST:
|
||||
case TARGET_UNIT_AREA_ALLY_DST:
|
||||
case TARGET_UNIT_AREA_ENTRY_DST:
|
||||
case TARGET_UNIT_AREA_PARTY_DST:
|
||||
case TARGET_OBJECT_AREA_DST:
|
||||
case TARGET_GAMEOBJECT_AREA_DST:
|
||||
SpellTargetType[i] = TARGET_TYPE_AREA_DST;
|
||||
break;
|
||||
case TARGET_UNIT_CONE_ENEMY:
|
||||
|
||||
Reference in New Issue
Block a user