Split settings into seperate source and header files
[oweals/minetest.git] / src / hud.cpp
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2010-2013 blue42u, Jonathon Anderson <anderjon@umail.iu.edu>
5 Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include "hud.h"
23 #include "main.h"
24 #include "settings.h"
25 #include "util/numeric.h"
26 #include "log.h"
27 #include "gamedef.h"
28 #include "itemdef.h"
29 #include "inventory.h"
30 #include "tile.h"
31 #include "localplayer.h"
32 #include "camera.h"
33 #include "porting.h"
34 #include <IGUIStaticText.h>
35
36 #ifdef HAVE_TOUCHSCREENGUI
37 #include "touchscreengui.h"
38 #endif
39
40 Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
41                 gui::IGUIEnvironment* guienv, gui::IGUIFont *font,
42                 u32 text_height, IGameDef *gamedef,
43                 LocalPlayer *player, Inventory *inventory) {
44         this->driver      = driver;
45         this->smgr        = smgr;
46         this->guienv      = guienv;
47         this->font        = font;
48         this->text_height = text_height;
49         this->gamedef     = gamedef;
50         this->player      = player;
51         this->inventory   = inventory;
52
53         m_screensize       = v2u32(0, 0);
54         m_displaycenter    = v2s32(0, 0);
55         m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
56         m_hotbar_imagesize *= g_settings->getFloat("gui_scaling");
57         m_padding = m_hotbar_imagesize / 12;
58
59         const video::SColor hbar_color(255, 255, 255, 255);
60         for (unsigned int i=0; i < 4; i++ ){
61                 hbar_colors[i] = hbar_color;
62         }
63         
64         tsrc = gamedef->getTextureSource();
65         
66         v3f crosshair_color = g_settings->getV3F("crosshair_color");
67         u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255);
68         u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255);
69         u32 cross_b = rangelim(myround(crosshair_color.Z), 0, 255);
70         u32 cross_a = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
71         crosshair_argb = video::SColor(cross_a, cross_r, cross_g, cross_b);
72         
73         v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
74         u32 sbox_r = rangelim(myround(selectionbox_color.X), 0, 255);
75         u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255);
76         u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255);
77         selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b);
78         
79         use_crosshair_image = tsrc->isKnownSourceImage("crosshair.png");
80
81         hotbar_image = "";
82         use_hotbar_image = false;
83         hotbar_selected_image = "";
84         use_hotbar_selected_image = false;
85 }
86
87 void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, bool selected) {
88
89         if (selected) {
90                         /* draw hihlighting around selected item */
91                         if (use_hotbar_selected_image) {
92                                 core::rect<s32> imgrect2 = rect;
93                                 imgrect2.UpperLeftCorner.X  -= (m_padding*2);
94                                 imgrect2.UpperLeftCorner.Y  -= (m_padding*2);
95                                 imgrect2.LowerRightCorner.X += (m_padding*2);
96                                 imgrect2.LowerRightCorner.Y += (m_padding*2);
97                                         video::ITexture *texture = tsrc->getTexture(hotbar_selected_image);
98                                         core::dimension2di imgsize(texture->getOriginalSize());
99                                 driver->draw2DImage(texture, imgrect2,
100                                                 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
101                                                 NULL, hbar_colors, true);
102                         } else {
103                                 video::SColor c_outside(255,255,0,0);
104                                 //video::SColor c_outside(255,0,0,0);
105                                 //video::SColor c_inside(255,192,192,192);
106                                 s32 x1 = rect.UpperLeftCorner.X;
107                                 s32 y1 = rect.UpperLeftCorner.Y;
108                                 s32 x2 = rect.LowerRightCorner.X;
109                                 s32 y2 = rect.LowerRightCorner.Y;
110                                 // Black base borders
111                                 driver->draw2DRectangle(c_outside,
112                                         core::rect<s32>(
113                                         v2s32(x1 - m_padding, y1 - m_padding),
114                                         v2s32(x2 + m_padding, y1)
115                                         ), NULL);
116                                 driver->draw2DRectangle(c_outside,
117                                         core::rect<s32>(
118                                         v2s32(x1 - m_padding, y2),
119                                         v2s32(x2 + m_padding, y2 + m_padding)
120                                         ), NULL);
121                                 driver->draw2DRectangle(c_outside,
122                                         core::rect<s32>(
123                                         v2s32(x1 - m_padding, y1),
124                                                 v2s32(x1, y2)
125                                         ), NULL);
126                                 driver->draw2DRectangle(c_outside,
127                                         core::rect<s32>(
128                                                 v2s32(x2, y1),
129                                         v2s32(x2 + m_padding, y2)
130                                         ), NULL);
131                                 /*// Light inside borders
132                                 driver->draw2DRectangle(c_inside,
133                                         core::rect<s32>(
134                                                 v2s32(x1 - padding/2, y1 - padding/2),
135                                                 v2s32(x2 + padding/2, y1)
136                                         ), NULL);
137                                 driver->draw2DRectangle(c_inside,
138                                         core::rect<s32>(
139                                                 v2s32(x1 - padding/2, y2),
140                                                 v2s32(x2 + padding/2, y2 + padding/2)
141                                         ), NULL);
142                                 driver->draw2DRectangle(c_inside,
143                                         core::rect<s32>(
144                                                 v2s32(x1 - padding/2, y1),
145                                                 v2s32(x1, y2)
146                                         ), NULL);
147                                 driver->draw2DRectangle(c_inside,
148                                         core::rect<s32>(
149                                                 v2s32(x2, y1),
150                                                 v2s32(x2 + padding/2, y2)
151                                         ), NULL);
152                                 */
153                         }
154                 }
155
156                 video::SColor bgcolor2(128, 0, 0, 0);
157                 if (!use_hotbar_image)
158                         driver->draw2DRectangle(bgcolor2, rect, NULL);
159                 drawItemStack(driver, font, item, rect, NULL, gamedef);
160         }
161
162 //NOTE: selectitem = 0 -> no selected; selectitem 1-based
163 void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
164                 InventoryList *mainlist, u16 selectitem, u16 direction)
165 {
166 #ifdef HAVE_TOUCHSCREENGUI
167         if ( (g_touchscreengui) && (offset == 0))
168                 g_touchscreengui->resetHud();
169 #endif
170
171         s32 height  = m_hotbar_imagesize + m_padding * 2;
172         s32 width   = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
173
174         if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
175                 width  = m_hotbar_imagesize + m_padding * 2;
176                 height = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
177         }
178
179         // Position of upper left corner of bar
180         v2s32 pos = upperleftpos;
181
182         if (hotbar_image != player->hotbar_image) {
183                 hotbar_image = player->hotbar_image;
184                 if (hotbar_image != "")
185                         use_hotbar_image = tsrc->isKnownSourceImage(hotbar_image);
186                 else
187                         use_hotbar_image = false;
188         }
189
190         if (hotbar_selected_image != player->hotbar_selected_image) {
191                 hotbar_selected_image = player->hotbar_selected_image;
192                 if (hotbar_selected_image != "")
193                         use_hotbar_selected_image = tsrc->isKnownSourceImage(hotbar_selected_image);
194                 else
195                         use_hotbar_selected_image = false;
196         }
197
198         /* draw customized item background */
199         if (use_hotbar_image) {
200                 core::rect<s32> imgrect2(-m_padding/2, -m_padding/2,
201                                 width+m_padding/2, height+m_padding/2);
202                 core::rect<s32> rect2 = imgrect2 + pos;
203                 video::ITexture *texture = tsrc->getTexture(hotbar_image);
204                 core::dimension2di imgsize(texture->getOriginalSize());
205                 driver->draw2DImage(texture, rect2,
206                         core::rect<s32>(core::position2d<s32>(0,0), imgsize),
207                         NULL, hbar_colors, true);
208         }
209
210         for (s32 i = offset; i < itemcount && (size_t)i < mainlist->getSize(); i++)
211         {
212                 v2s32 steppos;
213                 s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
214
215                 core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
216
217                 switch (direction) {
218                         case HUD_DIR_RIGHT_LEFT:
219                                 steppos = v2s32(-(m_padding + (i - offset) * fullimglen), m_padding);
220                                 break;
221                         case HUD_DIR_TOP_BOTTOM:
222                                 steppos = v2s32(m_padding, m_padding + (i - offset) * fullimglen);
223                                 break;
224                         case HUD_DIR_BOTTOM_TOP:
225                                 steppos = v2s32(m_padding, -(m_padding + (i - offset) * fullimglen));
226                                 break;
227                         default:
228                                 steppos = v2s32(m_padding + (i - offset) * fullimglen, m_padding);
229                                 break;
230                 }
231
232                 drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i +1) == selectitem );
233
234 #ifdef HAVE_TOUCHSCREENGUI
235                 if (g_touchscreengui)
236                         g_touchscreengui->registerHudItem(i, (imgrect + pos + steppos));
237 #endif
238         }
239 }
240
241
242 void Hud::drawLuaElements(v3s16 camera_offset) {
243         for (size_t i = 0; i != player->maxHudId(); i++) {
244                 HudElement *e = player->getHud(i);
245                 if (!e)
246                         continue;
247                 
248                 v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5),
249                                 floor(e->pos.Y * (float) m_screensize.Y + 0.5));
250                 switch (e->type) {
251                         case HUD_ELEM_IMAGE: {
252                                 video::ITexture *texture = tsrc->getTexture(e->text);
253                                 if (!texture)
254                                         continue;
255
256                                 const video::SColor color(255, 255, 255, 255);
257                                 const video::SColor colors[] = {color, color, color, color};
258                                 core::dimension2di imgsize(texture->getOriginalSize());
259                                 v2s32 dstsize(imgsize.Width * e->scale.X,
260                                               imgsize.Height * e->scale.Y);
261                                 if (e->scale.X < 0)
262                                         dstsize.X = m_screensize.X * (e->scale.X * -0.01);
263                                 if (e->scale.Y < 0)
264                                         dstsize.Y = m_screensize.Y * (e->scale.Y * -0.01);
265                                 v2s32 offset((e->align.X - 1.0) * dstsize.X / 2,
266                                              (e->align.Y - 1.0) * dstsize.Y / 2);
267                                 core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y);
268                                 rect += pos + offset + v2s32(e->offset.X, e->offset.Y);
269                                 driver->draw2DImage(texture, rect,
270                                         core::rect<s32>(core::position2d<s32>(0,0), imgsize),
271                                         NULL, colors, true);
272                                 break; }
273                         case HUD_ELEM_TEXT: {
274                                 video::SColor color(255, (e->number >> 16) & 0xFF,
275                                                                                  (e->number >> 8)  & 0xFF,
276                                                                                  (e->number >> 0)  & 0xFF);
277                                 core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
278                                 std::wstring text = narrow_to_wide(e->text);
279                                 core::dimension2d<u32> textsize = font->getDimension(text.c_str());
280                                 v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
281                                              (e->align.Y - 1.0) * (textsize.Height / 2));
282                                 v2s32 offs(e->offset.X, e->offset.Y);
283                                 font->draw(text.c_str(), size + pos + offset + offs, color);
284                                 break; }
285                         case HUD_ELEM_STATBAR: {
286                                 v2s32 offs(e->offset.X, e->offset.Y);
287                                 drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs, e->size);
288                                 break; }
289                         case HUD_ELEM_INVENTORY: {
290                                 InventoryList *inv = inventory->getList(e->text);
291                                 drawItems(pos, e->number, 0, inv, e->item, e->dir);
292                                 break; }
293                         case HUD_ELEM_WAYPOINT: {
294                                 v3f p_pos = player->getPosition() / BS;
295                                 v3f w_pos = e->world_pos * BS;
296                                 float distance = floor(10 * p_pos.getDistanceFrom(e->world_pos)) / 10;
297                                 scene::ICameraSceneNode* camera = smgr->getActiveCamera();
298                                 w_pos -= intToFloat(camera_offset, BS);
299                                 core::matrix4 trans = camera->getProjectionMatrix();
300                                 trans *= camera->getViewMatrix();
301                                 f32 transformed_pos[4] = { w_pos.X, w_pos.Y, w_pos.Z, 1.0f };
302                                 trans.multiplyWith1x4Matrix(transformed_pos);
303                                 if (transformed_pos[3] < 0)
304                                         break;
305                                 f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
306                                         core::reciprocal(transformed_pos[3]);
307                                 pos.X = m_screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5);
308                                 pos.Y = m_screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5);
309                                 video::SColor color(255, (e->number >> 16) & 0xFF,
310                                                                                  (e->number >> 8)  & 0xFF,
311                                                                                  (e->number >> 0)  & 0xFF);
312                                 core::rect<s32> size(0, 0, 200, 2 * text_height);
313                                 std::wstring text = narrow_to_wide(e->name);
314                                 font->draw(text.c_str(), size + pos, color);
315                                 std::ostringstream os;
316                                 os<<distance<<e->text;
317                                 text = narrow_to_wide(os.str());
318                                 pos.Y += text_height;
319                                 font->draw(text.c_str(), size + pos, color);
320                                 break; }
321                         default:
322                                 infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
323                                         " of hud element ID " << i << " due to unrecognized type" << std::endl;
324                 }
325         }
326 }
327
328
329 void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
330                 s32 count, v2s32 offset, v2s32 size)
331 {
332         const video::SColor color(255, 255, 255, 255);
333         const video::SColor colors[] = {color, color, color, color};
334         
335         video::ITexture *stat_texture = tsrc->getTexture(texture);
336         if (!stat_texture)
337                 return;
338                 
339         core::dimension2di srcd(stat_texture->getOriginalSize());
340         core::dimension2di dstd;
341         if (size == v2s32()) {
342                 dstd = srcd;
343         } else {
344                 dstd.Height = size.Y * g_settings->getFloat("gui_scaling") *
345                                 porting::getDisplayDensity();
346                 dstd.Width  = size.X * g_settings->getFloat("gui_scaling") *
347                                 porting::getDisplayDensity();
348
349                 offset.X *= g_settings->getFloat("gui_scaling") *
350                                 porting::getDisplayDensity();
351
352                 offset.Y *= g_settings->getFloat("gui_scaling") *
353                                 porting::getDisplayDensity();
354         }
355
356         v2s32 p = pos;
357         if (corner & HUD_CORNER_LOWER)
358                 p -= dstd.Height;
359
360         p += offset;
361
362         v2s32 steppos;
363         switch (drawdir) {
364                 case HUD_DIR_RIGHT_LEFT:
365                         steppos = v2s32(-1, 0);
366                         break;
367                 case HUD_DIR_TOP_BOTTOM:
368                         steppos = v2s32(0, 1);
369                         break;
370                 case HUD_DIR_BOTTOM_TOP:
371                         steppos = v2s32(0, -1);
372                         break;
373                 default:
374                         steppos = v2s32(1, 0);
375         }
376         steppos.X *= dstd.Width;
377         steppos.Y *= dstd.Height;
378         
379         for (s32 i = 0; i < count / 2; i++)
380         {
381                 core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height);
382                 core::rect<s32> dstrect(0,0, dstd.Width, dstd.Height);
383
384                 dstrect += p;
385                 driver->draw2DImage(stat_texture, dstrect, srcrect, NULL, colors, true);
386                 p += steppos;
387         }
388         
389         if (count % 2 == 1)
390         {
391                 core::rect<s32> srcrect(0, 0, srcd.Width / 2, srcd.Height);
392                 core::rect<s32> dstrect(0,0, dstd.Width / 2, dstd.Height);
393
394                 dstrect += p;
395                 driver->draw2DImage(stat_texture, dstrect, srcrect, NULL, colors, true);
396         }
397 }
398
399
400 void Hud::drawHotbar(u16 playeritem) {
401
402         v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y);
403
404         InventoryList *mainlist = inventory->getList("main");
405         if (mainlist == NULL) {
406                 //silently ignore this we may not be initialized completely
407                 return;
408         }
409         
410         s32 hotbar_itemcount = player->hud_hotbar_itemcount;
411         s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2);
412         v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3);
413
414         if ( (float) width / (float) porting::getWindowSize().X <=
415                         g_settings->getFloat("hud_hotbar_max_width")) {
416                 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
417                         drawItems(pos, hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
418                 }
419         }
420         else {
421                 pos.X += width/4;
422
423                 v2s32 secondpos = pos;
424                 pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
425
426                 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
427                         drawItems(pos, hotbar_itemcount/2, 0, mainlist, playeritem + 1, 0);
428                         drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 0);
429                 }
430         }
431
432         //////////////////////////// compatibility code to be removed //////////////
433         // this is ugly as hell but there's no other way to keep compatibility to
434         // old servers
435         if ( player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE)
436                 drawStatbar(v2s32(floor(0.5 * (float) m_screensize.X + 0.5),
437                                 floor(1 * (float) m_screensize.Y + 0.5)),
438                                 HUD_CORNER_UPPER, 0, "heart.png",
439                                 player->hp, v2s32((-10*24)-25,-(48+24+10)), v2s32(24,24));
440
441         if ((player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE) &&
442                         (player->getBreath() < 11))
443                 drawStatbar(v2s32(floor(0.5 * (float) m_screensize.X + 0.5),
444                                 floor(1 * (float) m_screensize.Y + 0.5)),
445                                 HUD_CORNER_UPPER, 0, "heart.png",
446                                 player->getBreath(), v2s32(25,-(48+24+10)), v2s32(24,24));
447         ////////////////////////////////////////////////////////////////////////////
448 }
449
450
451 void Hud::drawCrosshair() {
452                 
453         if (use_crosshair_image) {
454                 video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
455                 v2u32 size  = crosshair->getOriginalSize();
456                 v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2),
457                                 m_displaycenter.Y - (size.Y / 2));
458                 driver->draw2DImage(crosshair, lsize,
459                                 core::rect<s32>(0, 0, size.X, size.Y),
460                                 0, crosshair_argb, true);
461         } else {
462                 driver->draw2DLine(m_displaycenter - v2s32(10, 0),
463                                 m_displaycenter + v2s32(10, 0), crosshair_argb);
464                 driver->draw2DLine(m_displaycenter - v2s32(0, 10),
465                                 m_displaycenter + v2s32(0, 10), crosshair_argb);
466         }
467 }
468
469
470 void Hud::drawSelectionBoxes(std::vector<aabb3f> &hilightboxes) {
471         for (std::vector<aabb3f>::const_iterator
472                         i = hilightboxes.begin();
473                         i != hilightboxes.end(); i++) {
474                 driver->draw3DBox(*i, selectionbox_argb);
475         }
476 }
477
478
479 void Hud::resizeHotbar() {
480         if (m_screensize != porting::getWindowSize()) {
481                 m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
482                 m_hotbar_imagesize *= g_settings->getFloat("gui_scaling");
483                 m_padding = m_hotbar_imagesize / 12;
484                 m_screensize = porting::getWindowSize();
485                 m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);
486         }
487 }
488
489 void drawItemStack(video::IVideoDriver *driver,
490                 gui::IGUIFont *font,
491                 const ItemStack &item,
492                 const core::rect<s32> &rect,
493                 const core::rect<s32> *clip,
494                 IGameDef *gamedef)
495 {
496         if(item.empty())
497                 return;
498         
499         const ItemDefinition &def = item.getDefinition(gamedef->idef());
500         video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
501
502         // Draw the inventory texture
503         if(texture != NULL)
504         {
505                 const video::SColor color(255,255,255,255);
506                 const video::SColor colors[] = {color,color,color,color};
507                 driver->draw2DImage(texture, rect,
508                         core::rect<s32>(core::position2d<s32>(0,0),
509                         core::dimension2di(texture->getOriginalSize())),
510                         clip, colors, true);
511         }
512
513         if(def.type == ITEM_TOOL && item.wear != 0)
514         {
515                 // Draw a progressbar
516                 float barheight = rect.getHeight()/16;
517                 float barpad_x = rect.getWidth()/16;
518                 float barpad_y = rect.getHeight()/16;
519                 core::rect<s32> progressrect(
520                         rect.UpperLeftCorner.X + barpad_x,
521                         rect.LowerRightCorner.Y - barpad_y - barheight,
522                         rect.LowerRightCorner.X - barpad_x,
523                         rect.LowerRightCorner.Y - barpad_y);
524
525                 // Shrink progressrect by amount of tool damage
526                 float wear = item.wear / 65535.0;
527                 int progressmid =
528                         wear * progressrect.UpperLeftCorner.X +
529                         (1-wear) * progressrect.LowerRightCorner.X;
530
531                 // Compute progressbar color
532                 //   wear = 0.0: green
533                 //   wear = 0.5: yellow
534                 //   wear = 1.0: red
535                 video::SColor color(255,255,255,255);
536                 int wear_i = MYMIN(floor(wear * 600), 511);
537                 wear_i = MYMIN(wear_i + 10, 511);
538                 if(wear_i <= 255)
539                         color.set(255, wear_i, 255, 0);
540                 else
541                         color.set(255, 255, 511-wear_i, 0);
542
543                 core::rect<s32> progressrect2 = progressrect;
544                 progressrect2.LowerRightCorner.X = progressmid;
545                 driver->draw2DRectangle(color, progressrect2, clip);
546
547                 color = video::SColor(255,0,0,0);
548                 progressrect2 = progressrect;
549                 progressrect2.UpperLeftCorner.X = progressmid;
550                 driver->draw2DRectangle(color, progressrect2, clip);
551         }
552
553         if(font != NULL && item.count >= 2)
554         {
555                 // Get the item count as a string
556                 std::string text = itos(item.count);
557                 v2u32 dim = font->getDimension(narrow_to_wide(text).c_str());
558                 v2s32 sdim(dim.X,dim.Y);
559
560                 core::rect<s32> rect2(
561                         /*rect.UpperLeftCorner,
562                         core::dimension2d<u32>(rect.getWidth(), 15)*/
563                         rect.LowerRightCorner - sdim,
564                         sdim
565                 );
566
567                 video::SColor bgcolor(128,0,0,0);
568                 driver->draw2DRectangle(bgcolor, rect2, clip);
569
570                 video::SColor color(255,255,255,255);
571                 font->draw(text.c_str(), rect2, color, false, false, clip);
572         }
573 }