Files
TCPlayerbotCore/src/server/game/Entities/Object/Object.h
T

638 lines
30 KiB
C++
Raw Normal View History

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"
#include "GridRefManager.h"
#include "MovementInfo.h"
#include "ObjectDefines.h"
#include "ObjectGuid.h"
#include "Position.h"
#include "SharedDefines.h"
2017-05-18 23:52:58 +02:00
#include "UpdateFields.h"
#include <list>
2008-10-02 16:23:55 -05:00
#include <set>
#include <unordered_map>
2009-10-17 15:51:44 -07:00
2017-05-14 12:49:48 +02:00
class AreaTrigger;
class Conversation;
class Corpse;
2008-10-02 16:23:55 -05:00
class Creature;
class CreatureAI;
class DynamicObject;
class GameObject;
class InstanceScript;
2017-05-14 12:49:48 +02:00
class Map;
class Player;
class Scenario;
class TempSummon;
class Transport;
class Unit;
class UpdateData;
class WorldObject;
class WorldPacket;
class ZoneScript;
2017-05-14 12:49:48 +02:00
namespace G3D
{
class Quat;
}
typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
namespace UpdateMask
{
typedef uint32 BlockType;
enum DynamicFieldChangeType : uint16
{
UNCHANGED = 0,
VALUE_CHANGED = 0x7FFF,
VALUE_AND_SIZE_CHANGED = 0x8000
};
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;
}
inline std::size_t EncodeDynamicFieldChangeType(std::size_t blockCount, DynamicFieldChangeType changeType, uint8 updateType)
{
return blockCount | ((changeType & VALUE_AND_SIZE_CHANGED) * ((3 - updateType /*this part evaluates to 0 if update type is not VALUES*/) / 3));
}
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;
};
class TC_GAME_API Object
2008-10-02 16:23:55 -05:00
{
public:
virtual ~Object();
2009-10-17 15:51:44 -07:00
bool IsInWorld() const { return m_inWorld; }
2009-10-17 15:51:44 -07:00
virtual void AddToWorld();
virtual void RemoveFromWorld();
2009-10-17 15:51:44 -07: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); }
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
2009-10-17 15:51:44 -07:00
float GetObjectScale() const { return GetFloatValue(OBJECT_FIELD_SCALE_X); }
virtual void SetObjectScale(float scale) { SetFloatValue(OBJECT_FIELD_SCALE_X, scale); }
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
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
void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const;
void BuildOutOfRangeUpdateBlock(UpdateData* data) const;
2009-10-17 15:51:44 -07:00
virtual void DestroyForPlayer(Player* target) const;
2009-10-17 15:51:44 -07: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;
ObjectGuid const& GetGuidValue(uint16 index) const;
2009-10-17 15:51:44 -07:00
void SetInt32Value(uint16 index, int32 value);
void SetUInt32Value(uint16 index, uint32 value);
void UpdateUInt32Value(uint16 index, uint32 value);
void SetUInt64Value(uint16 index, uint64 value);
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);
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
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);
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);
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);
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
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;
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);
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; }
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
void SetFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags |= flag; }
2014-08-21 16:56:11 +02:00
void RemoveFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags &= uint16(~flag); }
2009-01-15 21:29:32 -05:00
// FG: some hacky helpers
void ForceValuesUpdateAtIndex(uint32);
2009-10-17 15:51:44 -07: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; }
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
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; }
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; }
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; }
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:
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);
std::string _ConcatFields(uint16 startIndex, uint16 size) const;
void _LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count);
2009-10-17 15:51:44 -07: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
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;
std::vector<uint8> _changesMask;
std::vector<UpdateMask::DynamicFieldChangeType> _dynamicChangesMask;
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
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;
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
template<class T>
class GridObject
{
public:
2014-04-20 16:48:35 +02:00
virtual ~GridObject() { }
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;
};
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;
};
class TC_GAME_API WorldObject : public Object, public WorldLocation
2009-08-29 14:58:45 -05:00
{
protected:
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-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;
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);
Position GetNearPosition(float dist, float angle);
void MovePositionToFirstCollision(Position &pos, float dist, float angle);
Position GetFirstCollisionPosition(float dist, float angle);
Position GetRandomNearPosition(float radius);
void GetContactPoint(WorldObject const* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const;
2009-10-17 15:51:44 -07:00
float GetObjectSize() const;
2008-10-02 16:23:55 -05:00
void UpdateGroundPositionZ(float x, float y, float &z) const;
void UpdateAllowedPositionZ(float x, float y, float &z) const;
2009-10-17 15:51:44 -07:00
void GetRandomPoint(Position const &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const;
Position GetRandomPoint(Position const &srcPos, float distance) const;
2009-10-17 15:51:44 -07:00
uint32 GetInstanceId() const { return m_InstanceId; }
2009-10-17 15:51:44 -07:00
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
virtual bool SetInPhase(uint32 id, bool update, bool apply);
void CopyPhaseFrom(WorldObject* obj, bool update = false);
void UpdateAreaAndZonePhase();
void ClearPhases(bool update = false);
void RebuildTerrainSwaps();
void RebuildWorldMapAreaSwaps();
bool HasInPhaseList(uint32 phase);
uint32 GetPhaseMask() const { return m_phaseMask; }
bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); }
bool IsInPhase(std::set<uint32> const& phases) const;
bool IsInPhase(WorldObject const* obj) const;
bool IsInTerrainSwap(uint32 terrainSwap) const { return _terrainSwaps.find(terrainSwap) != _terrainSwaps.end(); }
std::set<uint32> const& GetPhases() const { return _phases; }
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; }
// 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;
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
std::string const& GetName() const { return m_name; }
void SetName(std::string const& newname) { m_name=newname; }
2009-10-17 15:51:44 -07:00
virtual std::string const& GetNameForLocaleIdx(LocaleConstant /*locale_idx*/) const { return m_name; }
2009-10-17 15:51:44 -07:00
float GetDistance(WorldObject const* obj) const;
float GetDistance(Position const &pos) const;
float GetDistance(float x, float y, float z) const;
float GetDistance2d(WorldObject const* obj) const;
float GetDistance2d(float x, float y) const;
float GetDistanceZ(WorldObject const* obj) const;
2009-10-17 15:51:44 -07:00
bool IsSelfOrInSameMap(WorldObject const* obj) const;
bool IsInMap(WorldObject const* obj) const;
bool IsWithinDist3d(float x, float y, float z, float dist) const;
bool IsWithinDist3d(Position const* pos, float dist) const;
bool IsWithinDist2d(float x, float y, float dist) const;
bool IsWithinDist2d(Position const* pos, float dist) const;
// use only if you will sure about placing both object at same map
bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const;
bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const;
bool IsWithinLOS(float x, float y, float z) const;
bool IsWithinLOSInMap(WorldObject const* obj) const;
Position GetHitSpherePointFor(Position const& dest) const;
void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const;
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
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
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
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; }
void PlayDistanceSound(uint32 soundId, Player* target = nullptr);
void PlayDirectSound(uint32 soundId, Player* target = nullptr);
2009-10-17 15:51:44 -07: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;
float GetSightRange(WorldObject const* target = NULL) const;
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
virtual void SetMap(Map* map);
2009-08-10 23:47:47 -05:00
virtual void ResetMap();
Map* GetMap() const { ASSERT(m_currMap); return m_currMap; }
Map* FindMap() const { return m_currMap; }
//used to check all object's GetMap() calls when object is not in world!
2009-10-17 15:51:44 -07: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
void SetZoneScript();
ZoneScript* GetZoneScript() const { return m_zoneScript; }
2009-10-17 15:51:44 -07:00
Scenario* GetScenario() const;
TempSummon* SummonCreature(uint32 id, Position const& pos, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0, uint32 vehId = 0) const;
TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0) const;
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);
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL);
2009-10-17 15:51:44 -07:00
Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const;
GameObject* FindNearestGameObject(uint32 entry, float range) const;
GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const;
2009-10-17 15:51:44 -07: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
void DestroyForNearbyPlayers();
2010-02-27 15:25:14 +02:00
virtual void UpdateObjectVisibility(bool forced = true);
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
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; }
void SetNotified(uint16 f) { m_executed_notifies |= f;}
void ResetAllNotifies() { m_notifyflags = 0; m_executed_notifies = 0; }
bool isActiveObject() const { return m_isActive; }
void setActive(bool isActiveObject);
2009-02-26 16:29:55 -06:00
void SetWorldObject(bool apply);
bool IsPermanentWorldObject() const { return m_isWorldObject; }
bool IsWorldObject() const;
uint32 LastUsedScriptID;
// Transports
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(); }
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; }
virtual ObjectGuid GetTransGUID() const;
void SetTransport(Transport* t) { m_transport = t; }
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(); }
virtual uint16 GetAIAnimKitId() const { return 0; }
virtual uint16 GetMovementAnimKitId() const { return 0; }
virtual uint16 GetMeleeAnimKitId() const { return 0; }
2008-10-02 16:23:55 -05:00
protected:
std::string m_name;
bool m_isActive;
const bool m_isWorldObject;
ZoneScript* m_zoneScript;
2009-10-17 15:51:44 -07:00
// transports
Transport* m_transport;
//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
virtual bool IsNeverVisibleFor(WorldObject const* /*seer*/) const { return !IsInWorld(); }
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:
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
uint32 m_InstanceId; // in map copy with instance id
uint32 m_phaseMask; // in area phase state
std::set<uint32> _phases;
std::set<uint32> _terrainSwaps;
std::set<uint32> _worldMapAreaSwaps;
int32 _dbPhase;
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;
bool CanNeverSee(WorldObject const* obj) const;
virtual bool CanAlwaysSee(WorldObject const* /*obj*/) const { return false; }
bool CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert = false) const;
bool CanDetectInvisibilityOf(WorldObject const* obj) const;
bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const;
2008-10-02 16:23:55 -05:00
};
namespace Trinity
{
// Binary predicate to sort WorldObjects based on the distance to a reference WorldObject
class ObjectDistanceOrderPred
{
public:
ObjectDistanceOrderPred(WorldObject const* refObj, bool ascending = true) : _refObj(refObj), _ascending(ascending) { }
bool operator()(WorldObject const* left, WorldObject const* right) const
{
return _refObj->GetDistanceOrder(left, right) == _ascending;
}
private:
WorldObject const* _refObj;
bool _ascending;
};
}
2008-10-02 16:23:55 -05:00
#endif