summaryrefslogtreecommitdiffhomepage
path: root/editor/tests/path.cpp
blob: f6ebc1cb7ea402b5ccae4099b9541c907cbfe9ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#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"

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 = (pt->coord() - pt0.coord()) * iTILE_SIZE2 + 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:
        if (has_pending | has_result)
        {
            has_pending = has_result = false;
            pending = {};
            result = {};
            return true;
        }
        return false;
    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