#include "app.hpp" #include "compat/debug.hpp" #include "compat/shared-ptr-wrapper.hpp" #include "src/critter.hpp" #include "src/world.hpp" #include "src/wall-atlas.hpp" #include "src/timer.hpp" #include "loader/loader.hpp" namespace floormat { namespace { constexpr auto constantly(const auto& x) noexcept { return [x] (const Ts&...) constexpr -> const auto& { return x; }; } template void run(StringView name, const F& make_dt, critter& npc, const uint32_t max_steps, const point start, const rotation r, const point end, const Ns expected_time, const uint32_t fuzz_pixels, const Ns fuzz_time) { fm_assert(max_steps <= 1000); auto index = npc.index(); npc.teleport_to(index, start, rotation_COUNT); Ns time{0}; uint32_t steps; Debug{} << "=>" << name; Debug{} << ">>" << npc.position(); auto last_pos = npc.position(); uint32_t i; bool stopped = false; for (uint32_t i = 0; i <= max_steps; i++) { auto dt = Ns{make_dt()}; fm_assert(dt <= Ns(1e9)); npc.update_movement(index, dt, r); const auto pos = npc.position(); if (pos == last_pos) { stopped = true; break; } last_pos = pos; Debug{} << "" << i << Vector2i(pos.local()) << pos.offset(); } if (stopped) Debug{} << " break!"; else Debug{} << " loop ends..."; } /* ***** TEST 1 ***** * * wall n 0x0 - 8:9 * wall n 0x1 - 8:0 * * npc speed=5 bbox-offset=0 bbox-size=32x32 * * before chunk=0x0 tile=8:15 offset=-8:8 * after chunk=0x0 tile=8:9 offset=-8:-16 */ critter_proto make_proto(int accel) { critter_proto proto; proto.atlas = loader.anim_atlas("npc-walk", loader.ANIM_PATH); proto.name = "Player"_s; proto.speed = accel; proto.playable = true; proto.offset = {}; proto.bbox_offset = {}; proto.bbox_size = Vector2ub(tile_size_xy/2); return proto; } using enum rotation; template void test1(const F& make_dt, int accel) { const auto W = wall_image_proto{ loader.wall_atlas("empty"), 0 }; auto w = world(); w[{{0,0,0}, {8,9}}].t.wall_north() = W; w[{{0,1,0}, {8,0}}].t.wall_north() = W; constexpr point init {{0,0,0}, {8,15}, {-8, 8}}; constexpr point end {{0,0,0}, {8, 9}, {-8,-16}}; object_id id = 0; auto player = w.ensure_player_character(id, make_proto(accel)).ptr; w[chunk_coords_{0,0,0}].mark_modified(); w[chunk_coords_{0,1,0}].mark_modified(); run("test1"_s, make_dt, *player, 10, init, N, end, Second*7, 16, Millisecond*350); } template void test2(F&& make_dt, int accel) { // TODO diagonal! } } // namespace void test_app::test_critter() { Debug{} << ""; Debug{} << "--"; Debug{} << ""; test1(constantly(Millisecond * 1000), 1); Debug{} << ""; } } // namespace floormat