TrinityCore
Loading...
Searching...
No Matches
AreaTrigger.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITYCORE_AREATRIGGER_H
19#define TRINITYCORE_AREATRIGGER_H
20
21#include "Object.h"
22#include "GridObject.h"
23#include "MapObject.h"
24#include "QuaternionData.h"
25#include "AreaTriggerTemplate.h"
26
27class AuraEffect;
28class AreaTriggerAI;
29class SpellInfo;
30class Unit;
31
32namespace G3D
33{
34 class Vector2;
35 class Vector3;
36}
37namespace Movement
38{
39 template<typename length_type>
40 class Spline;
41}
42
44{
45 None = 0x0000,
46 HeightIgnoresScale = 0x0001,
47 WowLabsCircle = 0x0002,
48 CanLoop = 0x0004,
49 AbsoluteOrientation = 0x0008,
50 DynamicShape = 0x0010,
51 Attached = 0x0020,
52 FaceMovementDir = 0x0040, // applies when attached to unit (refers to movement direction of the unit)
53 FollowsTerrain = 0x0080,
54 UsesUnitRawFacing = 0x0100, // uses GetTransOffsetO instead of GetOrientation when attached to unit on a transport/vehicle
55 AlwaysExterior = 0x0200,
56 HasPlayers = 0x0400,
57};
58
60
62{
63 Spline = 0,
64 Orbit = 1,
65 Stationary = 2,
67};
68
70{
71 NotInside = 0, // Unit leave areatrigger
72 ByExpire = 1 // On areatrigger despawn
73};
74
75class TC_GAME_API AreaTrigger final : public WorldObject, public GridObject<AreaTrigger>, public MapObject
76{
77 public:
80
81 protected:
82 void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
83 void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
84 void ClearValuesChangesMask() override;
85
86 public:
87 void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
88 UF::AreaTriggerData::Mask const& requestedAreaTriggerMask, Player const* target, bool ignoreNestedChangesMask) const;
89
90 struct ValuesUpdateForPlayerWithMaskSender // sender compatible with MessageDistDeliverer
91 {
92 explicit ValuesUpdateForPlayerWithMaskSender(AreaTrigger const* owner) : Owner(owner), IgnoreNestedChangesMask(false) { }
93
98
99 void operator()(Player const* player) const;
100 };
101
102 void AddToWorld() override;
103 void RemoveFromWorld() override;
104
105 void AI_Initialize();
106 void AI_Destroy();
107
108 AreaTriggerAI* AI() { return _ai.get(); }
109
110 bool IsCustom() const { return _areaTriggerTemplate->Id.IsCustom; }
111 bool IsServerSide() const { return _areaTriggerTemplate->Flags.HasFlag(AreaTriggerFlag::IsServerSide); }
112 bool IsStaticSpawn() const { return _spawnId != 0; }
113 bool HasActionSetFlag(AreaTriggerActionSetFlag flag) const { return _areaTriggerTemplate->ActionSetFlags.HasFlag(flag); }
114
115 bool IsNeverVisibleFor(WorldObject const* seer, bool allowServersideObjects) const override;
116
117 Position const& GetStationaryPosition() const override { return _stationaryPosition; }
118 void RelocateStationaryPosition(Position const& pos) { _stationaryPosition.Relocate(pos); }
119 void PlaySpellVisual(uint32 spellVisualId) const;
120
121 private:
122 bool Create(AreaTriggerCreatePropertiesId areaTriggerCreatePropertiesId, Map* map, Position const& pos, int32 duration, AreaTriggerSpawn const* spawnData = nullptr, Unit* caster = nullptr, Unit* target = nullptr, SpellCastVisual spellVisual = { 0, 0 }, SpellInfo const* spellInfo = nullptr, Spell* spell = nullptr, AuraEffect const* aurEff = nullptr);
123
124 public:
125 static AreaTrigger* CreateAreaTrigger(AreaTriggerCreatePropertiesId areaTriggerCreatePropertiesId, Position const& pos, int32 duration, Unit* caster, Unit* target, SpellCastVisual spellVisual = { 0, 0 }, SpellInfo const* spellInfo = nullptr, Spell* spell = nullptr, AuraEffect const* aurEff = nullptr);
126 static ObjectGuid CreateNewMovementForceId(Map* map, uint32 areaTriggerId);
127 bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool allowDuplicate);
128
129 void Update(uint32 diff) override;
130 void Remove();
131 bool IsRemoved() const { return _isRemoved; }
132 uint32 GetSpellId() const { return m_areaTriggerData->SpellID; }
133 AuraEffect const* GetAuraEffect() const { return _aurEff; }
134 uint32 GetTimeSinceCreated() const;
135
136 EnumFlag<AreaTriggerFieldFlags> GetAreaTriggerFlags() const { return static_cast<AreaTriggerFieldFlags>(*m_areaTriggerData->Flags); }
137 bool HasAreaTriggerFlag(AreaTriggerFieldFlags flag) const { return GetAreaTriggerFlags().HasFlag(flag); }
141
142 float CalcCurrentScale() const;
143 void SetOverrideScaleCurve(float overrideScale);
144 void SetOverrideScaleCurve(std::array<DBCPosition2D, 2> const& points, Optional<uint32> startTimeOffset = {}, CurveInterpolationMode interpolation = CurveInterpolationMode::Linear);
145 void ClearOverrideScaleCurve();
146
147 void SetExtraScaleCurve(float extraScale);
148 void SetExtraScaleCurve(std::array<DBCPosition2D, 2> const& points, Optional<uint32> startTimeOffset = {}, CurveInterpolationMode interpolation = CurveInterpolationMode::Linear);
149 void ClearExtraScaleCurve();
150
151 void SetOverrideMoveCurve(float x, float y, float z);
152 void SetOverrideMoveCurve(std::array<DBCPosition2D, 2> const& xCurvePoints, std::array<DBCPosition2D, 2> const& yCurvePoints, std::array<DBCPosition2D, 2> const& zCurvePoints,
153 Optional<uint32> startTimeOffset = {}, CurveInterpolationMode interpolation = CurveInterpolationMode::Linear);
154 void ClearOverrideMoveCurve();
155
156 void SetOverrideShapeCurve(float overrideShape);
157 void SetOverrideShapeCurve(std::array<DBCPosition2D, 2> const& points, Optional<uint32> startTimeOffset = {}, CurveInterpolationMode interpolation = CurveInterpolationMode::Linear);
158 void ClearOverrideShapeCurve();
159
160 uint32 GetTimeToTarget() const { return m_areaTriggerData->TimeToTarget; }
161 void SetTimeToTarget(uint32 timeToTarget) { SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::TimeToTarget), timeToTarget); }
162
163 uint32 GetTimeToTargetScale() const { return m_areaTriggerData->TimeToTargetScale; }
164 void SetTimeToTargetScale(uint32 timeToTargetScale) { SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::TimeToTargetScale), timeToTargetScale); }
165
166 uint32 GetTimeToTargetExtraScale() const { return m_areaTriggerData->TimeToTargetExtraScale; }
167 void SetTimeToTargetExtraScale(uint32 timeToTargetExtraScale) { SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::TimeToTargetExtraScale), timeToTargetExtraScale); }
168
169 uint32 GetTimeToTargetPos() const { return m_areaTriggerData->TimeToTargetPos; }
170 void SetTimeToTargetPos(uint32 timeToTargetPos) { SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::TimeToTargetPos), timeToTargetPos); }
171
172 uint32 GetTimeToTargetShape() const { return m_areaTriggerData->TimeToTargetShape; }
173 void SetTimeToTargetShape(uint32 timeToTargetShape) { SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::TimeToTargetShape), timeToTargetShape); }
174
175 void SetSpellVisual(SpellCastVisual const& visual);
176
177 void SetRollPitchYaw(float roll, float pitch, float yaw,
178 Optional<float> targetRoll = {}, Optional<float> targetPitch = {}, Optional<float> targetYaw = {});
179 void SetRollPitchYaw(TaggedPosition<Position::XYZ> const& rollPitchYaw,
180 Optional<TaggedPosition<Position::XYZ>> const& targetRollPitchYaw = {});
181
182 int32 GetDuration() const { return _duration; }
183 int32 GetTotalDuration() const { return _totalDuration; }
184 void SetDuration(int32 newDuration);
185 void Delay(int32 delaytime) { SetDuration(GetDuration() - delaytime); }
186
187 GuidUnorderedSet const& GetInsideUnits() const { return _insideUnits; }
188
189 AreaTriggerCreateProperties const* GetCreateProperties() const { return _areaTriggerCreateProperties; }
190 AreaTriggerTemplate const* GetTemplate() const { return _areaTriggerTemplate; }
191 uint32 GetScriptId() const;
192
193 ObjectGuid GetCreatorGUID() const override { return GetCasterGuid(); }
194 ObjectGuid GetOwnerGUID() const override { return GetCasterGuid(); }
195 ObjectGuid const& GetCasterGuid() const { return m_areaTriggerData->Caster; }
196 Unit* GetCaster() const;
197 Unit* GetTarget() const;
198
199 uint32 GetFaction() const override;
200
201 void SetShape(AreaTriggerShapeInfo const& shape);
202 float GetMaxSearchRadius() const;
203 void InitSplineOffsets(std::vector<Position> const& offsets, Optional<float> overrideSpeed = {}, Optional<bool> speedIsTimeInSeconds = {});
204 void InitSplines(std::vector<G3D::Vector3> const& splinePoints, Optional<float> overrideSpeed = {}, Optional<bool> speedIsTimeInSeconds = {});
205 bool HasSplines() const { return _spline != nullptr; }
206 ::Movement::Spline<float> const& GetSpline() const { return *_spline; }
207 uint32 GetElapsedTimeForMovement() const;
208
209 void InitOrbit(AreaTriggerOrbitInfo const& orbit, Optional<float> overrideSpeed = {}, Optional<bool> speedIsTimeInSeconds = {});
210 bool HasOrbit() const { return m_areaTriggerData->PathData.Is<UF::AreaTriggerOrbit>(); }
211 UF::AreaTriggerOrbit const& GetOrbit() const { return *m_areaTriggerData->PathData.Get<UF::AreaTriggerOrbit>(); }
212
213 void SetPathTarget(ObjectGuid pathTarget) { SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::OrbitPathTarget), pathTarget); }
214
215 bool HasOverridePosition() const;
216
217 void UpdateShape();
218
219 void HandleUnitExit(Unit* unit);
220
222
223 protected:
224 void _UpdateDuration(int32 newDuration);
225
226 float GetScaleProgress() const { return GetOverrideCurveProgress(m_areaTriggerData->OverrideScaleCurve, m_areaTriggerData->TimeToTargetScale); }
227 float GetExtraScaleProgress() const { return GetOverrideCurveProgress(m_areaTriggerData->ExtraScaleCurve, m_areaTriggerData->TimeToTargetExtraScale); }
228 float GetOverridePosProgress() const { return GetOverrideCurveProgress(m_areaTriggerData->OverrideMoveCurveX, m_areaTriggerData->TimeToTargetPos); }
229 float GetShapeProgress() const { return GetOverrideCurveProgress(m_areaTriggerData->OverrideShapeCurve, m_areaTriggerData->TimeToTargetShape); }
230
232 {
233 uint32 StartTimeOffset = 0;
235
236 using Points = std::array<DBCPosition2D, 2>;
237 std::variant<float, Points> Curve;
238 };
239
240 float GetOverrideCurveProgress(UF::OverrideCurve const& overrideCurve, uint32 timeTo) const;
241 float GetOverrideCurveValueAtProgress(UF::OverrideCurve const& overrideCurve, float x) const;
242 float GetOverrideCurveValue(UF::OverrideCurve const& overrideCurve, uint32 timeTo) const;
243 void SetOverrideCurve(UF::MutableFieldReference<UF::OverrideCurve, false> overrideCurveMutator, float constantValue);
244 void SetOverrideCurve(UF::MutableFieldReference<UF::OverrideCurve, false> overrideCurveMutator, std::array<DBCPosition2D, 2> const& points, Optional<uint32> startTimeOffset, CurveInterpolationMode interpolation);
245 void ClearOverrideCurve(UF::MutableFieldReference<UF::OverrideCurve, false> overrideCurveMutator);
246 void SetOverrideCurve(UF::MutableFieldReference<UF::OverrideCurve, false> overrideCurveMutator, Optional<OverrideCurveData> const& curve);
247
248 void UpdateTargetList();
249 void SearchUnits(std::vector<Unit*>& targetList, float radius, bool check3D);
250 void SearchUnitInSphere(UF::AreaTriggerSphere const& sphere, std::vector<Unit*>& targetList);
251 void SearchUnitInBox(UF::AreaTriggerBox const& box, std::vector<Unit*>& targetList);
252 void SearchUnitInPolygon(UF::AreaTriggerPolygon const& polygon, std::vector<Unit*>& targetList);
253 void SearchUnitInCylinder(UF::AreaTriggerCylinder const& cylinder, std::vector<Unit*>& targetList);
254 void SearchUnitInDisk(UF::AreaTriggerDisk const& disk, std::vector<Unit*>& targetList);
255 void SearchUnitInBoundedPlane(UF::AreaTriggerBoundedPlane const& boundedPlane, std::vector<Unit*>& targetList);
256 void HandleUnitEnterExit(std::vector<Unit*> const& targetList, AreaTriggerExitReason exitMode = AreaTriggerExitReason::NotInside);
257 void HandleUnitEnter(Unit* unit);
258 void HandleUnitExitInternal(Unit* unit, AreaTriggerExitReason exitMode = AreaTriggerExitReason::NotInside);
259
260 void DoActions(Unit* unit);
261 void UndoActions(Unit* unit);
262
263 void UpdatePositionAndRotation();
264
266 MovementUpdateWorldResult CalculateWorldPositionAndRotation() const;
267
269 MovementUpdateLocalResult CalculateLocalPositionAndRotation() const;
270
272 MovementUpdateLocalResult CalculateLocalSplinePositionAndRotation() const;
273 MovementUpdateLocalResult CalculateLocalOrbitPositionAndRotation(UF::AreaTriggerOrbit const& orbit) const;
274 MovementUpdateLocalResult CalculateLocalStationaryPositionAndRotation() const;
275
276 Position const& GetMovementOrigin() const;
277
278 void UpdatePolygonVertices();
279
280 void UpdateDynamicShapeFlag();
281 void UpdateHasPlayersFlag();
282
283 void DebugVisualizePosition(); // Debug purpose only
284
286
288
290
297
298 std::vector<Position> _polygonVertices;
299 std::unique_ptr<::Movement::Spline<float>> _spline;
300
302
306
307 std::unique_ptr<AreaTriggerAI> _ai;
308};
309
310#endif
AreaTriggerFieldFlags
Definition AreaTrigger.h:44
AreaTriggerPathType
Definition AreaTrigger.h:62
AreaTriggerExitReason
Definition AreaTrigger.h:70
CurveInterpolationMode
Definition DBCEnums.h:923
AreaTriggerActionSetFlag
Definition DBCEnums.h:175
#define TC_GAME_API
Definition Define.h:129
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
uint16 flags
#define DEFINE_ENUM_FLAG(enumType)
Definition EnumFlag.h:26
std::unordered_set< ObjectGuid > GuidUnorderedSet
Definition ObjectGuid.h:435
@ TYPEID_AREATRIGGER
Definition ObjectGuid.h:49
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
AreaTriggerTemplate const * GetTemplate() const
::Movement::Spline< float > const & GetSpline() const
GuidUnorderedSet const & GetInsideUnits() const
AreaTriggerCreateProperties const * _areaTriggerCreateProperties
uint32 GetTimeToTargetExtraScale() const
bool HasAreaTriggerFlag(AreaTriggerFieldFlags flag) const
bool HasSplines() const
std::vector< Position > _polygonVertices
ObjectGuid::LowType _spawnId
bool HasActionSetFlag(AreaTriggerActionSetFlag flag) const
float GetShapeProgress() const
QuaternionData _rotation
int32 _duration
UF::AreaTriggerOrbit const & GetOrbit() const
EnumFlag< AreaTriggerFieldFlags > GetAreaTriggerFlags() const
AreaTriggerAI * AI()
ObjectGuid GetOwnerGUID() const override
void SetTimeToTargetPos(uint32 timeToTargetPos)
ObjectGuid const & GetCasterGuid() const
void RelocateStationaryPosition(Position const &pos)
bool _reachedDestination
int32 GetTotalDuration() const
Position _stationaryPosition
float GetOverridePosProgress() const
Position const & GetStationaryPosition() const override
std::unique_ptr< AreaTriggerAI > _ai
uint32 GetTimeToTargetPos() const
ObjectGuid _targetGuid
bool IsServerSide() const
float GetExtraScaleProgress() const
uint32 GetSpellId() const
void SetTimeToTargetShape(uint32 timeToTargetShape)
bool IsRemoved() const
void SetTimeToTarget(uint32 timeToTarget)
UF::UpdateField< UF::AreaTriggerData, int32(WowCS::EntityFragment::CGObject), TYPEID_AREATRIGGER > m_areaTriggerData
QuaternionData _verticesUpdatePreviousRotation
void SetAreaTriggerFlag(AreaTriggerFieldFlags flag)
uint32 GetTimeToTarget() const
GuidUnorderedSet _insideUnits
uint32 GetTimeToTargetScale() const
bool IsStaticSpawn() const
uint32 GetTimeToTargetShape() const
AreaTriggerTemplate const * _areaTriggerTemplate
void SetTimeToTargetScale(uint32 timeToTargetScale)
void RemoveAreaTriggerFlag(AreaTriggerFieldFlags flag)
float GetScaleProgress() const
bool IsCustom() const
AuraEffect const * _aurEff
AuraEffect const * GetAuraEffect() const
ObjectGuid GetCreatorGUID() const override
void ReplaceAllAreaTriggerFlags(AreaTriggerFieldFlags flag)
void SetTimeToTargetExtraScale(uint32 timeToTargetExtraScale)
int32 GetDuration() const
bool HasOrbit() const
AreaTriggerCreateProperties const * GetCreateProperties() const
int32 _totalDuration
void Delay(int32 delaytime)
std::unique_ptr<::Movement::Spline< float > > _spline
void SetPathTarget(ObjectGuid pathTarget)
void SetUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type value)
Definition BaseEntity.h:221
void SetUpdateFieldFlagValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type flag)
Definition BaseEntity.h:228
void RemoveUpdateFieldFlagValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type flag)
Definition BaseEntity.h:235
Definition Map.h:227
uint64 LowType
Definition ObjectGuid.h:321
virtual void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer &data, Player const *target) const =0
virtual void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer &data, Player const *target) const =0
virtual void ClearValuesChangesMask()
Definition Object.cpp:130
Definition Spell.h:277
Definition Unit.h:647
void AddToWorld() override
Definition Object.cpp:363
void RemoveFromWorld() override
Definition Object.cpp:369
virtual bool IsNeverVisibleFor(WorldObject const *seer, bool allowServersideObjects) const
Definition Object.h:605
virtual uint32 GetFaction() const =0
virtual void Update(uint32 diff)
Definition Object.cpp:243
UpdateFieldFlag
Definition UpdateField.h:37
std::conditional_t< std::is_base_of_v< HasChangesMaskTag, T >, MutableFieldReferenceWithChangesMask< T, PublicSet >, MutableFieldReferenceNoChangesMask< T, PublicSet > > MutableFieldReference
std::variant< float, Points > Curve
std::array< DBCPosition2D, 2 > Points
ValuesUpdateForPlayerWithMaskSender(AreaTrigger const *owner)
Definition AreaTrigger.h:92
UpdateField< ObjectGuid, 0, 20 > OrbitPathTarget
UpdateField< uint32, 0, 27 > Flags
UpdateField< uint32, 0, 12 > TimeToTargetPos
UpdateField< uint32, 0, 13 > TimeToTargetShape
UpdateField< uint32, 0, 11 > TimeToTargetExtraScale
UpdateField< uint32, 0, 10 > TimeToTargetScale
UpdateField< uint32, 0, 9 > TimeToTarget