summaryrefslogtreecommitdiff
path: root/src/game/interface.cpp
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2018-03-28 14:17:47 +0200
committerPaweł Redman <pawel.redman@gmail.com>2018-03-28 14:17:47 +0200
commit6966908022e36df9fb4c5e2233603a6fef18e97d (patch)
tree1540097e60001636cbe752d8fb1e459f45081e41 /src/game/interface.cpp
parentaa4731d2e1305ea4fb6d59032026bf1ce6f2b65d (diff)
Pie menu; start redoing shooting mechanics.
Diffstat (limited to 'src/game/interface.cpp')
-rw-r--r--src/game/interface.cpp105
1 files changed, 104 insertions, 1 deletions
diff --git a/src/game/interface.cpp b/src/game/interface.cpp
index 262c3ae..d3ef661 100644
--- a/src/game/interface.cpp
+++ b/src/game/interface.cpp
@@ -51,6 +51,69 @@ void state_t::stop_following(void)
print(text::get(text::FOLLOWING_OFF));
}
+void pie_menu_t::open(v2f_t wmouse, v2f_t mouse)
+{
+ size_t layer = 0;
+ float base_radius = 50.0f; // FIXME
+
+ for (size_t i = 0; i < items.size(); ) {
+ size_t left, layer_cap, on_layer;
+
+ left = items.size() - i;
+ layer_cap = (layer + 1) * (layer + 1);
+ on_layer = std::min(left, layer_cap);
+
+ for (size_t j = 0; j < on_layer; j++) {
+ pie_item_t *item = &items[i + j];
+ float dt = 2 * M_PI / on_layer;
+
+ item->r0 = layer * base_radius;
+ item->r1 = (layer + 1) * base_radius;
+ item->t0 = j * dt;
+ item->t1 = (j + 1) * dt;
+ }
+
+ i += on_layer;
+ layer++;
+ }
+
+ is_open = true;
+ x_world = wmouse;
+ x = mouse;
+}
+
+void pie_menu_t::close(game::state_t *game)
+{
+ if (!is_open)
+ return;
+
+ if (selected)
+ game->command(x_world, selected->action);
+
+ is_open = false;
+ items.clear();
+}
+
+void pie_menu_t::update(v2f_t mouse)
+{
+ v2f_t delta;
+ float r, t;
+
+ delta = mouse - x;
+ r = delta.len();
+ t = atan2(delta[1], delta[0]);
+ if (t < 0)
+ t += 2 * M_PI;
+
+ selected = nullptr;
+ for (pie_item_t &i : items) {
+ if (r >= i.r0 && r <= i.r1 && t >= i.t0 && t <= i.t1) {
+ selected = &i;
+ break;
+ }
+ }
+}
+
void state_t::tick(double dt)
{
vec_t<int, 2> window_size;
@@ -59,6 +122,7 @@ void state_t::tick(double dt)
v2f_t view_size;
v2f_t follow_center(0, 0), view_center, pan_delta;
float view_scale;
+ sf::Vector2i mouse;
v2f_t wmouse; // Mouse position in world space;
window_size = window->getSize();
@@ -101,6 +165,7 @@ void state_t::tick(double dt)
window->setView(sf::View(view_center, view_size));
}
+ mouse = sf::Mouse::getPosition(*window);
wmouse = window->mapPixelToCoords(sf::Mouse::getPosition(*window));
while (window->pollEvent(event)) {
@@ -119,7 +184,8 @@ void state_t::tick(double dt)
break;
case sf::Mouse::Button::Right:
- game->command(wmouse);
+ if (game->populate_pie_menu(pie_menu.items))
+ pie_menu.open(wmouse, mouse);
break;
case sf::Mouse::Button::Middle:
@@ -139,6 +205,10 @@ void state_t::tick(double dt)
select.selecting = false;
break;
+ case sf::Mouse::Button::Right:
+ pie_menu.close(game);
+ break;
+
case sf::Mouse::Button::Middle:
if (camera.panning)
camera.center += pan_delta;
@@ -207,6 +277,8 @@ void state_t::tick(double dt)
if (select.selecting)
select.rect[1] = wmouse;
+
+ pie_menu.update(mouse);
}
void state_t::print(std::string str)
@@ -215,6 +287,35 @@ void state_t::print(std::string str)
std::cout << str << std::endl;
}
+void pie_menu_t::render_to(render::state_t *render)
+{
+ if (!is_open)
+ return;
+
+ for (pie_item_t &i : items) {
+ sf::Color color;
+ v2f_t rad, center;
+
+ if (&i == selected)
+ color = sf::Color(255, 255, 255, 120);
+ else
+ color = sf::Color(255, 255, 255, 40);
+
+ render->render_ring_sect(x, i.r0, i.r1, i.t0, i.t1, color);
+
+ color.a = 255;
+
+ if (i.r0 == 0.0f) {
+ center = x;
+ } else {
+ center = x + (i.r1 + i.r0) / 2 *
+ v2f_t::rad((i.t1 + i.t0) / 2);
+ }
+
+ render->render_text(center, 15, i.label, render::text_align_t::ALIGN_CENTER_BOTTOM, color);
+ }
+}
+
void state_t::render_to(render::state_t *render)
{
size_t w = window->getSize().x, h = window->getSize().y;
@@ -228,6 +329,8 @@ void state_t::render_to(render::state_t *render)
window->setView(sf::View(sf::FloatRect(0, 0, w, h)));
em = std::max(w, h) * 0.017;
+ pie_menu.render_to(render);
+
for (auto i = log.begin(); i != log.end(); ) {
if (i->time + 3 < game->now)
i = log.erase(i);