From 79b1af52c004469dbad6b2fc8ba8ff239b48112f Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 23 Dec 2012 23:11:43 +0000 Subject: Use bitmaps to draw on-screen HUD targets, improved HUD target health bars. --- src/client/hud.cc | 174 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 135 insertions(+), 39 deletions(-) (limited to 'src/client/hud.cc') diff --git a/src/client/hud.cc b/src/client/hud.cc index 7db0398..bcbc3a8 100644 --- a/src/client/hud.cc +++ b/src/client/hud.cc @@ -16,6 +16,7 @@ #include "render/render.h" #include "render/renderext.h" #include "ui/ui.h" +#include "ui/paint.h" namespace client { @@ -118,6 +119,10 @@ void HUD::draw_offscreen_target(core::Entity *entity, bool is_active_target) gl::enable(GL_TEXTURE_2D); } +/* + * This function is called to draw on-screen targets + * if is_active_target is set, the target is the currently selected target + * */ void HUD::draw_target(core::Entity *entity, bool is_active_target) { using math::Vector3f; @@ -133,6 +138,8 @@ void HUD::draw_target(core::Entity *entity, bool is_active_target) return; } + // calculate target screen position + // transform the target into the camera coordinate system target = render::Camera::axis().transpose() * target; @@ -147,57 +154,138 @@ void HUD::draw_target(core::Entity *entity, bool is_active_target) draw_offscreen_target(entity, is_active_target); return; } + + // target bitmap properties + float bitmap_radius = 32.0f; + if (is_active_target) { + bitmap_radius *= 2.0f; + } + math::Vector2f bitmap_location(cx - bitmap_radius, cy - bitmap_radius); + math::Vector2f bitmap_size(2.0f * bitmap_radius, 2.0f * bitmap_radius); + math::Color bitmap_color; + std:: string bitmap_material; + + if (entity->type() == core::Entity::Controlable) { + if (is_active_target) { + bitmap_material.assign("bitmaps/hud/target_controlable"); + } else { + bitmap_material.assign("bitmaps/hud/target_default"); + } + bitmap_color.assign(palette()->fancy()); + + } else if (entity->has_flag(core::Entity::Dockable)) { + bitmap_material.assign("bitmaps/hud/target_dockable"); + bitmap_color.assign(palette()->foreground()); + + } else { + bitmap_material.assign("bitmaps/hud/target_default"); + bitmap_color.assign(palette()->text()); + } + + if (entity == core::localplayer()->mission_target()) { + bitmap_color.assign(palette()->mission()); + } - float r = ui::pointer_size; - if (!is_active_target) - r *= 0.5; - - gl::disable(GL_TEXTURE_2D); - // outer square shadow - gl::color(0, 0, 0, 1); - gl::begin(gl::LineLoop); - gl::vertex(cx + r, cy + 2); - gl::vertex(cx, cy + r + 2); - gl::vertex(cx - r, cy + 2); - gl::vertex(cx, cy - r + 2); - gl::end(); + ui::Paint::draw_bitmap(bitmap_location, bitmap_size, bitmap_color, bitmap_material); + - if (entity->has_flag(core::Entity::Dockable)) { - gl::begin(gl::LineLoop); - gl::vertex(cx + (r*0.25f), cy + 2); - gl::vertex(cx, cy + (r*0.25f) + 2); - gl::vertex(cx - (r*0.25f), cy + 2); - gl::vertex(cx, cy - (r*0.25f) + 2); - gl::end(); + // labels + std::string label_text; + + if (entity->type() == core::Entity::Controlable) { + const core::EntityControlable *ec = static_cast(entity); + if (ec->owner()) { + label_text.append("^B"); + label_text.append(ec->owner()->name()); + } else { + label_text.append("^B"); + label_text.append(entity->name()); + } + } else { + if (entity->has_flag(core::Entity::Dockable)) { + label_text.append("^B"); + } else { + label_text.append("^N"); + } + label_text.append(entity->name()); + } + + const ui::Font *label_font; + if (is_active_target) { + label_font = ui::root()->font_small(); + } else { + label_font = ui::root()->font_tiny(); } + + math::Vector2f label_size(2.0f * bitmap_radius, label_font->height()); + math::Vector2f label_location(cx - bitmap_radius, cy + bitmap_radius); + ui::Paint::draw_label(label_location, label_size,label_font, label_text); - if (entity == core::localplayer()->mission_target()) { - gl::color(palette()->mission()); + if (is_active_target) { - } else if (entity->type() == core::Entity::Controlable) { - gl::color(0, 1, 0, 1); // FIXME faction color + // draw distance + std::ostringstream strdistance; - } else { - gl::color(palette()->foreground()); + if (entity->type() == core::Entity::Controlable) { + strdistance << "^B"; + } else if (entity->has_flag(core::Entity::Dockable)) { + strdistance << "^B"; + } else { + strdistance << "^N"; + } + + float d = math::distance(core::localcontrol()->location(), entity->location()) - entity->radius() - core::localcontrol()->radius(); + if (d > 0) { + if (d > 100.0f) { + strdistance << roundf(d * 0.1f) << "km"; + } else { + strdistance << roundf(d * 100.0f) << "m"; + } + } else { + strdistance << "--"; + } + + label_location[1] += - label_size.height(); + ui::Paint::draw_label(label_location, label_size, label_font, strdistance.str()); } + + if (entity->type() == core::Entity::Controlable) { + const core::EntityControlable *ec = static_cast(entity); + + // health bar size + const float hb_width = bitmap_radius; + float hb_height = ui::root()->font_tiny()->width(); + if (!is_active_target) { + hb_height *= 0.5f; + } + const float hb_f = hb_width * ec->health() / 100.0f; - // outer square0 - gl::begin(gl::LineLoop); - gl::vertex(cx + r, cy); - gl::vertex(cx, cy + r); - gl::vertex(cx - r, cy); - gl::vertex(cx, cy - r); - gl::end(); + math::Vector2f pos; + pos[0] = cx - bitmap_radius; + pos[0] += bitmap_radius - 0.5f * hb_width; + pos[1] = cy - bitmap_radius; + + // health bar + gl::color(0, 1, 0, 1); + gl::begin(gl::Quads); + gl::vertex(pos[0], pos[1]); + gl::vertex(pos[0] + hb_f, pos[1]); + gl::vertex(pos[0] + hb_f, pos[1] + hb_height); + gl::vertex(pos[0], pos[1] + hb_height); + gl::end(); - if (entity->has_flag(core::Entity::Dockable)) { + // health bar frame + gl::color(palette()->foreground()); gl::begin(gl::LineLoop); - gl::vertex(cx + (r*0.25f), cy); - gl::vertex(cx, cy + (r*0.25f)); - gl::vertex(cx - (r*0.25f), cy); - gl::vertex(cx, cy - (r*0.25f)); + gl::vertex(pos[0], pos[1]); + gl::vertex(pos[0] + hb_width, pos[1]); + gl::vertex(pos[0] + hb_width, pos[1] + hb_height); + gl::vertex(pos[0], pos[1] + hb_height); gl::end(); + } + /* if (is_active_target) { gl::color(palette()->foreground()); @@ -270,6 +358,7 @@ void HUD::draw_target(core::Entity *entity, bool is_active_target) cy + r + 4 + render::Text::fontheight(), strdistance.str() ); } + */ } bool HUD::on_keypress(const int key, const unsigned int modifier) @@ -309,13 +398,20 @@ void HUD::draw() core::Entity *entity = (*it); if (entity == targets::current()) { + // draw current HUD target draw_target(entity, true); } else if (entity == core::localplayer()->mission_target()) { + // draw current mission target draw_target(entity, false); } else if ((entity->type() == core::Entity::Controlable) && (targets::is_valid_hud_target(entity))) { - draw_target(entity, false); + const core::EntityControlable *ec = static_cast(entity); + + if (ec->owner()) { + // draw other players + draw_target(entity, false); + } } } -- cgit v1.2.3