* 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->EffectImplicitTargetB[i] == TARGET_UNIT_NEARBY_ENTRY ||
|
||||||
spellProto->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT_NEARBY_ENTRY ||
|
spellProto->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT_NEARBY_ENTRY ||
|
||||||
spellProto->EffectImplicitTargetB[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->EffectImplicitTargetA[i] == TARGET_DST_NEARBY_ENTRY ||
|
||||||
spellProto->EffectImplicitTargetB[i] == TARGET_DST_NEARBY_ENTRY ||
|
spellProto->EffectImplicitTargetB[i] == TARGET_DST_NEARBY_ENTRY ||
|
||||||
spellProto->EffectImplicitTargetA[i] == TARGET_UNIT_CONE_ENTRY ||
|
spellProto->EffectImplicitTargetA[i] == TARGET_UNIT_CONE_ENTRY ||
|
||||||
@@ -781,8 +785,9 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
}
|
}
|
||||||
if (!targetfound)
|
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)\
|
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);
|
",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;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1177,13 +1177,17 @@ namespace Trinity
|
|||||||
class GameObjectInRangeCheck
|
class GameObjectInRangeCheck
|
||||||
{
|
{
|
||||||
public:
|
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)
|
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:
|
private:
|
||||||
float x, y, z, range;
|
float x, y, z, range;
|
||||||
|
uint32 entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Player checks and do
|
// Player checks and do
|
||||||
|
|||||||
@@ -1148,8 +1148,8 @@ enum Targets
|
|||||||
TARGET_DEST_CASTER_BACK = 48,
|
TARGET_DEST_CASTER_BACK = 48,
|
||||||
TARGET_DEST_CASTER_RIGHT = 49,
|
TARGET_DEST_CASTER_RIGHT = 49,
|
||||||
TARGET_DEST_CASTER_LEFT = 50,
|
TARGET_DEST_CASTER_LEFT = 50,
|
||||||
TARGET_OBJECT_AREA_SRC = 51,
|
TARGET_GAMEOBJECT_AREA_SRC = 51, // If used with SPELL_EFFECT_ACTIVATE_OBJECT, appliccable GO entries should be specified in conditions table
|
||||||
TARGET_OBJECT_AREA_DST = 52,
|
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_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_UNIT_CONE_ENEMY_UNKNOWN = 54, // 180 degree, or different angle
|
||||||
TARGET_DEST_CASTER_FRONT_LEAP = 55, // for a leap spell
|
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)
|
void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry)
|
||||||
{
|
{
|
||||||
|
if (TargetType == SPELL_TARGETS_GO)
|
||||||
|
return;
|
||||||
|
|
||||||
Position *pos;
|
Position *pos;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
@@ -1767,6 +1770,32 @@ void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNo
|
|||||||
TagUnitMap.remove(m_caster);
|
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)
|
WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType)
|
||||||
{
|
{
|
||||||
switch(TargetType)
|
switch(TargetType)
|
||||||
@@ -2328,6 +2357,11 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
|||||||
radius = GetSpellRadius(m_spellInfo, i, IsPositiveSpell(m_spellInfo->Id));
|
radius = GetSpellRadius(m_spellInfo, i, IsPositiveSpell(m_spellInfo->Id));
|
||||||
targetType = SPELL_TARGETS_ENTRY;
|
targetType = SPELL_TARGETS_ENTRY;
|
||||||
break;
|
break;
|
||||||
|
case TARGET_GAMEOBJECT_AREA_SRC:
|
||||||
|
case TARGET_GAMEOBJECT_AREA_DST:
|
||||||
|
radius = GetSpellRadius(m_spellInfo, i, true);
|
||||||
|
targetType = SPELL_TARGETS_GO;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
radius = GetSpellRadius(m_spellInfo, i, true);
|
radius = GetSpellRadius(m_spellInfo, i, true);
|
||||||
targetType = SPELL_TARGETS_NONE;
|
targetType = SPELL_TARGETS_NONE;
|
||||||
@@ -2339,169 +2373,170 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
|||||||
radius *= m_spellValue->RadiusMod;
|
radius *= m_spellValue->RadiusMod;
|
||||||
|
|
||||||
std::list<Unit*> unitList;
|
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);
|
case SPELL_TARGETS_ENTRY:
|
||||||
if (conditions.empty())
|
|
||||||
{
|
{
|
||||||
// Custom entries
|
ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
|
||||||
// TODO: move these to sql
|
if (!conditions.empty())
|
||||||
switch (m_spellInfo->Id)
|
|
||||||
{
|
{
|
||||||
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())
|
for (Unit::ControlList::iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
|
||||||
{
|
if ((*itr)->GetEntry() == (*i_spellST)->mConditionValue2 &&
|
||||||
case TYPEID_UNIT:
|
/*(*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)
|
||||||
m_targets.setDst(result);
|
unitList.push_back(*itr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// Corpse Explosion
|
}
|
||||||
case 49158:
|
else
|
||||||
case 51325:
|
{
|
||||||
case 51326:
|
// Custom entries
|
||||||
case 51327:
|
// TODO: move these to sql
|
||||||
case 51328:
|
switch (m_spellInfo->Id)
|
||||||
// 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()
|
case 46584: // Raise Dead
|
||||||
|| (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();
|
if (WorldObject* result = FindCorpseUsing<Trinity::RaiseDeadObjectCheck> ())
|
||||||
|
|
||||||
WorldObject* result = FindCorpseUsing <Trinity::ExplodeCorpseObjectCheck> ();
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
{
|
{
|
||||||
switch (result->GetTypeId())
|
switch(result->GetTypeId())
|
||||||
{
|
{
|
||||||
case TYPEID_UNIT:
|
case TYPEID_UNIT:
|
||||||
case TYPEID_PLAYER:
|
m_targets.setDst(result);
|
||||||
m_targets.setUnitTarget((Unit*)result);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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
|
else
|
||||||
{
|
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
}
|
||||||
m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id,true);
|
}
|
||||||
SendCastResult(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
|
break;
|
||||||
finish(false);
|
}
|
||||||
}
|
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;
|
break;
|
||||||
|
case TARGET_UNIT_PARTY_TARGET:
|
||||||
default:
|
m_targets.getUnitTarget()->GetPartyMemberInDist(unitList, radius);
|
||||||
sLog.outDebug("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
|
break;
|
||||||
|
case TARGET_UNIT_PARTY_CASTER:
|
||||||
if (m_spellInfo->Effect[i] == SPELL_EFFECT_TELEPORT_UNITS)
|
m_caster->GetPartyMemberInDist(unitList, radius);
|
||||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, 0);
|
break;
|
||||||
else if (IsPositiveEffect(m_spellInfo->Id, i))
|
case TARGET_UNIT_RAID_CASTER:
|
||||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ALLY);
|
m_caster->GetRaidMember(unitList, radius);
|
||||||
else
|
break;
|
||||||
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
|
case TARGET_UNIT_CLASS_TARGET:
|
||||||
}
|
|
||||||
}
|
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
for (Unit::ControlList::iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
|
Player* targetPlayer = m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER
|
||||||
if ((*itr)->GetEntry() == (*i_spellST)->mConditionValue2 &&
|
? (Player*)m_targets.getUnitTarget() : NULL;
|
||||||
/*(*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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Trinity::GameObjectInRangeCheck check(x, y, z, radius + 50);
|
Group* pGroup = targetPlayer ? targetPlayer->GetGroup() : NULL;
|
||||||
std::list<GameObject*> goList;
|
if (pGroup)
|
||||||
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())
|
|
||||||
{
|
{
|
||||||
Player* Target = itr->getSource();
|
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||||
|
|
||||||
// IsHostileTo check duel and controlled by enemy
|
|
||||||
if (Target && targetPlayer->IsWithinDistInMap(Target, radius) &&
|
|
||||||
targetPlayer->getClass() == Target->getClass() &&
|
|
||||||
!m_caster->IsHostileTo(Target))
|
|
||||||
{
|
{
|
||||||
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())
|
if (!unitList.empty())
|
||||||
{
|
{
|
||||||
@@ -2625,7 +2660,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
|||||||
|
|
||||||
if (m_spellInfo->Id == 5246) //Intimidating Shout
|
if (m_spellInfo->Id == 5246) //Intimidating Shout
|
||||||
unitList.remove(m_targets.getUnitTarget());
|
unitList.remove(m_targets.getUnitTarget());
|
||||||
Trinity::RandomResizeList(unitList, m_spellValue->MaxAffectedTargets);
|
Trinity::RandomResizeList(unitList, maxTargets);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2671,6 +2706,21 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
|||||||
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
|
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
|
||||||
AddUnitTarget(*itr, i);
|
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_ENTRY,
|
||||||
SPELL_TARGETS_CHAINHEAL,
|
SPELL_TARGETS_CHAINHEAL,
|
||||||
SPELL_TARGETS_ANY,
|
SPELL_TARGETS_ANY,
|
||||||
|
SPELL_TARGETS_GO
|
||||||
};
|
};
|
||||||
|
|
||||||
class Spell
|
class Spell
|
||||||
@@ -645,6 +646,7 @@ class Spell
|
|||||||
void DoAllEffectOnTarget(ItemTargetInfo *target);
|
void DoAllEffectOnTarget(ItemTargetInfo *target);
|
||||||
bool UpdateChanneledTargetList();
|
bool UpdateChanneledTargetList();
|
||||||
void SearchAreaTarget(std::list<Unit*> &unitList, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry = 0);
|
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);
|
void SearchChainTarget(std::list<Unit*> &unitList, float radius, uint32 unMaxTargets, SpellTargets TargetType);
|
||||||
WorldObject* SearchNearbyTarget(float range, SpellTargets TargetType);
|
WorldObject* SearchNearbyTarget(float range, SpellTargets TargetType);
|
||||||
bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;
|
bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;
|
||||||
|
|||||||
@@ -145,14 +145,14 @@ SpellMgr::SpellMgr()
|
|||||||
case TARGET_UNIT_AREA_ALLY_SRC:
|
case TARGET_UNIT_AREA_ALLY_SRC:
|
||||||
case TARGET_UNIT_AREA_ENTRY_SRC:
|
case TARGET_UNIT_AREA_ENTRY_SRC:
|
||||||
case TARGET_UNIT_AREA_PARTY_SRC:
|
case TARGET_UNIT_AREA_PARTY_SRC:
|
||||||
case TARGET_OBJECT_AREA_SRC:
|
case TARGET_GAMEOBJECT_AREA_SRC:
|
||||||
SpellTargetType[i] = TARGET_TYPE_AREA_SRC;
|
SpellTargetType[i] = TARGET_TYPE_AREA_SRC;
|
||||||
break;
|
break;
|
||||||
case TARGET_UNIT_AREA_ENEMY_DST:
|
case TARGET_UNIT_AREA_ENEMY_DST:
|
||||||
case TARGET_UNIT_AREA_ALLY_DST:
|
case TARGET_UNIT_AREA_ALLY_DST:
|
||||||
case TARGET_UNIT_AREA_ENTRY_DST:
|
case TARGET_UNIT_AREA_ENTRY_DST:
|
||||||
case TARGET_UNIT_AREA_PARTY_DST:
|
case TARGET_UNIT_AREA_PARTY_DST:
|
||||||
case TARGET_OBJECT_AREA_DST:
|
case TARGET_GAMEOBJECT_AREA_DST:
|
||||||
SpellTargetType[i] = TARGET_TYPE_AREA_DST;
|
SpellTargetType[i] = TARGET_TYPE_AREA_DST;
|
||||||
break;
|
break;
|
||||||
case TARGET_UNIT_CONE_ENEMY:
|
case TARGET_UNIT_CONE_ENEMY:
|
||||||
|
|||||||
Reference in New Issue
Block a user