/* * Copyright (C) 2008-2017 TrinityCore * Copyright (C) 2005-2009 MaNGOS * * 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 . */ #ifndef _OBJECT_H #define _OBJECT_H #include "Common.h" #include "Position.h" #include "UpdateMask.h" #include "GridReference.h" #include "ObjectDefines.h" #include "Map.h" #include "ModelIgnoreFlags.h" #include #include #include #define CONTACT_DISTANCE 0.5f #define INTERACTION_DISTANCE 5.0f #define ATTACK_DISTANCE 5.0f #define INSPECT_DISTANCE 28.0f #define TRADE_DISTANCE 11.11f #define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects #define SIGHT_RANGE_UNIT 50.0f #define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents #define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards #define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards #define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects #define DEFAULT_COMBAT_REACH 1.5f #define MIN_MELEE_REACH 2.0f #define NOMINAL_MELEE_RANGE 5.0f #define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players enum TempSummonType { TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN = 2, // despawns after a specified time OR when the creature dies TEMPSUMMON_TIMED_DESPAWN = 3, // despawns after a specified time TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT = 4, // despawns after a specified time after the creature is out of combat TEMPSUMMON_CORPSE_DESPAWN = 5, // despawns instantly after death TEMPSUMMON_CORPSE_TIMED_DESPAWN = 6, // despawns after a specified time after death TEMPSUMMON_DEAD_DESPAWN = 7, // despawns when the creature disappears TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called }; enum PhaseMasks { PHASEMASK_NORMAL = 0x00000001, PHASEMASK_ANYWHERE = 0xFFFFFFFF }; enum NotifyFlags { NOTIFY_NONE = 0x00, NOTIFY_AI_RELOCATION = 0x01, NOTIFY_VISIBILITY_CHANGED = 0x02, NOTIFY_ALL = 0xFF }; class Corpse; class Creature; class CreatureAI; class DynamicObject; class GameObject; class InstanceScript; class Player; class TempSummon; class Transport; class Unit; class UpdateData; class WorldObject; class WorldPacket; class ZoneScript; typedef std::unordered_map UpdateDataMapType; class TC_GAME_API Object { public: virtual ~Object(); bool IsInWorld() const { return m_inWorld; } virtual void AddToWorld(); virtual void RemoveFromWorld(); ObjectGuid GetGUID() const { return GetGuidValue(OBJECT_FIELD_GUID); } PackedGuid const& GetPackGUID() const { return m_PackGUID; } uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); } void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); } 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; } bool isType(uint16 mask) const { return (mask & m_objectType) != 0; } virtual void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const; void SendUpdateToPlayer(Player* player); void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const; void BuildOutOfRangeUpdateBlock(UpdateData* data) const; void BuildMovementUpdateBlock(UpdateData* data, uint32 flags = 0) const; virtual void DestroyForPlayer(Player* target, bool onDeath = false) const; 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 GetGuidValue(uint16 index) const; 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); void SetByteValue(uint16 index, uint8 offset, uint8 value); void SetUInt16Value(uint16 index, uint8 offset, uint16 value); void SetInt16Value(uint16 index, uint8 offset, int16 value) { SetUInt16Value(index, offset, (uint16)value); } void SetGuidValue(uint16 index, ObjectGuid value); void SetStatFloatValue(uint16 index, float value); void SetStatInt32Value(uint16 index, int32 value); bool AddGuidValue(uint16 index, ObjectGuid value); bool RemoveGuidValue(uint16 index, ObjectGuid value); void ApplyModUInt32Value(uint16 index, int32 val, bool apply); void ApplyModInt32Value(uint16 index, int32 val, bool apply); void ApplyModUInt64Value(uint16 index, int32 val, bool apply); void ApplyModPositiveFloatValue(uint16 index, float val, bool apply); void ApplyModSignedFloatValue(uint16 index, float val, bool apply); void ApplyPercentModFloatValue(uint16 index, float val, bool apply); 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); 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; void ApplyModByteFlag(uint16 index, uint8 offset, uint8 flag, bool apply); 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); void ClearUpdateMask(bool remove); uint16 GetValuesCount() const { return m_valuesCount; } virtual bool hasQuest(uint32 /* quest_id */) const { return false; } virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; } virtual void BuildUpdate(UpdateDataMapType&) { } void BuildFieldsUpdate(Player*, UpdateDataMapType &) const; void SetFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags |= flag; } void RemoveFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags &= uint16(~flag); } // FG: some hacky helpers void ForceValuesUpdateAtIndex(uint32); Player* ToPlayer() { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast(this); else return NULL; } Player const* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast(this); else return NULL; } Creature* ToCreature() { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast(this); else return NULL; } Creature const* ToCreature() const { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast(this); else return NULL; } Unit* ToUnit() { if (isType(TYPEMASK_UNIT)) return reinterpret_cast(this); else return NULL; } Unit const* ToUnit() const { if (isType(TYPEMASK_UNIT)) return reinterpret_cast(this); else return NULL; } GameObject* ToGameObject() { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast(this); else return NULL; } GameObject const* ToGameObject() const { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast(this); else return NULL; } Corpse* ToCorpse() { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast(this); else return NULL; } Corpse const* ToCorpse() const { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast(this); else return NULL; } DynamicObject* ToDynObject() { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast(this); else return NULL; } DynamicObject const* ToDynObject() const { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast(this); else return NULL; } protected: Object(); void _InitValues(); void _Create(ObjectGuid::LowType guidlow, uint32 entry, HighGuid guidhigh); std::string _ConcatFields(uint16 startIndex, uint16 size) const; void _LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count); uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const; void BuildMovementUpdate(ByteBuffer* data, uint16 flags) const; virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const; uint16 m_objectType; TypeID m_objectTypeId; uint16 m_updateFlag; union { int32 *m_int32Values; uint32 *m_uint32Values; float *m_floatValues; }; UpdateMask _changesMask; uint16 m_valuesCount; uint16 _fieldNotifyFlags; virtual void AddToObjectUpdate() = 0; virtual void RemoveFromObjectUpdate() = 0; void AddToObjectUpdateIfNeeded(); bool m_objectUpdated; private: bool m_inWorld; PackedGuid m_PackGUID; // 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; }; struct MovementInfo { // common ObjectGuid guid; uint32 flags; uint16 flags2; Position pos; uint32 time; // transport struct TransportInfo { void Reset() { guid.Clear(); pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); seat = -1; time = 0; time2 = 0; } ObjectGuid guid; Position pos; int8 seat; uint32 time; uint32 time2; } transport; // swimming/flying float pitch; // falling uint32 fallTime; // jumping struct JumpInfo { void Reset() { zspeed = sinAngle = cosAngle = xyspeed = 0.0f; } float zspeed, sinAngle, cosAngle, xyspeed; } jump; // spline float splineElevation; MovementInfo() : guid(), flags(0), flags2(0), time(0), pitch(0.0f), fallTime(0), splineElevation(0.0f) { pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); transport.Reset(); jump.Reset(); } uint32 GetMovementFlags() const { return flags; } void SetMovementFlags(uint32 flag) { flags = flag; } void AddMovementFlag(uint32 flag) { flags |= flag; } void RemoveMovementFlag(uint32 flag) { flags &= ~flag; } bool HasMovementFlag(uint32 flag) const { return (flags & flag) != 0; } uint16 GetExtraMovementFlags() const { return flags2; } void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; } bool HasExtraMovementFlag(uint16 flag) const { return (flags2 & flag) != 0; } void SetFallTime(uint32 time) { fallTime = time; } void OutDebug(); }; #define MAPID_INVALID 0xFFFFFFFF class WorldLocation : public Position { public: explicit WorldLocation(uint32 _mapId = MAPID_INVALID, float _x = 0.f, float _y = 0.f, float _z = 0.f, float _o = 0.f) : Position(_x, _y, _z, _o), m_mapId(_mapId) { } WorldLocation(uint32 mapId, Position const& position) : Position(position), m_mapId(mapId) { } WorldLocation(WorldLocation const& loc) : Position(loc), m_mapId(loc.GetMapId()) { } void WorldRelocate(WorldLocation const& loc) { m_mapId = loc.GetMapId(); Relocate(loc); } void WorldRelocate(uint32 _mapId = MAPID_INVALID, float _x = 0.f, float _y = 0.f, float _z = 0.f, float _o = 0.f) { m_mapId = _mapId; Relocate(_x, _y, _z, _o); } WorldLocation GetWorldLocation() const { return *this; } uint32 GetMapId() const { return m_mapId; } uint32 m_mapId; }; template class GridObject { public: virtual ~GridObject() { } bool IsInGrid() const { return _gridRef.isValid(); } void AddToGrid(GridRefManager& m) { ASSERT(!IsInGrid()); _gridRef.link(&m, (T*)this); } void RemoveFromGrid() { ASSERT(IsInGrid()); _gridRef.unlink(); } private: GridReference _gridRef; }; template class FlaggedValuesArray32 { public: FlaggedValuesArray32() { memset(&m_values, 0x00, sizeof(T_VALUES) * ARRAY_SIZE); 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; }; enum MapObjectCellMoveState { MAP_OBJECT_CELL_MOVE_NONE, //not in move list MAP_OBJECT_CELL_MOVE_ACTIVE, //in move list MAP_OBJECT_CELL_MOVE_INACTIVE, //in move list but should not move }; class TC_GAME_API MapObject { friend class Map; //map for moving creatures friend class ObjectGridLoader; //grid loader for loading creatures protected: MapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE) { _newPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f); } private: Cell _currentCell; Cell const& GetCurrentCell() const { return _currentCell; } void SetCurrentCell(Cell const& cell) { _currentCell = cell; } MapObjectCellMoveState _moveState; Position _newPosition; void SetNewCellPosition(float x, float y, float z, float o) { _moveState = MAP_OBJECT_CELL_MOVE_ACTIVE; _newPosition.Relocate(x, y, z, o); } }; class TC_GAME_API WorldObject : public Object, public WorldLocation { protected: explicit WorldObject(bool isWorldObject); //note: here it means if it is in grid object list or world object list public: virtual ~WorldObject(); virtual void Update (uint32 /*time_diff*/) { } void _Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32 phaseMask); virtual void RemoveFromWorld() override; void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const; 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; 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; float GetObjectSize() const; void UpdateGroundPositionZ(float x, float y, float &z) const; void UpdateAllowedPositionZ(float x, float y, float &z) const; 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; uint32 GetInstanceId() const { return m_InstanceId; } virtual void SetPhaseMask(uint32 newPhaseMask, bool update); uint32 GetPhaseMask() const { return m_phaseMask; } bool InSamePhase(WorldObject const* obj) const; bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask) != 0; } uint32 GetZoneId() const; uint32 GetAreaId() const; void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const; InstanceScript* GetInstanceScript(); std::string const& GetName() const { return m_name; } void SetName(std::string const& newname) { m_name=newname; } virtual std::string const& GetNameForLocaleIdx(LocaleConstant /*locale_idx*/) const { return m_name; } 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; 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, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const; bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) 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; bool isInFront(WorldObject const* target, float arc = float(M_PI)) const; bool isInBack(WorldObject const* target, float arc = float(M_PI)) const; 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); } virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units virtual void SendMessageToSet(WorldPacket* data, bool self); virtual void SendMessageToSetInRange(WorldPacket* data, float dist, bool self); virtual void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr); virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; } void PlayDistanceSound(uint32 sound_id, Player* target = NULL); void PlayDirectSound(uint32 sound_id, Player* target = NULL); void PlayDirectMusic(uint32 music_id, Player* target = NULL); void SendObjectDeSpawnAnim(ObjectGuid guid); virtual void SaveRespawnTime() { } void AddObjectToRemoveList(); 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; FlaggedValuesArray32 m_stealth; FlaggedValuesArray32 m_stealthDetect; FlaggedValuesArray32 m_invisibility; FlaggedValuesArray32 m_invisibilityDetect; FlaggedValuesArray32 m_serverSideVisibility; FlaggedValuesArray32 m_serverSideVisibilityDetect; virtual void SetMap(Map* map); 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! //this function should be removed in nearest time... Map const* GetBaseMap() const; void SetZoneScript(); void ClearZoneScript(); ZoneScript* GetZoneScript() const { return m_zoneScript; } 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 */); Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL); void SummonCreatureGroup(uint8 group, std::list* list = NULL); Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const; GameObject* FindNearestGameObject(uint32 entry, float range) const; GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const; template void GetGameObjectListWithEntryInGrid(Container& gameObjectContainer, uint32 entry, float maxSearchRange = 250.0f) const; template void GetCreatureListWithEntryInGrid(Container& creatureContainer, uint32 entry, float maxSearchRange = 250.0f) const; template void GetPlayerListInGrid(Container& playerContainer, float maxSearchRange) const; void DestroyForNearbyPlayers(); virtual void UpdateObjectVisibility(bool forced = true); virtual void UpdateObjectVisibilityOnCreate() { UpdateObjectVisibility(true); } void BuildUpdate(UpdateDataMapType&) override; void AddToObjectUpdate() override; void RemoveFromObjectUpdate() override; //relocation and visibility system functions void AddToNotify(uint16 f) { m_notifyflags |= f;} bool isNeedNotify(uint16 f) const { return (m_notifyflags & f) != 0; } uint16 GetNotifyFlags() const { return m_notifyflags; } 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); void SetWorldObject(bool apply); bool IsPermanentWorldObject() const { return m_isWorldObject; } bool IsWorldObject() const; template void VisitNearbyObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitAll(GetPositionX(), GetPositionY(), radius, notifier); } template void VisitNearbyGridObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitGrid(GetPositionX(), GetPositionY(), radius, notifier); } template void VisitNearbyWorldObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitWorld(GetPositionX(), GetPositionY(), radius, notifier); } uint32 LastUsedScriptID; // Transports Transport* GetTransport() const { return m_transport; } 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(); } 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; virtual float GetStationaryX() const { return GetPositionX(); } virtual float GetStationaryY() const { return GetPositionY(); } virtual float GetStationaryZ() const { return GetPositionZ(); } virtual float GetStationaryO() const { return GetOrientation(); } protected: std::string m_name; bool m_isActive; const bool m_isWorldObject; ZoneScript* m_zoneScript; // 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; } virtual bool IsNeverVisible() 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; } private: Map* m_currMap; //current object's Map location //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 uint16 m_notifyflags; uint16 m_executed_notifies; 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; }; 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; }; } #endif