aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/DynamicObject/DynamicObject.cpp33
-rw-r--r--src/server/game/Entities/DynamicObject/DynamicObject.h4
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp6
-rw-r--r--src/server/game/Maps/Map.cpp161
-rw-r--r--src/server/game/Maps/Map.h8
5 files changed, 210 insertions, 2 deletions
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
index f4e956e8839..7cc94d992a1 100644
--- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
@@ -26,6 +26,7 @@
#include "CellImpl.h"
#include "GridNotifiersImpl.h"
#include "ScriptMgr.h"
+#include "Transport.h"
DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject),
_aura(NULL), _removedAura(NULL), _caster(NULL), _duration(0), _isViewpoint(false)
@@ -47,6 +48,18 @@ DynamicObject::~DynamicObject()
delete _removedAura;
}
+void DynamicObject::CleanupsBeforeDelete(bool finalCleanup /* = true */)
+{
+ WorldObject::CleanupsBeforeDelete(finalCleanup);
+
+ if (Transport* transport = GetTransport())
+ {
+ transport->RemovePassenger(this);
+ SetTransport(NULL);
+ m_movementInfo.transport.Reset();
+ }
+}
+
void DynamicObject::AddToWorld()
{
///- Register the dynamicObject for guid lookup and for caster
@@ -108,8 +121,28 @@ bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spe
if (IsWorldObject())
setActive(true); //must before add to map to be put in world container
+ Transport* transport = caster->GetTransport();
+ if (transport)
+ {
+ m_movementInfo.transport.guid = GetGUID();
+
+ float x, y, z, o;
+ pos.GetPosition(x, y, z, o);
+ transport->CalculatePassengerOffset(x, y, z, &o);
+ m_movementInfo.transport.pos.Relocate(x, y, z, o);
+
+ SetTransport(transport);
+ // This object must be added to transport before adding to map for the client to properly display it
+ transport->AddPassenger(this);
+ }
+
if (!GetMap()->AddToMap(this))
+ {
+ // Returning false will cause the object to be deleted - remove from transport
+ if (transport)
+ transport->RemovePassenger(this);
return false;
+ }
return true;
}
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h
index 5b68bf377b9..cdba5982b3f 100644
--- a/src/server/game/Entities/DynamicObject/DynamicObject.h
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.h
@@ -32,7 +32,7 @@ enum DynamicObjectType
DYNAMIC_OBJECT_FARSIGHT_FOCUS = 0x2
};
-class DynamicObject : public WorldObject, public GridObject<DynamicObject>
+class DynamicObject : public WorldObject, public GridObject<DynamicObject>, public MapObject
{
public:
DynamicObject(bool isWorldObject);
@@ -41,6 +41,8 @@ class DynamicObject : public WorldObject, public GridObject<DynamicObject>
void AddToWorld();
void RemoveFromWorld();
+ void CleanupsBeforeDelete(bool finalCleanup = true) OVERRIDE;
+
bool CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type);
void Update(uint32 p_time);
void Remove();
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index f8c38d32390..6d6e749fe44 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -450,6 +450,9 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl
if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT))
_passengers.erase(obj);
break;
+ case TYPEID_DYNAMICOBJECT:
+ obj->AddObjectToRemoveList();
+ break;
default:
break;
}
@@ -518,6 +521,9 @@ void Transport::UpdatePassengerPositions(std::set<WorldObject*>& passengers)
case TYPEID_GAMEOBJECT:
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false);
break;
+ case TYPEID_DYNAMICOBJECT:
+ GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o);
+ break;
default:
break;
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 21e282cfcf4..ef993e9c116 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -217,7 +217,7 @@ void Map::DeleteStateMachine()
}
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent):
-_creatureToMoveLock(false), _gameObjectsToMoveLock(false),
+_creatureToMoveLock(false), _gameObjectsToMoveLock(false), _dynamicObjectsToMoveLock(false),
i_mapEntry(sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId),
m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD),
@@ -281,6 +281,15 @@ void Map::AddToGrid(GameObject* obj, Cell const& cell)
obj->SetCurrentCell(cell);
}
+template<>
+void Map::AddToGrid(DynamicObject* obj, Cell const& cell)
+{
+ NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
+ grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
+
+ obj->SetCurrentCell(cell);
+}
+
template<class T>
void Map::SwitchGridContainers(T* /*obj*/, bool /*on*/) { }
@@ -953,6 +962,38 @@ void Map::GameObjectRelocation(GameObject* go, float x, float y, float z, float
ASSERT(integrity_check == old_cell);
}
+void Map::DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float z, float orientation)
+{
+ Cell integrity_check(dynObj->GetPositionX(), dynObj->GetPositionY());
+ Cell old_cell = dynObj->GetCurrentCell();
+
+ ASSERT(integrity_check == old_cell);
+ Cell new_cell(x, y);
+
+ if (!getNGrid(new_cell.GridX(), new_cell.GridY()))
+ return;
+
+ // delay creature move for grid/cell to grid/cell moves
+ if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
+ {
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "GameObject (GUID: %u) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", dynObj->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
+#endif
+ AddDynamicObjectToMoveList(dynObj, x, y, z, orientation);
+ // in diffcell/diffgrid case notifiers called at finishing move dynObj in Map::MoveAllGameObjectsInMoveList
+ }
+ else
+ {
+ dynObj->Relocate(x, y, z, orientation);
+ dynObj->UpdateObjectVisibility(false);
+ RemoveDynamicObjectFromMoveList(dynObj);
+ }
+
+ old_cell = dynObj->GetCurrentCell();
+ integrity_check = Cell(dynObj->GetPositionX(), dynObj->GetPositionY());
+ ASSERT(integrity_check == old_cell);
+}
+
void Map::AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang)
{
if (_creatureToMoveLock) //can this happen?
@@ -991,6 +1032,25 @@ void Map::RemoveGameObjectFromMoveList(GameObject* go)
go->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE;
}
+void Map::AddDynamicObjectToMoveList(DynamicObject* dynObj, float x, float y, float z, float ang)
+{
+ if (_dynamicObjectsToMoveLock) //can this happen?
+ return;
+
+ if (dynObj->_moveState == MAP_OBJECT_CELL_MOVE_NONE)
+ _dynamicObjectsToMove.push_back(dynObj);
+ dynObj->SetNewCellPosition(x, y, z, ang);
+}
+
+void Map::RemoveDynamicObjectFromMoveList(DynamicObject* dynObj)
+{
+ if (_dynamicObjectsToMoveLock) //can this happen?
+ return;
+
+ if (dynObj->_moveState == MAP_OBJECT_CELL_MOVE_ACTIVE)
+ dynObj->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE;
+}
+
void Map::MoveAllCreaturesInMoveList()
{
_creatureToMoveLock = true;
@@ -1091,6 +1151,44 @@ void Map::MoveAllGameObjectsInMoveList()
_gameObjectsToMoveLock = false;
}
+void Map::MoveAllDynamicObjectsInMoveList()
+{
+ _dynamicObjectsToMoveLock = true;
+ for (std::vector<DynamicObject*>::iterator itr = _dynamicObjectsToMove.begin(); itr != _dynamicObjectsToMove.end(); ++itr)
+ {
+ DynamicObject* dynObj = *itr;
+ if (dynObj->FindMap() != this) //transport is teleported to another map
+ continue;
+
+ if (dynObj->_moveState != MAP_OBJECT_CELL_MOVE_ACTIVE)
+ {
+ dynObj->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
+ continue;
+ }
+
+ dynObj->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
+ if (!dynObj->IsInWorld())
+ continue;
+
+ // do move or do move to respawn or remove creature if previous all fail
+ if (DynamicObjectCellRelocation(dynObj, Cell(dynObj->_newPosition.m_positionX, dynObj->_newPosition.m_positionY)))
+ {
+ // update pos
+ dynObj->Relocate(dynObj->_newPosition);
+ dynObj->UpdateObjectVisibility(false);
+ }
+ else
+ {
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) cannot be moved to unloaded grid.", dynObj->GetGUIDLow());
+#endif
+ }
+ }
+
+ _dynamicObjectsToMove.clear();
+ _dynamicObjectsToMoveLock = false;
+}
+
bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
{
Cell const& old_cell = c->GetCurrentCell();
@@ -1213,6 +1311,67 @@ bool Map::GameObjectCellRelocation(GameObject* go, Cell new_cell)
return false;
}
+bool Map::DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell)
+{
+ Cell const& old_cell = go->GetCurrentCell();
+ if (!old_cell.DiffGrid(new_cell)) // in same grid
+ {
+ // if in same cell then none do
+ if (old_cell.DiffCell(new_cell))
+ {
+ #ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
+ #endif
+
+ go->RemoveFromGrid();
+ AddToGrid(go, new_cell);
+ }
+ else
+ {
+ #ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved in same grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY());
+ #endif
+ }
+
+ return true;
+ }
+
+ // in diff. grids but active GameObject
+ if (go->isActiveObject())
+ {
+ EnsureGridLoadedForActiveObject(new_cell, go);
+
+ #ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "Active DynamicObject (GUID: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
+ #endif
+
+ go->RemoveFromGrid();
+ AddToGrid(go, new_cell);
+
+ return true;
+ }
+
+ // in diff. loaded grid normal GameObject
+ if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY())))
+ {
+ #ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow() old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
+ #endif
+
+ go->RemoveFromGrid();
+ EnsureGridCreated(GridCoord(new_cell.GridX(), new_cell.GridY()));
+ AddToGrid(go, new_cell);
+
+ return true;
+ }
+
+ // fail to move: normal GameObject attempt move to unloaded grid
+ #ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
+ #endif
+ return false;
+}
+
bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly)
{
float resp_x, resp_y, resp_z, resp_o;
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 8e7886dc5d2..3d376d16c3d 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -280,6 +280,7 @@ class Map : public GridRefManager<NGridType>
void PlayerRelocation(Player*, float x, float y, float z, float orientation);
void CreatureRelocation(Creature* creature, float x, float y, float z, float ang, bool respawnRelocationOnFail = true);
void GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail = true);
+ void DynamicObjectRelocation(DynamicObject* go, float x, float y, float z, float orientation);
template<class T, class CONTAINER> void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor);
@@ -353,6 +354,7 @@ class Map : public GridRefManager<NGridType>
void MoveAllCreaturesInMoveList();
void MoveAllGameObjectsInMoveList();
+ void MoveAllDynamicObjectsInMoveList();
void RemoveAllObjectsInRemoveList();
virtual void RemoveAllPlayers();
@@ -502,12 +504,15 @@ class Map : public GridRefManager<NGridType>
bool CreatureCellRelocation(Creature* creature, Cell new_cell);
bool GameObjectCellRelocation(GameObject* go, Cell new_cell);
+ bool DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell);
template<class T> void InitializeObject(T* obj);
void AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang);
void RemoveCreatureFromMoveList(Creature* c);
void AddGameObjectToMoveList(GameObject* go, float x, float y, float z, float ang);
void RemoveGameObjectFromMoveList(GameObject* go);
+ void AddDynamicObjectToMoveList(DynamicObject* go, float x, float y, float z, float ang);
+ void RemoveDynamicObjectFromMoveList(DynamicObject* go);
bool _creatureToMoveLock;
std::vector<Creature*> _creaturesToMove;
@@ -515,6 +520,9 @@ class Map : public GridRefManager<NGridType>
bool _gameObjectsToMoveLock;
std::vector<GameObject*> _gameObjectsToMove;
+ bool _dynamicObjectsToMoveLock;
+ std::vector<DynamicObject*> _dynamicObjectsToMove;
+
bool IsGridLoaded(const GridCoord &) const;
void EnsureGridCreated(const GridCoord &);
void EnsureGridCreated_i(const GridCoord &);