diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 260a62763..5143c2ef3 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1399,6 +1399,8 @@ Player-only: (no-op for other objects) ^ flags: (is visible) hotbar, healthbar, crosshair, wielditem ^ pass a table containing a true/false value of each flag to be set or unset ^ if a flag is nil, the flag is not modified +- hud_set_hotbar_itemcount(count): sets number of items in builtin hotbar + ^ count: number of items, must be between 1 and 23 InvRef: Reference to an inventory methods: diff --git a/src/client.cpp b/src/client.cpp index e4ca52dd5..6b1789fe0 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -2136,6 +2136,23 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) player->hud_flags &= ~mask; player->hud_flags |= flags; } + else if(command == TOCLIENT_HUD_SET_PARAM) + { + std::string datastring((char *)&data[2], datasize - 2); + std::istringstream is(datastring, std::ios_base::binary); + + Player *player = m_env.getLocalPlayer(); + assert(player != NULL); + + u16 param = readU16(is); + std::string value = deSerializeString(is); + + if(param == HUD_PARAM_HOTBAR_ITEMCOUNT && value.size() == 4){ + s32 hotbar_itemcount = readS32((u8*) value.c_str()); + if(hotbar_itemcount > 0 && hotbar_itemcount <= HUD_HOTBAR_ITEMCOUNT_MAX) + player->hud_hotbar_itemcount = hotbar_itemcount; + } + } else { infostream<<"Client: Ignoring unknown command " diff --git a/src/clientserver.h b/src/clientserver.h index ee9271bbc..a43baab23 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -480,6 +480,14 @@ enum ToClientCommand u32 flags u32 mask */ + + TOCLIENT_HUD_SET_PARAM = 0x4d, + /* + u16 command + u16 param + u16 len + u8[len] value + */ }; enum ToServerCommand diff --git a/src/game.cpp b/src/game.cpp index 921cce327..4f0d1b663 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1987,7 +1987,7 @@ void the_game( { s32 wheel = input->getMouseWheel(); u16 max_item = MYMIN(PLAYER_INVENTORY_SIZE-1, - hud.hotbar_itemcount-1); + player->hud_hotbar_itemcount-1); if(wheel < 0) { @@ -2011,7 +2011,7 @@ void the_game( const KeyPress *kp = NumberKey + (i + 1) % 10; if(input->wasKeyDown(*kp)) { - if(i < PLAYER_INVENTORY_SIZE && i < hud.hotbar_itemcount) + if(i < PLAYER_INVENTORY_SIZE && i < player->hud_hotbar_itemcount) { new_playeritem = i; diff --git a/src/hud.cpp b/src/hud.cpp index 65c78ca50..a3ae38bcb 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -43,7 +43,6 @@ Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv, screensize = v2u32(0, 0); displaycenter = v2s32(0, 0); hotbar_imagesize = 48; - hotbar_itemcount = 8; tsrc = gamedef->getTextureSource(); @@ -286,6 +285,7 @@ void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem) { return; } + s32 hotbar_itemcount = player->hud_hotbar_itemcount; s32 padding = hotbar_imagesize / 12; s32 width = hotbar_itemcount * (hotbar_imagesize + padding * 2); v2s32 pos = centerlowerpos - v2s32(width / 2, hotbar_imagesize + padding * 2); diff --git a/src/hud.h b/src/hud.h index 54b7e7f36..fa9d33f8b 100644 --- a/src/hud.h +++ b/src/hud.h @@ -36,6 +36,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #define HUD_FLAG_CROSSHAIR_VISIBLE (1 << 2) #define HUD_FLAG_WIELDITEM_VISIBLE (1 << 3) +#define HUD_PARAM_HOTBAR_ITEMCOUNT 1 + +#define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8 +#define HUD_HOTBAR_ITEMCOUNT_MAX 23 + class Player; enum HudElementType { @@ -102,7 +107,6 @@ public: v2u32 screensize; v2s32 displaycenter; s32 hotbar_imagesize; - s32 hotbar_itemcount; video::SColor crosshair_argb; video::SColor selectionbox_argb; diff --git a/src/player.cpp b/src/player.cpp index 34f0fda08..4eb5955c0 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -81,6 +81,8 @@ Player::Player(IGameDef *gamedef): hud_flags = HUD_FLAG_HOTBAR_VISIBLE | HUD_FLAG_HEALTHBAR_VISIBLE | HUD_FLAG_CROSSHAIR_VISIBLE | HUD_FLAG_WIELDITEM_VISIBLE; + + hud_hotbar_itemcount = HUD_HOTBAR_ITEMCOUNT_DEFAULT; } Player::~Player() diff --git a/src/player.h b/src/player.h index 63e166b4b..d3738fd52 100644 --- a/src/player.h +++ b/src/player.h @@ -250,6 +250,7 @@ public: std::vector hud; u32 hud_flags; + s32 hud_hotbar_itemcount; protected: IGameDef *m_gamedef; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 6dec3db85..1e45610a6 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -978,6 +978,23 @@ int ObjectRef::l_hud_set_flags(lua_State *L) return 1; } +// hud_set_hotbar_itemcount(self, hotbar_itemcount) +int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L) +{ + ObjectRef *ref = checkobject(L, 1); + Player *player = getplayer(ref); + if (player == NULL) + return 0; + + s32 hotbar_itemcount = lua_tonumber(L, 2); + + if (!STACK_TO_SERVER(L)->hudSetHotbarItemcount(player, hotbar_itemcount)) + return 0; + + lua_pushboolean(L, true); + return 1; +} + ObjectRef::ObjectRef(ServerActiveObject *object): m_object(object) { @@ -1089,6 +1106,7 @@ const luaL_reg ObjectRef::methods[] = { luamethod(ObjectRef, hud_change), luamethod(ObjectRef, hud_get), luamethod(ObjectRef, hud_set_flags), + luamethod(ObjectRef, hud_set_hotbar_itemcount), {0,0} }; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 88f980a27..57dac0e64 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -209,6 +209,9 @@ private: // hud_set_flags(self, flags) static int l_hud_set_flags(lua_State *L); + // hud_set_hotbar_itemcount(self, hotbar_itemcount) + static int l_hud_set_hotbar_itemcount(lua_State *L); + public: ObjectRef(ServerActiveObject *object); diff --git a/src/server.cpp b/src/server.cpp index 12695e1b4..4268bb809 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3687,6 +3687,22 @@ void Server::SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask) m_con.Send(peer_id, 0, data, true); } +void Server::SendHUDSetParam(u16 peer_id, u16 param, const std::string &value) +{ + std::ostringstream os(std::ios_base::binary); + + // Write command + writeU16(os, TOCLIENT_HUD_SET_PARAM); + writeU16(os, param); + os< data((u8 *)s.c_str(), s.size()); + // Send as reliable + m_con.Send(peer_id, 0, data, true); +} + void Server::BroadcastChatMessage(const std::wstring &message) { for(std::map::iterator @@ -4684,6 +4700,18 @@ bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) { return true; } +bool Server::hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount) { + if (!player) + return false; + if (hotbar_itemcount <= 0 || hotbar_itemcount > HUD_HOTBAR_ITEMCOUNT_MAX) + return false; + + std::ostringstream os(std::ios::binary); + writeS32(os, hotbar_itemcount); + SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_ITEMCOUNT, os.str()); + return true; +} + void Server::notifyPlayers(const std::wstring msg) { BroadcastChatMessage(msg); diff --git a/src/server.h b/src/server.h index 3906f43b8..edc5c4895 100644 --- a/src/server.h +++ b/src/server.h @@ -541,6 +541,7 @@ public: bool hudRemove(Player *player, u32 id); bool hudChange(Player *player, u32 id, HudElementStat stat, void *value); bool hudSetFlags(Player *player, u32 flags, u32 mask); + bool hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount); private: @@ -585,6 +586,7 @@ private: void SendHUDRemove(u16 peer_id, u32 id); void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value); void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask); + void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value); /* Send a node removal/addition event to all clients except ignore_id.