diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/DynamicObject/DynamicObject.cpp | 33 | ||||
-rw-r--r-- | src/server/game/Entities/DynamicObject/DynamicObject.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Transport/Transport.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 161 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 8 |
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 &); |