summaryrefslogtreecommitdiffhomepage
path: root/editor/tests/path-test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/tests/path-test.cpp')
-rw-r--r--editor/tests/path-test.cpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/editor/tests/path-test.cpp b/editor/tests/path-test.cpp
new file mode 100644
index 00000000..2bc40717
--- /dev/null
+++ b/editor/tests/path-test.cpp
@@ -0,0 +1,128 @@
+#include "../tests-private.hpp"
+#include "../app.hpp"
+#include "floormat/main.hpp"
+#include "src/path-search.hpp"
+#include "src/critter.hpp"
+#include "shaders/shader.hpp"
+#include "../imgui-raii.hpp"
+#include "src/camera-offset.hpp"
+#include <Magnum/Math/Functions.h>
+
+namespace floormat::tests {
+
+bool path_test::handle_key(app& a, const key_event& e, bool is_down)
+{
+ (void)a; (void)e; (void)is_down;
+ return false;
+}
+
+bool path_test::handle_mouse_click(app& a, const mouse_button_event& e, bool is_down)
+{
+ if (is_down)
+ return false;
+
+ switch (e.button)
+ {
+ case mouse_button_left: {
+ auto& M = a.main();
+ auto& w = M.world();
+ auto C = a.ensure_player_character(w);
+ if (auto pt = a.cursor_state().point())
+ {
+ constexpr auto chunk_size = iTILE_SIZE2 * TILE_MAX_DIM;
+ auto pt0 = C->position();
+ auto vec = Math::abs((pt->coord() - pt0.coord())) * iTILE_SIZE2 * 2 + chunk_size * 1;
+ auto dist = (uint32_t)vec.length();
+
+ has_pending = true;
+ pending = { .from = pt0, .to = *pt, .own_id = C->id,
+ .max_dist = dist, .own_size = C->bbox_size, };
+ }
+ return true;
+ }
+ case mouse_button_right: {
+ bool ret = false;
+ if (has_pending)
+ {
+ has_pending = false;
+ pending = {};
+ ret = true;
+ }
+ if (has_result)
+ {
+ has_result = false;
+ result = {};
+ ret = true;
+ }
+ return ret;
+ }
+ default:
+ return false;
+ }
+}
+
+bool path_test::handle_mouse_move(app& a, const mouse_move_event& e)
+{
+ (void)a; (void)e;
+ return false;
+}
+
+void path_test::draw_overlay(app& a)
+{
+ if (!has_result)
+ return;
+
+ const auto win_size = a.main().window_size();
+ const auto line_color = ImGui::ColorConvertFloat4ToU32({0, 0, 1, 1});
+ const auto dot_color = ImGui::ColorConvertFloat4ToU32({1, 0, 0, 1});
+ constexpr float line_thickness = 3, dot_radius = 5;
+ auto& shader = a.main().shader();
+ ImDrawList& draw = *ImGui::GetForegroundDrawList();
+
+ constexpr auto get_screen_pos = [](tile_shader& shader, point pt, Vector2i win_size) {
+ auto c3 = pt.chunk3();
+ auto c2 = pt.chunk();
+ with_shifted_camera_offset co{shader, c3, c2, c2 };
+ auto world_pos = TILE_SIZE20 * Vector3(pt.local()) + Vector3(Vector2(pt.offset()), 0);
+ return Vector2(shader.camera_offset()) + Vector2(win_size)*.5f + shader.project(world_pos);
+ };
+
+ auto last = get_screen_pos(shader, result.from, win_size);
+ draw.AddCircleFilled({last.x(), last.y()}, dot_radius, dot_color);
+
+ for (auto pt : result.path)
+ {
+ auto pos = get_screen_pos(shader, pt, win_size);
+ draw.AddLine({pos.x(), pos.y()}, {last.x(), last.y()}, line_color, line_thickness);
+ draw.AddCircleFilled({pos.x(), pos.y()}, dot_radius, dot_color);
+ last = pos;
+ }
+}
+
+void path_test::update_pre(app& a)
+{
+ if (!has_pending)
+ return;
+
+ has_result = false;
+ has_pending = false;
+
+ auto& M = a.main();
+ auto& w = M.world();
+ auto& astar = M.astar();
+
+ auto res = astar.Dijkstra(w, pending.from, pending.to, pending.own_id, pending.max_dist, pending.own_size, 1);
+ if (res)
+ {
+ has_result = true;
+ result.from = pending.from;
+ result.path = res.path();
+ }
+}
+
+void path_test::update_post(app& a)
+{
+ (void)a;
+}
+
+} // namespace floormat::tests