| 1308 | } |
| 1309 | |
| 1310 | Maybe<CelestialCoordinate> UniverseServer::nextStarterWorld() { |
| 1311 | RecursiveMutexLocker locker(m_mainLock); |
| 1312 | |
| 1313 | auto assets = Root::singleton().assets(); |
| 1314 | String defaultWorldCoordinate = assets->json("/universe_server.config:defaultWorldCoordinate").toString(); |
| 1315 | if (!defaultWorldCoordinate.empty()) |
| 1316 | return CelestialCoordinate(defaultWorldCoordinate); |
| 1317 | |
| 1318 | if (m_nextRandomizedStarterWorld && m_nextRandomizedStarterWorld->done()) { |
| 1319 | CelestialCoordinate nextWorld = m_nextRandomizedStarterWorld->get(); |
| 1320 | m_nextRandomizedStarterWorld.reset(); |
| 1321 | return nextWorld; |
| 1322 | } |
| 1323 | |
| 1324 | if (!m_nextRandomizedStarterWorld) { |
| 1325 | m_nextRandomizedStarterWorld = m_workerPool.addProducer<CelestialCoordinate>([assets, celestialDatabase = m_celestialDatabase]() { |
| 1326 | Logger::info("Searching for new randomized starter world"); |
| 1327 | auto filterWorld = [celestialDatabase](CelestialCoordinate const& coordinate, Json const& filter) { |
| 1328 | auto parameters = celestialDatabase->parameters(coordinate); |
| 1329 | auto visitableParameters = parameters->visitableParameters(); |
| 1330 | if (!visitableParameters) |
| 1331 | return false; |
| 1332 | |
| 1333 | if (auto biome = filter.optString("terrestrialBiome")) { |
| 1334 | auto terrestrialParameters = as<TerrestrialWorldParameters>(visitableParameters); |
| 1335 | if (!terrestrialParameters || *biome != terrestrialParameters->primaryBiome) |
| 1336 | return false; |
| 1337 | } |
| 1338 | |
| 1339 | if (auto size = filter.optString("terrestrialSize")) { |
| 1340 | auto terrestrialParameters = as<TerrestrialWorldParameters>(visitableParameters); |
| 1341 | if (!terrestrialParameters || *size != terrestrialParameters->sizeName) |
| 1342 | return false; |
| 1343 | } |
| 1344 | |
| 1345 | if (auto dungeon = filter.optString("floatingDungeon")) { |
| 1346 | auto dungeonParameters = as<FloatingDungeonWorldParameters>(visitableParameters); |
| 1347 | if (!dungeonParameters || *dungeon != dungeonParameters->primaryDungeon) |
| 1348 | return false; |
| 1349 | } |
| 1350 | |
| 1351 | return true; |
| 1352 | }; |
| 1353 | |
| 1354 | auto findParameters = assets->json("/universe_server.config:findStarterWorldParameters"); |
| 1355 | auto randomWorld = celestialDatabase->findRandomWorld(findParameters.getUInt("tries"), findParameters.getUInt("range"), [&](CelestialCoordinate const& coordinate) { |
| 1356 | if (!filterWorld(coordinate, findParameters.get("starterWorld"))) |
| 1357 | return false; |
| 1358 | |
| 1359 | List<CelestialCoordinate> allChildren; |
| 1360 | for (auto const& planet : celestialDatabase->children(coordinate.system())) { |
| 1361 | allChildren.append(planet); |
| 1362 | for (auto const& satellite : celestialDatabase->children(planet)) |
| 1363 | allChildren.append(satellite); |
| 1364 | } |
| 1365 | |
| 1366 | for (auto const& requiredSystemWorld : findParameters.getArray("requiredSystemWorlds", {})) { |
| 1367 | bool worldFound = false; |
nothing calls this directly
no test coverage detected