+ const std::string &unit = e->text;
+ // waypoints reuse the item field to store precision, item = precision + 1
+ u32 item = e->item;
+ float precision = (item == 0) ? 10.0f : (item - 1.f);
+ bool draw_precision = precision > 0;
+
+ core::rect<s32> bounds(0, 0, font->getDimension(text.c_str()).Width, (draw_precision ? 2:1) * text_height);
+ pos.Y += (e->align.Y - 1.0) * bounds.getHeight() / 2;
+ bounds += pos;
+ font->draw(text.c_str(), bounds + v2s32((e->align.X - 1.0) * bounds.getWidth() / 2, 0), color);
+ if (draw_precision) {
+ std::ostringstream os;
+ float distance = std::floor(precision * p_pos.getDistanceFrom(e->world_pos)) / precision;
+ os << distance << unit;
+ text = unescape_translate(utf8_to_wide(os.str()));
+ bounds.LowerRightCorner.X = bounds.UpperLeftCorner.X + font->getDimension(text.c_str()).Width;
+ font->draw(text.c_str(), bounds + v2s32((e->align.X - 1.0f) * bounds.getWidth() / 2, text_height), color);
+ }
+ break; }
+ case HUD_ELEM_IMAGE_WAYPOINT: {
+ if (!calculateScreenPos(camera_offset, e, &pos))
+ break;
+ }
+ case HUD_ELEM_IMAGE: {
+ video::ITexture *texture = tsrc->getTexture(e->text);
+ if (!texture)
+ continue;
+
+ const video::SColor color(255, 255, 255, 255);
+ const video::SColor colors[] = {color, color, color, color};
+ core::dimension2di imgsize(texture->getOriginalSize());
+ v2s32 dstsize(imgsize.Width * e->scale.X * m_scale_factor,
+ imgsize.Height * e->scale.Y * m_scale_factor);
+ if (e->scale.X < 0)
+ dstsize.X = m_screensize.X * (e->scale.X * -0.01);
+ if (e->scale.Y < 0)
+ dstsize.Y = m_screensize.Y * (e->scale.Y * -0.01);
+ v2s32 offset((e->align.X - 1.0) * dstsize.X / 2,
+ (e->align.Y - 1.0) * dstsize.Y / 2);
+ core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y);
+ rect += pos + offset + v2s32(e->offset.X * m_scale_factor,
+ e->offset.Y * m_scale_factor);
+ draw2DImageFilterScaled(driver, texture, rect,
+ core::rect<s32>(core::position2d<s32>(0,0), imgsize),
+ NULL, colors, true);
+ break; }
+ case HUD_ELEM_COMPASS: {
+ video::ITexture *texture = tsrc->getTexture(e->text);
+ if (!texture)
+ continue;
+
+ // Positionning :
+ v2s32 dstsize(e->size.X, e->size.Y);
+ if (e->size.X < 0)
+ dstsize.X = m_screensize.X * (e->size.X * -0.01);
+ if (e->size.Y < 0)
+ dstsize.Y = m_screensize.Y * (e->size.Y * -0.01);
+
+ if (dstsize.X <= 0 || dstsize.Y <= 0)
+ return; // Avoid zero divides
+
+ // Angle according to camera view
+ v3f fore(0.f, 0.f, 1.f);
+ scene::ICameraSceneNode *cam = client->getSceneManager()->getActiveCamera();
+ cam->getAbsoluteTransformation().rotateVect(fore);
+ int angle = - fore.getHorizontalAngle().Y;
+
+ // Limit angle and ajust with given offset
+ angle = (angle + (int)e->number) % 360;
+
+ core::rect<s32> dstrect(0, 0, dstsize.X, dstsize.Y);
+ dstrect += pos + v2s32(
+ (e->align.X - 1.0) * dstsize.X / 2,
+ (e->align.Y - 1.0) * dstsize.Y / 2) +
+ v2s32(e->offset.X * m_hud_scaling, e->offset.Y * m_hud_scaling);
+
+ switch (e->dir) {
+ case HUD_COMPASS_ROTATE:
+ drawCompassRotate(e, texture, dstrect, angle);
+ break;
+ case HUD_COMPASS_ROTATE_REVERSE:
+ drawCompassRotate(e, texture, dstrect, -angle);
+ break;
+ case HUD_COMPASS_TRANSLATE:
+ drawCompassTranslate(e, texture, dstrect, angle);
+ break;
+ case HUD_COMPASS_TRANSLATE_REVERSE:
+ drawCompassTranslate(e, texture, dstrect, -angle);
+ break;
+ default:
+ break;
+ }
+ break; }
+ case HUD_ELEM_MINIMAP: {
+ if (e->size.X <= 0 || e->size.Y <= 0)
+ break;
+ if (!client->getMinimap())
+ break;
+ // Draw a minimap of size "size"
+ v2s32 dstsize(e->size.X * m_scale_factor,
+ e->size.Y * m_scale_factor);
+ // (no percent size as minimap would likely be anamorphosed)
+ v2s32 offset((e->align.X - 1.0) * dstsize.X / 2,
+ (e->align.Y - 1.0) * dstsize.Y / 2);
+ core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y);
+ rect += pos + offset + v2s32(e->offset.X * m_scale_factor,
+ e->offset.Y * m_scale_factor);
+ client->getMinimap()->drawMinimap(rect);