aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells
diff options
context:
space:
mode:
authorTraesh <Traesh@users.noreply.github.com>2021-08-15 11:09:46 +0200
committerGitHub <noreply@github.com>2021-08-15 11:09:46 +0200
commitfb6761c273d518eae6bab72fc9c2a2b6f93eec83 (patch)
treec2dc8907691bf0da898a62448058df38892d9333 /src/server/game/Spells
parent4725941567f9dae583fc27b52b51a23aa84cd098 (diff)
Core/Spells Implement targets 133, 134, 135 : TARGET_UNIT_LINE_CASTER_TO_DEST_*** (#26786)
Diffstat (limited to 'src/server/game/Spells')
-rw-r--r--src/server/game/Spells/Spell.cpp83
-rw-r--r--src/server/game/Spells/Spell.h11
-rw-r--r--src/server/game/Spells/SpellInfo.cpp6
-rw-r--r--src/server/game/Spells/SpellInfo.h3
-rw-r--r--src/server/game/Spells/SpellMgr.cpp3
-rw-r--r--src/server/game/Spells/SpellScript.cpp1
6 files changed, 103 insertions, 4 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index b62aaf65bc0..d5454d9065e 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -852,6 +852,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
case TARGET_SELECT_CATEGORY_NEARBY:
case TARGET_SELECT_CATEGORY_CONE:
case TARGET_SELECT_CATEGORY_AREA:
+ case TARGET_SELECT_CATEGORY_LINE:
// targets for effect already selected
if (effectMask & processedEffectMask)
return;
@@ -900,6 +901,9 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
SelectImplicitTrajTargets(effIndex, targetType);
break;
+ case TARGET_SELECT_CATEGORY_LINE:
+ SelectImplicitLineTargets(effIndex, targetType, effectMask);
+ break;
case TARGET_SELECT_CATEGORY_DEFAULT:
switch (targetType.GetObjectType())
{
@@ -1731,6 +1735,69 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTarge
veh->SetLastShootPos(*m_targets.GetDstPos());
}
+void Spell::SelectImplicitLineTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
+{
+ std::list<WorldObject*> targets;
+ SpellTargetObjectTypes objectType = targetType.GetObjectType();
+ SpellTargetCheckTypes selectionType = targetType.GetCheckType();
+ SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex);
+ if (!effect)
+ return;
+
+ Position const* dst = nullptr;
+ switch (targetType.GetReferenceType())
+ {
+ case TARGET_REFERENCE_TYPE_SRC:
+ dst = m_targets.GetSrcPos();
+ break;
+ case TARGET_REFERENCE_TYPE_DEST:
+ dst = m_targets.GetDstPos();
+ break;
+ case TARGET_REFERENCE_TYPE_CASTER:
+ dst = m_caster;
+ break;
+ case TARGET_REFERENCE_TYPE_TARGET:
+ dst = m_targets.GetUnitTarget();
+ break;
+ default:
+ ASSERT(false, "Spell::SelectImplicitLineTargets: received not implemented target reference type");
+ return;
+ }
+
+ ConditionContainer* condList = effect->ImplicitTargetConditions;
+ float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
+
+ if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
+ {
+ Trinity::WorldObjectSpellLineTargetCheck check(m_caster, dst, m_spellInfo->Width ? m_spellInfo->Width : m_caster->GetCombatReach(), radius, m_caster, m_spellInfo, selectionType, condList, objectType);
+ Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellLineTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
+ SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellLineTargetCheck>>(searcher, containerTypeMask, m_caster, m_caster, radius);
+
+ CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
+
+ if (!targets.empty())
+ {
+ // Other special target selection goes here
+ if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
+ {
+ if (maxTargets < targets.size())
+ {
+ targets.sort(Trinity::ObjectDistanceOrderPred(m_caster));
+ targets.resize(maxTargets);
+ }
+ }
+
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ {
+ if (Unit* unit = (*itr)->ToUnit())
+ AddUnitTarget(unit, effMask, false);
+ else if (GameObject* gObjTarget = (*itr)->ToGameObject())
+ AddGOTarget(gObjTarget, effMask);
+ }
+ }
+ }
+}
+
void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex)
{
// special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
@@ -8181,6 +8248,22 @@ bool WorldObjectSpellTrajTargetCheck::operator()(WorldObject* target)
return WorldObjectSpellTargetCheck::operator ()(target);
}
+WorldObjectSpellLineTargetCheck::WorldObjectSpellLineTargetCheck(Position const* srcPosition, Position const* dstPosition, float lineWidth, float range, Unit* caster,
+ SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType)
+ : WorldObjectSpellAreaTargetCheck(range, caster, caster, caster, spellInfo, selectionType, condList, objectType), _srcPosition(srcPosition), _dstPosition(dstPosition), _lineWidth(lineWidth) { }
+
+bool WorldObjectSpellLineTargetCheck::operator()(WorldObject* target)
+{
+ float angle = _caster->GetOrientation();
+ if (*_srcPosition != *_dstPosition)
+ angle = _srcPosition->GetAngle(_dstPosition);
+
+ if (!_caster->HasInLine(target, target->GetCombatReach(), _lineWidth, angle))
+ return false;
+
+ return WorldObjectSpellTargetCheck::operator ()(target);
+}
+
} //namespace Trinity
SpellCastVisual::operator UF::SpellCastVisual() const
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index cce4c750358..adaa408b65c 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -513,6 +513,7 @@ class TC_GAME_API Spell
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask);
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitLineTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask);
void SelectEffectTypeImplicitTargets(uint32 effIndex);
@@ -966,6 +967,16 @@ namespace Trinity
SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType);
bool operator()(WorldObject* target);
};
+
+ struct TC_GAME_API WorldObjectSpellLineTargetCheck : public WorldObjectSpellAreaTargetCheck
+ {
+ Position const* _srcPosition;
+ Position const* _dstPosition;
+ float _lineWidth;
+ WorldObjectSpellLineTargetCheck(Position const* srcPosition, Position const* dstPosition, float lineWidth, float range, Unit* caster,
+ SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType);
+ bool operator()(WorldObject* target);
+ };
}
typedef void(Spell::*pEffect)(SpellEffIndex effIndex);
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 9bca5fcf1c0..bbde23941f9 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -350,9 +350,9 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_
{TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 130
{TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 131 TARGET_DEST_SUMMONER
{TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 132 TARGET_DEST_TARGET_ALLY
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 133
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 134
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 135
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_LINE, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 133 TARGET_UNIT_LINE_CASTER_TO_DEST_ALLY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_LINE, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 134 TARGET_UNIT_LINE_CASTER_TO_DEST_ENEMY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_LINE, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 135 TARGET_UNIT_LINE_CASTER_TO_DEST
{TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 136
{TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 137
{TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 138
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 9e4265efac9..f4bd559d494 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -86,7 +86,8 @@ enum SpellTargetSelectionCategories
TARGET_SELECT_CATEGORY_NEARBY,
TARGET_SELECT_CATEGORY_CONE,
TARGET_SELECT_CATEGORY_AREA,
- TARGET_SELECT_CATEGORY_TRAJ
+ TARGET_SELECT_CATEGORY_TRAJ,
+ TARGET_SELECT_CATEGORY_LINE
};
enum SpellTargetReferenceTypes
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index c7df86abfe5..8422ff6360c 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -4553,6 +4553,9 @@ void SpellMgr::LoadSpellInfoCorrections()
if (spellInfo->ActiveIconFileDataId == 135754) // flight
spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
+
+ if (spellInfo->IsSingleTarget())
+ spellInfo->MaxAffectedTargets = 1;
}
if (SummonPropertiesEntry* properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(121)))
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 29d559cf0be..7213776011f 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -286,6 +286,7 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff
return true;
case TARGET_SELECT_CATEGORY_CONE: // AREA
case TARGET_SELECT_CATEGORY_AREA: // AREA
+ case TARGET_SELECT_CATEGORY_LINE: // AREA
return area;
case TARGET_SELECT_CATEGORY_DEFAULT:
switch (targetInfo.GetObjectType())