/* client/map.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "audio/audio.h" #include "core/application.h" #include "client/map.h" #include "client/input.h" #include "client/targets.h" #include "ui/ui.h" #include "ui/paint.h" #include "render/gl.h" #include "render/textures.h" #include "render/text.h" namespace client { Map::Map(ui::Widget *parent) : ui::Window(parent) { set_label("map"); set_border(true); set_background(true); set_font(ui::root()->font_small()); map_targetlabel = new ui::Label(this); map_targetlabel->set_label("targetlabel"); map_targetlabel->set_background(false); map_targetlabel->set_border(false); map_targetlabel->set_font(ui::root()->font_large()); map_targetlabel->set_alignment(ui::AlignCenter); map_scrollpane = new ui::ScrollPane(this, map_infotext); map_scrollpane->set_background(false); map_scrollpane->set_border(false); map_scrollpane->set_alignment(ui::AlignTop); set_target(0); map_hover = 0; hide(); } Map::~Map() { } void Map::hide() { ui::Window::hide(); map_hover = 0; map_target = 0; } void Map::show() { ui::Window::show(); map_hover = 0; if (core::localplayer()->view()) { map_target = core::localplayer()->view(); } else { map_target = targets::current(); } } void Map::toggle() { if (visible()) hide(); else show(); } void Map::resize() { const float fontmargin = map_targetlabel->font()->height(); // resize label map_targetlabel->set_size(width() - fontmargin * 2.0f, fontmargin); map_targetlabel->set_location(fontmargin, fontmargin); // resize infotext pane map_scrollpane->set_size(width() - ui::UI::elementsize.width() * 1.5f - fontmargin * 3.0f, height() - ui::UI::elementsize.height() * 2.0f - fontmargin * 3.0f); map_scrollpane->set_location(ui::UI::elementsize.width() * 1.5f + fontmargin * 2.0f, fontmargin * 3.0f); } void Map::draw() { const float fontmargin = map_targetlabel->font()->height(); const float s = ui::UI::elementsize.width() * 1.5f; const float blue = 0.8f; const float gridsize = 16; const core::Entity *entity; const core::Entity *current_target = map_target; map_target = 0; math::Color color; math::Vector2f v(global_location()); math::Vector2f l; v[0] += fontmargin; v[1] += fontmargin + (height() - s) * 0.5f; map_hover = 0; gl::color(0, 0, blue); gl::begin(gl::Lines); for (int i = 0; i <= gridsize; i++) { gl::vertex(v.x(), v.y() + s / gridsize * i); gl::vertex(v.x() + s, v.y() + s / gridsize * i); gl::vertex(v.x() + s / gridsize * i, v.y()); gl::vertex(v.x() + s / gridsize * i, v.y() + s); } gl::end(); 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); v[0] += s * 0.5f; v[1] += s * 0.5f; core::Zone *zone = core::localplayer()->zone(); const math::Vector2f cursor(input::mouse_position_x(), input::mouse_position_y()); const float r = 12.0f; float scale = 2048.0f; scale *= 2; gl::enable(GL_TEXTURE_2D); gl::begin(gl::Quads); // draw map icons for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { entity = (*it); bool draw_icon = false; l.assign(v); if (targets::is_valid_map_target(entity)) { draw_icon = true; l[0] -= s / scale * entity->location().y(); l[1] -= s / scale * entity->location().x(); if (math::distancesquared(cursor, l) < (r*r)) { map_hover = entity->id(); } if (entity == current_target) { map_target = entity; if (core::application()->time() - floorf(core::application()->time()) < 0.5f) { draw_icon = false; } } } if (draw_icon) { if (entity->type() == core::Entity::Globe) { if (entity->flag_is_set(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(l.x() - r, l.y() - r); glTexCoord2f(1.0f, 0.0f); gl::vertex(l.x() + r, l.y() - r); glTexCoord2f(1.0f, 1.0f); gl::vertex(l.x() + r, l.y() + r); glTexCoord2f(0.0f, 1.0f); gl::vertex(l.x() - r, l.y() + r); } } // draw localcontrol icon entity = core::localcontrol(); //if (core::localcontrol()->state() != core::Entity::Docked) { l.assign(v); l[0] -= s / scale * entity->location().y(); l[1] -= s / scale * entity->location().x(); if (core::application()->time() - floorf(core::application()->time()) < 0.5f) { if (texture_current != texture_entity) { gl::end(); 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(l.x() - r, l.y() - r); glTexCoord2f(1.0f, 0.0f); gl::vertex(l.x() + r, l.y() - r); glTexCoord2f(1.0f, 1.0f); gl::vertex(l.x() + r, l.y() + r); glTexCoord2f(0.0f, 1.0f); gl::vertex(l.x() - r, l.y() + r); } //} gl::end(); gl::disable(GL_TEXTURE_2D); if (map_target != current_target ) { // this makes sure the map target exists set_target(current_target); } else if (map_inforecord && (map_infotimestamp != map_inforecord->timestamp())) { set_target(map_target); } } void Map::set_target(const core::Entity *entity) { map_target = entity; map_infotimestamp = 0; map_inforecord = 0; map_infotext.clear(); if (map_target) { // set title label to target name map_targetlabel->set_text(map_target->name()); map_targetlabel->show(); if (map_target->info()) map_inforecord = core::game()->request_info(map_target->info()->id()); else map_inforecord = 0; if (map_inforecord) { for (core::Info::Text::const_iterator it = map_inforecord->text().begin(); it != map_inforecord->text().end(); it++) { map_infotext.push_back((*it)); } map_infotimestamp = map_inforecord->timestamp(); } else { map_infotext.push_back("Information is not available"); map_infotimestamp = 0; } map_scrollpane->show(); } else { map_targetlabel->hide(); map_scrollpane->hide(); } } bool Map::on_keypress(const int key, const unsigned int modifier) { if (key == 512 + SDL_BUTTON_LEFT) { if (hover()) { core::Entity *target = core::localplayer()->zone()->find_entity(hover()); if (targets::is_valid_map_target(target)) { set_target(target); targets::set_target(map_target); } } return true; } else if (key == SDLK_ESCAPE) { if (visible()) { hide(); return true; } } return false; } }