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
|
#include "markers.h"
#include <cmath>
#include <functional>
#include <string>
#include <utility>
#include <entt/entity/entity.hpp>
#include <entt/entity/handle.hpp>
#include <raylib.h>
#include <kurator/engine/Point.h>
#include <kurator/sim/components.h>
#include <kurator/sim/FloatingMovement.h>
#include <kurator/sim/State.h>
#include <kurator/universe/ShipType.h>
#include <kurator/universe/UniqueIdentifier.h>
#include "colors.h"
#include "PopupEmitter.h"
namespace kurator
{
void
attach_markers(sim::State& ctx)
{
auto ships = ctx.registry.view<sim::Team, universe::ShipType, universe::UniqueIdentifier, sim::Transform>();
for (const auto& [entity, team, type, identifier, transform] : ships.each()) {
auto pos = ctx.camera.to_screen(transform.position);
std::string label = TextFormat("%s (%d)", type.name.c_str(), identifier.id);
ctx.registry.emplace<Marker>(entity, std::move(pos), 5.0, team_color(team.id), std::move(label));
ctx.registry.emplace<PopupEmitter>(entity);
}
}
void
update_markers(sim::State& ctx, std::function<void(entt::handle)> select)
{
engine::Point mouse {static_cast<double>(GetMouseX()), static_cast<double>(GetMouseY())};
entt::entity hover {entt::null};
auto markers = ctx.registry.view<Marker, sim::Transform>();
for (auto&& [entity, marker, transform] : markers.each()) {
marker.screen = ctx.camera.to_screen(transform.position);
marker.hovered = false;
if (mouse.distance(marker.screen) <= marker.radius)
hover = entity;
}
if (ctx.registry.valid(hover)) {
auto& marker = ctx.registry.get<Marker>(hover);
marker.hovered = true;
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && select)
select(entt::handle{ctx.registry, hover});
}
}
void
draw_markers(const sim::State& ctx)
{
auto view = ctx.registry.view<Marker, sim::Transform>();
for (const auto& [entity, marker, transform] : view.each()) {
const auto& pos = marker.screen;
if (ctx.registry.all_of<sim::FloatingMovement>(entity)) {
const auto& movement = ctx.registry.get<sim::FloatingMovement>(entity);
const auto& velocity = movement.speed;
const auto edge = pos + velocity.normalized().scale(marker.radius);
const auto tip = edge + velocity.scale(2.0 * ctx.camera.scale);
DrawLine(edge.x, edge.y, tip.x, tip.y, DARKGREEN);
}
const engine::Point direction {std::cos(transform.angle), std::sin(transform.angle)};
const auto edge = pos + direction.scale(marker.radius);
if (marker.hovered)
DrawCircle(pos.x, pos.y, marker.radius + 2, WHITE);
DrawCircle(pos.x, pos.y, marker.radius, marker.color);
DrawLine(pos.x, pos.y, edge.x, edge.y, WHITE);
DrawText(marker.name.c_str(), pos.x+10, pos.y-5, 10.0f, marker.hovered ? WHITE : GRAY);
}
}
} // namespace kurator
|