mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
[11793] Add more features to SelectAttackingTarget
Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
This commit is contained in:
parent
6baf677a63
commit
0eff04c161
6 changed files with 98 additions and 32 deletions
|
|
@ -2027,40 +2027,101 @@ void Creature::SetInCombatWithZone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* Creature::SelectAttackingTarget(AttackingTarget target, uint32 position) const
|
bool Creature::MeetsSelectAttackingRequirement(Unit* pTarget, SpellEntry const* pSpellInfo, uint32 selectFlags) const
|
||||||
|
{
|
||||||
|
if (selectFlags & SELECT_FLAG_PLAYER && pTarget->GetTypeId() != TYPEID_PLAYER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (selectFlags & SELECT_FLAG_POWER_MANA && pTarget->getPowerType() != POWER_MANA)
|
||||||
|
return false;
|
||||||
|
else if (selectFlags & SELECT_FLAG_POWER_RAGE && pTarget->getPowerType() != POWER_RAGE)
|
||||||
|
return false;
|
||||||
|
else if (selectFlags & SELECT_FLAG_POWER_ENERGY && pTarget->getPowerType() != POWER_ENERGY)
|
||||||
|
return false;
|
||||||
|
else if (selectFlags & SELECT_FLAG_POWER_RUNIC && pTarget->getPowerType() != POWER_RUNIC_POWER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (selectFlags & SELECT_FLAG_IN_MELEE_RANGE && !CanReachWithMeleeAttack(pTarget))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (selectFlags & SELECT_FLAG_IN_LOS && !IsWithinLOSInMap(pTarget))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (pSpellInfo)
|
||||||
|
{
|
||||||
|
switch (pSpellInfo->rangeIndex)
|
||||||
|
{
|
||||||
|
case SPELL_RANGE_IDX_SELF_ONLY: return false;
|
||||||
|
case SPELL_RANGE_IDX_ANYWHERE: return true;
|
||||||
|
case SPELL_RANGE_IDX_COMBAT: return CanReachWithMeleeAttack(pTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(pSpellInfo->rangeIndex);
|
||||||
|
float max_range = GetSpellMaxRange(srange);
|
||||||
|
float min_range = GetSpellMinRange(srange);
|
||||||
|
float dist = GetCombatDistance(pTarget);
|
||||||
|
|
||||||
|
return dist < max_range && dist >= min_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* Creature::SelectAttackingTarget(AttackingTarget target, uint32 position, uint32 uiSpellEntry, uint32 selectFlags) const
|
||||||
|
{
|
||||||
|
return SelectAttackingTarget(target, position, sSpellStore.LookupEntry(uiSpellEntry), selectFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* Creature::SelectAttackingTarget(AttackingTarget target, uint32 position, SpellEntry const* pSpellInfo /*= NULL*/, uint32 selectFlags/*= 0*/) const
|
||||||
{
|
{
|
||||||
if (!CanHaveThreatList())
|
if (!CanHaveThreatList())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
//ThreatList m_threatlist;
|
// ThreatList m_threatlist;
|
||||||
ThreatList const& threatlist = getThreatManager().getThreatList();
|
ThreatList const& threatlist = getThreatManager().getThreatList();
|
||||||
ThreatList::const_iterator i = threatlist.begin();
|
ThreatList::const_iterator itr = threatlist.begin();
|
||||||
ThreatList::const_reverse_iterator r = threatlist.rbegin();
|
ThreatList::const_reverse_iterator ritr = threatlist.rbegin();
|
||||||
|
|
||||||
if (position >= threatlist.size() || !threatlist.size())
|
if (position >= threatlist.size() || !threatlist.size())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch(target)
|
switch (target)
|
||||||
{
|
{
|
||||||
case ATTACKING_TARGET_RANDOM:
|
case ATTACKING_TARGET_RANDOM:
|
||||||
{
|
{
|
||||||
advance(i, position + (rand() % (threatlist.size() - position)));
|
std::vector<Unit*> suitableUnits;
|
||||||
return GetMap()->GetUnit((*i)->getUnitGuid());
|
suitableUnits.reserve(threatlist.size() - position);
|
||||||
|
advance(itr, position);
|
||||||
|
for (itr; itr != threatlist.end(); ++itr)
|
||||||
|
if (Unit* pTarget = GetMap()->GetUnit((*itr)->getUnitGuid()))
|
||||||
|
if (!selectFlags || MeetsSelectAttackingRequirement(pTarget, pSpellInfo, selectFlags))
|
||||||
|
suitableUnits.push_back(pTarget);
|
||||||
|
|
||||||
|
if (!suitableUnits.empty())
|
||||||
|
return suitableUnits[urand(0, suitableUnits.size()-1)];
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case ATTACKING_TARGET_TOPAGGRO:
|
case ATTACKING_TARGET_TOPAGGRO:
|
||||||
{
|
{
|
||||||
advance(i, position);
|
advance(itr, position);
|
||||||
return GetMap()->GetUnit((*i)->getUnitGuid());
|
for (itr; itr != threatlist.end(); ++itr)
|
||||||
|
if (Unit* pTarget = GetMap()->GetUnit((*itr)->getUnitGuid()))
|
||||||
|
if (!selectFlags || MeetsSelectAttackingRequirement(pTarget, pSpellInfo, selectFlags))
|
||||||
|
return pTarget;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case ATTACKING_TARGET_BOTTOMAGGRO:
|
case ATTACKING_TARGET_BOTTOMAGGRO:
|
||||||
{
|
{
|
||||||
advance(r, position);
|
advance(ritr, position);
|
||||||
return GetMap()->GetUnit((*r)->getUnitGuid());
|
for (ritr; ritr != threatlist.rend(); ++ritr)
|
||||||
|
if (Unit* pTarget = GetMap()->GetUnit((*itr)->getUnitGuid()))
|
||||||
|
if (!selectFlags || MeetsSelectAttackingRequirement(pTarget, pSpellInfo, selectFlags))
|
||||||
|
return pTarget;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// TODO: implement these
|
|
||||||
//case ATTACKING_TARGET_RANDOM_PLAYER:
|
|
||||||
//case ATTACKING_TARGET_TOPAGGRO_PLAYER:
|
|
||||||
//case ATTACKING_TARGET_BOTTOMAGGRO_PLAYER:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -288,11 +288,17 @@ enum AttackingTarget
|
||||||
ATTACKING_TARGET_RANDOM = 0, //Just selects a random target
|
ATTACKING_TARGET_RANDOM = 0, //Just selects a random target
|
||||||
ATTACKING_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom
|
ATTACKING_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom
|
||||||
ATTACKING_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top
|
ATTACKING_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top
|
||||||
/* not implemented
|
};
|
||||||
ATTACKING_TARGET_RANDOM_PLAYER, //Just selects a random target (player only)
|
|
||||||
ATTACKING_TARGET_TOPAGGRO_PLAYER, //Selects targes from top aggro to bottom (player only)
|
enum SelectFlags
|
||||||
ATTACKING_TARGET_BOTTOMAGGRO_PLAYER, //Selects targets from bottom aggro to top (player only)
|
{
|
||||||
*/
|
SELECT_FLAG_IN_LOS = 0x001, // Default Selection Requirement for Spell-targets
|
||||||
|
SELECT_FLAG_PLAYER = 0x002,
|
||||||
|
SELECT_FLAG_POWER_MANA = 0x004, // For Energy based spells, like manaburn
|
||||||
|
SELECT_FLAG_POWER_RAGE = 0x008,
|
||||||
|
SELECT_FLAG_POWER_ENERGY = 0x010,
|
||||||
|
SELECT_FLAG_POWER_RUNIC = 0x020,
|
||||||
|
SELECT_FLAG_IN_MELEE_RANGE = 0x040,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vendors
|
// Vendors
|
||||||
|
|
@ -651,7 +657,8 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
||||||
|
|
||||||
void SetInCombatWithZone();
|
void SetInCombatWithZone();
|
||||||
|
|
||||||
Unit* SelectAttackingTarget(AttackingTarget target, uint32 position) const;
|
Unit* SelectAttackingTarget(AttackingTarget target, uint32 position, uint32 uiSpellEntry, uint32 selectFlags = 0) const;
|
||||||
|
Unit* SelectAttackingTarget(AttackingTarget target, uint32 position, SpellEntry const* pSpellInfo = NULL, uint32 selectFlags = 0) const;
|
||||||
|
|
||||||
bool HasQuest(uint32 quest_id) const;
|
bool HasQuest(uint32 quest_id) const;
|
||||||
bool HasInvolvedQuest(uint32 quest_id) const;
|
bool HasInvolvedQuest(uint32 quest_id) const;
|
||||||
|
|
@ -686,6 +693,8 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
||||||
void SetVirtualItem(VirtualItemSlot slot, uint32 item_id) { SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot, item_id); }
|
void SetVirtualItem(VirtualItemSlot slot, uint32 item_id) { SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot, item_id); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool MeetsSelectAttackingRequirement(Unit* pTarget, SpellEntry const* pSpellInfo, uint32 selectFlags) const;
|
||||||
|
|
||||||
bool CreateFromProto(uint32 guidlow, CreatureInfo const* cinfo, Team team, const CreatureData *data = NULL, GameEventCreatureData const* eventData =NULL);
|
bool CreateFromProto(uint32 guidlow, CreatureInfo const* cinfo, Team team, const CreatureData *data = NULL, GameEventCreatureData const* eventData =NULL);
|
||||||
bool InitEntry(uint32 entry, const CreatureData* data = NULL, GameEventCreatureData const* eventData = NULL);
|
bool InitEntry(uint32 entry, const CreatureData* data = NULL, GameEventCreatureData const* eventData = NULL);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1304,6 +1304,7 @@ enum SpellRangeIndex
|
||||||
{
|
{
|
||||||
SPELL_RANGE_IDX_SELF_ONLY = 1, // 0.0
|
SPELL_RANGE_IDX_SELF_ONLY = 1, // 0.0
|
||||||
SPELL_RANGE_IDX_COMBAT = 2, // 5.5 (but dynamic)
|
SPELL_RANGE_IDX_COMBAT = 2, // 5.5 (but dynamic)
|
||||||
|
SPELL_RANGE_IDX_ANYWHERE = 13, // 500000 (anywhere)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DamageEffectType
|
enum DamageEffectType
|
||||||
|
|
|
||||||
|
|
@ -5981,7 +5981,9 @@ SpellCastResult Spell::CheckRange(bool strict)
|
||||||
switch(m_spellInfo->rangeIndex)
|
switch(m_spellInfo->rangeIndex)
|
||||||
{
|
{
|
||||||
// self cast doesn't need range checking -- also for Starshards fix
|
// self cast doesn't need range checking -- also for Starshards fix
|
||||||
|
// spells that can be cast anywhere also need no check
|
||||||
case SPELL_RANGE_IDX_SELF_ONLY:
|
case SPELL_RANGE_IDX_SELF_ONLY:
|
||||||
|
case SPELL_RANGE_IDX_ANYWHERE:
|
||||||
return SPELL_CAST_OK;
|
return SPELL_CAST_OK;
|
||||||
// combat range spells are treated differently
|
// combat range spells are treated differently
|
||||||
case SPELL_RANGE_IDX_COMBAT:
|
case SPELL_RANGE_IDX_COMBAT:
|
||||||
|
|
|
||||||
|
|
@ -1080,18 +1080,11 @@ void Aura::TriggerSpell()
|
||||||
{
|
{
|
||||||
trigger_spell_id = 25779; // Mana Burn
|
trigger_spell_id = 25779; // Mana Burn
|
||||||
|
|
||||||
// expected selection current fight target
|
if (GetTarget()->GetTypeId() != TYPEID_UNIT)
|
||||||
triggerTarget = GetTarget()->getVictim();
|
|
||||||
if (!triggerTarget || triggerTarget->GetMaxPower(POWER_MANA) <= 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
|
triggerTarget = ((Creature*)GetTarget())->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0, trigger_spell_id, SELECT_FLAG_POWER_MANA);
|
||||||
if (!triggeredSpellInfo)
|
if (!triggerTarget)
|
||||||
return;
|
|
||||||
|
|
||||||
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex);
|
|
||||||
float max_range = GetSpellMaxRange(srange);
|
|
||||||
if (!triggerTarget->IsWithinDist(GetTarget(),max_range))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11792"
|
#define REVISION_NR "11793"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue