2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "ByteBuffer.h"
24 #include "UpdateFields.h"
25 #include "UpdateData.h"
26 #include "GameSystem/GridReference.h"
27 #include "ObjectDefines.h"
32 #define CONTACT_DISTANCE 0.5f
33 #define INTERACTION_DISTANCE 5.0f
34 #define ATTACK_DISTANCE 5.0f
35 #define MAX_VISIBILITY_DISTANCE (5*SIZE_OF_GRID_CELL/2.0f) // max distance for visible object show, limited by active zone for player based at cell size (active zone = 5x5 cells)
36 #define DEFAULT_VISIBILITY_DISTANCE (SIZE_OF_GRID_CELL) // default visible distance
38 #define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
42 TYPEMASK_OBJECT
= 0x0001,
43 TYPEMASK_ITEM
= 0x0002,
44 TYPEMASK_CONTAINER
= 0x0006, // TYPEMASK_ITEM | 0x0004
45 TYPEMASK_UNIT
= 0x0008,
46 TYPEMASK_PLAYER
= 0x0010,
47 TYPEMASK_GAMEOBJECT
= 0x0020,
48 TYPEMASK_DYNAMICOBJECT
= 0x0040,
49 TYPEMASK_CORPSE
= 0x0080,
50 TYPEMASK_AIGROUP
= 0x0100,
51 TYPEMASK_AREATRIGGER
= 0x0200
61 TYPEID_GAMEOBJECT
= 5,
62 TYPEID_DYNAMICOBJECT
= 6,
65 TYPEID_AREATRIGGER
= 9
68 uint32
GuidHigh2TypeId(uint32 guid_hi
);
72 TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
= 1, // despawns after a specified time OR when the creature disappears
73 TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN
= 2, // despawns after a specified time OR when the creature dies
74 TEMPSUMMON_TIMED_DESPAWN
= 3, // despawns after a specified time
75 TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
= 4, // despawns after a specified time after the creature is out of combat
76 TEMPSUMMON_CORPSE_DESPAWN
= 5, // despawns instantly after death
77 TEMPSUMMON_CORPSE_TIMED_DESPAWN
= 6, // despawns after a specified time after death
78 TEMPSUMMON_DEAD_DESPAWN
= 7, // despawns when the creature disappears
79 TEMPSUMMON_MANUAL_DESPAWN
= 8 // despawns when UnSummon() is called
92 typedef HM_NAMESPACE::hash_map
<Player
*, UpdateData
> UpdateDataMapType
;
101 explicit WorldLocation(uint32 mapid
= 0, float x
= 0, float y
= 0, float z
= 0, float o
= 0)
102 : mapid(mapid
), x(x
), y(y
), z(z
), o(o
) {}
103 WorldLocation(WorldLocation
const &loc
)
104 : mapid(loc
.mapid
), x(loc
.x
), y(loc
.y
), z(loc
.z
), o(loc
.o
) {}
107 class MANGOS_DLL_SPEC Object
112 const bool& IsInWorld() const { return m_inWorld
; }
113 virtual void AddToWorld()
120 // synchronize values mirror with values array (changes will send in updatecreate opcode any way
121 ClearUpdateMask(true);
123 virtual void RemoveFromWorld()
125 // if we remove from world then sending changes not required
127 ClearUpdateMask(true);
131 const uint64
& GetGUID() const { return GetUInt64Value(0); }
132 uint32
GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); }
133 uint32
GetGUIDMid() const { return GUID_ENPART(GetUInt64Value(0)); }
134 uint32
GetGUIDHigh() const { return GUID_HIPART(GetUInt64Value(0)); }
135 const ByteBuffer
& GetPackGUID() const { return m_PackGUID
; }
136 uint32
GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY
); }
137 void SetEntry(uint32 entry
) { SetUInt32Value(OBJECT_FIELD_ENTRY
, entry
); }
139 uint8
GetTypeId() const { return m_objectTypeId
; }
140 bool isType(uint16 mask
) const { return (mask
& m_objectType
); }
142 virtual void BuildCreateUpdateBlockForPlayer( UpdateData
*data
, Player
*target
) const;
143 void SendUpdateToPlayer(Player
* player
);
145 void BuildValuesUpdateBlockForPlayer( UpdateData
*data
, Player
*target
) const;
146 void BuildOutOfRangeUpdateBlock( UpdateData
*data
) const;
147 void BuildMovementUpdateBlock( UpdateData
* data
, uint32 flags
= 0 ) const;
148 void BuildUpdate(UpdateDataMapType
&);
150 virtual void DestroyForPlayer( Player
*target
) const;
152 const int32
& GetInt32Value( uint16 index
) const
154 ASSERT( index
< m_valuesCount
|| PrintIndexError( index
, false) );
155 return m_int32Values
[ index
];
158 const uint32
& GetUInt32Value( uint16 index
) const
160 ASSERT( index
< m_valuesCount
|| PrintIndexError( index
, false) );
161 return m_uint32Values
[ index
];
164 const uint64
& GetUInt64Value( uint16 index
) const
166 ASSERT( index
+ 1 < m_valuesCount
|| PrintIndexError( index
, false) );
167 return *((uint64
*)&(m_uint32Values
[ index
]));
170 const float& GetFloatValue( uint16 index
) const
172 ASSERT( index
< m_valuesCount
|| PrintIndexError( index
, false ) );
173 return m_floatValues
[ index
];
176 uint8
GetByteValue( uint16 index
, uint8 offset
) const
178 ASSERT( index
< m_valuesCount
|| PrintIndexError( index
, false) );
179 ASSERT( offset
< 4 );
180 return *(((uint8
*)&m_uint32Values
[ index
])+offset
);
183 uint8
GetUInt16Value( uint16 index
, uint8 offset
) const
185 ASSERT( index
< m_valuesCount
|| PrintIndexError( index
, false) );
186 ASSERT( offset
< 2 );
187 return *(((uint16
*)&m_uint32Values
[ index
])+offset
);
190 void SetInt32Value( uint16 index
, int32 value
);
191 void SetUInt32Value( uint16 index
, uint32 value
);
192 void SetUInt64Value( uint16 index
, const uint64
&value
);
193 void SetFloatValue( uint16 index
, float value
);
194 void SetByteValue( uint16 index
, uint8 offset
, uint8 value
);
195 void SetUInt16Value( uint16 index
, uint8 offset
, uint16 value
);
196 void SetInt16Value( uint16 index
, uint8 offset
, int16 value
) { SetUInt16Value(index
,offset
,(uint16
)value
); }
197 void SetStatFloatValue( uint16 index
, float value
);
198 void SetStatInt32Value( uint16 index
, int32 value
);
200 void ApplyModUInt32Value(uint16 index
, int32 val
, bool apply
);
201 void ApplyModInt32Value(uint16 index
, int32 val
, bool apply
);
202 void ApplyModUInt64Value(uint16 index
, int32 val
, bool apply
);
203 void ApplyModPositiveFloatValue( uint16 index
, float val
, bool apply
);
204 void ApplyModSignedFloatValue( uint16 index
, float val
, bool apply
);
206 void ApplyPercentModFloatValue(uint16 index
, float val
, bool apply
)
208 val
= val
!= -100.0f
? val
: -99.9f
;
209 SetFloatValue(index
, GetFloatValue(index
) * (apply
?(100.0f
+val
)/100.0f
: 100.0f
/ (100.0f
+val
)) );
212 void SetFlag( uint16 index
, uint32 newFlag
);
213 void RemoveFlag( uint16 index
, uint32 oldFlag
);
215 void ToggleFlag( uint16 index
, uint32 flag
)
217 if(HasFlag(index
, flag
))
218 RemoveFlag(index
, flag
);
220 SetFlag(index
, flag
);
223 bool HasFlag( uint16 index
, uint32 flag
) const
225 ASSERT( index
< m_valuesCount
|| PrintIndexError( index
, false ) );
226 return (m_uint32Values
[ index
] & flag
) != 0;
229 void ApplyModFlag( uint16 index
, uint32 flag
, bool apply
)
231 if(apply
) SetFlag(index
,flag
); else RemoveFlag(index
,flag
);
234 void SetFlag64( uint16 index
, uint64 newFlag
)
236 uint64 oldval
= GetUInt64Value(index
);
237 uint64 newval
= oldval
| newFlag
;
238 SetUInt64Value(index
,newval
);
241 void RemoveFlag64( uint16 index
, uint64 oldFlag
)
243 uint64 oldval
= GetUInt64Value(index
);
244 uint64 newval
= oldval
& ~oldFlag
;
245 SetUInt64Value(index
,newval
);
248 void ToggleFlag64( uint16 index
, uint64 flag
)
250 if(HasFlag64(index
, flag
))
251 RemoveFlag64(index
, flag
);
253 SetFlag64(index
, flag
);
256 bool HasFlag64( uint16 index
, uint64 flag
) const
258 ASSERT( index
< m_valuesCount
|| PrintIndexError( index
, false ) );
259 return (GetUInt64Value( index
) & flag
) != 0;
262 void ApplyModFlag64( uint16 index
, uint64 flag
, bool apply
)
264 if(apply
) SetFlag64(index
,flag
); else RemoveFlag64(index
,flag
);
267 void ClearUpdateMask(bool remove
);
268 void SendUpdateObjectToAllExcept(Player
* exceptPlayer
);
270 bool LoadValues(const char* data
);
272 uint16
GetValuesCount() const { return m_valuesCount
; }
274 void InitValues() { _InitValues(); }
276 virtual bool hasQuest(uint32
/* quest_id */) const { return false; }
277 virtual bool hasInvolvedQuest(uint32
/* quest_id */) const { return false; }
283 void _Create (uint32 guidlow
, uint32 entry
, HighGuid guidhigh
);
285 virtual void _SetUpdateBits(UpdateMask
*updateMask
, Player
*target
) const;
287 virtual void _SetCreateBits(UpdateMask
*updateMask
, Player
*target
) const;
288 void _BuildMovementUpdate(ByteBuffer
* data
, uint8 flags
, uint32 flags2
) const;
289 void _BuildValuesUpdate(uint8 updatetype
, ByteBuffer
*data
, UpdateMask
*updateMask
, Player
*target
) const;
293 uint8 m_objectTypeId
;
298 int32
*m_int32Values
;
299 uint32
*m_uint32Values
;
300 float *m_floatValues
;
303 uint32
*m_uint32Values_mirror
;
305 uint16 m_valuesCount
;
307 bool m_objectUpdated
;
312 ByteBuffer m_PackGUID
;
314 // for output helpfull error messages from asserts
315 bool PrintIndexError(uint32 index
, bool set
) const;
316 Object(const Object
&); // prevent generation copy constructor
317 Object
& operator=(Object
const&); // prevent generation assigment operator
320 class MANGOS_DLL_SPEC WorldObject
: public Object
323 virtual ~WorldObject ( ) {}
325 virtual void Update ( uint32
/*time_diff*/ ) { }
327 void _Create( uint32 guidlow
, HighGuid guidhigh
, uint32 mapid
);
329 void Relocate(float x
, float y
, float z
, float orientation
)
334 m_orientation
= orientation
;
337 void Relocate(float x
, float y
, float z
)
344 void Relocate(WorldLocation
const & loc
)
347 Relocate(loc
.x
, loc
.y
, loc
.z
, loc
.o
);
350 void SetOrientation(float orientation
) { m_orientation
= orientation
; }
352 float GetPositionX( ) const { return m_positionX
; }
353 float GetPositionY( ) const { return m_positionY
; }
354 float GetPositionZ( ) const { return m_positionZ
; }
355 void GetPosition( float &x
, float &y
, float &z
) const
356 { x
= m_positionX
; y
= m_positionY
; z
= m_positionZ
; }
357 void GetPosition( WorldLocation
&loc
) const
358 { loc
.mapid
= GetMapId(); GetPosition(loc
.x
, loc
.y
, loc
.z
); loc
.o
= GetOrientation(); }
359 float GetOrientation( ) const { return m_orientation
; }
360 void GetNearPoint2D( float &x
, float &y
, float distance
, float absAngle
) const;
361 void GetNearPoint( WorldObject
const* searcher
, float &x
, float &y
, float &z
, float searcher_size
, float distance2d
,float absAngle
) const;
362 void GetClosePoint(float &x
, float &y
, float &z
, float size
, float distance2d
= 0, float angle
= 0) const
364 // angle calculated from current orientation
365 GetNearPoint(NULL
,x
,y
,z
,size
,distance2d
,GetOrientation() + angle
);
367 void GetContactPoint( const WorldObject
* obj
, float &x
, float &y
, float &z
, float distance2d
= CONTACT_DISTANCE
) const
369 // angle to face `obj` to `this` using distance includes size of `obj`
370 GetNearPoint(obj
,x
,y
,z
,obj
->GetObjectSize(),distance2d
,GetAngle( obj
));
373 float GetObjectSize() const
375 return ( m_valuesCount
> UNIT_FIELD_BOUNDINGRADIUS
) ? m_floatValues
[UNIT_FIELD_BOUNDINGRADIUS
] : DEFAULT_WORLD_OBJECT_SIZE
;
377 bool IsPositionValid() const;
378 void UpdateGroundPositionZ(float x
, float y
, float &z
) const;
380 void GetRandomPoint( float x
, float y
, float z
, float distance
, float &rand_x
, float &rand_y
, float &rand_z
) const;
382 void SetMapId(uint32 newMap
) { m_mapId
= newMap
; }
384 uint32
GetMapId() const { return m_mapId
; }
386 uint32
GetZoneId() const;
387 uint32
GetAreaId() const;
389 InstanceData
* GetInstanceData();
391 const char* GetName() const { return m_name
.c_str(); }
392 void SetName(std::string newname
) { m_name
=newname
; }
394 float GetDistance( const WorldObject
* obj
) const;
395 float GetDistance(const float x
, const float y
, const float z
) const;
396 float GetDistance2d(const WorldObject
* obj
) const;
397 float GetDistance2d(const float x
, const float y
) const;
398 float GetDistanceZ(const WorldObject
* obj
) const;
399 bool IsInMap(const WorldObject
* obj
) const { return GetMapId()==obj
->GetMapId() && GetInstanceId()==obj
->GetInstanceId(); }
400 bool IsWithinDistInMap(const WorldObject
* obj
, const float dist2compare
) const;
401 bool IsWithinLOS(const float x
, const float y
, const float z
) const;
402 bool IsWithinLOSInMap(const WorldObject
* obj
) const;
404 float GetAngle( const WorldObject
* obj
) const;
405 float GetAngle( const float x
, const float y
) const;
406 bool HasInArc( const float arcangle
, const WorldObject
* obj
) const;
408 virtual void SendMessageToSet(WorldPacket
*data
, bool self
);
409 virtual void SendMessageToSetInRange(WorldPacket
*data
, float dist
, bool self
);
410 void BuildHeartBeatMsg( WorldPacket
*data
) const;
411 void BuildTeleportAckMsg( WorldPacket
*data
, float x
, float y
, float z
, float ang
) const;
412 bool IsBeingTeleported() { return mSemaphoreTeleport
; }
413 void SetSemaphoreTeleport(bool semphsetting
) { mSemaphoreTeleport
= semphsetting
; }
415 void MonsterSay(const char* text
, uint32 language
, uint64 TargetGuid
);
416 void MonsterYell(const char* text
, uint32 language
, uint64 TargetGuid
);
417 void MonsterTextEmote(const char* text
, uint64 TargetGuid
, bool IsBossEmote
= false);
418 void MonsterWhisper(const char* text
, uint64 receiver
, bool IsBossWhisper
= false);
419 void MonsterSay(int32 textId
, uint32 language
, uint64 TargetGuid
);
420 void MonsterYell(int32 textId
, uint32 language
, uint64 TargetGuid
);
421 void MonsterTextEmote(int32 textId
, uint64 TargetGuid
, bool IsBossEmote
= false);
422 void MonsterWhisper(int32 textId
, uint64 receiver
, bool IsBossWhisper
= false);
423 void BuildMonsterChat(WorldPacket
*data
, uint8 msgtype
, char const* text
, uint32 language
, char const* name
, uint64 TargetGuid
) const;
425 void SendObjectDeSpawnAnim(uint64 guid
);
427 virtual void SaveRespawnTime() {}
429 uint32
GetInstanceId() const { return m_InstanceId
; }
430 void SetInstanceId(uint32 val
) { m_InstanceId
= val
; }
432 void AddObjectToRemoveList();
434 // main visibility check function in normal case (ignore grey zone distance check)
435 bool isVisibleFor(Player
const* u
) const { return isVisibleForInState(u
,false); }
437 // low level function for visibility change code, must be define in all main world object subclasses
438 virtual bool isVisibleForInState(Player
const* u
, bool inVisibleList
) const = 0;
440 Map
* GetMap() const;
441 Map
const* GetBaseMap() const;
442 Creature
* SummonCreature(uint32 id
, float x
, float y
, float z
, float ang
,TempSummonType spwtype
,uint32 despwtime
);
445 explicit WorldObject();
456 bool mSemaphoreTeleport
;