- number: Number of items in the inventory to be displayed.
- item: Position of item that is selected.
- direction
-
+- waypoint
+ Displays distance to selected world position.
+ - name: The name of the waypoint.
+ - text: Distance suffix. Can be blank.
+ - number: An integer containing the RGB value of the color used to draw the text.
+ - world_pos: World position of the waypoint.
+
Representations of simple things
--------------------------------
Position/vector:
u32 dir = readU32(is);
v2f align = readV2F1000(is);
v2f offset = readV2F1000(is);
+ v3f world_pos;
+ try{
+ world_pos = readV3F1000(is);
+ }catch(SerializationError &e) {};
ClientEvent event;
event.type = CE_HUDADD;
event.hudadd.dir = dir;
event.hudadd.align = new v2f(align);
event.hudadd.offset = new v2f(offset);
+ event.hudadd.world_pos = new v3f(world_pos);
m_client_event_queue.push_back(event);
}
else if(command == TOCLIENT_HUDRM)
{
std::string sdata;
v2f v2fdata;
+ v3f v3fdata;
u32 intdata = 0;
std::string datastring((char *)&data[2], datasize - 2);
v2fdata = readV2F1000(is);
else if (stat == HUD_STAT_NAME || stat == HUD_STAT_TEXT)
sdata = deSerializeString(is);
+ else if (stat == HUD_STAT_WORLD_POS)
+ v3fdata = readV3F1000(is);
else
intdata = readU32(is);
event.hudchange.id = id;
event.hudchange.stat = (HudElementStat)stat;
event.hudchange.v2fdata = new v2f(v2fdata);
+ event.hudchange.v3fdata = new v3f(v3fdata);
event.hudchange.sdata = new std::string(sdata);
event.hudchange.data = intdata;
m_client_event_queue.push_back(event);
u32 dir;
v2f *align;
v2f *offset;
+ v3f *world_pos;
} hudadd;
struct{
u32 id;
v2f *v2fdata;
std::string *sdata;
u32 data;
+ v3f *v3fdata;
} hudchange;
};
};
/*
HUD object
*/
- Hud hud(driver, guienv, font, text_height,
+ Hud hud(driver, smgr, guienv, font, text_height,
gamedef, player, &local_inventory);
bool use_weather = g_settings->getBool("weather");
delete event.hudadd.text;
delete event.hudadd.align;
delete event.hudadd.offset;
+ delete event.hudadd.world_pos;
continue;
}
e->dir = event.hudadd.dir;
e->align = *event.hudadd.align;
e->offset = *event.hudadd.offset;
+ e->world_pos = *event.hudadd.world_pos;
if (id == nhudelem)
player->hud.push_back(e);
delete event.hudadd.text;
delete event.hudadd.align;
delete event.hudadd.offset;
+ delete event.hudadd.world_pos;
}
else if (event.type == CE_HUDRM)
{
{
u32 id = event.hudchange.id;
if (id >= player->hud.size() || !player->hud[id]) {
+ delete event.hudchange.v3fdata;
delete event.hudchange.v2fdata;
delete event.hudchange.sdata;
continue;
case HUD_STAT_OFFSET:
e->offset = *event.hudchange.v2fdata;
break;
+ case HUD_STAT_WORLD_POS:
+ e->world_pos = *event.hudchange.v3fdata;
+ break;
}
+ delete event.hudchange.v3fdata;
delete event.hudchange.v2fdata;
delete event.hudchange.sdata;
}
#include "inventory.h"
#include "tile.h"
#include "localplayer.h"
+#include "camera.h"
#include <IGUIStaticText.h>
-Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
- gui::IGUIFont *font, u32 text_height, IGameDef *gamedef,
+Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
+ gui::IGUIEnvironment* guienv, gui::IGUIFont *font,
+ u32 text_height, IGameDef *gamedef,
LocalPlayer *player, Inventory *inventory) {
this->driver = driver;
+ this->smgr = smgr;
this->guienv = guienv;
this->font = font;
this->text_height = text_height;
InventoryList *inv = inventory->getList(e->text);
drawItem(pos, hotbar_imagesize, e->number, inv, e->item, e->dir);
break; }
+ case HUD_ELEM_WAYPOINT: {
+ v3f p_pos = player->getPosition() / BS;
+ v3f w_pos = e->world_pos * BS;
+ float distance = floor(10 * p_pos.getDistanceFrom(e->world_pos)) / 10;
+ scene::ICameraSceneNode* camera = smgr->getActiveCamera();
+ core::matrix4 trans = camera->getProjectionMatrix();
+ trans *= camera->getViewMatrix();
+ f32 transformed_pos[4] = { w_pos.X, w_pos.Y, w_pos.Z, 1.0f };
+ trans.multiplyWith1x4Matrix(transformed_pos);
+ if (transformed_pos[3] < 0)
+ break;
+ f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
+ core::reciprocal(transformed_pos[3]);
+ pos.X = screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5);
+ pos.Y = screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5);
+ video::SColor color(255, (e->number >> 16) & 0xFF,
+ (e->number >> 8) & 0xFF,
+ (e->number >> 0) & 0xFF);
+ core::rect<s32> size(0, 0, 200, 2 * text_height);
+ std::wstring text = narrow_to_wide(e->name);
+ font->draw(text.c_str(), size + pos, color);
+ std::ostringstream os;
+ os<<distance<<e->text;
+ text = narrow_to_wide(os.str());
+ pos.Y += text_height;
+ font->draw(text.c_str(), size + pos, color);
+ break; }
default:
infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
" of hud element ID " << i << " due to unrecognized type" << std::endl;
font->draw(text.c_str(), rect2, color, false, false, clip);
}
}
-
HUD_ELEM_IMAGE = 0,
HUD_ELEM_TEXT = 1,
HUD_ELEM_STATBAR = 2,
- HUD_ELEM_INVENTORY = 3
+ HUD_ELEM_INVENTORY = 3,
+ HUD_ELEM_WAYPOINT = 4,
};
enum HudElementStat {
HUD_STAT_ITEM,
HUD_STAT_DIR,
HUD_STAT_ALIGN,
- HUD_STAT_OFFSET
+ HUD_STAT_OFFSET,
+ HUD_STAT_WORLD_POS
};
struct HudElement {
u32 dir;
v2f align;
v2f offset;
+ v3f world_pos;
};
#ifndef SERVER
class Hud {
public:
video::IVideoDriver *driver;
+ scene::ISceneManager* smgr;
gui::IGUIEnvironment *guienv;
gui::IGUIFont *font;
u32 text_height;
std::string hotbar_selected_image;
bool use_hotbar_selected_image;
- Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
- gui::IGUIFont *font, u32 text_height, IGameDef *gamedef,
+ Hud(video::IVideoDriver *driver,scene::ISceneManager* smgr,
+ gui::IGUIEnvironment* guienv, gui::IGUIFont *font,
+ u32 text_height, IGameDef *gamedef,
LocalPlayer *player, Inventory *inventory);
void drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount,
{HUD_ELEM_TEXT, "text"},
{HUD_ELEM_STATBAR, "statbar"},
{HUD_ELEM_INVENTORY, "inventory"},
+ {HUD_ELEM_WAYPOINT, "waypoint"},
{0, NULL},
};
{HUD_STAT_DIR, "direction"},
{HUD_STAT_ALIGN, "alignment"},
{HUD_STAT_OFFSET, "offset"},
+ {HUD_STAT_WORLD_POS, "world_pos"},
{0, NULL},
};
elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
lua_pop(L, 1);
+ lua_getfield(L, 2, "world_pos");
+ elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
+ lua_pop(L, 1);
+
u32 id = getServer(L)->hudAdd(player, elem);
if (id == (u32)-1) {
delete elem;
e->offset = read_v2f(L, 4);
value = &e->offset;
break;
+ case HUD_STAT_WORLD_POS:
+ e->world_pos = read_v3f(L, 4);
+ value = &e->world_pos;
+ break;
}
getServer(L)->hudChange(player, id, stat, value);
lua_pushnumber(L, e->dir);
lua_setfield(L, -2, "dir");
+ push_v3f(L, e->world_pos);
+ lua_setfield(L, -2, "world_pos");
+
return 1;
}
writeU32(os, form->dir);
writeV2F1000(os, form->align);
writeV2F1000(os, form->offset);
+ writeV3F1000(os, form->world_pos);
// Make data buffer
std::string s = os.str();
case HUD_STAT_TEXT:
os << serializeString(*(std::string *)value);
break;
+ case HUD_STAT_WORLD_POS:
+ writeV3F1000(os, *(v3f *)value);
+ break;
case HUD_STAT_NUMBER:
case HUD_STAT_ITEM:
case HUD_STAT_DIR: