Core/Spells: Fixed TargetB selectoin after d6ccdbea10

This commit is contained in:
Shauren
2024-04-13 17:19:53 +02:00
parent d6ccdbea10
commit eba78de1ee
2 changed files with 54 additions and 47 deletions

View File

@@ -753,10 +753,53 @@ void Spell::SelectSpellTargets()
if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT);
uint32 currentlyProcessedEffectMask = processedEffectsMaskForSpell;
SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetA, processedEffectsMaskForSpell);
SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetB, processedEffectsMaskForSpell);
currentlyProcessedEffectMask = processedEffectsMaskForSpell & ~currentlyProcessedEffectMask;
uint32 implicitTargetEffectMaskToSelect = [&]
{
uint32 effectMask = 1u << spellEffectInfo.EffectIndex;
// set the same target list for all effects
// some spells appear to need this, however this requires more research
std::array<SpellEffectInfo, MAX_SPELL_EFFECTS> const& effects = GetSpellInfo()->GetEffects();
// choose which targets we can select at once
for (uint32 j = spellEffectInfo.EffectIndex + 1; j < effects.size(); ++j)
{
if (effects[j].IsEffect() &&
spellEffectInfo.TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
spellEffectInfo.TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
spellEffectInfo.ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
CheckScriptEffectImplicitTargets(spellEffectInfo.EffectIndex, j))
{
auto shouldCheckRadius = [](SpellImplicitTargetInfo const& targetInfo)
{
switch (targetInfo.GetSelectionCategory())
{
case TARGET_SELECT_CATEGORY_NEARBY:
case TARGET_SELECT_CATEGORY_CONE:
case TARGET_SELECT_CATEGORY_AREA:
return true;
default:
break;
}
return false;
};
if (shouldCheckRadius(spellEffectInfo.TargetA) || shouldCheckRadius(spellEffectInfo.TargetB))
if (spellEffectInfo.CalcRadius(m_caster) != effects[j].CalcRadius(m_caster))
continue;
effectMask |= 1 << j;
}
}
return effectMask;
}();
implicitTargetEffectMaskToSelect &= ~processedEffectsMaskForSpell;
if (implicitTargetEffectMaskToSelect)
{
SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetA, implicitTargetEffectMaskToSelect);
SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetB, implicitTargetEffectMaskToSelect);
processedEffectsMaskForSpell |= implicitTargetEffectMaskToSelect;
}
// Select targets of effect based on effect type
// those are used when no valid target could be added for spell effect based on spell target type
@@ -768,7 +811,7 @@ void Spell::SelectSpellTargets()
if (m_targets.HasDst())
AddDestTarget(*m_targets.GetDst(), spellEffectInfo.EffectIndex);
if (currentlyProcessedEffectMask
if (implicitTargetEffectMaskToSelect
&& (spellEffectInfo.TargetA.GetObjectType() == TARGET_OBJECT_TYPE_UNIT
|| spellEffectInfo.TargetA.GetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST
|| spellEffectInfo.TargetB.GetObjectType() == TARGET_OBJECT_TYPE_UNIT
@@ -776,9 +819,9 @@ void Spell::SelectSpellTargets()
{
if (m_spellInfo->HasAttribute(SPELL_ATTR1_REQUIRE_ALL_TARGETS))
{
bool noTargetFound = std::ranges::none_of(m_UniqueTargetInfo, [currentlyProcessedEffectMask](TargetInfo const& target)
bool noTargetFound = std::ranges::none_of(m_UniqueTargetInfo, [implicitTargetEffectMaskToSelect](TargetInfo const& target)
{
return target.EffectMask & currentlyProcessedEffectMask;
return target.EffectMask & implicitTargetEffectMaskToSelect;
});
if (noTargetFound)
@@ -790,9 +833,9 @@ void Spell::SelectSpellTargets()
}
if (m_spellInfo->HasAttribute(SPELL_ATTR2_FAIL_ON_ALL_TARGETS_IMMUNE))
{
bool anyNonImmuneTargetFound = std::ranges::any_of(m_UniqueTargetInfo, [currentlyProcessedEffectMask](TargetInfo const& target)
bool anyNonImmuneTargetFound = std::ranges::any_of(m_UniqueTargetInfo, [implicitTargetEffectMaskToSelect](TargetInfo const& target)
{
return target.EffectMask & currentlyProcessedEffectMask && target.MissCondition != SPELL_MISS_IMMUNE && target.MissCondition != SPELL_MISS_IMMUNE2;
return target.EffectMask & implicitTargetEffectMaskToSelect && target.MissCondition != SPELL_MISS_IMMUNE && target.MissCondition != SPELL_MISS_IMMUNE2;
});
if (!anyNonImmuneTargetFound)
@@ -879,47 +922,11 @@ void Spell::RecalculateDelayMomentForDst()
m_caster->m_Events.ModifyEventTime(_spellEvent, Milliseconds(GetDelayStart() + m_delayMoment));
}
void Spell::SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask)
void Spell::SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effectMask)
{
if (!targetType.GetTarget())
return;
uint32 effectMask = 1 << spellEffectInfo.EffectIndex;
// targets for effect already selected
if (effectMask & processedEffectMask)
return;
// set the same target list for all effects
// some spells appear to need this, however this requires more research
std::array<SpellEffectInfo, MAX_SPELL_EFFECTS> const& effects = GetSpellInfo()->GetEffects();
// choose which targets we can select at once
for (uint32 j = spellEffectInfo.EffectIndex + 1; j < effects.size(); ++j)
{
if (effects[j].IsEffect() &&
spellEffectInfo.TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
spellEffectInfo.TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
spellEffectInfo.ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
CheckScriptEffectImplicitTargets(spellEffectInfo.EffectIndex, j))
{
switch (targetType.GetSelectionCategory())
{
case TARGET_SELECT_CATEGORY_NEARBY:
case TARGET_SELECT_CATEGORY_CONE:
case TARGET_SELECT_CATEGORY_AREA:
if (spellEffectInfo.CalcRadius(m_caster) != effects[j].CalcRadius(m_caster))
continue;
break;
default:
break;
}
effectMask |= 1 << j;
}
}
processedEffectMask |= effectMask;
switch (targetType.GetSelectionCategory())
{
case TARGET_SELECT_CATEGORY_CHANNEL:

View File

@@ -287,7 +287,7 @@ class TC_GAME_API Spell
void SelectExplicitTargets();
void SelectSpellTargets();
void SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask);
void SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effectMask);
void SelectImplicitChannelTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);
void SelectImplicitNearbyTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);
void SelectImplicitConeTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);