Core/Transports: Added support for DynamicObjects on transports

This commit is contained in:
Shauren
2014-03-16 20:00:09 +01:00
parent f26a028d97
commit f0f4a620fb
5 changed files with 210 additions and 2 deletions

View File

@@ -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;