New HUD element - waypoint.

This commit is contained in:
RealBadAngel 2014-01-26 21:31:59 +01:00
parent 3f0ee5d680
commit 21f1bec724
8 changed files with 85 additions and 9 deletions

@ -507,6 +507,12 @@ Note: Future revisions to the HUD API may be incompatible; the HUD API is still
- 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
--------------------------------

@ -1941,6 +1941,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
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;
@ -1955,6 +1959,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
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)
@ -1973,6 +1978,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
{
std::string sdata;
v2f v2fdata;
v3f v3fdata;
u32 intdata = 0;
std::string datastring((char *)&data[2], datasize - 2);
@ -1986,6 +1992,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
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);
@ -1994,6 +2002,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
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);

@ -204,6 +204,7 @@ struct ClientEvent
u32 dir;
v2f *align;
v2f *offset;
v3f *world_pos;
} hudadd;
struct{
u32 id;
@ -214,6 +215,7 @@ struct ClientEvent
v2f *v2fdata;
std::string *sdata;
u32 data;
v3f *v3fdata;
} hudchange;
};
};

@ -1486,7 +1486,7 @@ void the_game(
/*
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");
@ -2376,6 +2376,7 @@ void the_game(
delete event.hudadd.text;
delete event.hudadd.align;
delete event.hudadd.offset;
delete event.hudadd.world_pos;
continue;
}
@ -2390,6 +2391,7 @@ void the_game(
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);
@ -2402,6 +2404,7 @@ void the_game(
delete event.hudadd.text;
delete event.hudadd.align;
delete event.hudadd.offset;
delete event.hudadd.world_pos;
}
else if (event.type == CE_HUDRM)
{
@ -2415,6 +2418,7 @@ void the_game(
{
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;
@ -2449,8 +2453,12 @@ void the_game(
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;
}

@ -29,14 +29,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#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;
@ -268,6 +271,33 @@ void Hud::drawLuaElements() {
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;
@ -477,4 +507,3 @@ void drawItemStack(video::IVideoDriver *driver,
font->draw(text.c_str(), rect2, color, false, false, clip);
}
}

@ -49,7 +49,8 @@ enum HudElementType {
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 {
@ -61,7 +62,8 @@ enum HudElementStat {
HUD_STAT_ITEM,
HUD_STAT_DIR,
HUD_STAT_ALIGN,
HUD_STAT_OFFSET
HUD_STAT_OFFSET,
HUD_STAT_WORLD_POS
};
struct HudElement {
@ -75,6 +77,7 @@ struct HudElement {
u32 dir;
v2f align;
v2f offset;
v3f world_pos;
};
#ifndef SERVER
@ -93,6 +96,7 @@ struct ItemStack;
class Hud {
public:
video::IVideoDriver *driver;
scene::ISceneManager* smgr;
gui::IGUIEnvironment *guienv;
gui::IGUIFont *font;
u32 text_height;
@ -113,8 +117,9 @@ public:
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,

@ -38,6 +38,7 @@ struct EnumString es_HudElementType[] =
{HUD_ELEM_TEXT, "text"},
{HUD_ELEM_STATBAR, "statbar"},
{HUD_ELEM_INVENTORY, "inventory"},
{HUD_ELEM_WAYPOINT, "waypoint"},
{0, NULL},
};
@ -53,6 +54,7 @@ struct EnumString es_HudElementStat[] =
{HUD_STAT_DIR, "direction"},
{HUD_STAT_ALIGN, "alignment"},
{HUD_STAT_OFFSET, "offset"},
{HUD_STAT_WORLD_POS, "world_pos"},
{0, NULL},
};
@ -862,6 +864,10 @@ int ObjectRef::l_hud_add(lua_State *L)
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;
@ -953,6 +959,10 @@ int ObjectRef::l_hud_change(lua_State *L)
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);
@ -1003,6 +1013,9 @@ int ObjectRef::l_hud_get(lua_State *L)
lua_pushnumber(L, e->dir);
lua_setfield(L, -2, "dir");
push_v3f(L, e->world_pos);
lua_setfield(L, -2, "world_pos");
return 1;
}

@ -3724,6 +3724,7 @@ void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form)
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();
@ -3767,6 +3768,9 @@ void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value
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: