test: extend coverage of testBoss
This commit is contained in:
1 parent
41e4b6f89f
commit
e61823788a
1 file changed
+160
@@ -314,3 +314,163 @@ VF_TEST(theWitherIsCalledOutOfASoulSandPatternInEitherOrientation) {
|
||||
CHECK(findWitherPattern(alongZ, base, orientation));
|
||||
CHECK(!orientation);
|
||||
|
||||
WitherFight fight(11u);
|
||||
CHECK(fight.state().phase == BossPhase::Dormant);
|
||||
CHECK(!fight.state().bar.visible);
|
||||
CHECK(fight.summonFromWorld(alongX, base));
|
||||
CHECK(fight.state().phase == BossPhase::Summoning);
|
||||
CHECK(fight.state().bar.visible);
|
||||
CHECK(fight.state().bar.style == BossBarStyle::Notched6);
|
||||
CHECK_NEAR(fight.state().position.y, static_cast<float>(base.y + 1), 1e-6f);
|
||||
|
||||
// The pattern is consumed, so the same altar cannot be reused.
|
||||
CHECK(alongX.blockAt(base.x, base.y, base.z) == Block::Air);
|
||||
CHECK(alongX.blockAt(base.x, base.y + 2, base.z) == Block::Air);
|
||||
WitherFight second(12u);
|
||||
CHECK(!second.summonFromWorld(alongX, base));
|
||||
CHECK(second.state().phase == BossPhase::Dormant);
|
||||
|
||||
World broken = witherAltar(base, true);
|
||||
broken.setBlock(base.x, base.y + 2, base.z, Block::Stone);
|
||||
CHECK(!findWitherPattern(broken, base, orientation));
|
||||
}
|
||||
|
||||
VF_TEST(theWitherIsUntouchableWhileItChargesAndBlastsOnArrival) {
|
||||
WitherFight fight(5u, quickSummon(6));
|
||||
fight.begin(Vec3{0.0f, 64.0f, 0.0f});
|
||||
|
||||
std::vector<WitherTarget> targets;
|
||||
targets.push_back(WitherTarget{Vec3{4.0f, 64.0f, 0.0f}, 20.0f, true});
|
||||
targets.push_back(WitherTarget{Vec3{40.0f, 64.0f, 0.0f}, 20.0f, true});
|
||||
|
||||
std::vector<WitherHit> heavy;
|
||||
heavy.push_back(WitherHit{100.0f, false});
|
||||
|
||||
for (int step = 0; step < 5; ++step) {
|
||||
BossTickReport report = fight.tick(heavy, targets);
|
||||
CHECK(report.phase == BossPhase::Summoning);
|
||||
CHECK_NEAR(report.bossHealth, fight.settings().maxHealth, 1e-4f);
|
||||
}
|
||||
|
||||
BossTickReport blast = fight.tick(heavy, targets);
|
||||
CHECK(blast.phase == BossPhase::Explosive);
|
||||
CHECK(blast.phaseChanged);
|
||||
CHECK_NEAR(blast.damageToTargets, fight.settings().summonBlastDamage, 1e-4f);
|
||||
CHECK_NEAR(targets[0].health, 20.0f - fight.settings().summonBlastDamage, 1e-4f);
|
||||
CHECK_NEAR(targets[1].health, 20.0f, 1e-4f);
|
||||
|
||||
BossTickReport settle = fight.tick(std::vector<WitherHit>{}, targets);
|
||||
CHECK(settle.phase == BossPhase::Ranged);
|
||||
}
|
||||
|
||||
VF_TEST(theWitherArmoursUpExactlyAtHalfHealth) {
|
||||
WitherFight fight(21u, quickSummon(3));
|
||||
fight.begin(Vec3{0.0f, 64.0f, 0.0f});
|
||||
|
||||
std::vector<WitherTarget> targets;
|
||||
targets.push_back(WitherTarget{Vec3{10.0f, 64.0f, 0.0f}, 200.0f, true});
|
||||
runUpToRangedPhase(fight, targets);
|
||||
CHECK(fight.state().phase == BossPhase::Ranged);
|
||||
CHECK(!fight.armored());
|
||||
|
||||
float maxHealth = fight.settings().maxHealth;
|
||||
std::vector<WitherHit> nearlyHalf;
|
||||
nearlyHalf.push_back(WitherHit{maxHealth * 0.5f - 1.0f, false});
|
||||
BossTickReport stillBare = fight.tick(nearlyHalf, targets);
|
||||
CHECK(stillBare.phase == BossPhase::Ranged);
|
||||
CHECK_NEAR(stillBare.bossHealth, maxHealth * 0.5f + 1.0f, 1e-4f);
|
||||
CHECK(!fight.armored());
|
||||
|
||||
std::vector<WitherHit> theLastPoint;
|
||||
theLastPoint.push_back(WitherHit{1.0f, false});
|
||||
BossTickReport onTheLine = fight.tick(theLastPoint, targets);
|
||||
CHECK_NEAR(onTheLine.bossHealth, maxHealth * 0.5f, 1e-4f);
|
||||
CHECK(onTheLine.phase == BossPhase::Armored);
|
||||
CHECK(onTheLine.phaseChanged);
|
||||
CHECK(fight.armored());
|
||||
}
|
||||
|
||||
VF_TEST(armourStopsProjectilesButNotABladeAndTheWitherRegenerates) {
|
||||
WitherFight fight(33u, quickSummon(3));
|
||||
fight.begin(Vec3{0.0f, 64.0f, 0.0f});
|
||||
|
||||
std::vector<WitherTarget> targets;
|
||||
targets.push_back(WitherTarget{Vec3{10.0f, 64.0f, 0.0f}, 400.0f, true});
|
||||
runUpToRangedPhase(fight, targets);
|
||||
|
||||
std::vector<WitherHit> half;
|
||||
half.push_back(WitherHit{fight.settings().maxHealth * 0.5f, false});
|
||||
fight.tick(half, targets);
|
||||
CHECK(fight.armored());
|
||||
|
||||
float before = fight.state().health;
|
||||
std::vector<WitherHit> arrows;
|
||||
arrows.push_back(WitherHit{60.0f, true});
|
||||
BossTickReport shrugged = fight.tick(arrows, targets);
|
||||
CHECK(shrugged.bossHealth >= before);
|
||||
CHECK(shrugged.healedThisTick > 0.0f);
|
||||
|
||||
before = fight.state().health;
|
||||
std::vector<WitherHit> blade;
|
||||
blade.push_back(WitherHit{60.0f, false});
|
||||
BossTickReport cut = fight.tick(blade, targets);
|
||||
CHECK(cut.bossHealth < before - 50.0f);
|
||||
CHECK(fight.armored());
|
||||
}
|
||||
|
||||
VF_TEST(theArmouredWitherCallsMinionsUpToItsLimitAndKeepsShooting) {
|
||||
WitherFight fight(44u, quickSummon(3));
|
||||
fight.begin(Vec3{0.0f, 64.0f, 0.0f});
|
||||
|
||||
std::vector<WitherTarget> targets;
|
||||
targets.push_back(WitherTarget{Vec3{12.0f, 64.0f, 0.0f}, 100000.0f, true});
|
||||
runUpToRangedPhase(fight, targets);
|
||||
|
||||
std::vector<WitherHit> half;
|
||||
half.push_back(WitherHit{fight.settings().maxHealth * 0.5f, false});
|
||||
fight.tick(half, targets);
|
||||
CHECK(fight.armored());
|
||||
|
||||
std::vector<WitherHit> nothing;
|
||||
float targetHealthBefore = targets[0].health;
|
||||
for (int step = 0; step < 600; ++step) fight.tick(nothing, targets);
|
||||
|
||||
CHECK_EQ(fight.aliveMinionCount(), fight.settings().maxMinions);
|
||||
CHECK_EQ(fight.state().minionsSummoned, fight.settings().maxMinions);
|
||||
CHECK(targets[0].health < targetHealthBefore);
|
||||
CHECK(fight.state().attacksLaunched > 10);
|
||||
for (const BossMinion& minion : fight.minions()) {
|
||||
CHECK(minion.alive);
|
||||
CHECK(behaviorHorizontalDistance(minion.position, fight.state().position) > 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
VF_TEST(theWitherAlwaysSwitchesToTheNearestLivingTarget) {
|
||||
WitherFight fight(55u, quickSummon(3));
|
||||
fight.begin(Vec3{0.0f, 64.0f, 0.0f});
|
||||
|
||||
std::vector<WitherTarget> targets;
|
||||
targets.push_back(WitherTarget{Vec3{60.0f, 64.0f, 0.0f}, 500.0f, true});
|
||||
targets.push_back(WitherTarget{Vec3{12.0f, 64.0f, 0.0f}, 500.0f, true});
|
||||
targets.push_back(WitherTarget{Vec3{90.0f, 64.0f, 0.0f}, 500.0f, true});
|
||||
runUpToRangedPhase(fight, targets);
|
||||
|
||||
std::vector<WitherHit> nothing;
|
||||
fight.tick(nothing, targets);
|
||||
CHECK_EQ(fight.state().targetIndex, 1);
|
||||
|
||||
targets[1].alive = false;
|
||||
fight.tick(nothing, targets);
|
||||
CHECK_EQ(fight.state().targetIndex, 0);
|
||||
|
||||
targets[0].alive = false;
|
||||
targets[2].alive = false;
|
||||
BossTickReport alone = fight.tick(nothing, targets);
|
||||
CHECK_EQ(fight.state().targetIndex, -1);
|
||||
CHECK_NEAR(alone.damageToTargets, 0.0f, 1e-6f);
|
||||
}
|
||||
|
||||
VF_TEST(theWitherDiesWhenItsHealthRunsOutAndStopsTicking) {
|
||||
WitherFight fight(66u, quickSummon(3));
|
||||
fight.begin(Vec3{0.0f, 64.0f, 0.0f});
|
||||
|
||||
Reference in new issue
Block a user