void Transport::UpdatePosition(float x, float y, float z, float o) { bool newActive = GetMap()->IsGridLoaded(x, y); Cell oldCell(GetPositionX(), GetPositionY()); Relocate(x, y, z, o); m_stationaryPosition.SetOrientation(o); UpdateModelPosition(); UpdatePassengerPositions(_passengers); /* There are four possible scenarios that trigger loading/unloading passengers: 1. transport moves from inactive to active grid 2. the grid that transport is currently in becomes active 3. transport moves from active to inactive grid 4. the grid that transport is currently in unloads */ if (_staticPassengers.empty() && newActive) // 1. LoadStaticPassengers(); else if (!_staticPassengers.empty() && !newActive && oldCell.DiffGrid(Cell(GetPositionX(), GetPositionY()))) // 3. UnloadStaticPassengers(); else UpdatePassengerPositions(_staticPassengers); // 4. is handed by grid unload }
bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, float o) { Map const* oldMap = GetMap(); if (oldMap->GetId() != newMapid) { Map* newMap = sMapMgr->CreateBaseMap(newMapid); UnloadStaticPassengers(); GetMap()->RemoveFromMap<Transport>(this, false); SetMap(newMap); for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end();) { WorldObject* obj = (*itr++); float destX, destY, destZ, destO; obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, o); switch (obj->GetTypeId()) { case TYPEID_UNIT: if (!IS_PLAYER_GUID(obj->ToUnit()->GetOwnerGUID())) // pets should be teleported with player obj->ToCreature()->FarTeleportTo(newMap, destX, destY, destZ, destO); break; case TYPEID_GAMEOBJECT: { GameObject* go = obj->ToGameObject(); go->GetMap()->RemoveFromMap(go, false); go->Relocate(destX, destY, destZ, destO); go->SetMap(newMap); newMap->AddToMap(go); break; } case TYPEID_PLAYER: 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; } } Relocate(x, y, z, o); UpdateModelPosition(); GetMap()->AddToMap<Transport>(this); return true; } else { // Teleport players, they need to know it for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end(); ++itr) { if ((*itr)->GetTypeId() == TYPEID_PLAYER) { float destX, destY, destZ, destO; (*itr)->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, o); (*itr)->ToUnit()->NearTeleportTo(destX, destY, destZ, destO); } } UpdatePosition(x, y, z, o); return false; } }
bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z) { Map const* oldMap = GetMap(); if (oldMap->GetId() != newMapid) { Map* newMap = sMapMgr->CreateBaseMap(newMapid); Map::PlayerList const& oldPlayers = GetMap()->GetPlayers(); if (!oldPlayers.isEmpty()) { UpdateData data(GetMapId()); BuildOutOfRangeUpdateBlock(&data); WorldPacket packet; data.BuildPacket(&packet); for (Map::PlayerList::const_iterator itr = oldPlayers.begin(); itr != oldPlayers.end(); ++itr) if (itr->GetSource()->GetTransport() != this) itr->GetSource()->SendDirectMessage(&packet); } UnloadStaticPassengers(); GetMap()->RemoveFromMap<Transport>(this, false); SetMap(newMap); Map::PlayerList const& newPlayers = GetMap()->GetPlayers(); if (!newPlayers.isEmpty()) { for (Map::PlayerList::const_iterator itr = newPlayers.begin(); itr != newPlayers.end(); ++itr) { if (itr->GetSource()->GetTransport() != this) { UpdateData data(newMapid); BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); WorldPacket packet; data.BuildPacket(&packet); itr->GetSource()->SendDirectMessage(&packet); } } } for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end();) { WorldObject* obj = (*itr++); float destX, destY, destZ, destO; obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation()); switch (obj->GetTypeId()) { case TYPEID_UNIT: if (!IS_PLAYER_GUID(obj->ToUnit()->GetOwnerGUID())) // pets should be teleported with player obj->ToCreature()->FarTeleportTo(newMap, destX, destY, destZ, destO); break; case TYPEID_GAMEOBJECT: { GameObject* go = obj->ToGameObject(); go->GetMap()->RemoveFromMap(go, false); go->Relocate(destX, destY, destZ, destO); go->SetMap(newMap); newMap->AddToMap(go); break; } case TYPEID_PLAYER: if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT)) _passengers.erase(obj); break; default: break; } } Relocate(x, y, z, GetOrientation()); UpdateModelPosition(); GetMap()->AddToMap<Transport>(this); return true; } else { // Teleport players, they need to know it for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end(); ++itr) { if ((*itr)->GetTypeId() == TYPEID_PLAYER) { float destX, destY, destZ, destO; (*itr)->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation()); (*itr)->ToUnit()->NearTeleportTo(destX, destY, destZ, destO); } } UpdatePosition(x, y, z, GetOrientation()); return false; } }