[9581] Fixed apply damage reduction to melee/ranged damage.
[getmangos.git] / src / game / Object.h
blob3b805df939c95707888e1afff4438f301893e1b1
1 /*
2 * Copyright (C) 2005-2010 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
19 #ifndef _OBJECT_H
20 #define _OBJECT_H
22 #include "Common.h"
23 #include "ByteBuffer.h"
24 #include "UpdateFields.h"
25 #include "UpdateData.h"
26 #include "GameSystem/GridReference.h"
27 #include "ObjectGuid.h"
29 #include <set>
30 #include <string>
32 #define CONTACT_DISTANCE 0.5f
33 #define INTERACTION_DISTANCE 5.0f
34 #define ATTACK_DISTANCE 5.0f
35 #define MAX_VISIBILITY_DISTANCE 333.0f // max distance for visible object show, limited in 333 yards
36 #define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
37 #define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
38 #define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
40 #define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
41 #define MAX_STEALTH_DETECT_RANGE 45.0f
43 uint32 GuidHigh2TypeId(uint32 guid_hi);
45 enum TempSummonType
47 TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears
48 TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN = 2, // despawns after a specified time OR when the creature dies
49 TEMPSUMMON_TIMED_DESPAWN = 3, // despawns after a specified time
50 TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT = 4, // despawns after a specified time after the creature is out of combat
51 TEMPSUMMON_CORPSE_DESPAWN = 5, // despawns instantly after death
52 TEMPSUMMON_CORPSE_TIMED_DESPAWN = 6, // despawns after a specified time after death
53 TEMPSUMMON_DEAD_DESPAWN = 7, // despawns when the creature disappears
54 TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called
57 enum PhaseMasks
59 PHASEMASK_NORMAL = 0x00000001,
60 PHASEMASK_ANYWHERE = 0xFFFFFFFF
63 class WorldPacket;
64 class UpdateData;
65 class WorldSession;
66 class Creature;
67 class Player;
68 class Unit;
69 class Map;
70 class UpdateMask;
71 class InstanceData;
73 typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
75 struct WorldLocation
77 uint32 mapid;
78 float coord_x;
79 float coord_y;
80 float coord_z;
81 float orientation;
82 explicit WorldLocation(uint32 _mapid = 0, float _x = 0, float _y = 0, float _z = 0, float _o = 0)
83 : mapid(_mapid), coord_x(_x), coord_y(_y), coord_z(_z), orientation(_o) {}
84 WorldLocation(WorldLocation const &loc)
85 : mapid(loc.mapid), coord_x(loc.coord_x), coord_y(loc.coord_y), coord_z(loc.coord_z), orientation(loc.orientation) {}
88 class MANGOS_DLL_SPEC Object
90 public:
91 virtual ~Object ( );
93 const bool& IsInWorld() const { return m_inWorld; }
94 virtual void AddToWorld()
96 if(m_inWorld)
97 return;
99 m_inWorld = true;
101 // synchronize values mirror with values array (changes will send in updatecreate opcode any way
102 ClearUpdateMask(false); // false - we can't have update dat in update queue before adding to world
104 virtual void RemoveFromWorld()
106 // if we remove from world then sending changes not required
107 ClearUpdateMask(true);
108 m_inWorld = false;
111 ObjectGuid const& GetObjectGuid() const { return *reinterpret_cast<ObjectGuid const*>(&GetUInt64Value(0)); }
113 const uint64& GetGUID() const { return GetUInt64Value(0); }
114 uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); }
115 PackedGuid const& GetPackGUID() const { return m_PackGUID; }
116 uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
117 void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
119 uint8 GetTypeId() const { return m_objectTypeId; }
120 bool isType(uint16 mask) const { return (mask & m_objectType); }
122 virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
123 void SendCreateUpdateToPlayer(Player* player);
125 // must be overwrite in appropriate subclasses (WorldObject, Item currently), or will crash
126 virtual void AddToClientUpdateList();
127 virtual void RemoveFromClientUpdateList();
128 virtual void BuildUpdateData(UpdateDataMapType& update_players);
130 void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
131 void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;
132 void BuildMovementUpdateBlock( UpdateData * data, uint16 flags = 0 ) const;
134 virtual void DestroyForPlayer( Player *target, bool anim = false ) const;
136 const int32& GetInt32Value( uint16 index ) const
138 ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
139 return m_int32Values[ index ];
142 const uint32& GetUInt32Value( uint16 index ) const
144 ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
145 return m_uint32Values[ index ];
148 const uint64& GetUInt64Value( uint16 index ) const
150 ASSERT( index + 1 < m_valuesCount || PrintIndexError( index , false) );
151 return *((uint64*)&(m_uint32Values[ index ]));
154 const float& GetFloatValue( uint16 index ) const
156 ASSERT( index < m_valuesCount || PrintIndexError( index , false ) );
157 return m_floatValues[ index ];
160 uint8 GetByteValue( uint16 index, uint8 offset) const
162 ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
163 ASSERT( offset < 4 );
164 return *(((uint8*)&m_uint32Values[ index ])+offset);
167 uint16 GetUInt16Value( uint16 index, uint8 offset) const
169 ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
170 ASSERT( offset < 2 );
171 return *(((uint16*)&m_uint32Values[ index ])+offset);
174 void SetInt32Value( uint16 index, int32 value );
175 void SetUInt32Value( uint16 index, uint32 value );
176 void SetUInt64Value( uint16 index, const uint64 &value );
177 void SetFloatValue( uint16 index, float value );
178 void SetByteValue( uint16 index, uint8 offset, uint8 value );
179 void SetUInt16Value( uint16 index, uint8 offset, uint16 value );
180 void SetInt16Value( uint16 index, uint8 offset, int16 value ) { SetUInt16Value(index,offset,(uint16)value); }
181 void SetStatFloatValue( uint16 index, float value);
182 void SetStatInt32Value( uint16 index, int32 value);
184 void ApplyModUInt32Value(uint16 index, int32 val, bool apply);
185 void ApplyModInt32Value(uint16 index, int32 val, bool apply);
186 void ApplyModUInt64Value(uint16 index, int32 val, bool apply);
187 void ApplyModPositiveFloatValue( uint16 index, float val, bool apply);
188 void ApplyModSignedFloatValue( uint16 index, float val, bool apply);
190 void ApplyPercentModFloatValue(uint16 index, float val, bool apply)
192 val = val != -100.0f ? val : -99.9f ;
193 SetFloatValue(index, GetFloatValue(index) * (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val)) );
196 void SetFlag( uint16 index, uint32 newFlag );
197 void RemoveFlag( uint16 index, uint32 oldFlag );
199 void ToggleFlag( uint16 index, uint32 flag)
201 if(HasFlag(index, flag))
202 RemoveFlag(index, flag);
203 else
204 SetFlag(index, flag);
207 bool HasFlag( uint16 index, uint32 flag ) const
209 ASSERT( index < m_valuesCount || PrintIndexError( index , false ) );
210 return (m_uint32Values[ index ] & flag) != 0;
213 void SetByteFlag( uint16 index, uint8 offset, uint8 newFlag );
214 void RemoveByteFlag( uint16 index, uint8 offset, uint8 newFlag );
216 void ToggleFlag( uint16 index, uint8 offset, uint8 flag )
218 if(HasByteFlag(index, offset, flag))
219 RemoveByteFlag(index, offset, flag);
220 else
221 SetByteFlag(index, offset, flag);
224 bool HasByteFlag( uint16 index, uint8 offset, uint8 flag ) const
226 ASSERT( index < m_valuesCount || PrintIndexError( index , false ) );
227 ASSERT( offset < 4 );
228 return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0;
231 void ApplyModFlag( uint16 index, uint32 flag, bool apply)
233 if(apply) SetFlag(index,flag); else RemoveFlag(index,flag);
236 void SetFlag64( uint16 index, uint64 newFlag )
238 uint64 oldval = GetUInt64Value(index);
239 uint64 newval = oldval | newFlag;
240 SetUInt64Value(index,newval);
243 void RemoveFlag64( uint16 index, uint64 oldFlag )
245 uint64 oldval = GetUInt64Value(index);
246 uint64 newval = oldval & ~oldFlag;
247 SetUInt64Value(index,newval);
250 void ToggleFlag64( uint16 index, uint64 flag)
252 if(HasFlag64(index, flag))
253 RemoveFlag64(index, flag);
254 else
255 SetFlag64(index, flag);
258 bool HasFlag64( uint16 index, uint64 flag ) const
260 ASSERT( index < m_valuesCount || PrintIndexError( index , false ) );
261 return (GetUInt64Value( index ) & flag) != 0;
264 void ApplyModFlag64( uint16 index, uint64 flag, bool apply)
266 if(apply) SetFlag64(index,flag); else RemoveFlag64(index, flag);
269 void ClearUpdateMask(bool remove);
271 bool LoadValues(const char* data);
273 uint16 GetValuesCount() const { return m_valuesCount; }
275 void InitValues() { _InitValues(); }
277 virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
278 virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
279 protected:
281 Object ( );
283 void _InitValues();
284 void _Create (uint32 guidlow, uint32 entry, HighGuid guidhigh);
286 virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
288 virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
290 void BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const;
291 void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
292 void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players);
294 uint16 m_objectType;
296 uint8 m_objectTypeId;
297 uint16 m_updateFlag;
299 union
301 int32 *m_int32Values;
302 uint32 *m_uint32Values;
303 float *m_floatValues;
306 uint32 *m_uint32Values_mirror;
308 uint16 m_valuesCount;
310 bool m_objectUpdated;
312 private:
313 bool m_inWorld;
315 PackedGuid m_PackGUID;
317 // for output helpfull error messages from asserts
318 bool PrintIndexError(uint32 index, bool set) const;
319 Object(const Object&); // prevent generation copy constructor
320 Object& operator=(Object const&); // prevent generation assigment operator
323 struct WorldObjectChangeAccumulator;
325 class MANGOS_DLL_SPEC WorldObject : public Object
327 friend struct WorldObjectChangeAccumulator;
329 public:
330 virtual ~WorldObject ( ) {}
332 virtual void Update ( uint32 /*time_diff*/ ) { }
334 void _Create( uint32 guidlow, HighGuid guidhigh, uint32 phaseMask);
336 void Relocate(float x, float y, float z, float orientation);
337 void Relocate(float x, float y, float z);
339 void SetOrientation(float orientation) { m_orientation = orientation; }
341 float GetPositionX( ) const { return m_positionX; }
342 float GetPositionY( ) const { return m_positionY; }
343 float GetPositionZ( ) const { return m_positionZ; }
344 void GetPosition( float &x, float &y, float &z ) const
345 { x = m_positionX; y = m_positionY; z = m_positionZ; }
346 void GetPosition( WorldLocation &loc ) const
347 { loc.mapid = m_mapId; GetPosition(loc.coord_x, loc.coord_y, loc.coord_z); loc.orientation = GetOrientation(); }
348 float GetOrientation( ) const { return m_orientation; }
349 void GetNearPoint2D( float &x, float &y, float distance, float absAngle) const;
350 void GetNearPoint( WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d,float absAngle) const;
351 void GetClosePoint(float &x, float &y, float &z, float size, float distance2d = 0, float angle = 0) const
353 // angle calculated from current orientation
354 GetNearPoint(NULL,x,y,z,size,distance2d,GetOrientation() + angle);
356 void GetContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const
358 // angle to face `obj` to `this` using distance includes size of `obj`
359 GetNearPoint(obj,x,y,z,obj->GetObjectSize(),distance2d,GetAngle( obj ));
362 float GetObjectSize() const
364 return ( m_valuesCount > UNIT_FIELD_BOUNDINGRADIUS ) ? m_floatValues[UNIT_FIELD_BOUNDINGRADIUS] : DEFAULT_WORLD_OBJECT_SIZE;
366 bool IsPositionValid() const;
367 void UpdateGroundPositionZ(float x, float y, float &z) const;
369 void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const;
371 uint32 GetMapId() const { return m_mapId; }
372 uint32 GetInstanceId() const { return m_InstanceId; }
374 virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
375 uint32 GetPhaseMask() const { return m_phaseMask; }
376 bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); }
377 bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); }
379 uint32 GetZoneId() const;
380 uint32 GetAreaId() const;
381 void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const;
383 InstanceData* GetInstanceData();
385 const char* GetName() const { return m_name.c_str(); }
386 void SetName(const std::string& newname) { m_name=newname; }
388 virtual const char* GetNameForLocaleIdx(int32 /*locale_idx*/) const { return GetName(); }
390 float GetDistance( const WorldObject* obj ) const;
391 float GetDistance(float x, float y, float z) const;
392 float GetDistance2d(const WorldObject* obj) const;
393 float GetDistance2d(float x, float y) const;
394 float GetDistanceZ(const WorldObject* obj) const;
395 bool IsInMap(const WorldObject* obj) const
397 return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()) && InSamePhase(obj);
399 bool IsWithinDist3d(float x, float y, float z, float dist2compare) const;
400 bool IsWithinDist2d(float x, float y, float dist2compare) const;
401 bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const;
403 // use only if you will sure about placing both object at same map
404 bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const
406 return obj && _IsWithinDist(obj,dist2compare,is3D);
409 bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const
411 return obj && IsInMap(obj) && _IsWithinDist(obj,dist2compare,is3D);
413 bool IsWithinLOS(float x, float y, float z) const;
414 bool IsWithinLOSInMap(const WorldObject* obj) const;
415 bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const;
416 bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const;
417 bool IsInRange2d(float x, float y, float minRange, float maxRange) const;
418 bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const;
420 float GetAngle( const WorldObject* obj ) const;
421 float GetAngle( const float x, const float y ) const;
422 bool HasInArc( const float arcangle, const WorldObject* obj ) const;
423 bool isInFrontInMap(WorldObject const* target,float distance, float arc = M_PI) const;
424 bool isInBackInMap(WorldObject const* target, float distance, float arc = M_PI) const;
425 bool isInFront(WorldObject const* target,float distance, float arc = M_PI) const;
426 bool isInBack(WorldObject const* target, float distance, float arc = M_PI) const;
428 virtual void CleanupsBeforeDelete(); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
430 virtual void SendMessageToSet(WorldPacket *data, bool self);
431 virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self);
433 void MonsterSay(const char* text, uint32 language, uint64 TargetGuid);
434 void MonsterYell(const char* text, uint32 language, uint64 TargetGuid);
435 void MonsterTextEmote(const char* text, uint64 TargetGuid, bool IsBossEmote = false);
436 void MonsterWhisper(const char* text, uint64 receiver, bool IsBossWhisper = false);
437 void MonsterSay(int32 textId, uint32 language, uint64 TargetGuid);
438 void MonsterYell(int32 textId, uint32 language, uint64 TargetGuid);
439 void MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false);
440 void MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper = false);
441 void MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid);
442 void BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const* text, uint32 language, char const* name, uint64 TargetGuid) const;
444 void PlayDistanceSound(uint32 sound_id, Player* target = NULL);
445 void PlayDirectSound(uint32 sound_id, Player* target = NULL);
447 void SendObjectDeSpawnAnim(uint64 guid);
448 void SendGameObjectCustomAnim(uint64 guid);
450 virtual bool IsHostileTo(Unit const* unit) const =0;
451 virtual bool IsFriendlyTo(Unit const* unit) const =0;
452 bool IsControlledByPlayer() const;
454 virtual void SaveRespawnTime() {}
455 void AddObjectToRemoveList();
457 void UpdateObjectVisibility();
459 // main visibility check function in normal case (ignore grey zone distance check)
460 bool isVisibleFor(Player const* u, WorldObject const* viewPoint) const { return isVisibleForInState(u,viewPoint,false); }
462 // low level function for visibility change code, must be define in all main world object subclasses
463 virtual bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const = 0;
465 void SetMap(Map * map);
466 Map * GetMap() const { ASSERT(m_currMap); return m_currMap; }
467 //used to check all object's GetMap() calls when object is not in world!
468 void ResetMap() { m_currMap = NULL; }
470 //this function should be removed in nearest time...
471 Map const* GetBaseMap() const;
473 void AddToClientUpdateList();
474 void RemoveFromClientUpdateList();
475 void BuildUpdateData(UpdateDataMapType &);
477 Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
478 protected:
479 explicit WorldObject();
481 //these functions are used mostly for Relocate() and Corpse/Player specific stuff...
482 //use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
483 //mapId/instanceId should be set in SetMap() function!
484 void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
485 void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
487 std::string m_name;
489 private:
490 Map * m_currMap; //current object's Map location
492 uint32 m_mapId; // object at map with map_id
493 uint32 m_InstanceId; // in map copy with instance id
494 uint32 m_phaseMask; // in area phase state
496 float m_positionX;
497 float m_positionY;
498 float m_positionZ;
499 float m_orientation;
501 #endif