This commit is contained in:
DanielProl1xy
2024-02-21 14:19:40 +03:00
27 changed files with 498 additions and 168 deletions
+11 -1
View File
@@ -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"
@@ -33,7 +34,7 @@ lua::LuaState::LuaState() {
setglobal(envName(0));
}
const std::string lua::LuaState::envName(int env) const {
const std::string lua::LuaState::envName(int env) {
return "_ENV"+util::mangleid(env);
}
@@ -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);
+3 -1
View File
@@ -25,12 +25,13 @@ namespace lua {
LuaState();
~LuaState();
const std::string envName(int env) const;
static const std::string envName(int env);
void loadbuffer(int env, const std::string& src, const std::string& file);
int gettop() const;
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="<string>");
-55
View File
@@ -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;
auto 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();
-16
View File
@@ -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<l_player_get_pos>},
{"set_pos", lua_wrap_errors<l_player_set_pos>},
{"get_rot", lua_wrap_errors<l_player_get_rot>},
{"set_rot", lua_wrap_errors<l_player_set_rot>},
{"get_inventory", lua_wrap_errors<l_player_get_inv>},
{NULL, NULL}
};
/* == item library == */
extern int l_item_name(lua_State* L);
extern int l_item_index(lua_State* L);
+108 -2
View File
@@ -3,6 +3,7 @@
#include <iostream>
#include "../scripting.h"
#include "lua_util.h"
#include "LuaState.h"
#include "../../../engine.h"
#include "../../../assets/Assets.h"
@@ -23,12 +24,61 @@ static gui::UINode* getDocumentNode(lua_State* L, const std::string& name, const
return node.get();
}
static bool getattr(lua_State* L, gui::TrackBar* bar, const std::string& attr) {
if (bar == nullptr)
return false;
if (attr == "value") {
lua_pushnumber(L, bar->getValue()); return true;
} else if (attr == "min") {
lua_pushnumber(L, bar->getMin()); return true;
} else if (attr == "max") {
lua_pushnumber(L, bar->getMax());
return true;
} else if (attr == "step") {
lua_pushnumber(L, bar->getStep());
return true;
} else if (attr == "trackWidth") {
lua_pushnumber(L, bar->getTrackWidth());
return true;
} else if (attr == "trackColor") {
return lua::pushcolor_arr(L, bar->getTrackColor());
}
return false;
}
static bool setattr(lua_State* L, gui::TrackBar* bar, const std::string& attr) {
if (bar == nullptr)
return false;
if (attr == "value") {
bar->setValue(lua_tonumber(L, 4));
return true;
} else if (attr == "min") {
bar->setMin(lua_tonumber(L, 4));
return true;
} else if (attr == "max") {
bar->setMax(lua_tonumber(L, 4));
return true;
} else if (attr == "step") {
bar->setStep(lua_tonumber(L, 4));
return true;
} else if (attr == "trackWidth") {
bar->setTrackWidth(lua_tonumber(L, 4));
return true;
} else if (attr == "trackColor") {
bar->setTrackColor(lua::tocolor(L, 4));
return true;
}
return false;
}
static bool getattr(lua_State* L, gui::Button* button, const std::string& attr) {
if (button == nullptr)
return false;
if (attr == "text") {
lua_pushstring(L, util::wstr2str_utf8(button->getText()).c_str());
return true;
} else if (attr == "pressedColor") {
return lua::pushcolor_arr(L, button->getPressedColor());
}
return false;
}
@@ -43,12 +93,34 @@ 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;
if (attr == "text") {
button->setText(util::str2wstr_utf8(lua_tostring(L, 4)));
return true;
} else if (attr == "pressedColor") {
button->setPressedColor(lua::tocolor(L, 4));
}
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;
}
@@ -75,12 +147,24 @@ int l_gui_getattr(lua_State* L) {
return lua::pushvec2_arr(L, node->getCoord());
} else if (attr == "size") {
return lua::pushvec2_arr(L, node->getSize());
} else if (attr == "hoverColor") {
return lua::pushcolor_arr(L, node->getHoverColor());
} else if (attr == "interactive") {
lua_pushboolean(L, node->isInteractive());
return 1;
} else if (attr == "visible") {
lua_pushboolean(L, node->isVisible());
return 1;
}
if (getattr(L, dynamic_cast<gui::Button*>(node), attr))
return 1;
if (getattr(L, dynamic_cast<gui::Label*>(node), attr))
return 1;
if (getattr(L, dynamic_cast<gui::TrackBar*>(node), attr))
return 1;
if (getattr(L, dynamic_cast<gui::FullCheckBox*>(node), attr))
return 1;
return 0;
}
@@ -97,14 +181,36 @@ int l_gui_setattr(lua_State* L) {
auto node = getDocumentNode(L, docname, element);
if (attr == "pos") {
node->setCoord(lua::tovec2(L, 1));
node->setCoord(lua::tovec2(L, 4));
} else if (attr == "size") {
node->setSize(lua::tovec2(L, 1));
node->setSize(lua::tovec2(L, 4));
} else if (attr == "color") {
node->setColor(lua::tocolor(L, 4));
} else if (attr == "hoverColor") {
node->setHoverColor(lua::tocolor(L, 4));
} else if (attr == "interactive") {
node->setInteractive(lua_toboolean(L, 4));
} else if (attr == "visible") {
node->setVisible(lua_toboolean(L, 4));
} else {
if (setattr(L, dynamic_cast<gui::Button*>(node), attr))
return 0;
if (setattr(L, dynamic_cast<gui::Label*>(node), attr))
return 0;
if (setattr(L, dynamic_cast<gui::TrackBar*>(node), attr))
return 0;
if (setattr(L, dynamic_cast<gui::FullCheckBox*>(node), attr))
return 0;
}
return 0;
}
int l_gui_get_env(lua_State* L) {
auto name = lua_tostring(L, 1);
auto doc = scripting::engine->getAssets()->getLayout(name);
if (doc == nullptr) {
luaL_error(L, "document '%s' not found", name);
}
lua_getglobal(L, lua::LuaState::envName(doc->getEnvironment()).c_str());
return 1;
}
+6 -4
View File
@@ -1,16 +1,18 @@
#ifndef LOGIC_SCRIPTING_API_LIBGUI_H_
#define LOGIC_SCRIPTING_API_LIBGUI_H_
#include <lua.hpp>
#include "lua_commons.h"
extern int l_gui_getviewport(lua_State* L);
extern int l_gui_getattr(lua_State* L);
extern int l_gui_setattr(lua_State* L);
extern int l_gui_get_env(lua_State* L);
static const luaL_Reg guilib [] = {
{"get_viewport", l_gui_getviewport},
{"getattr", l_gui_getattr},
{"setattr", l_gui_setattr},
{"get_viewport", lua_wrap_errors<l_gui_getviewport>},
{"getattr", lua_wrap_errors<l_gui_getattr>},
{"setattr", lua_wrap_errors<l_gui_setattr>},
{"get_env", lua_wrap_errors<l_gui_get_env>},
{NULL, NULL}
};
-7
View File
@@ -53,13 +53,6 @@ int l_hud_open_block(lua_State* L) {
}
auto id = scripting::blocks->createBlockInventory(x, y, z);
if (id == 0) {
luaL_error(L,
"block '%s' at %d %d %d has no inventory",
def->name.c_str(),
x, y, z
);
}
scripting::hud->openInventory(
glm::ivec3(x, y, z), layout, scripting::level->inventories->get(id)
+64
View File
@@ -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 <glm/glm.hpp>
/* == 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;
auto player = scripting::level->player;
lua_pushinteger(L, player->getInventory()->getId());
lua_pushinteger(L, player->getChosenSlot());
return 2;
}
+22
View File
@@ -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<l_player_get_pos>},
{"set_pos", lua_wrap_errors<l_player_set_pos>},
{"get_rot", lua_wrap_errors<l_player_get_rot>},
{"set_rot", lua_wrap_errors<l_player_set_rot>},
{"get_inventory", lua_wrap_errors<l_player_get_inv>},
{NULL, NULL}
};
#endif // LOGIC_SCRIPTING_LUA_LIBPLAYER_H_
+1 -1
View File
@@ -25,4 +25,4 @@ template <lua_CFunction func> int lua_wrap_errors(lua_State *L) {
return result;
}
#endif // LOGIC_SCRIPTING_LUA_H_
#endif // LOGIC_SCRIPTING_LUA_H_
+21 -2
View File
@@ -87,12 +87,31 @@ namespace lua {
}
inline glm::vec2 tovec2(lua_State* L, int idx) {
lua_rawgeti(L, idx, 1);
lua_pushvalue(L, idx);
lua_rawgeti(L, -1, 1);
lua::luanumber x = lua_tonumber(L, -1); lua_pop(L, -1);
lua_rawgeti(L, idx, 1);
lua_rawgeti(L, -2, 2);
lua::luanumber y = lua_tonumber(L, -1); lua_pop(L, -1);
lua_pop(L, -1);
return glm::vec2(x, y);
}
inline glm::vec4 tocolor(lua_State* L, int idx) {
lua_pushvalue(L, idx);
if (!lua_istable(L, -1)) {
luaL_error(L, "RGBA array required");
}
lua_rawgeti(L, -1, 1);
lua::luanumber r = lua_tonumber(L, -1); lua_pop(L, -1);
lua_rawgeti(L, -2, 2);
lua::luanumber g = lua_tonumber(L, -1); lua_pop(L, -1);
lua_rawgeti(L, -3, 3);
lua::luanumber b = lua_tonumber(L, -1); lua_pop(L, -1);
lua_rawgeti(L, -4, 4);
lua::luanumber a = lua_tonumber(L, -1); lua_pop(L, -1);
lua_pop(L, -1);
return glm::vec4(r/255, g/255, b/255, a/255);
}
}
#endif // LOGIC_SCRIPTING_LUA_UTIL_H_
+3
View File
@@ -124,6 +124,9 @@ void scripting::on_world_quit() {
state->callNoThrow(0);
}
}
if (state->getglobal("__scripts_cleanup")) {
state->callNoThrow(0);
}
scripting::level = nullptr;
scripting::content = nullptr;
scripting::indices = nullptr;
+48 -1
View File
@@ -17,7 +17,11 @@ runnable scripting::create_runnable(
const std::string& file
) {
return [=](){
state->execute(env, src, file);
try {
state->execute(env, src, file);
} catch (const lua::luaerror& err) {
std::cerr << err.what() << std::endl;
}
};
}
@@ -47,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,
@@ -18,6 +18,24 @@ namespace scripting {
const std::string& file="<string>"
);
wstringsupplier create_wstring_supplier(
int env,
const std::string& src,
const std::string& file="<string>"
);
boolconsumer create_bool_consumer(
int env,
const std::string& src,
const std::string& file="<string>"
);
boolsupplier create_bool_supplier(
int env,
const std::string& src,
const std::string& file="<string>"
);
doubleconsumer create_number_consumer(
int env,
const std::string& src,