diff options
-rw-r--r-- | sql/updates/world/master/2017_03_21_02_world.sql | 11 | ||||
-rw-r--r-- | src/server/game/AI/CoreAI/AreaTriggerAI.cpp | 26 | ||||
-rw-r--r-- | src/server/game/AI/CoreAI/AreaTriggerAI.h | 65 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 82 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.h | 9 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h | 27 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.cpp | 155 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.h | 34 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_priest.cpp | 96 |
10 files changed, 346 insertions, 160 deletions
diff --git a/sql/updates/world/master/2017_03_21_02_world.sql b/sql/updates/world/master/2017_03_21_02_world.sql new file mode 100644 index 00000000000..5430cc6a8b4 --- /dev/null +++ b/sql/updates/world/master/2017_03_21_02_world.sql @@ -0,0 +1,11 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` = 121536; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(121536, "spell_pri_angelic_feather_trigger"); + +DELETE FROM `areatrigger_template` WHERE `Id`=3153; +INSERT INTO `areatrigger_template` (`Id`, `Type`, `Flags`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `ScriptName`, `VerifiedBuild`) VALUES +(3153, 0, 0, 3, 3, 0, 0, 0, 0, "areatrigger_pri_angelic_feather", 23420); + +DELETE FROM `spell_areatrigger` WHERE `SpellMiscId`=337; +INSERT INTO `spell_areatrigger` (`SpellMiscId`, `AreaTriggerId`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `DecalPropertiesId`, `TimeToTarget`, `TimeToTargetScale`, `VerifiedBuild`) VALUES +(337, 3153, 0, 0, 0, 0, 0, 0, 600000, 23420); -- SpellId : 158624 diff --git a/src/server/game/AI/CoreAI/AreaTriggerAI.cpp b/src/server/game/AI/CoreAI/AreaTriggerAI.cpp new file mode 100644 index 00000000000..ce5d46f7773 --- /dev/null +++ b/src/server/game/AI/CoreAI/AreaTriggerAI.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "AreaTriggerAI.h" + +AreaTriggerAI::AreaTriggerAI(AreaTrigger* a) : at(a) +{ +} + +AreaTriggerAI::~AreaTriggerAI() +{ +} diff --git a/src/server/game/AI/CoreAI/AreaTriggerAI.h b/src/server/game/AI/CoreAI/AreaTriggerAI.h new file mode 100644 index 00000000000..9f045bccdfd --- /dev/null +++ b/src/server/game/AI/CoreAI/AreaTriggerAI.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_AREATRIGGERAI_H +#define TRINITY_AREATRIGGERAI_H + +#include "Define.h" + +class AreaTrigger; +class Unit; + +class TC_GAME_API AreaTriggerAI +{ + protected: + AreaTrigger* const at; + public: + explicit AreaTriggerAI(AreaTrigger* a); + virtual ~AreaTriggerAI(); + + // Called when the AreaTrigger has just been initialized, just before added to map + virtual void OnInitialize() { } + + // Called when the AreaTrigger has just been created + virtual void OnCreate() { } + + // Called on each AreaTrigger update + virtual void OnUpdate(uint32 /*diff*/) { } + + // Called when the AreaTrigger reach splineIndex + virtual void OnSplineIndexReached(int /*splineIndex*/) { } + + // Called when the AreaTrigger reach its destination + virtual void OnDestinationReached() { } + + // Called when an unit enter the AreaTrigger + virtual void OnUnitEnter(Unit* /*unit*/) { } + + // Called when an unit exit the AreaTrigger, or when the AreaTrigger is removed + virtual void OnUnitExit(Unit* /*unit*/) { } + + // Called when the AreaTrigger is removed + virtual void OnRemove() { } +}; + +class NullAreaTriggerAI : public AreaTriggerAI +{ + public: + explicit NullAreaTriggerAI(AreaTrigger* areaTrigger) : AreaTriggerAI(areaTrigger) { } +}; + +#endif diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index 4393d15a401..97f70e5a8f7 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -33,11 +33,12 @@ #include "Transport.h" #include "Unit.h" #include "UpdateData.h" +#include "AreaTriggerAI.h" AreaTrigger::AreaTrigger() : WorldObject(false), MapObject(), _duration(0), _totalDuration(0), _timeSinceCreated(0), _previousCheckOrientation(std::numeric_limits<float>::infinity()), _isRemoved(false), _reachedDestination(true), _lastSplineIndex(0), _movementTime(0), - _areaTriggerMiscTemplate(nullptr) + _areaTriggerMiscTemplate(nullptr), _ai() { m_objectType |= TYPEMASK_AREATRIGGER; m_objectTypeId = TYPEID_AREATRIGGER; @@ -104,11 +105,14 @@ bool AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* targ SetUInt32Value(AREATRIGGER_SPELLID, spell->Id); SetUInt32Value(AREATRIGGER_SPELL_X_SPELL_VISUAL_ID, spellXSpellVisualId); - uint32 timeToTarget = GetMiscTemplate()->TimeToTarget != 0 ? GetMiscTemplate()->TimeToTarget : GetUInt32Value(AREATRIGGER_DURATION); SetUInt32Value(AREATRIGGER_TIME_TO_TARGET_SCALE, GetMiscTemplate()->TimeToTargetScale != 0 ? GetMiscTemplate()->TimeToTargetScale : GetUInt32Value(AREATRIGGER_DURATION)); SetFloatValue(AREATRIGGER_BOUNDS_RADIUS_2D, GetTemplate()->MaxSearchRadius); SetUInt32Value(AREATRIGGER_DECAL_PROPERTIES_ID, GetMiscTemplate()->DecalPropertiesId); + for (uint8 scaleCurveIndex = 0; scaleCurveIndex < MAX_AREATRIGGER_SCALE; ++scaleCurveIndex) + if (GetMiscTemplate()->ScaleInfo.ExtraScale[scaleCurveIndex].AsInt32) + SetUInt32Value(AREATRIGGER_EXTRA_SCALE_CURVE + scaleCurveIndex, GetMiscTemplate()->ScaleInfo.ExtraScale[scaleCurveIndex].AsInt32); + CopyPhaseFrom(caster); if (target && GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED)) @@ -119,9 +123,10 @@ bool AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* targ UpdateShape(); if (GetMiscTemplate()->HasSplines()) + { + uint32 timeToTarget = GetMiscTemplate()->TimeToTarget != 0 ? GetMiscTemplate()->TimeToTarget : GetUInt32Value(AREATRIGGER_DURATION); InitSplineOffsets(GetMiscTemplate()->SplinePoints, timeToTarget); - - sScriptMgr->OnAreaTriggerEntityInitialize(this); + } // movement on transport of areatriggers on unit is handled by themself Transport* transport = m_movementInfo.transport.guid.IsEmpty() ? caster->GetTransport() : nullptr; @@ -136,6 +141,8 @@ bool AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* targ transport->AddPassenger(this); } + AI_Initialize(); + if (!GetMap()->AddToMap(this)) { // Returning false will cause the object to be deleted - remove from transport @@ -146,15 +153,15 @@ bool AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* targ caster->_RegisterAreaTrigger(this); - sScriptMgr->OnAreaTriggerEntityCreate(this); + _ai->OnCreate(); return true; } -void AreaTrigger::Update(uint32 p_time) +void AreaTrigger::Update(uint32 diff) { - WorldObject::Update(p_time); - _timeSinceCreated += p_time; + WorldObject::Update(diff); + _timeSinceCreated += diff; if (GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED)) { @@ -162,14 +169,12 @@ void AreaTrigger::Update(uint32 p_time) GetMap()->AreaTriggerRelocation(this, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation()); } else - UpdateSplinePosition(p_time); - - sScriptMgr->OnAreaTriggerEntityUpdate(this, p_time); + UpdateSplinePosition(diff); if (GetDuration() != -1) { - if (GetDuration() > int32(p_time)) - _UpdateDuration(_duration - p_time); + if (GetDuration() > int32(diff)) + _UpdateDuration(_duration - diff); else { Remove(); // expired @@ -177,6 +182,8 @@ void AreaTrigger::Update(uint32 p_time) } } + _ai->OnUpdate(diff); + UpdateTargetList(); } @@ -192,7 +199,7 @@ void AreaTrigger::Remove() // Handle removal of all units, calling OnUnitExit & deleting auras if needed HandleUnitEnterExit({}); - sScriptMgr->OnAreaTriggerEntityRemove(this); + _ai->OnRemove(); RemoveFromWorld(); AddObjectToRemoveList(); @@ -353,7 +360,8 @@ void AreaTrigger::HandleUnitEnterExit(std::list<Unit*> const& newTargetList) ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_ENTERED, GetTemplate()->Id); DoActions(unit); - sScriptMgr->OnAreaTriggerEntityUnitEnter(this, unit); + + _ai->OnUnitEnter(unit); } for (ObjectGuid const& exitUnitGuid : exitUnits) @@ -365,7 +373,8 @@ void AreaTrigger::HandleUnitEnterExit(std::list<Unit*> const& newTargetList) ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_LEFT, GetTemplate()->Id); UndoActions(leavingUnit); - sScriptMgr->OnAreaTriggerEntityUnitExit(this, leavingUnit); + + _ai->OnUnitExit(leavingUnit); } } } @@ -422,29 +431,28 @@ bool AreaTrigger::CheckIsInPolygon2D(Position const* pos) const float testY = pos->GetPositionY(); //this method uses the ray tracing algorithm to determine if the point is in the polygon - int nPoints = _polygonVertices.size(); bool locatedInPolygon = false; - for (int i = 0; i < nPoints; ++i) + for (std::size_t vertex = 0; vertex < _polygonVertices.size(); ++vertex) { - int j = -999; + std::size_t nextVertex; //repeat loop for all sets of points - if (i == (nPoints - 1)) + if (vertex == (_polygonVertices.size() - 1)) { //if i is the last vertex, let j be the first vertex - j = 0; + nextVertex = 0; } else { //for all-else, let j=(i+1)th vertex - j = i + 1; + nextVertex = vertex + 1; } - float vertX_i = GetPositionX() + _polygonVertices[i].x; - float vertY_i = GetPositionY() + _polygonVertices[i].y; - float vertX_j = GetPositionX() + _polygonVertices[j].x; - float vertY_j = GetPositionY() + _polygonVertices[j].y; + float vertX_i = GetPositionX() + _polygonVertices[vertex].x; + float vertY_i = GetPositionY() + _polygonVertices[vertex].y; + float vertX_j = GetPositionX() + _polygonVertices[nextVertex].x; + float vertY_j = GetPositionY() + _polygonVertices[nextVertex].y; // following statement checks if testPoint.Y is below Y-coord of i-th vertex bool belowLowY = vertY_i > testY; @@ -633,8 +641,8 @@ void AreaTrigger::UpdateSplinePosition(uint32 diff) DebugVisualizePosition(); #endif - sScriptMgr->OnAreaTriggerEntitySplineIndexReached(this, _lastSplineIndex); - sScriptMgr->OnAreaTriggerEntityDestinationReached(this); + _ai->OnSplineIndexReached(_lastSplineIndex); + _ai->OnDestinationReached(); return; } @@ -677,7 +685,7 @@ void AreaTrigger::UpdateSplinePosition(uint32 diff) if (_lastSplineIndex != lastPositionIndex) { _lastSplineIndex = lastPositionIndex; - sScriptMgr->OnAreaTriggerEntitySplineIndexReached(this, _lastSplineIndex); + _ai->OnSplineIndexReached(_lastSplineIndex); } } @@ -688,3 +696,19 @@ void AreaTrigger::DebugVisualizePosition() if (player->isDebugAreaTriggers) player->SummonCreature(1, *this, TEMPSUMMON_TIMED_DESPAWN, GetTimeToTarget()); } + +void AreaTrigger::AI_Initialize() +{ + AI_Destroy(); + AreaTriggerAI* ai = sScriptMgr->GetAreaTriggerAI(this); + if (!ai) + ai = new NullAreaTriggerAI(this); + + _ai.reset(ai); + _ai->OnInitialize(); +} + +void AreaTrigger::AI_Destroy() +{ + _ai.reset(); +} diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index 57ea7b4e704..980c57feb72 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -26,6 +26,8 @@ class AreaTriggerTemplate; class AreaTriggerMiscTemplate; class SpellInfo; class Unit; +class AreaTriggerAI; + struct AreaTriggerPolygonVertice; class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigger>, public MapObject @@ -37,6 +39,11 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge void AddToWorld() override; void RemoveFromWorld() override; + void AI_Initialize(); + void AI_Destroy(); + + AreaTriggerAI* AI() { return _ai.get(); } + bool CreateAreaTrigger(uint32 triggerEntry, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId = ObjectGuid::Empty); void Update(uint32 p_time) override; void Remove(); @@ -109,6 +116,8 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge AreaTriggerMiscTemplate const* _areaTriggerMiscTemplate; GuidUnorderedSet _insideUnits; + + std::unique_ptr<AreaTriggerAI> _ai; }; #endif diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h index 0a6cd76c499..cc9e75c01ce 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h @@ -23,6 +23,7 @@ #include "Define.h" #define MAX_AREATRIGGER_ENTITY_DATA 6 +#define MAX_AREATRIGGER_SCALE 7 enum AreaTriggerFlags { @@ -74,6 +75,30 @@ struct AreaTriggerAction AreaTriggerActionUserTypes TargetType; }; +struct AreaTriggerScaleInfo +{ + AreaTriggerScaleInfo() + { + memset(OverrideScale, 0, sizeof(OverrideScale)); + memset(ExtraScale, 0, sizeof(ExtraScale)); + + ExtraScale[5].AsFloat = 1.0000001f; + ExtraScale[6].AsInt32 = 1; + } + + union + { + int32 AsInt32; + float AsFloat; + } OverrideScale[MAX_AREATRIGGER_SCALE]; + + union + { + int32 AsInt32; + float AsFloat; + } ExtraScale[MAX_AREATRIGGER_SCALE]; +}; + class AreaTriggerTemplate { public: @@ -182,6 +207,8 @@ public: uint32 TimeToTarget; uint32 TimeToTargetScale; + AreaTriggerScaleInfo ScaleInfo; + AreaTriggerTemplate const* Template; std::vector<G3D::Vector3> SplinePoints; }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 26ed9f8263f..d450b32aa1a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17,6 +17,7 @@ */ #include "Player.h" +#include "AreaTrigger.h" #include "AccountMgr.h" #include "AchievementMgr.h" #include "ArenaTeam.h" diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 4bb870e9e0a..9f912d95177 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -37,6 +37,7 @@ #include "MapManager.h" #include "LFGScripts.h" #include "InstanceScript.h" +#include "AreaTriggerAI.h" // Trait which indicates whether this script type // must be assigned in the database. @@ -332,9 +333,9 @@ public: } }; -/// This hook is responsible for swapping Creature and GameObject AI's +/// This hook is responsible for swapping Creature, GameObject and AreaTrigger AI's template<typename ObjectType, typename ScriptType, typename Base> -class CreatureGameObjectScriptRegistrySwapHooks +class CreatureGameObjectAreaTriggerScriptRegistrySwapHooks : public ScriptRegistrySwapHookBase { template<typename W> @@ -413,6 +414,20 @@ class CreatureGameObjectScriptRegistrySwapHooks "The AI should be null here!"); } + // Hook which is called before a areatrigger is swapped + static void UnloadResetScript(AreaTrigger* at) + { + at->AI()->OnRemove(); + } + + static void UnloadDestroyScript(AreaTrigger* at) + { + at->AI_Destroy(); + + ASSERT(!at->AI(), + "The AI should be null here!"); + } + // Hook which is called after a creature was swapped static void LoadInitializeScript(Creature* creature) { @@ -455,6 +470,20 @@ class CreatureGameObjectScriptRegistrySwapHooks gameobject->AI()->Reset(); } + // Hook which is called after a areatrigger was swapped + static void LoadInitializeScript(AreaTrigger* at) + { + ASSERT(!at->AI(), + "The AI should be null here!"); + + at->AI_Initialize(); + } + + static void LoadResetScript(AreaTrigger* at) + { + at->AI()->OnCreate(); + } + static Creature* GetEntityFromMap(std::common_type<Creature>, Map* map, ObjectGuid const& guid) { return map->GetCreature(guid); @@ -465,6 +494,11 @@ class CreatureGameObjectScriptRegistrySwapHooks return map->GetGameObject(guid); } + static AreaTrigger* GetEntityFromMap(std::common_type<AreaTrigger>, Map* map, ObjectGuid const& guid) + { + return map->GetAreaTrigger(guid); + } + template<typename T> static void VisitObjectsToSwapOnMap(Map* map, std::unordered_set<uint32> const& idsToRemove, T visitor) { @@ -583,17 +617,24 @@ private: // This hook is responsible for swapping CreatureAI's template<typename Base> class ScriptRegistrySwapHooks<CreatureScript, Base> - : public CreatureGameObjectScriptRegistrySwapHooks< + : public CreatureGameObjectAreaTriggerScriptRegistrySwapHooks< Creature, CreatureScript, Base > { }; // This hook is responsible for swapping GameObjectAI's template<typename Base> class ScriptRegistrySwapHooks<GameObjectScript, Base> - : public CreatureGameObjectScriptRegistrySwapHooks< + : public CreatureGameObjectAreaTriggerScriptRegistrySwapHooks< GameObject, GameObjectScript, Base > { }; +// This hook is responsible for swapping AreaTriggerAI's +template<typename Base> +class ScriptRegistrySwapHooks<AreaTriggerEntityScript, Base> + : public CreatureGameObjectAreaTriggerScriptRegistrySwapHooks< + AreaTrigger, AreaTriggerEntityScript, Base + > { }; + /// This hook is responsible for swapping BattlegroundScript's template<typename Base> class ScriptRegistrySwapHooks<BattlegroundScript, Base> @@ -666,35 +707,6 @@ private: bool swapped; }; -/// This hook is responsible for swapping AreaTriggerEntityScript's -template<typename Base> -class ScriptRegistrySwapHooks<AreaTriggerEntityScript, Base> - : public ScriptRegistrySwapHookBase -{ -public: - ScriptRegistrySwapHooks() : swapped(false) { } - - void BeforeReleaseContext(std::string const& context) final override - { - auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context); - if (bounds.first != bounds.second) - swapped = true; - } - - void BeforeSwapContext(bool /*initialize*/) override - { - swapped = false; - } - - void BeforeUnload() final override - { - ASSERT(!swapped); - } - -private: - bool swapped; -}; - /// This hook is responsible for swapping SceneScript's template<typename Base> class ScriptRegistrySwapHooks<SceneScript, Base> @@ -771,7 +783,7 @@ class SpecializedScriptRegistry<ScriptType, true> friend class ScriptRegistrySwapHooks; template<typename, typename, typename> - friend class CreatureGameObjectScriptRegistrySwapHooks; + friend class CreatureGameObjectAreaTriggerScriptRegistrySwapHooks; public: SpecializedScriptRegistry() { } @@ -1734,6 +1746,14 @@ GameObjectAI* ScriptMgr::GetGameObjectAI(GameObject* gameobject) return tmpscript->GetAI(gameobject); } +AreaTriggerAI* ScriptMgr::GetAreaTriggerAI(AreaTrigger* areatrigger) +{ + ASSERT(areatrigger); + + GET_SCRIPT_RET(AreaTriggerEntityScript, areatrigger->GetScriptId(), tmpscript, NULL); + return tmpscript->GetAI(areatrigger); +} + void ScriptMgr::OnCreatureUpdate(Creature* creature, uint32 diff) { ASSERT(creature); @@ -2382,73 +2402,6 @@ void ScriptMgr::ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& dama FOREACH_SCRIPT(PlayerScript)->ModifySpellDamageTaken(target, attacker, damage); } -// AreaTriggerEntityScript -void ScriptMgr::OnAreaTriggerEntityInitialize(AreaTrigger* areaTrigger) -{ - ASSERT(areaTrigger); - - GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript); - tmpscript->OnInitialize(areaTrigger); -} - -void ScriptMgr::OnAreaTriggerEntityCreate(AreaTrigger* areaTrigger) -{ - ASSERT(areaTrigger); - - GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript); - tmpscript->OnCreate(areaTrigger); -} - -void ScriptMgr::OnAreaTriggerEntityUpdate(AreaTrigger* areaTrigger, uint32 diff) -{ - ASSERT(areaTrigger); - - GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript); - tmpscript->OnUpdate(areaTrigger, diff); -} - -void ScriptMgr::OnAreaTriggerEntitySplineIndexReached(AreaTrigger* areaTrigger, int splineIndex) -{ - ASSERT(areaTrigger); - - GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript); - tmpscript->OnSplineIndexReached(areaTrigger, splineIndex); -} - -void ScriptMgr::OnAreaTriggerEntityDestinationReached(AreaTrigger* areaTrigger) -{ - ASSERT(areaTrigger); - - GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript); - tmpscript->OnDestinationReached(areaTrigger); -} - -void ScriptMgr::OnAreaTriggerEntityUnitEnter(AreaTrigger* areaTrigger, Unit* unit) -{ - ASSERT(areaTrigger); - ASSERT(unit); - - GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript); - tmpscript->OnUnitEnter(areaTrigger, unit); -} - -void ScriptMgr::OnAreaTriggerEntityUnitExit(AreaTrigger* areaTrigger, Unit* unit) -{ - ASSERT(areaTrigger); - ASSERT(unit); - - GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript); - tmpscript->OnUnitExit(areaTrigger, unit); -} - -void ScriptMgr::OnAreaTriggerEntityRemove(AreaTrigger* areaTrigger) -{ - ASSERT(areaTrigger); - - GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript); - tmpscript->OnRemove(areaTrigger); -} - // Scene void ScriptMgr::OnSceneStart(Player* player, uint32 sceneInstanceID, SceneTemplate const* sceneTemplate) { diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 09292747668..f4cbfff2c47 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -29,6 +29,7 @@ class AccountMgr; class AreaTrigger; +class AreaTriggerAI; class AuctionHouseObject; class Aura; class AuraScript; @@ -849,29 +850,9 @@ class TC_GAME_API AreaTriggerEntityScript : public ScriptObject AreaTriggerEntityScript(const char* name); public: - // Called when the AreaTrigger has just been initialized, just before added to map - virtual void OnInitialize(AreaTrigger* /*areaTrigger*/) { } - // Called when the AreaTrigger has just been created - virtual void OnCreate(AreaTrigger* /*areaTrigger*/) { } - - // Called on each AreaTrigger update - virtual void OnUpdate(AreaTrigger* /*areaTrigger*/, uint32 /*diff*/) { } - - // Called when the AreaTrigger reach splineIndex - virtual void OnSplineIndexReached(AreaTrigger* /*areaTrigger*/, int /*splineIndex*/) { } - - // Called when the AreaTrigger reach its destination - virtual void OnDestinationReached(AreaTrigger* /*areaTrigger*/) { } - - // Called when an unit enter the AreaTrigger - virtual void OnUnitEnter(AreaTrigger* /*areaTrigger*/, Unit* /*unit*/) { } - - // Called when an unit exit the AreaTrigger, or when the AreaTrigger is removed - virtual void OnUnitExit(AreaTrigger* /*areaTrigger*/, Unit* /*unit*/) { } - - // Called when the AreaTrigger is removed - virtual void OnRemove(AreaTrigger* /*areaTrigger*/) { } + // Called when a AreaTriggerAI object is needed for the areatrigger. + virtual AreaTriggerAI* GetAI(AreaTrigger* /*at*/) const { return nullptr; } }; class TC_GAME_API SceneScript : public ScriptObject @@ -1174,14 +1155,7 @@ class TC_GAME_API ScriptMgr public: /* AreaTriggerEntityScript */ - void OnAreaTriggerEntityInitialize(AreaTrigger* areaTrigger); - void OnAreaTriggerEntityCreate(AreaTrigger* areaTrigger); - void OnAreaTriggerEntityUpdate(AreaTrigger* areaTrigger, uint32 diff); - void OnAreaTriggerEntitySplineIndexReached(AreaTrigger* areaTrigger, int splineIndex); - void OnAreaTriggerEntityDestinationReached(AreaTrigger* areaTrigger); - void OnAreaTriggerEntityUnitEnter(AreaTrigger* areaTrigger, Unit* unit); - void OnAreaTriggerEntityUnitExit(AreaTrigger* areaTrigger, Unit* unit); - void OnAreaTriggerEntityRemove(AreaTrigger* areaTrigger); + AreaTriggerAI* GetAreaTriggerAI(AreaTrigger* areaTrigger); public: /* SceneScript */ void OnSceneStart(Player* player, uint32 sceneInstanceID, SceneTemplate const* sceneTemplate); diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index c6b88a3c5d4..b5fffcc9259 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -26,10 +26,15 @@ #include "SpellScript.h" #include "SpellAuraEffects.h" #include "GridNotifiers.h" +#include "AreaTriggerTemplate.h" +#include "AreaTriggerAI.h" enum PriestSpells { SPELL_PRIEST_ABSOLUTION = 33167, + SPELL_PRIEST_ANGELIC_FEATHER_TRIGGER = 121536, + SPELL_PRIEST_ANGELIC_FEATHER_AURA = 121557, + SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER = 158624, SPELL_PRIEST_BODY_AND_SOUL = 64129, SPELL_PRIEST_BODY_AND_SOUL_DISPEL = 64136, SPELL_PRIEST_BODY_AND_SOUL_SPEED = 65081, @@ -1289,6 +1294,95 @@ class spell_pri_vampiric_touch : public SpellScriptLoader } }; +// 121536 - Angelic Feather talent +class spell_pri_angelic_feather_trigger : public SpellScriptLoader +{ + public: + spell_pri_angelic_feather_trigger() : SpellScriptLoader("spell_pri_angelic_feather_trigger") { } + + class spell_pri_angelic_feather_trigger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pri_angelic_feather_trigger_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER)) + return false; + return true; + } + + void HandleEffectDummy(SpellEffIndex /*effIndex*/) + { + Position destPos = GetHitDest()->GetPosition(); + float radius = GetEffectInfo()->CalcRadius(); + + // Caster is prioritary + if (GetCaster()->IsWithinDist2d(&destPos, radius)) + { + GetCaster()->CastSpell(GetCaster(), SPELL_PRIEST_ANGELIC_FEATHER_AURA, true); + } + else + { + SpellCastTargets targets; + targets.SetDst(destPos); + GetCaster()->CastSpell(targets, sSpellMgr->GetSpellInfo(SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER), nullptr); + } + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_pri_angelic_feather_trigger_SpellScript::HandleEffectDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_pri_angelic_feather_trigger_SpellScript(); + } +}; + +// Angelic Feather areatrigger - created by SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER +class areatrigger_pri_angelic_feather : public AreaTriggerEntityScript +{ +public: + areatrigger_pri_angelic_feather() : AreaTriggerEntityScript("areatrigger_pri_angelic_feather") { } + + struct areatrigger_pri_angelic_featherAI : AreaTriggerAI + { + areatrigger_pri_angelic_featherAI(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + + // Called when the AreaTrigger has just been initialized, just before added to map + void OnInitialize() override + { + if (Unit* caster = at->GetCaster()) + { + std::vector<AreaTrigger*> areaTriggers = caster->GetAreaTriggers(SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER); + + if (areaTriggers.size() >= 3) + areaTriggers.front()->SetDuration(0); + } + } + + void OnUnitEnter(Unit* unit) override + { + if (Unit* caster = at->GetCaster()) + { + if (caster->IsFriendlyTo(unit)) + { + // If target already has aura, increase duration to max 130% of initial duration + caster->CastSpell(unit, SPELL_PRIEST_ANGELIC_FEATHER_AURA, true); + at->SetDuration(0); + } + } + } + }; + + AreaTriggerAI* GetAI(AreaTrigger* areatrigger) const override + { + return new areatrigger_pri_angelic_featherAI(areatrigger); + } +}; + void AddSC_priest_spell_scripts() { new spell_pri_body_and_soul(); @@ -1318,4 +1412,6 @@ void AddSC_priest_spell_scripts() new spell_pri_vampiric_embrace(); new spell_pri_vampiric_embrace_target(); new spell_pri_vampiric_touch(); + new spell_pri_angelic_feather_trigger(); + new areatrigger_pri_angelic_feather(); } |