aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTraesh <traesh@farahlon.com>2017-03-21 18:14:23 +0100
committerShauren <shauren.trinity@gmail.com>2017-03-21 18:14:23 +0100
commit9cc5273cd27069d7abb8538eca20f429801b6f00 (patch)
tree2325cfc80cb3c6b9ae4ae907a2abc284d61bb0fa
parent024ae15681736db1adea3ac82f666d725d931e6c (diff)
Core/AreaTriggers: Areatrigger rework script system + fix priest angelic feather
Closes #19171
-rw-r--r--sql/updates/world/master/2017_03_21_02_world.sql11
-rw-r--r--src/server/game/AI/CoreAI/AreaTriggerAI.cpp26
-rw-r--r--src/server/game/AI/CoreAI/AreaTriggerAI.h65
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp82
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.h9
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h27
-rw-r--r--src/server/game/Entities/Player/Player.cpp1
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp155
-rw-r--r--src/server/game/Scripting/ScriptMgr.h34
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp96
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();
}