aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/lua_api')
-rw-r--r--src/script/lua_api/CMakeLists.txt10
-rw-r--r--src/script/lua_api/l_areastore.cpp4
-rw-r--r--src/script/lua_api/l_areastore.h7
-rw-r--r--src/script/lua_api/l_base.cpp26
-rw-r--r--src/script/lua_api/l_base.h16
-rw-r--r--src/script/lua_api/l_camera.cpp202
-rw-r--r--src/script/lua_api/l_camera.h44
-rw-r--r--src/script/lua_api/l_client.cpp356
-rw-r--r--src/script/lua_api/l_client.h98
-rw-r--r--src/script/lua_api/l_craft.cpp2
-rw-r--r--src/script/lua_api/l_env.cpp109
-rw-r--r--src/script/lua_api/l_env.h14
-rw-r--r--src/script/lua_api/l_internal.h14
-rw-r--r--src/script/lua_api/l_inventory.cpp12
-rw-r--r--src/script/lua_api/l_inventory.h2
-rw-r--r--src/script/lua_api/l_item.cpp66
-rw-r--r--src/script/lua_api/l_item.h7
-rw-r--r--src/script/lua_api/l_itemstackmeta.cpp120
-rw-r--r--src/script/lua_api/l_itemstackmeta.h59
-rw-r--r--src/script/lua_api/l_localplayer.cpp358
-rw-r--r--src/script/lua_api/l_localplayer.h85
-rw-r--r--src/script/lua_api/l_mainmenu.cpp76
-rw-r--r--src/script/lua_api/l_mainmenu.h10
-rw-r--r--src/script/lua_api/l_mapgen.cpp20
-rw-r--r--src/script/lua_api/l_mapgen.h3
-rw-r--r--src/script/lua_api/l_metadata.cpp266
-rw-r--r--src/script/lua_api/l_metadata.h75
-rw-r--r--src/script/lua_api/l_minimap.cpp227
-rw-r--r--src/script/lua_api/l_minimap.h65
-rw-r--r--src/script/lua_api/l_nodemeta.cpp330
-rw-r--r--src/script/lua_api/l_nodemeta.h48
-rw-r--r--src/script/lua_api/l_nodetimer.cpp4
-rw-r--r--src/script/lua_api/l_nodetimer.h9
-rw-r--r--src/script/lua_api/l_noise.cpp10
-rw-r--r--src/script/lua_api/l_noise.h37
-rw-r--r--src/script/lua_api/l_object.cpp271
-rw-r--r--src/script/lua_api/l_object.h67
-rw-r--r--src/script/lua_api/l_particles.cpp29
-rw-r--r--src/script/lua_api/l_server.cpp79
-rw-r--r--src/script/lua_api/l_server.h17
-rw-r--r--src/script/lua_api/l_settings.cpp85
-rw-r--r--src/script/lua_api/l_settings.h43
-rw-r--r--src/script/lua_api/l_sound.cpp53
-rw-r--r--src/script/lua_api/l_sound.h36
-rw-r--r--src/script/lua_api/l_storage.cpp147
-rw-r--r--src/script/lua_api/l_storage.h63
-rw-r--r--src/script/lua_api/l_util.cpp137
-rw-r--r--src/script/lua_api/l_util.h24
-rw-r--r--src/script/lua_api/l_vmanip.cpp49
-rw-r--r--src/script/lua_api/l_vmanip.h9
50 files changed, 3167 insertions, 733 deletions
diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt
index d507dcf70..1a78580e6 100644
--- a/src/script/lua_api/CMakeLists.txt
+++ b/src/script/lua_api/CMakeLists.txt
@@ -5,7 +5,9 @@ set(common_SCRIPT_LUA_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_itemstackmeta.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_metadata.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp
@@ -13,6 +15,7 @@ set(common_SCRIPT_LUA_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/l_particles.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_rollback.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_server.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_storage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_util.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_vmanip.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_settings.cpp
@@ -20,6 +23,11 @@ set(common_SCRIPT_LUA_API_SRCS
PARENT_SCOPE)
set(client_SCRIPT_LUA_API_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_client.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_minimap.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_storage.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_sound.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_localplayer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_camera.cpp
PARENT_SCOPE)
-
diff --git a/src/script/lua_api/l_areastore.cpp b/src/script/lua_api/l_areastore.cpp
index 09a5c78f9..b81985a7f 100644
--- a/src/script/lua_api/l_areastore.cpp
+++ b/src/script/lua_api/l_areastore.cpp
@@ -74,7 +74,7 @@ static inline void push_areas(lua_State *L, const std::vector<Area *> &areas,
static int deserialization_helper(lua_State *L, AreaStore *as,
std::istream &is)
{
- try {
+ try {
as->deserialize(is);
} catch (const SerializationError &e) {
lua_pushboolean(L, false);
@@ -380,7 +380,7 @@ void LuaAreaStore::Register(lua_State *L)
}
const char LuaAreaStore::className[] = "AreaStore";
-const luaL_reg LuaAreaStore::methods[] = {
+const luaL_Reg LuaAreaStore::methods[] = {
luamethod(LuaAreaStore, get_area),
luamethod(LuaAreaStore, get_areas_for_pos),
luamethod(LuaAreaStore, get_areas_in_area),
diff --git a/src/script/lua_api/l_areastore.h b/src/script/lua_api/l_areastore.h
index 4bd94cebe..8292e7712 100644
--- a/src/script/lua_api/l_areastore.h
+++ b/src/script/lua_api/l_areastore.h
@@ -22,14 +22,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_base.h"
-
class AreaStore;
-class LuaAreaStore : public ModApiBase {
+class LuaAreaStore : public ModApiBase
+{
private:
-
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
static int gc_object(lua_State *L);
diff --git a/src/script/lua_api/l_base.cpp b/src/script/lua_api/l_base.cpp
index 515a7d933..5d7ba9640 100644
--- a/src/script/lua_api/l_base.cpp
+++ b/src/script/lua_api/l_base.cpp
@@ -37,6 +37,18 @@ Server *ModApiBase::getServer(lua_State *L)
return getScriptApiBase(L)->getServer();
}
+#ifndef SERVER
+Client *ModApiBase::getClient(lua_State *L)
+{
+ return getScriptApiBase(L)->getClient();
+}
+#endif
+
+IGameDef *ModApiBase::getGameDef(lua_State *L)
+{
+ return getScriptApiBase(L)->getGameDef();
+}
+
Environment *ModApiBase::getEnv(lua_State *L)
{
return getScriptApiBase(L)->getEnv();
@@ -62,17 +74,13 @@ std::string ModApiBase::getCurrentModPath(lua_State *L)
}
-bool ModApiBase::registerFunction(
- lua_State *L,
- const char *name,
- lua_CFunction fct,
- int top)
+bool ModApiBase::registerFunction(lua_State *L, const char *name,
+ lua_CFunction func, int top)
{
- //TODO check presence first!
+ // TODO: Check presence first!
- lua_pushstring(L,name);
- lua_pushcfunction(L,fct);
- lua_settable(L, top);
+ lua_pushcfunction(L, func);
+ lua_setfield(L, top, name);
return true;
}
diff --git a/src/script/lua_api/l_base.h b/src/script/lua_api/l_base.h
index 641013dfd..af89afd93 100644
--- a/src/script/lua_api/l_base.h
+++ b/src/script/lua_api/l_base.h
@@ -22,12 +22,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_types.h"
#include "common/c_internal.h"
+#include "gamedef.h"
extern "C" {
#include <lua.h>
#include <lauxlib.h>
}
+#ifndef SERVER
+#include "client.h"
+#endif
+
class ScriptApiBase;
class Server;
class Environment;
@@ -38,6 +43,12 @@ class ModApiBase {
public:
static ScriptApiBase* getScriptApiBase(lua_State *L);
static Server* getServer(lua_State *L);
+ #ifndef SERVER
+ static Client* getClient(lua_State *L);
+ #endif // !SERVER
+
+ static IGameDef* getGameDef(lua_State *L);
+
static Environment* getEnv(lua_State *L);
static GUIEngine* getGuiEngine(lua_State *L);
// When we are not loading the mod, this function returns "."
@@ -57,9 +68,8 @@ public:
static bool registerFunction(lua_State *L,
const char* name,
- lua_CFunction fct,
- int top
- );
+ lua_CFunction func,
+ int top);
};
#endif /* L_BASE_H_ */
diff --git a/src/script/lua_api/l_camera.cpp b/src/script/lua_api/l_camera.cpp
new file mode 100644
index 000000000..862384198
--- /dev/null
+++ b/src/script/lua_api/l_camera.cpp
@@ -0,0 +1,202 @@
+#include "script/common/c_converter.h"
+#include "l_camera.h"
+#include "l_internal.h"
+#include "content_cao.h"
+#include "camera.h"
+
+LuaCamera::LuaCamera(Camera *m)
+{
+ m_camera = m;
+}
+
+void LuaCamera::create(lua_State *L, Camera *m)
+{
+ LuaCamera *o = new LuaCamera(m);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+
+ int camera_object = lua_gettop(L);
+
+ lua_getglobal(L, "core");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ int coretable = lua_gettop(L);
+
+ lua_pushvalue(L, camera_object);
+ lua_setfield(L, coretable, "camera");
+}
+
+int LuaCamera::l_set_camera_mode(lua_State *L)
+{
+ Camera *camera = getobject(L, 1);
+ GenericCAO *playercao = getClient(L)->getEnv().getLocalPlayer()->getCAO();
+ if (!camera)
+ return 0;
+ sanity_check(playercao);
+ if (!lua_isnumber(L, 2))
+ return 0;
+
+ camera->setCameraMode((CameraMode)((int)lua_tonumber(L, 2)));
+ playercao->setVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
+ playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
+ return 0;
+}
+
+int LuaCamera::l_get_camera_mode(lua_State *L)
+{
+ Camera *camera = getobject(L, 1);
+ if (!camera)
+ return 0;
+
+ lua_pushnumber(L, (int)camera->getCameraMode());
+
+ return 1;
+}
+
+int LuaCamera::l_get_fov(lua_State *L)
+{
+ Camera *camera = getobject(L, 1);
+ if (!camera)
+ return 0;
+
+ lua_newtable(L);
+ lua_pushnumber(L, camera->getFovX() * core::DEGTORAD);
+ lua_setfield(L, -2, "x");
+ lua_pushnumber(L, camera->getFovY() * core::DEGTORAD);
+ lua_setfield(L, -2, "y");
+ lua_pushnumber(L, camera->getCameraNode()->getFOV() * core::RADTODEG);
+ lua_setfield(L, -2, "actual");
+ lua_pushnumber(L, camera->getFovMax() * core::RADTODEG);
+ lua_setfield(L, -2, "max");
+ return 1;
+}
+
+int LuaCamera::l_get_pos(lua_State *L)
+{
+ Camera *camera = getobject(L, 1);
+ if (!camera)
+ return 0;
+
+ push_v3f(L, camera->getPosition());
+ return 1;
+}
+
+int LuaCamera::l_get_offset(lua_State *L)
+{
+ Camera *camera = getobject(L, 1);
+ if (!camera)
+ return 0;
+
+ push_v3s16(L, camera->getOffset());
+ return 1;
+}
+
+int LuaCamera::l_get_look_dir(lua_State *L)
+{
+ LocalPlayer *player = getClient(L)->getEnv().getLocalPlayer();
+ sanity_check(player);
+
+ float pitch = -1.0 * player->getPitch() * core::DEGTORAD;
+ float yaw = (player->getYaw() + 90.) * core::DEGTORAD;
+ v3f v(cos(pitch) * cos(yaw), sin(pitch), cos(pitch) * sin(yaw));
+
+ push_v3f(L, v);
+ return 1;
+}
+
+int LuaCamera::l_get_look_horizontal(lua_State *L)
+{
+ LocalPlayer *player = getClient(L)->getEnv().getLocalPlayer();
+ sanity_check(player);
+
+ lua_pushnumber(L, (player->getYaw() + 90.) * core::DEGTORAD);
+ return 1;
+}
+
+int LuaCamera::l_get_look_vertical(lua_State *L)
+{
+ LocalPlayer *player = getClient(L)->getEnv().getLocalPlayer();
+ sanity_check(player);
+
+ lua_pushnumber(L, -1.0 * player->getPitch() * core::DEGTORAD);
+ return 1;
+}
+
+int LuaCamera::l_get_aspect_ratio(lua_State *L)
+{
+ Camera *camera = getobject(L, 1);
+ if (!camera)
+ return 0;
+
+ lua_pushnumber(L, camera->getCameraNode()->getAspectRatio());
+ return 1;
+}
+
+LuaCamera *LuaCamera::checkobject(lua_State *L, int narg)
+{
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+
+ void *ud = luaL_checkudata(L, narg, className);
+ if (!ud)
+ luaL_typerror(L, narg, className);
+
+ return *(LuaCamera **)ud;
+}
+
+Camera *LuaCamera::getobject(LuaCamera *ref)
+{
+ return ref->m_camera;
+}
+
+Camera *LuaCamera::getobject(lua_State *L, int narg)
+{
+ LuaCamera *ref = checkobject(L, narg);
+ assert(ref);
+ Camera *camera = getobject(ref);
+ if (!camera)
+ return NULL;
+ return camera;
+}
+
+int LuaCamera::gc_object(lua_State *L)
+{
+ LuaCamera *o = *(LuaCamera **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+void LuaCamera::Register(lua_State *L)
+{
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1);
+
+ luaL_openlib(L, 0, methods, 0);
+ lua_pop(L, 1);
+}
+
+const char LuaCamera::className[] = "Camera";
+const luaL_Reg LuaCamera::methods[] = {luamethod(LuaCamera, set_camera_mode),
+ luamethod(LuaCamera, get_camera_mode), luamethod(LuaCamera, get_fov),
+ luamethod(LuaCamera, get_pos), luamethod(LuaCamera, get_offset),
+ luamethod(LuaCamera, get_look_dir),
+ luamethod(LuaCamera, get_look_vertical),
+ luamethod(LuaCamera, get_look_horizontal),
+ luamethod(LuaCamera, get_aspect_ratio),
+
+ {0, 0}};
diff --git a/src/script/lua_api/l_camera.h b/src/script/lua_api/l_camera.h
new file mode 100644
index 000000000..04921ad03
--- /dev/null
+++ b/src/script/lua_api/l_camera.h
@@ -0,0 +1,44 @@
+#ifndef L_CAMERA_H
+#define L_CAMERA_H
+
+#include "l_base.h"
+
+class Camera;
+
+class LuaCamera : public ModApiBase
+{
+private:
+ static const char className[];
+ static const luaL_Reg methods[];
+
+ // garbage collector
+ static int gc_object(lua_State *L);
+
+ static int l_set_camera_mode(lua_State *L);
+ static int l_get_camera_mode(lua_State *L);
+
+ static int l_get_fov(lua_State *L);
+
+ static int l_get_pos(lua_State *L);
+ static int l_get_offset(lua_State *L);
+ static int l_get_look_dir(lua_State *L);
+ static int l_get_look_vertical(lua_State *L);
+ static int l_get_look_horizontal(lua_State *L);
+ static int l_get_aspect_ratio(lua_State *L);
+
+ Camera *m_camera;
+
+public:
+ LuaCamera(Camera *m);
+ ~LuaCamera() {}
+
+ static void create(lua_State *L, Camera *m);
+
+ static LuaCamera *checkobject(lua_State *L, int narg);
+ static Camera *getobject(LuaCamera *ref);
+ static Camera *getobject(lua_State *L, int narg);
+
+ static void Register(lua_State *L);
+};
+
+#endif // L_CAMERA_H
diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp
new file mode 100644
index 000000000..3c2955bcd
--- /dev/null
+++ b/src/script/lua_api/l_client.cpp
@@ -0,0 +1,356 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "l_client.h"
+#include "clientenvironment.h"
+#include "common/c_content.h"
+#include "common/c_converter.h"
+#include "cpp_api/s_base.h"
+#include "gettext.h"
+#include "l_internal.h"
+#include "lua_api/l_item.h"
+#include "lua_api/l_nodemeta.h"
+#include "mainmenumanager.h"
+#include "map.h"
+#include "util/string.h"
+#include "nodedef.h"
+
+extern MainGameCallback *g_gamecallback;
+
+int ModApiClient::l_get_current_modname(lua_State *L)
+{
+ lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
+ return 1;
+}
+
+// get_last_run_mod()
+int ModApiClient::l_get_last_run_mod(lua_State *L)
+{
+ lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
+ const char *current_mod = lua_tostring(L, -1);
+ if (current_mod == NULL || current_mod[0] == '\0') {
+ lua_pop(L, 1);
+ lua_pushstring(L, getScriptApiBase(L)->getOrigin().c_str());
+ }
+ return 1;
+}
+
+// set_last_run_mod(modname)
+int ModApiClient::l_set_last_run_mod(lua_State *L)
+{
+ if (!lua_isstring(L, 1))
+ return 0;
+
+ const char *mod = lua_tostring(L, 1);
+ getScriptApiBase(L)->setOriginDirect(mod);
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+// print(text)
+int ModApiClient::l_print(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ std::string text = luaL_checkstring(L, 1);
+ rawstream << text << std::endl;
+ return 0;
+}
+
+// display_chat_message(message)
+int ModApiClient::l_display_chat_message(lua_State *L)
+{
+ if (!lua_isstring(L, 1))
+ return 0;
+
+ std::string message = luaL_checkstring(L, 1);
+ getClient(L)->pushToChatQueue(utf8_to_wide(message));
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+// send_chat_message(message)
+int ModApiClient::l_send_chat_message(lua_State *L)
+{
+ if (!lua_isstring(L, 1))
+ return 0;
+ std::string message = luaL_checkstring(L, 1);
+ getClient(L)->sendChatMessage(utf8_to_wide(message));
+ return 0;
+}
+
+// clear_out_chat_queue()
+int ModApiClient::l_clear_out_chat_queue(lua_State *L)
+{
+ getClient(L)->clearOutChatQueue();
+ return 0;
+}
+
+// get_player_names()
+int ModApiClient::l_get_player_names(lua_State *L)
+{
+ const std::list<std::string> &plist = getClient(L)->getConnectedPlayerNames();
+ lua_createtable(L, plist.size(), 0);
+ int newTable = lua_gettop(L);
+ int index = 1;
+ std::list<std::string>::const_iterator iter;
+ for (iter = plist.begin(); iter != plist.end(); ++iter) {
+ lua_pushstring(L, (*iter).c_str());
+ lua_rawseti(L, newTable, index);
+ index++;
+ }
+ return 1;
+}
+
+// show_formspec(formspec)
+int ModApiClient::l_show_formspec(lua_State *L)
+{
+ if (!lua_isstring(L, 1) || !lua_isstring(L, 2))
+ return 0;
+
+ ClientEvent event;
+ event.type = CE_SHOW_LOCAL_FORMSPEC;
+ event.show_formspec.formname = new std::string(luaL_checkstring(L, 1));
+ event.show_formspec.formspec = new std::string(luaL_checkstring(L, 2));
+ getClient(L)->pushToEventQueue(event);
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+// send_respawn()
+int ModApiClient::l_send_respawn(lua_State *L)
+{
+ getClient(L)->sendRespawn();
+ return 0;
+}
+
+// disconnect()
+int ModApiClient::l_disconnect(lua_State *L)
+{
+ // Stops badly written Lua code form causing boot loops
+ if (getClient(L)->isShutdown()) {
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ g_gamecallback->disconnect();
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+// gettext(text)
+int ModApiClient::l_gettext(lua_State *L)
+{
+ std::string text = strgettext(std::string(luaL_checkstring(L, 1)));
+ lua_pushstring(L, text.c_str());
+
+ return 1;
+}
+
+// get_node(pos)
+// pos = {x=num, y=num, z=num}
+int ModApiClient::l_get_node(lua_State *L)
+{
+ // pos
+ v3s16 pos = read_v3s16(L, 1);
+ // Do it
+ bool pos_ok;
+ MapNode n = getClient(L)->getNode(pos, &pos_ok);
+ // Return node
+ pushnode(L, n, getClient(L)->ndef());
+ return 1;
+}
+
+// get_node_or_nil(pos)
+// pos = {x=num, y=num, z=num}
+int ModApiClient::l_get_node_or_nil(lua_State *L)
+{
+ // pos
+ v3s16 pos = read_v3s16(L, 1);
+ // Do it
+ bool pos_ok;
+ MapNode n = getClient(L)->getNode(pos, &pos_ok);
+ if (pos_ok) {
+ // Return node
+ pushnode(L, n, getClient(L)->ndef());
+ } else {
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
+int ModApiClient::l_get_wielded_item(lua_State *L)
+{
+ Client *client = getClient(L);
+
+ Inventory local_inventory(client->idef());
+ client->getLocalInventory(local_inventory);
+
+ InventoryList *mlist = local_inventory.getList("main");
+
+ if (mlist && client->getPlayerItem() < mlist->getSize()) {
+ LuaItemStack::create(L, mlist->getItem(client->getPlayerItem()));
+ } else {
+ LuaItemStack::create(L, ItemStack());
+ }
+ return 1;
+}
+
+// get_meta(pos)
+int ModApiClient::l_get_meta(lua_State *L)
+{
+ v3s16 p = read_v3s16(L, 1);
+ NodeMetadata *meta = getClient(L)->getEnv().getMap().getNodeMetadata(p);
+ NodeMetaRef::createClient(L, meta);
+ return 1;
+}
+
+int ModApiClient::l_sound_play(lua_State *L)
+{
+ ISoundManager *sound = getClient(L)->getSoundManager();
+
+ SimpleSoundSpec spec;
+ read_soundspec(L, 1, spec);
+ float gain = 1.0;
+ bool looped = false;
+ s32 handle;
+
+ if (lua_istable(L, 2)) {
+ getfloatfield(L, 2, "gain", gain);
+ getboolfield(L, 2, "loop", looped);
+
+ lua_getfield(L, 2, "pos");
+ if (!lua_isnil(L, -1)) {
+ v3f pos = read_v3f(L, -1) * BS;
+ lua_pop(L, 1);
+ handle = sound->playSoundAt(
+ spec.name, looped, gain * spec.gain, pos);
+ lua_pushinteger(L, handle);
+ return 1;
+ }
+ }
+
+ handle = sound->playSound(spec.name, looped, gain * spec.gain);
+ lua_pushinteger(L, handle);
+
+ return 1;
+}
+
+int ModApiClient::l_sound_stop(lua_State *L)
+{
+ u32 handle = luaL_checkinteger(L, 1);
+
+ getClient(L)->getSoundManager()->stopSound(handle);
+
+ return 0;
+}
+
+// get_server_info()
+int ModApiClient::l_get_server_info(lua_State *L)
+{
+ Client *client = getClient(L);
+ Address serverAddress = client->getServerAddress();
+ lua_newtable(L);
+ lua_pushstring(L, client->getAddressName().c_str());
+ lua_setfield(L, -2, "address");
+ lua_pushstring(L, serverAddress.serializeString().c_str());
+ lua_setfield(L, -2, "ip");
+ lua_pushinteger(L, serverAddress.getPort());
+ lua_setfield(L, -2, "port");
+ lua_pushinteger(L, client->getProtoVersion());
+ lua_setfield(L, -2, "protocol_version");
+ return 1;
+}
+
+// get_item_def(itemstring)
+int ModApiClient::l_get_item_def(lua_State *L)
+{
+ IGameDef *gdef = getGameDef(L);
+ assert(gdef);
+
+ IItemDefManager *idef = gdef->idef();
+ assert(idef);
+
+ if (!lua_isstring(L, 1))
+ return 0;
+
+ const std::string &name(lua_tostring(L, 1));
+ if (!idef->isKnown(name))
+ return 0;
+ const ItemDefinition &def = idef->get(name);
+
+ push_item_definition_full(L, def);
+
+ return 1;
+}
+
+// get_node_def(nodename)
+int ModApiClient::l_get_node_def(lua_State *L)
+{
+ IGameDef *gdef = getGameDef(L);
+ assert(gdef);
+
+ INodeDefManager *ndef = gdef->ndef();
+ assert(ndef);
+
+ if (!lua_isstring(L, 1))
+ return 0;
+
+ const std::string &name = lua_tostring(L, 1);
+ const ContentFeatures &cf = ndef->get(ndef->getId(name));
+ if (cf.name != name) // Unknown node. | name = <whatever>, cf.name = ignore
+ return 0;
+
+ push_content_features(L, cf);
+
+ return 1;
+}
+
+int ModApiClient::l_take_screenshot(lua_State *L)
+{
+ Client *client = getClient(L);
+ client->makeScreenshot(client->getDevice());
+ return 0;
+}
+
+void ModApiClient::Initialize(lua_State *L, int top)
+{
+ API_FCT(get_current_modname);
+ API_FCT(print);
+ API_FCT(display_chat_message);
+ API_FCT(send_chat_message);
+ API_FCT(clear_out_chat_queue);
+ API_FCT(get_player_names);
+ API_FCT(set_last_run_mod);
+ API_FCT(get_last_run_mod);
+ API_FCT(show_formspec);
+ API_FCT(send_respawn);
+ API_FCT(gettext);
+ API_FCT(get_node);
+ API_FCT(get_node_or_nil);
+ API_FCT(get_wielded_item);
+ API_FCT(disconnect);
+ API_FCT(get_meta);
+ API_FCT(sound_play);
+ API_FCT(sound_stop);
+ API_FCT(get_server_info);
+ API_FCT(get_item_def);
+ API_FCT(get_node_def);
+ API_FCT(take_screenshot);
+}
diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h
new file mode 100644
index 000000000..fe5780fb1
--- /dev/null
+++ b/src/script/lua_api/l_client.h
@@ -0,0 +1,98 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_CLIENT_H_
+#define L_CLIENT_H_
+
+#include "lua_api/l_base.h"
+#include "itemdef.h"
+#include "tool.h"
+
+class ModApiClient : public ModApiBase
+{
+private:
+ // get_current_modname()
+ static int l_get_current_modname(lua_State *L);
+
+ // print(text)
+ static int l_print(lua_State *L);
+
+ // display_chat_message(message)
+ static int l_display_chat_message(lua_State *L);
+
+ // send_chat_message(message)
+ static int l_send_chat_message(lua_State *L);
+
+ // clear_out_chat_queue()
+ static int l_clear_out_chat_queue(lua_State *L);
+
+ // get_player_names()
+ static int l_get_player_names(lua_State *L);
+
+ // show_formspec(name, formspec)
+ static int l_show_formspec(lua_State *L);
+
+ // send_respawn()
+ static int l_send_respawn(lua_State *L);
+
+ // disconnect()
+ static int l_disconnect(lua_State *L);
+
+ // gettext(text)
+ static int l_gettext(lua_State *L);
+
+ // get_last_run_mod(n)
+ static int l_get_last_run_mod(lua_State *L);
+
+ // set_last_run_mod(modname)
+ static int l_set_last_run_mod(lua_State *L);
+
+ // get_node(pos)
+ static int l_get_node(lua_State *L);
+
+ // get_node_or_nil(pos)
+ static int l_get_node_or_nil(lua_State *L);
+
+ // get_wielded_item()
+ static int l_get_wielded_item(lua_State *L);
+
+ // get_meta(pos)
+ static int l_get_meta(lua_State *L);
+
+ static int l_sound_play(lua_State *L);
+
+ static int l_sound_stop(lua_State *L);
+
+ // get_server_info()
+ static int l_get_server_info(lua_State *L);
+
+ // get_item_def(itemstring)
+ static int l_get_item_def(lua_State *L);
+
+ // get_node_def(nodename)
+ static int l_get_node_def(lua_State *L);
+
+ static int l_take_screenshot(lua_State *L);
+
+public:
+ static void Initialize(lua_State *L, int top);
+};
+
+#endif
diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp
index 2236566de..315391856 100644
--- a/src/script/lua_api/l_craft.cpp
+++ b/src/script/lua_api/l_craft.cpp
@@ -414,7 +414,7 @@ static void push_craft_recipe(lua_State *L, IGameDef *gdef,
lua_newtable(L); // items
std::vector<ItemStack>::const_iterator iter = input.items.begin();
- for (u16 j = 1; iter != input.items.end(); iter++, j++) {
+ for (u16 j = 1; iter != input.items.end(); ++iter, j++) {
if (iter->empty())
continue;
lua_pushstring(L, iter->name.c_str());
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index 68d10308c..b8b6bc5ba 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_vmanip.h"
#include "common/c_converter.h"
#include "common/c_content.h"
-#include "scripting_game.h"
+#include "scripting_server.h"
#include "environment.h"
#include "server.h"
#include "nodedef.h"
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "treegen.h"
#include "emerge.h"
#include "pathfinder.h"
+#include "face_position_cache.h"
struct EnumString ModApiEnvMod::es_ClearObjectsMode[] =
{
@@ -49,7 +50,7 @@ struct EnumString ModApiEnvMod::es_ClearObjectsMode[] =
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
u32 active_object_count, u32 active_object_count_wider)
{
- GameScripting *scriptIface = env->getScriptIface();
+ ServerScripting *scriptIface = env->getScriptIface();
scriptIface->realityCheck();
lua_State *L = scriptIface->getStack();
@@ -92,7 +93,7 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n)
{
- GameScripting *scriptIface = env->getScriptIface();
+ ServerScripting *scriptIface = env->getScriptIface();
scriptIface->realityCheck();
lua_State *L = scriptIface->getStack();
@@ -284,7 +285,7 @@ int ModApiEnvMod::l_place_node(lua_State *L)
return 1;
}
// Create item to place
- ItemStack item(ndef->get(n).name, 1, 0, "", idef);
+ ItemStack item(ndef->get(n).name, 1, 0, idef);
// Make pointed position
PointedThing pointed;
pointed.type = POINTEDTHING_NODE;
@@ -347,7 +348,10 @@ int ModApiEnvMod::l_punch_node(lua_State *L)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_get_node_max_level(lua_State *L)
{
- GET_ENV_PTR;
+ Environment *env = getEnv(L);
+ if (!env) {
+ return 0;
+ }
v3s16 pos = read_v3s16(L, 1);
MapNode n = env->getMap().getNodeNoEx(pos);
@@ -359,7 +363,10 @@ int ModApiEnvMod::l_get_node_max_level(lua_State *L)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_get_node_level(lua_State *L)
{
- GET_ENV_PTR;
+ Environment *env = getEnv(L);
+ if (!env) {
+ return 0;
+ }
v3s16 pos = read_v3s16(L, 1);
MapNode n = env->getMap().getNodeNoEx(pos);
@@ -440,7 +447,7 @@ int ModApiEnvMod::l_get_node_timer(lua_State *L)
return 1;
}
-// add_entity(pos, entityname) -> ObjectRef or nil
+// add_entity(pos, entityname, [staticdata]) -> ObjectRef or nil
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_add_entity(lua_State *L)
{
@@ -450,8 +457,10 @@ int ModApiEnvMod::l_add_entity(lua_State *L)
v3f pos = checkFloatPos(L, 1);
// content
const char *name = luaL_checkstring(L, 2);
+ // staticdata
+ const char *staticdata = luaL_optstring(L, 3, "");
// Do it
- ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
+ ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, staticdata);
int objectid = env->addActiveObject(obj);
// If failed to add, return nothing (reads as nil)
if(objectid == 0)
@@ -470,7 +479,7 @@ int ModApiEnvMod::l_add_item(lua_State *L)
// pos
//v3f pos = checkFloatPos(L, 1);
// item
- ItemStack item = read_item(L, 2,getServer(L));
+ ItemStack item = read_item(L, 2,getServer(L)->idef());
if(item.empty() || !item.isKnown(getServer(L)->idef()))
return 0;
@@ -526,7 +535,7 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
ScriptApiBase *script = getScriptApiBase(L);
lua_createtable(L, ids.size(), 0);
std::vector<u16>::const_iterator iter = ids.begin();
- for(u32 i = 0; iter != ids.end(); iter++) {
+ for(u32 i = 0; iter != ids.end(); ++iter) {
ServerActiveObject *obj = env->getActiveObject(*iter);
// Insert object reference into table
script->objectrefGetOrCreate(L, obj);
@@ -556,11 +565,14 @@ int ModApiEnvMod::l_set_timeofday(lua_State *L)
// get_timeofday() -> 0...1
int ModApiEnvMod::l_get_timeofday(lua_State *L)
{
- GET_ENV_PTR;
+ Environment *env = getEnv(L);
+ if (!env) {
+ return 0;
+ }
// Do it
int timeofday_mh = env->getTimeOfDay();
- float timeofday_f = (float)timeofday_mh / 24000.0;
+ float timeofday_f = (float)timeofday_mh / 24000.0f;
lua_pushnumber(L, timeofday_f);
return 1;
}
@@ -568,7 +580,10 @@ int ModApiEnvMod::l_get_timeofday(lua_State *L)
// get_day_count() -> int
int ModApiEnvMod::l_get_day_count(lua_State *L)
{
- GET_ENV_PTR;
+ Environment *env = getEnv(L);
+ if (!env) {
+ return 0;
+ }
lua_pushnumber(L, env->getDayCount());
return 1;
@@ -585,37 +600,40 @@ int ModApiEnvMod::l_get_gametime(lua_State *L)
}
-// find_node_near(pos, radius, nodenames) -> pos or nil
+// find_node_near(pos, radius, nodenames, search_center) -> pos or nil
// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
int ModApiEnvMod::l_find_node_near(lua_State *L)
{
- GET_ENV_PTR;
+ Environment *env = getEnv(L);
+ if (!env) {
+ return 0;
+ }
- INodeDefManager *ndef = getServer(L)->ndef();
+ INodeDefManager *ndef = getGameDef(L)->ndef();
v3s16 pos = read_v3s16(L, 1);
int radius = luaL_checkinteger(L, 2);
std::set<content_t> filter;
- if(lua_istable(L, 3)){
- int table = 3;
+ if (lua_istable(L, 3)) {
lua_pushnil(L);
- while(lua_next(L, table) != 0){
+ while (lua_next(L, 3) != 0) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
ndef->getIds(lua_tostring(L, -1), filter);
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
- } else if(lua_isstring(L, 3)){
+ } else if (lua_isstring(L, 3)) {
ndef->getIds(lua_tostring(L, 3), filter);
}
- for(int d=1; d<=radius; d++){
+ int start_radius = (lua_toboolean(L, 4)) ? 0 : 1;
+ for (int d = start_radius; d <= radius; d++) {
std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
- for(std::vector<v3s16>::iterator i = list.begin();
- i != list.end(); ++i){
+ for (std::vector<v3s16>::iterator i = list.begin();
+ i != list.end(); ++i) {
v3s16 p = pos + (*i);
content_t c = env->getMap().getNodeNoEx(p).getContent();
- if(filter.count(c) != 0){
+ if (filter.count(c) != 0) {
push_v3s16(L, p);
return 1;
}
@@ -830,6 +848,36 @@ int ModApiEnvMod::l_line_of_sight(lua_State *L)
return 1;
}
+// fix_light(p1, p2)
+int ModApiEnvMod::l_fix_light(lua_State *L)
+{
+ GET_ENV_PTR;
+
+ v3s16 blockpos1 = getContainerPos(read_v3s16(L, 1), MAP_BLOCKSIZE);
+ v3s16 blockpos2 = getContainerPos(read_v3s16(L, 2), MAP_BLOCKSIZE);
+ ServerMap &map = env->getServerMap();
+ std::map<v3s16, MapBlock *> modified_blocks;
+ bool success = true;
+ v3s16 blockpos;
+ for (blockpos.X = blockpos1.X; blockpos.X <= blockpos2.X; blockpos.X++)
+ for (blockpos.Y = blockpos1.Y; blockpos.Y <= blockpos2.Y; blockpos.Y++)
+ for (blockpos.Z = blockpos1.Z; blockpos.Z <= blockpos2.Z; blockpos.Z++) {
+ success = success & map.repairBlockLight(blockpos, &modified_blocks);
+ }
+ if (modified_blocks.size() > 0) {
+ MapEditEvent event;
+ event.type = MEET_OTHER;
+ for (std::map<v3s16, MapBlock *>::iterator it = modified_blocks.begin();
+ it != modified_blocks.end(); ++it)
+ event.modified_blocks.insert(it->first);
+
+ map.dispatchEvent(&event);
+ }
+ lua_pushboolean(L, success);
+
+ return 1;
+}
+
// emerge_area(p1, p2, [callback, context])
// emerge mapblocks in area p1..p2, calls callback with context upon completion
int ModApiEnvMod::l_emerge_area(lua_State *L)
@@ -938,8 +986,7 @@ int ModApiEnvMod::l_find_path(lua_State *L)
lua_newtable(L);
int top = lua_gettop(L);
unsigned int index = 1;
- for (std::vector<v3s16>::iterator i = path.begin(); i != path.end();i++)
- {
+ for (std::vector<v3s16>::iterator i = path.begin(); i != path.end(); ++i) {
lua_pushnumber(L,index);
push_v3s16(L, *i);
lua_settable(L, top);
@@ -1072,6 +1119,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
API_FCT(find_node_near);
API_FCT(find_nodes_in_area);
API_FCT(find_nodes_in_area_under_air);
+ API_FCT(fix_light);
API_FCT(emerge_area);
API_FCT(delete_area);
API_FCT(get_perlin);
@@ -1085,3 +1133,12 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
API_FCT(forceload_block);
API_FCT(forceload_free_block);
}
+
+void ModApiEnvMod::InitializeClient(lua_State *L, int top)
+{
+ API_FCT(get_timeofday);
+ API_FCT(get_day_count);
+ API_FCT(get_node_max_level);
+ API_FCT(get_node_level);
+ API_FCT(find_node_near);
+}
diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h
index 89dd7978f..7ce19b085 100644
--- a/src/script/lua_api/l_env.h
+++ b/src/script/lua_api/l_env.h
@@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define L_ENV_H_
#include "lua_api/l_base.h"
-#include "environment.h"
+#include "serverenvironment.h"
class ModApiEnvMod : public ModApiBase {
private:
@@ -116,7 +116,7 @@ private:
// get_day_count() -> int
static int l_get_day_count(lua_State *L);
- // find_node_near(pos, radius, nodenames) -> pos or nil
+ // find_node_near(pos, radius, nodenames, search_center) -> pos or nil
// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
static int l_find_node_near(lua_State *L);
@@ -128,6 +128,9 @@ private:
// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
static int l_find_nodes_in_area_under_air(lua_State *L);
+ // fix_light(p1, p2) -> true/false
+ static int l_fix_light(lua_State *L);
+
// emerge_area(p1, p2)
static int l_emerge_area(lua_State *L);
@@ -173,6 +176,7 @@ private:
public:
static void Initialize(lua_State *L, int top);
+ static void InitializeClient(lua_State *L, int top);
static struct EnumString es_ClearObjectsMode[];
};
@@ -199,11 +203,11 @@ public:
m_simple_catch_up(simple_catch_up)
{
}
- virtual std::set<std::string> getTriggerContents()
+ virtual const std::set<std::string> &getTriggerContents() const
{
return m_trigger_contents;
}
- virtual std::set<std::string> getRequiredNeighbors()
+ virtual const std::set<std::string> &getRequiredNeighbors() const
{
return m_required_neighbors;
}
@@ -242,7 +246,7 @@ public:
};
struct ScriptCallbackState {
- GameScripting *script;
+ ServerScripting *script;
int callback_ref;
int args_ref;
unsigned int refcount;
diff --git a/src/script/lua_api/l_internal.h b/src/script/lua_api/l_internal.h
index 456c8fcce..e9b689931 100644
--- a/src/script/lua_api/l_internal.h
+++ b/src/script/lua_api/l_internal.h
@@ -30,22 +30,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_internal.h"
#define luamethod(class, name) {#name, class::l_##name}
-#define API_FCT(name) registerFunction(L, #name, l_##name,top)
-#define ASYNC_API_FCT(name) engine.registerFunction(#name, l_##name)
+#define luamethod_aliased(class, name, alias) {#name, class::l_##name}, {#alias, class::l_##name}
+#define API_FCT(name) registerFunction(L, #name, l_##name, top)
#define MAP_LOCK_REQUIRED
#define NO_MAP_LOCK_REQUIRED
-/*
-#if (defined(WIN32) || defined(_WIN32_WCE))
- #define NO_MAP_LOCK_REQUIRED
-#else
- #include "profiler.h"
- #define NO_MAP_LOCK_REQUIRED \
- ScopeProfiler nolocktime(g_profiler,"Scriptapi: unlockable time",SPT_ADD)
-#endif
-*/
-
#define GET_ENV_PTR_NO_MAP_LOCK \
ServerEnvironment *env = (ServerEnvironment *)getEnv(L); \
if (env == NULL) \
diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp
index 38eade609..f5e76a7b6 100644
--- a/src/script/lua_api/l_inventory.cpp
+++ b/src/script/lua_api/l_inventory.cpp
@@ -194,7 +194,7 @@ int InvRef::l_set_stack(lua_State *L)
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
int i = luaL_checknumber(L, 3) - 1;
- ItemStack newitem = read_item(L, 4, getServer(L));
+ ItemStack newitem = read_item(L, 4, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list != NULL && i >= 0 && i < (int) list->getSize()){
list->changeItem(i, newitem);
@@ -295,7 +295,7 @@ int InvRef::l_add_item(lua_State *L)
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
- ItemStack item = read_item(L, 3, getServer(L));
+ ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list){
ItemStack leftover = list->addItem(item);
@@ -315,7 +315,7 @@ int InvRef::l_room_for_item(lua_State *L)
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
- ItemStack item = read_item(L, 3, getServer(L));
+ ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list){
lua_pushboolean(L, list->roomForItem(item));
@@ -332,7 +332,7 @@ int InvRef::l_contains_item(lua_State *L)
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
- ItemStack item = read_item(L, 3, getServer(L));
+ ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list){
lua_pushboolean(L, list->containsItem(item));
@@ -349,7 +349,7 @@ int InvRef::l_remove_item(lua_State *L)
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
- ItemStack item = read_item(L, 3, getServer(L));
+ ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list){
ItemStack removed = list->removeItem(item);
@@ -463,7 +463,7 @@ void InvRef::Register(lua_State *L)
}
const char InvRef::className[] = "InvRef";
-const luaL_reg InvRef::methods[] = {
+const luaL_Reg InvRef::methods[] = {
luamethod(InvRef, is_empty),
luamethod(InvRef, get_size),
luamethod(InvRef, set_size),
diff --git a/src/script/lua_api/l_inventory.h b/src/script/lua_api/l_inventory.h
index cc5333965..91d41c0d0 100644
--- a/src/script/lua_api/l_inventory.h
+++ b/src/script/lua_api/l_inventory.h
@@ -36,7 +36,7 @@ private:
InventoryLocation m_loc;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
static InvRef *checkobject(lua_State *L, int narg);
diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp
index ff0baea14..0e4fc4ef0 100644
--- a/src/script/lua_api/l_item.cpp
+++ b/src/script/lua_api/l_item.cpp
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "lua_api/l_item.h"
+#include "lua_api/l_itemstackmeta.h"
#include "lua_api/l_internal.h"
#include "common/c_converter.h"
#include "common/c_content.h"
@@ -137,16 +138,28 @@ int LuaItemStack::l_set_wear(lua_State *L)
return 1;
}
+// get_meta(self) -> string
+int LuaItemStack::l_get_meta(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ LuaItemStack *o = checkobject(L, 1);
+ ItemStackMetaRef::create(L, &o->m_stack);
+ return 1;
+}
+
+// DEPRECATED
// get_metadata(self) -> string
int LuaItemStack::l_get_metadata(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
- lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
+ const std::string &value = item.metadata.getString("");
+ lua_pushlstring(L, value.c_str(), value.size());
return 1;
}
+// DEPRECATED
// set_metadata(self, string)
int LuaItemStack::l_set_metadata(lua_State *L)
{
@@ -156,7 +169,7 @@ int LuaItemStack::l_set_metadata(lua_State *L)
size_t len = 0;
const char *ptr = luaL_checklstring(L, 2, &len);
- item.metadata.assign(ptr, len);
+ item.metadata.setString("", std::string(ptr, len));
lua_pushboolean(L, true);
return 1;
@@ -177,7 +190,7 @@ int LuaItemStack::l_replace(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
LuaItemStack *o = checkobject(L, 1);
- o->m_stack = read_item(L,2,getServer(L));
+ o->m_stack = read_item(L, 2, getGameDef(L)->idef());
lua_pushboolean(L, true);
return 1;
}
@@ -211,8 +224,24 @@ int LuaItemStack::l_to_table(lua_State *L)
lua_setfield(L, -2, "count");
lua_pushinteger(L, item.wear);
lua_setfield(L, -2, "wear");
- lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
+
+ const std::string &metadata_str = item.metadata.getString("");
+ lua_pushlstring(L, metadata_str.c_str(), metadata_str.size());
lua_setfield(L, -2, "metadata");
+
+ lua_newtable(L);
+ const StringMap &fields = item.metadata.getStrings();
+ for (StringMap::const_iterator it = fields.begin();
+ it != fields.end(); ++it) {
+ const std::string &name = it->first;
+ if (name.empty())
+ continue;
+ const std::string &value = it->second;
+ lua_pushlstring(L, name.c_str(), name.size());
+ lua_pushlstring(L, value.c_str(), value.size());
+ lua_settable(L, -3);
+ }
+ lua_setfield(L, -2, "meta");
}
return 1;
}
@@ -223,7 +252,7 @@ int LuaItemStack::l_get_stack_max(lua_State *L)
NO_MAP_LOCK_REQUIRED;
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
- lua_pushinteger(L, item.getStackMax(getServer(L)->idef()));
+ lua_pushinteger(L, item.getStackMax(getGameDef(L)->idef()));
return 1;
}
@@ -233,7 +262,7 @@ int LuaItemStack::l_get_free_space(lua_State *L)
NO_MAP_LOCK_REQUIRED;
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
- lua_pushinteger(L, item.freeSpace(getServer(L)->idef()));
+ lua_pushinteger(L, item.freeSpace(getGameDef(L)->idef()));
return 1;
}
@@ -244,7 +273,7 @@ int LuaItemStack::l_is_known(lua_State *L)
NO_MAP_LOCK_REQUIRED;
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
- bool is_known = item.isKnown(getServer(L)->idef());
+ bool is_known = item.isKnown(getGameDef(L)->idef());
lua_pushboolean(L, is_known);
return 1;
}
@@ -280,7 +309,7 @@ int LuaItemStack::l_get_tool_capabilities(lua_State *L)
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
const ToolCapabilities &prop =
- item.getToolCapabilities(getServer(L)->idef());
+ item.getToolCapabilities(getGameDef(L)->idef());
push_tool_capabilities(L, prop);
return 1;
}
@@ -295,7 +324,7 @@ int LuaItemStack::l_add_wear(lua_State *L)
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
int amount = lua_tointeger(L, 2);
- bool result = item.addWear(amount, getServer(L)->idef());
+ bool result = item.addWear(amount, getGameDef(L)->idef());
lua_pushboolean(L, result);
return 1;
}
@@ -307,8 +336,8 @@ int LuaItemStack::l_add_item(lua_State *L)
NO_MAP_LOCK_REQUIRED;
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
- ItemStack newitem = read_item(L,-1, getServer(L));
- ItemStack leftover = item.addItem(newitem, getServer(L)->idef());
+ ItemStack newitem = read_item(L, -1, getGameDef(L)->idef());
+ ItemStack leftover = item.addItem(newitem, getGameDef(L)->idef());
create(L, leftover);
return 1;
}
@@ -321,9 +350,9 @@ int LuaItemStack::l_item_fits(lua_State *L)
NO_MAP_LOCK_REQUIRED;
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
- ItemStack newitem = read_item(L, 2, getServer(L));
+ ItemStack newitem = read_item(L, 2, getGameDef(L)->idef());
ItemStack restitem;
- bool fits = item.itemFits(newitem, &restitem, getServer(L)->idef());
+ bool fits = item.itemFits(newitem, &restitem, getGameDef(L)->idef());
lua_pushboolean(L, fits); // first return value
create(L, restitem); // second return value
return 2;
@@ -380,7 +409,7 @@ ItemStack& LuaItemStack::getItem()
int LuaItemStack::create_object(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- ItemStack item = read_item(L, 1, getServer(L));
+ ItemStack item = read_item(L, 1, getGameDef(L)->idef());
LuaItemStack *o = new LuaItemStack(item);
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, className);
@@ -435,7 +464,7 @@ void LuaItemStack::Register(lua_State *L)
}
const char LuaItemStack::className[] = "ItemStack";
-const luaL_reg LuaItemStack::methods[] = {
+const luaL_Reg LuaItemStack::methods[] = {
luamethod(LuaItemStack, is_empty),
luamethod(LuaItemStack, get_name),
luamethod(LuaItemStack, set_name),
@@ -443,6 +472,7 @@ const luaL_reg LuaItemStack::methods[] = {
luamethod(LuaItemStack, set_count),
luamethod(LuaItemStack, get_wear),
luamethod(LuaItemStack, set_wear),
+ luamethod(LuaItemStack, get_meta),
luamethod(LuaItemStack, get_metadata),
luamethod(LuaItemStack, set_metadata),
luamethod(LuaItemStack, clear),
@@ -496,7 +526,7 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
def.node_placement_prediction = "__default";
// Read the item definition
- def = read_item_definition(L, table, def);
+ read_item_definition(L, table, def, def);
// Default to having client-side placement prediction for nodes
// ("" in item definition sets it off)
@@ -568,7 +598,7 @@ int ModApiItemMod::l_get_content_id(lua_State *L)
NO_MAP_LOCK_REQUIRED;
std::string name = luaL_checkstring(L, 1);
- INodeDefManager *ndef = getServer(L)->getNodeDefManager();
+ INodeDefManager *ndef = getGameDef(L)->getNodeDefManager();
content_t c = ndef->getId(name);
lua_pushinteger(L, c);
@@ -581,7 +611,7 @@ int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
NO_MAP_LOCK_REQUIRED;
content_t c = luaL_checkint(L, 1);
- INodeDefManager *ndef = getServer(L)->getNodeDefManager();
+ INodeDefManager *ndef = getGameDef(L)->getNodeDefManager();
const char *name = ndef->get(c).name.c_str();
lua_pushstring(L, name);
diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h
index be919b701..b4efaefc8 100644
--- a/src/script/lua_api/l_item.h
+++ b/src/script/lua_api/l_item.h
@@ -28,7 +28,7 @@ private:
ItemStack m_stack;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
// Exported functions
@@ -56,9 +56,14 @@ private:
// set_wear(self, number)
static int l_set_wear(lua_State *L);
+ // get_meta(self) -> string
+ static int l_get_meta(lua_State *L);
+
+ // DEPRECATED
// get_metadata(self) -> string
static int l_get_metadata(lua_State *L);
+ // DEPRECATED
// set_metadata(self, string)
static int l_set_metadata(lua_State *L);
diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp
new file mode 100644
index 000000000..c37a82116
--- /dev/null
+++ b/src/script/lua_api/l_itemstackmeta.cpp
@@ -0,0 +1,120 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_itemstackmeta.h"
+#include "lua_api/l_internal.h"
+#include "common/c_content.h"
+
+/*
+ NodeMetaRef
+*/
+ItemStackMetaRef* ItemStackMetaRef::checkobject(lua_State *L, int narg)
+{
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+ void *ud = luaL_checkudata(L, narg, className);
+ if (!ud)
+ luaL_typerror(L, narg, className);
+
+ return *(ItemStackMetaRef**)ud; // unbox pointer
+}
+
+Metadata* ItemStackMetaRef::getmeta(bool auto_create)
+{
+ return &istack->metadata;
+}
+
+void ItemStackMetaRef::clearMeta()
+{
+ istack->metadata.clear();
+}
+
+void ItemStackMetaRef::reportMetadataChange()
+{
+ // TODO
+}
+
+// Exported functions
+
+// garbage collector
+int ItemStackMetaRef::gc_object(lua_State *L) {
+ ItemStackMetaRef *o = *(ItemStackMetaRef **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+// Creates an NodeMetaRef and leaves it on top of stack
+// Not callable from Lua; all references are created on the C side.
+void ItemStackMetaRef::create(lua_State *L, ItemStack *istack)
+{
+ ItemStackMetaRef *o = new ItemStackMetaRef(istack);
+ //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+}
+
+void ItemStackMetaRef::Register(lua_State *L)
+{
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+
+ lua_pushliteral(L, "metadata_class");
+ lua_pushlstring(L, className, strlen(className));
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__eq");
+ lua_pushcfunction(L, l_equals);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1); // drop metatable
+
+ luaL_openlib(L, 0, methods, 0); // fill methodtable
+ lua_pop(L, 1); // drop methodtable
+
+ // Cannot be created from Lua
+ //lua_register(L, className, create_object);
+}
+
+const char ItemStackMetaRef::className[] = "ItemStackMetaRef";
+const luaL_Reg ItemStackMetaRef::methods[] = {
+ luamethod(MetaDataRef, get_string),
+ luamethod(MetaDataRef, set_string),
+ luamethod(MetaDataRef, get_int),
+ luamethod(MetaDataRef, set_int),
+ luamethod(MetaDataRef, get_float),
+ luamethod(MetaDataRef, set_float),
+ luamethod(MetaDataRef, to_table),
+ luamethod(MetaDataRef, from_table),
+ luamethod(MetaDataRef, equals),
+ {0,0}
+};
diff --git a/src/script/lua_api/l_itemstackmeta.h b/src/script/lua_api/l_itemstackmeta.h
new file mode 100644
index 000000000..4ef64a91e
--- /dev/null
+++ b/src/script/lua_api/l_itemstackmeta.h
@@ -0,0 +1,59 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_ITEMSTACKMETA_H_
+#define L_ITEMSTACKMETA_H_
+
+#include "lua_api/l_base.h"
+#include "lua_api/l_metadata.h"
+#include "irrlichttypes_bloated.h"
+#include "inventory.h"
+
+class ItemStackMetaRef : public MetaDataRef
+{
+private:
+ ItemStack *istack;
+
+ static const char className[];
+ static const luaL_Reg methods[];
+
+ static ItemStackMetaRef *checkobject(lua_State *L, int narg);
+
+ virtual Metadata* getmeta(bool auto_create);
+
+ virtual void clearMeta();
+
+ virtual void reportMetadataChange();
+
+ // Exported functions
+
+ // garbage collector
+ static int gc_object(lua_State *L);
+public:
+ ItemStackMetaRef(ItemStack *istack): istack(istack) {}
+ ~ItemStackMetaRef() {}
+
+ // Creates an ItemStackMetaRef and leaves it on top of stack
+ // Not callable from Lua; all references are created on the C side.
+ static void create(lua_State *L, ItemStack *istack);
+
+ static void Register(lua_State *L);
+};
+
+#endif
diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp
new file mode 100644
index 000000000..7ec4eaa62
--- /dev/null
+++ b/src/script/lua_api/l_localplayer.cpp
@@ -0,0 +1,358 @@
+/*
+Minetest
+Copyright (C) 2017 Dumbeldor, Vincent Glize <vincent.glize@live.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "l_localplayer.h"
+#include "l_internal.h"
+#include "script/common/c_converter.h"
+
+LuaLocalPlayer::LuaLocalPlayer(LocalPlayer *m)
+{
+ m_localplayer = m;
+}
+
+void LuaLocalPlayer::create(lua_State *L, LocalPlayer *m)
+{
+ LuaLocalPlayer *o = new LuaLocalPlayer(m);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+
+ // Keep localplayer object stack id
+ int localplayer_object = lua_gettop(L);
+
+ lua_getglobal(L, "core");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ int coretable = lua_gettop(L);
+
+ lua_pushvalue(L, localplayer_object);
+ lua_setfield(L, coretable, "localplayer");
+}
+
+int LuaLocalPlayer::l_get_velocity(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ push_v3f(L, player->getSpeed() / BS);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_hp(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushinteger(L, player->hp);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_name(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushstring(L, player->getName());
+ return 1;
+}
+
+int LuaLocalPlayer::l_is_attached(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushboolean(L, player->isAttached);
+ return 1;
+}
+
+int LuaLocalPlayer::l_is_touching_ground(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushboolean(L, player->touching_ground);
+ return 1;
+}
+
+int LuaLocalPlayer::l_is_in_liquid(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushboolean(L, player->in_liquid);
+ return 1;
+}
+
+int LuaLocalPlayer::l_is_in_liquid_stable(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushboolean(L, player->in_liquid_stable);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_liquid_viscosity(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushinteger(L, player->liquid_viscosity);
+ return 1;
+}
+
+int LuaLocalPlayer::l_is_climbing(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushboolean(L, player->is_climbing);
+ return 1;
+}
+
+int LuaLocalPlayer::l_swimming_vertical(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushboolean(L, player->swimming_vertical);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_physics_override(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_newtable(L);
+ lua_pushnumber(L, player->physics_override_speed);
+ lua_setfield(L, -2, "speed");
+
+ lua_pushnumber(L, player->physics_override_jump);
+ lua_setfield(L, -2, "jump");
+
+ lua_pushnumber(L, player->physics_override_gravity);
+ lua_setfield(L, -2, "gravity");
+
+ lua_pushboolean(L, player->physics_override_sneak);
+ lua_setfield(L, -2, "sneak");
+
+ lua_pushboolean(L, player->physics_override_sneak_glitch);
+ lua_setfield(L, -2, "sneak_glitch");
+
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_override_pos(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ push_v3f(L, player->overridePosition);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_last_pos(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ push_v3f(L, player->last_position / BS);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_last_velocity(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ push_v3f(L, player->last_speed);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_last_look_vertical(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushnumber(L, -1.0 * player->last_pitch * core::DEGTORAD);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_last_look_horizontal(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushnumber(L, (player->last_yaw + 90.) * core::DEGTORAD);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_key_pressed(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushinteger(L, player->last_keyPressed);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_breath(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_pushinteger(L, player->getBreath());
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_pos(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ push_v3f(L, player->getPosition() / BS);
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_movement_acceleration(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_newtable(L);
+ lua_pushnumber(L, player->movement_acceleration_default);
+ lua_setfield(L, -2, "default");
+
+ lua_pushnumber(L, player->movement_acceleration_air);
+ lua_setfield(L, -2, "air");
+
+ lua_pushnumber(L, player->movement_acceleration_fast);
+ lua_setfield(L, -2, "fast");
+
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_movement_speed(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_newtable(L);
+ lua_pushnumber(L, player->movement_speed_walk);
+ lua_setfield(L, -2, "walk");
+
+ lua_pushnumber(L, player->movement_speed_crouch);
+ lua_setfield(L, -2, "crouch");
+
+ lua_pushnumber(L, player->movement_speed_fast);
+ lua_setfield(L, -2, "fast");
+
+ lua_pushnumber(L, player->movement_speed_climb);
+ lua_setfield(L, -2, "climb");
+
+ lua_pushnumber(L, player->movement_speed_jump);
+ lua_setfield(L, -2, "jump");
+
+ return 1;
+}
+
+int LuaLocalPlayer::l_get_movement(lua_State *L)
+{
+ LocalPlayer *player = getobject(L, 1);
+
+ lua_newtable(L);
+
+ lua_pushnumber(L, player->movement_liquid_fluidity);
+ lua_setfield(L, -2, "liquid_fluidity");
+
+ lua_pushnumber(L, player->movement_liquid_fluidity_smooth);
+ lua_setfield(L, -2, "liquid_fluidity_smooth");
+
+ lua_pushnumber(L, player->movement_liquid_sink);
+ lua_setfield(L, -2, "liquid_sink");
+
+ lua_pushnumber(L, player->movement_gravity);
+ lua_setfield(L, -2, "gravity");
+
+ return 1;
+}
+
+LuaLocalPlayer *LuaLocalPlayer::checkobject(lua_State *L, int narg)
+{
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+
+ void *ud = luaL_checkudata(L, narg, className);
+ if (!ud)
+ luaL_typerror(L, narg, className);
+
+ return *(LuaLocalPlayer **)ud;
+}
+
+LocalPlayer *LuaLocalPlayer::getobject(LuaLocalPlayer *ref)
+{
+ return ref->m_localplayer;
+}
+
+LocalPlayer *LuaLocalPlayer::getobject(lua_State *L, int narg)
+{
+ LuaLocalPlayer *ref = checkobject(L, narg);
+ assert(ref);
+ LocalPlayer *player = getobject(ref);
+ assert(player);
+ return player;
+}
+
+int LuaLocalPlayer::gc_object(lua_State *L)
+{
+ LuaLocalPlayer *o = *(LuaLocalPlayer **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+void LuaLocalPlayer::Register(lua_State *L)
+{
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable); // hide metatable from lua getmetatable()
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1); // Drop metatable
+
+ luaL_openlib(L, 0, methods, 0); // fill methodtable
+ lua_pop(L, 1); // Drop methodtable
+}
+
+const char LuaLocalPlayer::className[] = "LocalPlayer";
+const luaL_Reg LuaLocalPlayer::methods[] = {
+ luamethod(LuaLocalPlayer, get_velocity),
+ luamethod(LuaLocalPlayer, get_hp),
+ luamethod(LuaLocalPlayer, get_name),
+ luamethod(LuaLocalPlayer, is_attached),
+ luamethod(LuaLocalPlayer, is_touching_ground),
+ luamethod(LuaLocalPlayer, is_in_liquid),
+ luamethod(LuaLocalPlayer, is_in_liquid_stable),
+ luamethod(LuaLocalPlayer, get_liquid_viscosity),
+ luamethod(LuaLocalPlayer, is_climbing),
+ luamethod(LuaLocalPlayer, swimming_vertical),
+ luamethod(LuaLocalPlayer, get_physics_override),
+ luamethod(LuaLocalPlayer, get_override_pos),
+ luamethod(LuaLocalPlayer, get_last_pos),
+ luamethod(LuaLocalPlayer, get_last_velocity),
+ luamethod(LuaLocalPlayer, get_last_look_horizontal),
+ luamethod(LuaLocalPlayer, get_last_look_vertical),
+ luamethod(LuaLocalPlayer, get_key_pressed),
+ luamethod(LuaLocalPlayer, get_breath),
+ luamethod(LuaLocalPlayer, get_pos),
+ luamethod(LuaLocalPlayer, get_movement_acceleration),
+ luamethod(LuaLocalPlayer, get_movement_speed),
+ luamethod(LuaLocalPlayer, get_movement),
+
+ {0, 0}
+};
diff --git a/src/script/lua_api/l_localplayer.h b/src/script/lua_api/l_localplayer.h
new file mode 100644
index 000000000..e56ec808f
--- /dev/null
+++ b/src/script/lua_api/l_localplayer.h
@@ -0,0 +1,85 @@
+/*
+Minetest
+Copyright (C) 2017 Dumbeldor, Vincent Glize <vincent.glize@live.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef MINETEST_L_LOCALPLAYER_H
+#define MINETEST_L_LOCALPLAYER_H
+
+#include "l_base.h"
+
+class LocalPlayer;
+
+class LuaLocalPlayer : public ModApiBase
+{
+private:
+ static const char className[];
+ static const luaL_Reg methods[];
+
+ // garbage collector
+ static int gc_object(lua_State *L);
+
+ static int l_get_velocity(lua_State *L);
+
+ static int l_get_hp(lua_State *L);
+
+ static int l_get_name(lua_State *L);
+
+ static int l_is_attached(lua_State *L);
+ static int l_is_touching_ground(lua_State *L);
+ static int l_is_in_liquid(lua_State *L);
+ static int l_is_in_liquid_stable(lua_State *L);
+ static int l_get_liquid_viscosity(lua_State *L);
+ static int l_is_climbing(lua_State *L);
+ static int l_swimming_vertical(lua_State *L);
+
+ static int l_get_physics_override(lua_State *L);
+
+ static int l_get_override_pos(lua_State *L);
+
+ static int l_get_last_pos(lua_State *L);
+ static int l_get_last_velocity(lua_State *L);
+ static int l_get_last_look_vertical(lua_State *L);
+ static int l_get_last_look_horizontal(lua_State *L);
+ static int l_get_key_pressed(lua_State *L);
+
+ static int l_get_breath(lua_State *L);
+
+ static int l_get_pos(lua_State *L);
+
+ static int l_get_movement_acceleration(lua_State *L);
+
+ static int l_get_movement_speed(lua_State *L);
+
+ static int l_get_movement(lua_State *L);
+
+ LocalPlayer *m_localplayer;
+
+public:
+ LuaLocalPlayer(LocalPlayer *m);
+ ~LuaLocalPlayer() {}
+
+ static void create(lua_State *L, LocalPlayer *m);
+
+ static LuaLocalPlayer *checkobject(lua_State *L, int narg);
+ static LocalPlayer *getobject(LuaLocalPlayer *ref);
+ static LocalPlayer *getobject(lua_State *L, int narg);
+
+ static void Register(lua_State *L);
+};
+
+#endif // MINETEST_L_LOCALPLAYER_H
diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
index 4a2484613..dc8654960 100644
--- a/src/script/lua_api/l_mainmenu.cpp
+++ b/src/script/lua_api/l_mainmenu.cpp
@@ -32,14 +32,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "convert_json.h"
#include "serverlist.h"
#include "mapgen.h"
-#include "sound.h"
#include "settings.h"
-#include "log.h"
#include "EDriverTypes.h"
#include <IFileArchive.h>
#include <IFileSystem.h>
+
/******************************************************************************/
std::string ModApiMainMenu::getTextData(lua_State *L, std::string name)
{
@@ -299,7 +298,7 @@ int ModApiMainMenu::l_get_games(lua_State *L)
int table2 = lua_gettop(L);
int internal_index=1;
for (std::set<std::string>::iterator iter = games[i].addon_mods_paths.begin();
- iter != games[i].addon_mods_paths.end(); iter++) {
+ iter != games[i].addon_mods_paths.end(); ++iter) {
lua_pushnumber(L,internal_index);
lua_pushstring(L,(*iter).c_str());
lua_settable(L, table2);
@@ -577,6 +576,13 @@ int ModApiMainMenu::l_get_favorites(lua_State *L)
lua_settable(L, top_lvl2);
}
+ if (servers[i].isMember("ping")) {
+ float ping = servers[i]["ping"].asFloat();
+ lua_pushstring(L, "ping");
+ lua_pushnumber(L, ping);
+ lua_settable(L, top_lvl2);
+ }
+
lua_settable(L, top);
index++;
}
@@ -956,33 +962,6 @@ int ModApiMainMenu::l_show_file_open_dialog(lua_State *L)
}
/******************************************************************************/
-int ModApiMainMenu::l_sound_play(lua_State *L)
-{
- GUIEngine* engine = getGuiEngine(L);
-
- SimpleSoundSpec spec;
- read_soundspec(L, 1, spec);
- bool looped = lua_toboolean(L, 2);
-
- u32 handle = engine->playSound(spec, looped);
-
- lua_pushinteger(L, handle);
-
- return 1;
-}
-
-/******************************************************************************/
-int ModApiMainMenu::l_sound_stop(lua_State *L)
-{
- GUIEngine* engine = getGuiEngine(L);
-
- u32 handle = luaL_checkinteger(L, 1);
- engine->stopSound(handle);
-
- return 1;
-}
-
-/******************************************************************************/
int ModApiMainMenu::l_download_file(lua_State *L)
{
const char *url = luaL_checkstring(L, 1);
@@ -1153,8 +1132,6 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
API_FCT(download_file);
API_FCT(get_modstore_details);
API_FCT(get_modstore_list);
- API_FCT(sound_play);
- API_FCT(sound_stop);
API_FCT(gettext);
API_FCT(get_video_drivers);
API_FCT(get_video_modes);
@@ -1165,23 +1142,24 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
}
/******************************************************************************/
-void ModApiMainMenu::InitializeAsync(AsyncEngine& engine)
+void ModApiMainMenu::InitializeAsync(lua_State *L, int top)
{
- ASYNC_API_FCT(get_worlds);
- ASYNC_API_FCT(get_games);
- ASYNC_API_FCT(get_favorites);
- ASYNC_API_FCT(get_mapgen_names);
- ASYNC_API_FCT(get_modpath);
- ASYNC_API_FCT(get_gamepath);
- ASYNC_API_FCT(get_texturepath);
- ASYNC_API_FCT(get_texturepath_share);
- ASYNC_API_FCT(create_dir);
- ASYNC_API_FCT(delete_dir);
- ASYNC_API_FCT(copy_dir);
- //ASYNC_API_FCT(extract_zip); //TODO remove dependency to GuiEngine
- ASYNC_API_FCT(download_file);
- ASYNC_API_FCT(get_modstore_details);
- ASYNC_API_FCT(get_modstore_list);
- //ASYNC_API_FCT(gettext); (gettext lib isn't threadsafe)
+ API_FCT(get_worlds);
+ API_FCT(get_games);
+ API_FCT(get_favorites);
+ API_FCT(get_mapgen_names);
+ API_FCT(get_modpath);
+ API_FCT(get_gamepath);
+ API_FCT(get_texturepath);
+ API_FCT(get_texturepath_share);
+ API_FCT(create_dir);
+ API_FCT(delete_dir);
+ API_FCT(copy_dir);
+ //API_FCT(extract_zip); //TODO remove dependency to GuiEngine
+ API_FCT(download_file);
+ API_FCT(get_modstore_details);
+ API_FCT(get_modstore_list);
+ //API_FCT(gettext); (gettext lib isn't threadsafe)
}
+
diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h
index ad5155ac6..d4946bab1 100644
--- a/src/script/lua_api/l_mainmenu.h
+++ b/src/script/lua_api/l_mainmenu.h
@@ -25,7 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class AsyncEngine;
/** Implementation of lua api support for mainmenu */
-class ModApiMainMenu : public ModApiBase {
+class ModApiMainMenu: public ModApiBase
+{
private:
/**
@@ -79,10 +80,6 @@ private:
static int l_delete_favorite(lua_State *L);
- static int l_sound_play(lua_State *L);
-
- static int l_sound_stop(lua_State *L);
-
static int l_gettext(lua_State *L);
//gui
@@ -145,6 +142,7 @@ private:
static int l_do_async_callback(lua_State *L);
public:
+
/**
* initialize this API module
* @param L lua stack to initialize
@@ -152,7 +150,7 @@ public:
*/
static void Initialize(lua_State *L, int top);
- static void InitializeAsync(AsyncEngine& engine);
+ static void InitializeAsync(lua_State *L, int top);
};
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index bc1c32f03..32eb7af84 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -325,14 +325,22 @@ void read_schematic_replacements(lua_State *L, int index, StringMap *replace_nam
if (lua_istable(L, -1)) { // Old {{"x", "y"}, ...} format
lua_rawgeti(L, -1, 1);
+ if (!lua_isstring(L, -1))
+ throw LuaError("schematics: replace_from field is not a string");
replace_from = lua_tostring(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, -1, 2);
+ if (!lua_isstring(L, -1))
+ throw LuaError("schematics: replace_to field is not a string");
replace_to = lua_tostring(L, -1);
lua_pop(L, 1);
} else { // New {x = "y", ...} format
+ if (!lua_isstring(L, -2))
+ throw LuaError("schematics: replace_from field is not a string");
replace_from = lua_tostring(L, -2);
+ if (!lua_isstring(L, -1))
+ throw LuaError("schematics: replace_to field is not a string");
replace_to = lua_tostring(L, -1);
}
@@ -419,7 +427,7 @@ size_t get_biome_list(lua_State *L, int index,
if (is_single) {
Biome *biome = get_or_load_biome(L, index, biomemgr);
if (!biome) {
- errorstream << "get_biome_list: failed to get biome '"
+ infostream << "get_biome_list: failed to get biome '"
<< (lua_isstring(L, index) ? lua_tostring(L, index) : "")
<< "'." << std::endl;
return 1;
@@ -438,7 +446,7 @@ size_t get_biome_list(lua_State *L, int index,
Biome *biome = get_or_load_biome(L, -1, biomemgr);
if (!biome) {
fail_count++;
- errorstream << "get_biome_list: failed to get biome '"
+ infostream << "get_biome_list: failed to get biome '"
<< (lua_isstring(L, -1) ? lua_tostring(L, -1) : "")
<< "'" << std::endl;
continue;
@@ -927,7 +935,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
//// Get biomes associated with this decoration (if any)
lua_getfield(L, index, "biomes");
if (get_biome_list(L, -1, biomemgr, &deco->biomes))
- errorstream << "register_decoration: couldn't get all biomes " << std::endl;
+ infostream << "register_decoration: couldn't get all biomes " << std::endl;
lua_pop(L, 1);
//// Get node name(s) to 'spawn by'
@@ -1092,7 +1100,7 @@ int ModApiMapgen::l_register_ore(lua_State *L)
//// Get biomes associated with this decoration (if any)
lua_getfield(L, index, "biomes");
if (get_biome_list(L, -1, bmgr, &ore->biomes))
- errorstream << "register_ore: couldn't get all biomes " << std::endl;
+ infostream << "register_ore: couldn't get all biomes " << std::endl;
lua_pop(L, 1);
//// Get noise parameters if needed
@@ -1357,7 +1365,9 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
{
MAP_LOCK_REQUIRED;
- Map *map = &(getEnv(L)->getMap());
+ GET_ENV_PTR;
+
+ ServerMap *map = &(env->getServerMap());
SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
//// Read position
diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h
index bb94575c7..a26c8b950 100644
--- a/src/script/lua_api/l_mapgen.h
+++ b/src/script/lua_api/l_mapgen.h
@@ -22,7 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_base.h"
-class ModApiMapgen : public ModApiBase {
+class ModApiMapgen : public ModApiBase
+{
private:
// get_biome_id(biomename)
// returns the biome id used in biomemap
diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp
new file mode 100644
index 000000000..5f4e984cb
--- /dev/null
+++ b/src/script/lua_api/l_metadata.cpp
@@ -0,0 +1,266 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_metadata.h"
+#include "lua_api/l_internal.h"
+#include "common/c_content.h"
+#include "serverenvironment.h"
+#include "map.h"
+#include "server.h"
+
+// LUALIB_API
+void *luaL_checkudata_is_metadataref(lua_State *L, int ud) {
+ void *p = lua_touserdata(L, ud);
+ if (p != NULL && // value is a userdata?
+ lua_getmetatable(L, ud)) { // does it have a metatable?
+ lua_getfield(L, -1, "metadata_class");
+ if (lua_type(L, -1) == LUA_TSTRING) { // does it have a metadata_class field?
+ return p;
+ }
+ }
+ luaL_typerror(L, ud, "MetaDataRef");
+ return NULL;
+}
+
+MetaDataRef* MetaDataRef::checkobject(lua_State *L, int narg)
+{
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+ void *ud = luaL_checkudata_is_metadataref(L, narg);
+ if (!ud)
+ luaL_typerror(L, narg, "MetaDataRef");
+
+ return *(MetaDataRef**)ud; // unbox pointer
+}
+
+// Exported functions
+
+// get_string(self, name)
+int MetaDataRef::l_get_string(lua_State *L)
+{
+ MAP_LOCK_REQUIRED;
+
+ MetaDataRef *ref = checkobject(L, 1);
+ std::string name = luaL_checkstring(L, 2);
+
+ Metadata *meta = ref->getmeta(false);
+ if (meta == NULL) {
+ lua_pushlstring(L, "", 0);
+ return 1;
+ }
+
+ const std::string &str = meta->getString(name);
+ lua_pushlstring(L, str.c_str(), str.size());
+ return 1;
+}
+
+// set_string(self, name, var)
+int MetaDataRef::l_set_string(lua_State *L)
+{
+ MAP_LOCK_REQUIRED;
+
+ MetaDataRef *ref = checkobject(L, 1);
+ std::string name = luaL_checkstring(L, 2);
+ size_t len = 0;
+ const char *s = lua_tolstring(L, 3, &len);
+ std::string str(s, len);
+
+ Metadata *meta = ref->getmeta(!str.empty());
+ if (meta == NULL || str == meta->getString(name))
+ return 0;
+
+ meta->setString(name, str);
+ ref->reportMetadataChange();
+ return 0;
+}
+
+// get_int(self, name)
+int MetaDataRef::l_get_int(lua_State *L)
+{
+ MAP_LOCK_REQUIRED;
+
+ MetaDataRef *ref = checkobject(L, 1);
+ std::string name = lua_tostring(L, 2);
+
+ Metadata *meta = ref->getmeta(false);
+ if (meta == NULL) {
+ lua_pushnumber(L, 0);
+ return 1;
+ }
+
+ const std::string &str = meta->getString(name);
+ lua_pushnumber(L, stoi(str));
+ return 1;
+}
+
+// set_int(self, name, var)
+int MetaDataRef::l_set_int(lua_State *L)
+{
+ MAP_LOCK_REQUIRED;
+
+ MetaDataRef *ref = checkobject(L, 1);
+ std::string name = lua_tostring(L, 2);
+ int a = lua_tointeger(L, 3);
+ std::string str = itos(a);
+
+ Metadata *meta = ref->getmeta(true);
+ if (meta == NULL || str == meta->getString(name))
+ return 0;
+
+ meta->setString(name, str);
+ ref->reportMetadataChange();
+ return 0;
+}
+
+// get_float(self, name)
+int MetaDataRef::l_get_float(lua_State *L)
+{
+ MAP_LOCK_REQUIRED;
+
+ MetaDataRef *ref = checkobject(L, 1);
+ std::string name = lua_tostring(L, 2);
+
+ Metadata *meta = ref->getmeta(false);
+ if (meta == NULL) {
+ lua_pushnumber(L, 0);
+ return 1;
+ }
+
+ const std::string &str = meta->getString(name);
+ lua_pushnumber(L, stof(str));
+ return 1;
+}
+
+// set_float(self, name, var)
+int MetaDataRef::l_set_float(lua_State *L)
+{
+ MAP_LOCK_REQUIRED;
+
+ MetaDataRef *ref = checkobject(L, 1);
+ std::string name = lua_tostring(L, 2);
+ float a = lua_tonumber(L, 3);
+ std::string str = ftos(a);
+
+ Metadata *meta = ref->getmeta(true);
+ if (meta == NULL || str == meta->getString(name))
+ return 0;
+
+ meta->setString(name, str);
+ ref->reportMetadataChange();
+ return 0;
+}
+
+// to_table(self)
+int MetaDataRef::l_to_table(lua_State *L)
+{
+ MAP_LOCK_REQUIRED;
+
+ MetaDataRef *ref = checkobject(L, 1);
+
+ Metadata *meta = ref->getmeta(true);
+ if (meta == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+ lua_newtable(L);
+
+ ref->handleToTable(L, meta);
+
+ return 1;
+}
+
+// from_table(self, table)
+int MetaDataRef::l_from_table(lua_State *L)
+{
+ MAP_LOCK_REQUIRED;
+
+ MetaDataRef *ref = checkobject(L, 1);
+ int base = 2;
+
+ ref->clearMeta();
+
+ if (!lua_istable(L, base)) {
+ // No metadata
+ lua_pushboolean(L, true);
+ return 1;
+ }
+
+ // Create new metadata
+ Metadata *meta = ref->getmeta(true);
+ if (meta == NULL) {
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ bool was_successful = ref->handleFromTable(L, base, meta);
+ ref->reportMetadataChange();
+ lua_pushboolean(L, was_successful);
+ return 1;
+}
+
+void MetaDataRef::handleToTable(lua_State *L, Metadata *meta)
+{
+ lua_newtable(L);
+ {
+ const StringMap &fields = meta->getStrings();
+ for (StringMap::const_iterator
+ it = fields.begin(); it != fields.end(); ++it) {
+ const std::string &name = it->first;
+ const std::string &value = it->second;
+ lua_pushlstring(L, name.c_str(), name.size());
+ lua_pushlstring(L, value.c_str(), value.size());
+ lua_settable(L, -3);
+ }
+ }
+ lua_setfield(L, -2, "fields");
+}
+
+bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta)
+{
+ // Set fields
+ lua_getfield(L, table, "fields");
+ if (lua_istable(L, -1)) {
+ int fieldstable = lua_gettop(L);
+ lua_pushnil(L);
+ while (lua_next(L, fieldstable) != 0) {
+ // key at index -2 and value at index -1
+ std::string name = lua_tostring(L, -2);
+ size_t cl;
+ const char *cs = lua_tolstring(L, -1, &cl);
+ meta->setString(name, std::string(cs, cl));
+ lua_pop(L, 1); // Remove value, keep key for next iteration
+ }
+ lua_pop(L, 1);
+ }
+
+ return true;
+}
+
+// equals(self, other)
+int MetaDataRef::l_equals(lua_State *L)
+{
+ MetaDataRef *ref1 = checkobject(L, 1);
+ Metadata *data1 = ref1->getmeta(false);
+ MetaDataRef *ref2 = checkobject(L, 2);
+ Metadata *data2 = ref2->getmeta(false);
+ if (data1 == NULL || data2 == NULL)
+ lua_pushboolean(L, data1 == data2);
+ else
+ lua_pushboolean(L, *data1 == *data2);
+ return 1;
+}
diff --git a/src/script/lua_api/l_metadata.h b/src/script/lua_api/l_metadata.h
new file mode 100644
index 000000000..a4d8214d3
--- /dev/null
+++ b/src/script/lua_api/l_metadata.h
@@ -0,0 +1,75 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#ifndef L_METADATA_H_
+#define L_METADATA_H_
+
+#include "irrlichttypes_bloated.h"
+#include "lua_api/l_base.h"
+
+class Metadata;
+
+/*
+ NodeMetaRef
+*/
+
+class MetaDataRef : public ModApiBase
+{
+public:
+ virtual ~MetaDataRef() {}
+protected:
+ static MetaDataRef *checkobject(lua_State *L, int narg);
+
+ virtual void reportMetadataChange() {}
+ virtual Metadata *getmeta(bool auto_create) = 0;
+ virtual void clearMeta() = 0;
+
+ virtual void handleToTable(lua_State *L, Metadata *meta);
+ virtual bool handleFromTable(lua_State *L, int table, Metadata *meta);
+
+ // Exported functions
+
+ // get_string(self, name)
+ static int l_get_string(lua_State *L);
+
+ // set_string(self, name, var)
+ static int l_set_string(lua_State *L);
+
+ // get_int(self, name)
+ static int l_get_int(lua_State *L);
+
+ // set_int(self, name, var)
+ static int l_set_int(lua_State *L);
+
+ // get_float(self, name)
+ static int l_get_float(lua_State *L);
+
+ // set_float(self, name, var)
+ static int l_set_float(lua_State *L);
+
+ // to_table(self)
+ static int l_to_table(lua_State *L);
+
+ // from_table(self, table)
+ static int l_from_table(lua_State *L);
+
+ // equals(self, other)
+ static int l_equals(lua_State *L);
+};
+
+#endif /* L_NODEMETA_H_ */
diff --git a/src/script/lua_api/l_minimap.cpp b/src/script/lua_api/l_minimap.cpp
new file mode 100644
index 000000000..afb3766fb
--- /dev/null
+++ b/src/script/lua_api/l_minimap.cpp
@@ -0,0 +1,227 @@
+/*
+Minetest
+Copyright (C) 2017 Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+
+#include "lua_api/l_minimap.h"
+#include "lua_api/l_internal.h"
+#include "common/c_converter.h"
+#include "minimap.h"
+#include "settings.h"
+
+LuaMinimap::LuaMinimap(Minimap *m)
+{
+ m_minimap = m;
+}
+
+void LuaMinimap::create(lua_State *L, Minimap *m)
+{
+ LuaMinimap *o = new LuaMinimap(m);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+
+ // Keep minimap object stack id
+ int minimap_object = lua_gettop(L);
+
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "ui");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ int uitable = lua_gettop(L);
+
+ lua_pushvalue(L, minimap_object); // Copy object to top of stack
+ lua_setfield(L, uitable, "minimap");
+}
+
+int LuaMinimap::l_get_pos(lua_State *L)
+{
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ push_v3s16(L, m->getPos());
+ return 1;
+}
+
+int LuaMinimap::l_set_pos(lua_State *L)
+{
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ m->setPos(read_v3s16(L, 2));
+ return 1;
+}
+
+int LuaMinimap::l_get_angle(lua_State *L)
+{
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ lua_pushinteger(L, m->getAngle());
+ return 1;
+}
+
+int LuaMinimap::l_set_angle(lua_State *L)
+{
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ m->setAngle(lua_tointeger(L, 2));
+ return 1;
+}
+
+int LuaMinimap::l_get_mode(lua_State *L)
+{
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ lua_pushinteger(L, m->getMinimapMode());
+ return 1;
+}
+
+int LuaMinimap::l_set_mode(lua_State *L)
+{
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ s32 mode = lua_tointeger(L, 2);
+ if (mode < MINIMAP_MODE_OFF ||
+ mode >= MINIMAP_MODE_COUNT) {
+ return 0;
+ }
+
+ m->setMinimapMode((MinimapMode) mode);
+ return 1;
+}
+
+int LuaMinimap::l_set_shape(lua_State *L)
+{
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+ if (!lua_isnumber(L, 2))
+ return 0;
+
+ m->setMinimapShape((MinimapShape)((int)lua_tonumber(L, 2)));
+ return 0;
+}
+
+int LuaMinimap::l_get_shape(lua_State *L)
+{
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ lua_pushnumber(L, (int)m->getMinimapShape());
+ return 1;
+}
+
+int LuaMinimap::l_show(lua_State *L)
+{
+ // If minimap is disabled by config, don't show it.
+ if (!g_settings->getBool("enable_minimap"))
+ return 1;
+
+ Client *client = getClient(L);
+ assert(client);
+
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ if (m->getMinimapMode() == MINIMAP_MODE_OFF)
+ m->setMinimapMode(MINIMAP_MODE_SURFACEx1);
+
+ client->showMinimap(true);
+ return 1;
+}
+
+int LuaMinimap::l_hide(lua_State *L)
+{
+ Client *client = getClient(L);
+ assert(client);
+
+ LuaMinimap *ref = checkobject(L, 1);
+ Minimap *m = getobject(ref);
+
+ if (m->getMinimapMode() != MINIMAP_MODE_OFF)
+ m->setMinimapMode(MINIMAP_MODE_OFF);
+
+ client->showMinimap(false);
+ return 1;
+}
+
+LuaMinimap *LuaMinimap::checkobject(lua_State *L, int narg)
+{
+ NO_MAP_LOCK_REQUIRED;
+
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+
+ void *ud = luaL_checkudata(L, narg, className);
+ if (!ud)
+ luaL_typerror(L, narg, className);
+
+ return *(LuaMinimap **)ud; // unbox pointer
+}
+
+Minimap* LuaMinimap::getobject(LuaMinimap *ref)
+{
+ return ref->m_minimap;
+}
+
+int LuaMinimap::gc_object(lua_State *L) {
+ LuaMinimap *o = *(LuaMinimap **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+void LuaMinimap::Register(lua_State *L)
+{
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1); // drop metatable
+
+ luaL_openlib(L, 0, methods, 0); // fill methodtable
+ lua_pop(L, 1); // drop methodtable
+}
+
+const char LuaMinimap::className[] = "Minimap";
+const luaL_Reg LuaMinimap::methods[] = {
+ luamethod(LuaMinimap, show),
+ luamethod(LuaMinimap, hide),
+ luamethod(LuaMinimap, get_pos),
+ luamethod(LuaMinimap, set_pos),
+ luamethod(LuaMinimap, get_angle),
+ luamethod(LuaMinimap, set_angle),
+ luamethod(LuaMinimap, get_mode),
+ luamethod(LuaMinimap, set_mode),
+ luamethod(LuaMinimap, set_shape),
+ luamethod(LuaMinimap, get_shape),
+ {0,0}
+};
diff --git a/src/script/lua_api/l_minimap.h b/src/script/lua_api/l_minimap.h
new file mode 100644
index 000000000..ba702b0b1
--- /dev/null
+++ b/src/script/lua_api/l_minimap.h
@@ -0,0 +1,65 @@
+/*
+Minetest
+Copyright (C) 2017 Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_MINIMAP_H_
+#define L_MINIMAP_H_
+
+#include "l_base.h"
+
+class Minimap;
+
+class LuaMinimap : public ModApiBase
+{
+private:
+ static const char className[];
+ static const luaL_Reg methods[];
+
+ // garbage collector
+ static int gc_object(lua_State *L);
+
+ static int l_get_pos(lua_State *L);
+ static int l_set_pos(lua_State *L);
+
+ static int l_get_angle(lua_State *L);
+ static int l_set_angle(lua_State *L);
+
+ static int l_get_mode(lua_State *L);
+ static int l_set_mode(lua_State *L);
+
+ static int l_show(lua_State *L);
+ static int l_hide(lua_State *L);
+
+ static int l_set_shape(lua_State *L);
+ static int l_get_shape(lua_State *L);
+
+ Minimap *m_minimap;
+
+public:
+ LuaMinimap(Minimap *m);
+ ~LuaMinimap() {}
+
+ static void create(lua_State *L, Minimap *object);
+
+ static LuaMinimap *checkobject(lua_State *L, int narg);
+ static Minimap *getobject(LuaMinimap *ref);
+
+ static void Register(lua_State *L);
+};
+
+#endif // L_MINIMAP_H_
diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp
index c8bc7d558..5dfa6d52e 100644
--- a/src/script/lua_api/l_nodemeta.cpp
+++ b/src/script/lua_api/l_nodemeta.cpp
@@ -20,14 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_nodemeta.h"
#include "lua_api/l_internal.h"
#include "lua_api/l_inventory.h"
-#include "common/c_converter.h"
#include "common/c_content.h"
-#include "environment.h"
+#include "serverenvironment.h"
#include "map.h"
-#include "gamedef.h"
-#include "nodemetadata.h"
-
-
+#include "server.h"
/*
NodeMetaRef
@@ -40,12 +36,15 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg)
return *(NodeMetaRef**)ud; // unbox pointer
}
-NodeMetadata* NodeMetaRef::getmeta(NodeMetaRef *ref, bool auto_create)
+Metadata* NodeMetaRef::getmeta(bool auto_create)
{
- NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
- if(meta == NULL && auto_create) {
- meta = new NodeMetadata(ref->m_env->getGameDef()->idef());
- if(!ref->m_env->getMap().setNodeMetadata(ref->m_p, meta)) {
+ if (m_is_local)
+ return m_meta;
+
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p);
+ if (meta == NULL && auto_create) {
+ meta = new NodeMetadata(m_env->getGameDef()->idef());
+ if (!m_env->getMap().setNodeMetadata(m_p, meta)) {
delete meta;
return NULL;
}
@@ -53,17 +52,22 @@ NodeMetadata* NodeMetaRef::getmeta(NodeMetaRef *ref, bool auto_create)
return meta;
}
-void NodeMetaRef::reportMetadataChange(NodeMetaRef *ref)
+void NodeMetaRef::clearMeta()
+{
+ m_env->getMap().removeNodeMetadata(m_p);
+}
+
+void NodeMetaRef::reportMetadataChange()
{
// NOTE: This same code is in rollback_interface.cpp
// Inform other things that the metadata has changed
- v3s16 blockpos = getNodeBlockPos(ref->m_p);
+ v3s16 blockpos = getNodeBlockPos(m_p);
MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
event.p = blockpos;
- ref->m_env->getMap().dispatchEvent(&event);
+ m_env->getMap().dispatchEvent(&event);
// Set the block to be saved
- MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
+ MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
if (block) {
block->raiseModified(MOD_STATE_WRITE_NEEDED,
MOD_REASON_REPORT_META_CHANGE);
@@ -79,154 +83,49 @@ int NodeMetaRef::gc_object(lua_State *L) {
return 0;
}
-// get_string(self, name)
-int NodeMetaRef::l_get_string(lua_State *L)
-{
- MAP_LOCK_REQUIRED;
-
- NodeMetaRef *ref = checkobject(L, 1);
- std::string name = luaL_checkstring(L, 2);
-
- NodeMetadata *meta = getmeta(ref, false);
- if(meta == NULL){
- lua_pushlstring(L, "", 0);
- return 1;
- }
- std::string str = meta->getString(name);
- lua_pushlstring(L, str.c_str(), str.size());
- return 1;
-}
-
-// set_string(self, name, var)
-int NodeMetaRef::l_set_string(lua_State *L)
-{
- MAP_LOCK_REQUIRED;
-
- NodeMetaRef *ref = checkobject(L, 1);
- std::string name = luaL_checkstring(L, 2);
- size_t len = 0;
- const char *s = lua_tolstring(L, 3, &len);
- std::string str(s, len);
-
- NodeMetadata *meta = getmeta(ref, !str.empty());
- if(meta == NULL || str == meta->getString(name))
- return 0;
- meta->setString(name, str);
- reportMetadataChange(ref);
- return 0;
-}
-
-// get_int(self, name)
-int NodeMetaRef::l_get_int(lua_State *L)
-{
- MAP_LOCK_REQUIRED;
-
- NodeMetaRef *ref = checkobject(L, 1);
- std::string name = lua_tostring(L, 2);
-
- NodeMetadata *meta = getmeta(ref, false);
- if(meta == NULL){
- lua_pushnumber(L, 0);
- return 1;
- }
- std::string str = meta->getString(name);
- lua_pushnumber(L, stoi(str));
- return 1;
-}
-
-// set_int(self, name, var)
-int NodeMetaRef::l_set_int(lua_State *L)
-{
- MAP_LOCK_REQUIRED;
-
- NodeMetaRef *ref = checkobject(L, 1);
- std::string name = lua_tostring(L, 2);
- int a = lua_tointeger(L, 3);
- std::string str = itos(a);
-
- NodeMetadata *meta = getmeta(ref, true);
- if(meta == NULL || str == meta->getString(name))
- return 0;
- meta->setString(name, str);
- reportMetadataChange(ref);
- return 0;
-}
-
-// get_float(self, name)
-int NodeMetaRef::l_get_float(lua_State *L)
-{
- MAP_LOCK_REQUIRED;
-
- NodeMetaRef *ref = checkobject(L, 1);
- std::string name = lua_tostring(L, 2);
-
- NodeMetadata *meta = getmeta(ref, false);
- if(meta == NULL){
- lua_pushnumber(L, 0);
- return 1;
- }
- std::string str = meta->getString(name);
- lua_pushnumber(L, stof(str));
- return 1;
-}
-
-// set_float(self, name, var)
-int NodeMetaRef::l_set_float(lua_State *L)
-{
- MAP_LOCK_REQUIRED;
-
- NodeMetaRef *ref = checkobject(L, 1);
- std::string name = lua_tostring(L, 2);
- float a = lua_tonumber(L, 3);
- std::string str = ftos(a);
-
- NodeMetadata *meta = getmeta(ref, true);
- if(meta == NULL || str == meta->getString(name))
- return 0;
- meta->setString(name, str);
- reportMetadataChange(ref);
- return 0;
-}
-
// get_inventory(self)
int NodeMetaRef::l_get_inventory(lua_State *L)
{
MAP_LOCK_REQUIRED;
NodeMetaRef *ref = checkobject(L, 1);
- getmeta(ref, true); // try to ensure the metadata exists
+ ref->getmeta(true); // try to ensure the metadata exists
InvRef::createNodeMeta(L, ref->m_p);
return 1;
}
-// to_table(self)
-int NodeMetaRef::l_to_table(lua_State *L)
+// mark_as_private(self, <string> or {<string>, <string>, ...})
+int NodeMetaRef::l_mark_as_private(lua_State *L)
{
MAP_LOCK_REQUIRED;
NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = dynamic_cast<NodeMetadata*>(ref->getmeta(true));
+ assert(meta);
- NodeMetadata *meta = getmeta(ref, true);
- if (meta == NULL) {
+ if (lua_istable(L, 2)) {
lua_pushnil(L);
- return 1;
+ while (lua_next(L, 2) != 0) {
+ // key at index -2 and value at index -1
+ luaL_checktype(L, -1, LUA_TSTRING);
+ meta->markPrivate(lua_tostring(L, -1), true);
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+ } else if (lua_isstring(L, 2)) {
+ meta->markPrivate(lua_tostring(L, 2), true);
}
- lua_newtable(L);
+ ref->reportMetadataChange();
+ return 0;
+}
+
+void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta)
+{
// fields
- lua_newtable(L);
- {
- StringMap fields = meta->getStrings();
- for (StringMap::const_iterator
- it = fields.begin(); it != fields.end(); ++it) {
- const std::string &name = it->first;
- const std::string &value = it->second;
- lua_pushlstring(L, name.c_str(), name.size());
- lua_pushlstring(L, value.c_str(), value.size());
- lua_settable(L, -3);
- }
- }
- lua_setfield(L, -2, "fields");
+ MetaDataRef::handleToTable(L, _meta);
+
+ NodeMetadata *meta = (NodeMetadata*) _meta;
// inventory
lua_newtable(L);
@@ -234,71 +133,52 @@ int NodeMetaRef::l_to_table(lua_State *L)
if (inv) {
std::vector<const InventoryList *> lists = inv->getLists();
for(std::vector<const InventoryList *>::const_iterator
- i = lists.begin(); i != lists.end(); i++) {
+ i = lists.begin(); i != lists.end(); ++i) {
push_inventory_list(L, inv, (*i)->getName().c_str());
lua_setfield(L, -2, (*i)->getName().c_str());
}
}
lua_setfield(L, -2, "inventory");
- return 1;
}
// from_table(self, table)
-int NodeMetaRef::l_from_table(lua_State *L)
+bool NodeMetaRef::handleFromTable(lua_State *L, int table, Metadata *_meta)
{
- MAP_LOCK_REQUIRED;
-
- NodeMetaRef *ref = checkobject(L, 1);
- int base = 2;
-
- // clear old metadata first
- ref->m_env->getMap().removeNodeMetadata(ref->m_p);
+ // fields
+ if (!MetaDataRef::handleFromTable(L, table, _meta))
+ return false;
- if(lua_isnil(L, base)){
- // No metadata
- lua_pushboolean(L, true);
- return 1;
- }
+ NodeMetadata *meta = (NodeMetadata*) _meta;
- // Create new metadata
- NodeMetadata *meta = getmeta(ref, true);
- if(meta == NULL){
- lua_pushboolean(L, false);
- return 1;
- }
- // Set fields
- lua_getfield(L, base, "fields");
- int fieldstable = lua_gettop(L);
- lua_pushnil(L);
- while(lua_next(L, fieldstable) != 0){
- // key at index -2 and value at index -1
- std::string name = lua_tostring(L, -2);
- size_t cl;
- const char *cs = lua_tolstring(L, -1, &cl);
- std::string value(cs, cl);
- meta->setString(name, value);
- lua_pop(L, 1); // removes value, keeps key for next iteration
- }
- // Set inventory
+ // inventory
Inventory *inv = meta->getInventory();
- lua_getfield(L, base, "inventory");
- int inventorytable = lua_gettop(L);
- lua_pushnil(L);
- while(lua_next(L, inventorytable) != 0){
- // key at index -2 and value at index -1
- std::string name = lua_tostring(L, -2);
- read_inventory_list(L, -1, inv, name.c_str(), getServer(L));
- lua_pop(L, 1); // removes value, keeps key for next iteration
+ lua_getfield(L, table, "inventory");
+ if (lua_istable(L, -1)) {
+ int inventorytable = lua_gettop(L);
+ lua_pushnil(L);
+ while (lua_next(L, inventorytable) != 0) {
+ // key at index -2 and value at index -1
+ std::string name = lua_tostring(L, -2);
+ read_inventory_list(L, -1, inv, name.c_str(), getServer(L));
+ lua_pop(L, 1); // Remove value, keep key for next iteration
+ }
+ lua_pop(L, 1);
}
- reportMetadataChange(ref);
- lua_pushboolean(L, true);
- return 1;
+
+ return true;
}
NodeMetaRef::NodeMetaRef(v3s16 p, ServerEnvironment *env):
m_p(p),
- m_env(env)
+ m_env(env),
+ m_is_local(false)
+{
+}
+
+NodeMetaRef::NodeMetaRef(Metadata *meta):
+ m_meta(meta),
+ m_is_local(true)
{
}
@@ -317,7 +197,17 @@ void NodeMetaRef::create(lua_State *L, v3s16 p, ServerEnvironment *env)
lua_setmetatable(L, -2);
}
-void NodeMetaRef::Register(lua_State *L)
+// Client-sided version of the above
+void NodeMetaRef::createClient(lua_State *L, Metadata *meta)
+{
+ NodeMetaRef *o = new NodeMetaRef(meta);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+}
+
+const char NodeMetaRef::className[] = "NodeMetaRef";
+void NodeMetaRef::RegisterCommon(lua_State *L)
{
lua_newtable(L);
int methodtable = lua_gettop(L);
@@ -328,6 +218,10 @@ void NodeMetaRef::Register(lua_State *L)
lua_pushvalue(L, methodtable);
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+ lua_pushliteral(L, "metadata_class");
+ lua_pushlstring(L, className, strlen(className));
+ lua_settable(L, metatable);
+
lua_pushliteral(L, "__index");
lua_pushvalue(L, methodtable);
lua_settable(L, metatable);
@@ -336,25 +230,49 @@ void NodeMetaRef::Register(lua_State *L)
lua_pushcfunction(L, gc_object);
lua_settable(L, metatable);
+ lua_pushliteral(L, "__eq");
+ lua_pushcfunction(L, l_equals);
+ lua_settable(L, metatable);
+
lua_pop(L, 1); // drop metatable
+}
- luaL_openlib(L, 0, methods, 0); // fill methodtable
+void NodeMetaRef::Register(lua_State *L)
+{
+ RegisterCommon(L);
+ luaL_openlib(L, 0, methodsServer, 0); // fill methodtable
lua_pop(L, 1); // drop methodtable
-
- // Cannot be created from Lua
- //lua_register(L, className, create_object);
}
-const char NodeMetaRef::className[] = "NodeMetaRef";
-const luaL_reg NodeMetaRef::methods[] = {
- luamethod(NodeMetaRef, get_string),
- luamethod(NodeMetaRef, set_string),
- luamethod(NodeMetaRef, get_int),
- luamethod(NodeMetaRef, set_int),
- luamethod(NodeMetaRef, get_float),
- luamethod(NodeMetaRef, set_float),
+
+const luaL_Reg NodeMetaRef::methodsServer[] = {
+ luamethod(MetaDataRef, get_string),
+ luamethod(MetaDataRef, set_string),
+ luamethod(MetaDataRef, get_int),
+ luamethod(MetaDataRef, set_int),
+ luamethod(MetaDataRef, get_float),
+ luamethod(MetaDataRef, set_float),
+ luamethod(MetaDataRef, to_table),
+ luamethod(MetaDataRef, from_table),
luamethod(NodeMetaRef, get_inventory),
- luamethod(NodeMetaRef, to_table),
- luamethod(NodeMetaRef, from_table),
+ luamethod(NodeMetaRef, mark_as_private),
+ luamethod(MetaDataRef, equals),
+ {0,0}
+};
+
+
+void NodeMetaRef::RegisterClient(lua_State *L)
+{
+ RegisterCommon(L);
+ luaL_openlib(L, 0, methodsClient, 0); // fill methodtable
+ lua_pop(L, 1); // drop methodtable
+}
+
+
+const luaL_Reg NodeMetaRef::methodsClient[] = {
+ luamethod(MetaDataRef, get_string),
+ luamethod(MetaDataRef, get_int),
+ luamethod(MetaDataRef, get_float),
+ luamethod(MetaDataRef, to_table),
{0,0}
};
diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h
index e39ac3931..dd4260ff9 100644
--- a/src/script/lua_api/l_nodemeta.h
+++ b/src/script/lua_api/l_nodemeta.h
@@ -20,7 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define L_NODEMETA_H_
#include "lua_api/l_base.h"
+#include "lua_api/l_metadata.h"
#include "irrlichttypes_bloated.h"
+#include "nodemetadata.h"
class ServerEnvironment;
class NodeMetadata;
@@ -29,13 +31,16 @@ class NodeMetadata;
NodeMetaRef
*/
-class NodeMetaRef : public ModApiBase {
+class NodeMetaRef : public MetaDataRef {
private:
v3s16 m_p;
ServerEnvironment *m_env;
+ Metadata *m_meta;
+ bool m_is_local;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methodsServer[];
+ static const luaL_Reg methodsClient[];
static NodeMetaRef *checkobject(lua_State *L, int narg);
@@ -52,44 +57,28 @@ private:
* @param auto_create when true, try to create metadata information for the node if it has none.
* @return pointer to a @c NodeMetadata object or @c NULL in case of error.
*/
- static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create);
+ virtual Metadata* getmeta(bool auto_create);
+ virtual void clearMeta();
- static void reportMetadataChange(NodeMetaRef *ref);
+ virtual void reportMetadataChange();
+
+ virtual void handleToTable(lua_State *L, Metadata *_meta);
+ virtual bool handleFromTable(lua_State *L, int table, Metadata *_meta);
// Exported functions
// garbage collector
static int gc_object(lua_State *L);
- // get_string(self, name)
- static int l_get_string(lua_State *L);
-
- // set_string(self, name, var)
- static int l_set_string(lua_State *L);
-
- // get_int(self, name)
- static int l_get_int(lua_State *L);
-
- // set_int(self, name, var)
- static int l_set_int(lua_State *L);
-
- // get_float(self, name)
- static int l_get_float(lua_State *L);
-
- // set_float(self, name, var)
- static int l_set_float(lua_State *L);
-
// get_inventory(self)
static int l_get_inventory(lua_State *L);
- // to_table(self)
- static int l_to_table(lua_State *L);
-
- // from_table(self, table)
- static int l_from_table(lua_State *L);
+ // mark_as_private(self, <string> or {<string>, <string>, ...})
+ static int l_mark_as_private(lua_State *L);
public:
NodeMetaRef(v3s16 p, ServerEnvironment *env);
+ NodeMetaRef(Metadata *meta);
~NodeMetaRef();
@@ -97,7 +86,12 @@ public:
// Not callable from Lua; all references are created on the C side.
static void create(lua_State *L, v3s16 p, ServerEnvironment *env);
+ // Client-sided version of the above
+ static void createClient(lua_State *L, Metadata *meta);
+
+ static void RegisterCommon(lua_State *L);
static void Register(lua_State *L);
+ static void RegisterClient(lua_State *L);
};
#endif /* L_NODEMETA_H_ */
diff --git a/src/script/lua_api/l_nodetimer.cpp b/src/script/lua_api/l_nodetimer.cpp
index 3242d6ea5..17b275c46 100644
--- a/src/script/lua_api/l_nodetimer.cpp
+++ b/src/script/lua_api/l_nodetimer.cpp
@@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_nodetimer.h"
#include "lua_api/l_internal.h"
-#include "environment.h"
+#include "serverenvironment.h"
#include "map.h"
@@ -162,7 +162,7 @@ void NodeTimerRef::Register(lua_State *L)
}
const char NodeTimerRef::className[] = "NodeTimerRef";
-const luaL_reg NodeTimerRef::methods[] = {
+const luaL_Reg NodeTimerRef::methods[] = {
luamethod(NodeTimerRef, start),
luamethod(NodeTimerRef, set),
luamethod(NodeTimerRef, stop),
diff --git a/src/script/lua_api/l_nodetimer.h b/src/script/lua_api/l_nodetimer.h
index 9f8dd21c8..ae362d8b3 100644
--- a/src/script/lua_api/l_nodetimer.h
+++ b/src/script/lua_api/l_nodetimer.h
@@ -20,18 +20,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef L_NODETIMER_H_
#define L_NODETIMER_H_
-#include "lua_api/l_base.h"
#include "irr_v3d.h"
+#include "lua_api/l_base.h"
class ServerEnvironment;
-class NodeTimerRef : public ModApiBase {
+class NodeTimerRef : public ModApiBase
+{
private:
v3s16 m_p;
ServerEnvironment *m_env;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
static int gc_object(lua_State *L);
@@ -62,6 +63,4 @@ public:
static void Register(lua_State *L);
};
-
-
#endif /* L_NODETIMER_H_ */
diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp
index e0039371f..e3e76191f 100644
--- a/src/script/lua_api/l_noise.cpp
+++ b/src/script/lua_api/l_noise.cpp
@@ -135,7 +135,7 @@ void LuaPerlinNoise::Register(lua_State *L)
const char LuaPerlinNoise::className[] = "PerlinNoise";
-const luaL_reg LuaPerlinNoise::methods[] = {
+const luaL_Reg LuaPerlinNoise::methods[] = {
luamethod(LuaPerlinNoise, get2d),
luamethod(LuaPerlinNoise, get3d),
{0,0}
@@ -393,7 +393,7 @@ void LuaPerlinNoiseMap::Register(lua_State *L)
const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap";
-const luaL_reg LuaPerlinNoiseMap::methods[] = {
+const luaL_Reg LuaPerlinNoiseMap::methods[] = {
luamethod(LuaPerlinNoiseMap, get2dMap),
luamethod(LuaPerlinNoiseMap, get2dMap_flat),
luamethod(LuaPerlinNoiseMap, calc2dMap),
@@ -498,7 +498,7 @@ void LuaPseudoRandom::Register(lua_State *L)
const char LuaPseudoRandom::className[] = "PseudoRandom";
-const luaL_reg LuaPseudoRandom::methods[] = {
+const luaL_Reg LuaPseudoRandom::methods[] = {
luamethod(LuaPseudoRandom, next),
{0,0}
};
@@ -597,7 +597,7 @@ void LuaPcgRandom::Register(lua_State *L)
const char LuaPcgRandom::className[] = "PcgRandom";
-const luaL_reg LuaPcgRandom::methods[] = {
+const luaL_Reg LuaPcgRandom::methods[] = {
luamethod(LuaPcgRandom, next),
luamethod(LuaPcgRandom, rand_normal_dist),
{0,0}
@@ -711,7 +711,7 @@ void LuaSecureRandom::Register(lua_State *L)
}
const char LuaSecureRandom::className[] = "SecureRandom";
-const luaL_reg LuaSecureRandom::methods[] = {
+const luaL_Reg LuaSecureRandom::methods[] = {
luamethod(LuaSecureRandom, next_bytes),
{0,0}
};
diff --git a/src/script/lua_api/l_noise.h b/src/script/lua_api/l_noise.h
index 40bfd1315..f252b5ba2 100644
--- a/src/script/lua_api/l_noise.h
+++ b/src/script/lua_api/l_noise.h
@@ -20,18 +20,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef L_NOISE_H_
#define L_NOISE_H_
-#include "lua_api/l_base.h"
#include "irr_v3d.h"
+#include "lua_api/l_base.h"
#include "noise.h"
/*
LuaPerlinNoise
*/
-class LuaPerlinNoise : public ModApiBase {
+class LuaPerlinNoise : public ModApiBase
+{
private:
NoiseParams np;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
// Exported functions
@@ -57,12 +58,13 @@ public:
/*
LuaPerlinNoiseMap
*/
-class LuaPerlinNoiseMap : public ModApiBase {
+class LuaPerlinNoiseMap : public ModApiBase
+{
NoiseParams np;
Noise *noise;
bool m_is3d;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
// Exported functions
@@ -95,12 +97,13 @@ public:
/*
LuaPseudoRandom
*/
-class LuaPseudoRandom : public ModApiBase {
+class LuaPseudoRandom : public ModApiBase
+{
private:
PseudoRandom m_pseudo;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
// Exported functions
@@ -111,8 +114,7 @@ private:
static int l_next(lua_State *L);
public:
- LuaPseudoRandom(s32 seed) :
- m_pseudo(seed) {}
+ LuaPseudoRandom(s32 seed) : m_pseudo(seed) {}
// LuaPseudoRandom(seed)
// Creates an LuaPseudoRandom and leaves it on top of stack
@@ -126,12 +128,13 @@ public:
/*
LuaPcgRandom
*/
-class LuaPcgRandom : public ModApiBase {
+class LuaPcgRandom : public ModApiBase
+{
private:
PcgRandom m_rnd;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
// Exported functions
@@ -146,10 +149,8 @@ private:
static int l_rand_normal_dist(lua_State *L);
public:
- LuaPcgRandom(u64 seed) :
- m_rnd(seed) {}
- LuaPcgRandom(u64 seed, u64 seq) :
- m_rnd(seed, seq) {}
+ LuaPcgRandom(u64 seed) : m_rnd(seed) {}
+ LuaPcgRandom(u64 seed, u64 seq) : m_rnd(seed, seq) {}
// LuaPcgRandom(seed)
// Creates an LuaPcgRandom and leaves it on top of stack
@@ -160,15 +161,15 @@ public:
static void Register(lua_State *L);
};
-
/*
LuaSecureRandom
*/
-class LuaSecureRandom : public ModApiBase {
+class LuaSecureRandom : public ModApiBase
+{
private:
static const size_t RAND_BUF_SIZE = 2048;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
u32 m_rand_idx;
char m_rand_buf[RAND_BUF_SIZE];
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 2a8b8a64e..aaab0d98e 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_sao.h"
#include "server.h"
#include "hud.h"
-#include "scripting_game.h"
+#include "scripting_server.h"
struct EnumString es_HudElementType[] =
{
@@ -137,8 +137,8 @@ int ObjectRef::l_remove(lua_State *L)
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
return 0;
- UNORDERED_SET<int> child_ids = co->getAttachmentChildIds();
- UNORDERED_SET<int>::iterator it;
+ const UNORDERED_SET<int> &child_ids = co->getAttachmentChildIds();
+ UNORDERED_SET<int>::const_iterator it;
for (it = child_ids.begin(); it != child_ids.end(); ++it) {
// Child can be NULL if it was deleted earlier
if (ServerActiveObject *child = env->getActiveObject(*it))
@@ -150,9 +150,9 @@ int ObjectRef::l_remove(lua_State *L)
return 0;
}
-// getpos(self)
+// get_pos(self)
// returns: {x=num, y=num, z=num}
-int ObjectRef::l_getpos(lua_State *L)
+int ObjectRef::l_get_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -169,8 +169,8 @@ int ObjectRef::l_getpos(lua_State *L)
return 1;
}
-// setpos(self, pos)
-int ObjectRef::l_setpos(lua_State *L)
+// set_pos(self, pos)
+int ObjectRef::l_set_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -184,8 +184,8 @@ int ObjectRef::l_setpos(lua_State *L)
return 0;
}
-// moveto(self, pos, continuous=false)
-int ObjectRef::l_moveto(lua_State *L)
+// move_to(self, pos, continuous=false)
+int ObjectRef::l_move_to(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -364,7 +364,7 @@ int ObjectRef::l_set_wielded_item(lua_State *L)
ServerActiveObject *co = getobject(ref);
if (co == NULL) return 0;
// Do it
- ItemStack item = read_item(L, 2, getServer(L));
+ ItemStack item = read_item(L, 2, getServer(L)->idef());
bool success = co->setWieldedItem(item);
if (success && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
getServer(L)->SendInventory(((PlayerSAO*)co));
@@ -396,13 +396,12 @@ int ObjectRef::l_get_armor_groups(lua_State *L)
if (co == NULL)
return 0;
// Do it
- ItemGroupList groups = co->getArmorGroups();
- push_groups(L, groups);
+ push_groups(L, co->getArmorGroups());
return 1;
}
// set_physics_override(self, physics_override_speed, physics_override_jump,
-// physics_override_gravity, sneak, sneak_glitch)
+// physics_override_gravity, sneak, sneak_glitch, new_move)
int ObjectRef::l_set_physics_override(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
@@ -411,11 +410,18 @@ int ObjectRef::l_set_physics_override(lua_State *L)
if (co == NULL) return 0;
// Do it
if (lua_istable(L, 2)) {
- co->m_physics_override_speed = getfloatfield_default(L, 2, "speed", co->m_physics_override_speed);
- co->m_physics_override_jump = getfloatfield_default(L, 2, "jump", co->m_physics_override_jump);
- co->m_physics_override_gravity = getfloatfield_default(L, 2, "gravity", co->m_physics_override_gravity);
- co->m_physics_override_sneak = getboolfield_default(L, 2, "sneak", co->m_physics_override_sneak);
- co->m_physics_override_sneak_glitch = getboolfield_default(L, 2, "sneak_glitch", co->m_physics_override_sneak_glitch);
+ co->m_physics_override_speed = getfloatfield_default(
+ L, 2, "speed", co->m_physics_override_speed);
+ co->m_physics_override_jump = getfloatfield_default(
+ L, 2, "jump", co->m_physics_override_jump);
+ co->m_physics_override_gravity = getfloatfield_default(
+ L, 2, "gravity", co->m_physics_override_gravity);
+ co->m_physics_override_sneak = getboolfield_default(
+ L, 2, "sneak", co->m_physics_override_sneak);
+ co->m_physics_override_sneak_glitch = getboolfield_default(
+ L, 2, "sneak_glitch", co->m_physics_override_sneak_glitch);
+ co->m_physics_override_new_move = getboolfield_default(
+ L, 2, "new_move", co->m_physics_override_new_move);
co->m_physics_override_sent = false;
} else {
// old, non-table format
@@ -455,6 +461,8 @@ int ObjectRef::l_get_physics_override(lua_State *L)
lua_setfield(L, -2, "sneak");
lua_pushboolean(L, co->m_physics_override_sneak_glitch);
lua_setfield(L, -2, "sneak_glitch");
+ lua_pushboolean(L, co->m_physics_override_new_move);
+ lua_setfield(L, -2, "new_move");
return 1;
}
@@ -718,11 +726,13 @@ int ObjectRef::l_set_detach(lua_State *L)
v3f rotation;
co->getAttachment(&parent_id, &bone, &position, &rotation);
ServerActiveObject *parent = NULL;
- if (parent_id)
+ if (parent_id) {
parent = env->getActiveObject(parent_id);
-
+ co->setAttachment(0, "", position, rotation);
+ } else {
+ co->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0));
+ }
// Do it
- co->setAttachment(0, "", v3f(0,0,0), v3f(0,0,0));
if (parent != NULL)
parent->removeAttachmentChild(co->getId());
return 0;
@@ -738,7 +748,7 @@ int ObjectRef::l_set_properties(lua_State *L)
ObjectProperties *prop = co->accessObjectProperties();
if (!prop)
return 0;
- read_object_properties(L, 2, prop);
+ read_object_properties(L, 2, prop, getServer(L)->idef());
co->notifyObjectPropertiesModified();
return 0;
}
@@ -790,8 +800,7 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L)
lua_pop(L, 1);
std::string nametag = getstringfield_default(L, 2, "text", "");
- if (nametag != "")
- prop->nametag = nametag;
+ prop->nametag = nametag;
co->notifyObjectPropertiesModified();
lua_pushboolean(L, true);
@@ -823,8 +832,8 @@ int ObjectRef::l_get_nametag_attributes(lua_State *L)
/* LuaEntitySAO-only */
-// setvelocity(self, {x=num, y=num, z=num})
-int ObjectRef::l_setvelocity(lua_State *L)
+// set_velocity(self, {x=num, y=num, z=num})
+int ObjectRef::l_set_velocity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -836,8 +845,8 @@ int ObjectRef::l_setvelocity(lua_State *L)
return 0;
}
-// getvelocity(self)
-int ObjectRef::l_getvelocity(lua_State *L)
+// get_velocity(self)
+int ObjectRef::l_get_velocity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -849,8 +858,8 @@ int ObjectRef::l_getvelocity(lua_State *L)
return 1;
}
-// setacceleration(self, {x=num, y=num, z=num})
-int ObjectRef::l_setacceleration(lua_State *L)
+// set_acceleration(self, {x=num, y=num, z=num})
+int ObjectRef::l_set_acceleration(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -863,8 +872,8 @@ int ObjectRef::l_setacceleration(lua_State *L)
return 0;
}
-// getacceleration(self)
-int ObjectRef::l_getacceleration(lua_State *L)
+// get_acceleration(self)
+int ObjectRef::l_get_acceleration(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -876,8 +885,8 @@ int ObjectRef::l_getacceleration(lua_State *L)
return 1;
}
-// setyaw(self, radians)
-int ObjectRef::l_setyaw(lua_State *L)
+// set_yaw(self, radians)
+int ObjectRef::l_set_yaw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -889,8 +898,8 @@ int ObjectRef::l_setyaw(lua_State *L)
return 0;
}
-// getyaw(self)
-int ObjectRef::l_getyaw(lua_State *L)
+// get_yaw(self)
+int ObjectRef::l_get_yaw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -902,8 +911,8 @@ int ObjectRef::l_getyaw(lua_State *L)
return 1;
}
-// settexturemod(self, mod)
-int ObjectRef::l_settexturemod(lua_State *L)
+// set_texture_mod(self, mod)
+int ObjectRef::l_set_texture_mod(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -915,9 +924,22 @@ int ObjectRef::l_settexturemod(lua_State *L)
return 0;
}
-// setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
+// get_texture_mod(self)
+int ObjectRef::l_get_texture_mod(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if (co == NULL) return 0;
+ // Do it
+ std::string mod = co->getTextureMod();
+ lua_pushstring(L, mod.c_str());
+ return 1;
+}
+
+// set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
// select_horiz_by_yawpitch=false)
-int ObjectRef::l_setsprite(lua_State *L)
+int ObjectRef::l_set_sprite(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
@@ -1152,13 +1174,8 @@ int ObjectRef::l_set_breath(lua_State *L)
PlayerSAO* co = getplayersao(ref);
if (co == NULL) return 0;
u16 breath = luaL_checknumber(L, 2);
- // Do it
co->setBreath(breath);
- // If the object is a player sent the breath to client
- if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
- getServer(L)->SendPlayerBreath(((PlayerSAO*)co)->getPeerID());
-
return 0;
}
@@ -1175,6 +1192,46 @@ int ObjectRef::l_get_breath(lua_State *L)
return 1;
}
+// set_attribute(self, attribute, value)
+int ObjectRef::l_set_attribute(lua_State *L)
+{
+ ObjectRef *ref = checkobject(L, 1);
+ PlayerSAO* co = getplayersao(ref);
+ if (co == NULL) {
+ return 0;
+ }
+
+ std::string attr = luaL_checkstring(L, 2);
+ if (lua_isnil(L, 3)) {
+ co->removeExtendedAttribute(attr);
+ } else {
+ std::string value = luaL_checkstring(L, 3);
+ co->setExtendedAttribute(attr, value);
+ }
+ return 1;
+}
+
+// get_attribute(self, attribute)
+int ObjectRef::l_get_attribute(lua_State *L)
+{
+ ObjectRef *ref = checkobject(L, 1);
+ PlayerSAO* co = getplayersao(ref);
+ if (co == NULL) {
+ return 0;
+ }
+
+ std::string attr = luaL_checkstring(L, 2);
+
+ std::string value = "";
+ if (co->getExtendedAttribute(attr, &value)) {
+ lua_pushstring(L, value.c_str());
+ return 1;
+ }
+
+ return 0;
+}
+
+
// set_inventory_formspec(self, formspec)
int ObjectRef::l_set_inventory_formspec(lua_State *L)
{
@@ -1606,7 +1663,7 @@ int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L)
return 1;
}
-// set_sky(self, bgcolor, type, list)
+// set_sky(self, bgcolor, type, list, clouds = true)
int ObjectRef::l_set_sky(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
@@ -1622,9 +1679,8 @@ int ObjectRef::l_set_sky(lua_State *L)
std::vector<std::string> params;
if (lua_istable(L, 4)) {
- int table = lua_gettop(L);
lua_pushnil(L);
- while (lua_next(L, table) != 0) {
+ while (lua_next(L, 4) != 0) {
// key at index -2 and value at index -1
if (lua_isstring(L, -1))
params.push_back(lua_tostring(L, -1));
@@ -1638,7 +1694,11 @@ int ObjectRef::l_set_sky(lua_State *L)
if (type == "skybox" && params.size() != 6)
throw LuaError("skybox expects 6 textures");
- if (!getServer(L)->setSky(player, bgcolor, type, params))
+ bool clouds = true;
+ if (lua_isboolean(L, 5))
+ clouds = lua_toboolean(L, 5);
+
+ if (!getServer(L)->setSky(player, bgcolor, type, params, clouds))
return 0;
lua_pushboolean(L, true);
@@ -1656,8 +1716,9 @@ int ObjectRef::l_get_sky(lua_State *L)
video::SColor bgcolor(255, 255, 255, 255);
std::string type;
std::vector<std::string> params;
+ bool clouds;
- player->getSky(&bgcolor, &type, &params);
+ player->getSky(&bgcolor, &type, &params, &clouds);
type = type == "" ? "regular" : type;
push_ARGB8(L, bgcolor);
@@ -1670,9 +1731,89 @@ int ObjectRef::l_get_sky(lua_State *L)
lua_rawseti(L, -2, i);
i++;
}
- return 3;
+ lua_pushboolean(L, clouds);
+ return 4;
}
+// set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=})
+int ObjectRef::l_set_clouds(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ ObjectRef *ref = checkobject(L, 1);
+ RemotePlayer *player = getplayer(ref);
+ if (!player)
+ return 0;
+ if (!lua_istable(L, 2))
+ return 0;
+
+ CloudParams cloud_params = player->getCloudParams();
+
+ cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density);
+
+ lua_getfield(L, 2, "color");
+ if (!lua_isnil(L, -1))
+ read_color(L, -1, &cloud_params.color_bright);
+ lua_pop(L, 1);
+ lua_getfield(L, 2, "ambient");
+ if (!lua_isnil(L, -1))
+ read_color(L, -1, &cloud_params.color_ambient);
+ lua_pop(L, 1);
+
+ cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height );
+ cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness);
+
+ lua_getfield(L, 2, "speed");
+ if (lua_istable(L, -1)) {
+ v2f new_speed;
+ new_speed.X = getfloatfield_default(L, -1, "x", 0);
+ new_speed.Y = getfloatfield_default(L, -1, "y", 0);
+ cloud_params.speed = new_speed;
+ }
+ lua_pop(L, 1);
+
+ if (!getServer(L)->setClouds(player, cloud_params.density,
+ cloud_params.color_bright, cloud_params.color_ambient,
+ cloud_params.height, cloud_params.thickness,
+ cloud_params.speed))
+ return 0;
+
+ player->setCloudParams(cloud_params);
+
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+int ObjectRef::l_get_clouds(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ ObjectRef *ref = checkobject(L, 1);
+ RemotePlayer *player = getplayer(ref);
+ if (!player)
+ return 0;
+ const CloudParams &cloud_params = player->getCloudParams();
+
+ lua_newtable(L);
+ lua_pushnumber(L, cloud_params.density);
+ lua_setfield(L, -2, "density");
+ push_ARGB8(L, cloud_params.color_bright);
+ lua_setfield(L, -2, "color");
+ push_ARGB8(L, cloud_params.color_ambient);
+ lua_setfield(L, -2, "ambient");
+ lua_pushnumber(L, cloud_params.height);
+ lua_setfield(L, -2, "height");
+ lua_pushnumber(L, cloud_params.thickness);
+ lua_setfield(L, -2, "thickness");
+ lua_newtable(L);
+ lua_pushnumber(L, cloud_params.speed.X);
+ lua_setfield(L, -2, "x");
+ lua_pushnumber(L, cloud_params.speed.Y);
+ lua_setfield(L, -2, "y");
+ lua_setfield(L, -2, "speed");
+
+ return 1;
+}
+
+
// override_day_night_ratio(self, brightness=0...1)
int ObjectRef::l_override_day_night_ratio(lua_State *L)
{
@@ -1778,12 +1919,12 @@ void ObjectRef::Register(lua_State *L)
}
const char ObjectRef::className[] = "ObjectRef";
-const luaL_reg ObjectRef::methods[] = {
+const luaL_Reg ObjectRef::methods[] = {
// ServerActiveObject
luamethod(ObjectRef, remove),
- luamethod(ObjectRef, getpos),
- luamethod(ObjectRef, setpos),
- luamethod(ObjectRef, moveto),
+ luamethod_aliased(ObjectRef, get_pos, getpos),
+ luamethod_aliased(ObjectRef, set_pos, setpos),
+ luamethod_aliased(ObjectRef, move_to, moveto),
luamethod(ObjectRef, punch),
luamethod(ObjectRef, right_click),
luamethod(ObjectRef, set_hp),
@@ -1807,14 +1948,14 @@ const luaL_reg ObjectRef::methods[] = {
luamethod(ObjectRef, set_nametag_attributes),
luamethod(ObjectRef, get_nametag_attributes),
// LuaEntitySAO-only
- luamethod(ObjectRef, setvelocity),
- luamethod(ObjectRef, getvelocity),
- luamethod(ObjectRef, setacceleration),
- luamethod(ObjectRef, getacceleration),
- luamethod(ObjectRef, setyaw),
- luamethod(ObjectRef, getyaw),
- luamethod(ObjectRef, settexturemod),
- luamethod(ObjectRef, setsprite),
+ luamethod_aliased(ObjectRef, set_velocity, setvelocity),
+ luamethod_aliased(ObjectRef, get_velocity, getvelocity),
+ luamethod_aliased(ObjectRef, set_acceleration, setacceleration),
+ luamethod_aliased(ObjectRef, get_acceleration, getacceleration),
+ luamethod_aliased(ObjectRef, set_yaw, setyaw),
+ luamethod_aliased(ObjectRef, get_yaw, getyaw),
+ luamethod_aliased(ObjectRef, set_texture_mod, settexturemod),
+ luamethod_aliased(ObjectRef, set_sprite, setsprite),
luamethod(ObjectRef, get_entity_name),
luamethod(ObjectRef, get_luaentity),
// Player-only
@@ -1833,6 +1974,8 @@ const luaL_reg ObjectRef::methods[] = {
luamethod(ObjectRef, set_look_pitch),
luamethod(ObjectRef, get_breath),
luamethod(ObjectRef, set_breath),
+ luamethod(ObjectRef, get_attribute),
+ luamethod(ObjectRef, set_attribute),
luamethod(ObjectRef, set_inventory_formspec),
luamethod(ObjectRef, get_inventory_formspec),
luamethod(ObjectRef, get_player_control),
@@ -1853,6 +1996,8 @@ const luaL_reg ObjectRef::methods[] = {
luamethod(ObjectRef, hud_get_hotbar_selected_image),
luamethod(ObjectRef, set_sky),
luamethod(ObjectRef, get_sky),
+ luamethod(ObjectRef, set_clouds),
+ luamethod(ObjectRef, get_clouds),
luamethod(ObjectRef, override_day_night_ratio),
luamethod(ObjectRef, get_day_night_ratio),
luamethod(ObjectRef, set_local_animation),
diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h
index 09f10e417..9801ce02b 100644
--- a/src/script/lua_api/l_object.h
+++ b/src/script/lua_api/l_object.h
@@ -37,7 +37,7 @@ private:
ServerActiveObject *m_object;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
public:
static ObjectRef *checkobject(lua_State *L, int narg);
@@ -57,15 +57,15 @@ private:
// remove(self)
static int l_remove(lua_State *L);
- // getpos(self)
+ // get_pos(self)
// returns: {x=num, y=num, z=num}
- static int l_getpos(lua_State *L);
+ static int l_get_pos(lua_State *L);
- // setpos(self, pos)
- static int l_setpos(lua_State *L);
+ // set_pos(self, pos)
+ static int l_set_pos(lua_State *L);
- // moveto(self, pos, continuous=false)
- static int l_moveto(lua_State *L);
+ // move_to(self, pos, continuous=false)
+ static int l_move_to(lua_State *L);
// punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
static int l_punch(lua_State *L);
@@ -105,7 +105,7 @@ private:
static int l_get_armor_groups(lua_State *L);
// set_physics_override(self, physics_override_speed, physics_override_jump,
- // physics_override_gravity, sneak, sneak_glitch)
+ // physics_override_gravity, sneak, sneak_glitch, new_move)
static int l_set_physics_override(lua_State *L);
// get_physics_override(self)
@@ -143,30 +143,33 @@ private:
/* LuaEntitySAO-only */
- // setvelocity(self, {x=num, y=num, z=num})
- static int l_setvelocity(lua_State *L);
+ // set_velocity(self, {x=num, y=num, z=num})
+ static int l_set_velocity(lua_State *L);
- // getvelocity(self)
- static int l_getvelocity(lua_State *L);
+ // get_velocity(self)
+ static int l_get_velocity(lua_State *L);
- // setacceleration(self, {x=num, y=num, z=num})
- static int l_setacceleration(lua_State *L);
+ // set_acceleration(self, {x=num, y=num, z=num})
+ static int l_set_acceleration(lua_State *L);
- // getacceleration(self)
- static int l_getacceleration(lua_State *L);
+ // get_acceleration(self)
+ static int l_get_acceleration(lua_State *L);
- // setyaw(self, radians)
- static int l_setyaw(lua_State *L);
+ // set_yaw(self, radians)
+ static int l_set_yaw(lua_State *L);
- // getyaw(self)
- static int l_getyaw(lua_State *L);
+ // get_yaw(self)
+ static int l_get_yaw(lua_State *L);
- // settexturemod(self, mod)
- static int l_settexturemod(lua_State *L);
+ // set_texture_mod(self, mod)
+ static int l_set_texture_mod(lua_State *L);
- // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
+ // l_get_texture_mod(self)
+ static int l_get_texture_mod(lua_State *L);
+
+ // set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
// select_horiz_by_yawpitch=false)
- static int l_setsprite(lua_State *L);
+ static int l_set_sprite(lua_State *L);
// DEPRECATED
// get_entity_name(self)
@@ -223,6 +226,12 @@ private:
// get_breath(self, breath)
static int l_get_breath(lua_State *L);
+ // set_attribute(self, attribute, value)
+ static int l_set_attribute(lua_State *L);
+
+ // get_attribute(self, attribute)
+ static int l_get_attribute(lua_State *L);
+
// set_inventory_formspec(self, formspec)
static int l_set_inventory_formspec(lua_State *L);
@@ -274,12 +283,18 @@ private:
// hud_get_hotbar_selected_image(self)
static int l_hud_get_hotbar_selected_image(lua_State *L);
- // set_sky(self, type, list)
+ // set_sky(self, bgcolor, type, list, clouds = true)
static int l_set_sky(lua_State *L);
- // get_sky(self, type, list)
+ // get_sky(self)
static int l_get_sky(lua_State *L);
+ // set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=})
+ static int l_set_clouds(lua_State *L);
+
+ // get_clouds(self)
+ static int l_get_clouds(lua_State *L);
+
// override_day_night_ratio(self, type)
static int l_override_day_night_ratio(lua_State *L);
diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp
index 667ac7272..2f3e9a58d 100644
--- a/src/script/lua_api/l_particles.cpp
+++ b/src/script/lua_api/l_particles.cpp
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_object.h"
#include "lua_api/l_internal.h"
#include "common/c_converter.h"
+#include "common/c_content.h"
#include "server.h"
#include "particles.h"
@@ -34,6 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// collision_removal = bool
// vertical = bool
// texture = e.g."default_wood.png"
+// animation = TileAnimation definition
+// glow = num
int ModApiParticles::l_add_particle(lua_State *L)
{
MAP_LOCK_REQUIRED;
@@ -47,10 +50,14 @@ int ModApiParticles::l_add_particle(lua_State *L)
bool collisiondetection, vertical, collision_removal;
collisiondetection = vertical = collision_removal = false;
+ struct TileAnimationParams animation;
+ animation.type = TAT_NONE;
std::string texture = "";
std::string playername = "";
+ u8 glow = 0;
+
if (lua_gettop(L) > 1) // deprecated
{
log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition");
@@ -101,11 +108,18 @@ int ModApiParticles::l_add_particle(lua_State *L)
collision_removal = getboolfield_default(L, 1,
"collision_removal", collision_removal);
vertical = getboolfield_default(L, 1, "vertical", vertical);
+
+ lua_getfield(L, 1, "animation");
+ animation = read_animation_definition(L, -1);
+ lua_pop(L, 1);
+
texture = getstringfield_default(L, 1, "texture", "");
playername = getstringfield_default(L, 1, "playername", "");
+
+ glow = getintfield_default(L, 1, "glow", 0);
}
getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size,
- collisiondetection, collision_removal, vertical, texture);
+ collisiondetection, collision_removal, vertical, texture, animation, glow);
return 1;
}
@@ -127,6 +141,8 @@ int ModApiParticles::l_add_particle(lua_State *L)
// collision_removal = bool
// vertical = bool
// texture = e.g."default_wood.png"
+// animation = TileAnimation definition
+// glow = num
int ModApiParticles::l_add_particlespawner(lua_State *L)
{
MAP_LOCK_REQUIRED;
@@ -139,9 +155,12 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
time= minexptime= maxexptime= minsize= maxsize= 1;
bool collisiondetection, vertical, collision_removal;
collisiondetection = vertical = collision_removal = false;
+ struct TileAnimationParams animation;
+ animation.type = TAT_NONE;
ServerActiveObject *attached = NULL;
std::string texture = "";
std::string playername = "";
+ u8 glow = 0;
if (lua_gettop(L) > 1) //deprecated
{
@@ -201,6 +220,10 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
collision_removal = getboolfield_default(L, 1,
"collision_removal", collision_removal);
+ lua_getfield(L, 1, "animation");
+ animation = read_animation_definition(L, -1);
+ lua_pop(L, 1);
+
lua_getfield(L, 1, "attached");
if (!lua_isnil(L, -1)) {
ObjectRef *ref = ObjectRef::checkobject(L, -1);
@@ -211,6 +234,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
vertical = getboolfield_default(L, 1, "vertical", vertical);
texture = getstringfield_default(L, 1, "texture", "");
playername = getstringfield_default(L, 1, "playername", "");
+ glow = getintfield_default(L, 1, "glow", 0);
}
u32 id = getServer(L)->addParticleSpawner(amount, time,
@@ -223,7 +247,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
collision_removal,
attached,
vertical,
- texture, playername);
+ texture, playername,
+ animation, glow);
lua_pushnumber(L, id);
return 1;
diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp
index b6d44e0ff..a0e475dec 100644
--- a/src/script/lua_api/l_server.cpp
+++ b/src/script/lua_api/l_server.cpp
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "environment.h"
#include "player.h"
#include "log.h"
+#include <algorithm>
// request_shutdown()
int ModApiServer::l_request_shutdown(lua_State *L)
@@ -33,7 +34,8 @@ int ModApiServer::l_request_shutdown(lua_State *L)
NO_MAP_LOCK_REQUIRED;
const char *msg = lua_tolstring(L, 1, NULL);
bool reconnect = lua_toboolean(L, 2);
- getServer(L)->requestShutdown(msg ? msg : "", reconnect);
+ float seconds_before_shutdown = lua_tonumber(L, 3);
+ getServer(L)->requestShutdown(msg ? msg : "", reconnect, seconds_before_shutdown);
return 0;
}
@@ -102,7 +104,7 @@ int ModApiServer::l_get_player_privs(lua_State *L)
int table = lua_gettop(L);
std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
for(std::set<std::string>::const_iterator
- i = privs_s.begin(); i != privs_s.end(); i++){
+ i = privs_s.begin(); i != privs_s.end(); ++i){
lua_pushboolean(L, true);
lua_setfield(L, table, i->c_str());
}
@@ -136,7 +138,7 @@ int ModApiServer::l_get_player_ip(lua_State *L)
}
}
-// get_player_information()
+// get_player_information(name)
int ModApiServer::l_get_player_information(lua_State *L)
{
@@ -230,15 +232,15 @@ int ModApiServer::l_get_player_information(lua_State *L)
lua_pushnumber(L, uptime);
lua_settable(L, table);
+ lua_pushstring(L,"protocol_version");
+ lua_pushnumber(L, prot_vers);
+ lua_settable(L, table);
+
#ifndef NDEBUG
lua_pushstring(L,"serialization_version");
lua_pushnumber(L, ser_vers);
lua_settable(L, table);
- lua_pushstring(L,"protocol_version");
- lua_pushnumber(L, prot_vers);
- lua_settable(L, table);
-
lua_pushstring(L,"major");
lua_pushnumber(L, major);
lua_settable(L, table);
@@ -333,6 +335,22 @@ int ModApiServer::l_kick_player(lua_State *L)
return 1;
}
+int ModApiServer::l_remove_player(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ std::string name = luaL_checkstring(L, 1);
+ ServerEnvironment *s_env = dynamic_cast<ServerEnvironment *>(getEnv(L));
+ assert(s_env);
+
+ RemotePlayer *player = s_env->getPlayer(name.c_str());
+ if (!player)
+ lua_pushinteger(L, s_env->removePlayerFromDatabase(name) ? 0 : 1);
+ else
+ lua_pushinteger(L, 2);
+
+ return 1;
+}
+
// unban_player_or_ip()
int ModApiServer::l_unban_player_or_ip(lua_State *L)
{
@@ -400,7 +418,7 @@ int ModApiServer::l_get_modnames(lua_State *L)
// Package them up for Lua
lua_createtable(L, modlist.size(), 0);
std::vector<std::string>::iterator iter = modlist.begin();
- for (u16 i = 0; iter != modlist.end(); iter++) {
+ for (u16 i = 0; iter != modlist.end(); ++iter) {
lua_pushstring(L, iter->c_str());
lua_rawseti(L, -2, ++i);
}
@@ -438,6 +456,16 @@ int ModApiServer::l_sound_stop(lua_State *L)
return 0;
}
+int ModApiServer::l_sound_fade(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ s32 handle = luaL_checkinteger(L, 1);
+ float step = luaL_checknumber(L, 2);
+ float gain = luaL_checknumber(L, 3);
+ getServer(L)->fadeSound(handle, step, gain);
+ return 0;
+}
+
// is_singleplayer()
int ModApiServer::l_is_singleplayer(lua_State *L)
{
@@ -482,36 +510,6 @@ int ModApiServer::l_set_last_run_mod(lua_State *L)
return 0;
}
-#ifndef NDEBUG
-// cause_error(type_of_error)
-int ModApiServer::l_cause_error(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- std::string type_of_error = "none";
- if(lua_isstring(L, 1))
- type_of_error = lua_tostring(L, 1);
-
- errorstream << "Error handler test called, errortype=" << type_of_error << std::endl;
-
- if(type_of_error == "segv") {
- volatile int* some_pointer = 0;
- errorstream << "Cause a sigsegv now: " << (*some_pointer) << std::endl;
-
- } else if (type_of_error == "zerodivision") {
-
- unsigned int some_number = porting::getTimeS();
- unsigned int zerovalue = 0;
- unsigned int result = some_number / zerovalue;
- errorstream << "Well this shouldn't ever be shown: " << result << std::endl;
-
- } else if (type_of_error == "exception") {
- throw BaseException("Errorhandler test fct called");
- }
-
- return 0;
-}
-#endif
-
void ModApiServer::Initialize(lua_State *L, int top)
{
API_FCT(request_shutdown);
@@ -531,6 +529,7 @@ void ModApiServer::Initialize(lua_State *L, int top)
API_FCT(show_formspec);
API_FCT(sound_play);
API_FCT(sound_stop);
+ API_FCT(sound_fade);
API_FCT(get_player_information);
API_FCT(get_player_privs);
@@ -539,12 +538,10 @@ void ModApiServer::Initialize(lua_State *L, int top)
API_FCT(get_ban_description);
API_FCT(ban_player);
API_FCT(kick_player);
+ API_FCT(remove_player);
API_FCT(unban_player_or_ip);
API_FCT(notify_authentication_modified);
API_FCT(get_last_run_mod);
API_FCT(set_last_run_mod);
-#ifndef NDEBUG
- API_FCT(cause_error);
-#endif
}
diff --git a/src/script/lua_api/l_server.h b/src/script/lua_api/l_server.h
index 1ad46d440..251a0ce89 100644
--- a/src/script/lua_api/l_server.h
+++ b/src/script/lua_api/l_server.h
@@ -22,7 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_base.h"
-class ModApiServer : public ModApiBase {
+class ModApiServer : public ModApiBase
+{
private:
// request_shutdown([message], [reconnect])
static int l_request_shutdown(lua_State *L);
@@ -67,13 +68,16 @@ private:
// sound_stop(handle)
static int l_sound_stop(lua_State *L);
+ // sound_fade(handle, step, gain)
+ static int l_sound_fade(lua_State *L);
+
// get_player_privs(name, text)
static int l_get_player_privs(lua_State *L);
// get_player_ip()
static int l_get_player_ip(lua_State *L);
- // get_player_information()
+ // get_player_information(name)
static int l_get_player_information(lua_State *L);
// get_ban_list()
@@ -91,6 +95,9 @@ private:
// kick_player(name, [message]) -> success
static int l_kick_player(lua_State *L);
+ // remove_player(name)
+ static int l_remove_player(lua_State *L);
+
// notify_authentication_modified(name)
static int l_notify_authentication_modified(lua_State *L);
@@ -100,14 +107,8 @@ private:
// set_last_run_mod(modname)
static int l_set_last_run_mod(lua_State *L);
-#ifndef NDEBUG
- // cause_error(type_of_error)
- static int l_cause_error(lua_State *L);
-#endif
-
public:
static void Initialize(lua_State *L, int top);
-
};
#endif /* L_SERVER_H_ */
diff --git a/src/script/lua_api/l_settings.cpp b/src/script/lua_api/l_settings.cpp
index d3fe03005..70807f3d2 100644
--- a/src/script/lua_api/l_settings.cpp
+++ b/src/script/lua_api/l_settings.cpp
@@ -23,6 +23,47 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "log.h"
+
+#define SET_SECURITY_CHECK(L, name) \
+ if (o->m_settings == g_settings && ScriptApiSecurity::isSecure(L) && \
+ name.compare(0, 7, "secure.") == 0) { \
+ throw LuaError("Attempt to set secure setting."); \
+ }
+
+LuaSettings::LuaSettings(Settings *settings, const std::string &filename) :
+ m_settings(settings),
+ m_filename(filename),
+ m_is_own_settings(false),
+ m_write_allowed(true)
+{
+}
+
+LuaSettings::LuaSettings(const std::string &filename, bool write_allowed) :
+ m_filename(filename),
+ m_is_own_settings(true),
+ m_write_allowed(write_allowed)
+{
+ m_settings = new Settings();
+ m_settings->readConfigFile(filename.c_str());
+}
+
+LuaSettings::~LuaSettings()
+{
+ if (m_is_own_settings)
+ delete m_settings;
+}
+
+
+void LuaSettings::create(lua_State *L, Settings *settings,
+ const std::string &filename)
+{
+ LuaSettings *o = new LuaSettings(settings, filename);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+}
+
+
// garbage collector
int LuaSettings::gc_object(lua_State* L)
{
@@ -31,6 +72,7 @@ int LuaSettings::gc_object(lua_State* L)
return 0;
}
+
// get(self, key) -> value
int LuaSettings::l_get(lua_State* L)
{
@@ -74,12 +116,30 @@ int LuaSettings::l_set(lua_State* L)
std::string key = std::string(luaL_checkstring(L, 2));
const char* value = luaL_checkstring(L, 3);
+ SET_SECURITY_CHECK(L, key);
+
if (!o->m_settings->set(key, value))
throw LuaError("Invalid sequence found in setting parameters");
return 0;
}
+// set_bool(self, key, value)
+int LuaSettings::l_set_bool(lua_State* L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ LuaSettings* o = checkobject(L, 1);
+
+ std::string key = std::string(luaL_checkstring(L, 2));
+ bool value = lua_toboolean(L, 3);
+
+ SET_SECURITY_CHECK(L, key);
+
+ o->m_settings->setBool(key, value);
+
+ return 1;
+}
+
// remove(self, key) -> success
int LuaSettings::l_remove(lua_State* L)
{
@@ -88,6 +148,8 @@ int LuaSettings::l_remove(lua_State* L)
std::string key = std::string(luaL_checkstring(L, 2));
+ SET_SECURITY_CHECK(L, key);
+
bool success = o->m_settings->remove(key);
lua_pushboolean(L, success);
@@ -147,19 +209,6 @@ int LuaSettings::l_to_table(lua_State* L)
return 1;
}
-LuaSettings::LuaSettings(const char* filename, bool write_allowed)
-{
- m_write_allowed = write_allowed;
- m_filename = std::string(filename);
-
- m_settings = new Settings();
- m_settings->readConfigFile(m_filename.c_str());
-}
-
-LuaSettings::~LuaSettings()
-{
- delete m_settings;
-}
void LuaSettings::Register(lua_State* L)
{
@@ -190,7 +239,7 @@ void LuaSettings::Register(lua_State* L)
}
// LuaSettings(filename)
-// Creates an LuaSettings and leaves it on top of stack
+// Creates a LuaSettings and leaves it on top of the stack
int LuaSettings::create_object(lua_State* L)
{
NO_MAP_LOCK_REQUIRED;
@@ -209,15 +258,17 @@ LuaSettings* LuaSettings::checkobject(lua_State* L, int narg)
NO_MAP_LOCK_REQUIRED;
luaL_checktype(L, narg, LUA_TUSERDATA);
void *ud = luaL_checkudata(L, narg, className);
- if(!ud) luaL_typerror(L, narg, className);
- return *(LuaSettings**)ud; // unbox pointer
+ if (!ud)
+ luaL_typerror(L, narg, className);
+ return *(LuaSettings**) ud; // unbox pointer
}
const char LuaSettings::className[] = "Settings";
-const luaL_reg LuaSettings::methods[] = {
+const luaL_Reg LuaSettings::methods[] = {
luamethod(LuaSettings, get),
luamethod(LuaSettings, get_bool),
luamethod(LuaSettings, set),
+ luamethod(LuaSettings, set_bool),
luamethod(LuaSettings, remove),
luamethod(LuaSettings, get_names),
luamethod(LuaSettings, write),
diff --git a/src/script/lua_api/l_settings.h b/src/script/lua_api/l_settings.h
index bca333e31..54b003ab3 100644
--- a/src/script/lua_api/l_settings.h
+++ b/src/script/lua_api/l_settings.h
@@ -24,51 +24,58 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class Settings;
-class LuaSettings : public ModApiBase {
+class LuaSettings : public ModApiBase
+{
private:
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
// garbage collector
- static int gc_object(lua_State* L);
+ static int gc_object(lua_State *L);
// get(self, key) -> value
- static int l_get(lua_State* L);
+ static int l_get(lua_State *L);
// get_bool(self, key) -> boolean
- static int l_get_bool(lua_State* L);
+ static int l_get_bool(lua_State *L);
// set(self, key, value)
- static int l_set(lua_State* L);
+ static int l_set(lua_State *L);
+
+ // set_bool(self, key, value)
+ static int l_set_bool(lua_State *L);
// remove(self, key) -> success
- static int l_remove(lua_State* L);
+ static int l_remove(lua_State *L);
// get_names(self) -> {key1, ...}
- static int l_get_names(lua_State* L);
+ static int l_get_names(lua_State *L);
// write(self) -> success
- static int l_write(lua_State* L);
+ static int l_write(lua_State *L);
// to_table(self) -> {[key1]=value1,...}
- static int l_to_table(lua_State* L);
+ static int l_to_table(lua_State *L);
- bool m_write_allowed;
- Settings* m_settings;
+ Settings *m_settings;
std::string m_filename;
+ bool m_is_own_settings;
+ bool m_write_allowed;
public:
- LuaSettings(const char* filename, bool write_allowed);
+ LuaSettings(Settings *settings, const std::string &filename);
+ LuaSettings(const std::string &filename, bool write_allowed);
~LuaSettings();
- // LuaSettings(filename)
- // Creates an LuaSettings and leaves it on top of stack
- static int create_object(lua_State* L);
+ static void create(lua_State *L, Settings *settings, const std::string &filename);
- static LuaSettings* checkobject(lua_State* L, int narg);
+ // LuaSettings(filename)
+ // Creates a LuaSettings and leaves it on top of the stack
+ static int create_object(lua_State *L);
- static void Register(lua_State* L);
+ static LuaSettings *checkobject(lua_State *L, int narg);
+ static void Register(lua_State *L);
};
#endif
diff --git a/src/script/lua_api/l_sound.cpp b/src/script/lua_api/l_sound.cpp
new file mode 100644
index 000000000..07ce36daa
--- /dev/null
+++ b/src/script/lua_api/l_sound.cpp
@@ -0,0 +1,53 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "l_sound.h"
+#include "l_internal.h"
+#include "common/c_content.h"
+#include "guiEngine.h"
+
+
+int ModApiSound::l_sound_play(lua_State *L)
+{
+ SimpleSoundSpec spec;
+ read_soundspec(L, 1, spec);
+ bool looped = lua_toboolean(L, 2);
+
+ s32 handle = getGuiEngine(L)->playSound(spec, looped);
+
+ lua_pushinteger(L, handle);
+
+ return 1;
+}
+
+int ModApiSound::l_sound_stop(lua_State *L)
+{
+ u32 handle = luaL_checkinteger(L, 1);
+
+ getGuiEngine(L)->stopSound(handle);
+
+ return 1;
+}
+
+void ModApiSound::Initialize(lua_State *L, int top)
+{
+ API_FCT(sound_play);
+ API_FCT(sound_stop);
+}
diff --git a/src/script/lua_api/l_sound.h b/src/script/lua_api/l_sound.h
new file mode 100644
index 000000000..1f0c1eba1
--- /dev/null
+++ b/src/script/lua_api/l_sound.h
@@ -0,0 +1,36 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_SOUND_H_
+#define L_SOUND_H_
+
+#include "lua_api/l_base.h"
+
+class ModApiSound : public ModApiBase
+{
+private:
+ static int l_sound_play(lua_State *L);
+ static int l_sound_stop(lua_State *L);
+
+public:
+ static void Initialize(lua_State *L, int top);
+};
+
+#endif
diff --git a/src/script/lua_api/l_storage.cpp b/src/script/lua_api/l_storage.cpp
new file mode 100644
index 000000000..4c6b2a182
--- /dev/null
+++ b/src/script/lua_api/l_storage.cpp
@@ -0,0 +1,147 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_storage.h"
+#include "l_internal.h"
+#include "mods.h"
+#include "server.h"
+
+int ModApiStorage::l_get_mod_storage(lua_State *L)
+{
+ lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
+ if (!lua_isstring(L, -1)) {
+ return 0;
+ }
+
+ std::string mod_name = lua_tostring(L, -1);
+
+ ModMetadata *store = new ModMetadata(mod_name);
+ if (IGameDef *gamedef = getGameDef(L)) {
+ store->load(gamedef->getModStoragePath());
+ gamedef->registerModStorage(store);
+ } else {
+ assert(false); // this should not happen
+ }
+
+ StorageRef::create(L, store);
+ int object = lua_gettop(L);
+
+ lua_pushvalue(L, object);
+ return 1;
+}
+
+void ModApiStorage::Initialize(lua_State *L, int top)
+{
+ API_FCT(get_mod_storage);
+}
+
+StorageRef::StorageRef(ModMetadata *object):
+ m_object(object)
+{
+}
+
+void StorageRef::create(lua_State *L, ModMetadata *object)
+{
+ StorageRef *o = new StorageRef(object);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+}
+
+int StorageRef::gc_object(lua_State *L)
+{
+ StorageRef *o = *(StorageRef **)(lua_touserdata(L, 1));
+ // Server side
+ if (IGameDef *gamedef = getGameDef(L))
+ gamedef->unregisterModStorage(getobject(o)->getModName());
+ delete o;
+ return 0;
+}
+
+void StorageRef::Register(lua_State *L)
+{
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+
+ lua_pushliteral(L, "metadata_class");
+ lua_pushlstring(L, className, strlen(className));
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__eq");
+ lua_pushcfunction(L, l_equals);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1); // drop metatable
+
+ luaL_openlib(L, 0, methods, 0); // fill methodtable
+ lua_pop(L, 1); // drop methodtable
+}
+
+StorageRef* StorageRef::checkobject(lua_State *L, int narg)
+{
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+ void *ud = luaL_checkudata(L, narg, className);
+ if (!ud) luaL_typerror(L, narg, className);
+ return *(StorageRef**)ud; // unbox pointer
+}
+
+ModMetadata* StorageRef::getobject(StorageRef *ref)
+{
+ ModMetadata *co = ref->m_object;
+ return co;
+}
+
+Metadata* StorageRef::getmeta(bool auto_create)
+{
+ return m_object;
+}
+
+void StorageRef::clearMeta()
+{
+ m_object->clear();
+}
+
+const char StorageRef::className[] = "StorageRef";
+const luaL_Reg StorageRef::methods[] = {
+ luamethod(MetaDataRef, get_string),
+ luamethod(MetaDataRef, set_string),
+ luamethod(MetaDataRef, get_int),
+ luamethod(MetaDataRef, set_int),
+ luamethod(MetaDataRef, get_float),
+ luamethod(MetaDataRef, set_float),
+ luamethod(MetaDataRef, to_table),
+ luamethod(MetaDataRef, from_table),
+ luamethod(MetaDataRef, equals),
+ {0,0}
+};
diff --git a/src/script/lua_api/l_storage.h b/src/script/lua_api/l_storage.h
new file mode 100644
index 000000000..ec6f8d941
--- /dev/null
+++ b/src/script/lua_api/l_storage.h
@@ -0,0 +1,63 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __L_STORAGE_H__
+#define __L_STORAGE_H__
+
+#include "l_metadata.h"
+#include "lua_api/l_base.h"
+
+class ModMetadata;
+
+class ModApiStorage : public ModApiBase
+{
+protected:
+ static int l_get_mod_storage(lua_State *L);
+
+public:
+ static void Initialize(lua_State *L, int top);
+};
+
+class StorageRef : public MetaDataRef
+{
+private:
+ ModMetadata *m_object;
+
+ static const char className[];
+ static const luaL_Reg methods[];
+
+ virtual Metadata *getmeta(bool auto_create);
+ virtual void clearMeta();
+
+ // garbage collector
+ static int gc_object(lua_State *L);
+
+public:
+ StorageRef(ModMetadata *object);
+ ~StorageRef() {}
+
+ static void Register(lua_State *L);
+ static void create(lua_State *L, ModMetadata *object);
+
+ static StorageRef *checkobject(lua_State *L, int narg);
+ static ModMetadata *getobject(StorageRef *ref);
+};
+
+#endif /* __L_STORAGE_H__ */
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
index 26e2b985c..c4a988e07 100644
--- a/src/script/lua_api/l_util.cpp
+++ b/src/script/lua_api/l_util.cpp
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_util.h"
#include "lua_api/l_internal.h"
+#include "lua_api/l_settings.h"
#include "common/c_converter.h"
#include "common/c_content.h"
#include "cpp_api/s_async.h"
@@ -77,71 +78,6 @@ int ModApiUtil::l_get_us_time(lua_State *L)
return 1;
}
-#define CHECK_SECURE_SETTING(L, name) \
- if (ScriptApiSecurity::isSecure(L) && \
- name.compare(0, 7, "secure.") == 0) { \
- throw LuaError("Attempt to set secure setting."); \
- }
-
-// setting_set(name, value)
-int ModApiUtil::l_setting_set(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- std::string name = luaL_checkstring(L, 1);
- std::string value = luaL_checkstring(L, 2);
- CHECK_SECURE_SETTING(L, name);
- g_settings->set(name, value);
- return 0;
-}
-
-// setting_get(name)
-int ModApiUtil::l_setting_get(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- const char *name = luaL_checkstring(L, 1);
- try{
- std::string value = g_settings->get(name);
- lua_pushstring(L, value.c_str());
- } catch(SettingNotFoundException &e){
- lua_pushnil(L);
- }
- return 1;
-}
-
-// setting_setbool(name)
-int ModApiUtil::l_setting_setbool(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- std::string name = luaL_checkstring(L, 1);
- bool value = lua_toboolean(L, 2);
- CHECK_SECURE_SETTING(L, name);
- g_settings->setBool(name, value);
- return 0;
-}
-
-// setting_getbool(name)
-int ModApiUtil::l_setting_getbool(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- const char *name = luaL_checkstring(L, 1);
- try{
- bool value = g_settings->getBool(name);
- lua_pushboolean(L, value);
- } catch(SettingNotFoundException &e){
- lua_pushnil(L);
- }
- return 1;
-}
-
-// setting_save()
-int ModApiUtil::l_setting_save(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- if(g_settings_path != "")
- g_settings->updateConfigFile(g_settings_path.c_str());
- return 0;
-}
-
// parse_json(str[, nullvalue])
int ModApiUtil::l_parse_json(lua_State *L)
{
@@ -398,7 +334,8 @@ int ModApiUtil::l_get_dir_list(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
const char *path = luaL_checkstring(L, 1);
- short is_dir = lua_isboolean(L, 2) ? lua_toboolean(L, 2) : -1;
+ bool list_all = !lua_isboolean(L, 2); // if its not a boolean list all
+ bool list_dirs = lua_toboolean(L, 2); // true: list dirs, false: list files
CHECK_SECURE_PATH(L, path, false);
@@ -408,7 +345,7 @@ int ModApiUtil::l_get_dir_list(lua_State *L)
lua_newtable(L);
for (size_t i = 0; i < list.size(); i++) {
- if (is_dir == -1 || is_dir == list[i].dir) {
+ if (list_all || list_dirs == list[i].dir) {
lua_pushstring(L, list[i].name.c_str());
lua_rawseti(L, -2, ++index);
}
@@ -492,12 +429,6 @@ void ModApiUtil::Initialize(lua_State *L, int top)
API_FCT(get_us_time);
- API_FCT(setting_set);
- API_FCT(setting_get);
- API_FCT(setting_setbool);
- API_FCT(setting_getbool);
- API_FCT(setting_save);
-
API_FCT(parse_json);
API_FCT(write_json);
@@ -523,36 +454,58 @@ void ModApiUtil::Initialize(lua_State *L, int top)
API_FCT(decode_base64);
API_FCT(get_version);
+
+ LuaSettings::create(L, g_settings, g_settings_path);
+ lua_setfield(L, top, "settings");
}
-void ModApiUtil::InitializeAsync(AsyncEngine& engine)
+void ModApiUtil::InitializeClient(lua_State *L, int top)
{
- ASYNC_API_FCT(log);
+ API_FCT(log);
+
+ API_FCT(get_us_time);
+
+ API_FCT(parse_json);
+ API_FCT(write_json);
+
+ API_FCT(is_yes);
+
+ API_FCT(get_builtin_path);
+
+ API_FCT(compress);
+ API_FCT(decompress);
+
+ API_FCT(encode_base64);
+ API_FCT(decode_base64);
+
+ API_FCT(get_version);
+}
- ASYNC_API_FCT(get_us_time);
+void ModApiUtil::InitializeAsync(lua_State *L, int top)
+{
+ API_FCT(log);
- //ASYNC_API_FCT(setting_set);
- ASYNC_API_FCT(setting_get);
- //ASYNC_API_FCT(setting_setbool);
- ASYNC_API_FCT(setting_getbool);
- //ASYNC_API_FCT(setting_save);
+ API_FCT(get_us_time);
- ASYNC_API_FCT(parse_json);
- ASYNC_API_FCT(write_json);
+ API_FCT(parse_json);
+ API_FCT(write_json);
- ASYNC_API_FCT(is_yes);
+ API_FCT(is_yes);
- ASYNC_API_FCT(get_builtin_path);
+ API_FCT(get_builtin_path);
- ASYNC_API_FCT(compress);
- ASYNC_API_FCT(decompress);
+ API_FCT(compress);
+ API_FCT(decompress);
+
+ API_FCT(mkdir);
+ API_FCT(get_dir_list);
- ASYNC_API_FCT(mkdir);
- ASYNC_API_FCT(get_dir_list);
+ API_FCT(encode_base64);
+ API_FCT(decode_base64);
- ASYNC_API_FCT(encode_base64);
- ASYNC_API_FCT(decode_base64);
+ API_FCT(get_version);
- ASYNC_API_FCT(get_version);
+ LuaSettings::create(L, g_settings, g_settings_path);
+ lua_setfield(L, top, "settings");
}
diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h
index 9910704b3..b75d9db29 100644
--- a/src/script/lua_api/l_util.h
+++ b/src/script/lua_api/l_util.h
@@ -24,7 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class AsyncEngine;
-class ModApiUtil : public ModApiBase {
+class ModApiUtil : public ModApiBase
+{
private:
/*
NOTE:
@@ -44,21 +45,6 @@ private:
// get us precision time
static int l_get_us_time(lua_State *L);
- // setting_set(name, value)
- static int l_setting_set(lua_State *L);
-
- // setting_get(name)
- static int l_setting_get(lua_State *L);
-
- // setting_setbool(name, value)
- static int l_setting_setbool(lua_State *L);
-
- // setting_getbool(name)
- static int l_setting_getbool(lua_State *L);
-
- // setting_save()
- static int l_setting_save(lua_State *L);
-
// parse_json(str[, nullvalue])
static int l_parse_json(lua_State *L);
@@ -109,10 +95,10 @@ private:
public:
static void Initialize(lua_State *L, int top);
+ static void InitializeAsync(lua_State *L, int top);
+ static void InitializeClient(lua_State *L, int top);
- static void InitializeAsync(AsyncEngine& engine);
-
+ static void InitializeAsync(AsyncEngine &engine);
};
#endif /* L_UTIL_H_ */
-
diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp
index bdf720f0a..254a7e5a6 100644
--- a/src/script/lua_api/l_vmanip.cpp
+++ b/src/script/lua_api/l_vmanip.cpp
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "map.h"
#include "server.h"
#include "mapgen.h"
+#include "voxelalgorithms.h"
// garbage collector
int LuaVoxelManip::gc_object(lua_State *L)
@@ -109,10 +110,25 @@ int LuaVoxelManip::l_write_to_map(lua_State *L)
MAP_LOCK_REQUIRED;
LuaVoxelManip *o = checkobject(L, 1);
- MMVManip *vm = o->vm;
+ bool update_light = lua_isboolean(L, 2) ? lua_toboolean(L, 2) : true;
+ GET_ENV_PTR;
+ ServerMap *map = &(env->getServerMap());
+ if (o->is_mapgen_vm || !update_light) {
+ o->vm->blitBackAll(&(o->modified_blocks));
+ } else {
+ voxalgo::blit_back_with_light(map, o->vm,
+ &(o->modified_blocks));
+ }
- vm->blitBackAll(&o->modified_blocks);
+ MapEditEvent event;
+ event.type = MEET_OTHER;
+ for (std::map<v3s16, MapBlock *>::iterator it = o->modified_blocks.begin();
+ it != o->modified_blocks.end(); ++it)
+ event.modified_blocks.insert(it->first);
+ map->dispatchEvent(&event);
+
+ o->modified_blocks.clear();
return 0;
}
@@ -322,33 +338,6 @@ int LuaVoxelManip::l_set_param2_data(lua_State *L)
int LuaVoxelManip::l_update_map(lua_State *L)
{
- GET_ENV_PTR;
-
- LuaVoxelManip *o = checkobject(L, 1);
- if (o->is_mapgen_vm)
- return 0;
-
- Map *map = &(env->getMap());
-
- // TODO: Optimize this by using Mapgen::calcLighting() instead
- std::map<v3s16, MapBlock *> lighting_mblocks;
- std::map<v3s16, MapBlock *> *mblocks = &o->modified_blocks;
-
- lighting_mblocks.insert(mblocks->begin(), mblocks->end());
-
- map->updateLighting(lighting_mblocks, *mblocks);
-
- MapEditEvent event;
- event.type = MEET_OTHER;
- for (std::map<v3s16, MapBlock *>::iterator
- it = mblocks->begin();
- it != mblocks->end(); ++it)
- event.modified_blocks.insert(it->first);
-
- map->dispatchEvent(&event);
-
- mblocks->clear();
-
return 0;
}
@@ -464,7 +453,7 @@ void LuaVoxelManip::Register(lua_State *L)
}
const char LuaVoxelManip::className[] = "VoxelManip";
-const luaL_reg LuaVoxelManip::methods[] = {
+const luaL_Reg LuaVoxelManip::methods[] = {
luamethod(LuaVoxelManip, read_from_map),
luamethod(LuaVoxelManip, get_data),
luamethod(LuaVoxelManip, set_data),
diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h
index 1adb78c4e..b6a69f36a 100644
--- a/src/script/lua_api/l_vmanip.h
+++ b/src/script/lua_api/l_vmanip.h
@@ -20,9 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef L_VMANIP_H_
#define L_VMANIP_H_
-#include "lua_api/l_base.h"
-#include "irr_v3d.h"
#include <map>
+#include "irr_v3d.h"
+#include "lua_api/l_base.h"
class Map;
class MapBlock;
@@ -31,13 +31,14 @@ class MMVManip;
/*
VoxelManip
*/
-class LuaVoxelManip : public ModApiBase {
+class LuaVoxelManip : public ModApiBase
+{
private:
std::map<v3s16, MapBlock *> modified_blocks;
bool is_mapgen_vm;
static const char className[];
- static const luaL_reg methods[];
+ static const luaL_Reg methods[];
static int gc_object(lua_State *L);