New HUD element - waypoint.
authorRealBadAngel <maciej.kasatkin@yahoo.com>
Sun, 26 Jan 2014 20:31:59 +0000 (21:31 +0100)
committerRealBadAngel <maciej.kasatkin@yahoo.com>
Sun, 26 Jan 2014 20:31:59 +0000 (21:31 +0100)
doc/lua_api.txt
src/client.cpp
src/client.h
src/game.cpp
src/hud.cpp
src/hud.h
src/script/lua_api/l_object.cpp
src/server.cpp

index 736f6ca4f061a87dd01ed03e379800828d3bc6ed..9d97dd6fadd9dafba897babd57b2fa60c816dbbe 100644 (file)
@@ -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:
index b2709b6f0afae9c3215b728abee72173ec0d3902..6c4d9eea87a831c6493ef2d63254687b405ae89a 100644 (file)
@@ -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);
index 7f13c8149b60d55e6a7e7ef85679c22c50d52c74..9a788dfca5d70fcedec70d535ead46808c413ff5 100644 (file)
@@ -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;
        };
 };
index 16fd42f1607699dfe1a630246743c04f6d7044d7..407672ac29c857b2103dcadaa692f088392b4cbb 100644 (file)
@@ -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;
                                }
index 183f94e4905140d2402c19dbdb04143755bbecd7..80112a6ec63b8bcd7bc0a6f5a2ae39661cb1ba02 100644 (file)
@@ -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);
        }
 }
-
index c69867a23506b7123f8d9dfcc6889666a4ec5cd7..1a24d094572bd0293cfa25cf76f0ec5deaa51543 100644 (file)
--- 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,
index 6d4ce54fc1a3e3bfae2d2c89eb370352be1f5187..6c6415a09800eab0088e25c37e8f71a47e47c628 100644 (file)
@@ -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;
 }
 
index 0ada4d8181b5234e099e866d9036227c370bb9ac..9fb0455ebbde4207ce4bfcf589d95a6ab3a7cc1e 100644 (file)
@@ -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: