diff --git a/src/frontend/gui/gui_xml.cpp b/src/frontend/gui/gui_xml.cpp index bb218568..5a75e3ad 100644 --- a/src/frontend/gui/gui_xml.cpp +++ b/src/frontend/gui/gui_xml.cpp @@ -178,6 +178,32 @@ static std::shared_ptr readButton(UiXmlReader& reader, xml::xmlelement e return button; } +static std::shared_ptr readCheckBox(UiXmlReader& reader, xml::xmlelement element) { + auto text = readAndProcessInnerText(element); + bool checked = element->attr("checked", "false").asBool(); + auto checkbox = std::make_shared(text, glm::vec2(), checked); + _readPanel(reader, element, *checkbox); + + if (element->has("consumer")) { + auto consumer = scripting::create_bool_consumer( + reader.getEnvironment().getId(), + element->attr("consumer").getText(), + reader.getFilename()+".lua" + ); + checkbox->setConsumer(consumer); + } + + if (element->has("supplier")) { + auto supplier = scripting::create_bool_supplier( + reader.getEnvironment().getId(), + element->attr("supplier").getText(), + reader.getFilename()+".lua" + ); + checkbox->setSupplier(supplier); + } + return checkbox; +} + static std::shared_ptr readTextBox(UiXmlReader& reader, xml::xmlelement element) { auto placeholder = util::str2wstr_utf8(element->attr("placeholder", "").getText()); auto text = readAndProcessInnerText(element); @@ -193,6 +219,15 @@ static std::shared_ptr readTextBox(UiXmlReader& reader, xml::xmlelement ); textbox->setTextConsumer(consumer); } + + if (element->has("supplier")) { + auto supplier = scripting::create_wstring_supplier( + reader.getEnvironment().getId(), + element->attr("consumer").getText(), + reader.getFilename()+".lua" + ); + textbox->setTextSupplier(supplier); + } return textbox; } @@ -242,6 +277,7 @@ UiXmlReader::UiXmlReader(const scripting::Environment& env, AssetsLoader& assets add("panel", readPanel); add("button", readButton); add("textbox", readTextBox); + add("chackbox", readCheckBox); add("trackbar", readTrackBar); add("container", readContainer); } diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index ff0bca6d..68fe1ebd 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -4,6 +4,7 @@ #include "lua_util.h" #include "api_lua.h" #include "libgui.h" +#include "libplayer.h" #include "libinventory.h" #include "../../../util/stringutil.h" @@ -172,6 +173,11 @@ int lua::LuaState::pushnumber(luanumber x) { return 1; } +int lua::LuaState::pushboolean(bool x) { + lua_pushboolean(L, x); + return 1; +} + int lua::LuaState::pushivec3(luaint x, luaint y, luaint z) { lua::pushivec3(L, x, y, z); return 3; @@ -233,6 +239,10 @@ lua::luanumber lua::LuaState::tonumber(int idx) { return lua_tonumber(L, idx); } +const char* lua::LuaState::tostring(int idx) { + return lua_tostring(L, idx); +} + void lua::LuaState::openlib(const std::string& name, const luaL_Reg* libfuncs, int nup) { lua_newtable(L); luaL_setfuncs(L, libfuncs, nup); diff --git a/src/logic/scripting/lua/LuaState.h b/src/logic/scripting/lua/LuaState.h index bff884d3..b80d2aab 100644 --- a/src/logic/scripting/lua/LuaState.h +++ b/src/logic/scripting/lua/LuaState.h @@ -31,6 +31,7 @@ namespace lua { int pushivec3(luaint x, luaint y, luaint z); int pushinteger(luaint x); int pushnumber(luanumber x); + int pushboolean(bool x); int pushstring(const std::string& str); int pushenv(int env); int pushvalue(int idx); @@ -42,6 +43,7 @@ namespace lua { bool toboolean(int idx); luaint tointeger(int idx); luanumber tonumber(int idx); + const char* tostring(int idx); int call(int argc); int callNoThrow(int argc); int execute(int env, const std::string& src, const std::string& file=""); diff --git a/src/logic/scripting/lua/api_lua.cpp b/src/logic/scripting/lua/api_lua.cpp index 88835056..dd47dab4 100644 --- a/src/logic/scripting/lua/api_lua.cpp +++ b/src/logic/scripting/lua/api_lua.cpp @@ -142,61 +142,6 @@ int l_world_get_seed(lua_State* L) { return 1; } -/* == player library ==*/ -int l_player_get_pos(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - glm::vec3 pos = scripting::level->player->hitbox->position; - lua_pushnumber(L, pos.x); - lua_pushnumber(L, pos.y); - lua_pushnumber(L, pos.z); - return 3; -} - -int l_player_get_rot(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - glm::vec2 rot = scripting::level->player->cam; - lua_pushnumber(L, rot.x); - lua_pushnumber(L, rot.y); - return 2; -} - -int l_player_set_rot(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - glm::vec2& cam = scripting::level->player->cam; - cam.x = x; - cam.y = y; - return 0; -} - -int l_player_set_pos(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - lua::luanumber z = lua_tonumber(L, 4); - scripting::level->player->hitbox->position = glm::vec3(x, y, z); - return 0; -} - -int l_player_get_inv(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - Player* player = scripting::level->player; - lua_pushinteger(L, player->getInventory()->getId()); - lua_pushinteger(L, player->getChosenSlot()); - return 2; -} - /* == item library == */ int l_item_name(lua_State* L) { auto indices = scripting::content->getIndices(); diff --git a/src/logic/scripting/lua/api_lua.h b/src/logic/scripting/lua/api_lua.h index ea809ceb..27fd4c85 100644 --- a/src/logic/scripting/lua/api_lua.h +++ b/src/logic/scripting/lua/api_lua.h @@ -58,22 +58,6 @@ static const luaL_Reg worldlib [] = { {NULL, NULL} }; -/* == player library ==*/ -extern int l_player_get_pos(lua_State* L); -extern int l_player_get_rot(lua_State* L); -extern int l_player_set_rot(lua_State* L); -extern int l_player_set_pos(lua_State* L); -extern int l_player_get_inv(lua_State* L); - -static const luaL_Reg playerlib [] = { - {"get_pos", lua_wrap_errors}, - {"set_pos", lua_wrap_errors}, - {"get_rot", lua_wrap_errors}, - {"set_rot", lua_wrap_errors}, - {"get_inventory", lua_wrap_errors}, - {NULL, NULL} -}; - /* == item library == */ extern int l_item_name(lua_State* L); extern int l_item_index(lua_State* L); diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 321e518f..cdcc6561 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -93,6 +93,16 @@ static bool getattr(lua_State* L, gui::Label* label, const std::string& attr) { return false; } +static bool getattr(lua_State* L, gui::FullCheckBox* box, const std::string& attr) { + if (box == nullptr) + return false; + if (attr == "checked") { + lua_pushboolean(L, box->isChecked()); + return true; + } + return false; +} + static bool setattr(lua_State* L, gui::Button* button, const std::string& attr) { if (button == nullptr) return false; @@ -105,6 +115,16 @@ static bool setattr(lua_State* L, gui::Button* button, const std::string& attr) return false; } +static bool setattr(lua_State* L, gui::FullCheckBox* box, const std::string& attr) { + if (box == nullptr) + return false; + if (attr == "checked") { + box->setChecked(lua_toboolean(L, 4)); + return true; + } + return false; +} + static bool setattr(lua_State* L, gui::Label* label, const std::string& attr) { if (label == nullptr) return false; @@ -143,6 +163,8 @@ int l_gui_getattr(lua_State* L) { return 1; if (getattr(L, dynamic_cast(node), attr)) return 1; + if (getattr(L, dynamic_cast(node), attr)) + return 1; return 0; } @@ -177,6 +199,8 @@ int l_gui_setattr(lua_State* L) { return 0; if (setattr(L, dynamic_cast(node), attr)) return 0; + if (setattr(L, dynamic_cast(node), attr)) + return 0; } return 0; } diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp new file mode 100644 index 00000000..cbf1fe47 --- /dev/null +++ b/src/logic/scripting/lua/libplayer.cpp @@ -0,0 +1,64 @@ +#include "libplayer.h" +#include "../scripting.h" +#include "../../../world/Level.h" +#include "../../../objects/Player.h" +#include "../../../physics/Hitbox.h" +#include "../../../window/Camera.h" +#include "../../../items/Inventory.h" + +#include + +/* == player library ==*/ +int l_player_get_pos(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + glm::vec3 pos = scripting::level->player->hitbox->position; + lua_pushnumber(L, pos.x); + lua_pushnumber(L, pos.y); + lua_pushnumber(L, pos.z); + return 3; +} + +int l_player_get_rot(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + glm::vec2 rot = scripting::level->player->cam; + lua_pushnumber(L, rot.x); + lua_pushnumber(L, rot.y); + return 2; +} + +int l_player_set_rot(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + lua::luanumber x = lua_tonumber(L, 2); + lua::luanumber y = lua_tonumber(L, 3); + glm::vec2& cam = scripting::level->player->cam; + cam.x = x; + cam.y = y; + return 0; +} + +int l_player_set_pos(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + lua::luanumber x = lua_tonumber(L, 2); + lua::luanumber y = lua_tonumber(L, 3); + lua::luanumber z = lua_tonumber(L, 4); + scripting::level->player->hitbox->position = glm::vec3(x, y, z); + return 0; +} + +int l_player_get_inv(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + Player* player = scripting::level->player; + lua_pushinteger(L, player->getInventory()->getId()); + lua_pushinteger(L, player->getChosenSlot()); + return 2; +} diff --git a/src/logic/scripting/lua/libplayer.h b/src/logic/scripting/lua/libplayer.h new file mode 100644 index 00000000..e53b83b8 --- /dev/null +++ b/src/logic/scripting/lua/libplayer.h @@ -0,0 +1,22 @@ +#ifndef LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ +#define LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ + +#include "lua_commons.h" + +/* == player library ==*/ +extern int l_player_get_pos(lua_State* L); +extern int l_player_get_rot(lua_State* L); +extern int l_player_set_rot(lua_State* L); +extern int l_player_set_pos(lua_State* L); +extern int l_player_get_inv(lua_State* L); + +static const luaL_Reg playerlib [] = { + {"get_pos", lua_wrap_errors}, + {"set_pos", lua_wrap_errors}, + {"get_rot", lua_wrap_errors}, + {"set_rot", lua_wrap_errors}, + {"get_inventory", lua_wrap_errors}, + {NULL, NULL} +}; + +#endif // LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ diff --git a/src/logic/scripting/lua/lua_commons.h b/src/logic/scripting/lua/lua_commons.h index c139be40..4732662d 100644 --- a/src/logic/scripting/lua/lua_commons.h +++ b/src/logic/scripting/lua/lua_commons.h @@ -25,4 +25,4 @@ template int lua_wrap_errors(lua_State *L) { return result; } -#endif // LOGIC_SCRIPTING_LUA_H_ \ No newline at end of file +#endif // LOGIC_SCRIPTING_LUA_H_ diff --git a/src/logic/scripting/scripting_functional.cpp b/src/logic/scripting/scripting_functional.cpp index e075590b..619d751a 100644 --- a/src/logic/scripting/scripting_functional.cpp +++ b/src/logic/scripting/scripting_functional.cpp @@ -51,6 +51,49 @@ wstringconsumer scripting::create_wstring_consumer( }; } +wstringsupplier scripting::create_wstring_supplier( + int env, + const std::string& src, + const std::string& file +) { + return [=](){ + if (processCallback(env, src, file)) { + state->callNoThrow(0); + auto str = state->tostring(-1); state->pop(); + return util::str2wstr_utf8(str); + } + return std::wstring(L""); + }; +} + +boolconsumer scripting::create_bool_consumer( + int env, + const std::string& src, + const std::string& file +) { + return [=](bool x){ + if (processCallback(env, src, file)) { + state->pushboolean(x); + state->callNoThrow(1); + } + }; +} + +boolsupplier scripting::create_bool_supplier( + int env, + const std::string& src, + const std::string& file +) { + return [=](){ + if (processCallback(env, src, file)) { + state->callNoThrow(0); + bool x = state->toboolean(-1); state->pop(); + return x; + } + return false; + }; +} + doubleconsumer scripting::create_number_consumer( int env, const std::string& src, diff --git a/src/logic/scripting/scripting_functional.h b/src/logic/scripting/scripting_functional.h index d608eded..c5db97e4 100644 --- a/src/logic/scripting/scripting_functional.h +++ b/src/logic/scripting/scripting_functional.h @@ -18,6 +18,24 @@ namespace scripting { const std::string& file="" ); + wstringsupplier create_wstring_supplier( + int env, + const std::string& src, + const std::string& file="" + ); + + boolconsumer create_bool_consumer( + int env, + const std::string& src, + const std::string& file="" + ); + + boolsupplier create_bool_supplier( + int env, + const std::string& src, + const std::string& file="" + ); + doubleconsumer create_number_consumer( int env, const std::string& src,