TrinityCore
Loading...
Searching...
No Matches
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#include "WorldPacket.h"
34
35DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject),
36 _aura(nullptr), _removedAura(nullptr), _caster(nullptr), _duration(0), _isViewpoint(false)
37{
39
41
43}
44
46{
47 // make sure all references were properly removed
48 ASSERT(!_aura);
51 delete _removedAura;
52}
53
64
66{
68 if (IsInWorld())
69 {
70 if (_isViewpoint)
72
73 if (_aura)
74 RemoveAura();
75
76 // dynobj could get removed in Aura::RemoveAura
77 if (!IsInWorld())
78 return;
79
83 }
84}
85
86bool DynamicObject::CreateDynamicObject(ObjectGuid::LowType guidlow, Unit* caster, SpellInfo const* spell, Position const& pos, float radius, DynamicObjectType type, SpellCastVisual spellVisual)
87{
88 SetMap(caster->GetMap());
89 Relocate(pos);
90 if (!IsPositionValid())
91 {
92 TC_LOG_ERROR("misc", "DynamicObject (spell {}) not created. Suggested coordinates isn't valid (X: {} Y: {})", spell->Id, GetPositionX(), GetPositionY());
93 return false;
94 }
95
96 _Create(ObjectGuid::Create<HighGuid::DynamicObject>(GetMapId(), spell->Id, guidlow));
98
101
102 SetEntry(spell->Id);
103 SetObjectScale(1.0f);
105 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::Caster), caster->GetGUID());
106 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::Type), type);
108 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::SpellVisual).ModifyValue(&UF::SpellCastVisual::ScriptVisualID), spellVisual.ScriptVisualID);
109 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::SpellID), spell->Id);
110 SetUpdateFieldValue(dynamicObjectData.ModifyValue(&UF::DynamicObjectData::Radius), radius);
112
114 setActive(true); //must before add to map to be put in world container
115
116 TransportBase* transport = caster->GetTransport();
117 if (transport)
118 {
119 // This object must be added to transport before adding to map for the client to properly display it
120 transport->AddPassenger(this, transport->GetPositionOffsetTo(pos));
121 }
122
123 if (!GetMap()->AddToMap(this))
124 {
125 // Returning false will cause the object to be deleted - remove from transport
126 if (transport)
127 transport->RemovePassenger(this);
128 return false;
129 }
130
131 return true;
132}
133
135{
136 // caster has to be always available and in the same map
138 ASSERT(_caster->GetMap() == GetMap());
139
140 bool expired = false;
141
142 if (_aura)
143 {
144 if (!_aura->IsRemoved())
145 _aura->UpdateOwner(p_time, this);
146
147 // _aura may be set to null in Aura::UpdateOwner call
148 if (_aura && (_aura->IsRemoved() || _aura->IsExpired()))
149 expired = true;
150 }
151 else
152 {
153 if (GetDuration() > int32(p_time))
154 _duration -= p_time;
155 else
156 expired = true;
157 }
158
159 if (expired)
160 Remove();
161 else
162 sScriptMgr->OnDynamicObjectUpdate(this, p_time);
163}
164
166{
167 if (IsInWorld())
169}
170
172{
173 if (!_aura)
174 return _duration;
175 else
176 return _aura->GetDuration();
177}
178
180{
181 if (!_aura)
182 _duration = newDuration;
183 else
184 _aura->SetDuration(newDuration);
185}
186
188{
189 SetDuration(GetDuration() - delaytime);
190}
191
193{
194 ASSERT(!_aura && aura);
195 _aura = aura;
196}
197
206
208{
209 if (Player* caster = _caster->ToPlayer())
210 {
211 caster->SetViewpoint(this, true);
212 _isViewpoint = true;
213 }
214}
215
217{
218 if (Player* caster = _caster->ToPlayer())
219 {
220 caster->SetViewpoint(this, false);
221 _isViewpoint = false;
222 }
223}
224
226{
228 return _caster->GetFaction();
229}
230
239
241{
244 _caster = nullptr;
245}
246
248{
249 return sSpellMgr->GetSpellInfo(GetSpellId(), GetMap()->GetDifficultyID());
250}
251
253{
254 m_objectData->WriteCreate(flags, data, target, this);
255 m_dynamicObjectData->WriteCreate(flags, data, target, this);
256}
257
259{
261
263 m_objectData->WriteUpdate(flags, data, target, this);
264
266 m_dynamicObjectData->WriteUpdate(flags, data, target, this);
267}
268
270 UF::DynamicObjectData::Mask const& requestedDynamicObjectMask, Player const* target, bool ignoreNestedChangesMask) const
271{
274 if (requestedObjectMask.IsAnySet())
275 valuesMask.Set(TYPEID_OBJECT);
276
277 if (requestedDynamicObjectMask.IsAnySet())
278 valuesMask.Set(TYPEID_DYNAMICOBJECT);
279
281 std::size_t sizePos = buffer.wpos();
282 buffer << uint32(0);
284 buffer << uint32(valuesMask.GetBlock(0));
285
286 if (valuesMask[TYPEID_OBJECT])
287 m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, ignoreNestedChangesMask);
288
289 if (valuesMask[TYPEID_DYNAMICOBJECT])
290 m_dynamicObjectData->WriteUpdate(requestedDynamicObjectMask, buffer, target, this, ignoreNestedChangesMask);
291
292 buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
293
294 data->AddUpdateBlock();
295}
296
307
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
uint16 flags
DynamicObjectType
#define ASSERT
Definition Errors.h:80
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
@ TYPEID_OBJECT
Definition ObjectGuid.h:38
@ TYPEID_DYNAMICOBJECT
Definition ObjectGuid.h:47
#define sScriptMgr
Definition ScriptMgr.h:1449
@ AURA_REMOVE_BY_DEFAULT
#define sSpellMgr
Definition SpellMgr.h:812
bool IsRemoved() const
Definition SpellAuras.h:254
int32 GetDuration() const
Definition SpellAuras.h:222
void UpdateOwner(uint32 diff, WorldObject *owner)
void SetDuration(int32 duration, bool withMods=false)
bool IsExpired() const
Definition SpellAuras.h:226
void _Remove(AuraRemoveMode removeMode)
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
void SetUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type value)
Definition BaseEntity.h:221
WowCS::EntityFragmentsHolder m_entityFragments
Definition BaseEntity.h:353
UF::UpdateFieldHolder m_values
Definition BaseEntity.h:205
bool IsInWorld() const
Definition BaseEntity.h:158
void _Create(ObjectGuid const &guid)
Definition BaseEntity.h:218
CreateObjectBits m_updateFlag
Definition BaseEntity.h:352
ByteBuffer & PrepareValuesUpdateBuffer(UpdateData *data) const
TypeID m_objectTypeId
Definition BaseEntity.h:351
virtual UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const *target) const
size_t wpos() const
Definition ByteBuffer.h:461
void put(std::size_t pos, T value)
Definition ByteBuffer.h:260
void SetAura(Aura *aura)
UF::UpdateField< UF::DynamicObjectData, int32(WowCS::EntityFragment::CGObject), TYPEID_DYNAMICOBJECT > m_dynamicObjectData
void SetCasterViewpoint()
void Update(uint32 p_time) override
void AddToWorld() override
void BuildValuesUpdateForPlayerWithMask(UpdateData *data, UF::ObjectData::Mask const &requestedObjectMask, UF::DynamicObjectData::Mask const &requestedDynamicObjectMask, Player const *target, bool ignoreNestedChangesMask) const
DynamicObject(bool isWorldObject)
SpellInfo const * GetSpellInfo() const
void SetDuration(int32 newDuration)
void RemoveCasterViewpoint()
uint32 GetSpellId() const
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, SpellInfo const *spell, Position const &pos, float radius, DynamicObjectType type, SpellCastVisual spellVisual)
void ClearValuesChangesMask() override
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer &data, Player const *target) const override
ObjectGuid GetCasterGUID() const
uint32 GetFaction() const override
Aura * _removedAura
void Delay(int32 delaytime)
int32 GetDuration() const
void RemoveFromWorld() override
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer &data, Player const *target) const override
MapStoredObjectTypesContainer & GetObjectsStore()
Definition Map.h:458
uint64 LowType
Definition ObjectGuid.h:321
Player * ToPlayer()
Definition Object.h:126
void BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer &data, EnumFlag< UF::UpdateFieldFlag > flags) const
Definition Object.cpp:113
void SetEntry(uint32 entry)
Definition Object.h:90
virtual void ClearValuesChangesMask()
Definition Object.cpp:130
virtual void SetObjectScale(float scale)
Definition Object.h:93
UF::UpdateField< UF::ObjectData, int32(WowCS::EntityFragment::CGObject), TYPEID_OBJECT > m_objectData
Definition Object.h:161
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6283
uint32 const Id
Definition SpellInfo.h:328
virtual Position GetPositionOffsetTo(Position const &endPos) const =0
This method transforms supplied global coordinates into local offsets.
virtual void AddPassenger(WorldObject *passenger, Position const &offset)=0
virtual TransportBase * RemovePassenger(WorldObject *passenger)=0
Mask const & GetChangesMask() const
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
bool HasChanged(uint32 index) const
Definition BaseEntity.h:83
uint32 GetChangedObjectTypeMask() const
Definition BaseEntity.h:81
Definition Unit.h:635
void _UnregisterDynObject(DynamicObject *dynObj)
Definition Unit.cpp:5297
void _RegisterDynObject(DynamicObject *dynObj)
Definition Unit.cpp:5290
uint32 GetFaction() const override
Definition Unit.h:871
bool BuildPacket(WorldPacket *packet)
void AddUpdateBlock()
Definition UpdateData.h:46
constexpr uint32 GetBlock(uint32 index) const
Definition UpdateMask.h:59
constexpr void Set(uint32 index)
Definition UpdateMask.h:91
constexpr uint32 GetMapId() const
Definition Position.h:216
Map * GetMap() const
Definition Object.h:411
void AddToWorld() override
Definition Object.cpp:365
void RemoveFromWorld() override
Definition Object.cpp:371
void SetZoneScript()
Definition Object.cpp:1384
TransportBase * GetTransport() const
Definition Object.h:537
void setActive(bool isActiveObject)
Definition Object.cpp:276
virtual void SetMap(Map *map)
Definition Object.cpp:1144
void AddObjectToRemoveList()
Definition Object.cpp:1174
void UpdatePositionData()
Definition Object.cpp:346
bool IsStoredInWorldObjectGridContainer() const
Definition Object.cpp:265
uint32 GetGameTimeMS()
Definition GameTime.cpp:57
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
UpdateFieldFlag
Definition UpdateField.h:37
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
bool IsPositionValid() const
Definition Position.cpp:42
constexpr void Relocate(float x, float y)
Definition Position.h:74
uint32 SpellXSpellVisualID
bool Insert(ValueType< ObjectType > object)
bool Remove(ValueType< ObjectType > object)
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
void Add(EntityFragment fragment, bool update, void const *data=nullptr)