test: add tests for base entity transform and physics integration
This commit is contained in:
1 parent
3505749616
commit
eabd2b10b4
1 file changed
+123
@@ -0,0 +1,123 @@
|
|||||||
|
#include "testHarness.h"
|
||||||
|
#include "vf/Entity.h"
|
||||||
|
|
||||||
|
using namespace vf;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
World floorWorld(int x0 = -4, int z0 = -4, int x1 = 24, int z1 = 24) {
|
||||||
|
World world;
|
||||||
|
for (int x = x0; x <= x1; ++x)
|
||||||
|
for (int z = z0; z <= z1; ++z)
|
||||||
|
world.setBlock(x, 0, z, Block::Stone);
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
VF_TEST(mobFallsAndLandsOnFloor) {
|
||||||
|
World world = floorWorld();
|
||||||
|
Mob mob;
|
||||||
|
mob.position = {5.0f, 6.0f, 5.0f};
|
||||||
|
MobConfig config;
|
||||||
|
|
||||||
|
for (int i = 0; i < 240; ++i) stepMob(world, mob, {0, 0, 0}, config, 1.0f / 60.0f);
|
||||||
|
|
||||||
|
CHECK(mob.onGround);
|
||||||
|
CHECK_NEAR(mob.position.y, 1.0f, 0.02f);
|
||||||
|
CHECK(!boxOverlapsSolid(world, mobBox(mob)));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(mobStopsAtWall) {
|
||||||
|
World world = floorWorld();
|
||||||
|
for (int y = 1; y <= 3; ++y)
|
||||||
|
for (int z = -4; z <= 24; ++z)
|
||||||
|
world.setBlock(10, y, z, Block::Stone);
|
||||||
|
|
||||||
|
Mob mob;
|
||||||
|
mob.position = {5.0f, 1.0f, 5.0f};
|
||||||
|
MobConfig config;
|
||||||
|
|
||||||
|
for (int i = 0; i < 300; ++i) stepMob(world, mob, {1.0f, 0.0f, 0.0f}, config, 1.0f / 60.0f);
|
||||||
|
|
||||||
|
CHECK(mob.position.x + mob.width * 0.5f <= 10.0f + 1e-3f);
|
||||||
|
CHECK(!boxOverlapsSolid(world, mobBox(mob)));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(mobBrainWandersWhenTargetFar) {
|
||||||
|
World world = floorWorld();
|
||||||
|
Mob mob;
|
||||||
|
mob.position = {5.0f, 1.0f, 5.0f};
|
||||||
|
MobConfig config;
|
||||||
|
Vec3 target{80.0f, 1.0f, 80.0f}; // way past chaseRadius
|
||||||
|
|
||||||
|
Vec3 wish = updateMobBrain(world, mob, target, config);
|
||||||
|
CHECK(mob.state == MobState::Wander);
|
||||||
|
CHECK(length(wish) > 0.5f); // still produces a heading
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(mobBrainChasesReachableTarget) {
|
||||||
|
World world = floorWorld();
|
||||||
|
Mob mob;
|
||||||
|
mob.position = {5.0f, 1.0f, 5.0f};
|
||||||
|
MobConfig config;
|
||||||
|
Vec3 target{9.0f, 1.0f, 5.0f}; // within chaseRadius, open ground
|
||||||
|
|
||||||
|
Vec3 wish = updateMobBrain(world, mob, target, config);
|
||||||
|
CHECK(mob.state == MobState::Chase);
|
||||||
|
CHECK(wish.x > 0.5f); // heads toward +x target
|
||||||
|
CHECK(wish.x > std::fabs(wish.z)); // +x is the dominant component
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(mobBrainHysteresisKeepsChaseInBand) {
|
||||||
|
World world = floorWorld();
|
||||||
|
Mob mob;
|
||||||
|
mob.position = {5.0f, 1.0f, 5.0f};
|
||||||
|
mob.state = MobState::Chase;
|
||||||
|
MobConfig config; // chase 12, lose 16
|
||||||
|
Vec3 inBand{5.0f + 14.0f, 1.0f, 5.0f}; // between chase and lose
|
||||||
|
|
||||||
|
updateMobBrain(world, mob, inBand, config);
|
||||||
|
CHECK(mob.state == MobState::Chase); // stays chasing in the band
|
||||||
|
|
||||||
|
Vec3 farOut{5.0f + 20.0f, 1.0f, 5.0f};
|
||||||
|
updateMobBrain(world, mob, farOut, config);
|
||||||
|
CHECK(mob.state == MobState::Wander); // drops chase past loseRadius
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(mobBrainWandersWhenTargetUnreachable) {
|
||||||
|
World world = floorWorld();
|
||||||
|
// seal a target cell at {9,1,5}
|
||||||
|
for (int y = 1; y <= 2; ++y) {
|
||||||
|
world.setBlock(8, y, 5, Block::Stone);
|
||||||
|
world.setBlock(10, y, 5, Block::Stone);
|
||||||
|
world.setBlock(9, y, 4, Block::Stone);
|
||||||
|
world.setBlock(9, y, 6, Block::Stone);
|
||||||
|
}
|
||||||
|
Mob mob;
|
||||||
|
mob.position = {5.0f, 1.0f, 5.0f};
|
||||||
|
MobConfig config;
|
||||||
|
Vec3 target{9.0f, 1.0f, 5.0f}; // in range but sealed off
|
||||||
|
|
||||||
|
updateMobBrain(world, mob, target, config);
|
||||||
|
CHECK(mob.state == MobState::Wander);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(mobChaseClosesDistanceOverTime) {
|
||||||
|
World world = floorWorld(-4, -4, 30, 30);
|
||||||
|
Mob mob;
|
||||||
|
mob.position = {2.5f, 1.0f, 2.5f};
|
||||||
|
MobConfig config;
|
||||||
|
config.chaseRadius = 40.0f;
|
||||||
|
config.loseRadius = 50.0f;
|
||||||
|
Vec3 target{18.5f, 1.0f, 2.5f};
|
||||||
|
|
||||||
|
float startDist = mob.position.x;
|
||||||
|
for (int i = 0; i < 500; ++i) {
|
||||||
|
Vec3 wish = updateMobBrain(world, mob, target, config);
|
||||||
|
stepMob(world, mob, wish, config, 1.0f / 60.0f);
|
||||||
|
}
|
||||||
|
CHECK(mob.state == MobState::Chase);
|
||||||
|
CHECK(mob.position.x > startDist + 10.0f); // advanced toward the target
|
||||||
|
CHECK(std::fabs(mob.position.x - target.x) < 1.5f); // arrived near it
|
||||||
|
}
|
||||||
Reference in new issue
Block a user