aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/mmaps_common/Management/MMapManager.cpp86
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.cpp43
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.h12
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
-rw-r--r--src/server/game/Spells/SpellDefines.h2
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp43
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp66
7 files changed, 176 insertions, 78 deletions
diff --git a/src/common/mmaps_common/Management/MMapManager.cpp b/src/common/mmaps_common/Management/MMapManager.cpp
index a45c1ee5fbb..32d77959d6e 100644
--- a/src/common/mmaps_common/Management/MMapManager.cpp
+++ b/src/common/mmaps_common/Management/MMapManager.cpp
@@ -29,8 +29,6 @@ namespace MMAP
constexpr char MAP_FILE_NAME_FORMAT[] = "{}mmaps/{:04}.mmap";
constexpr char TILE_FILE_NAME_FORMAT[] = "{}mmaps/{:04}_{:02}_{:02}.mmtile";
- static thread_local bool thread_safe_environment = false;
-
using NavMeshQuerySet = std::unordered_map<std::pair<uint32, uint32>, dtNavMeshQuery>;
using MMapTileSet = std::unordered_map<uint32, dtTileRef>;
@@ -71,15 +69,18 @@ namespace MMAP
std::pair<MeshDataMap::iterator, bool> GetMeshData(uint32 mapId, uint32 instanceId)
{
- // for maps that won't have dynamic mesh, return 0 to reuse the same mesh across all instances
return meshData.try_emplace(GetInstanceIdForMeshLookup(mapId, instanceId));
}
MeshDataMap::iterator FindMeshData(uint32 mapId, uint32 instanceId)
{
- // for maps that won't have dynamic mesh, return 0 to reuse the same mesh across all instances
return meshData.find(GetInstanceIdForMeshLookup(mapId, instanceId));
}
+
+ MeshDataMap::node_type RemoveMeshData(uint32 mapId, uint32 instanceId)
+ {
+ return meshData.extract(GetInstanceIdForMeshLookup(mapId, instanceId));
+ }
};
// ######################## MMapManager ########################
@@ -97,13 +98,10 @@ namespace MMAP
// the caller must pass the list of all mapIds that will be used in the MMapManager lifetime
for (auto const& [mapId, childMapIds] : mapData)
{
- loadedMMaps[mapId].reset(new MMapData());
+ loadedMMaps.try_emplace(mapId, new MMapData());
for (uint32 childMapId : childMapIds)
parentMapData[childMapId] = mapId;
}
-
- // mark the loading main thread as safe
- thread_safe_environment = true;
}
MMapDataSet::const_iterator MMapManager::GetMMapData(uint32 mapId) const
@@ -124,20 +122,8 @@ namespace MMAP
LoadResult MMapManager::loadMapData(std::string_view basePath, uint32 mapId, uint32 instanceId)
{
// we already have this map loaded?
- MMapDataSet::iterator itr;
- if (thread_safe_environment)
- {
- bool needsLoading;
- std::tie(itr, needsLoading) = loadedMMaps.try_emplace(mapId);
- if (needsLoading)
- itr->second.reset(new MMapData());
- }
- else
- {
- itr = loadedMMaps.find(mapId);
- if (itr == loadedMMaps.end())
- ABORT_MSG("Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId);
- }
+ MMapDataSet::iterator itr = loadedMMaps.find(mapId);
+ ASSERT(itr != loadedMMaps.end(), "Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId);
auto [meshItr, needsLoading] = itr->second->GetMeshData(mapId, instanceId);
if (!needsLoading)
@@ -230,7 +216,7 @@ namespace MMAP
}
// get this mmap data
- MMapData* mmap = loadedMMaps[mapId].get();
+ MMapData* mmap = Trinity::Containers::MapGetValuePtr(loadedMMaps, mapId);
MMapMapData& meshData = mmap->GetMeshData(mapId, instanceId).first->second;
// check if we already have this tile loaded
@@ -327,7 +313,7 @@ namespace MMAP
return false;
}
- MMapData* mmap = loadedMMaps[meshMapId].get();
+ MMapData* mmap = Trinity::Containers::MapGetValuePtr(loadedMMaps, meshMapId);
auto [queryItr, inserted] = mmap->navMeshQueries.try_emplace({ instanceMapId, instanceId });
if (!inserted)
return true;
@@ -340,7 +326,6 @@ namespace MMAP
// allocate mesh query
if (dtStatusFailed(queryItr->second.init(&mmap->GetMeshData(meshMapId, instanceId).first->second.navMesh, 1024)))
{
- mmap->navMeshQueries.erase(queryItr);
TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {:04} instanceId {}", instanceMapId, instanceId);
return false;
}
@@ -397,20 +382,21 @@ namespace MMAP
return;
}
- if (MMapData::GetInstanceIdForMeshLookup(mapId, std::numeric_limits<uint32>::max()) == 0)
+ if (!isRebuildingTilesEnabledOnMap(mapId))
{
- // unload all tiles from given map
- MMapMapData& mesh = itr->second->meshData[0];
- for (auto const& [tileId, tileRef] : mesh.loadedTileRefs)
+ if (MeshDataMap::node_type meshNode = itr->second->RemoveMeshData(mapId, 0))
{
- uint32 x = (tileId >> 16);
- uint32 y = (tileId & 0x0000FFFF);
- if (dtStatusFailed(mesh.navMesh.removeTile(tileRef, nullptr, nullptr)))
- TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", mapId, x, y);
- else
+ for (auto const& [tileId, tileRef] : meshNode.mapped().loadedTileRefs)
{
- --loadedTiles;
- TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:04}", mapId, x, y, mapId);
+ uint32 x = (tileId >> 16);
+ uint32 y = (tileId & 0x0000FFFF);
+ if (dtStatusFailed(meshNode.mapped().navMesh.removeTile(tileRef, nullptr, nullptr)))
+ TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", mapId, x, y);
+ else
+ {
+ --loadedTiles;
+ TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:04}", mapId, x, y, mapId);
+ }
}
}
}
@@ -436,24 +422,24 @@ namespace MMAP
if (!erased)
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId {:04} instanceId {}", instanceMapId, instanceId);
- MeshDataMap::iterator meshItr = mmap->FindMeshData(meshMapId, instanceId);
- if (meshItr != mmap->meshData.end())
+ if (isRebuildingTilesEnabledOnMap(meshMapId))
{
- // unload all tiles from given map
- for (auto const& [tileId, tileRef] : meshItr->second.loadedTileRefs)
+ if (MeshDataMap::node_type meshNode = mmap->RemoveMeshData(meshMapId, instanceId))
{
- uint32 x = (tileId >> 16);
- uint32 y = (tileId & 0x0000FFFF);
- if (dtStatusFailed(meshItr->second.navMesh.removeTile(tileRef, nullptr, nullptr)))
- TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", meshMapId, x, y);
- else
+ // unload all tiles from given map
+ for (auto const& [tileId, tileRef] : meshNode.mapped().loadedTileRefs)
{
- --loadedTiles;
- TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:04}", meshMapId, x, y, meshMapId);
+ uint32 x = (tileId >> 16);
+ uint32 y = (tileId & 0x0000FFFF);
+ if (dtStatusFailed(meshNode.mapped().navMesh.removeTile(tileRef, nullptr, nullptr)))
+ TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", meshMapId, x, y);
+ else
+ {
+ --loadedTiles;
+ TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:04}", meshMapId, x, y, meshMapId);
+ }
}
}
-
- mmap->meshData.erase(meshItr);
}
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId {:04} instanceId {}", instanceMapId, instanceId);
@@ -474,7 +460,7 @@ namespace MMAP
dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId)
{
- auto itr = GetMMapData(meshMapId);
+ MMapDataSet::const_iterator itr = GetMMapData(meshMapId);
if (itr == loadedMMaps.end())
return nullptr;
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp
index 1f80091cb59..7627a6a82ae 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp
@@ -7411,7 +7411,7 @@ void VisualAnim::ClearChangesMask()
void ForceSetAreaTriggerPositionAndRotation::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const
{
data << TriggerGUID;
- data << Position;
+ data << Pos;
data << float(Rotation.x);
data << float(Rotation.y);
data << float(Rotation.z);
@@ -7421,7 +7421,7 @@ void ForceSetAreaTriggerPositionAndRotation::WriteCreate(ByteBuffer& data, AreaT
void ForceSetAreaTriggerPositionAndRotation::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const
{
data << TriggerGUID;
- data << Position;
+ data << Pos;
data << float(Rotation.x);
data << float(Rotation.y);
data << float(Rotation.z);
@@ -7431,7 +7431,7 @@ void ForceSetAreaTriggerPositionAndRotation::WriteUpdate(ByteBuffer& data, bool
bool ForceSetAreaTriggerPositionAndRotation::operator==(ForceSetAreaTriggerPositionAndRotation const& right) const
{
return TriggerGUID == right.TriggerGUID
- && Position == right.Position
+ && Pos == right.Pos
&& Rotation == right.Rotation;
}
@@ -8614,6 +8614,7 @@ void DecorStoragePersistedData::WriteCreate(ByteBuffer& data, Object const* owne
data << *HouseGUID;
data << uint8(Field_20);
data.WriteBits(Dyes.has_value(), 1);
+ data.FlushBits();
if (Dyes.has_value())
{
Dyes->WriteCreate(data, owner, receiver);
@@ -8626,26 +8627,24 @@ void DecorStoragePersistedData::WriteUpdate(ByteBuffer& data, bool ignoreChanges
if (ignoreChangesMask)
changesMask.SetAll();
- data.WriteBits(changesMask.GetBlock(0), 4);
+ data.WriteBits(changesMask.GetBlock(0), 3);
data.FlushBits();
if (changesMask[0])
{
- if (changesMask[1])
- {
- data << *HouseGUID;
- }
- if (changesMask[3])
- {
- data << uint8(Field_20);
- }
- data.WriteBits(Dyes.has_value(), 1);
- if (changesMask[2])
+ data << *HouseGUID;
+ }
+ if (changesMask[2])
+ {
+ data << uint8(Field_20);
+ }
+ data.WriteBits(Dyes.has_value(), 1);
+ data.FlushBits();
+ if (changesMask[1])
+ {
+ if (Dyes.has_value())
{
- if (Dyes.has_value())
- {
- Dyes->WriteUpdate(data, ignoreChangesMask, owner, receiver);
- }
+ Dyes->WriteUpdate(data, ignoreChangesMask, owner, receiver);
}
}
}
@@ -8663,8 +8662,9 @@ void HousingDecorData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
data << *DecorGUID;
data << *AttachParentGUID;
data << uint8(Flags);
- data << *Field_68;
+ data << *TargetGameObjectGUID;
data.WriteBits(PersistedData.has_value(), 1);
+ data.FlushBits();
if (PersistedData.has_value())
{
PersistedData->WriteCreate(data, owner, receiver);
@@ -8697,9 +8697,10 @@ void HousingDecorData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
if (changesMask[5])
{
- data << *Field_68;
+ data << *TargetGameObjectGUID;
}
data.WriteBits(PersistedData.has_value(), 1);
+ data.FlushBits();
if (changesMask[4])
{
if (PersistedData.has_value())
@@ -8716,7 +8717,7 @@ void HousingDecorData::ClearChangesMask()
Base::ClearChangesMask(AttachParentGUID);
Base::ClearChangesMask(Flags);
Base::ClearChangesMask(PersistedData);
- Base::ClearChangesMask(Field_68);
+ Base::ClearChangesMask(TargetGameObjectGUID);
_changesMask.ResetAll();
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h
index 1ccb5e0fdd7..582473c702c 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.h
@@ -1383,7 +1383,7 @@ struct VisualAnim : public IsUpdateFieldStructureTag, public HasChangesMask<5>
struct ForceSetAreaTriggerPositionAndRotation : public IsUpdateFieldStructureTag
{
ObjectGuid TriggerGUID;
- TaggedPosition<Position::XYZ> Position;
+ TaggedPosition<Position::XYZ> Pos;
QuaternionData Rotation;
void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const;
@@ -1649,11 +1649,11 @@ struct DecorStoragePersistedDataDyes : public IsUpdateFieldStructureTag
bool operator!=(DecorStoragePersistedDataDyes const& right) const { return !(*this == right); }
};
-struct DecorStoragePersistedData : public IsUpdateFieldStructureTag, public HasChangesMask<4>
+struct DecorStoragePersistedData : public IsUpdateFieldStructureTag, public HasChangesMask<3>
{
- UpdateField<ObjectGuid, 0, 1> HouseGUID;
- OptionalUpdateField<UF::DecorStoragePersistedDataDyes, 0, 2> Dyes;
- UpdateField<uint8, 0, 3> Field_20;
+ UpdateField<ObjectGuid, -1, 0> HouseGUID;
+ OptionalUpdateField<UF::DecorStoragePersistedDataDyes, -1, 1> Dyes;
+ UpdateField<uint8, -1, 2> Field_20;
void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const;
@@ -1666,7 +1666,7 @@ struct HousingDecorData : public IsUpdateFieldStructureTag, public HasChangesMas
UpdateField<ObjectGuid, 0, 2> AttachParentGUID;
UpdateField<uint8, 0, 3> Flags;
OptionalUpdateField<UF::DecorStoragePersistedData, 0, 4> PersistedData;
- UpdateField<ObjectGuid, 0, 5> Field_68;
+ UpdateField<ObjectGuid, 0, 5> TargetGameObjectGUID;
void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const;
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 86b4ab48672..49aa00c14e0 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -2256,6 +2256,8 @@ void AuraEffect::HandleAuraTransform(AuraApplication const* aurApp, uint8 mode,
if (target->IsMounted())
target->RemoveAurasByType(SPELL_AURA_MOUNTED);
}
+
+ target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2::Transform);
}
else
{
diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h
index 120f2fa68c1..f5c849c3b32 100644
--- a/src/server/game/Spells/SpellDefines.h
+++ b/src/server/game/Spells/SpellDefines.h
@@ -122,7 +122,7 @@ enum class SpellAuraInterruptFlags2 : uint32
Swimming = 0x00000002,
NotMoving = 0x00000004, // NYI
Ground = 0x00000008,
- Transform = 0x00000010, // NYI
+ Transform = 0x00000010,
Jump = 0x00000020,
ChangeSpec = 0x00000040,
AbandonVehicle = 0x00000080, // Implemented in Unit::_ExitVehicle
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 4ab419b1067..3bbf48b8d47 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -71,6 +71,7 @@ enum PaladinSpells
SPELL_PALADIN_DIVINE_STORM_DAMAGE = 224239,
SPELL_PALADIN_ENDURING_LIGHT = 40471,
SPELL_PALADIN_ENDURING_JUDGEMENT = 40472,
+ SPELL_PALADIN_ETERNAL_FLAME = 156322,
SPELL_PALADIN_EXECUTION_SENTENCE_DAMAGE = 387113,
SPELL_PALADIN_EXECUTION_SENTENCE_11_SECONDS = 406919,
SPELL_PALADIN_EXECUTION_SENTENCE_8_SECONDS = 386579,
@@ -693,6 +694,47 @@ class spell_pal_divine_storm : public SpellScript
}
};
+// 156322 - Eternal Flame
+class spell_pal_eternal_flame : public SpellScript
+{
+ bool Validate(SpellInfo const* spellInfo) override
+ {
+ return ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } });
+ }
+
+ void CalculateHealing(SpellEffectInfo const& /*effectInfo*/, Unit const* victim, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
+ {
+ Unit* caster = GetCaster();
+ if (victim == caster)
+ AddPct(pctMod, GetEffectInfo(EFFECT_2).CalcValue(caster));
+ }
+
+ void Register() override
+ {
+ CalcHealing += SpellCalcHealingFn(spell_pal_eternal_flame::CalculateHealing);
+ }
+};
+
+class spell_pal_eternal_flame_aura : public AuraScript
+{
+ bool Validate(SpellInfo const* spellInfo) override
+ {
+ return ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } });
+ }
+
+ void CalculateHealing(AuraEffect const* /*aurEff*/, Unit const* victim, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
+ {
+ Unit* caster = GetCaster();
+ if (victim == caster)
+ AddPct(pctMod, GetEffectInfo(EFFECT_2).CalcValue(caster));
+ }
+
+ void Register() override
+ {
+ DoEffectCalcDamageAndHealing += AuraEffectCalcHealingFn(spell_pal_eternal_flame_aura::CalculateHealing, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
+ }
+};
+
// 343527 - Execution Sentence
class spell_pal_execution_sentence : public SpellScript
{
@@ -1806,6 +1848,7 @@ void AddSC_paladin_spell_scripts()
RegisterSpellScript(spell_pal_divine_shield);
RegisterSpellScript(spell_pal_divine_steed);
RegisterSpellScript(spell_pal_divine_storm);
+ RegisterSpellAndAuraScriptPair(spell_pal_eternal_flame, spell_pal_eternal_flame_aura);
RegisterSpellAndAuraScriptPair(spell_pal_execution_sentence, spell_pal_execution_sentence_aura);
RegisterSpellScript(spell_pal_eye_for_an_eye);
RegisterSpellScript(spell_pal_final_verdict);
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 6100943eb12..1cb580810c5 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -38,6 +38,7 @@
#include "SpellScript.h"
#include "TaskScheduler.h"
#include "TemporarySummon.h"
+#include "CommonPredicates.h"
enum PriestSpells
{
@@ -70,6 +71,8 @@ enum PriestSpells
SPELL_PRIEST_DARK_REPRIMAND_DAMAGE = 373130,
SPELL_PRIEST_DARK_REPRIMAND_HEALING = 400187,
SPELL_PRIEST_DAZZLING_LIGHT = 196810,
+ SPELL_PRIEST_DISPERSING_LIGHT = 1215265,
+ SPELL_PRIEST_DISPERSING_LIGHT_HEAL = 1215266,
SPELL_PRIEST_DIVINE_AEGIS = 47515,
SPELL_PRIEST_DIVINE_AEGIS_ABSORB = 47753,
SPELL_PRIEST_DIVINE_BLESSING = 40440,
@@ -796,6 +799,67 @@ class spell_pri_dark_indulgence : public SpellScript
}
};
+// 1215265 - Dispersing Light
+class spell_pri_dispersing_light : public AuraScript
+{
+ bool Validate(SpellInfo const* spellInfo) override
+ {
+ return ValidateSpellInfo({ SPELL_PRIEST_DISPERSING_LIGHT_HEAL })
+ && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
+ {
+ HealInfo* healInfo = eventInfo.GetHealInfo();
+ if (!healInfo || !healInfo->GetHeal())
+ return;
+
+ Unit* caster = eventInfo.GetActor();
+ Unit* target = eventInfo.GetActionTarget();
+
+ caster->CastSpell(nullptr, SPELL_PRIEST_DISPERSING_LIGHT_HEAL, CastSpellExtraArgsInit
+ {
+ .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
+ .TriggeringAura = aurEff,
+ .SpellValueOverrides =
+ {
+ { SPELLVALUE_BASE_POINT0, int32(CalculatePct(healInfo->GetHeal(), aurEff->GetAmount())) },
+ { SPELLVALUE_MAX_TARGETS, GetEffectInfo(EFFECT_1).CalcValue(caster) }
+ },
+ .CustomArg = TriggerArgs{ .TargetToExclude = target->GetGUID() }
+ });
+ }
+
+ void Register() override
+ {
+ OnEffectProc += AuraEffectProcFn(spell_pri_dispersing_light::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+
+public:
+ struct TriggerArgs
+ {
+ ObjectGuid TargetToExclude;
+ };
+};
+
+// 1215266 - Dispersing Light (Heal)
+class spell_pri_dispersing_light_heal : public SpellScript
+{
+ void FilterTargets(std::list<WorldObject*>& targets) const
+ {
+ spell_pri_dispersing_light::TriggerArgs const* args = std::any_cast<spell_pri_dispersing_light::TriggerArgs>(&GetSpell()->m_customArg);
+ if (!args || args->TargetToExclude.IsEmpty())
+ return;
+
+ targets.remove_if(Trinity::ObjectGUIDCheck(args->TargetToExclude));
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_dispersing_light_heal::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
+ }
+};
+
namespace DivineImageHelpers
{
Unit* GetSummon(Unit const* owner)
@@ -3681,6 +3745,8 @@ void AddSC_priest_spell_scripts()
RegisterSpellScript(spell_pri_circle_of_healing);
RegisterSpellScript(spell_pri_crystalline_reflection);
RegisterSpellScript(spell_pri_dark_indulgence);
+ RegisterSpellScript(spell_pri_dispersing_light);
+ RegisterSpellScript(spell_pri_dispersing_light_heal);
RegisterSpellScript(spell_pri_divine_aegis);
RegisterSpellScript(spell_pri_divine_image);
RegisterSpellScript(spell_pri_divine_image_spell_triggered);