test: extend coverage of testRaid
This commit is contained in:
1 parent
817e000542
commit
67a5f3ff27
1 file changed
+137
@@ -319,3 +319,140 @@ VF_TEST(golemsTurnOnThePlayerOnceTheVillageReputationCollapses) {
|
|||||||
updateGolemHostility(spawner, buildReputation(calm, {}));
|
updateGolemHostility(spawner, buildReputation(calm, {}));
|
||||||
CHECK(!spawner.hostileToPlayer);
|
CHECK(!spawner.hostileToPlayer);
|
||||||
|
|
||||||
|
GossipLedger angry;
|
||||||
|
angry.add(GossipKind::MajorNegative, gossipMajorNegativeGain);
|
||||||
|
std::vector<const GossipLedger*> village{&angry, &angry};
|
||||||
|
updateGolemHostility(spawner, buildReputation(calm, village));
|
||||||
|
CHECK(spawner.hostileToPlayer);
|
||||||
|
|
||||||
|
std::vector<const GossipLedger*> mixed{&angry, &calm, &calm, &calm, &calm, &calm};
|
||||||
|
updateGolemHostility(spawner, buildReputation(calm, mixed));
|
||||||
|
CHECK(!spawner.hostileToPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(twoRaidManagersOnTheSameSeedProduceTheSameRaid) {
|
||||||
|
World world = makeRaidWorld();
|
||||||
|
VillagerSchedule schedule;
|
||||||
|
TimeOfDay clock(static_cast<WorldTick>(0.35 * 24000.0));
|
||||||
|
|
||||||
|
PoiRegistry firstPois;
|
||||||
|
firstPois.scan(world, villageCenter, 12, 4);
|
||||||
|
std::vector<Villager> firstVillagers = makeVillagers(4);
|
||||||
|
OmenState firstOmen = omenAt(2);
|
||||||
|
RaidManager first(villageCenter, 4242u, raidDifficultyHard);
|
||||||
|
CHECK(first.tryStart(firstOmen, {0.5f, static_cast<float>(walkY), 0.5f}, 32.0f));
|
||||||
|
first.tick(world, firstVillagers, firstPois, firstOmen, schedule, clock, 300);
|
||||||
|
|
||||||
|
PoiRegistry secondPois;
|
||||||
|
secondPois.scan(world, villageCenter, 12, 4);
|
||||||
|
std::vector<Villager> secondVillagers = makeVillagers(4);
|
||||||
|
OmenState secondOmen = omenAt(2);
|
||||||
|
RaidManager second(villageCenter, 4242u, raidDifficultyHard);
|
||||||
|
CHECK(second.tryStart(secondOmen, {0.5f, static_cast<float>(walkY), 0.5f}, 32.0f));
|
||||||
|
second.tick(world, secondVillagers, secondPois, secondOmen, schedule, clock, 300);
|
||||||
|
|
||||||
|
CHECK_EQ(first.totalSpawned(), second.totalSpawned());
|
||||||
|
CHECK_EQ(first.livingRaiders(), second.livingRaiders());
|
||||||
|
CHECK_EQ(first.golems().spawnedTotal, second.golems().spawnedTotal);
|
||||||
|
CHECK(first.state() == second.state());
|
||||||
|
|
||||||
|
bool identical = first.raiders().size() == second.raiders().size();
|
||||||
|
for (std::size_t i = 0; i < first.raiders().size() && identical; ++i) {
|
||||||
|
const Raider& a = first.raiders()[i];
|
||||||
|
const Raider& b = second.raiders()[i];
|
||||||
|
if (a.kind != b.kind || a.alive != b.alive) identical = false;
|
||||||
|
if (std::fabs(a.position.x - b.position.x) > 1e-5f) identical = false;
|
||||||
|
if (std::fabs(a.position.z - b.position.z) > 1e-5f) identical = false;
|
||||||
|
if (std::fabs(a.health - b.health) > 1e-5f) identical = false;
|
||||||
|
}
|
||||||
|
CHECK(identical);
|
||||||
|
|
||||||
|
RaidManager other(villageCenter, 99u, raidDifficultyHard);
|
||||||
|
OmenState otherOmen = omenAt(2);
|
||||||
|
std::vector<Villager> otherVillagers = makeVillagers(4);
|
||||||
|
PoiRegistry otherPois;
|
||||||
|
otherPois.scan(world, villageCenter, 12, 4);
|
||||||
|
CHECK(other.tryStart(otherOmen, {0.5f, static_cast<float>(walkY), 0.5f}, 32.0f));
|
||||||
|
other.tick(world, otherVillagers, otherPois, otherOmen, schedule, clock, 1);
|
||||||
|
CHECK_EQ(other.wave().total(), first.wave().total());
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(villagersPanicHomeInsteadOfWorkingWhileTheRaidIsRunning) {
|
||||||
|
World world = makeRaidWorld();
|
||||||
|
PoiRegistry pois;
|
||||||
|
pois.scan(world, villageCenter, 12, 4);
|
||||||
|
std::vector<Villager> villagers = makeVillagers(2);
|
||||||
|
VillagerSchedule schedule;
|
||||||
|
TimeOfDay clock(static_cast<WorldTick>(0.35 * 24000.0));
|
||||||
|
|
||||||
|
for (int tick = 0; tick < 400; ++tick)
|
||||||
|
for (Villager& villager : villagers)
|
||||||
|
tickVillager(world, villager, pois, clock, schedule, villageCenter, false, 0.05f);
|
||||||
|
CHECK(villagers[0].activity == VillagerActivity::Work);
|
||||||
|
CHECK(villagers[0].employed());
|
||||||
|
int workBefore = villagers[0].workTicks;
|
||||||
|
|
||||||
|
OmenState omen = omenAt(1);
|
||||||
|
RaidManager raid(villageCenter, 8u, raidDifficultyEasy);
|
||||||
|
CHECK(raid.tryStart(omen, {0.5f, static_cast<float>(walkY), 0.5f}, 32.0f));
|
||||||
|
raid.tick(world, villagers, pois, omen, schedule, clock, 120);
|
||||||
|
|
||||||
|
CHECK(villagers[0].activity == VillagerActivity::Panic);
|
||||||
|
CHECK_EQ(villagers[0].workTicks, workBefore);
|
||||||
|
CHECK(villagers[0].bedIndex >= 0);
|
||||||
|
CHECK(villagers[0].alive);
|
||||||
|
CHECK(pois.at(villagers[0].bedIndex).ownerId == villagers[0].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(aWaveAdvancesOnTimeoutWhenTheRaidersRefuseToDie) {
|
||||||
|
World world = makeRaidWorld();
|
||||||
|
PoiRegistry pois;
|
||||||
|
pois.scan(world, villageCenter, 12, 4);
|
||||||
|
std::vector<Villager> villagers = makeVillagers(2);
|
||||||
|
VillagerSchedule schedule;
|
||||||
|
TimeOfDay clock(static_cast<WorldTick>(0.35 * 24000.0));
|
||||||
|
OmenState omen = omenAt(1);
|
||||||
|
|
||||||
|
RaidManager raid(villageCenter, 606u, raidDifficultyNormal);
|
||||||
|
CHECK(raid.tryStart(omen, {0.5f, static_cast<float>(walkY), 0.5f}, 32.0f));
|
||||||
|
|
||||||
|
int firstWaveSize = 0;
|
||||||
|
for (int tick = 0; tick < raidWaveTimeoutTicks - 5; ++tick) {
|
||||||
|
raid.tick(world, villagers, pois, omen, schedule, clock, 1);
|
||||||
|
for (Villager& villager : villagers)
|
||||||
|
if (villager.alive) villager.health = 20.0f;
|
||||||
|
if (firstWaveSize == 0) firstWaveSize = raid.totalSpawned();
|
||||||
|
}
|
||||||
|
CHECK_EQ(raid.waveIndex(), 0);
|
||||||
|
CHECK_EQ(raid.totalSpawned(), firstWaveSize);
|
||||||
|
CHECK(raid.livingRaiders() > 0);
|
||||||
|
|
||||||
|
for (int tick = 0; tick < 20; ++tick) {
|
||||||
|
raid.tick(world, villagers, pois, omen, schedule, clock, 1);
|
||||||
|
for (Villager& villager : villagers)
|
||||||
|
if (villager.alive) villager.health = 20.0f;
|
||||||
|
}
|
||||||
|
CHECK_EQ(raid.waveIndex(), 1);
|
||||||
|
CHECK(raid.totalSpawned() > firstWaveSize);
|
||||||
|
CHECK(raid.state() == RaidState::Fighting);
|
||||||
|
CHECK_EQ(livingVillagerCount(villagers), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(raiderKindsCarryDistinctStatsAndReadableNames) {
|
||||||
|
const Raider::Stats& footSoldier = raiderStats(RaiderKind::Raider);
|
||||||
|
const Raider::Stats& brute = raiderStats(RaiderKind::Ravager);
|
||||||
|
CHECK(brute.maxHealth > footSoldier.maxHealth);
|
||||||
|
CHECK(brute.damage > footSoldier.damage);
|
||||||
|
CHECK(brute.speed > footSoldier.speed);
|
||||||
|
CHECK(raiderStats(RaiderKind::Witch).attackRange > footSoldier.attackRange);
|
||||||
|
|
||||||
|
CHECK_EQ(std::string(raiderKindName(RaiderKind::Vindicator)), std::string("vindicator"));
|
||||||
|
CHECK_EQ(std::string(raidStateName(RaidState::Victory)), std::string("victory"));
|
||||||
|
CHECK_EQ(std::string(raidStateName(RaidState::Defeat)), std::string("defeat"));
|
||||||
|
|
||||||
|
RaidManager raid(villageCenter, 1u);
|
||||||
|
CHECK(raid.center() == villageCenter);
|
||||||
|
CHECK_EQ(raid.livingRaiders(), 0);
|
||||||
|
CHECK(!raid.damageRaider(0, 5.0f));
|
||||||
|
CHECK(raid.state() == RaidState::Inactive);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user