test: extend coverage of testSpawning
This commit is contained in:
1 parent
832d5f6b8b
commit
5dbfacf76f
1 file changed
+158
@@ -314,3 +314,161 @@ VF_TEST(aRunningCycleStopsSpawningOnceTheCapIsReached) {
|
||||
spawner.runCycle(env, SpawnCategory::Hostile, columns, 1234u + static_cast<uint64_t>(cycle));
|
||||
}
|
||||
|
||||
CHECK(env.populationOf(SpawnCategory::Hostile) > 0);
|
||||
CHECK(env.populationOf(SpawnCategory::Hostile) <= limit + 4);
|
||||
CHECK(spawner.denialCount(SpawnDenial::CategoryCapReached) > 0);
|
||||
}
|
||||
|
||||
VF_TEST(aPackArrivesSpreadAroundItsOriginCell) {
|
||||
World world = plateWorld(Block::Grass);
|
||||
LightField light = bakeLight(world);
|
||||
SpawnEnvironment env = nightEnvironment(world, light);
|
||||
|
||||
SpawnRule rule = zombieRule();
|
||||
rule.packMin = 4;
|
||||
rule.packMax = 4;
|
||||
rule.packSpread = 3;
|
||||
|
||||
Spawner spawner({rule});
|
||||
SpawnTrial trial;
|
||||
trial.cell = originCell();
|
||||
trial.species = Species::Zombie;
|
||||
trial.category = SpawnCategory::Hostile;
|
||||
trial.ruleFound = true;
|
||||
trial.cellFound = true;
|
||||
trial.packSize = 4;
|
||||
|
||||
SpawnResult result = spawner.attemptSpawn(env, rule, trial, 4242u);
|
||||
CHECK(result.spawned);
|
||||
CHECK(result.denial == SpawnDenial::None);
|
||||
CHECK(result.packSize() >= 2);
|
||||
CHECK(result.packSize() <= 4);
|
||||
CHECK(result.role == BehaviorRole::HostileHunter);
|
||||
|
||||
for (const Vec3& spot : result.positions) {
|
||||
CHECK(std::fabs(spot.x - 0.5f) <= static_cast<float>(rule.packSpread));
|
||||
CHECK(std::fabs(spot.z - 0.5f) <= static_cast<float>(rule.packSpread));
|
||||
CHECK(world.solidAt(static_cast<int>(std::floor(spot.x)), floorY,
|
||||
static_cast<int>(std::floor(spot.z))));
|
||||
}
|
||||
}
|
||||
|
||||
VF_TEST(aSpawnedPackBecomesAgentsCarryingTheRightBehaviourRole) {
|
||||
World world = plateWorld(Block::Grass);
|
||||
LightField light = bakeLight(world);
|
||||
SpawnEnvironment env = nightEnvironment(world, light);
|
||||
|
||||
SpawnRule rule = zombieRule();
|
||||
rule.packMin = 3;
|
||||
rule.packMax = 3;
|
||||
Spawner spawner({rule});
|
||||
|
||||
SpawnTrial trial;
|
||||
trial.cell = originCell();
|
||||
trial.species = Species::Zombie;
|
||||
trial.ruleFound = true;
|
||||
trial.cellFound = true;
|
||||
trial.packSize = 3;
|
||||
|
||||
SpawnResult result = spawner.attemptSpawn(env, rule, trial, 77u);
|
||||
CHECK(result.spawned);
|
||||
|
||||
std::vector<BehaviorAgent> agents = agentsFromSpawn(result, 5u);
|
||||
CHECK_EQ(agents.size(), result.positions.size());
|
||||
const SpeciesStats& stats = speciesStats(Species::Zombie);
|
||||
for (const BehaviorAgent& agent : agents) {
|
||||
CHECK(agent.species == Species::Zombie);
|
||||
CHECK_NEAR(agent.health, stats.maxHealth, 1e-6f);
|
||||
CHECK_NEAR(agent.maxHealth, stats.maxHealth, 1e-6f);
|
||||
CHECK(agent.moveStep > 0.0f);
|
||||
CHECK(agent.rng != 0u);
|
||||
}
|
||||
CHECK(makeTreeForRole(result.role).structureValid());
|
||||
|
||||
SpawnResult refused;
|
||||
CHECK(agentsFromSpawn(refused, 5u).empty());
|
||||
}
|
||||
|
||||
VF_TEST(despawnNeverTouchesAMobStandingNextToThePlayer) {
|
||||
DespawnPolicy policy;
|
||||
DespawnCandidate mob;
|
||||
mob.position = {10.0f, 64.0f, 0.0f};
|
||||
Vec3 player{0.0f, 64.0f, 0.0f};
|
||||
|
||||
CHECK(despawnBandFor(policy, mob.position, player) == DespawnBand::Protected);
|
||||
uint32_t rng = 12345u;
|
||||
for (int tick = 0; tick < 2000; ++tick) {
|
||||
CHECK(!shouldDespawn(policy, mob, player, rng));
|
||||
}
|
||||
}
|
||||
|
||||
VF_TEST(despawnRemovesAMobBeyondTheHardDistanceImmediately) {
|
||||
DespawnPolicy policy;
|
||||
DespawnCandidate mob;
|
||||
mob.position = {200.0f, 64.0f, 0.0f};
|
||||
Vec3 player{0.0f, 64.0f, 0.0f};
|
||||
|
||||
CHECK(despawnBandFor(policy, mob.position, player) == DespawnBand::Immediate);
|
||||
uint32_t rng = 1u;
|
||||
CHECK(shouldDespawn(policy, mob, player, rng));
|
||||
CHECK_EQ(rng, 1u);
|
||||
}
|
||||
|
||||
VF_TEST(despawnInTheMiddleBandIsARollThatMatchesItsStatedOdds) {
|
||||
DespawnPolicy policy;
|
||||
policy.randomChanceDenominator = 50;
|
||||
DespawnCandidate mob;
|
||||
mob.position = {64.0f, 64.0f, 0.0f};
|
||||
Vec3 player{0.0f, 64.0f, 0.0f};
|
||||
CHECK(despawnBandFor(policy, mob.position, player) == DespawnBand::Random);
|
||||
|
||||
int hits = 0;
|
||||
uint32_t rng = 0x1337u;
|
||||
for (int tick = 0; tick < 5000; ++tick) {
|
||||
if (shouldDespawn(policy, mob, player, rng)) ++hits;
|
||||
}
|
||||
CHECK(hits > 40);
|
||||
CHECK(hits < 180);
|
||||
|
||||
// Same seed, same sequence of rolls.
|
||||
int replay = 0;
|
||||
uint32_t again = 0x1337u;
|
||||
for (int tick = 0; tick < 5000; ++tick) {
|
||||
if (shouldDespawn(policy, mob, player, again)) ++replay;
|
||||
}
|
||||
CHECK_EQ(replay, hits);
|
||||
}
|
||||
|
||||
VF_TEST(namedAndLeashedMobsSurviveEvenAtTheEdgeOfTheWorld) {
|
||||
DespawnPolicy policy;
|
||||
Vec3 player{0.0f, 64.0f, 0.0f};
|
||||
uint32_t rng = 9u;
|
||||
|
||||
DespawnCandidate named;
|
||||
named.position = {500.0f, 64.0f, 0.0f};
|
||||
named.named = true;
|
||||
CHECK(despawnCandidateIsProtected(policy, named));
|
||||
CHECK(!shouldDespawn(policy, named, player, rng));
|
||||
|
||||
DespawnCandidate leashed;
|
||||
leashed.position = {500.0f, 64.0f, 0.0f};
|
||||
leashed.leashed = true;
|
||||
CHECK(!shouldDespawn(policy, leashed, player, rng));
|
||||
|
||||
DespawnCandidate persistent;
|
||||
persistent.position = {500.0f, 64.0f, 0.0f};
|
||||
persistent.persistent = true;
|
||||
CHECK(!shouldDespawn(policy, persistent, player, rng));
|
||||
|
||||
DespawnPolicy ruthless;
|
||||
ruthless.despawnNamed = true;
|
||||
CHECK(!despawnCandidateIsProtected(ruthless, named));
|
||||
CHECK(shouldDespawn(ruthless, named, player, rng));
|
||||
}
|
||||
|
||||
VF_TEST(theSpawnerBlockCountsDownActivatesAndRespectsItsNearbyLimit) {
|
||||
World world = plateWorld(Block::Grass);
|
||||
LightField light = bakeLight(world);
|
||||
SpawnEnvironment env = nightEnvironment(world, light);
|
||||
env.playerPosition = {0.5f, static_cast<float>(spawnY), 0.5f};
|
||||
|
||||
Reference in new issue
Block a user