TrinityCore
DynamicObject.cpp
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#include "DynamicObject.h"
19#include "Common.h"
20#include "GameTime.h"
21#include "Log.h"
22#include "Map.h"
23#include "ObjectAccessor.h"
24#include "PhasingHandler.h"
25#include "Player.h"
26#include "ScriptMgr.h"
27#include "SpellAuras.h"
28#include "SpellInfo.h"
29#include "SpellMgr.h"
30#include "Transport.h"
31#include "Unit.h"
32#include "UpdateData.h"
33
34DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject),
35 _aura(nullptr), _removedAura(nullptr), _caster(nullptr), _duration(0), _isViewpoint(false)
36{
39
41}
42
44{
45 // make sure all references were properly removed
46 ASSERT(!_aura);
49 delete _removedAura;
50}
51
53{
55 if (!IsInWorld())
56 {
60 }
61}
62
64{
66 if (IsInWorld())
67 {
68 if (_isViewpoint)
70
71 if (_aura)
72 RemoveAura();
73
74 // dynobj could get removed in Aura::RemoveAura
75 if (!IsInWorld())
76 return;
77
81 }
82}
83
84bool DynamicObject::CreateDynamicObject(ObjectGuid::LowType guidlow, Unit* caster, SpellInfo const* spell, Position const& pos, float radius, DynamicObjectType type, SpellCastVisual spellVisual)
85{
86 SetMap(caster->GetMap());
87 Relocate(pos);
88 if (!IsPositionValid())
89 {
90 TC_LOG_ERROR("misc", "DynamicObject (spell {}) not created. Suggested coordinates isn't valid (X: {} Y: {})", spell->Id, GetPositionX(), GetPositionY());
91 return false;
92 }
93
94 WorldObject::_Create(ObjectGuid::Create<HighGuid::DynamicObject>(GetMapId(), spell->Id, guidlow));
96
99
100 SetEntry(spell->Id);
101 SetObjectScale(1.0f);
103 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::Caster), caster->GetGUID());
104 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::Type), type);
106 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::SpellVisual).ModifyValue(&UF::SpellCastVisual::ScriptVisualID), spellVisual.ScriptVisualID);
107 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::SpellID), spell->Id);
108 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::Radius), radius);
110
112 setActive(true); //must before add to map to be put in world container
113
114 TransportBase* transport = caster->GetTransport();
115 if (transport)
116 {
117 float x, y, z, o;
118 pos.GetPosition(x, y, z, o);
119 transport->CalculatePassengerOffset(x, y, z, &o);
121
122 // This object must be added to transport before adding to map for the client to properly display it
123 transport->AddPassenger(this);
124 }
125
126 if (!GetMap()->AddToMap(this))
127 {
128 // Returning false will cause the object to be deleted - remove from transport
129 if (transport)
130 transport->RemovePassenger(this);
131 return false;
132 }
133
134 return true;
135}
136
138{
139 // caster has to be always available and in the same map
141 ASSERT(_caster->GetMap() == GetMap());
142
143 bool expired = false;
144
145 if (_aura)
146 {
147 if (!_aura->IsRemoved())
148 _aura->UpdateOwner(p_time, this);
149
150 // _aura may be set to null in Aura::UpdateOwner call
151 if (_aura && (_aura->IsRemoved() || _aura->IsExpired()))
152 expired = true;
153 }
154 else
155 {
156 if (GetDuration() > int32(p_time))
157 _duration -= p_time;
158 else
159 expired = true;
160 }
161
162 if (expired)
163 Remove();
164 else
165 sScriptMgr->OnDynamicObjectUpdate(this, p_time);
166}
167
169{
170 if (IsInWorld())
172}
173
175{
176 if (!_aura)
177 return _duration;
178 else
179 return _aura->GetDuration();
180}
181
183{
184 if (!_aura)
185 _duration = newDuration;
186 else
187 _aura->SetDuration(newDuration);
188}
189
191{
192 SetDuration(GetDuration() - delaytime);
193}
194
196{
197 ASSERT(!_aura && aura);
198 _aura = aura;
199}
200
202{
205 _aura = nullptr;
206 if (!_removedAura->IsRemoved())
208}
209
211{
212 if (Player* caster = _caster->ToPlayer())
213 {
214 caster->SetViewpoint(this, true);
215 _isViewpoint = true;
216 }
217}
218
220{
221 if (Player* caster = _caster->ToPlayer())
222 {
223 caster->SetViewpoint(this, false);
224 _isViewpoint = false;
225 }
226}
227
229{
231 return _caster->GetFaction();
232}
233
235{
236 ASSERT(!_caster);
239 ASSERT(_caster->GetMap() == GetMap());
241}
242
244{
247 _caster = nullptr;
248}
249
251{
252 return sSpellMgr->GetSpellInfo(GetSpellId(), GetMap()->GetDifficultyID());
253}
254
255void DynamicObject::BuildValuesCreate(ByteBuffer* data, Player const* target) const
256{
258 std::size_t sizePos = data->wpos();
259 *data << uint32(0);
260 *data << uint8(flags);
261 m_objectData->WriteCreate(*data, flags, this, target);
262 m_dynamicObjectData->WriteCreate(*data, flags, this, target);
263 data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
264}
265
266void DynamicObject::BuildValuesUpdate(ByteBuffer* data, Player const* target) const
267{
269 std::size_t sizePos = data->wpos();
270 *data << uint32(0);
272
274 m_objectData->WriteUpdate(*data, flags, this, target);
275
277 m_dynamicObjectData->WriteUpdate(*data, flags, this, target);
278
279 data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
280}
281
283 UF::DynamicObjectData::Mask const& requestedDynamicObjectMask, Player const* target) const
284{
286 if (requestedObjectMask.IsAnySet())
287 valuesMask.Set(TYPEID_OBJECT);
288
289 if (requestedDynamicObjectMask.IsAnySet())
290 valuesMask.Set(TYPEID_DYNAMICOBJECT);
291
293 std::size_t sizePos = buffer.wpos();
294 buffer << uint32(0);
295 buffer << uint32(valuesMask.GetBlock(0));
296
297 if (valuesMask[TYPEID_OBJECT])
298 m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
299
300 if (valuesMask[TYPEID_DYNAMICOBJECT])
301 m_dynamicObjectData->WriteUpdate(buffer, requestedDynamicObjectMask, true, this, target);
302
303 buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
304
305 data->AddUpdateBlock();
306}
307
309{
310 UpdateData udata(Owner->GetMapId());
311 WorldPacket packet;
312
314
315 udata.BuildPacket(&packet);
316 player->SendDirectMessage(&packet);
317}
318
320{
323}
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
uint16 flags
Definition: DisableMgr.cpp:49
DynamicObjectType
Definition: DynamicObject.h:30
#define ASSERT
Definition: Errors.h:68
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
@ TYPEID_OBJECT
Definition: ObjectGuid.h:35
@ TYPEID_DYNAMICOBJECT
Definition: ObjectGuid.h:44
@ TYPEMASK_DYNAMICOBJECT
Definition: ObjectGuid.h:64
#define sScriptMgr
Definition: ScriptMgr.h:1418
@ AURA_REMOVE_BY_DEFAULT
#define sSpellMgr
Definition: SpellMgr.h:849
bool IsRemoved() const
Definition: SpellAuras.h:205
int32 GetDuration() const
Definition: SpellAuras.h:173
void UpdateOwner(uint32 diff, WorldObject *owner)
Definition: SpellAuras.cpp:773
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:892
bool IsExpired() const
Definition: SpellAuras.h:177
void _Remove(AuraRemoveMode removeMode)
Definition: SpellAuras.cpp:592
size_t wpos() const
Definition: ByteBuffer.h:412
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:220
void SetAura(Aura *aura)
void BuildValuesUpdate(ByteBuffer *data, Player const *target) const override
void SetCasterViewpoint()
void UnbindFromCaster()
void Update(uint32 p_time) override
void AddToWorld() override
DynamicObject(bool isWorldObject)
SpellInfo const * GetSpellInfo() const
void SetDuration(int32 newDuration)
void RemoveCasterViewpoint()
uint32 GetSpellId() const
Definition: DynamicObject.h:79
void BuildValuesCreate(ByteBuffer *data, Player const *target) const override
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, SpellInfo const *spell, Position const &pos, float radius, DynamicObjectType type, SpellCastVisual spellVisual)
void ClearUpdateMask(bool remove) override
ObjectGuid GetCasterGUID() const
Definition: DynamicObject.h:81
uint32 GetFaction() const override
Aura * _removedAura
Definition: DynamicObject.h:90
void Delay(int32 delaytime)
UF::UpdateField< UF::DynamicObjectData, 0, TYPEID_DYNAMICOBJECT > m_dynamicObjectData
Definition: DynamicObject.h:86
int32 GetDuration() const
void BuildValuesUpdateForPlayerWithMask(UpdateData *data, UF::ObjectData::Mask const &requestedObjectMask, UF::DynamicObjectData::Mask const &requestedDynamicObjectMask, Player const *target) const
void RemoveFromWorld() override
MapStoredObjectTypesContainer & GetObjectsStore()
Definition: Map.h:422
uint64 LowType
Definition: ObjectGuid.h:278
uint16 m_objectType
Definition: Object.h:401
ObjectGuid const & GetGUID() const
Definition: Object.h:160
bool IsInWorld() const
Definition: Object.h:154
UF::UpdateField< UF::ObjectData, 0, TYPEID_OBJECT > m_objectData
Definition: Object.h:267
CreateObjectBits m_updateFlag
Definition: Object.h:404
virtual void ClearUpdateMask(bool remove)
Definition: Object.cpp:790
void SetUpdateFieldValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type value)
Definition: Object.h:287
UF::UpdateFieldHolder m_values
Definition: Object.h:266
void _Create(ObjectGuid const &guid)
Definition: Object.cpp:101
ByteBuffer & PrepareValuesUpdateBuffer(UpdateData *data) const
Definition: Object.cpp:225
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
void SetEntry(uint32 entry)
Definition: Object.h:162
virtual void SetObjectScale(float scale)
Definition: Object.h:165
virtual UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const *target) const
Definition: Object.cpp:770
TypeID m_objectTypeId
Definition: Object.h:403
static Player * ToPlayer(Object *o)
Definition: Object.h:213
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:6324
uint32 const Id
Definition: SpellInfo.h:325
virtual TransportBase * RemovePassenger(WorldObject *passenger)=0
virtual void CalculatePassengerOffset(float &x, float &y, float &z, float *o=nullptr) const =0
This method transforms supplied global coordinates into local offsets.
virtual void AddPassenger(WorldObject *passenger)=0
bool Remove(KEY_TYPE const &handle)
bool Insert(KEY_TYPE const &handle, SPECIFIC_TYPE *obj)
Mask const & GetChangesMask() const
Definition: UpdateField.h:605
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:683
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:690
bool HasChanged(uint32 index) const
Definition: UpdateField.h:701
uint32 GetChangedObjectTypeMask() const
Definition: UpdateField.h:696
Definition: Unit.h:627
void _UnregisterDynObject(DynamicObject *dynObj)
Definition: Unit.cpp:5157
void _RegisterDynObject(DynamicObject *dynObj)
Definition: Unit.cpp:5150
uint32 GetFaction() const override
Definition: Unit.h:858
bool BuildPacket(WorldPacket *packet)
Definition: UpdateData.cpp:40
void AddUpdateBlock()
Definition: UpdateData.h:49
uint32 GetBlock(uint32 index) const
Definition: UpdateMask.h:53
void Set(uint32 index)
Definition: UpdateMask.h:84
constexpr uint32 GetMapId() const
Definition: Position.h:201
Map * GetMap() const
Definition: Object.h:624
void AddToWorld() override
Definition: Object.cpp:1011
void RemoveFromWorld() override
Definition: Object.cpp:1017
void SetZoneScript()
Definition: Object.cpp:2011
TransportBase * GetTransport() const
Definition: Object.h:750
void setActive(bool isActiveObject)
Definition: Object.cpp:922
virtual void SetMap(Map *map)
Definition: Object.cpp:1794
void AddObjectToRemoveList()
Definition: Object.cpp:1824
void UpdatePositionData()
Definition: Object.cpp:992
bool IsStoredInWorldObjectGridContainer() const
Definition: Object.cpp:911
MovementInfo m_movementInfo
Definition: Object.h:761
uint32 GetGameTimeMS()
Definition: GameTime.cpp:49
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
UpdateFieldFlag
Definition: UpdateField.h:34
bool Stationary
Definition: Object.h:88
struct MovementInfo::TransportInfo transport
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
bool IsPositionValid() const
Definition: Position.cpp:42
constexpr void Relocate(float x, float y)
Definition: Position.h:63
uint32 ScriptVisualID
Definition: SpellDefines.h:505
uint32 SpellXSpellVisualID
Definition: SpellDefines.h:504
UpdateField< ObjectGuid, 0, 1 > Caster
UpdateField< uint8, 0, 2 > Type
UpdateField< uint32, 0, 6 > CastTime
UpdateField< float, 0, 5 > Radius
UpdateField< UF::SpellCastVisual, 0, 3 > SpellVisual
UpdateField< int32, 0, 4 > SpellID