Transport* MapManager::LoadTransportInMap(Map* instance, uint32 goEntry, uint32 period) { const GameObjectTemplate* goInfo = sObjectMgr->GetGameObjectTemplate(goEntry); if(!goInfo) { sLog->outErrorDb("Transport ID:%u, will not be loaded, gameobject_template missing", goEntry); return NULL; } if(goInfo->type != GAMEOBJECT_TYPE_MO_TRANSPORT) { sLog->outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template type wrong", goEntry, goInfo->name.c_str()); return NULL; } Transport* t = new Transport(period, goInfo->ScriptId); std::set<uint32> mapsUsed; if(!t->GenerateWaypoints(goInfo->moTransport.taxiPathId, mapsUsed)) { sLog->outErrorDb("Transport (path id %u) path size = 0. Transport ignored, check DBC files or the gameobject's data0 field.", goInfo->moTransport.taxiPathId); delete t; return NULL; } uint32 transportLowGuid = sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT); if(!t->Create(transportLowGuid, goEntry, t->m_WayPoints[0].mapid, t->m_WayPoints[0].x, t->m_WayPoints[0].y, t->m_WayPoints[0].z-10, 0.0f, 0, 0)) { delete t; return NULL; } m_Transports.insert(t); for(std::set<uint32>::const_iterator i = mapsUsed.begin(); i != mapsUsed.end(); ++i) m_TransportsByMap[*i].insert(t); t->SetMap(instance); t->AddToWorld(); t->BuildStartMovePacket(instance); t->BuildStopMovePacket(instance); // Make transport realy stoppped at server-side. Movement will be handled by scripts t->m_WayPoints.clear(); return t; }
Transport* MapManager::LoadTransportInMap(Map* instance, uint32 goEntry, uint32 period) { const GameObjectTemplate* goInfo = sObjectMgr->GetGameObjectTemplate(goEntry); if (!goInfo) { sLog->outError(LOG_FILTER_SQL, "Transport ID:%u, will not be loaded, gameobject_template missing", goEntry); return NULL; } if (goInfo->type != GAMEOBJECT_TYPE_MO_TRANSPORT) { sLog->outError(LOG_FILTER_SQL, "Transport ID:%u, Name: %s, will not be loaded, gameobject_template type wrong", goEntry, goInfo->name.c_str()); return NULL; } Transport* t = new Transport(period, goInfo->ScriptId); std::set<uint32> mapsUsed; if (!t->GenerateWaypoints(goInfo->moTransport.taxiPathId, mapsUsed)) { sLog->outError(LOG_FILTER_SQL, "Transport (path id %u) path size = 0. Transport ignored, check DBC files or the gameobject's data0 field.", goInfo->moTransport.taxiPathId); delete t; return NULL; } uint32 transportLowGuid = sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT); if (!t->Create(transportLowGuid, goEntry, t->m_WayPoints[0].mapid, t->m_WayPoints[0].x, t->m_WayPoints[0].y, t->m_WayPoints[0].z-10, 0.0f, 0, 0)) { delete t; return NULL; } m_Transports.insert(t); m_TransportsByInstanceIdMap[instance->GetInstanceId()].insert(t); t->SetMap(instance); t->AddToWorld(); // Spameando la nave quieta t->BuildWaitMovePacket(instance); sLog->outInfo(LOG_FILTER_UNITS,"Creando el transporte <---"); return t; }
void MapManager::CreateTransportsOnMap(Map* map) { // no transports on this map? if (m_TransportInfosByMap.find(map->GetId()) == m_TransportInfosByMap.end()) return; for (auto ti : m_TransportInfosByMap[map->GetId()]) { Transport* t = new Transport; t->m_period = ti->period; std::set<uint32> mapsUsed; // skip transports with empty waypoints list if (!t->GenerateWaypoints(ti->pathid, mapsUsed)) { sLog.outErrorDb("Transport (path id %u) path size = 0. Transport not created, check DBC files or transport GO data0 field.", ti->pathid); delete t; continue; } // creates the Gameobject if (!t->Create(ti->entry, map->GetId(), ti->pos.x, ti->pos.y, ti->pos.z, ti->pos.o, GO_ANIMPROGRESS_DEFAULT, 0)) { delete t; continue; } m_Transports.insert(t); for (uint32 i : mapsUsed) m_TransportsByMap[i].insert(t); // link transport to the map on which it spawns (its first waypoint) t->SetMap(map); // add the transport to world t->AddToWorld(); } }
Transport* MapManager::LoadTransportInMap(Map* instance, uint32 goEntry, uint32 period) { const GameObjectTemplate* goInfo = sObjectMgr->GetGameObjectTemplate(goEntry); if (!goInfo) { return NULL; } if (goInfo->type != GAMEOBJECT_TYPE_MO_TRANSPORT) { return NULL; } Transport* t = new Transport(period, goInfo->ScriptId); std::set<uint32> mapsUsed; if (!t->GenerateWaypoints(goInfo->moTransport.taxiPathId, mapsUsed)) { delete t; return NULL; } uint32 transportLowGuid = sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT); if (!t->Create(transportLowGuid, goEntry, t->m_WayPoints[0].mapid, t->m_WayPoints[0].x, t->m_WayPoints[0].y, t->m_WayPoints[0].z-10, 0.0f, 0, 0)) { delete t; return NULL; } m_Transports.insert(t); m_TransportsByInstanceIdMap[instance->GetInstanceId()].insert(t); t->SetMap(instance); t->AddToWorld(); return t; }
void MapManager::LoadTransports() { uint32 oldMSTime = getMSTime(); QueryResult result = WorldDatabase.Query("SELECT guid, entry, name, period, ScriptName FROM transports"); if(!result) { sLog->outString(">> Loaded 0 transports. DB table `transports` is empty!"); sLog->outString(); return; } uint32 count = 0; do { Field* fields = result->Fetch(); uint32 lowguid = fields[0].GetUInt32(); uint32 entry = fields[1].GetUInt32(); std::string name = fields[2].GetString(); uint32 period = fields[3].GetUInt32(); uint32 scriptId = sObjectMgr->GetScriptId(fields[4].GetCString()); const GameObjectTemplate* goinfo = sObjectMgr->GetGameObjectTemplate(entry); if(!goinfo) { sLog->outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template missing", entry, name.c_str()); continue; } if(goinfo->type != GAMEOBJECT_TYPE_MO_TRANSPORT) { sLog->outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template type wrong", entry, name.c_str()); continue; } // sLog->outString("Loading transport %d between %s, %s", entry, name.c_str(), goinfo->name); std::set<uint32> mapsUsed; Transport* t = new Transport(period, scriptId); if(!t->GenerateWaypoints(goinfo->moTransport.taxiPathId, mapsUsed)) // skip transports with empty waypoints list { sLog->outErrorDb("Transport (path id %u) path size = 0. Transport ignored, check DBC files or transport GO data0 field.", goinfo->moTransport.taxiPathId); delete t; continue; } float x = t->m_WayPoints[0].x; float y = t->m_WayPoints[0].y; float z = t->m_WayPoints[0].z; uint32 mapid = t->m_WayPoints[0].mapid; float o = 1.0f; // creates the Gameobject if(!t->Create(lowguid, entry, mapid, x, y, z, o, 100, 0)) { delete t; continue; } m_Transports.insert(t); for(std::set<uint32>::const_iterator i = mapsUsed.begin(); i != mapsUsed.end(); ++i) m_TransportsByMap[*i].insert(t); //If we someday decide to use the grid to track transports, here: t->SetMap(sMapMgr->CreateMap(mapid, t, 0)); t->AddToWorld(); ++count; } while(result->NextRow()); // check transport data DB integrity result = WorldDatabase.Query("SELECT gameobject.guid, gameobject.id, transports.name FROM gameobject, transports WHERE gameobject.id = transports.entry"); if(result) // wrong data found { do { Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); uint32 entry = fields[1].GetUInt32(); std::string name = fields[2].GetString(); sLog->outErrorDb("Transport %u '%s' have record (GUID: %u) in `gameobject`. Transports must not have any records in `gameobject` or its behavior will be unpredictable/bugged.", entry, name.c_str(), guid); } while(result->NextRow()); } sLog->outString(">> Loaded %u transports in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); }
Transport* TransportMgr::CreateTransport(uint32 entry, Map* map /*= NULL*/) { // instance case, execute GetGameObjectEntry hook if (map) { // SetZoneScript() is called after adding to map, so fetch the script using map if (map->IsDungeon()) if (InstanceScript* instance = static_cast<InstanceMap*>(map)->GetInstanceScript()) entry = instance->GetGameObjectEntry(0, entry); if (!entry) return NULL; } TransportTemplate const* tInfo = GetTransportTemplate(entry); if (!tInfo) { sLog->outErrorDb("Transport %u will not be loaded, `transport_template` missing", entry); return NULL; } // create transport... Transport* trans = new Transport(); // ...at first waypoint TaxiPathNodeEntry const* startNode = tInfo->keyFrames.begin()->node; uint32 mapId = startNode->mapid; float x = startNode->x; float y = startNode->y; float z = startNode->z; float o = 1.0f; // initialize the gameobject base if (!trans->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT), entry, mapId, x, y, z, o, 100, 0)) { delete trans; return NULL; } if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId)) { if (uint32(mapEntry->Instanceable()) != trans->GetGOInfo()->moTransport.inInstance) { sLog->outError("Transport %u (name: %s) attempted creation in instance map (id: %u) but it is not an instanced transport!", entry, trans->GetName(), mapId); delete trans; return NULL; } } // use preset map for instances (need to know which instance) trans->SetMap(map ? map : sMapMgr->CreateMap(mapId, trans, 0)); trans->SetZoneScript(); // Get all spawns on Transport map if (uint32 mapId = trans->GetGOInfo()->moTransport.mapID) { CellObjectGuidsMap const& cells = sObjectMgr->GetMapObjectGuids(mapId, REGULAR_DIFFICULTY); CellGuidSet::const_iterator guidEnd; for (CellObjectGuidsMap::const_iterator cellItr = cells.begin(); cellItr != cells.end(); ++cellItr) { // Creatures on transport guidEnd = cellItr->second.creatures.end(); for (CellGuidSet::const_iterator guidItr = cellItr->second.creatures.begin(); guidItr != guidEnd; ++guidItr) { CreatureData const* data = sObjectMgr->GetCreatureData(*guidItr); trans->CreateNPCPassenger(data->id, data->posX, data->posY, data->posZ, data->orientation, data); } // GameObjects on transport } } // register in container for updates _transportUpdates.insert(trans); // and in container designed for quicker access by mapId for (std::set<uint32>::const_iterator i = tInfo->mapsUsed.begin(); i != tInfo->mapsUsed.end(); ++i) _transportMap[*i].insert(trans); trans->AddToWorld(); if (map) trans->UpdateForMap(map); return trans; }