aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt8
-rw-r--r--src/client.cpp9
-rw-r--r--src/client.h2
-rw-r--r--src/game.cpp10
-rw-r--r--src/hud.cpp35
-rw-r--r--src/hud.h13
-rw-r--r--src/script/lua_api/l_object.cpp13
-rw-r--r--src/server.cpp4
8 files changed, 85 insertions, 9 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 736f6ca4f..9d97dd6fa 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -507,7 +507,13 @@ 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
--------------------------------
Position/vector:
diff --git a/src/client.cpp b/src/client.cpp
index b2709b6f0..6c4d9eea8 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -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);
diff --git a/src/client.h b/src/client.h
index 7f13c8149..9a788dfca 100644
--- a/src/client.h
+++ b/src/client.h
@@ -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;
};
};
diff --git a/src/game.cpp b/src/game.cpp
index 16fd42f16..407672ac2 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -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;
}
diff --git a/src/hud.cpp b/src/hud.cpp
index 183f94e49..80112a6ec 100644
--- a/src/hud.cpp
+++ b/src/hud.cpp
@@ -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);
}
}
-
diff --git a/src/hud.h b/src/hud.h
index c69867a23..1a24d0945 100644
--- a/src/hud.h
+++ b/src/hud.h
@@ -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,
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 6d4ce54fc..6c6415a09 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -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;
}
diff --git a/src/server.cpp b/src/server.cpp
index 0ada4d818..9fb0455eb 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -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: