/* client/mapwidget.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "client/mapwidget.h" #include "client/targets.h" #include "core/application.h" #include "ui/paint.h" #include "render/render.h" #include "render/gl.h" #include "client/targets.h" #include "ui/ui.h" namespace client { MapWidget::MapWidget(ui::Widget *parent) : ui::Widget(parent) { set_label("mapwidget"); mapwidget_zone = 0; mapwidget_target = 0; mapwidget_hover_id = 0; mapwidget_zoom = 1.0f; } MapWidget::~MapWidget() { } void MapWidget::set_zoom(const float zoom) { mapwidget_zoom = zoom; } void MapWidget::set_target(const core::Entity *entity) { mapwidget_target = entity; } void MapWidget::set_zone(core::Zone *zone) { mapwidget_zone = zone; } bool MapWidget::on_keypress(const int key, const unsigned int modifier) { if (key == 512 + SDL_BUTTON_LEFT) { if (mapwidget_zone && has_mouse_focus() && hover()) { core::Entity *target = mapwidget_zone->find_entity(hover()); if (targets::is_valid_map_target(target)) { set_target(target); emit(ui::Widget::EventClicked); } } return true; } return false; } void MapWidget::draw() { if (!mapwidget_zone) return; // size and global location of the map const float map_size = math::min(width(), height()); math::Vector2f map_location(global_location()); if (map_size < width()) { map_location[0] += (width() - map_size) * 0.5f; } if (map_size < height()) { map_location[1] += (height() - map_size) * 0.5f; } // draw background math::Vector2f background_size(map_size, map_size); ui::Paint::draw_material(map_location, background_size, "ui/background"); // number of squares in one grid segment const float grid_size = 16.0f; // draw the grid itself gl::color(0, 0, 0.8f); gl::begin(gl::Lines); for (float i = 0; i <= grid_size; i += 1.0f) { gl::vertex(map_location.x(), map_location.y() + map_size / grid_size * i); gl::vertex(map_location.x() + map_size, map_location.y() + map_size / grid_size * i); gl::vertex(map_location.x() + map_size / grid_size * i, map_location.y()); gl::vertex(map_location.x() + map_size / grid_size * i, map_location.y() + map_size); } gl::end(); // request required textures const size_t texture_entity = render::Textures::load("bitmaps/icons/entity_default"); const size_t texture_globe = render::Textures::load("bitmaps/icons/entity_globe"); const size_t texture_bright = render::Textures::load("bitmaps/icons/entity_bright"); size_t texture_current = render::Textures::bind(texture_entity); // global mouse cursor location const math::Vector2f cursor(ui::root()->global_mouse_coords()); mapwidget_hover_id = 0; // map center math::Vector2f map_center(map_location[0] + map_size / 2.0f, map_location[1] + map_size / 2.0f); math::Vector2f icon_location; const float r = 12.0f; // radius of map icons float scale = 4096.0f; // map size in game units math::Color color; const core::Entity *entity = 0; // draw map icons gl::enable(GL_TEXTURE_2D); gl::begin(gl::Quads); for (core::Zone::Content::iterator it = mapwidget_zone->content().begin(); it != mapwidget_zone->content().end(); it++) { entity = (*it); bool draw_icon = false; icon_location.assign(map_center); if (targets::is_valid_map_target(entity)) { draw_icon = true; icon_location[0] -= map_size / scale * entity->location().y(); icon_location[1] -= map_size / scale * entity->location().x(); if (math::distancesquared(cursor, icon_location) < (r*r)) { mapwidget_hover_id = entity->id(); } if (entity == mapwidget_target) { if (core::application()->time() - floorf(core::application()->time()) < 0.5f) { draw_icon = false; } } } if (draw_icon) { if (entity->type() == core::Entity::Globe) { if (entity->has_flag(core::Entity::Bright)) { if (texture_current != texture_bright) { gl::end(); texture_current = render::Textures::bind(texture_bright); gl::begin(gl::Quads); } } else { if (texture_current != texture_globe) { gl::end(); texture_current = render::Textures::bind(texture_globe); gl::begin(gl::Quads); } } } else { if (texture_current != texture_entity) { gl::end(); texture_current = render::Textures::bind(texture_entity); gl::begin(gl::Quads); } } if (entity == core::localplayer()->mission_target()) { color.assign(palette()->mission()); } else { color.assign(entity->color()); } color.a = 1.0f; gl::color(color); glTexCoord2f(0.0f, 0.0f); gl::vertex(icon_location.x() - r, icon_location.y() - r); glTexCoord2f(1.0f, 0.0f); gl::vertex(icon_location.x() + r, icon_location.y() - r); glTexCoord2f(1.0f, 1.0f); gl::vertex(icon_location.x() + r, icon_location.y() + r); glTexCoord2f(0.0f, 1.0f); gl::vertex(icon_location.x() - r, icon_location.y() + r); } } gl::end(); // draw localcontrol icon // TODO draw a ship icon if (core::localcontrol()->zone() == mapwidget_zone) { entity = core::localcontrol(); //if (core::localcontrol()->state() != core::Entity::Docked) { icon_location.assign(map_center); icon_location[0] -= map_size / scale * entity->location().y(); icon_location[1] -= map_size / scale * entity->location().x(); if (core::application()->time() - floorf(core::application()->time()) < 0.5f) { texture_current = render::Textures::bind(texture_entity); gl::begin(gl::Quads); math::Color color(entity->color()); color.a = 1.0f; gl::color(color); glTexCoord2f(0.0f, 0.0f); gl::vertex(icon_location.x() - r, icon_location.y() - r); glTexCoord2f(1.0f, 0.0f); gl::vertex(icon_location.x() + r, icon_location.y() - r); glTexCoord2f(1.0f, 1.0f); gl::vertex(icon_location.x() + r, icon_location.y() + r); glTexCoord2f(0.0f, 1.0f); gl::vertex(icon_location.x() - r, icon_location.y() + r); gl::end(); } } gl::disable(GL_TEXTURE_2D); if (has_mouse_focus()) { if (mapwidget_hover_id) ui::root()->set_pointer("target", ui::Palette::Active, true); } } } // namespace client