fix(Core/Spell): implement SPELL_ATTR5_NOT_ON_PLAYER and SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC (#22332)
This commit is contained in:
@@ -191,8 +191,23 @@ SpellCastResult UnitAI::DoCast(uint32 spellId)
|
|||||||
{
|
{
|
||||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
|
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
|
||||||
{
|
{
|
||||||
bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER);
|
DefaultTargetSelector targetSelector(me, spellInfo->GetMaxRange(false), false, true, 0);
|
||||||
target = SelectTarget(SelectTargetMethod::Random, 0, spellInfo->GetMaxRange(false), playerOnly);
|
target = SelectTarget(SelectTargetMethod::Random, 0, [&](Unit* target) {
|
||||||
|
if (target->IsPlayer())
|
||||||
|
{
|
||||||
|
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && target->IsControlledByPlayer())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return targetSelector(target);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -206,12 +221,27 @@ SpellCastResult UnitAI::DoCast(uint32 spellId)
|
|||||||
{
|
{
|
||||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
|
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
|
||||||
{
|
{
|
||||||
bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER);
|
|
||||||
float range = spellInfo->GetMaxRange(false);
|
float range = spellInfo->GetMaxRange(false);
|
||||||
|
|
||||||
DefaultTargetSelector targetSelector(me, range, playerOnly, true, -(int32)spellId);
|
DefaultTargetSelector defaultTargetSelector(me, range, false, true, -(int32)spellId);
|
||||||
if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM)
|
auto targetSelector = [&](Unit* target) {
|
||||||
&& targetSelector(me->GetVictim()))
|
if (target->IsPlayer())
|
||||||
|
{
|
||||||
|
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && target->IsControlledByPlayer())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return defaultTargetSelector(target);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM) && targetSelector(me->GetVictim()))
|
||||||
target = me->GetVictim();
|
target = me->GetVictim();
|
||||||
else
|
else
|
||||||
target = SelectTarget(SelectTargetMethod::Random, 0, targetSelector);
|
target = SelectTarget(SelectTargetMethod::Random, 0, targetSelector);
|
||||||
|
|||||||
@@ -2147,6 +2147,8 @@ uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList*
|
|||||||
retMask &= GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_PLAYER;
|
retMask &= GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_PLAYER;
|
||||||
if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_GHOSTS))
|
if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_GHOSTS))
|
||||||
retMask &= GRID_MAP_TYPE_MASK_PLAYER;
|
retMask &= GRID_MAP_TYPE_MASK_PLAYER;
|
||||||
|
if (m_spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||||
|
retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
|
||||||
|
|
||||||
if (condList)
|
if (condList)
|
||||||
retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
|
retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
|
||||||
|
|||||||
@@ -1863,9 +1863,20 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
|
|||||||
else return SPELL_CAST_OK;
|
else return SPELL_CAST_OK;
|
||||||
|
|
||||||
// corpseOwner and unit specific target checks
|
// corpseOwner and unit specific target checks
|
||||||
if (AttributesEx3 & SPELL_ATTR3_ONLY_ON_PLAYER && !unitTarget->ToPlayer())
|
if (unitTarget->IsPlayer())
|
||||||
|
{
|
||||||
|
if (HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
|
||||||
|
return SPELL_FAILED_TARGET_IS_PLAYER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
|
||||||
return SPELL_FAILED_TARGET_NOT_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;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
|
if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
|
||||||
return SPELL_FAILED_TARGETS_DEAD;
|
return SPELL_FAILED_TARGETS_DEAD;
|
||||||
|
|
||||||
|
|||||||
@@ -571,7 +571,7 @@ enum SpellAttr5 : uint32
|
|||||||
SPELL_ATTR5_TRIGGERS_CHANNELING = 0x00000010, // TITLE Unknown attribute 4@Attr5
|
SPELL_ATTR5_TRIGGERS_CHANNELING = 0x00000010, // TITLE Unknown attribute 4@Attr5
|
||||||
SPELL_ATTR5_LIMIT_N = 0x00000020, // TITLE Single-target aura DESCRIPTION Remove previous application to another unit if applied
|
SPELL_ATTR5_LIMIT_N = 0x00000020, // TITLE Single-target aura DESCRIPTION Remove previous application to another unit if applied
|
||||||
SPELL_ATTR5_IGNORE_AREA_EFFECT_PVP_CHECK = 0x00000040, // TITLE Unknown attribute 6@Attr5
|
SPELL_ATTR5_IGNORE_AREA_EFFECT_PVP_CHECK = 0x00000040, // TITLE Unknown attribute 6@Attr5
|
||||||
SPELL_ATTR5_NOT_ON_PLAYER = 0x00000080, // TITLE Unknown attribute 7@Attr5
|
SPELL_ATTR5_NOT_ON_PLAYER = 0x00000080, // TITLE Cannot target players
|
||||||
SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC = 0x00000100, // TITLE Cannot target player controlled units but can target players
|
SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC = 0x00000100, // TITLE Cannot target player controlled units but can target players
|
||||||
SPELL_ATTR5_EXTRA_INITIAL_PERIOD = 0x00000200, // TITLE Immediately do periodic tick on apply
|
SPELL_ATTR5_EXTRA_INITIAL_PERIOD = 0x00000200, // TITLE Immediately do periodic tick on apply
|
||||||
SPELL_ATTR5_DO_NOT_DISPLAY_DURATION = 0x00000400, // TITLE Do not send aura duration to client
|
SPELL_ATTR5_DO_NOT_DISPLAY_DURATION = 0x00000400, // TITLE Do not send aura duration to client
|
||||||
|
|||||||
Reference in New Issue
Block a user