2010-10-07 15:54:07 +02:00
/*
2017-01-01 16:21:30 +01:00
* Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:54:07 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
#ifndef _OBJECT_H
#define _OBJECT_H
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
#include "Common.h"
2010-06-08 13:05:47 -06:00
#include "GridReference.h"
2017-05-15 22:55:16 +02:00
#include "GridRefManager.h"
2017-05-21 23:18:43 +02:00
#include "MovementInfo.h"
#include "ObjectDefines.h"
2017-05-15 22:55:16 +02:00
#include "ObjectGuid.h"
#include "Position.h"
#include "SharedDefines.h"
2017-05-18 23:52:58 +02:00
2016-07-10 00:11:19 +02:00
#include "UpdateFields.h"
2017-05-15 22:55:16 +02:00
#include <list>
2008-10-02 16:23:55 -05:00
#include <set>
2017-05-15 22:55:16 +02:00
#include <unordered_map>
2009-10-17 15:51:44 -07:00
2017-05-14 12:49:48 +02:00
class AreaTrigger ;
class Conversation ;
2013-03-25 10:36:30 +01:00
class Corpse ;
2008-10-02 16:23:55 -05:00
class Creature ;
2013-03-25 10:36:30 +01:00
class CreatureAI ;
class DynamicObject ;
2008-10-17 18:13:04 -05:00
class GameObject ;
2013-03-25 10:36:30 +01:00
class InstanceScript ;
2017-05-14 12:49:48 +02:00
class Map ;
2013-03-25 10:36:30 +01:00
class Player ;
2016-11-06 23:30:49 +01:00
class Scenario ;
2009-03-19 14:41:30 -06:00
class TempSummon ;
2010-07-30 21:54:46 -07:00
class Transport ;
2013-03-25 10:36:30 +01:00
class Unit ;
class UpdateData ;
class WorldObject ;
class WorldPacket ;
class ZoneScript ;
2010-07-30 21:54:46 -07:00
2017-05-14 12:49:48 +02:00
namespace G3D
{
class Quat ;
}
2014-05-01 10:10:13 +02:00
typedef std :: unordered_map < Player * , UpdateData > UpdateDataMapType ;
2010-07-30 21:54:46 -07:00
2016-07-11 17:14:42 +02:00
namespace UpdateMask
{
typedef uint32 BlockType ;
2016-07-13 16:53:50 +02:00
enum DynamicFieldChangeType : uint16
2016-07-13 00:07:09 +02:00
{
2016-07-20 13:27:04 +02:00
UNCHANGED = 0 ,
2016-07-13 16:53:50 +02:00
VALUE_CHANGED = 0x7FFF ,
VALUE_AND_SIZE_CHANGED = 0x8000
2016-07-13 00:07:09 +02:00
};
2016-07-11 17:14:42 +02:00
inline std :: size_t GetBlockCount ( std :: size_t bitCount )
{
using BitsPerBlock = std :: integral_constant < std :: size_t , sizeof ( BlockType ) * 8 > ;
return ( bitCount + BitsPerBlock :: value - 1 ) / BitsPerBlock :: value ;
}
2016-07-13 00:07:09 +02:00
inline std :: size_t EncodeDynamicFieldChangeType ( std :: size_t blockCount , DynamicFieldChangeType changeType , uint8 updateType )
{
2016-07-14 08:52:36 +02:00
return blockCount | (( changeType & VALUE_AND_SIZE_CHANGED ) * (( 3 - updateType /*this part evaluates to 0 if update type is not VALUES*/ ) / 3 ));
2016-07-13 00:07:09 +02:00
}
2016-07-11 17:14:42 +02:00
template < typename T >
inline void SetUpdateBit ( T * data , std :: size_t bitIndex )
{
static_assert ( std :: is_integral < T >:: value && std :: is_unsigned < T >:: value , "Type used for SetUpdateBit data arg is not an unsigned integer" );
using BitsPerBlock = std :: integral_constant < std :: size_t , sizeof ( T ) * 8 > ;
data [ bitIndex / BitsPerBlock :: value ] |= T ( 1 ) << ( bitIndex % BitsPerBlock :: value );
}
}
2016-07-10 14:41:18 +02:00
// Helper class used to iterate object dynamic fields while interpreting them as a structure instead of raw int array
template < class T >
class DynamicFieldStructuredView
{
public :
explicit DynamicFieldStructuredView ( std :: vector < uint32 > const & data ) : _data ( data ) { }
T const * begin () const
{
return reinterpret_cast < T const *> ( _data . data ());
}
T const * end () const
{
return reinterpret_cast < T const *> ( _data . data () + _data . size ());
}
std :: size_t size () const
{
using BlockCount = std :: integral_constant < uint16 , sizeof ( T ) / sizeof ( uint32 ) > ;
return _data . size () / BlockCount :: value ;
}
private :
std :: vector < uint32 > const & _data ;
};
2016-03-11 16:37:14 +01:00
class TC_GAME_API Object
2008-10-02 16:23:55 -05:00
{
public :
2012-05-30 08:01:02 +02:00
virtual ~ Object ();
2009-10-17 15:51:44 -07:00
2011-08-01 14:23:27 +02:00
bool IsInWorld () const { return m_inWorld ; }
2009-10-17 15:51:44 -07:00
2011-08-30 13:46:36 +02:00
virtual void AddToWorld ();
virtual void RemoveFromWorld ();
2009-10-17 15:51:44 -07:00
2014-10-22 17:33:55 +02:00
ObjectGuid const & GetGUID () const { return GetGuidValue ( OBJECT_FIELD_GUID ); }
2008-10-02 16:23:55 -05:00
uint32 GetEntry () const { return GetUInt32Value ( OBJECT_FIELD_ENTRY ); }
2008-11-12 16:21:08 -06:00
void SetEntry ( uint32 entry ) { SetUInt32Value ( OBJECT_FIELD_ENTRY , entry ); }
2009-10-17 15:51:44 -07:00
2013-08-17 23:46:36 +02:00
float GetObjectScale () const { return GetFloatValue ( OBJECT_FIELD_SCALE_X ); }
2013-06-15 14:45:28 +02:00
virtual void SetObjectScale ( float scale ) { SetFloatValue ( OBJECT_FIELD_SCALE_X , scale ); }
2012-05-30 08:01:02 +02:00
2009-08-06 10:38:46 -05:00
TypeID GetTypeId () const { return m_objectTypeId ; }
2014-07-17 15:42:57 +02:00
bool isType ( uint16 mask ) const { return ( mask & m_objectType ) != 0 ; }
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
virtual void BuildCreateUpdateBlockForPlayer ( UpdateData * data , Player * target ) const ;
2009-12-19 19:46:07 +01:00
void SendUpdateToPlayer ( Player * player );
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void BuildValuesUpdateBlockForPlayer ( UpdateData * data , Player * target ) const ;
void BuildOutOfRangeUpdateBlock ( UpdateData * data ) const ;
2009-10-17 15:51:44 -07:00
2015-01-01 20:38:19 +01:00
virtual void DestroyForPlayer ( Player * target ) const ;
2009-10-17 15:51:44 -07:00
2013-03-04 11:45:57 +01:00
int32 GetInt32Value ( uint16 index ) const ;
uint32 GetUInt32Value ( uint16 index ) const ;
uint64 GetUInt64Value ( uint16 index ) const ;
float GetFloatValue ( uint16 index ) const ;
uint8 GetByteValue ( uint16 index , uint8 offset ) const ;
uint16 GetUInt16Value ( uint16 index , uint8 offset ) const ;
2014-10-22 17:33:55 +02:00
ObjectGuid const & GetGuidValue ( uint16 index ) const ;
2009-10-17 15:51:44 -07:00
2011-08-28 17:36:02 +02:00
void SetInt32Value ( uint16 index , int32 value );
void SetUInt32Value ( uint16 index , uint32 value );
void UpdateUInt32Value ( uint16 index , uint32 value );
2011-08-30 13:46:36 +02:00
void SetUInt64Value ( uint16 index , uint64 value );
2011-08-28 17:36:02 +02:00
void SetFloatValue ( uint16 index , float value );
2010-04-07 22:59:46 +02:00
void SetByteValue ( uint16 index , uint8 offset , uint8 value );
void SetUInt16Value ( uint16 index , uint8 offset , uint16 value );
2014-10-22 17:33:55 +02:00
void SetGuidValue ( uint16 index , ObjectGuid const & value );
2010-04-07 22:59:46 +02:00
void SetStatFloatValue ( uint16 index , float value );
void SetStatInt32Value ( uint16 index , int32 value );
2009-10-17 15:51:44 -07:00
2014-10-22 17:33:55 +02:00
bool AddGuidValue ( uint16 index , ObjectGuid const & value );
bool RemoveGuidValue ( uint16 index , ObjectGuid const & value );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void ApplyModUInt32Value ( uint16 index , int32 val , bool apply );
void ApplyModInt32Value ( uint16 index , int32 val , bool apply );
2015-02-01 20:52:05 +01:00
void ApplyModUInt16Value ( uint16 index , uint8 offset , int16 val , bool apply );
2010-04-07 22:59:46 +02:00
void ApplyModPositiveFloatValue ( uint16 index , float val , bool apply );
void ApplyModSignedFloatValue ( uint16 index , float val , bool apply );
2013-03-04 11:45:57 +01:00
void ApplyPercentModFloatValue ( uint16 index , float val , bool apply );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void SetFlag ( uint16 index , uint32 newFlag );
void RemoveFlag ( uint16 index , uint32 oldFlag );
2013-03-04 11:45:57 +01:00
void ToggleFlag ( uint16 index , uint32 flag );
bool HasFlag ( uint16 index , uint32 flag ) const ;
void ApplyModFlag ( uint16 index , uint32 flag , bool apply );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void SetByteFlag ( uint16 index , uint8 offset , uint8 newFlag );
void RemoveByteFlag ( uint16 index , uint8 offset , uint8 newFlag );
2013-03-04 11:45:57 +01:00
void ToggleByteFlag ( uint16 index , uint8 offset , uint8 flag );
bool HasByteFlag ( uint16 index , uint8 offset , uint8 flag ) const ;
2009-10-17 15:51:44 -07:00
2013-03-04 11:45:57 +01:00
void SetFlag64 ( uint16 index , uint64 newFlag );
void RemoveFlag64 ( uint16 index , uint64 oldFlag );
void ToggleFlag64 ( uint16 index , uint64 flag );
bool HasFlag64 ( uint16 index , uint64 flag ) const ;
void ApplyModFlag64 ( uint16 index , uint64 flag , bool apply );
2009-10-17 15:51:44 -07:00
2014-10-26 22:06:48 +01:00
std :: vector < uint32 > const & GetDynamicValues ( uint16 index ) const ;
2016-06-28 18:34:50 +02:00
uint32 GetDynamicValue ( uint16 index , uint16 offset ) const ;
2014-10-26 22:06:48 +01:00
void AddDynamicValue ( uint16 index , uint32 value );
void RemoveDynamicValue ( uint16 index , uint32 value );
void ClearDynamicValue ( uint16 index );
2016-06-28 18:34:50 +02:00
void SetDynamicValue ( uint16 index , uint16 offset , uint32 value );
2014-10-26 22:06:48 +01:00
2016-07-10 14:41:18 +02:00
template < class T >
DynamicFieldStructuredView < T > GetDynamicStructuredValues ( uint16 index ) const
{
2017-04-16 01:13:09 +02:00
static_assert ( std :: is_standard_layout < T >:: value && std :: is_trivially_destructible < T >:: value , "T used for Object::SetDynamicStructuredValue<T> is not a trivially destructible standard layout type" );
2016-07-10 14:41:18 +02:00
using BlockCount = std :: integral_constant < uint16 , sizeof ( T ) / sizeof ( uint32 ) > ;
ASSERT ( index < _dynamicValuesCount || PrintIndexError ( index , false ));
std :: vector < uint32 > const & values = _dynamicValues [ index ];
ASSERT (( values . size () % BlockCount :: value ) == 0 , "Dynamic field value count must exactly fit into structure" );
return DynamicFieldStructuredView < T > ( values );
}
template < class T >
T const * GetDynamicStructuredValue ( uint16 index , uint16 offset ) const
{
2017-04-16 01:13:09 +02:00
static_assert ( std :: is_standard_layout < T >:: value && std :: is_trivially_destructible < T >:: value , "T used for Object::SetDynamicStructuredValue<T> is not a trivially destructible standard layout type" );
2016-07-10 14:41:18 +02:00
using BlockCount = std :: integral_constant < uint16 , sizeof ( T ) / sizeof ( uint32 ) > ;
ASSERT ( index < _dynamicValuesCount || PrintIndexError ( index , false ));
std :: vector < uint32 > const & values = _dynamicValues [ index ];
ASSERT (( values . size () % BlockCount :: value ) == 0 , "Dynamic field value count must exactly fit into structure" );
if ( offset * BlockCount :: value >= values . size ())
return nullptr ;
return reinterpret_cast < T const *> ( & values [ offset * BlockCount :: value ]);
}
template < class T >
void SetDynamicStructuredValue ( uint16 index , uint16 offset , T const * value )
{
2017-04-16 01:13:09 +02:00
static_assert ( std :: is_standard_layout < T >:: value && std :: is_trivially_destructible < T >:: value , "T used for Object::SetDynamicStructuredValue<T> is not a trivially destructible standard layout type" );
2016-07-10 14:41:18 +02:00
using BlockCount = std :: integral_constant < uint16 , sizeof ( T ) / sizeof ( uint32 ) > ;
SetDynamicValue ( index , ( offset + 1 ) * BlockCount :: value - 1 , 0 ); // reserve space
for ( uint16 i = 0 ; i < BlockCount :: value ; ++ i )
SetDynamicValue ( index , offset * BlockCount :: value + i , * ( reinterpret_cast < uint32 const *> ( value ) + i ));
}
2017-04-16 01:13:09 +02:00
template < class T >
void AddDynamicStructuredValue ( uint16 index , T const * value )
{
static_assert ( std :: is_standard_layout < T >:: value && std :: is_trivially_destructible < T >:: value , "T used for Object::SetDynamicStructuredValue<T> is not a trivially destructible standard layout type" );
using BlockCount = std :: integral_constant < uint16 , sizeof ( T ) / sizeof ( uint32 ) > ;
std :: vector < uint32 > const & values = _dynamicValues [ index ];
uint16 offset = uint16 ( values . size () / BlockCount :: value );
SetDynamicValue ( index , ( offset + 1 ) * BlockCount :: value - 1 , 0 ); // reserve space
for ( uint16 i = 0 ; i < BlockCount :: value ; ++ i )
SetDynamicValue ( index , offset * BlockCount :: value + i , * ( reinterpret_cast < uint32 const *> ( value ) + i ));
}
2008-10-02 16:23:55 -05:00
void ClearUpdateMask ( bool remove );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint16 GetValuesCount () const { return m_valuesCount ; }
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
virtual bool hasQuest ( uint32 /* quest_id */ ) const { return false ; }
virtual bool hasInvolvedQuest ( uint32 /* quest_id */ ) const { return false ; }
2013-10-27 22:27:46 +01:00
virtual void BuildUpdate ( UpdateDataMapType & ) { }
2011-09-29 12:43:05 +02:00
void BuildFieldsUpdate ( Player * , UpdateDataMapType & ) const ;
2009-10-17 15:51:44 -07:00
2012-07-22 14:20:26 +02:00
void SetFieldNotifyFlag ( uint16 flag ) { _fieldNotifyFlags |= flag ; }
2014-08-21 16:56:11 +02:00
void RemoveFieldNotifyFlag ( uint16 flag ) { _fieldNotifyFlags &= uint16 ( ~ flag ); }
2012-07-22 14:20:26 +02:00
2009-01-15 21:29:32 -05:00
// FG: some hacky helpers
void ForceValuesUpdateAtIndex ( uint32 );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
Player * ToPlayer () { if ( GetTypeId () == TYPEID_PLAYER ) return reinterpret_cast < Player *> ( this ); else return NULL ; }
2012-08-07 13:27:33 +02:00
Player const * ToPlayer () const { if ( GetTypeId () == TYPEID_PLAYER ) return reinterpret_cast < Player const *> ( this ); else return NULL ; }
2012-05-30 08:01:02 +02:00
Creature * ToCreature () { if ( GetTypeId () == TYPEID_UNIT ) return reinterpret_cast < Creature *> ( this ); else return NULL ; }
2012-08-07 13:27:33 +02:00
Creature const * ToCreature () const { if ( GetTypeId () == TYPEID_UNIT ) return reinterpret_cast < Creature const *> ( this ); else return NULL ; }
Unit * ToUnit () { if ( isType ( TYPEMASK_UNIT )) return reinterpret_cast < Unit *> ( this ); else return NULL ; }
Unit const * ToUnit () const { if ( isType ( TYPEMASK_UNIT )) return reinterpret_cast < Unit const *> ( this ); else return NULL ; }
2010-03-07 15:20:19 +01:00
2012-05-30 08:01:02 +02:00
GameObject * ToGameObject () { if ( GetTypeId () == TYPEID_GAMEOBJECT ) return reinterpret_cast < GameObject *> ( this ); else return NULL ; }
2012-08-07 13:27:33 +02:00
GameObject const * ToGameObject () const { if ( GetTypeId () == TYPEID_GAMEOBJECT ) return reinterpret_cast < GameObject const *> ( this ); else return NULL ; }
2011-08-26 12:05:47 +02:00
2012-05-30 08:01:02 +02:00
Corpse * ToCorpse () { if ( GetTypeId () == TYPEID_CORPSE ) return reinterpret_cast < Corpse *> ( this ); else return NULL ; }
2012-08-07 13:27:33 +02:00
Corpse const * ToCorpse () const { if ( GetTypeId () == TYPEID_CORPSE ) return reinterpret_cast < Corpse const *> ( this ); else return NULL ; }
2009-10-17 15:51:44 -07:00
2012-08-07 13:27:33 +02:00
DynamicObject * ToDynObject () { if ( GetTypeId () == TYPEID_DYNAMICOBJECT ) return reinterpret_cast < DynamicObject *> ( this ); else return NULL ; }
DynamicObject const * ToDynObject () const { if ( GetTypeId () == TYPEID_DYNAMICOBJECT ) return reinterpret_cast < DynamicObject const *> ( this ); else return NULL ; }
2013-05-26 04:56:43 +03:00
AreaTrigger * ToAreaTrigger () { if ( GetTypeId () == TYPEID_AREATRIGGER ) return reinterpret_cast < AreaTrigger *> ( this ); else return NULL ; }
AreaTrigger const * ToAreaTrigger () const { if ( GetTypeId () == TYPEID_AREATRIGGER ) return reinterpret_cast < AreaTrigger const *> ( this ); else return NULL ; }
2017-05-14 11:40:55 +02:00
Conversation * ToConversation () { if ( GetTypeId () == TYPEID_CONVERSATION ) return reinterpret_cast < Conversation *> ( this ); else return NULL ; }
Conversation const * ToConversation () const { if ( GetTypeId () == TYPEID_CONVERSATION ) return reinterpret_cast < Conversation const *> ( this ); else return NULL ; }
2012-08-07 13:27:33 +02:00
protected :
2012-05-30 08:01:02 +02:00
Object ();
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void _InitValues ();
2014-10-29 21:13:21 +01:00
void _Create ( ObjectGuid const & guid );
2011-04-11 14:39:00 +06:00
std :: string _ConcatFields ( uint16 startIndex , uint16 size ) const ;
2012-10-24 13:29:34 +02:00
void _LoadIntoDataField ( std :: string const & data , uint32 startOffset , uint32 count );
2009-10-17 15:51:44 -07:00
2013-02-03 12:16:10 +01:00
uint32 GetUpdateFieldData ( Player const * target , uint32 *& flags ) const ;
2014-10-26 22:06:48 +01:00
uint32 GetDynamicUpdateFieldData ( Player const * target , uint32 *& flags ) const ;
2009-10-17 15:51:44 -07:00
2014-11-02 14:56:16 +01:00
void BuildMovementUpdate ( ByteBuffer * data , uint32 flags ) const ;
2013-06-15 15:16:36 +02:00
virtual void BuildValuesUpdate ( uint8 updatetype , ByteBuffer * data , Player * target ) const ;
2014-10-26 22:06:48 +01:00
virtual void BuildDynamicValuesUpdate ( uint8 updatetype , ByteBuffer * data , Player * target ) const ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint16 m_objectType ;
2009-10-17 15:51:44 -07:00
2009-08-06 10:38:46 -05:00
TypeID m_objectTypeId ;
2014-11-02 14:56:16 +01:00
uint32 m_updateFlag ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
union
{
int32 * m_int32Values ;
uint32 * m_uint32Values ;
2008-12-12 11:21:28 -06:00
float * m_floatValues ;
2008-10-02 16:23:55 -05:00
};
2009-10-17 15:51:44 -07:00
2014-10-26 22:06:48 +01:00
std :: vector < uint32 >* _dynamicValues ;
2016-07-10 00:11:19 +02:00
std :: vector < uint8 > _changesMask ;
2016-07-13 00:07:09 +02:00
std :: vector < UpdateMask :: DynamicFieldChangeType > _dynamicChangesMask ;
2016-07-10 00:11:19 +02:00
std :: vector < uint8 >* _dynamicChangesArrayMask ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint16 m_valuesCount ;
2014-10-26 22:06:48 +01:00
uint16 _dynamicValuesCount ;
2009-10-17 15:51:44 -07:00
2012-07-22 14:20:26 +02:00
uint16 _fieldNotifyFlags ;
2015-02-25 00:13:14 +01:00
virtual void AddToObjectUpdate () = 0 ;
virtual void RemoveFromObjectUpdate () = 0 ;
void AddToObjectUpdateIfNeeded ();
2008-10-02 16:23:55 -05:00
bool m_objectUpdated ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
private :
bool m_inWorld ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// for output helpfull error messages from asserts
bool PrintIndexError ( uint32 index , bool set ) const ;
2014-04-29 16:35:11 +02:00
Object ( Object const & right ) = delete ;
Object & operator = ( Object const & right ) = delete ;
2008-10-02 16:23:55 -05:00
};
2009-10-17 15:51:44 -07:00
2009-12-26 11:38:30 +01:00
template < class T >
class GridObject
{
public :
2014-04-20 16:48:35 +02:00
virtual ~ GridObject () { }
2011-11-10 17:31:45 -05:00
bool IsInGrid () const { return _gridRef . isValid (); }
void AddToGrid ( GridRefManager < T >& m ) { ASSERT ( ! IsInGrid ()); _gridRef . link ( & m , ( T * ) this ); }
void RemoveFromGrid () { ASSERT ( IsInGrid ()); _gridRef . unlink (); }
private :
GridReference < T > _gridRef ;
2009-12-26 11:38:30 +01:00
};
2010-11-13 17:18:09 +01:00
template < class T_VALUES , class T_FLAGS , class FLAG_TYPE , uint8 ARRAY_SIZE >
class FlaggedValuesArray32
{
public :
FlaggedValuesArray32 ()
{
2017-05-19 00:41:18 +02:00
for ( uint32 i = 0 ; i < ARRAY_SIZE ; ++ i )
m_values [ i ] = T_VALUES ( 0 );
2010-11-13 17:18:09 +01:00
m_flags = 0 ;
}
T_FLAGS GetFlags () const { return m_flags ; }
bool HasFlag ( FLAG_TYPE flag ) const { return m_flags & ( 1 << flag ); }
void AddFlag ( FLAG_TYPE flag ) { m_flags |= ( 1 << flag ); }
void DelFlag ( FLAG_TYPE flag ) { m_flags &= ~ ( 1 << flag ); }
T_VALUES GetValue ( FLAG_TYPE flag ) const { return m_values [ flag ]; }
void SetValue ( FLAG_TYPE flag , T_VALUES value ) { m_values [ flag ] = value ; }
void AddValue ( FLAG_TYPE flag , T_VALUES value ) { m_values [ flag ] += value ; }
private :
T_VALUES m_values [ ARRAY_SIZE ];
T_FLAGS m_flags ;
};
2016-03-11 16:37:14 +01:00
class TC_GAME_API WorldObject : public Object , public WorldLocation
2009-08-29 14:58:45 -05:00
{
2010-08-08 20:32:14 +02:00
protected :
2011-12-20 17:05:08 -05:00
explicit WorldObject ( bool isWorldObject ); //note: here it means if it is in grid object list or world object list
2009-08-29 14:58:45 -05:00
public :
virtual ~ WorldObject ();
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
virtual void Update ( uint32 /*time_diff*/ ) { }
2009-10-17 15:51:44 -07:00
2014-08-09 20:17:40 +01:00
virtual void RemoveFromWorld () override ;
2010-11-16 21:17:49 +01:00
2010-04-07 22:59:46 +02:00
void GetNearPoint2D ( float & x , float & y , float distance , float absAngle ) const ;
2011-04-29 20:47:02 +02:00
void GetNearPoint ( WorldObject const * searcher , float & x , float & y , float & z , float searcher_size , float distance2d , float absAngle ) const ;
2013-03-04 11:45:57 +01:00
void GetClosePoint ( float & x , float & y , float & z , float size , float distance2d = 0 , float angle = 0 ) const ;
2009-08-29 23:20:16 -05:00
void MovePosition ( Position & pos , float dist , float angle );
2014-04-25 21:19:30 +02:00
Position GetNearPosition ( float dist , float angle );
2010-07-21 02:06:51 +02:00
void MovePositionToFirstCollision ( Position & pos , float dist , float angle );
2014-04-25 21:19:30 +02:00
Position GetFirstCollisionPosition ( float dist , float angle );
Position GetRandomNearPosition ( float radius );
2013-03-25 10:36:30 +01:00
void GetContactPoint ( WorldObject const * obj , float & x , float & y , float & z , float distance2d = CONTACT_DISTANCE ) const ;
2009-10-17 15:51:44 -07:00
2013-03-04 11:45:57 +01:00
float GetObjectSize () const ;
2008-10-02 16:23:55 -05:00
void UpdateGroundPositionZ ( float x , float y , float & z ) const ;
2012-01-14 15:34:41 +01:00
void UpdateAllowedPositionZ ( float x , float y , float & z ) const ;
2009-10-17 15:51:44 -07:00
2013-03-25 10:36:30 +01:00
void GetRandomPoint ( Position const & srcPos , float distance , float & rand_x , float & rand_y , float & rand_z ) const ;
2014-04-25 21:19:30 +02:00
Position GetRandomPoint ( Position const & srcPos , float distance ) const ;
2009-10-17 15:51:44 -07:00
2009-08-25 11:42:18 -05:00
uint32 GetInstanceId () const { return m_InstanceId ; }
2009-10-17 15:51:44 -07:00
2009-01-31 16:38:50 -06:00
virtual void SetPhaseMask ( uint32 newPhaseMask , bool update );
2015-03-16 07:28:49 +01:00
virtual bool SetInPhase ( uint32 id , bool update , bool apply );
void CopyPhaseFrom ( WorldObject * obj , bool update = false );
2016-05-18 20:06:47 +02:00
void UpdateAreaAndZonePhase ();
2015-03-16 07:28:49 +01:00
void ClearPhases ( bool update = false );
void RebuildTerrainSwaps ();
void RebuildWorldMapAreaSwaps ();
bool HasInPhaseList ( uint32 phase );
2009-01-31 16:38:50 -06:00
uint32 GetPhaseMask () const { return m_phaseMask ; }
2014-06-01 22:27:29 -05:00
bool IsInPhase ( uint32 phase ) const { return _phases . find ( phase ) != _phases . end (); }
2017-05-05 20:48:08 +02:00
bool IsInPhase ( std :: set < uint32 > const & phases ) const ;
2014-06-01 22:27:29 -05:00
bool IsInPhase ( WorldObject const * obj ) const ;
2015-03-16 07:28:49 +01:00
bool IsInTerrainSwap ( uint32 terrainSwap ) const { return _terrainSwaps . find ( terrainSwap ) != _terrainSwaps . end (); }
2014-06-01 22:27:29 -05:00
std :: set < uint32 > const & GetPhases () const { return _phases ; }
2015-03-16 07:28:49 +01:00
std :: set < uint32 > const & GetTerrainSwaps () const { return _terrainSwaps ; }
std :: set < uint32 > const & GetWorldMapAreaSwaps () const { return _worldMapAreaSwaps ; }
2015-07-22 23:24:56 +01:00
int32 GetDBPhase () const { return _dbPhase ; }
2015-03-16 07:28:49 +01:00
// if negative it is used as PhaseGroupId
void SetDBPhase ( int32 p ) { _dbPhase = p ; }
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint32 GetZoneId () const ;
uint32 GetAreaId () const ;
2009-03-11 16:17:37 -06:00
void GetZoneAndAreaId ( uint32 & zoneid , uint32 & areaid ) const ;
2009-10-17 15:51:44 -07:00
2010-08-08 22:54:58 +06:00
InstanceScript * GetInstanceScript ();
2009-10-17 15:51:44 -07:00
2012-10-24 13:29:34 +02:00
std :: string const & GetName () const { return m_name ; }
2012-10-24 15:34:23 +02:00
void SetName ( std :: string const & newname ) { m_name = newname ; }
2009-10-17 15:51:44 -07:00
2012-10-24 13:29:34 +02:00
virtual std :: string const & GetNameForLocaleIdx ( LocaleConstant /*locale_idx*/ ) const { return m_name ; }
2009-10-17 15:51:44 -07:00
2013-03-25 10:36:30 +01:00
float GetDistance ( WorldObject const * obj ) const ;
float GetDistance ( Position const & pos ) const ;
2013-03-04 11:45:57 +01:00
float GetDistance ( float x , float y , float z ) const ;
2013-03-25 10:36:30 +01:00
float GetDistance2d ( WorldObject const * obj ) const ;
2013-03-04 11:45:57 +01:00
float GetDistance2d ( float x , float y ) const ;
2013-03-25 10:36:30 +01:00
float GetDistanceZ ( WorldObject const * obj ) const ;
2009-10-17 15:51:44 -07:00
2013-03-25 10:36:30 +01:00
bool IsSelfOrInSameMap ( WorldObject const * obj ) const ;
bool IsInMap ( WorldObject const * obj ) const ;
2013-03-04 11:45:57 +01:00
bool IsWithinDist3d ( float x , float y , float z , float dist ) const ;
2013-03-25 10:36:30 +01:00
bool IsWithinDist3d ( Position const * pos , float dist ) const ;
2013-03-04 11:45:57 +01:00
bool IsWithinDist2d ( float x , float y , float dist ) const ;
2013-03-25 10:36:30 +01:00
bool IsWithinDist2d ( Position const * pos , float dist ) const ;
2010-02-06 00:28:19 +01:00
// use only if you will sure about placing both object at same map
2013-03-04 11:45:57 +01:00
bool IsWithinDist ( WorldObject const * obj , float dist2compare , bool is3D = true ) const ;
bool IsWithinDistInMap ( WorldObject const * obj , float dist2compare , bool is3D = true ) const ;
2009-05-14 16:50:47 -05:00
bool IsWithinLOS ( float x , float y , float z ) const ;
2013-03-25 10:36:30 +01:00
bool IsWithinLOSInMap ( WorldObject const * obj ) const ;
2015-11-03 11:20:30 +01:00
Position GetHitSpherePointFor ( Position const & dest ) const ;
void GetHitSpherePointFor ( Position const & dest , float & x , float & y , float & z ) const ;
2009-05-14 16:50:47 -05:00
bool GetDistanceOrder ( WorldObject const * obj1 , WorldObject const * obj2 , bool is3D = true ) const ;
bool IsInRange ( WorldObject const * obj , float minRange , float maxRange , bool is3D = true ) const ;
bool IsInRange2d ( float x , float y , float minRange , float maxRange ) const ;
bool IsInRange3d ( float x , float y , float z , float minRange , float maxRange ) const ;
2014-08-21 16:56:11 +02:00
bool isInFront ( WorldObject const * target , float arc = float ( M_PI )) const ;
bool isInBack ( WorldObject const * target , float arc = float ( M_PI )) const ;
2009-10-17 15:51:44 -07:00
2016-09-10 14:14:34 +02:00
bool IsInBetween ( Position const & pos1 , Position const & pos2 , float size = 0 ) const ;
bool IsInBetween ( WorldObject const * obj1 , WorldObject const * obj2 , float size = 0 ) const { return obj1 && obj2 && IsInBetween ( obj1 -> GetPosition (), obj2 -> GetPosition (), size ); }
2009-10-17 15:51:44 -07:00
2010-01-22 20:03:47 +01:00
virtual void CleanupsBeforeDelete ( bool finalCleanup = true ); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
2009-10-17 15:51:44 -07:00
2014-11-16 18:17:08 +02:00
virtual void SendMessageToSet ( WorldPacket const * data , bool self );
virtual void SendMessageToSetInRange ( WorldPacket const * data , float dist , bool self );
virtual void SendMessageToSet ( WorldPacket const * data , Player const * skipped_rcvr );
2009-10-17 15:51:44 -07:00
2010-11-13 17:18:09 +01:00
virtual uint8 getLevelForTarget ( WorldObject const * /*target*/ ) const { return 1 ; }
2016-12-03 16:45:30 +01:00
void PlayDistanceSound ( uint32 soundId , Player * target = nullptr );
void PlayDirectSound ( uint32 soundId , Player * target = nullptr );
2009-10-17 15:51:44 -07:00
2013-10-27 22:27:46 +01:00
virtual void SaveRespawnTime () { }
2008-10-02 16:23:55 -05:00
void AddObjectToRemoveList ();
2009-10-17 15:51:44 -07:00
2010-11-13 17:18:09 +01:00
float GetGridActivationRange () const ;
float GetVisibilityRange () const ;
2013-03-25 10:36:30 +01:00
float GetSightRange ( WorldObject const * target = NULL ) const ;
2015-07-15 18:43:19 +02:00
bool CanSeeOrDetect ( WorldObject const * obj , bool ignoreStealth = false , bool distanceCheck = false , bool checkAlert = false ) const ;
2010-11-13 17:18:09 +01:00
FlaggedValuesArray32 < int32 , uint32 , StealthType , TOTAL_STEALTH_TYPES > m_stealth ;
FlaggedValuesArray32 < int32 , uint32 , StealthType , TOTAL_STEALTH_TYPES > m_stealthDetect ;
FlaggedValuesArray32 < int32 , uint32 , InvisibilityType , TOTAL_INVISIBILITY_TYPES > m_invisibility ;
FlaggedValuesArray32 < int32 , uint32 , InvisibilityType , TOTAL_INVISIBILITY_TYPES > m_invisibilityDetect ;
2009-10-17 15:51:44 -07:00
2010-11-13 17:18:09 +01:00
FlaggedValuesArray32 < int32 , uint32 , ServerSideVisibilityType , TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility ;
FlaggedValuesArray32 < int32 , uint32 , ServerSideVisibilityType , TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibilityDetect ;
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
virtual void SetMap ( Map * map );
2009-08-10 23:47:47 -05:00
virtual void ResetMap ();
2011-09-15 14:08:17 +02:00
Map * GetMap () const { ASSERT ( m_currMap ); return m_currMap ; }
Map * FindMap () const { return m_currMap ; }
2009-07-16 11:49:00 +08:00
//used to check all object's GetMap() calls when object is not in world!
2009-10-17 15:51:44 -07:00
2009-07-16 11:49:00 +08:00
//this function should be removed in nearest time...
2008-10-02 16:23:55 -05:00
Map const * GetBaseMap () const ;
2009-10-17 15:51:44 -07:00
2009-05-30 22:15:05 -05:00
void SetZoneScript ();
2011-09-15 14:08:17 +02:00
ZoneScript * GetZoneScript () const { return m_zoneScript ; }
2009-10-17 15:51:44 -07:00
2016-11-06 23:30:49 +01:00
Scenario * GetScenario () const ;
2016-07-30 18:50:44 -03:00
TempSummon * SummonCreature ( uint32 id , Position const & pos , TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN , uint32 despwtime = 0 , uint32 vehId = 0 ) const ;
2013-03-04 11:45:57 +01:00
TempSummon * SummonCreature ( uint32 id , float x , float y , float z , float ang = 0 , TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN , uint32 despwtime = 0 ) const ;
2016-07-30 18:50:44 -03:00
GameObject * SummonGameObject ( uint32 entry , Position const & pos , G3D :: Quat const & rot , uint32 respawnTime /* s */ );
GameObject * SummonGameObject ( uint32 entry , float x , float y , float z , float ang , G3D :: Quat const & rot , uint32 respawnTime /* s */ );
2009-03-18 21:39:09 -06:00
Creature * SummonTrigger ( float x , float y , float z , float ang , uint32 dur , CreatureAI * ( * GetAI )( Creature * ) = NULL );
2013-02-26 02:33:08 +01:00
void SummonCreatureGroup ( uint8 group , std :: list < TempSummon *>* list = NULL );
2009-10-17 15:51:44 -07:00
2011-08-30 13:46:36 +02:00
Creature * FindNearestCreature ( uint32 entry , float range , bool alive = true ) const ;
GameObject * FindNearestGameObject ( uint32 entry , float range ) const ;
2012-09-08 23:15:29 +01:00
GameObject * FindNearestGameObjectOfType ( GameobjectTypes type , float range ) const ;
2009-10-17 15:51:44 -07:00
2016-05-13 00:56:52 +02:00
void GetGameObjectListWithEntryInGrid ( std :: list < GameObject *>& lList , uint32 uiEntry = 0 , float fMaxSearchRange = 250.0f ) const ;
void GetCreatureListWithEntryInGrid ( std :: list < Creature *>& lList , uint32 uiEntry = 0 , float fMaxSearchRange = 250.0f ) const ;
2015-02-10 22:16:07 -05:00
void GetPlayerListInGrid ( std :: list < Player *>& lList , float fMaxSearchRange ) const ;
2009-10-17 15:51:44 -07:00
2009-08-28 14:19:14 -05:00
void DestroyForNearbyPlayers ();
2010-02-27 15:25:14 +02:00
virtual void UpdateObjectVisibility ( bool forced = true );
2016-03-02 23:54:37 +01:00
virtual void UpdateObjectVisibilityOnCreate ()
{
UpdateObjectVisibility ( true );
}
2014-08-09 20:17:40 +01:00
void BuildUpdate ( UpdateDataMapType & ) override ;
2015-02-25 00:13:14 +01:00
void AddToObjectUpdate () override ;
void RemoveFromObjectUpdate () override ;
2009-10-17 15:51:44 -07:00
2010-02-27 15:25:14 +02:00
//relocation and visibility system functions
2009-12-19 10:12:40 +01:00
void AddToNotify ( uint16 f ) { m_notifyflags |= f ;}
2014-07-17 15:42:57 +02:00
bool isNeedNotify ( uint16 f ) const { return ( m_notifyflags & f ) != 0 ; }
2010-02-27 15:25:14 +02:00
uint16 GetNotifyFlags () const { return m_notifyflags ; }
2014-07-17 15:42:57 +02:00
bool NotifyExecuted ( uint16 f ) const { return ( m_executed_notifies & f ) != 0 ; }
2009-12-19 10:12:40 +01:00
void SetNotified ( uint16 f ) { m_executed_notifies |= f ;}
void ResetAllNotifies () { m_notifyflags = 0 ; m_executed_notifies = 0 ; }
2009-02-25 20:52:20 -06:00
bool isActiveObject () const { return m_isActive ; }
void setActive ( bool isActiveObject );
2009-02-26 16:29:55 -06:00
void SetWorldObject ( bool apply );
2011-12-20 17:05:08 -05:00
bool IsPermanentWorldObject () const { return m_isWorldObject ; }
bool IsWorldObject () const ;
2010-05-16 17:45:45 +02:00
uint32 LastUsedScriptID ;
2010-07-30 21:54:46 -07:00
// Transports
2011-09-15 14:08:17 +02:00
Transport * GetTransport () const { return m_transport ; }
2013-10-16 18:37:29 +02:00
float GetTransOffsetX () const { return m_movementInfo . transport . pos . GetPositionX (); }
float GetTransOffsetY () const { return m_movementInfo . transport . pos . GetPositionY (); }
float GetTransOffsetZ () const { return m_movementInfo . transport . pos . GetPositionZ (); }
float GetTransOffsetO () const { return m_movementInfo . transport . pos . GetOrientation (); }
2017-05-15 22:55:16 +02:00
Position const & GetTransOffset () const { return m_movementInfo . transport . pos ; }
2013-10-16 18:37:29 +02:00
uint32 GetTransTime () const { return m_movementInfo . transport . time ; }
int8 GetTransSeat () const { return m_movementInfo . transport . seat ; }
2014-09-14 16:14:12 +02:00
virtual ObjectGuid GetTransGUID () const ;
2011-09-15 14:08:17 +02:00
void SetTransport ( Transport * t ) { m_transport = t ; }
2010-07-30 21:54:46 -07:00
MovementInfo m_movementInfo ;
2013-10-16 18:37:29 +02:00
virtual float GetStationaryX () const { return GetPositionX (); }
virtual float GetStationaryY () const { return GetPositionY (); }
virtual float GetStationaryZ () const { return GetPositionZ (); }
virtual float GetStationaryO () const { return GetOrientation (); }
2015-09-16 17:06:24 +02:00
virtual uint16 GetAIAnimKitId () const { return 0 ; }
virtual uint16 GetMovementAnimKitId () const { return 0 ; }
virtual uint16 GetMeleeAnimKitId () const { return 0 ; }
2015-05-25 01:50:03 +02:00
2008-10-02 16:23:55 -05:00
protected :
std :: string m_name ;
2008-10-27 08:41:55 -05:00
bool m_isActive ;
2011-12-20 17:05:08 -05:00
const bool m_isWorldObject ;
2011-09-15 14:08:17 +02:00
ZoneScript * m_zoneScript ;
2009-10-17 15:51:44 -07:00
2010-07-30 21:54:46 -07:00
// transports
2011-09-15 14:08:17 +02:00
Transport * m_transport ;
2010-07-30 21:54:46 -07:00
2009-08-25 11:42:18 -05:00
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
//mapId/instanceId should be set in SetMap() function!
void SetLocationMapId ( uint32 _mapId ) { m_mapId = _mapId ; }
void SetLocationInstanceId ( uint32 _instanceId ) { m_InstanceId = _instanceId ; }
2009-10-17 15:51:44 -07:00
2017-05-05 13:31:25 +02:00
virtual bool IsNeverVisibleFor ( WorldObject const * /*seer*/ ) const { return ! IsInWorld (); }
2011-10-13 17:01:55 -04:00
virtual bool IsAlwaysVisibleFor ( WorldObject const * /*seer*/ ) const { return false ; }
virtual bool IsInvisibleDueToDespawn () const { return false ; }
//difference from IsAlwaysVisibleFor: 1. after distance check; 2. use owner or charmer as seer
virtual bool IsAlwaysDetectableFor ( WorldObject const * /*seer*/ ) const { return false ; }
2008-10-02 16:23:55 -05:00
private :
2011-09-15 14:08:17 +02:00
Map * m_currMap ; //current object's Map location
2009-10-17 15:51:44 -07:00
2009-08-29 14:58:45 -05:00
//uint32 m_mapId; // object at map with map_id
2009-08-25 11:42:18 -05:00
uint32 m_InstanceId ; // in map copy with instance id
2009-01-31 16:38:50 -06:00
uint32 m_phaseMask ; // in area phase state
2014-06-01 22:27:29 -05:00
std :: set < uint32 > _phases ;
2015-03-16 07:28:49 +01:00
std :: set < uint32 > _terrainSwaps ;
std :: set < uint32 > _worldMapAreaSwaps ;
int32 _dbPhase ;
2009-12-19 10:12:40 +01:00
uint16 m_notifyflags ;
uint16 m_executed_notifies ;
2011-10-13 14:02:07 -04:00
virtual bool _IsWithinDist ( WorldObject const * obj , float dist2compare , bool is3D ) const ;
2013-03-04 11:45:57 +01:00
bool CanNeverSee ( WorldObject const * obj ) const ;
2011-10-13 17:01:55 -04:00
virtual bool CanAlwaysSee ( WorldObject const * /*obj*/ ) const { return false ; }
2015-07-15 18:43:19 +02:00
bool CanDetect ( WorldObject const * obj , bool ignoreStealth , bool checkAlert = false ) const ;
2011-10-13 17:01:55 -04:00
bool CanDetectInvisibilityOf ( WorldObject const * obj ) const ;
2015-07-15 18:43:19 +02:00
bool CanDetectStealthOf ( WorldObject const * obj , bool checkAlert = false ) const ;
2008-10-02 16:23:55 -05:00
};
2010-05-30 04:23:27 +02:00
namespace Trinity
{
// Binary predicate to sort WorldObjects based on the distance to a reference WorldObject
class ObjectDistanceOrderPred
{
public :
2014-08-14 16:09:14 +02:00
ObjectDistanceOrderPred ( WorldObject const * refObj , bool ascending = true ) : _refObj ( refObj ), _ascending ( ascending ) { }
bool operator ()( WorldObject const * left , WorldObject const * right ) const
2010-05-30 04:23:27 +02:00
{
2014-08-14 16:09:14 +02:00
return _refObj -> GetDistanceOrder ( left , right ) == _ascending ;
2010-05-30 04:23:27 +02:00
}
2014-08-14 16:09:14 +02:00
2010-05-30 04:23:27 +02:00
private :
2014-08-14 16:09:14 +02:00
WorldObject const * _refObj ;
bool _ascending ;
2010-05-30 04:23:27 +02:00
};
}
2008-10-02 16:23:55 -05:00
#endif