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

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

View File

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

View File

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

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;

View File

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