Files
voxelforge/tests/testNetherGen.cpp
T

167 lines
5.3 KiB
C++

#include "testHarness.h"
#include "vf/NetherGen.h"
#include <map>
#include <set>
using namespace vf;
namespace {
std::map<Block, int> censusColumn(const World& world, int columnX, int columnZ, int ceilingY) {
std::map<Block, int> tally;
int ox = columnX * chunkSize;
int oz = columnZ * chunkSize;
for (int gx = ox; gx < ox + chunkSize; ++gx)
for (int gz = oz; gz < oz + chunkSize; ++gz)
for (int gy = 0; gy < ceilingY; ++gy)
++tally[world.blockAt(gx, gy, gz)];
return tally;
}
int countOf(const std::map<Block, int>& tally, Block block) {
auto it = tally.find(block);
return it == tally.end() ? 0 : it->second;
}
int findColumnWithBiome(const NetherGenerator& generator, NetherBiome biome, int& outColumnX,
int& outColumnZ) {
for (int columnX = -40; columnX <= 40; ++columnX) {
for (int columnZ = -40; columnZ <= 40; ++columnZ) {
int probeX = columnX * chunkSize + 8;
int probeZ = columnZ * chunkSize + 8;
if (generator.biomeAt(probeX, probeZ) != biome) continue;
outColumnX = columnX;
outColumnZ = columnZ;
return 1;
}
}
return 0;
}
} // namespace
VF_TEST(netherChunkGenerationRepeatsExactlyOnTheSameSeed) {
NetherGenerator generator;
Chunk first, second;
generator.generateChunk(first, {2, 3, -4});
generator.generateChunk(second, {2, 3, -4});
CHECK(first.raw() == second.raw());
Chunk elsewhere;
generator.generateChunk(elsewhere, {2, 3, 5});
CHECK(first.raw() != elsewhere.raw());
NetherGenerator::Params other;
other.seed = 9001u;
NetherGenerator reseeded(other);
World original, alternative;
generator.generateColumn(original, 2, -4);
reseeded.generateColumn(alternative, 2, -4);
int differingChunks = 0;
for (const auto& entry : original.allChunks()) {
const Chunk* twin = alternative.chunkAt(entry.first);
if (!twin || twin->raw() != entry.second->raw()) ++differingChunks;
}
CHECK(differingChunks > 0);
}
VF_TEST(netherColumnIsByteIdenticalAcrossTwoRuns) {
NetherGenerator generator;
World first, second;
generator.generateColumn(first, -3, 6);
generator.generateColumn(second, -3, 6);
CHECK_EQ(first.chunkCount(), second.chunkCount());
CHECK_EQ(first.chunkCount(), static_cast<std::size_t>(generator.stackChunkCount()));
int mismatches = 0;
for (const auto& entry : first.allChunks()) {
const Chunk* twin = second.chunkAt(entry.first);
if (!twin || twin->raw() != entry.second->raw()) ++mismatches;
}
CHECK_EQ(mismatches, 0);
}
VF_TEST(netherGenerationStaysInsideTheColumnItWasAskedFor) {
NetherGenerator generator;
World world;
generator.generateColumn(world, 5, 7);
int strays = 0;
for (const auto& entry : world.allChunks())
if (entry.first.x != 5 || entry.first.z != 7) ++strays;
CHECK_EQ(strays, 0);
}
VF_TEST(netherIsSealedByBedrockAtTheFloorAndTheRoof) {
NetherGenerator generator;
const NetherGenerator::Params& params = generator.settings();
World world;
generator.generateColumn(world, 0, 0);
int floorGaps = 0;
int roofGaps = 0;
for (int gx = 0; gx < chunkSize; ++gx) {
for (int gz = 0; gz < chunkSize; ++gz) {
if (world.blockAt(gx, params.floorY, gz) != Block::Bedrock) ++floorGaps;
if (world.blockAt(gx, params.ceilingY - 1, gz) != Block::Bedrock) ++roofGaps;
}
}
CHECK_EQ(floorGaps, 0);
CHECK_EQ(roofGaps, 0);
// The bands just inside those layers are ragged, not uniformly bedrock.
int raggedFloor = 0;
for (int gx = 0; gx < chunkSize; ++gx)
for (int gz = 0; gz < chunkSize; ++gz)
if (generator.isBedrock(gx, params.floorY + 2, gz)) ++raggedFloor;
CHECK(raggedFloor > 0);
CHECK(raggedFloor < chunkSize * chunkSize);
CHECK(!generator.isBedrock(0, 60, 0));
}
VF_TEST(netherCavernSitsBetweenTheFloorAndTheRoofMass) {
NetherGenerator generator;
const NetherGenerator::Params& params = generator.settings();
int drownedColumns = 0;
int dryColumns = 0;
for (int gx = -400; gx <= 400; gx += 37) {
for (int gz = -400; gz <= 400; gz += 37) {
NetherColumn column = generator.columnAt(gx, gz);
CHECK(column.floorHeight > params.floorY);
CHECK(column.ceilingHeight < params.ceilingY - 1);
CHECK(column.cavernHeight() >= 9);
CHECK_EQ(column.lavaLevel, params.lavaLevel);
if (column.drowned) ++drownedColumns;
else ++dryColumns;
}
}
CHECK(drownedColumns > 0);
CHECK(dryColumns > 0);
}
VF_TEST(netherLavaSeaLeavesNoAirBelowItsSurface) {
NetherGenerator generator;
const NetherGenerator::Params& params = generator.settings();
int airBelowLava = 0;
int lavaSamples = 0;
for (int gx = -120; gx <= 120; gx += 11) {
for (int gz = -120; gz <= 120; gz += 11) {
NetherColumn column = generator.columnAt(gx, gz);
for (int gy = params.floorY + 1; gy <= params.lavaLevel; ++gy) {
Block block = generator.blockAt(column, gx, gy, gz);
if (block == Block::Air) ++airBelowLava;
if (block == Block::Lava) ++lavaSamples;
}
}
}
CHECK_EQ(airBelowLava, 0);
CHECK(lavaSamples > 0);
}