diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 34 | ||||
| -rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.h | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 10 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 3 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_priest.cpp | 237 |
5 files changed, 256 insertions, 30 deletions
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index 1a97401096a..5b0612fedc7 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -299,7 +299,7 @@ bool AreaTrigger::Create(AreaTriggerCreatePropertiesId areaTriggerCreateProperti if (caster) caster->_RegisterAreaTrigger(this); - _ai->OnCreate(spell ? spell : nullptr); + _ai->OnCreate(spell); return true; } @@ -1380,26 +1380,8 @@ void AreaTrigger::UpdateSplinePosition(Movement::Spline<float>& spline) if (_reachedDestination) return; - if (GetElapsedTimeForMovement() >= GetTimeToTarget()) - { - _reachedDestination = true; - _lastSplineIndex = int32(spline.last()); - - G3D::Vector3 lastSplinePosition = spline.getPoint(_lastSplineIndex); - GetMap()->AreaTriggerRelocation(this, lastSplinePosition.x, lastSplinePosition.y, lastSplinePosition.z, GetOrientation()); -#ifdef TRINITY_DEBUG - DebugVisualizePosition(); -#endif - - _ai->OnSplineIndexReached(_lastSplineIndex); - _ai->OnDestinationReached(); - return; - } - - float currentTimePercent = float(GetElapsedTimeForMovement()) / float(GetTimeToTarget()); - - if (currentTimePercent <= 0.f) - return; + float currentTimePercent = std::clamp(float(GetElapsedTimeForMovement()) / float(GetTimeToTarget()), 0.0f, 1.0f); + _reachedDestination = currentTimePercent >= 1.0f; if (m_areaTriggerData->MoveCurveId) { @@ -1438,10 +1420,16 @@ void AreaTrigger::UpdateSplinePosition(Movement::Spline<float>& spline) DebugVisualizePosition(); #endif - if (_lastSplineIndex != lastPositionIndex) + if (_lastSplineIndex != lastPositionIndex || _reachedDestination) { _lastSplineIndex = lastPositionIndex; - _ai->OnSplineIndexReached(_lastSplineIndex); + _ai->OnSplineIndexReached(_lastSplineIndex - _spline->first() /*translate to index of the input array used for AreaTrigger::InitSplines*/); + if (_reachedDestination) + { + _ai->OnDestinationReached(); + _spline = nullptr; + SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::PathType), int32(AreaTriggerPathType::None)); + } } } diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index b4638b57c10..d9b2027c8bd 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -196,6 +196,8 @@ class TC_GAME_API AreaTrigger final : public WorldObject, public GridObject<Area bool HasOrbit() const { return m_areaTriggerData->PathData.Is<UF::AreaTriggerOrbit>(); } UF::AreaTriggerOrbit const& GetOrbit() const { return *m_areaTriggerData->PathData.Get<UF::AreaTriggerOrbit>(); } + void SetPathTarget(ObjectGuid pathTarget) { SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::OrbitPathTarget), pathTarget); } + bool HasOverridePosition() const; void UpdateShape(); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 185826c720b..1c0f9309679 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -3601,8 +3601,8 @@ void SpellInfo::_LoadSqrtTargetLimit(int32 maxTargets, int32 numNonDiminishedTar maxTargetValueHolder = sSpellMgr->GetSpellInfo(*maxTargetsValueHolderSpell, Difficulty); if (!maxTargetValueHolder) - TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not exist", maxTargetsValueHolderSpell); - else if (maxTargetsValueHolderEffect >= maxTargetValueHolder->GetEffects().size()) + TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not exist", *maxTargetsValueHolderSpell); + else if (*maxTargetsValueHolderEffect >= maxTargetValueHolder->GetEffects().size()) TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not have effect {}", maxTargetValueHolder->Id, AsUnderlyingType(*maxTargetsValueHolderEffect)); else @@ -3622,10 +3622,10 @@ void SpellInfo::_LoadSqrtTargetLimit(int32 maxTargets, int32 numNonDiminishedTar numNonDiminishedTargetsValueHolder = sSpellMgr->GetSpellInfo(*numNonDiminishedTargetsValueHolderSpell, Difficulty); if (!numNonDiminishedTargetsValueHolder) - TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not exist", maxTargetsValueHolderSpell); - else if (numNonDiminishedTargetsValueHolderEffect >= numNonDiminishedTargetsValueHolder->GetEffects().size()) + TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not exist", *numNonDiminishedTargetsValueHolderSpell); + else if (*numNonDiminishedTargetsValueHolderEffect >= numNonDiminishedTargetsValueHolder->GetEffects().size()) TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not have effect {}", - numNonDiminishedTargetsValueHolder->Id, AsUnderlyingType(*maxTargetsValueHolderEffect)); + numNonDiminishedTargetsValueHolder->Id, AsUnderlyingType(*numNonDiminishedTargetsValueHolderEffect)); else { SpellEffectInfo const& valueHolder = numNonDiminishedTargetsValueHolder->GetEffect(*numNonDiminishedTargetsValueHolderEffect); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 149c063bf6a..bb5a8acf7c6 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1197,7 +1197,8 @@ void World::LoadConfigSettings(bool reload) _gameRules = { - { .Rule = ::GameRule::TransmogEnabled, .Value = true } + { .Rule = ::GameRule::TransmogEnabled, .Value = true }, + { .Rule = ::GameRule::HousingEnabled, .Value = true } }; if (reload) diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 712705d43ad..bb4d07fa971 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -26,7 +26,6 @@ #include "Containers.h" #include "G3DPosition.hpp" #include "GridNotifiers.h" -#include "ListUtils.h" #include "Log.h" #include "MoveSplineInitArgs.h" #include "ObjectAccessor.h" @@ -55,6 +54,7 @@ enum PriestSpells SPELL_PRIEST_ATONEMENT_EFFECT = 194384, SPELL_PRIEST_ATONEMENT_HEAL = 81751, SPELL_PRIEST_BENEDICTION = 193157, + SPELL_PRIEST_BINDING_HEALS_HEAL = 368276, SPELL_PRIEST_BLAZE_OF_LIGHT = 215768, SPELL_PRIEST_BLAZE_OF_LIGHT_INCREASE = 355851, SPELL_PRIEST_BLAZE_OF_LIGHT_DECREASE = 356084, @@ -91,6 +91,12 @@ enum PriestSpells SPELL_PRIEST_DIVINE_STAR_SHADOW_HEAL = 390981, SPELL_PRIEST_DIVINE_WRATH = 40441, SPELL_PRIEST_EMPOWERED_RENEW = 391339, + SPELL_PRIEST_EMPOWERED_RENEW_HEAL = 391359, + SPELL_PRIEST_ENTROPIC_RIFT = 447444, + SPELL_PRIEST_ENTROPIC_RIFT_AREATRIGGER = 447445, + SPELL_PRIEST_ENTROPIC_RIFT_AURA = 450193, + SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE = 447448, + SPELL_PRIEST_ENTROPIC_RIFT_PERIODIC = 459314, SPELL_PRIEST_EPIPHANY = 414553, SPELL_PRIEST_EPIPHANY_HIGHLIGHT = 414556, SPELL_PRIEST_ESSENCE_DEVOURER = 415479, @@ -131,6 +137,7 @@ enum PriestSpells SPELL_PRIEST_MASOCHISM_TALENT = 193063, SPELL_PRIEST_MASOCHISM_PERIODIC_HEAL = 193065, SPELL_PRIEST_MASTERY_GRACE = 271534, + SPELL_PRIEST_MIND_BLAST = 8092, SPELL_PRIEST_MIND_DEVOURER = 373202, SPELL_PRIEST_MIND_DEVOURER_AURA = 373204, SPELL_PRIEST_MINDBENDER_DISC = 123040, @@ -217,6 +224,7 @@ enum PriestSpells SPELL_PRIEST_VAMPIRIC_TOUCH = 34914, SPELL_PRIEST_VOID_SHIELD = 199144, SPELL_PRIEST_VOID_SHIELD_EFFECT = 199145, + SPELL_PRIEST_VOID_TORRENT = 263165, SPELL_PRIEST_WEAKENED_SOUL = 6788, SPELL_PRIEST_WHISPERING_SHADOWS = 406777, SPELL_PRIEST_WHISPERING_SHADOWS_DUMMY = 391286, @@ -716,6 +724,38 @@ class spell_pri_benediction : public SpellScript } }; +// 368275 - Binding Heals +class spell_pri_binding_heals : public AuraScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_BINDING_HEALS_HEAL }); + } + + static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo) + { + return eventInfo.GetActor() != eventInfo.GetProcTarget(); + } + + static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo) + { + Unit* caster = eventInfo.GetActor(); + + caster->CastSpell(caster, SPELL_PRIEST_BINDING_HEALS_HEAL, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringSpell = eventInfo.GetProcSpell(), + .TriggeringAura = aurEff, + .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, int32(CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount())) } } + }); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_binding_heals::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_binding_heals::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + // 215768 - Blaze of Light class spell_pri_blaze_of_light : public AuraScript { @@ -1309,6 +1349,196 @@ class spell_pri_empowered_renew_heal : public AuraScript } }; +// 447444 - Entropic Rift +// Triggered by 8092 - Mind Blast (Discipline) and 263165 - Void Torrent (Shadow) +class spell_pri_entropic_rift : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_ENTROPIC_RIFT }); + } + + bool Load() override + { + Unit* caster = GetCaster(); + return caster->HasAura(SPELL_PRIEST_ENTROPIC_RIFT) + && caster->IsPlayer() + && GetSpellInfo()->Id == uint32(caster->ToPlayer()->GetPrimarySpecialization() == ChrSpecialization::PriestShadow + ? SPELL_PRIEST_VOID_TORRENT + : SPELL_PRIEST_MIND_BLAST); + } + + void HandleEffectHit(SpellEffIndex /*effIndex*/) const + { + Unit* target = GetHitUnit(); + + GetCaster()->CastSpell(target->GetPosition(), SPELL_PRIEST_ENTROPIC_RIFT_AREATRIGGER, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .CustomArg = target->GetGUID() + }); + } + + void Register() override + { + if (m_scriptSpellId == SPELL_PRIEST_MIND_BLAST) + OnEffectHitTarget += SpellEffectFn(spell_pri_entropic_rift::HandleEffectHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + else + OnEffectHitTarget += SpellEffectFn(spell_pri_entropic_rift::HandleEffectHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } +}; + +// 450193 - Entropic Rift (Aura) +class spell_pri_entropic_rift_aura : public AuraScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_ENTROPIC_RIFT_AREATRIGGER }); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const + { + if (AreaTrigger* at = GetTarget()->GetAreaTrigger(SPELL_PRIEST_ENTROPIC_RIFT_AREATRIGGER)) + at->Remove(); + } + + void Register() override + { + OnEffectRemove += AuraEffectApplyFn(spell_pri_entropic_rift_aura::HandleRemove, EFFECT_0, SPELL_AURA_MOD_SPEED_ALWAYS, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 459314 - Entropic Rift (Periodic) +class spell_pri_entropic_rift_periodic : public AuraScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_ENTROPIC_RIFT_AREATRIGGER, SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE }); + } + + void HandlePeriodic(AuraEffect const* /*aurEff*/) const + { + Unit* caster = GetTarget(); + + AreaTrigger const* at = caster->GetAreaTrigger(SPELL_PRIEST_ENTROPIC_RIFT_AREATRIGGER); + if (!at) + return; + + SpellInfo const* damageSpell = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE, GetCastDifficulty()); + + for (ObjectGuid const& unitInAreaTrigger : at->GetInsideUnits()) + if (Unit* target = ObjectAccessor::GetUnit(*at, unitInAreaTrigger)) + if (caster->IsValidAttackTarget(target, damageSpell)) + caster->CastSpell(target, SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_pri_entropic_rift_periodic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// 447445 - Entropic Rift (AreaTrigger) +struct areatrigger_pri_entropic_rift : public AreaTriggerAI +{ + using AreaTriggerAI::AreaTriggerAI; + + static constexpr std::array<DBCPosition2D, 2> OverrideScaleCurve = + {{ + { .X = 0.0f, .Y = 1.0f }, + { .X = 1.0f, .Y = 1.0f }, + }}; + + void OnCreate(Spell const* creatingSpell) override + { + Unit* caster = at->GetCaster(); + if (!caster) + return; + + CastSpellExtraArgs args; + args.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR; + + if (creatingSpell) + { + args.OriginalCastId = creatingSpell->m_castId; + + if (ObjectGuid const* targetGUID = std::any_cast<ObjectGuid>(&creatingSpell->m_customArg)) + at->SetPathTarget(*targetGUID); + + _searchRadius = creatingSpell->GetSpellInfo()->GetMaxRange(); + } + + caster->CastSpell(caster, SPELL_PRIEST_ENTROPIC_RIFT_AURA, args); + caster->CastSpell(caster, SPELL_PRIEST_ENTROPIC_RIFT_PERIODIC, args); + + UpdateMovement(); + _scheduler.Schedule(500ms, [this](TaskContext task) + { + UpdateMovement(); + task.Repeat(500ms); + }); + } + + void OnUpdate(uint32 diff) override + { + _scheduler.Update(diff); + } + + void OnDestinationReached() override + { + _movementSpeed = 7.0f; // Entropic Rift moves slower after reaching its target + } + + void UpdateMovement() + { + at->SetOverrideScaleCurve(OverrideScaleCurve); // updates StartTimeOffset of the curve + + Unit* target = UpdateTarget(); + if (!target) + return; + + at->SetPathTarget(target->GetGUID()); + + if (at->IsInDist2d(target, 0.5f)) + return; + + PathGenerator path(at); + path.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false); + at->InitSplines(path.GetPath(), _movementSpeed); + } + + Unit* UpdateTarget() const + { + SpellInfo const* damageSpell = sSpellMgr->GetSpellInfo(SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE, DIFFICULTY_NONE); + if (!damageSpell || damageSpell->GetEffects().empty()) + return nullptr; + + Unit* caster = at->GetCaster(); + if (!caster) + return nullptr; + + SpellEffectInfo const& damageEffect = damageSpell->GetEffect(EFFECT_0); + Trinity::WorldObjectSpellAreaTargetCheck check(_searchRadius, caster, caster, caster, damageSpell, TARGET_CHECK_ENEMY, damageEffect.ImplicitTargetConditions.get(), TARGET_OBJECT_TYPE_UNIT); + + Unit* target = ObjectAccessor::GetUnit(*at, at->m_areaTriggerData->OrbitPathTarget); + if (!target || !check(target)) + { + std::vector<Unit*> targets; + Trinity::UnitListSearcher searcher(at, targets, check); + Spell::SearchTargets(searcher, GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER, caster, caster, _searchRadius); + Trinity::Containers::EraseIf(targets, [caster](Unit const* target) { return !caster->IsInCombatWith(target); }); + if (!targets.empty()) + target = Trinity::Containers::SelectRandomContainerElement(targets); + } + + return target; + } + +private: + TaskScheduler _scheduler; + float _movementSpeed = 12.0f; + float _searchRadius = 0.0f; +}; + // 414553 - Epiphany class spell_pri_epiphany : public AuraScript { @@ -4035,6 +4265,7 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_atonement_effect_aura); RegisterSpellScript(spell_pri_atonement_passive); RegisterSpellScript(spell_pri_benediction); + RegisterSpellScript(spell_pri_binding_heals); RegisterSpellScript(spell_pri_blaze_of_light); RegisterSpellScript(spell_pri_circle_of_healing); RegisterSpellScript(spell_pri_crystalline_reflection); @@ -4051,6 +4282,10 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_divine_procession); RegisterSpellScript(spell_pri_empowered_renew); RegisterSpellScript(spell_pri_empowered_renew_heal); + RegisterSpellScript(spell_pri_entropic_rift); + RegisterSpellScript(spell_pri_entropic_rift_aura); + RegisterSpellScript(spell_pri_entropic_rift_periodic); + RegisterAreaTriggerAI(areatrigger_pri_entropic_rift); RegisterSpellScript(spell_pri_epiphany); RegisterSpellScript(spell_pri_essence_devourer_heal); RegisterSpellScript(spell_pri_evangelism); |
