MCPcopy Create free account
hub / github.com/OpenStarbound/OpenStarbound / findPlayerStart

Method findPlayerStart

source/game/StarWorldServer.cpp:2376–2431  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2374}
2375
2376Vec2F WorldServer::findPlayerStart(Maybe<Vec2F> firstTry) {
2377 Vec2F spawnRectSize = jsonToVec2F(m_serverConfig.get("playerStartRegionSize"));
2378 auto maximumVerticalSearch = m_serverConfig.getInt("playerStartRegionMaximumVerticalSearch");
2379 auto maximumTries = m_serverConfig.getInt("playerStartRegionMaximumTries");
2380
2381 static const Set<DungeonId> allowedSpawnDungeonIds = {NoDungeonId, SpawnDungeonId, ConstructionDungeonId, DestroyedBlockDungeonId};
2382
2383 Vec2F pos;
2384 if (firstTry)
2385 pos = *firstTry;
2386 else
2387 pos = Vec2F(m_worldTemplate->findSensiblePlayerStart().value(Vec2I(0, m_worldTemplate->surfaceLevel())));
2388
2389 CollisionSet collideWithAnything{CollisionKind::Null, CollisionKind::Block, CollisionKind::Dynamic, CollisionKind::Platform, CollisionKind::Slippery};
2390 for (int t = 0; t < maximumTries; ++t) {
2391 bool foundGround = false;
2392 // First go downward until we collide with terrain
2393 for (int i = 0; i < maximumVerticalSearch; ++i) {
2394 RectF spawnRect = RectF(pos[0] - spawnRectSize[0] / 2, pos[1], pos[0] + spawnRectSize[0] / 2, pos[1] + spawnRectSize[1]);
2395 generateRegion(RectI::integral(spawnRect));
2396 if (rectTileCollision(RectI::integral(spawnRect), collideWithAnything)) {
2397 foundGround = true;
2398 break;
2399 }
2400 --pos[1];
2401 }
2402
2403 if (foundGround) {
2404 // Then go up until our spawn region is no longer in the terrain, but bail
2405 // out and try again if we can't signal the region or we are stuck in a
2406 // dungeon.
2407 for (int i = 0; i < maximumVerticalSearch; ++i) {
2408 if (m_tileArray->tile(Vec2I::floor(pos)).liquid.liquid != EmptyLiquidId)
2409 break;
2410
2411 RectF spawnRect = RectF(pos[0] - spawnRectSize[0] / 2, pos[1], pos[0] + spawnRectSize[0] / 2, pos[1] + spawnRectSize[1]);
2412
2413 generateRegion(RectI::integral(spawnRect));
2414
2415 auto tileDungeonId = getServerTile(Vec2I::floor(pos)).dungeonId;
2416
2417 if (!allowedSpawnDungeonIds.contains(tileDungeonId))
2418 break;
2419
2420 if (!rectTileCollision(RectI::integral(spawnRect), collideWithAnything) && spawnRect.yMax() < m_geometry.height())
2421 return pos;
2422
2423 ++pos[1];
2424 }
2425 }
2426
2427 pos = Vec2F(m_worldTemplate->findSensiblePlayerStart().value(Vec2I(0, m_worldTemplate->surfaceLevel())));
2428 }
2429
2430 return pos;
2431}
2432
2433Vec2F WorldServer::findPlayerSpaceStart(float targetX) {

Callers

nothing calls this directly

Calls 10

jsonToVec2FFunction · 0.85
rectTileCollisionFunction · 0.85
getIntMethod · 0.80
surfaceLevelMethod · 0.80
yMaxMethod · 0.80
getMethod · 0.45
valueMethod · 0.45
containsMethod · 0.45
heightMethod · 0.45

Tested by

no test coverage detected