Core/Spells: Implemented SPELL_ATTR5_NOT_ON_PLAYER and SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC
This commit is contained in:
1 parent
86fbfb77f4
commit
8fa4b57925
5 files changed
+59
-20
No files matched your search
@@ -133,8 +133,23 @@ SpellCastResult UnitAI::DoCast(uint32 spellId)
|
||||
{
|
||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
|
||||
{
|
||||
bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER);
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0, spellInfo->GetMaxRange(false), playerOnly);
|
||||
DefaultTargetSelector targetSelectorInner(me, spellInfo->GetMaxRange(false), false, true, 0);
|
||||
auto targetSelector = [&](Unit const* candidate) -> bool
|
||||
{
|
||||
if (!candidate->IsPlayer())
|
||||
{
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
|
||||
return false;
|
||||
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && candidate->IsControlledByPlayer())
|
||||
return false;
|
||||
}
|
||||
else if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||
return false;
|
||||
|
||||
return targetSelectorInner(candidate);
|
||||
};
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0, targetSelector);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -148,10 +163,24 @@ SpellCastResult UnitAI::DoCast(uint32 spellId)
|
||||
{
|
||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
|
||||
{
|
||||
bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER);
|
||||
float range = spellInfo->GetMaxRange(false);
|
||||
|
||||
DefaultTargetSelector targetSelector(me, range, playerOnly, true, -(int32)spellId);
|
||||
DefaultTargetSelector targetSelectorInner(me, range, false, true, -(int32)spellId);
|
||||
auto targetSelector = [&](Unit const* candidate) -> bool
|
||||
{
|
||||
if (!candidate->IsPlayer())
|
||||
{
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
|
||||
return false;
|
||||
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && candidate->IsControlledByPlayer())
|
||||
return false;
|
||||
}
|
||||
else if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||
return false;
|
||||
|
||||
return targetSelectorInner(candidate);
|
||||
};
|
||||
if (!spellInfo->HasAuraInterruptFlag(SpellAuraInterruptFlags::NOT_VICTIM) && targetSelector(me->GetVictim()))
|
||||
target = me->GetVictim();
|
||||
else
|
||||
|
||||
@@ -1065,23 +1065,26 @@ namespace Trinity
|
||||
AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr, bool incOwnRadius = true, bool incTargetRadius = true)
|
||||
: i_obj(obj), i_funit(funit), _spellInfo(spellInfo), i_range(range), i_incOwnRadius(incOwnRadius), i_incTargetRadius(incTargetRadius)
|
||||
{
|
||||
Unit const* check = i_funit;
|
||||
Unit const* owner = i_funit->GetOwner();
|
||||
if (owner)
|
||||
check = owner;
|
||||
i_targetForPlayer = (check->GetTypeId() == TYPEID_PLAYER);
|
||||
}
|
||||
bool operator()(Unit* u)
|
||||
{
|
||||
// Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems
|
||||
// Check contains checks for: live, uninteractible, non-attackable flags, flight check and GM check, ignore totems
|
||||
if (u->GetTypeId() == TYPEID_UNIT && u->IsTotem())
|
||||
return false;
|
||||
|
||||
if (_spellInfo && _spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER) && u->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
if (_spellInfo)
|
||||
{
|
||||
if (!u->IsPlayer())
|
||||
{
|
||||
if (_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
|
||||
return false;
|
||||
|
||||
if (_spellInfo && _spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER) && u->GetTypeId() == TYPEID_PLAYER)
|
||||
return false;
|
||||
if (_spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && u->IsControlledByPlayer())
|
||||
return false;
|
||||
}
|
||||
else if (_spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!i_funit->IsValidAttackTarget(u, _spellInfo))
|
||||
return false;
|
||||
@@ -1095,7 +1098,6 @@ namespace Trinity
|
||||
return u->IsInMap(i_obj) && u->IsInPhase(i_obj) && u->IsWithinDoubleVerticalCylinder(i_obj, searchRadius, searchRadius);
|
||||
}
|
||||
private:
|
||||
bool i_targetForPlayer;
|
||||
WorldObject const* i_obj;
|
||||
Unit const* i_funit;
|
||||
SpellInfo const* _spellInfo;
|
||||
|
||||
@@ -541,8 +541,8 @@ enum SpellAttr5 : uint32
|
||||
SPELL_ATTR5_TRIGGERS_CHANNELING = 0x00000010, // TITLE Triggers Channeling
|
||||
SPELL_ATTR5_LIMIT_N = 0x00000020, // TITLE Limit N DESCRIPTION Remove previous application to another unit if applied
|
||||
SPELL_ATTR5_IGNORE_AREA_EFFECT_PVP_CHECK = 0x00000040, // TITLE Ignore Area Effect PvP Check
|
||||
SPELL_ATTR5_NOT_ON_PLAYER = 0x00000080, /*NYI*/ // TITLE Not On Player
|
||||
SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC = 0x00000100, /*NYI*/ // TITLE Not On Player Controlled NPC
|
||||
SPELL_ATTR5_NOT_ON_PLAYER = 0x00000080, // TITLE Not On Player
|
||||
SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC = 0x00000100, // TITLE Not On Player Controlled NPC
|
||||
SPELL_ATTR5_EXTRA_INITIAL_PERIOD = 0x00000200, // TITLE Extra Initial Period DESCRIPTION Immediately do periodic tick on apply
|
||||
SPELL_ATTR5_DO_NOT_DISPLAY_DURATION = 0x00000400, // TITLE Do Not Display Duration
|
||||
SPELL_ATTR5_IMPLIED_TARGETING = 0x00000800, // TITLE Implied Targeting (client only)
|
||||
|
||||
@@ -1966,7 +1966,7 @@ uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionConta
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_GHOSTS))
|
||||
retMask &= GRID_MAP_TYPE_MASK_PLAYER;
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||
retMask &= ~(GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_PLAYER);
|
||||
retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
|
||||
|
||||
if (condList)
|
||||
retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
|
||||
|
||||
@@ -1942,8 +1942,16 @@ SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject co
|
||||
else return SPELL_CAST_OK;
|
||||
|
||||
// corpseOwner and unit specific target checks
|
||||
if (HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER) && unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return SPELL_FAILED_TARGET_NOT_PLAYER;
|
||||
if (!unitTarget->IsPlayer())
|
||||
{
|
||||
if (HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
|
||||
return SPELL_FAILED_TARGET_NOT_PLAYER;
|
||||
|
||||
if (HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && unitTarget->IsControlledByPlayer())
|
||||
return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED;
|
||||
}
|
||||
else if (HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||
return SPELL_FAILED_TARGET_IS_PLAYER;
|
||||
|
||||
if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
|
||||
return SPELL_FAILED_TARGETS_DEAD;
|
||||
|
||||
Reference in new issue
Block a user